aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r--drivers/net/wireless/ath/Kconfig2
-rw-r--r--drivers/net/wireless/ath/ar9170/main.c14
-rw-r--r--drivers/net/wireless/ath/ath5k/ath5k.h257
-rw-r--r--drivers/net/wireless/ath/ath5k/attach.c5
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c167
-rw-r--r--drivers/net/wireless/ath/ath5k/base.h20
-rw-r--r--drivers/net/wireless/ath/ath5k/caps.c3
-rw-r--r--drivers/net/wireless/ath/ath5k/debug.c212
-rw-r--r--drivers/net/wireless/ath/ath5k/debug.h2
-rw-r--r--drivers/net/wireless/ath/ath5k/desc.c18
-rw-r--r--drivers/net/wireless/ath/ath5k/eeprom.c4
-rw-r--r--drivers/net/wireless/ath/ath5k/eeprom.h88
-rw-r--r--drivers/net/wireless/ath/ath5k/pcu.c306
-rw-r--r--drivers/net/wireless/ath/ath5k/phy.c38
-rw-r--r--drivers/net/wireless/ath/ath5k/qcu.c17
-rw-r--r--drivers/net/wireless/ath/ath5k/reg.h2
-rw-r--r--drivers/net/wireless/ath/ath5k/reset.c38
-rw-r--r--drivers/net/wireless/ath/ath9k/Kconfig21
-rw-r--r--drivers/net/wireless/ath/ath9k/Makefile10
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.c25
-rw-r--r--drivers/net/wireless/ath/ath9k/common.c421
-rw-r--r--drivers/net/wireless/ath/ath9k/common.h17
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.c993
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.h105
-rw-r--r--drivers/net/wireless/ath/ath9k/htc.h441
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_beacon.c260
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_init.c713
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c1626
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_txrx.c604
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_hst.c463
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_hst.h246
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c150
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h9
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/initvals.h141
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.h26
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.h5
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h3
-rw-r--r--drivers/net/wireless/ath/ath9k/wmi.c319
-rw-r--r--drivers/net/wireless/ath/ath9k/wmi.h126
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c4
-rw-r--r--drivers/net/wireless/ath/debug.h1
44 files changed, 7198 insertions, 743 deletions
diff --git a/drivers/net/wireless/ath/Kconfig b/drivers/net/wireless/ath/Kconfig
index 4e7a7fd695c..0a75be027af 100644
--- a/drivers/net/wireless/ath/Kconfig
+++ b/drivers/net/wireless/ath/Kconfig
@@ -3,7 +3,7 @@ menuconfig ATH_COMMON
3 depends on CFG80211 3 depends on CFG80211
4 ---help--- 4 ---help---
5 This will enable the support for the Atheros wireless drivers. 5 This will enable the support for the Atheros wireless drivers.
6 ath5k, ath9k and ar9170 drivers share some common code, this option 6 ath5k, ath9k, ath9k_htc and ar9170 drivers share some common code, this option
7 enables the common ath.ko module which shares common helpers. 7 enables the common ath.ko module which shares common helpers.
8 8
9 For more information and documentation on this module you can visit: 9 For more information and documentation on this module you can visit:
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c
index c5369298099..7c4a7d84535 100644
--- a/drivers/net/wireless/ath/ar9170/main.c
+++ b/drivers/net/wireless/ath/ar9170/main.c
@@ -2046,21 +2046,17 @@ out:
2046 return err; 2046 return err;
2047} 2047}
2048 2048
2049static u64 ar9170_op_prepare_multicast(struct ieee80211_hw *hw, int mc_count, 2049static u64 ar9170_op_prepare_multicast(struct ieee80211_hw *hw,
2050 struct dev_addr_list *mclist) 2050 struct netdev_hw_addr_list *mc_list)
2051{ 2051{
2052 u64 mchash; 2052 u64 mchash;
2053 int i; 2053 struct netdev_hw_addr *ha;
2054 2054
2055 /* always get broadcast frames */ 2055 /* always get broadcast frames */
2056 mchash = 1ULL << (0xff >> 2); 2056 mchash = 1ULL << (0xff >> 2);
2057 2057
2058 for (i = 0; i < mc_count; i++) { 2058 netdev_hw_addr_list_for_each(ha, mc_list)
2059 if (WARN_ON(!mclist)) 2059 mchash |= 1ULL << (ha->addr[5] >> 2);
2060 break;
2061 mchash |= 1ULL << (mclist->dmi_addr[5] >> 2);
2062 mclist = mclist->next;
2063 }
2064 2060
2065 return mchash; 2061 return mchash;
2066} 2062}
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index ac67f02e26d..1d7491c8546 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 */
624struct 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 */
1030struct ath5k_hw { 1007struct 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 */
1161extern int ath5k_hw_attach(struct ath5k_softc *sc); 1133int ath5k_hw_attach(struct ath5k_softc *sc);
1162extern void ath5k_hw_detach(struct ath5k_hw *ah); 1134void ath5k_hw_detach(struct ath5k_hw *ah);
1163 1135
1164/* LED functions */ 1136/* LED functions */
1165extern int ath5k_init_leds(struct ath5k_softc *sc); 1137int ath5k_init_leds(struct ath5k_softc *sc);
1166extern void ath5k_led_enable(struct ath5k_softc *sc); 1138void ath5k_led_enable(struct ath5k_softc *sc);
1167extern void ath5k_led_off(struct ath5k_softc *sc); 1139void ath5k_led_off(struct ath5k_softc *sc);
1168extern void ath5k_unregister_leds(struct ath5k_softc *sc); 1140void ath5k_unregister_leds(struct ath5k_softc *sc);
1169 1141
1170/* Reset Functions */ 1142/* Reset Functions */
1171extern int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial); 1143int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial);
1172extern int ath5k_hw_on_hold(struct ath5k_hw *ah); 1144int ath5k_hw_on_hold(struct ath5k_hw *ah);
1173extern int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, struct ieee80211_channel *channel, bool change_channel); 1145int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1146 struct ieee80211_channel *channel, bool change_channel);
1147int 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 */
1175extern 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 */
1178extern void ath5k_hw_start_rx_dma(struct ath5k_hw *ah); 1152void ath5k_hw_start_rx_dma(struct ath5k_hw *ah);
1179extern int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah); 1153int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah);
1180extern u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah); 1154u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah);
1181extern void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr); 1155void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr);
1182extern int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue); 1156int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue);
1183extern int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue); 1157int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue);
1184extern u32 ath5k_hw_get_txdp(struct ath5k_hw *ah, unsigned int queue); 1158u32 ath5k_hw_get_txdp(struct ath5k_hw *ah, unsigned int queue);
1185extern int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue, 1159int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue,
1186 u32 phys_addr); 1160 u32 phys_addr);
1187extern int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase); 1161int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase);
1188/* Interrupt handling */ 1162/* Interrupt handling */
1189extern bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah); 1163bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah);
1190extern int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask); 1164int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask);
1191extern enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum 1165enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask);
1192ath5k_int new_mask); 1166void ath5k_hw_update_mib_counters(struct ath5k_hw *ah,
1193extern 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 */
1196extern int ath5k_eeprom_init(struct ath5k_hw *ah); 1170int ath5k_eeprom_init(struct ath5k_hw *ah);
1197extern void ath5k_eeprom_detach(struct ath5k_hw *ah); 1171void ath5k_eeprom_detach(struct ath5k_hw *ah);
1198extern int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac); 1172int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac);
1199extern bool ath5k_eeprom_is_hb63(struct ath5k_hw *ah);
1200 1173
1201/* Protocol Control Unit Functions */ 1174/* Protocol Control Unit Functions */
1202extern int ath5k_hw_set_opmode(struct ath5k_hw *ah); 1175extern int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode);
1203extern void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class); 1176void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class);
1204/* BSSID Functions */ 1177/* BSSID Functions */
1205extern int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac); 1178int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac);
1206extern void ath5k_hw_set_associd(struct ath5k_hw *ah); 1179void ath5k_hw_set_associd(struct ath5k_hw *ah);
1207extern void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask); 1180void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask);
1208/* Receive start/stop functions */ 1181/* Receive start/stop functions */
1209extern void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah); 1182void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah);
1210extern void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah); 1183void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah);
1211/* RX Filter functions */ 1184/* RX Filter functions */
1212extern void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1); 1185void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1);
1213extern int ath5k_hw_set_mcast_filter_idx(struct ath5k_hw *ah, u32 index); 1186u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah);
1214extern int ath5k_hw_clear_mcast_filter_idx(struct ath5k_hw *ah, u32 index); 1187void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter);
1215extern u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah);
1216extern void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter);
1217/* Beacon control functions */ 1188/* Beacon control functions */
1218extern u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah); 1189u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah);
1219extern u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah); 1190void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64);
1220extern void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64); 1191void ath5k_hw_reset_tsf(struct ath5k_hw *ah);
1221extern void ath5k_hw_reset_tsf(struct ath5k_hw *ah); 1192void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval);
1222extern void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval);
1223#if 0
1224extern int ath5k_hw_set_beacon_timers(struct ath5k_hw *ah, const struct ath5k_beacon_state *state);
1225extern void ath5k_hw_reset_beacon(struct ath5k_hw *ah);
1226extern int ath5k_hw_beaconq_finish(struct ath5k_hw *ah, unsigned long phys_addr);
1227#endif
1228/* ACK bit rate */ 1193/* ACK bit rate */
1229void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high); 1194void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high);
1230/* ACK/CTS Timeouts */
1231extern int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout);
1232extern unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah);
1233extern int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout);
1234extern unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah);
1235/* Clock rate related functions */ 1195/* Clock rate related functions */
1236unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec); 1196unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec);
1237unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock); 1197unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock);
1238unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah); 1198unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah);
1239/* Key table (WEP) functions */ 1199/* Key table (WEP) functions */
1240extern int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry); 1200int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry);
1241extern int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry); 1201int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry,
1242extern 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);
1243extern int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac); 1203int 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 */
1246extern int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue, struct ath5k_txq_info *queue_info); 1206int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,
1247extern 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); 1208int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue,
1249extern 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, 1210int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah,
1251 struct ath5k_txq_info *queue_info); 1211 enum ath5k_tx_queue queue_type,
1252extern u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue); 1212 struct ath5k_txq_info *queue_info);
1253extern void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue); 1213u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue);
1254extern int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue); 1214void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue);
1255extern unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah); 1215int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue);
1256extern int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time); 1216int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time);
1257 1217
1258/* Hardware Descriptor Functions */ 1218/* Hardware Descriptor Functions */
1259extern int ath5k_hw_init_desc_functions(struct ath5k_hw *ah); 1219int ath5k_hw_init_desc_functions(struct ath5k_hw *ah);
1260 1220
1261/* GPIO Functions */ 1221/* GPIO Functions */
1262extern void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state); 1222void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state);
1263extern int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio); 1223int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio);
1264extern int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio); 1224int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio);
1265extern u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio); 1225u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio);
1266extern int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val); 1226int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val);
1267extern void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, u32 interrupt_level); 1227void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio,
1228 u32 interrupt_level);
1268 1229
1269/* rfkill Functions */ 1230/* rfkill Functions */
1270extern void ath5k_rfkill_hw_start(struct ath5k_hw *ah); 1231void ath5k_rfkill_hw_start(struct ath5k_hw *ah);
1271extern void ath5k_rfkill_hw_stop(struct ath5k_hw *ah); 1232void ath5k_rfkill_hw_stop(struct ath5k_hw *ah);
1272 1233
1273/* Misc functions */ 1234/* Misc functions */
1274int ath5k_hw_set_capabilities(struct ath5k_hw *ah); 1235int ath5k_hw_set_capabilities(struct ath5k_hw *ah);
1275extern int ath5k_hw_get_capability(struct ath5k_hw *ah, enum ath5k_capability_type cap_type, u32 capability, u32 *result); 1236int ath5k_hw_get_capability(struct ath5k_hw *ah,
1276extern int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid, u16 assoc_id); 1237 enum ath5k_capability_type cap_type, u32 capability,
1277extern int ath5k_hw_disable_pspoll(struct ath5k_hw *ah); 1238 u32 *result);
1239int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid, u16 assoc_id);
1240int ath5k_hw_disable_pspoll(struct ath5k_hw *ah);
1278 1241
1279/* Initial register settings functions */ 1242/* Initial register settings functions */
1280extern int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel); 1243int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel);
1281 1244
1282/* Initialize RF */ 1245/* Initialize RF */
1283extern int ath5k_hw_rfregs_init(struct ath5k_hw *ah, 1246int 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);
1286extern int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq); 1249int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq);
1287extern enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah); 1250enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah);
1288extern int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah); 1251int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah);
1289/* PHY/RF channel functions */ 1252/* PHY/RF channel functions */
1290extern bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags); 1253bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags);
1291extern int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel); 1254int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel);
1292/* PHY calibration */ 1255/* PHY calibration */
1293void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah); 1256void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah);
1294extern int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, struct ieee80211_channel *channel); 1257int ath5k_hw_phy_calibrate(struct ath5k_hw *ah,
1295extern int ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq); 1258 struct ieee80211_channel *channel);
1296extern s16 ath5k_hw_get_noise_floor(struct ath5k_hw *ah); 1259void ath5k_hw_calibration_poll(struct ath5k_hw *ah);
1297extern void ath5k_hw_calibration_poll(struct ath5k_hw *ah);
1298/* Spur mitigation */ 1260/* Spur mitigation */
1299bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah, 1261bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
1300 struct ieee80211_channel *channel); 1262 struct ieee80211_channel *channel);
1301void ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah, 1263void 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 */
1304extern u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan); 1266u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan);
1305extern int ath5k_hw_phy_disable(struct ath5k_hw *ah); 1267int ath5k_hw_phy_disable(struct ath5k_hw *ah);
1306/* Antenna control */ 1268/* Antenna control */
1307extern void ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode); 1269void ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode);
1308extern void ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant);
1309extern unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah);
1310/* TX power setup */ 1270/* TX power setup */
1311extern int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, u8 ee_mode, u8 txpower); 1271int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
1312extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower); 1272 u8 ee_mode, u8 txpower);
1273int 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 */
1342static 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
1361static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits) 1299static 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
1373static 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 dc0786cc263..f571ad1a225 100644
--- a/drivers/net/wireless/ath/ath5k/attach.c
+++ b/drivers/net/wireless/ath/ath5k/attach.c
@@ -114,7 +114,6 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
114 /* 114 /*
115 * HW information 115 * HW information
116 */ 116 */
117 ah->ah_op_mode = NL80211_IFTYPE_STATION;
118 ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT; 117 ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT;
119 ah->ah_turbo = false; 118 ah->ah_turbo = false;
120 ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER; 119 ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
@@ -124,6 +123,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
124 ah->ah_cw_min = AR5K_TUNE_CWMIN; 123 ah->ah_cw_min = AR5K_TUNE_CWMIN;
125 ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY; 124 ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY;
126 ah->ah_software_retry = false; 125 ah->ah_software_retry = false;
126 ah->ah_ant_mode = AR5K_ANTMODE_DEFAULT;
127 127
128 /* 128 /*
129 * Find the mac version 129 * Find the mac version
@@ -149,7 +149,6 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
149 /* Get MAC, PHY and RADIO revisions */ 149 /* Get MAC, PHY and RADIO revisions */
150 ah->ah_mac_srev = srev; 150 ah->ah_mac_srev = srev;
151 ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER); 151 ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER);
152 ah->ah_mac_revision = AR5K_REG_MS(srev, AR5K_SREV_REV);
153 ah->ah_phy_revision = ath5k_hw_reg_read(ah, AR5K_PHY_CHIP_ID) & 152 ah->ah_phy_revision = ath5k_hw_reg_read(ah, AR5K_PHY_CHIP_ID) &
154 0xffffffff; 153 0xffffffff;
155 ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah, 154 ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah,
@@ -328,7 +327,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
328 /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */ 327 /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */
329 memcpy(common->curbssid, ath_bcast_mac, ETH_ALEN); 328 memcpy(common->curbssid, ath_bcast_mac, ETH_ALEN);
330 ath5k_hw_set_associd(ah); 329 ath5k_hw_set_associd(ah);
331 ath5k_hw_set_opmode(ah); 330 ath5k_hw_set_opmode(ah, sc->opmode);
332 331
333 ath5k_hw_rfgain_opt_init(ah); 332 ath5k_hw_rfgain_opt_init(ah);
334 333
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 3abbe7513ab..7ac3a720e52 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -199,7 +199,7 @@ static void __devexit ath5k_pci_remove(struct pci_dev *pdev);
199static int ath5k_pci_suspend(struct device *dev); 199static int ath5k_pci_suspend(struct device *dev);
200static int ath5k_pci_resume(struct device *dev); 200static int ath5k_pci_resume(struct device *dev);
201 201
202SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume); 202static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume);
203#define ATH5K_PM_OPS (&ath5k_pm_ops) 203#define ATH5K_PM_OPS (&ath5k_pm_ops)
204#else 204#else
205#define ATH5K_PM_OPS NULL 205#define ATH5K_PM_OPS NULL
@@ -231,7 +231,7 @@ static void ath5k_remove_interface(struct ieee80211_hw *hw,
231 struct ieee80211_vif *vif); 231 struct ieee80211_vif *vif);
232static int ath5k_config(struct ieee80211_hw *hw, u32 changed); 232static int ath5k_config(struct ieee80211_hw *hw, u32 changed);
233static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw, 233static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw,
234 int mc_count, struct dev_addr_list *mc_list); 234 struct netdev_hw_addr_list *mc_list);
235static void ath5k_configure_filter(struct ieee80211_hw *hw, 235static void ath5k_configure_filter(struct ieee80211_hw *hw,
236 unsigned int changed_flags, 236 unsigned int changed_flags,
237 unsigned int *new_flags, 237 unsigned int *new_flags,
@@ -308,7 +308,7 @@ static int ath5k_rxbuf_setup(struct ath5k_softc *sc,
308 struct ath5k_buf *bf); 308 struct ath5k_buf *bf);
309static int ath5k_txbuf_setup(struct ath5k_softc *sc, 309static int ath5k_txbuf_setup(struct ath5k_softc *sc,
310 struct ath5k_buf *bf, 310 struct ath5k_buf *bf,
311 struct ath5k_txq *txq); 311 struct ath5k_txq *txq, int padsize);
312static inline void ath5k_txbuf_free(struct ath5k_softc *sc, 312static inline void ath5k_txbuf_free(struct ath5k_softc *sc,
313 struct ath5k_buf *bf) 313 struct ath5k_buf *bf)
314{ 314{
@@ -1138,8 +1138,6 @@ ath5k_mode_setup(struct ath5k_softc *sc)
1138 struct ath5k_hw *ah = sc->ah; 1138 struct ath5k_hw *ah = sc->ah;
1139 u32 rfilt; 1139 u32 rfilt;
1140 1140
1141 ah->ah_op_mode = sc->opmode;
1142
1143 /* configure rx filter */ 1141 /* configure rx filter */
1144 rfilt = sc->filter_flags; 1142 rfilt = sc->filter_flags;
1145 ath5k_hw_set_rx_filter(ah, rfilt); 1143 ath5k_hw_set_rx_filter(ah, rfilt);
@@ -1148,8 +1146,9 @@ ath5k_mode_setup(struct ath5k_softc *sc)
1148 ath5k_hw_set_bssid_mask(ah, sc->bssidmask); 1146 ath5k_hw_set_bssid_mask(ah, sc->bssidmask);
1149 1147
1150 /* configure operational mode */ 1148 /* configure operational mode */
1151 ath5k_hw_set_opmode(ah); 1149 ath5k_hw_set_opmode(ah, sc->opmode);
1152 1150
1151 ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "mode setup opmode %d\n", sc->opmode);
1153 ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt); 1152 ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt);
1154} 1153}
1155 1154
@@ -1272,7 +1271,7 @@ static enum ath5k_pkt_type get_hw_packet_type(struct sk_buff *skb)
1272 1271
1273static int 1272static int
1274ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, 1273ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
1275 struct ath5k_txq *txq) 1274 struct ath5k_txq *txq, int padsize)
1276{ 1275{
1277 struct ath5k_hw *ah = sc->ah; 1276 struct ath5k_hw *ah = sc->ah;
1278 struct ath5k_desc *ds = bf->desc; 1277 struct ath5k_desc *ds = bf->desc;
@@ -1324,7 +1323,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
1324 sc->vif, pktlen, info)); 1323 sc->vif, pktlen, info));
1325 } 1324 }
1326 ret = ah->ah_setup_tx_desc(ah, ds, pktlen, 1325 ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
1327 ieee80211_get_hdrlen_from_skb(skb), 1326 ieee80211_get_hdrlen_from_skb(skb), padsize,
1328 get_hw_packet_type(skb), 1327 get_hw_packet_type(skb),
1329 (sc->power_level * 2), 1328 (sc->power_level * 2),
1330 hw_rate, 1329 hw_rate,
@@ -1806,6 +1805,67 @@ ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb,
1806 } 1805 }
1807} 1806}
1808 1807
1808/*
1809 * Compute padding position. skb must contains an IEEE 802.11 frame
1810 */
1811static int ath5k_common_padpos(struct sk_buff *skb)
1812{
1813 struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data;
1814 __le16 frame_control = hdr->frame_control;
1815 int padpos = 24;
1816
1817 if (ieee80211_has_a4(frame_control)) {
1818 padpos += ETH_ALEN;
1819 }
1820 if (ieee80211_is_data_qos(frame_control)) {
1821 padpos += IEEE80211_QOS_CTL_LEN;
1822 }
1823
1824 return padpos;
1825}
1826
1827/*
1828 * This function expects a 802.11 frame and returns the number of
1829 * bytes added, or -1 if we don't have enought header room.
1830 */
1831
1832static int ath5k_add_padding(struct sk_buff *skb)
1833{
1834 int padpos = ath5k_common_padpos(skb);
1835 int padsize = padpos & 3;
1836
1837 if (padsize && skb->len>padpos) {
1838
1839 if (skb_headroom(skb) < padsize)
1840 return -1;
1841
1842 skb_push(skb, padsize);
1843 memmove(skb->data, skb->data+padsize, padpos);
1844 return padsize;
1845 }
1846
1847 return 0;
1848}
1849
1850/*
1851 * This function expects a 802.11 frame and returns the number of
1852 * bytes removed
1853 */
1854
1855static int ath5k_remove_padding(struct sk_buff *skb)
1856{
1857 int padpos = ath5k_common_padpos(skb);
1858 int padsize = padpos & 3;
1859
1860 if (padsize && skb->len>=padpos+padsize) {
1861 memmove(skb->data + padsize, skb->data, padpos);
1862 skb_pull(skb, padsize);
1863 return padsize;
1864 }
1865
1866 return 0;
1867}
1868
1809static void 1869static void
1810ath5k_tasklet_rx(unsigned long data) 1870ath5k_tasklet_rx(unsigned long data)
1811{ 1871{
@@ -1819,8 +1879,6 @@ ath5k_tasklet_rx(unsigned long data)
1819 struct ath5k_buf *bf; 1879 struct ath5k_buf *bf;
1820 struct ath5k_desc *ds; 1880 struct ath5k_desc *ds;
1821 int ret; 1881 int ret;
1822 int hdrlen;
1823 int padsize;
1824 int rx_flag; 1882 int rx_flag;
1825 1883
1826 spin_lock(&sc->rxbuflock); 1884 spin_lock(&sc->rxbuflock);
@@ -1845,18 +1903,28 @@ ath5k_tasklet_rx(unsigned long data)
1845 break; 1903 break;
1846 else if (unlikely(ret)) { 1904 else if (unlikely(ret)) {
1847 ATH5K_ERR(sc, "error in processing rx descriptor\n"); 1905 ATH5K_ERR(sc, "error in processing rx descriptor\n");
1906 sc->stats.rxerr_proc++;
1848 spin_unlock(&sc->rxbuflock); 1907 spin_unlock(&sc->rxbuflock);
1849 return; 1908 return;
1850 } 1909 }
1851 1910
1911 sc->stats.rx_all_count++;
1912
1852 if (unlikely(rs.rs_more)) { 1913 if (unlikely(rs.rs_more)) {
1853 ATH5K_WARN(sc, "unsupported jumbo\n"); 1914 ATH5K_WARN(sc, "unsupported jumbo\n");
1915 sc->stats.rxerr_jumbo++;
1854 goto next; 1916 goto next;
1855 } 1917 }
1856 1918
1857 if (unlikely(rs.rs_status)) { 1919 if (unlikely(rs.rs_status)) {
1858 if (rs.rs_status & AR5K_RXERR_PHY) 1920 if (rs.rs_status & AR5K_RXERR_CRC)
1921 sc->stats.rxerr_crc++;
1922 if (rs.rs_status & AR5K_RXERR_FIFO)
1923 sc->stats.rxerr_fifo++;
1924 if (rs.rs_status & AR5K_RXERR_PHY) {
1925 sc->stats.rxerr_phy++;
1859 goto next; 1926 goto next;
1927 }
1860 if (rs.rs_status & AR5K_RXERR_DECRYPT) { 1928 if (rs.rs_status & AR5K_RXERR_DECRYPT) {
1861 /* 1929 /*
1862 * Decrypt error. If the error occurred 1930 * Decrypt error. If the error occurred
@@ -1868,12 +1936,14 @@ ath5k_tasklet_rx(unsigned long data)
1868 * 1936 *
1869 * XXX do key cache faulting 1937 * XXX do key cache faulting
1870 */ 1938 */
1939 sc->stats.rxerr_decrypt++;
1871 if (rs.rs_keyix == AR5K_RXKEYIX_INVALID && 1940 if (rs.rs_keyix == AR5K_RXKEYIX_INVALID &&
1872 !(rs.rs_status & AR5K_RXERR_CRC)) 1941 !(rs.rs_status & AR5K_RXERR_CRC))
1873 goto accept; 1942 goto accept;
1874 } 1943 }
1875 if (rs.rs_status & AR5K_RXERR_MIC) { 1944 if (rs.rs_status & AR5K_RXERR_MIC) {
1876 rx_flag |= RX_FLAG_MMIC_ERROR; 1945 rx_flag |= RX_FLAG_MMIC_ERROR;
1946 sc->stats.rxerr_mic++;
1877 goto accept; 1947 goto accept;
1878 } 1948 }
1879 1949
@@ -1905,12 +1975,8 @@ accept:
1905 * bytes and we can optimize this a bit. In addition, we must 1975 * bytes and we can optimize this a bit. In addition, we must
1906 * not try to remove padding from short control frames that do 1976 * not try to remove padding from short control frames that do
1907 * not have payload. */ 1977 * not have payload. */
1908 hdrlen = ieee80211_get_hdrlen_from_skb(skb); 1978 ath5k_remove_padding(skb);
1909 padsize = ath5k_pad_size(hdrlen); 1979
1910 if (padsize) {
1911 memmove(skb->data + padsize, skb->data, hdrlen);
1912 skb_pull(skb, padsize);
1913 }
1914 rxs = IEEE80211_SKB_RXCB(skb); 1980 rxs = IEEE80211_SKB_RXCB(skb);
1915 1981
1916 /* 1982 /*
@@ -1943,6 +2009,12 @@ accept:
1943 rxs->signal = rxs->noise + rs.rs_rssi; 2009 rxs->signal = rxs->noise + rs.rs_rssi;
1944 2010
1945 rxs->antenna = rs.rs_antenna; 2011 rxs->antenna = rs.rs_antenna;
2012
2013 if (rs.rs_antenna > 0 && rs.rs_antenna < 5)
2014 sc->stats.antenna_rx[rs.rs_antenna]++;
2015 else
2016 sc->stats.antenna_rx[0]++; /* invalid */
2017
1946 rxs->rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate); 2018 rxs->rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate);
1947 rxs->flag |= ath5k_rx_decrypted(sc, ds, skb, &rs); 2019 rxs->flag |= ath5k_rx_decrypted(sc, ds, skb, &rs);
1948 2020
@@ -1997,6 +2069,7 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
1997 break; 2069 break;
1998 } 2070 }
1999 2071
2072 sc->stats.tx_all_count++;
2000 skb = bf->skb; 2073 skb = bf->skb;
2001 info = IEEE80211_SKB_CB(skb); 2074 info = IEEE80211_SKB_CB(skb);
2002 bf->skb = NULL; 2075 bf->skb = NULL;
@@ -2023,13 +2096,30 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
2023 2096
2024 if (unlikely(ts.ts_status)) { 2097 if (unlikely(ts.ts_status)) {
2025 sc->ll_stats.dot11ACKFailureCount++; 2098 sc->ll_stats.dot11ACKFailureCount++;
2026 if (ts.ts_status & AR5K_TXERR_FILT) 2099 if (ts.ts_status & AR5K_TXERR_FILT) {
2027 info->flags |= IEEE80211_TX_STAT_TX_FILTERED; 2100 info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
2101 sc->stats.txerr_filt++;
2102 }
2103 if (ts.ts_status & AR5K_TXERR_XRETRY)
2104 sc->stats.txerr_retry++;
2105 if (ts.ts_status & AR5K_TXERR_FIFO)
2106 sc->stats.txerr_fifo++;
2028 } else { 2107 } else {
2029 info->flags |= IEEE80211_TX_STAT_ACK; 2108 info->flags |= IEEE80211_TX_STAT_ACK;
2030 info->status.ack_signal = ts.ts_rssi; 2109 info->status.ack_signal = ts.ts_rssi;
2031 } 2110 }
2032 2111
2112 /*
2113 * Remove MAC header padding before giving the frame
2114 * back to mac80211.
2115 */
2116 ath5k_remove_padding(skb);
2117
2118 if (ts.ts_antenna > 0 && ts.ts_antenna < 5)
2119 sc->stats.antenna_tx[ts.ts_antenna]++;
2120 else
2121 sc->stats.antenna_tx[0]++; /* invalid */
2122
2033 ieee80211_tx_status(sc->hw, skb); 2123 ieee80211_tx_status(sc->hw, skb);
2034 2124
2035 spin_lock(&sc->txbuflock); 2125 spin_lock(&sc->txbuflock);
@@ -2073,6 +2163,7 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
2073 int ret = 0; 2163 int ret = 0;
2074 u8 antenna; 2164 u8 antenna;
2075 u32 flags; 2165 u32 flags;
2166 const int padsize = 0;
2076 2167
2077 bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len, 2168 bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len,
2078 PCI_DMA_TODEVICE); 2169 PCI_DMA_TODEVICE);
@@ -2120,7 +2211,7 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
2120 * from tx power (value is in dB units already) */ 2211 * from tx power (value is in dB units already) */
2121 ds->ds_data = bf->skbaddr; 2212 ds->ds_data = bf->skbaddr;
2122 ret = ah->ah_setup_tx_desc(ah, ds, skb->len, 2213 ret = ah->ah_setup_tx_desc(ah, ds, skb->len,
2123 ieee80211_get_hdrlen_from_skb(skb), 2214 ieee80211_get_hdrlen_from_skb(skb), padsize,
2124 AR5K_PKT_TYPE_BEACON, (sc->power_level * 2), 2215 AR5K_PKT_TYPE_BEACON, (sc->power_level * 2),
2125 ieee80211_get_tx_rate(sc->hw, info)->hw_value, 2216 ieee80211_get_tx_rate(sc->hw, info)->hw_value,
2126 1, AR5K_TXKEYIX_INVALID, 2217 1, AR5K_TXKEYIX_INVALID,
@@ -2680,7 +2771,6 @@ static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
2680 struct ath5k_softc *sc = hw->priv; 2771 struct ath5k_softc *sc = hw->priv;
2681 struct ath5k_buf *bf; 2772 struct ath5k_buf *bf;
2682 unsigned long flags; 2773 unsigned long flags;
2683 int hdrlen;
2684 int padsize; 2774 int padsize;
2685 2775
2686 ath5k_debug_dump_skb(sc, skb, "TX ", 1); 2776 ath5k_debug_dump_skb(sc, skb, "TX ", 1);
@@ -2692,17 +2782,11 @@ static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
2692 * the hardware expects the header padded to 4 byte boundaries 2782 * the hardware expects the header padded to 4 byte boundaries
2693 * if this is not the case we add the padding after the header 2783 * if this is not the case we add the padding after the header
2694 */ 2784 */
2695 hdrlen = ieee80211_get_hdrlen_from_skb(skb); 2785 padsize = ath5k_add_padding(skb);
2696 padsize = ath5k_pad_size(hdrlen); 2786 if (padsize < 0) {
2697 if (padsize) { 2787 ATH5K_ERR(sc, "tx hdrlen not %%4: not enough"
2698 2788 " headroom to pad");
2699 if (skb_headroom(skb) < padsize) { 2789 goto drop_packet;
2700 ATH5K_ERR(sc, "tx hdrlen not %%4: %d not enough"
2701 " headroom to pad %d\n", hdrlen, padsize);
2702 goto drop_packet;
2703 }
2704 skb_push(skb, padsize);
2705 memmove(skb->data, skb->data+padsize, hdrlen);
2706 } 2790 }
2707 2791
2708 spin_lock_irqsave(&sc->txbuflock, flags); 2792 spin_lock_irqsave(&sc->txbuflock, flags);
@@ -2721,7 +2805,7 @@ static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
2721 2805
2722 bf->skb = skb; 2806 bf->skb = skb;
2723 2807
2724 if (ath5k_txbuf_setup(sc, bf, txq)) { 2808 if (ath5k_txbuf_setup(sc, bf, txq, padsize)) {
2725 bf->skb = NULL; 2809 bf->skb = NULL;
2726 spin_lock_irqsave(&sc->txbuflock, flags); 2810 spin_lock_irqsave(&sc->txbuflock, flags);
2727 list_add_tail(&bf->list, &sc->txbuf); 2811 list_add_tail(&bf->list, &sc->txbuf);
@@ -2836,6 +2920,8 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
2836 goto end; 2920 goto end;
2837 } 2921 }
2838 2922
2923 ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "add interface mode %d\n", sc->opmode);
2924
2839 ath5k_hw_set_lladdr(sc->ah, vif->addr); 2925 ath5k_hw_set_lladdr(sc->ah, vif->addr);
2840 ath5k_mode_setup(sc); 2926 ath5k_mode_setup(sc);
2841 2927
@@ -2906,7 +2992,7 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed)
2906 * then we must allow the user to set how many tx antennas we 2992 * then we must allow the user to set how many tx antennas we
2907 * have available 2993 * have available
2908 */ 2994 */
2909 ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_DEFAULT); 2995 ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode);
2910 2996
2911unlock: 2997unlock:
2912 mutex_unlock(&sc->lock); 2998 mutex_unlock(&sc->lock);
@@ -2914,22 +3000,20 @@ unlock:
2914} 3000}
2915 3001
2916static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw, 3002static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw,
2917 int mc_count, struct dev_addr_list *mclist) 3003 struct netdev_hw_addr_list *mc_list)
2918{ 3004{
2919 u32 mfilt[2], val; 3005 u32 mfilt[2], val;
2920 int i;
2921 u8 pos; 3006 u8 pos;
3007 struct netdev_hw_addr *ha;
2922 3008
2923 mfilt[0] = 0; 3009 mfilt[0] = 0;
2924 mfilt[1] = 1; 3010 mfilt[1] = 1;
2925 3011
2926 for (i = 0; i < mc_count; i++) { 3012 netdev_hw_addr_list_for_each(ha, mc_list) {
2927 if (!mclist)
2928 break;
2929 /* calculate XOR of eight 6-bit values */ 3013 /* calculate XOR of eight 6-bit values */
2930 val = get_unaligned_le32(mclist->dmi_addr + 0); 3014 val = get_unaligned_le32(ha->addr + 0);
2931 pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val; 3015 pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
2932 val = get_unaligned_le32(mclist->dmi_addr + 3); 3016 val = get_unaligned_le32(ha->addr + 3);
2933 pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val; 3017 pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
2934 pos &= 0x3f; 3018 pos &= 0x3f;
2935 mfilt[pos / 32] |= (1 << (pos % 32)); 3019 mfilt[pos / 32] |= (1 << (pos % 32));
@@ -2937,8 +3021,7 @@ static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw,
2937 * but not sure, needs testing, if we do use this we'd 3021 * but not sure, needs testing, if we do use this we'd
2938 * neet to inform below to not reset the mcast */ 3022 * neet to inform below to not reset the mcast */
2939 /* ath5k_hw_set_mcast_filterindex(ah, 3023 /* ath5k_hw_set_mcast_filterindex(ah,
2940 * mclist->dmi_addr[5]); */ 3024 * ha->addr[5]); */
2941 mclist = mclist->next;
2942 } 3025 }
2943 3026
2944 return ((u64)(mfilt[1]) << 32) | mfilt[0]; 3027 return ((u64)(mfilt[1]) << 32) | mfilt[0];
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h
index 7e1a88a5abd..33f1d8b87ee 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) */
109struct 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 367a6c7d3cc..e618e71b1ce 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 747508c15d3..bccd4a78027 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
369static 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
430static 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
460static 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
470static 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
531static 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
560static 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
369void 570void
@@ -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
398void 608void
@@ -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 66f69f04e55..da24ff52e27 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 dc30a2b70a6..9d920fb14d5 100644
--- a/drivers/net/wireless/ath/ath5k/desc.c
+++ b/drivers/net/wireless/ath/ath5k/desc.c
@@ -35,7 +35,8 @@
35 */ 35 */
36static int 36static int
37ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, 37ath5k_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 */
166static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, 167static 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 67665cdc7af..ed0263672d6 100644
--- a/drivers/net/wireless/ath/ath5k/eeprom.c
+++ b/drivers/net/wireless/ath/ath5k/eeprom.c
@@ -331,7 +331,8 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,
331 ee->ee_x_gain[mode] = (val >> 1) & 0xf; 331 ee->ee_x_gain[mode] = (val >> 1) & 0xf;
332 ee->ee_xpd[mode] = val & 0x1; 332 ee->ee_xpd[mode] = val & 0x1;
333 333
334 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) 334 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0 &&
335 mode != AR5K_EEPROM_MODE_11B)
335 ee->ee_fixed_bias[mode] = (val >> 13) & 0x1; 336 ee->ee_fixed_bias[mode] = (val >> 13) & 0x1;
336 337
337 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_3) { 338 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_3) {
@@ -341,6 +342,7 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,
341 if (mode == AR5K_EEPROM_MODE_11A) 342 if (mode == AR5K_EEPROM_MODE_11A)
342 ee->ee_xr_power[mode] = val & 0x3f; 343 ee->ee_xr_power[mode] = val & 0x3f;
343 else { 344 else {
345 /* b_DB_11[bg] and b_OB_11[bg] */
344 ee->ee_ob[mode][0] = val & 0x7; 346 ee->ee_ob[mode][0] = val & 0x7;
345 ee->ee_db[mode][0] = (val >> 3) & 0x7; 347 ee->ee_db[mode][0] = (val >> 3) & 0x7;
346 } 348 }
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.h b/drivers/net/wireless/ath/ath5k/eeprom.h
index 473a483bb9c..c4a6d5f26af 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 */
393struct ath5k_eeprom_info { 433struct 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 aefe84f9c04..1b9fcb84216 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 */
47int ath5k_hw_set_opmode(struct ath5k_hw *ah) 46int 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 */
186unsigned 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 */
200int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout) 187static 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 */
218unsigned 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 */
231int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout) 206static 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 */
293unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah) 268static 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 */
311unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah) 286static 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 */
457int 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 */
475int 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 */
581u32 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 */
729int 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 */
856void 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 */
875int 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 */
977int 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
987static 703static
988int ath5k_keycache_type(const struct ieee80211_key_conf *key) 704int 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 68e2bccd90d..3ee74c83976 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#include <linux/slab.h> 24#include <linux/slab.h>
27 25
@@ -1191,7 +1189,7 @@ static s16 ath5k_hw_get_median_noise_floor(struct ath5k_hw *ah)
1191 * The median of the values in the history is then loaded into the 1189 * The median of the values in the history is then loaded into the
1192 * hardware for its own use for RSSI and CCA measurements. 1190 * hardware for its own use for RSSI and CCA measurements.
1193 */ 1191 */
1194void ath5k_hw_update_noise_floor(struct ath5k_hw *ah) 1192static void ath5k_hw_update_noise_floor(struct ath5k_hw *ah)
1195{ 1193{
1196 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 1194 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1197 u32 val; 1195 u32 val;
@@ -1400,7 +1398,11 @@ static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah,
1400 } 1398 }
1401 1399
1402 i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7; 1400 i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7;
1403 q_coffd = q_pwr >> 7; 1401
1402 if (ah->ah_version == AR5K_AR5211)
1403 q_coffd = q_pwr >> 6;
1404 else
1405 q_coffd = q_pwr >> 7;
1404 1406
1405 /* protect against divide by 0 and loss of sign bits */ 1407 /* protect against divide by 0 and loss of sign bits */
1406 if (i_coffd == 0 || q_coffd < 2) 1408 if (i_coffd == 0 || q_coffd < 2)
@@ -1769,7 +1771,7 @@ u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan)
1769* Antenna control * 1771* Antenna control *
1770\*****************/ 1772\*****************/
1771 1773
1772void /*TODO:Boundary check*/ 1774static void /*TODO:Boundary check*/
1773ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant) 1775ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant)
1774{ 1776{
1775 ATH5K_TRACE(ah->ah_sc); 1777 ATH5K_TRACE(ah->ah_sc);
@@ -1778,16 +1780,6 @@ ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant)
1778 ath5k_hw_reg_write(ah, ant & 0x7, AR5K_DEFAULT_ANTENNA); 1780 ath5k_hw_reg_write(ah, ant & 0x7, AR5K_DEFAULT_ANTENNA);
1779} 1781}
1780 1782
1781unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah)
1782{
1783 ATH5K_TRACE(ah->ah_sc);
1784
1785 if (ah->ah_version != AR5K_AR5210)
1786 return ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA) & 0x7;
1787
1788 return false; /*XXX: What do we return for 5210 ?*/
1789}
1790
1791/* 1783/*
1792 * Enable/disable fast rx antenna diversity 1784 * Enable/disable fast rx antenna diversity
1793 */ 1785 */
@@ -1931,6 +1923,7 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)
1931 1923
1932 ah->ah_tx_ant = tx_ant; 1924 ah->ah_tx_ant = tx_ant;
1933 ah->ah_ant_mode = ant_mode; 1925 ah->ah_ant_mode = ant_mode;
1926 ah->ah_def_ant = def_ant;
1934 1927
1935 sta_id1 |= use_def_for_tx ? AR5K_STA_ID1_DEFAULT_ANTENNA : 0; 1928 sta_id1 |= use_def_for_tx ? AR5K_STA_ID1_DEFAULT_ANTENNA : 0;
1936 sta_id1 |= update_def_on_tx ? AR5K_STA_ID1_DESC_ANTENNA : 0; 1929 sta_id1 |= update_def_on_tx ? AR5K_STA_ID1_DESC_ANTENNA : 0;
@@ -2441,19 +2434,6 @@ ath5k_combine_linear_pcdac_curves(struct ath5k_hw *ah, s16* table_min,
2441 pcdac_tmp = pcdac_high_pwr; 2434 pcdac_tmp = pcdac_high_pwr;
2442 2435
2443 edge_flag = 0x40; 2436 edge_flag = 0x40;
2444#if 0
2445 /* If both min and max power limits are in lower
2446 * power curve's range, only use the low power curve.
2447 * TODO: min/max levels are related to target
2448 * power values requested from driver/user
2449 * XXX: Is this really needed ? */
2450 if (min_pwr < table_max[1] &&
2451 max_pwr < table_max[1]) {
2452 edge_flag = 0;
2453 pcdac_tmp = pcdac_low_pwr;
2454 max_pwr_idx = (table_max[1] - table_min[1])/2;
2455 }
2456#endif
2457 } else { 2437 } else {
2458 pcdac_low_pwr = ah->ah_txpower.tmpL[1]; /* Zeroed */ 2438 pcdac_low_pwr = ah->ah_txpower.tmpL[1]; /* Zeroed */
2459 pcdac_high_pwr = ah->ah_txpower.tmpL[0]; 2439 pcdac_high_pwr = ah->ah_txpower.tmpL[0];
@@ -3144,5 +3124,3 @@ int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower)
3144 3124
3145 return ath5k_hw_txpower(ah, channel, ee_mode, txpower); 3125 return ath5k_hw_txpower(ah, channel, ee_mode, txpower);
3146} 3126}
3147
3148#undef _ATH5K_PHY
diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c
index 9122a8556f4..f5831da33f7 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 */
522unsigned 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 */
539int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time) 522int 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 1464f89b249..47f04932ab8 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 cbf28e37984..44bbbf2a6ed 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 */
38int 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 */
224int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, 243static 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/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig
index 5774cea23a3..35f23bdc442 100644
--- a/drivers/net/wireless/ath/ath9k/Kconfig
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
@@ -32,3 +32,24 @@ config ATH9K_DEBUGFS
32 32
33 Also required for changing debug message flags at run time. 33 Also required for changing debug message flags at run time.
34 34
35config ATH9K_HTC
36 tristate "Atheros HTC based wireless cards support"
37 depends on USB && MAC80211
38 select ATH9K_HW
39 select MAC80211_LEDS
40 select LEDS_CLASS
41 select NEW_LEDS
42 select ATH9K_COMMON
43 ---help---
44 Support for Atheros HTC based cards.
45 Chipsets supported: AR9271
46
47 For more information: http://wireless.kernel.org/en/users/Drivers/ath9k_htc
48
49 The built module will be ath9k_htc.
50
51config ATH9K_HTC_DEBUGFS
52 bool "Atheros ath9k_htc debugging"
53 depends on ATH9K_HTC && DEBUG_FS
54 ---help---
55 Say Y, if you need access to ath9k_htc's statistics.
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index 6b50d5eb9ec..97133beda26 100644
--- a/drivers/net/wireless/ath/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -28,3 +28,13 @@ obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o
28 28
29obj-$(CONFIG_ATH9K_COMMON) += ath9k_common.o 29obj-$(CONFIG_ATH9K_COMMON) += ath9k_common.o
30ath9k_common-y:= common.o 30ath9k_common-y:= common.o
31
32ath9k_htc-y += htc_hst.o \
33 hif_usb.o \
34 wmi.o \
35 htc_drv_txrx.o \
36 htc_drv_main.o \
37 htc_drv_beacon.o \
38 htc_drv_init.o
39
40obj-$(CONFIG_ATH9K_HTC) += ath9k_htc.o
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index 238a5744d8e..d5026e4f484 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -101,9 +101,13 @@ static void ath9k_hw_do_getnf(struct ath_hw *ah,
101 nf = 0 - ((nf ^ 0x1ff) + 1); 101 nf = 0 - ((nf ^ 0x1ff) + 1);
102 ath_print(common, ATH_DBG_CALIBRATE, 102 ath_print(common, ATH_DBG_CALIBRATE,
103 "NF calibrated [ctl] [chain 0] is %d\n", nf); 103 "NF calibrated [ctl] [chain 0] is %d\n", nf);
104
105 if (AR_SREV_9271(ah) && (nf >= -114))
106 nf = -116;
107
104 nfarray[0] = nf; 108 nfarray[0] = nf;
105 109
106 if (!AR_SREV_9285(ah)) { 110 if (!AR_SREV_9285(ah) && !AR_SREV_9271(ah)) {
107 if (AR_SREV_9280_10_OR_LATER(ah)) 111 if (AR_SREV_9280_10_OR_LATER(ah))
108 nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), 112 nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
109 AR9280_PHY_CH1_MINCCA_PWR); 113 AR9280_PHY_CH1_MINCCA_PWR);
@@ -139,9 +143,13 @@ static void ath9k_hw_do_getnf(struct ath_hw *ah,
139 nf = 0 - ((nf ^ 0x1ff) + 1); 143 nf = 0 - ((nf ^ 0x1ff) + 1);
140 ath_print(common, ATH_DBG_CALIBRATE, 144 ath_print(common, ATH_DBG_CALIBRATE,
141 "NF calibrated [ext] [chain 0] is %d\n", nf); 145 "NF calibrated [ext] [chain 0] is %d\n", nf);
146
147 if (AR_SREV_9271(ah) && (nf >= -114))
148 nf = -116;
149
142 nfarray[3] = nf; 150 nfarray[3] = nf;
143 151
144 if (!AR_SREV_9285(ah)) { 152 if (!AR_SREV_9285(ah) && !AR_SREV_9271(ah)) {
145 if (AR_SREV_9280_10_OR_LATER(ah)) 153 if (AR_SREV_9280_10_OR_LATER(ah))
146 nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), 154 nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
147 AR9280_PHY_CH1_EXT_MINCCA_PWR); 155 AR9280_PHY_CH1_EXT_MINCCA_PWR);
@@ -621,7 +629,7 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
621 u8 chainmask, rx_chain_status; 629 u8 chainmask, rx_chain_status;
622 630
623 rx_chain_status = REG_READ(ah, AR_PHY_RX_CHAINMASK); 631 rx_chain_status = REG_READ(ah, AR_PHY_RX_CHAINMASK);
624 if (AR_SREV_9285(ah)) 632 if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
625 chainmask = 0x9; 633 chainmask = 0x9;
626 else if (AR_SREV_9280(ah) || AR_SREV_9287(ah)) { 634 else if (AR_SREV_9280(ah) || AR_SREV_9287(ah)) {
627 if ((rx_chain_status & 0x2) || (rx_chain_status & 0x4)) 635 if ((rx_chain_status & 0x2) || (rx_chain_status & 0x4))
@@ -715,7 +723,7 @@ void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah)
715 723
716 if (AR_SREV_9280(ah)) 724 if (AR_SREV_9280(ah))
717 noise_floor = AR_PHY_CCA_MAX_AR9280_GOOD_VALUE; 725 noise_floor = AR_PHY_CCA_MAX_AR9280_GOOD_VALUE;
718 else if (AR_SREV_9285(ah)) 726 else if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
719 noise_floor = AR_PHY_CCA_MAX_AR9285_GOOD_VALUE; 727 noise_floor = AR_PHY_CCA_MAX_AR9285_GOOD_VALUE;
720 else if (AR_SREV_9287(ah)) 728 else if (AR_SREV_9287(ah))
721 noise_floor = AR_PHY_CCA_MAX_AR9287_GOOD_VALUE; 729 noise_floor = AR_PHY_CCA_MAX_AR9287_GOOD_VALUE;
@@ -1051,9 +1059,12 @@ bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
1051 /* Do NF cal only at longer intervals */ 1059 /* Do NF cal only at longer intervals */
1052 if (longcal) { 1060 if (longcal) {
1053 /* Do periodic PAOffset Cal */ 1061 /* Do periodic PAOffset Cal */
1054 if (AR_SREV_9271(ah)) 1062 if (AR_SREV_9271(ah)) {
1055 ath9k_hw_9271_pa_cal(ah, false); 1063 if (!ah->pacal_info.skipcount)
1056 else if (AR_SREV_9285_11_OR_LATER(ah)) { 1064 ath9k_hw_9271_pa_cal(ah, false);
1065 else
1066 ah->pacal_info.skipcount--;
1067 } else if (AR_SREV_9285_11_OR_LATER(ah)) {
1057 if (!ah->pacal_info.skipcount) 1068 if (!ah->pacal_info.skipcount)
1058 ath9k_hw_9285_pa_cal(ah, false); 1069 ath9k_hw_9285_pa_cal(ah, false);
1059 else 1070 else
diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c
index 4d775ae141d..7902d287f67 100644
--- a/drivers/net/wireless/ath/ath9k/common.c
+++ b/drivers/net/wireless/ath/ath9k/common.c
@@ -286,6 +286,427 @@ int ath9k_cmn_padpos(__le16 frame_control)
286} 286}
287EXPORT_SYMBOL(ath9k_cmn_padpos); 287EXPORT_SYMBOL(ath9k_cmn_padpos);
288 288
289int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb)
290{
291 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
292
293 if (tx_info->control.hw_key) {
294 if (tx_info->control.hw_key->alg == ALG_WEP)
295 return ATH9K_KEY_TYPE_WEP;
296 else if (tx_info->control.hw_key->alg == ALG_TKIP)
297 return ATH9K_KEY_TYPE_TKIP;
298 else if (tx_info->control.hw_key->alg == ALG_CCMP)
299 return ATH9K_KEY_TYPE_AES;
300 }
301
302 return ATH9K_KEY_TYPE_CLEAR;
303}
304EXPORT_SYMBOL(ath9k_cmn_get_hw_crypto_keytype);
305
306/*
307 * Calculate the RX filter to be set in the HW.
308 */
309u32 ath9k_cmn_calcrxfilter(struct ieee80211_hw *hw, struct ath_hw *ah,
310 unsigned int rxfilter)
311{
312#define RX_FILTER_PRESERVE (ATH9K_RX_FILTER_PHYERR | ATH9K_RX_FILTER_PHYRADAR)
313
314 u32 rfilt;
315
316 rfilt = (ath9k_hw_getrxfilter(ah) & RX_FILTER_PRESERVE)
317 | ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST
318 | ATH9K_RX_FILTER_MCAST;
319
320 /* If not a STA, enable processing of Probe Requests */
321 if (ah->opmode != NL80211_IFTYPE_STATION)
322 rfilt |= ATH9K_RX_FILTER_PROBEREQ;
323
324 /*
325 * Set promiscuous mode when FIF_PROMISC_IN_BSS is enabled for station
326 * mode interface or when in monitor mode. AP mode does not need this
327 * since it receives all in-BSS frames anyway.
328 */
329 if (((ah->opmode != NL80211_IFTYPE_AP) &&
330 (rxfilter & FIF_PROMISC_IN_BSS)) ||
331 (ah->opmode == NL80211_IFTYPE_MONITOR))
332 rfilt |= ATH9K_RX_FILTER_PROM;
333
334 if (rxfilter & FIF_CONTROL)
335 rfilt |= ATH9K_RX_FILTER_CONTROL;
336
337 if ((ah->opmode == NL80211_IFTYPE_STATION) &&
338 !(rxfilter & FIF_BCN_PRBRESP_PROMISC))
339 rfilt |= ATH9K_RX_FILTER_MYBEACON;
340 else
341 rfilt |= ATH9K_RX_FILTER_BEACON;
342
343 if ((AR_SREV_9280_10_OR_LATER(ah) ||
344 AR_SREV_9285_10_OR_LATER(ah)) &&
345 (ah->opmode == NL80211_IFTYPE_AP) &&
346 (rxfilter & FIF_PSPOLL))
347 rfilt |= ATH9K_RX_FILTER_PSPOLL;
348
349 if (conf_is_ht(&hw->conf))
350 rfilt |= ATH9K_RX_FILTER_COMP_BAR;
351
352 return rfilt;
353
354#undef RX_FILTER_PRESERVE
355}
356EXPORT_SYMBOL(ath9k_cmn_calcrxfilter);
357
358/*
359 * Recv initialization for opmode change.
360 */
361void ath9k_cmn_opmode_init(struct ieee80211_hw *hw, struct ath_hw *ah,
362 unsigned int rxfilter)
363{
364 struct ath_common *common = ath9k_hw_common(ah);
365
366 u32 rfilt, mfilt[2];
367
368 /* configure rx filter */
369 rfilt = ath9k_cmn_calcrxfilter(hw, ah, rxfilter);
370 ath9k_hw_setrxfilter(ah, rfilt);
371
372 /* configure bssid mask */
373 if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
374 ath_hw_setbssidmask(common);
375
376 /* configure operational mode */
377 ath9k_hw_setopmode(ah);
378
379 /* Handle any link-level address change. */
380 ath9k_hw_setmac(ah, common->macaddr);
381
382 /* calculate and install multicast filter */
383 mfilt[0] = mfilt[1] = ~0;
384 ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]);
385}
386EXPORT_SYMBOL(ath9k_cmn_opmode_init);
387
388static u32 ath9k_get_extchanmode(struct ieee80211_channel *chan,
389 enum nl80211_channel_type channel_type)
390{
391 u32 chanmode = 0;
392
393 switch (chan->band) {
394 case IEEE80211_BAND_2GHZ:
395 switch (channel_type) {
396 case NL80211_CHAN_NO_HT:
397 case NL80211_CHAN_HT20:
398 chanmode = CHANNEL_G_HT20;
399 break;
400 case NL80211_CHAN_HT40PLUS:
401 chanmode = CHANNEL_G_HT40PLUS;
402 break;
403 case NL80211_CHAN_HT40MINUS:
404 chanmode = CHANNEL_G_HT40MINUS;
405 break;
406 }
407 break;
408 case IEEE80211_BAND_5GHZ:
409 switch (channel_type) {
410 case NL80211_CHAN_NO_HT:
411 case NL80211_CHAN_HT20:
412 chanmode = CHANNEL_A_HT20;
413 break;
414 case NL80211_CHAN_HT40PLUS:
415 chanmode = CHANNEL_A_HT40PLUS;
416 break;
417 case NL80211_CHAN_HT40MINUS:
418 chanmode = CHANNEL_A_HT40MINUS;
419 break;
420 }
421 break;
422 default:
423 break;
424 }
425
426 return chanmode;
427}
428
429/*
430 * Update internal channel flags.
431 */
432void ath9k_cmn_update_ichannel(struct ieee80211_hw *hw,
433 struct ath9k_channel *ichan)
434{
435 struct ieee80211_channel *chan = hw->conf.channel;
436 struct ieee80211_conf *conf = &hw->conf;
437
438 ichan->channel = chan->center_freq;
439 ichan->chan = chan;
440
441 if (chan->band == IEEE80211_BAND_2GHZ) {
442 ichan->chanmode = CHANNEL_G;
443 ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM | CHANNEL_G;
444 } else {
445 ichan->chanmode = CHANNEL_A;
446 ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM;
447 }
448
449 if (conf_is_ht(conf))
450 ichan->chanmode = ath9k_get_extchanmode(chan,
451 conf->channel_type);
452}
453EXPORT_SYMBOL(ath9k_cmn_update_ichannel);
454
455/*
456 * Get the internal channel reference.
457 */
458struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw,
459 struct ath_hw *ah)
460{
461 struct ieee80211_channel *curchan = hw->conf.channel;
462 struct ath9k_channel *channel;
463 u8 chan_idx;
464
465 chan_idx = curchan->hw_value;
466 channel = &ah->channels[chan_idx];
467 ath9k_cmn_update_ichannel(hw, channel);
468
469 return channel;
470}
471EXPORT_SYMBOL(ath9k_cmn_get_curchannel);
472
473static int ath_setkey_tkip(struct ath_common *common, u16 keyix, const u8 *key,
474 struct ath9k_keyval *hk, const u8 *addr,
475 bool authenticator)
476{
477 struct ath_hw *ah = common->ah;
478 const u8 *key_rxmic;
479 const u8 *key_txmic;
480
481 key_txmic = key + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY;
482 key_rxmic = key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY;
483
484 if (addr == NULL) {
485 /*
486 * Group key installation - only two key cache entries are used
487 * regardless of splitmic capability since group key is only
488 * used either for TX or RX.
489 */
490 if (authenticator) {
491 memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
492 memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_mic));
493 } else {
494 memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
495 memcpy(hk->kv_txmic, key_rxmic, sizeof(hk->kv_mic));
496 }
497 return ath9k_hw_set_keycache_entry(ah, keyix, hk, addr);
498 }
499 if (!common->splitmic) {
500 /* TX and RX keys share the same key cache entry. */
501 memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
502 memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic));
503 return ath9k_hw_set_keycache_entry(ah, keyix, hk, addr);
504 }
505
506 /* Separate key cache entries for TX and RX */
507
508 /* TX key goes at first index, RX key at +32. */
509 memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
510 if (!ath9k_hw_set_keycache_entry(ah, keyix, hk, NULL)) {
511 /* TX MIC entry failed. No need to proceed further */
512 ath_print(common, ATH_DBG_FATAL,
513 "Setting TX MIC Key Failed\n");
514 return 0;
515 }
516
517 memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
518 /* XXX delete tx key on failure? */
519 return ath9k_hw_set_keycache_entry(ah, keyix + 32, hk, addr);
520}
521
522static int ath_reserve_key_cache_slot_tkip(struct ath_common *common)
523{
524 int i;
525
526 for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) {
527 if (test_bit(i, common->keymap) ||
528 test_bit(i + 64, common->keymap))
529 continue; /* At least one part of TKIP key allocated */
530 if (common->splitmic &&
531 (test_bit(i + 32, common->keymap) ||
532 test_bit(i + 64 + 32, common->keymap)))
533 continue; /* At least one part of TKIP key allocated */
534
535 /* Found a free slot for a TKIP key */
536 return i;
537 }
538 return -1;
539}
540
541static int ath_reserve_key_cache_slot(struct ath_common *common)
542{
543 int i;
544
545 /* First, try to find slots that would not be available for TKIP. */
546 if (common->splitmic) {
547 for (i = IEEE80211_WEP_NKID; i < common->keymax / 4; i++) {
548 if (!test_bit(i, common->keymap) &&
549 (test_bit(i + 32, common->keymap) ||
550 test_bit(i + 64, common->keymap) ||
551 test_bit(i + 64 + 32, common->keymap)))
552 return i;
553 if (!test_bit(i + 32, common->keymap) &&
554 (test_bit(i, common->keymap) ||
555 test_bit(i + 64, common->keymap) ||
556 test_bit(i + 64 + 32, common->keymap)))
557 return i + 32;
558 if (!test_bit(i + 64, common->keymap) &&
559 (test_bit(i , common->keymap) ||
560 test_bit(i + 32, common->keymap) ||
561 test_bit(i + 64 + 32, common->keymap)))
562 return i + 64;
563 if (!test_bit(i + 64 + 32, common->keymap) &&
564 (test_bit(i, common->keymap) ||
565 test_bit(i + 32, common->keymap) ||
566 test_bit(i + 64, common->keymap)))
567 return i + 64 + 32;
568 }
569 } else {
570 for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) {
571 if (!test_bit(i, common->keymap) &&
572 test_bit(i + 64, common->keymap))
573 return i;
574 if (test_bit(i, common->keymap) &&
575 !test_bit(i + 64, common->keymap))
576 return i + 64;
577 }
578 }
579
580 /* No partially used TKIP slots, pick any available slot */
581 for (i = IEEE80211_WEP_NKID; i < common->keymax; i++) {
582 /* Do not allow slots that could be needed for TKIP group keys
583 * to be used. This limitation could be removed if we know that
584 * TKIP will not be used. */
585 if (i >= 64 && i < 64 + IEEE80211_WEP_NKID)
586 continue;
587 if (common->splitmic) {
588 if (i >= 32 && i < 32 + IEEE80211_WEP_NKID)
589 continue;
590 if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID)
591 continue;
592 }
593
594 if (!test_bit(i, common->keymap))
595 return i; /* Found a free slot for a key */
596 }
597
598 /* No free slot found */
599 return -1;
600}
601
602/*
603 * Configure encryption in the HW.
604 */
605int ath9k_cmn_key_config(struct ath_common *common,
606 struct ieee80211_vif *vif,
607 struct ieee80211_sta *sta,
608 struct ieee80211_key_conf *key)
609{
610 struct ath_hw *ah = common->ah;
611 struct ath9k_keyval hk;
612 const u8 *mac = NULL;
613 int ret = 0;
614 int idx;
615
616 memset(&hk, 0, sizeof(hk));
617
618 switch (key->alg) {
619 case ALG_WEP:
620 hk.kv_type = ATH9K_CIPHER_WEP;
621 break;
622 case ALG_TKIP:
623 hk.kv_type = ATH9K_CIPHER_TKIP;
624 break;
625 case ALG_CCMP:
626 hk.kv_type = ATH9K_CIPHER_AES_CCM;
627 break;
628 default:
629 return -EOPNOTSUPP;
630 }
631
632 hk.kv_len = key->keylen;
633 memcpy(hk.kv_val, key->key, key->keylen);
634
635 if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
636 /* For now, use the default keys for broadcast keys. This may
637 * need to change with virtual interfaces. */
638 idx = key->keyidx;
639 } else if (key->keyidx) {
640 if (WARN_ON(!sta))
641 return -EOPNOTSUPP;
642 mac = sta->addr;
643
644 if (vif->type != NL80211_IFTYPE_AP) {
645 /* Only keyidx 0 should be used with unicast key, but
646 * allow this for client mode for now. */
647 idx = key->keyidx;
648 } else
649 return -EIO;
650 } else {
651 if (WARN_ON(!sta))
652 return -EOPNOTSUPP;
653 mac = sta->addr;
654
655 if (key->alg == ALG_TKIP)
656 idx = ath_reserve_key_cache_slot_tkip(common);
657 else
658 idx = ath_reserve_key_cache_slot(common);
659 if (idx < 0)
660 return -ENOSPC; /* no free key cache entries */
661 }
662
663 if (key->alg == ALG_TKIP)
664 ret = ath_setkey_tkip(common, idx, key->key, &hk, mac,
665 vif->type == NL80211_IFTYPE_AP);
666 else
667 ret = ath9k_hw_set_keycache_entry(ah, idx, &hk, mac);
668
669 if (!ret)
670 return -EIO;
671
672 set_bit(idx, common->keymap);
673 if (key->alg == ALG_TKIP) {
674 set_bit(idx + 64, common->keymap);
675 if (common->splitmic) {
676 set_bit(idx + 32, common->keymap);
677 set_bit(idx + 64 + 32, common->keymap);
678 }
679 }
680
681 return idx;
682}
683EXPORT_SYMBOL(ath9k_cmn_key_config);
684
685/*
686 * Delete Key.
687 */
688void ath9k_cmn_key_delete(struct ath_common *common,
689 struct ieee80211_key_conf *key)
690{
691 struct ath_hw *ah = common->ah;
692
693 ath9k_hw_keyreset(ah, key->hw_key_idx);
694 if (key->hw_key_idx < IEEE80211_WEP_NKID)
695 return;
696
697 clear_bit(key->hw_key_idx, common->keymap);
698 if (key->alg != ALG_TKIP)
699 return;
700
701 clear_bit(key->hw_key_idx + 64, common->keymap);
702 if (common->splitmic) {
703 ath9k_hw_keyreset(ah, key->hw_key_idx + 32);
704 clear_bit(key->hw_key_idx + 32, common->keymap);
705 clear_bit(key->hw_key_idx + 64 + 32, common->keymap);
706 }
707}
708EXPORT_SYMBOL(ath9k_cmn_key_delete);
709
289static int __init ath9k_cmn_init(void) 710static int __init ath9k_cmn_init(void)
290{ 711{
291 return 0; 712 return 0;
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h
index 042999c2fe9..bbcc57f6eba 100644
--- a/drivers/net/wireless/ath/ath9k/common.h
+++ b/drivers/net/wireless/ath/ath9k/common.h
@@ -23,6 +23,8 @@
23 23
24/* Common header for Atheros 802.11n base driver cores */ 24/* Common header for Atheros 802.11n base driver cores */
25 25
26#define IEEE80211_WEP_NKID 4
27
26#define WME_NUM_TID 16 28#define WME_NUM_TID 16
27#define WME_BA_BMP_SIZE 64 29#define WME_BA_BMP_SIZE 64
28#define WME_MAX_BA WME_BA_BMP_SIZE 30#define WME_MAX_BA WME_BA_BMP_SIZE
@@ -125,3 +127,18 @@ void ath9k_cmn_rx_skb_postprocess(struct ath_common *common,
125 bool decrypt_error); 127 bool decrypt_error);
126 128
127int ath9k_cmn_padpos(__le16 frame_control); 129int ath9k_cmn_padpos(__le16 frame_control);
130int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb);
131u32 ath9k_cmn_calcrxfilter(struct ieee80211_hw *hw, struct ath_hw *ah,
132 unsigned int rxfilter);
133void ath9k_cmn_opmode_init(struct ieee80211_hw *hw, struct ath_hw *ah,
134 unsigned int rxfilter);
135void ath9k_cmn_update_ichannel(struct ieee80211_hw *hw,
136 struct ath9k_channel *ichan);
137struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw,
138 struct ath_hw *ah);
139int ath9k_cmn_key_config(struct ath_common *common,
140 struct ieee80211_vif *vif,
141 struct ieee80211_sta *sta,
142 struct ieee80211_key_conf *key);
143void ath9k_cmn_key_delete(struct ath_common *common,
144 struct ieee80211_key_conf *key);
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
new file mode 100644
index 00000000000..fc4f6e8c9ef
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -0,0 +1,993 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "htc.h"
18
19#define ATH9K_FW_USB_DEV(devid, fw) \
20 { USB_DEVICE(0x0cf3, devid), .driver_info = (unsigned long) fw }
21
22static struct usb_device_id ath9k_hif_usb_ids[] = {
23 ATH9K_FW_USB_DEV(0x9271, "ar9271.fw"),
24 { },
25};
26
27MODULE_DEVICE_TABLE(usb, ath9k_hif_usb_ids);
28
29static int __hif_usb_tx(struct hif_device_usb *hif_dev);
30
31static void hif_usb_regout_cb(struct urb *urb)
32{
33 struct cmd_buf *cmd = (struct cmd_buf *)urb->context;
34 struct hif_device_usb *hif_dev = cmd->hif_dev;
35
36 if (!hif_dev) {
37 usb_free_urb(urb);
38 if (cmd) {
39 if (cmd->skb)
40 dev_kfree_skb_any(cmd->skb);
41 kfree(cmd);
42 }
43 return;
44 }
45
46 switch (urb->status) {
47 case 0:
48 break;
49 case -ENOENT:
50 case -ECONNRESET:
51 break;
52 case -ENODEV:
53 case -ESHUTDOWN:
54 return;
55 default:
56 break;
57 }
58
59 if (cmd) {
60 ath9k_htc_txcompletion_cb(cmd->hif_dev->htc_handle,
61 cmd->skb, 1);
62 kfree(cmd);
63 usb_free_urb(urb);
64 }
65}
66
67static int hif_usb_send_regout(struct hif_device_usb *hif_dev,
68 struct sk_buff *skb)
69{
70 struct urb *urb;
71 struct cmd_buf *cmd;
72 int ret = 0;
73
74 urb = usb_alloc_urb(0, GFP_KERNEL);
75 if (urb == NULL)
76 return -ENOMEM;
77
78 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
79 if (cmd == NULL) {
80 usb_free_urb(urb);
81 return -ENOMEM;
82 }
83
84 cmd->skb = skb;
85 cmd->hif_dev = hif_dev;
86
87 usb_fill_int_urb(urb, hif_dev->udev,
88 usb_sndintpipe(hif_dev->udev, USB_REG_OUT_PIPE),
89 skb->data, skb->len,
90 hif_usb_regout_cb, cmd, 1);
91
92 ret = usb_submit_urb(urb, GFP_KERNEL);
93 if (ret) {
94 usb_free_urb(urb);
95 kfree(cmd);
96 }
97
98 return ret;
99}
100
101static void hif_usb_tx_cb(struct urb *urb)
102{
103 struct tx_buf *tx_buf = (struct tx_buf *) urb->context;
104 struct hif_device_usb *hif_dev = tx_buf->hif_dev;
105 struct sk_buff *skb;
106 bool drop, flush;
107
108 if (!hif_dev)
109 return;
110
111 switch (urb->status) {
112 case 0:
113 break;
114 case -ENOENT:
115 case -ECONNRESET:
116 break;
117 case -ENODEV:
118 case -ESHUTDOWN:
119 return;
120 default:
121 break;
122 }
123
124 if (tx_buf) {
125 spin_lock(&hif_dev->tx.tx_lock);
126 drop = !!(hif_dev->tx.flags & HIF_USB_TX_STOP);
127 flush = !!(hif_dev->tx.flags & HIF_USB_TX_FLUSH);
128 spin_unlock(&hif_dev->tx.tx_lock);
129
130 while ((skb = __skb_dequeue(&tx_buf->skb_queue)) != NULL) {
131 if (!drop && !flush) {
132 ath9k_htc_txcompletion_cb(hif_dev->htc_handle,
133 skb, 1);
134 TX_STAT_INC(skb_completed);
135 } else {
136 dev_kfree_skb_any(skb);
137 }
138 }
139
140 if (flush)
141 return;
142
143 tx_buf->len = tx_buf->offset = 0;
144 __skb_queue_head_init(&tx_buf->skb_queue);
145
146 spin_lock(&hif_dev->tx.tx_lock);
147 list_del(&tx_buf->list);
148 list_add_tail(&tx_buf->list, &hif_dev->tx.tx_buf);
149 hif_dev->tx.tx_buf_cnt++;
150 if (!drop)
151 __hif_usb_tx(hif_dev); /* Check for pending SKBs */
152 TX_STAT_INC(buf_completed);
153 spin_unlock(&hif_dev->tx.tx_lock);
154 }
155}
156
157/* TX lock has to be taken */
158static int __hif_usb_tx(struct hif_device_usb *hif_dev)
159{
160 struct tx_buf *tx_buf = NULL;
161 struct sk_buff *nskb = NULL;
162 int ret = 0, i;
163 u16 *hdr, tx_skb_cnt = 0;
164 u8 *buf;
165
166 if (hif_dev->tx.tx_skb_cnt == 0)
167 return 0;
168
169 /* Check if a free TX buffer is available */
170 if (list_empty(&hif_dev->tx.tx_buf))
171 return 0;
172
173 tx_buf = list_first_entry(&hif_dev->tx.tx_buf, struct tx_buf, list);
174 list_del(&tx_buf->list);
175 list_add_tail(&tx_buf->list, &hif_dev->tx.tx_pending);
176 hif_dev->tx.tx_buf_cnt--;
177
178 tx_skb_cnt = min_t(u16, hif_dev->tx.tx_skb_cnt, MAX_TX_AGGR_NUM);
179
180 for (i = 0; i < tx_skb_cnt; i++) {
181 nskb = __skb_dequeue(&hif_dev->tx.tx_skb_queue);
182
183 /* Should never be NULL */
184 BUG_ON(!nskb);
185
186 hif_dev->tx.tx_skb_cnt--;
187
188 buf = tx_buf->buf;
189 buf += tx_buf->offset;
190 hdr = (u16 *)buf;
191 *hdr++ = nskb->len;
192 *hdr++ = ATH_USB_TX_STREAM_MODE_TAG;
193 buf += 4;
194 memcpy(buf, nskb->data, nskb->len);
195 tx_buf->len = nskb->len + 4;
196
197 if (i < (tx_skb_cnt - 1))
198 tx_buf->offset += (((tx_buf->len - 1) / 4) + 1) * 4;
199
200 if (i == (tx_skb_cnt - 1))
201 tx_buf->len += tx_buf->offset;
202
203 __skb_queue_tail(&tx_buf->skb_queue, nskb);
204 TX_STAT_INC(skb_queued);
205 }
206
207 usb_fill_bulk_urb(tx_buf->urb, hif_dev->udev,
208 usb_sndbulkpipe(hif_dev->udev, USB_WLAN_TX_PIPE),
209 tx_buf->buf, tx_buf->len,
210 hif_usb_tx_cb, tx_buf);
211
212 ret = usb_submit_urb(tx_buf->urb, GFP_ATOMIC);
213 if (ret) {
214 tx_buf->len = tx_buf->offset = 0;
215 __skb_queue_purge(&tx_buf->skb_queue);
216 __skb_queue_head_init(&tx_buf->skb_queue);
217 list_move_tail(&tx_buf->list, &hif_dev->tx.tx_buf);
218 hif_dev->tx.tx_buf_cnt++;
219 }
220
221 if (!ret)
222 TX_STAT_INC(buf_queued);
223
224 return ret;
225}
226
227static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb,
228 struct ath9k_htc_tx_ctl *tx_ctl)
229{
230 unsigned long flags;
231
232 spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
233
234 if (hif_dev->tx.flags & HIF_USB_TX_STOP) {
235 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
236 return -ENODEV;
237 }
238
239 /* Check if the max queue count has been reached */
240 if (hif_dev->tx.tx_skb_cnt > MAX_TX_BUF_NUM) {
241 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
242 return -ENOMEM;
243 }
244
245 __skb_queue_tail(&hif_dev->tx.tx_skb_queue, skb);
246 hif_dev->tx.tx_skb_cnt++;
247
248 /* Send normal frames immediately */
249 if (!tx_ctl || (tx_ctl && (tx_ctl->type == ATH9K_HTC_NORMAL)))
250 __hif_usb_tx(hif_dev);
251
252 /* Check if AMPDUs have to be sent immediately */
253 if (tx_ctl && (tx_ctl->type == ATH9K_HTC_AMPDU) &&
254 (hif_dev->tx.tx_buf_cnt == MAX_TX_URB_NUM) &&
255 (hif_dev->tx.tx_skb_cnt < 2)) {
256 __hif_usb_tx(hif_dev);
257 }
258
259 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
260
261 return 0;
262}
263
264static void hif_usb_start(void *hif_handle, u8 pipe_id)
265{
266 struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle;
267 unsigned long flags;
268
269 hif_dev->flags |= HIF_USB_START;
270
271 spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
272 hif_dev->tx.flags &= ~HIF_USB_TX_STOP;
273 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
274}
275
276static void hif_usb_stop(void *hif_handle, u8 pipe_id)
277{
278 struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle;
279 unsigned long flags;
280
281 spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
282 __skb_queue_purge(&hif_dev->tx.tx_skb_queue);
283 hif_dev->tx.tx_skb_cnt = 0;
284 hif_dev->tx.flags |= HIF_USB_TX_STOP;
285 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
286}
287
288static int hif_usb_send(void *hif_handle, u8 pipe_id, struct sk_buff *skb,
289 struct ath9k_htc_tx_ctl *tx_ctl)
290{
291 struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle;
292 int ret = 0;
293
294 switch (pipe_id) {
295 case USB_WLAN_TX_PIPE:
296 ret = hif_usb_send_tx(hif_dev, skb, tx_ctl);
297 break;
298 case USB_REG_OUT_PIPE:
299 ret = hif_usb_send_regout(hif_dev, skb);
300 break;
301 default:
302 ret = -EINVAL;
303 break;
304 }
305
306 return ret;
307}
308
309static struct ath9k_htc_hif hif_usb = {
310 .transport = ATH9K_HIF_USB,
311 .name = "ath9k_hif_usb",
312
313 .control_ul_pipe = USB_REG_OUT_PIPE,
314 .control_dl_pipe = USB_REG_IN_PIPE,
315
316 .start = hif_usb_start,
317 .stop = hif_usb_stop,
318 .send = hif_usb_send,
319};
320
321static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
322 struct sk_buff *skb)
323{
324 struct sk_buff *nskb, *skb_pool[8];
325 int index = 0, i = 0, chk_idx, len = skb->len;
326 int rx_remain_len = 0, rx_pkt_len = 0;
327 u16 pkt_len, pkt_tag, pool_index = 0;
328 u8 *ptr;
329
330 rx_remain_len = hif_dev->rx_remain_len;
331 rx_pkt_len = hif_dev->rx_transfer_len;
332
333 if (rx_remain_len != 0) {
334 struct sk_buff *remain_skb = hif_dev->remain_skb;
335
336 if (remain_skb) {
337 ptr = (u8 *) remain_skb->data;
338
339 index = rx_remain_len;
340 rx_remain_len -= hif_dev->rx_pad_len;
341 ptr += rx_pkt_len;
342
343 memcpy(ptr, skb->data, rx_remain_len);
344
345 rx_pkt_len += rx_remain_len;
346 hif_dev->rx_remain_len = 0;
347 skb_put(remain_skb, rx_pkt_len);
348
349 skb_pool[pool_index++] = remain_skb;
350
351 } else {
352 index = rx_remain_len;
353 }
354 }
355
356 while (index < len) {
357 ptr = (u8 *) skb->data;
358
359 pkt_len = ptr[index] + (ptr[index+1] << 8);
360 pkt_tag = ptr[index+2] + (ptr[index+3] << 8);
361
362 if (pkt_tag == ATH_USB_RX_STREAM_MODE_TAG) {
363 u16 pad_len;
364
365 pad_len = 4 - (pkt_len & 0x3);
366 if (pad_len == 4)
367 pad_len = 0;
368
369 chk_idx = index;
370 index = index + 4 + pkt_len + pad_len;
371
372 if (index > MAX_RX_BUF_SIZE) {
373 hif_dev->rx_remain_len = index - MAX_RX_BUF_SIZE;
374 hif_dev->rx_transfer_len =
375 MAX_RX_BUF_SIZE - chk_idx - 4;
376 hif_dev->rx_pad_len = pad_len;
377
378 nskb = __dev_alloc_skb(pkt_len + 32,
379 GFP_ATOMIC);
380 if (!nskb) {
381 dev_err(&hif_dev->udev->dev,
382 "ath9k_htc: RX memory allocation"
383 " error\n");
384 goto err;
385 }
386 skb_reserve(nskb, 32);
387 RX_STAT_INC(skb_allocated);
388
389 memcpy(nskb->data, &(skb->data[chk_idx+4]),
390 hif_dev->rx_transfer_len);
391
392 /* Record the buffer pointer */
393 hif_dev->remain_skb = nskb;
394 } else {
395 nskb = __dev_alloc_skb(pkt_len + 32, GFP_ATOMIC);
396 if (!nskb) {
397 dev_err(&hif_dev->udev->dev,
398 "ath9k_htc: RX memory allocation"
399 " error\n");
400 goto err;
401 }
402 skb_reserve(nskb, 32);
403 RX_STAT_INC(skb_allocated);
404
405 memcpy(nskb->data, &(skb->data[chk_idx+4]), pkt_len);
406 skb_put(nskb, pkt_len);
407 skb_pool[pool_index++] = nskb;
408 }
409 } else {
410 RX_STAT_INC(skb_dropped);
411 dev_kfree_skb_any(skb);
412 return;
413 }
414 }
415
416err:
417 dev_kfree_skb_any(skb);
418
419 for (i = 0; i < pool_index; i++) {
420 ath9k_htc_rx_msg(hif_dev->htc_handle, skb_pool[i],
421 skb_pool[i]->len, USB_WLAN_RX_PIPE);
422 RX_STAT_INC(skb_completed);
423 }
424}
425
426static void ath9k_hif_usb_rx_cb(struct urb *urb)
427{
428 struct sk_buff *skb = (struct sk_buff *) urb->context;
429 struct sk_buff *nskb;
430 struct hif_device_usb *hif_dev = (struct hif_device_usb *)
431 usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
432 int ret;
433
434 if (!hif_dev)
435 goto free;
436
437 switch (urb->status) {
438 case 0:
439 break;
440 case -ENOENT:
441 case -ECONNRESET:
442 case -ENODEV:
443 case -ESHUTDOWN:
444 goto free;
445 default:
446 goto resubmit;
447 }
448
449 if (likely(urb->actual_length != 0)) {
450 skb_put(skb, urb->actual_length);
451
452 nskb = __dev_alloc_skb(MAX_RX_BUF_SIZE, GFP_ATOMIC);
453 if (!nskb)
454 goto resubmit;
455
456 usb_fill_bulk_urb(urb, hif_dev->udev,
457 usb_rcvbulkpipe(hif_dev->udev,
458 USB_WLAN_RX_PIPE),
459 nskb->data, MAX_RX_BUF_SIZE,
460 ath9k_hif_usb_rx_cb, nskb);
461
462 ret = usb_submit_urb(urb, GFP_ATOMIC);
463 if (ret) {
464 dev_kfree_skb_any(nskb);
465 goto free;
466 }
467
468 ath9k_hif_usb_rx_stream(hif_dev, skb);
469 return;
470 }
471
472resubmit:
473 skb_reset_tail_pointer(skb);
474 skb_trim(skb, 0);
475
476 ret = usb_submit_urb(urb, GFP_ATOMIC);
477 if (ret)
478 goto free;
479
480 return;
481free:
482 dev_kfree_skb_any(skb);
483}
484
485static void ath9k_hif_usb_reg_in_cb(struct urb *urb)
486{
487 struct sk_buff *skb = (struct sk_buff *) urb->context;
488 struct sk_buff *nskb;
489 struct hif_device_usb *hif_dev = (struct hif_device_usb *)
490 usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
491 int ret;
492
493 if (!hif_dev)
494 goto free;
495
496 switch (urb->status) {
497 case 0:
498 break;
499 case -ENOENT:
500 case -ECONNRESET:
501 case -ENODEV:
502 case -ESHUTDOWN:
503 goto free;
504 default:
505 goto resubmit;
506 }
507
508 if (likely(urb->actual_length != 0)) {
509 skb_put(skb, urb->actual_length);
510
511 nskb = __dev_alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_ATOMIC);
512 if (!nskb)
513 goto resubmit;
514
515 usb_fill_int_urb(urb, hif_dev->udev,
516 usb_rcvintpipe(hif_dev->udev, USB_REG_IN_PIPE),
517 nskb->data, MAX_REG_IN_BUF_SIZE,
518 ath9k_hif_usb_reg_in_cb, nskb, 1);
519
520 ret = usb_submit_urb(urb, GFP_ATOMIC);
521 if (ret) {
522 dev_kfree_skb_any(nskb);
523 goto free;
524 }
525
526 ath9k_htc_rx_msg(hif_dev->htc_handle, skb,
527 skb->len, USB_REG_IN_PIPE);
528
529 return;
530 }
531
532resubmit:
533 skb_reset_tail_pointer(skb);
534 skb_trim(skb, 0);
535
536 ret = usb_submit_urb(urb, GFP_ATOMIC);
537 if (ret)
538 goto free;
539
540 return;
541free:
542 dev_kfree_skb_any(skb);
543}
544
545static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev)
546{
547 unsigned long flags;
548 struct tx_buf *tx_buf = NULL, *tx_buf_tmp = NULL;
549
550 list_for_each_entry_safe(tx_buf, tx_buf_tmp, &hif_dev->tx.tx_buf, list) {
551 list_del(&tx_buf->list);
552 usb_free_urb(tx_buf->urb);
553 kfree(tx_buf->buf);
554 kfree(tx_buf);
555 }
556
557 spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
558 hif_dev->tx.flags |= HIF_USB_TX_FLUSH;
559 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
560
561 list_for_each_entry_safe(tx_buf, tx_buf_tmp,
562 &hif_dev->tx.tx_pending, list) {
563 usb_kill_urb(tx_buf->urb);
564 list_del(&tx_buf->list);
565 usb_free_urb(tx_buf->urb);
566 kfree(tx_buf->buf);
567 kfree(tx_buf);
568 }
569
570 spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
571 hif_dev->tx.flags &= ~HIF_USB_TX_FLUSH;
572 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
573}
574
575static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev)
576{
577 struct tx_buf *tx_buf;
578 int i;
579
580 INIT_LIST_HEAD(&hif_dev->tx.tx_buf);
581 INIT_LIST_HEAD(&hif_dev->tx.tx_pending);
582 spin_lock_init(&hif_dev->tx.tx_lock);
583 __skb_queue_head_init(&hif_dev->tx.tx_skb_queue);
584
585 for (i = 0; i < MAX_TX_URB_NUM; i++) {
586 tx_buf = kzalloc(sizeof(struct tx_buf), GFP_KERNEL);
587 if (!tx_buf)
588 goto err;
589
590 tx_buf->buf = kzalloc(MAX_TX_BUF_SIZE, GFP_KERNEL);
591 if (!tx_buf->buf)
592 goto err;
593
594 tx_buf->urb = usb_alloc_urb(0, GFP_KERNEL);
595 if (!tx_buf->urb)
596 goto err;
597
598 tx_buf->hif_dev = hif_dev;
599 __skb_queue_head_init(&tx_buf->skb_queue);
600
601 list_add_tail(&tx_buf->list, &hif_dev->tx.tx_buf);
602 }
603
604 hif_dev->tx.tx_buf_cnt = MAX_TX_URB_NUM;
605
606 return 0;
607err:
608 ath9k_hif_usb_dealloc_tx_urbs(hif_dev);
609 return -ENOMEM;
610}
611
612static void ath9k_hif_usb_dealloc_rx_skbs(struct hif_device_usb *hif_dev)
613{
614 int i;
615
616 for (i = 0; i < MAX_RX_URB_NUM; i++) {
617 if (hif_dev->wlan_rx_data_urb[i]) {
618 if (hif_dev->wlan_rx_data_urb[i]->transfer_buffer)
619 dev_kfree_skb_any((void *)
620 hif_dev->wlan_rx_data_urb[i]->context);
621 }
622 }
623}
624
625static void ath9k_hif_usb_dealloc_rx_urbs(struct hif_device_usb *hif_dev)
626{
627 int i;
628
629 for (i = 0; i < MAX_RX_URB_NUM; i++) {
630 if (hif_dev->wlan_rx_data_urb[i]) {
631 usb_kill_urb(hif_dev->wlan_rx_data_urb[i]);
632 usb_free_urb(hif_dev->wlan_rx_data_urb[i]);
633 hif_dev->wlan_rx_data_urb[i] = NULL;
634 }
635 }
636}
637
638static int ath9k_hif_usb_prep_rx_urb(struct hif_device_usb *hif_dev,
639 struct urb *urb)
640{
641 struct sk_buff *skb;
642
643 skb = __dev_alloc_skb(MAX_RX_BUF_SIZE, GFP_KERNEL);
644 if (!skb)
645 return -ENOMEM;
646
647 usb_fill_bulk_urb(urb, hif_dev->udev,
648 usb_rcvbulkpipe(hif_dev->udev, USB_WLAN_RX_PIPE),
649 skb->data, MAX_RX_BUF_SIZE,
650 ath9k_hif_usb_rx_cb, skb);
651 return 0;
652}
653
654static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev)
655{
656 int i, ret;
657
658 for (i = 0; i < MAX_RX_URB_NUM; i++) {
659
660 /* Allocate URB */
661 hif_dev->wlan_rx_data_urb[i] = usb_alloc_urb(0, GFP_KERNEL);
662 if (hif_dev->wlan_rx_data_urb[i] == NULL) {
663 ret = -ENOMEM;
664 goto err_rx_urb;
665 }
666
667 /* Allocate buffer */
668 ret = ath9k_hif_usb_prep_rx_urb(hif_dev,
669 hif_dev->wlan_rx_data_urb[i]);
670 if (ret)
671 goto err_rx_urb;
672
673 /* Submit URB */
674 ret = usb_submit_urb(hif_dev->wlan_rx_data_urb[i], GFP_KERNEL);
675 if (ret)
676 goto err_rx_urb;
677
678 }
679
680 return 0;
681
682err_rx_urb:
683 ath9k_hif_usb_dealloc_rx_skbs(hif_dev);
684 ath9k_hif_usb_dealloc_rx_urbs(hif_dev);
685 return ret;
686}
687
688static void ath9k_hif_usb_dealloc_reg_in_urb(struct hif_device_usb *hif_dev)
689{
690 if (hif_dev->reg_in_urb) {
691 usb_kill_urb(hif_dev->reg_in_urb);
692 usb_free_urb(hif_dev->reg_in_urb);
693 hif_dev->reg_in_urb = NULL;
694 }
695}
696
697static int ath9k_hif_usb_alloc_reg_in_urb(struct hif_device_usb *hif_dev)
698{
699 struct sk_buff *skb;
700
701 hif_dev->reg_in_urb = usb_alloc_urb(0, GFP_KERNEL);
702 if (hif_dev->reg_in_urb == NULL)
703 return -ENOMEM;
704
705 skb = __dev_alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_KERNEL);
706 if (!skb)
707 goto err;
708
709 usb_fill_int_urb(hif_dev->reg_in_urb, hif_dev->udev,
710 usb_rcvintpipe(hif_dev->udev, USB_REG_IN_PIPE),
711 skb->data, MAX_REG_IN_BUF_SIZE,
712 ath9k_hif_usb_reg_in_cb, skb, 1);
713
714 if (usb_submit_urb(hif_dev->reg_in_urb, GFP_KERNEL) != 0)
715 goto err_skb;
716
717 return 0;
718
719err_skb:
720 dev_kfree_skb_any(skb);
721err:
722 ath9k_hif_usb_dealloc_reg_in_urb(hif_dev);
723 return -ENOMEM;
724}
725
726static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev)
727{
728 /* TX */
729 if (ath9k_hif_usb_alloc_tx_urbs(hif_dev) < 0)
730 goto err;
731
732 /* RX */
733 if (ath9k_hif_usb_alloc_rx_urbs(hif_dev) < 0)
734 goto err;
735
736 /* Register Read/Write */
737 if (ath9k_hif_usb_alloc_reg_in_urb(hif_dev) < 0)
738 goto err;
739
740 return 0;
741err:
742 return -ENOMEM;
743}
744
745static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev)
746{
747 int transfer, err;
748 const void *data = hif_dev->firmware->data;
749 size_t len = hif_dev->firmware->size;
750 u32 addr = AR9271_FIRMWARE;
751 u8 *buf = kzalloc(4096, GFP_KERNEL);
752
753 if (!buf)
754 return -ENOMEM;
755
756 while (len) {
757 transfer = min_t(int, len, 4096);
758 memcpy(buf, data, transfer);
759
760 err = usb_control_msg(hif_dev->udev,
761 usb_sndctrlpipe(hif_dev->udev, 0),
762 FIRMWARE_DOWNLOAD, 0x40 | USB_DIR_OUT,
763 addr >> 8, 0, buf, transfer, HZ);
764 if (err < 0) {
765 kfree(buf);
766 return err;
767 }
768
769 len -= transfer;
770 data += transfer;
771 addr += transfer;
772 }
773 kfree(buf);
774
775 /*
776 * Issue FW download complete command to firmware.
777 */
778 err = usb_control_msg(hif_dev->udev, usb_sndctrlpipe(hif_dev->udev, 0),
779 FIRMWARE_DOWNLOAD_COMP,
780 0x40 | USB_DIR_OUT,
781 AR9271_FIRMWARE_TEXT >> 8, 0, NULL, 0, HZ);
782 if (err)
783 return -EIO;
784
785 dev_info(&hif_dev->udev->dev, "ath9k_htc: Transferred FW: %s, size: %ld\n",
786 "ar9271.fw", (unsigned long) hif_dev->firmware->size);
787
788 return 0;
789}
790
791static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev,
792 const char *fw_name)
793{
794 int ret;
795
796 /* Request firmware */
797 ret = request_firmware(&hif_dev->firmware, fw_name, &hif_dev->udev->dev);
798 if (ret) {
799 dev_err(&hif_dev->udev->dev,
800 "ath9k_htc: Firmware - %s not found\n", fw_name);
801 goto err_fw_req;
802 }
803
804 /* Download firmware */
805 ret = ath9k_hif_usb_download_fw(hif_dev);
806 if (ret) {
807 dev_err(&hif_dev->udev->dev,
808 "ath9k_htc: Firmware - %s download failed\n", fw_name);
809 goto err_fw_download;
810 }
811
812 /* Alloc URBs */
813 ret = ath9k_hif_usb_alloc_urbs(hif_dev);
814 if (ret) {
815 dev_err(&hif_dev->udev->dev,
816 "ath9k_htc: Unable to allocate URBs\n");
817 goto err_urb;
818 }
819
820 return 0;
821
822err_urb:
823 /* Nothing */
824err_fw_download:
825 release_firmware(hif_dev->firmware);
826err_fw_req:
827 hif_dev->firmware = NULL;
828 return ret;
829}
830
831static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev)
832{
833 ath9k_hif_usb_dealloc_reg_in_urb(hif_dev);
834 ath9k_hif_usb_dealloc_tx_urbs(hif_dev);
835 ath9k_hif_usb_dealloc_rx_urbs(hif_dev);
836}
837
838static void ath9k_hif_usb_dev_deinit(struct hif_device_usb *hif_dev)
839{
840 ath9k_hif_usb_dealloc_urbs(hif_dev);
841 if (hif_dev->firmware)
842 release_firmware(hif_dev->firmware);
843}
844
845static int ath9k_hif_usb_probe(struct usb_interface *interface,
846 const struct usb_device_id *id)
847{
848 struct usb_device *udev = interface_to_usbdev(interface);
849 struct hif_device_usb *hif_dev;
850 const char *fw_name = (const char *) id->driver_info;
851 int ret = 0;
852
853 hif_dev = kzalloc(sizeof(struct hif_device_usb), GFP_KERNEL);
854 if (!hif_dev) {
855 ret = -ENOMEM;
856 goto err_alloc;
857 }
858
859 usb_get_dev(udev);
860 hif_dev->udev = udev;
861 hif_dev->interface = interface;
862 hif_dev->device_id = id->idProduct;
863#ifdef CONFIG_PM
864 udev->reset_resume = 1;
865#endif
866 usb_set_intfdata(interface, hif_dev);
867
868 ret = ath9k_hif_usb_dev_init(hif_dev, fw_name);
869 if (ret) {
870 ret = -EINVAL;
871 goto err_hif_init_usb;
872 }
873
874 hif_dev->htc_handle = ath9k_htc_hw_alloc(hif_dev);
875 if (hif_dev->htc_handle == NULL) {
876 ret = -ENOMEM;
877 goto err_htc_hw_alloc;
878 }
879
880 ret = ath9k_htc_hw_init(&hif_usb, hif_dev->htc_handle, hif_dev,
881 &hif_dev->udev->dev, hif_dev->device_id,
882 ATH9K_HIF_USB);
883 if (ret) {
884 ret = -EINVAL;
885 goto err_htc_hw_init;
886 }
887
888 dev_info(&hif_dev->udev->dev, "ath9k_htc: USB layer initialized\n");
889
890 return 0;
891
892err_htc_hw_init:
893 ath9k_htc_hw_free(hif_dev->htc_handle);
894err_htc_hw_alloc:
895 ath9k_hif_usb_dev_deinit(hif_dev);
896err_hif_init_usb:
897 usb_set_intfdata(interface, NULL);
898 kfree(hif_dev);
899 usb_put_dev(udev);
900err_alloc:
901 return ret;
902}
903
904static void ath9k_hif_usb_disconnect(struct usb_interface *interface)
905{
906 struct usb_device *udev = interface_to_usbdev(interface);
907 struct hif_device_usb *hif_dev =
908 (struct hif_device_usb *) usb_get_intfdata(interface);
909
910 if (hif_dev) {
911 ath9k_htc_hw_deinit(hif_dev->htc_handle, true);
912 ath9k_htc_hw_free(hif_dev->htc_handle);
913 ath9k_hif_usb_dev_deinit(hif_dev);
914 usb_set_intfdata(interface, NULL);
915 }
916
917 if (hif_dev->flags & HIF_USB_START)
918 usb_reset_device(udev);
919
920 kfree(hif_dev);
921 dev_info(&udev->dev, "ath9k_htc: USB layer deinitialized\n");
922 usb_put_dev(udev);
923}
924
925#ifdef CONFIG_PM
926static int ath9k_hif_usb_suspend(struct usb_interface *interface,
927 pm_message_t message)
928{
929 struct hif_device_usb *hif_dev =
930 (struct hif_device_usb *) usb_get_intfdata(interface);
931
932 ath9k_hif_usb_dealloc_urbs(hif_dev);
933
934 return 0;
935}
936
937static int ath9k_hif_usb_resume(struct usb_interface *interface)
938{
939 struct hif_device_usb *hif_dev =
940 (struct hif_device_usb *) usb_get_intfdata(interface);
941 int ret;
942
943 ret = ath9k_hif_usb_alloc_urbs(hif_dev);
944 if (ret)
945 return ret;
946
947 if (hif_dev->firmware) {
948 ret = ath9k_hif_usb_download_fw(hif_dev);
949 if (ret)
950 goto fail_resume;
951 } else {
952 ath9k_hif_usb_dealloc_urbs(hif_dev);
953 return -EIO;
954 }
955
956 mdelay(100);
957
958 ret = ath9k_htc_resume(hif_dev->htc_handle);
959
960 if (ret)
961 goto fail_resume;
962
963 return 0;
964
965fail_resume:
966 ath9k_hif_usb_dealloc_urbs(hif_dev);
967
968 return ret;
969}
970#endif
971
972static struct usb_driver ath9k_hif_usb_driver = {
973 .name = "ath9k_hif_usb",
974 .probe = ath9k_hif_usb_probe,
975 .disconnect = ath9k_hif_usb_disconnect,
976#ifdef CONFIG_PM
977 .suspend = ath9k_hif_usb_suspend,
978 .resume = ath9k_hif_usb_resume,
979 .reset_resume = ath9k_hif_usb_resume,
980#endif
981 .id_table = ath9k_hif_usb_ids,
982 .soft_unbind = 1,
983};
984
985int ath9k_hif_usb_init(void)
986{
987 return usb_register(&ath9k_hif_usb_driver);
988}
989
990void ath9k_hif_usb_exit(void)
991{
992 usb_deregister(&ath9k_hif_usb_driver);
993}
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h
new file mode 100644
index 00000000000..7cc3762a678
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.h
@@ -0,0 +1,105 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef HTC_USB_H
18#define HTC_USB_H
19
20#define AR9271_FIRMWARE 0x501000
21#define AR9271_FIRMWARE_TEXT 0x903000
22
23#define FIRMWARE_DOWNLOAD 0x30
24#define FIRMWARE_DOWNLOAD_COMP 0x31
25
26#define ATH_USB_RX_STREAM_MODE_TAG 0x4e00
27#define ATH_USB_TX_STREAM_MODE_TAG 0x697e
28
29/* FIXME: Verify these numbers (with Windows) */
30#define MAX_TX_URB_NUM 8
31#define MAX_TX_BUF_NUM 1024
32#define MAX_TX_BUF_SIZE 32768
33#define MAX_TX_AGGR_NUM 20
34
35#define MAX_RX_URB_NUM 8
36#define MAX_RX_BUF_SIZE 16384
37
38#define MAX_REG_OUT_URB_NUM 1
39#define MAX_REG_OUT_BUF_NUM 8
40
41#define MAX_REG_IN_BUF_SIZE 64
42
43/* USB Endpoint definition */
44#define USB_WLAN_TX_PIPE 1
45#define USB_WLAN_RX_PIPE 2
46#define USB_REG_IN_PIPE 3
47#define USB_REG_OUT_PIPE 4
48
49#define HIF_USB_MAX_RXPIPES 2
50#define HIF_USB_MAX_TXPIPES 4
51
52struct tx_buf {
53 u8 *buf;
54 u16 len;
55 u16 offset;
56 struct urb *urb;
57 struct sk_buff_head skb_queue;
58 struct hif_device_usb *hif_dev;
59 struct list_head list;
60};
61
62#define HIF_USB_TX_STOP BIT(0)
63#define HIF_USB_TX_FLUSH BIT(1)
64
65struct hif_usb_tx {
66 u8 flags;
67 u8 tx_buf_cnt;
68 u16 tx_skb_cnt;
69 struct sk_buff_head tx_skb_queue;
70 struct list_head tx_buf;
71 struct list_head tx_pending;
72 spinlock_t tx_lock;
73};
74
75struct cmd_buf {
76 struct sk_buff *skb;
77 struct hif_device_usb *hif_dev;
78};
79
80#define HIF_USB_START BIT(0)
81
82struct hif_device_usb {
83 u16 device_id;
84 struct usb_device *udev;
85 struct usb_interface *interface;
86 const struct firmware *firmware;
87 struct htc_target *htc_handle;
88 u8 flags;
89
90 struct hif_usb_tx tx;
91
92 struct urb *wlan_rx_data_urb[MAX_RX_URB_NUM];
93 struct urb *reg_in_urb;
94
95 struct sk_buff *remain_skb;
96 int rx_remain_len;
97 int rx_pkt_len;
98 int rx_transfer_len;
99 int rx_pad_len;
100};
101
102int ath9k_hif_usb_init(void);
103void ath9k_hif_usb_exit(void);
104
105#endif /* HTC_USB_H */
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
new file mode 100644
index 00000000000..777064945fc
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -0,0 +1,441 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef HTC_H
18#define HTC_H
19
20#include <linux/module.h>
21#include <linux/usb.h>
22#include <linux/firmware.h>
23#include <linux/skbuff.h>
24#include <linux/netdevice.h>
25#include <linux/leds.h>
26#include <net/mac80211.h>
27
28#include "common.h"
29#include "htc_hst.h"
30#include "hif_usb.h"
31#include "wmi.h"
32
33#define ATH_STA_SHORT_CALINTERVAL 1000 /* 1 second */
34#define ATH_ANI_POLLINTERVAL 100 /* 100 ms */
35#define ATH_LONG_CALINTERVAL 30000 /* 30 seconds */
36#define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */
37
38#define ATH_DEFAULT_BMISS_LIMIT 10
39#define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024)
40#define TSF_TO_TU(_h, _l) \
41 ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
42
43extern struct ieee80211_ops ath9k_htc_ops;
44extern int htc_modparam_nohwcrypt;
45
46enum htc_phymode {
47 HTC_MODE_AUTO = 0,
48 HTC_MODE_11A = 1,
49 HTC_MODE_11B = 2,
50 HTC_MODE_11G = 3,
51 HTC_MODE_FH = 4,
52 HTC_MODE_TURBO_A = 5,
53 HTC_MODE_TURBO_G = 6,
54 HTC_MODE_11NA = 7,
55 HTC_MODE_11NG = 8
56};
57
58enum htc_opmode {
59 HTC_M_STA = 1,
60 HTC_M_IBSS = 0,
61 HTC_M_AHDEMO = 3,
62 HTC_M_HOSTAP = 6,
63 HTC_M_MONITOR = 8,
64 HTC_M_WDS = 2
65};
66
67#define ATH9K_HTC_HDRSPACE sizeof(struct htc_frame_hdr)
68#define ATH9K_HTC_AMPDU 1
69#define ATH9K_HTC_NORMAL 2
70
71#define ATH9K_HTC_TX_CTSONLY 0x1
72#define ATH9K_HTC_TX_RTSCTS 0x2
73#define ATH9K_HTC_TX_USE_MIN_RATE 0x100
74
75struct tx_frame_hdr {
76 u8 data_type;
77 u8 node_idx;
78 u8 vif_idx;
79 u8 tidno;
80 u32 flags; /* ATH9K_HTC_TX_* */
81 u8 key_type;
82 u8 keyix;
83 u8 reserved[26];
84} __packed;
85
86struct tx_mgmt_hdr {
87 u8 node_idx;
88 u8 vif_idx;
89 u8 tidno;
90 u8 flags;
91 u8 key_type;
92 u8 keyix;
93 u16 reserved;
94} __packed;
95
96struct tx_beacon_header {
97 u8 len_changed;
98 u8 vif_index;
99 u16 rev;
100} __packed;
101
102struct ath9k_htc_target_hw {
103 u32 flags;
104 u32 flags_ext;
105 u32 ampdu_limit;
106 u8 ampdu_subframes;
107 u8 tx_chainmask;
108 u8 tx_chainmask_legacy;
109 u8 rtscts_ratecode;
110 u8 protmode;
111} __packed;
112
113struct ath9k_htc_cap_target {
114 u32 flags;
115 u32 flags_ext;
116 u32 ampdu_limit;
117 u8 ampdu_subframes;
118 u8 tx_chainmask;
119 u8 tx_chainmask_legacy;
120 u8 rtscts_ratecode;
121 u8 protmode;
122} __packed;
123
124struct ath9k_htc_target_vif {
125 u8 index;
126 u8 des_bssid[ETH_ALEN];
127 enum htc_opmode opmode;
128 u8 myaddr[ETH_ALEN];
129 u8 bssid[ETH_ALEN];
130 u32 flags;
131 u32 flags_ext;
132 u16 ps_sta;
133 u16 rtsthreshold;
134 u8 ath_cap;
135 u8 node;
136 s8 mcast_rate;
137} __packed;
138
139#define ATH_HTC_STA_AUTH 0x0001
140#define ATH_HTC_STA_QOS 0x0002
141#define ATH_HTC_STA_ERP 0x0004
142#define ATH_HTC_STA_HT 0x0008
143
144/* FIXME: UAPSD variables */
145struct ath9k_htc_target_sta {
146 u16 associd;
147 u16 txpower;
148 u32 ucastkey;
149 u8 macaddr[ETH_ALEN];
150 u8 bssid[ETH_ALEN];
151 u8 sta_index;
152 u8 vif_index;
153 u8 vif_sta;
154 u16 flags; /* ATH_HTC_STA_* */
155 u16 htcap;
156 u8 valid;
157 u16 capinfo;
158 struct ath9k_htc_target_hw *hw;
159 struct ath9k_htc_target_vif *vif;
160 u16 txseqmgmt;
161 u8 is_vif_sta;
162 u16 maxampdu;
163 u16 iv16;
164 u32 iv32;
165} __packed;
166
167struct ath9k_htc_target_aggr {
168 u8 sta_index;
169 u8 tidno;
170 u8 aggr_enable;
171 u8 padding;
172} __packed;
173
174#define ATH_HTC_RATE_MAX 30
175
176#define WLAN_RC_DS_FLAG 0x01
177#define WLAN_RC_40_FLAG 0x02
178#define WLAN_RC_SGI_FLAG 0x04
179#define WLAN_RC_HT_FLAG 0x08
180
181struct ath9k_htc_rateset {
182 u8 rs_nrates;
183 u8 rs_rates[ATH_HTC_RATE_MAX];
184};
185
186struct ath9k_htc_rate {
187 struct ath9k_htc_rateset legacy_rates;
188 struct ath9k_htc_rateset ht_rates;
189} __packed;
190
191struct ath9k_htc_target_rate {
192 u8 sta_index;
193 u8 isnew;
194 u32 capflags;
195 struct ath9k_htc_rate rates;
196};
197
198struct ath9k_htc_target_stats {
199 u32 tx_shortretry;
200 u32 tx_longretry;
201 u32 tx_xretries;
202 u32 ht_txunaggr_xretry;
203 u32 ht_tx_xretries;
204} __packed;
205
206struct ath9k_htc_vif {
207 u8 index;
208};
209
210#define ATH9K_HTC_MAX_STA 8
211#define ATH9K_HTC_MAX_TID 8
212
213enum tid_aggr_state {
214 AGGR_STOP = 0,
215 AGGR_PROGRESS,
216 AGGR_START,
217 AGGR_OPERATIONAL
218};
219
220struct ath9k_htc_sta {
221 u8 index;
222 enum tid_aggr_state tid_state[ATH9K_HTC_MAX_TID];
223};
224
225struct ath9k_htc_aggr_work {
226 u16 tid;
227 u8 sta_addr[ETH_ALEN];
228 struct ieee80211_hw *hw;
229 struct ieee80211_vif *vif;
230 enum ieee80211_ampdu_mlme_action action;
231 struct mutex mutex;
232};
233
234#define ATH9K_HTC_RXBUF 256
235#define HTC_RX_FRAME_HEADER_SIZE 40
236
237struct ath9k_htc_rxbuf {
238 bool in_process;
239 struct sk_buff *skb;
240 struct ath_htc_rx_status rxstatus;
241 struct list_head list;
242};
243
244struct ath9k_htc_rx {
245 int last_rssi; /* FIXME: per-STA */
246 struct list_head rxbuf;
247 spinlock_t rxbuflock;
248};
249
250struct ath9k_htc_tx_ctl {
251 u8 type; /* ATH9K_HTC_* */
252};
253
254#ifdef CONFIG_ATH9K_HTC_DEBUGFS
255
256#define TX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c++)
257#define RX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.rx_stats.c++)
258
259struct ath_tx_stats {
260 u32 buf_queued;
261 u32 buf_completed;
262 u32 skb_queued;
263 u32 skb_completed;
264};
265
266struct ath_rx_stats {
267 u32 skb_allocated;
268 u32 skb_completed;
269 u32 skb_dropped;
270};
271
272struct ath9k_debug {
273 struct dentry *debugfs_phy;
274 struct dentry *debugfs_tgt_stats;
275 struct dentry *debugfs_xmit;
276 struct dentry *debugfs_recv;
277 struct ath_tx_stats tx_stats;
278 struct ath_rx_stats rx_stats;
279 u32 txrate;
280};
281
282#else
283
284#define TX_STAT_INC(c) do { } while (0)
285#define RX_STAT_INC(c) do { } while (0)
286
287#endif /* CONFIG_ATH9K_HTC_DEBUGFS */
288
289#define ATH_LED_PIN_DEF 1
290#define ATH_LED_PIN_9287 8
291#define ATH_LED_PIN_9271 15
292#define ATH_LED_ON_DURATION_IDLE 350 /* in msecs */
293#define ATH_LED_OFF_DURATION_IDLE 250 /* in msecs */
294
295enum ath_led_type {
296 ATH_LED_RADIO,
297 ATH_LED_ASSOC,
298 ATH_LED_TX,
299 ATH_LED_RX
300};
301
302struct ath_led {
303 struct ath9k_htc_priv *priv;
304 struct led_classdev led_cdev;
305 enum ath_led_type led_type;
306 struct delayed_work brightness_work;
307 char name[32];
308 bool registered;
309 int brightness;
310};
311
312#define OP_INVALID BIT(0)
313#define OP_SCANNING BIT(1)
314#define OP_FULL_RESET BIT(2)
315#define OP_LED_ASSOCIATED BIT(3)
316#define OP_LED_ON BIT(4)
317#define OP_PREAMBLE_SHORT BIT(5)
318#define OP_PROTECT_ENABLE BIT(6)
319#define OP_TXAGGR BIT(7)
320#define OP_ASSOCIATED BIT(8)
321#define OP_ENABLE_BEACON BIT(9)
322#define OP_LED_DEINIT BIT(10)
323
324struct ath9k_htc_priv {
325 struct device *dev;
326 struct ieee80211_hw *hw;
327 struct ath_hw *ah;
328 struct htc_target *htc;
329 struct wmi *wmi;
330
331 enum htc_endpoint_id wmi_cmd_ep;
332 enum htc_endpoint_id beacon_ep;
333 enum htc_endpoint_id cab_ep;
334 enum htc_endpoint_id uapsd_ep;
335 enum htc_endpoint_id mgmt_ep;
336 enum htc_endpoint_id data_be_ep;
337 enum htc_endpoint_id data_bk_ep;
338 enum htc_endpoint_id data_vi_ep;
339 enum htc_endpoint_id data_vo_ep;
340
341 u16 op_flags;
342 u16 curtxpow;
343 u16 txpowlimit;
344 u16 nvifs;
345 u16 nstations;
346 u16 seq_no;
347 u32 bmiss_cnt;
348
349 struct sk_buff *beacon;
350 spinlock_t beacon_lock;
351
352 struct ieee80211_vif *vif;
353 unsigned int rxfilter;
354 struct tasklet_struct wmi_tasklet;
355 struct tasklet_struct rx_tasklet;
356 struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
357 struct ath9k_htc_rx rx;
358 struct tasklet_struct tx_tasklet;
359 struct sk_buff_head tx_queue;
360 struct ath9k_htc_aggr_work aggr_work;
361 struct delayed_work ath9k_aggr_work;
362 struct delayed_work ath9k_ani_work;
363
364 struct ath_led radio_led;
365 struct ath_led assoc_led;
366 struct ath_led tx_led;
367 struct ath_led rx_led;
368 struct delayed_work ath9k_led_blink_work;
369 int led_on_duration;
370 int led_off_duration;
371 int led_on_cnt;
372 int led_off_cnt;
373 int hwq_map[ATH9K_WME_AC_VO+1];
374
375#ifdef CONFIG_ATH9K_HTC_DEBUGFS
376 struct ath9k_debug debug;
377#endif
378 struct ath9k_htc_target_rate tgt_rate;
379
380 struct mutex mutex;
381};
382
383static inline void ath_read_cachesize(struct ath_common *common, int *csz)
384{
385 common->bus_ops->read_cachesize(common, csz);
386}
387
388void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv,
389 struct ieee80211_vif *vif,
390 struct ieee80211_bss_conf *bss_conf);
391void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending);
392void ath9k_htc_beacon_update(struct ath9k_htc_priv *priv,
393 struct ieee80211_vif *vif);
394
395void ath9k_htc_rxep(void *priv, struct sk_buff *skb,
396 enum htc_endpoint_id ep_id);
397void ath9k_htc_txep(void *priv, struct sk_buff *skb, enum htc_endpoint_id ep_id,
398 bool txok);
399
400void ath9k_htc_station_work(struct work_struct *work);
401void ath9k_htc_aggr_work(struct work_struct *work);
402void ath9k_ani_work(struct work_struct *work);;
403
404int ath9k_tx_init(struct ath9k_htc_priv *priv);
405void ath9k_tx_tasklet(unsigned long data);
406int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb);
407void ath9k_tx_cleanup(struct ath9k_htc_priv *priv);
408bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv,
409 enum ath9k_tx_queue_subtype qtype);
410int get_hw_qnum(u16 queue, int *hwq_map);
411int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum,
412 struct ath9k_tx_queue_info *qinfo);
413
414int ath9k_rx_init(struct ath9k_htc_priv *priv);
415void ath9k_rx_cleanup(struct ath9k_htc_priv *priv);
416void ath9k_host_rx_init(struct ath9k_htc_priv *priv);
417void ath9k_rx_tasklet(unsigned long data);
418
419void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv);
420void ath9k_init_leds(struct ath9k_htc_priv *priv);
421void ath9k_deinit_leds(struct ath9k_htc_priv *priv);
422
423int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
424 u16 devid);
425void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug);
426#ifdef CONFIG_PM
427int ath9k_htc_resume(struct htc_target *htc_handle);
428#endif
429#ifdef CONFIG_ATH9K_HTC_DEBUGFS
430int ath9k_htc_debug_create_root(void);
431void ath9k_htc_debug_remove_root(void);
432int ath9k_htc_init_debug(struct ath_hw *ah);
433void ath9k_htc_exit_debug(struct ath_hw *ah);
434#else
435static inline int ath9k_htc_debug_create_root(void) { return 0; };
436static inline void ath9k_htc_debug_remove_root(void) {};
437static inline int ath9k_htc_init_debug(struct ath_hw *ah) { return 0; };
438static inline void ath9k_htc_exit_debug(struct ath_hw *ah) {};
439#endif /* CONFIG_ATH9K_HTC_DEBUGFS */
440
441#endif /* HTC_H */
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
new file mode 100644
index 00000000000..25f5b5377ba
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
@@ -0,0 +1,260 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "htc.h"
18
19#define FUDGE 2
20
21static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv,
22 struct ieee80211_bss_conf *bss_conf)
23{
24 struct ath_common *common = ath9k_hw_common(priv->ah);
25 struct ath9k_beacon_state bs;
26 enum ath9k_int imask = 0;
27 int dtimperiod, dtimcount, sleepduration;
28 int cfpperiod, cfpcount, bmiss_timeout;
29 u32 nexttbtt = 0, intval, tsftu, htc_imask = 0;
30 u64 tsf;
31 int num_beacons, offset, dtim_dec_count, cfp_dec_count;
32 int ret;
33 u8 cmd_rsp;
34
35 memset(&bs, 0, sizeof(bs));
36
37 intval = bss_conf->beacon_int & ATH9K_BEACON_PERIOD;
38 bmiss_timeout = (ATH_DEFAULT_BMISS_LIMIT * bss_conf->beacon_int);
39
40 /*
41 * Setup dtim and cfp parameters according to
42 * last beacon we received (which may be none).
43 */
44 dtimperiod = bss_conf->dtim_period;
45 if (dtimperiod <= 0) /* NB: 0 if not known */
46 dtimperiod = 1;
47 dtimcount = 1;
48 if (dtimcount >= dtimperiod) /* NB: sanity check */
49 dtimcount = 0;
50 cfpperiod = 1; /* NB: no PCF support yet */
51 cfpcount = 0;
52
53 sleepduration = intval;
54 if (sleepduration <= 0)
55 sleepduration = intval;
56
57 /*
58 * Pull nexttbtt forward to reflect the current
59 * TSF and calculate dtim+cfp state for the result.
60 */
61 tsf = ath9k_hw_gettsf64(priv->ah);
62 tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE;
63
64 num_beacons = tsftu / intval + 1;
65 offset = tsftu % intval;
66 nexttbtt = tsftu - offset;
67 if (offset)
68 nexttbtt += intval;
69
70 /* DTIM Beacon every dtimperiod Beacon */
71 dtim_dec_count = num_beacons % dtimperiod;
72 /* CFP every cfpperiod DTIM Beacon */
73 cfp_dec_count = (num_beacons / dtimperiod) % cfpperiod;
74 if (dtim_dec_count)
75 cfp_dec_count++;
76
77 dtimcount -= dtim_dec_count;
78 if (dtimcount < 0)
79 dtimcount += dtimperiod;
80
81 cfpcount -= cfp_dec_count;
82 if (cfpcount < 0)
83 cfpcount += cfpperiod;
84
85 bs.bs_intval = intval;
86 bs.bs_nexttbtt = nexttbtt;
87 bs.bs_dtimperiod = dtimperiod*intval;
88 bs.bs_nextdtim = bs.bs_nexttbtt + dtimcount*intval;
89 bs.bs_cfpperiod = cfpperiod*bs.bs_dtimperiod;
90 bs.bs_cfpnext = bs.bs_nextdtim + cfpcount*bs.bs_dtimperiod;
91 bs.bs_cfpmaxduration = 0;
92
93 /*
94 * Calculate the number of consecutive beacons to miss* before taking
95 * a BMISS interrupt. The configuration is specified in TU so we only
96 * need calculate based on the beacon interval. Note that we clamp the
97 * result to at most 15 beacons.
98 */
99 if (sleepduration > intval) {
100 bs.bs_bmissthreshold = ATH_DEFAULT_BMISS_LIMIT / 2;
101 } else {
102 bs.bs_bmissthreshold = DIV_ROUND_UP(bmiss_timeout, intval);
103 if (bs.bs_bmissthreshold > 15)
104 bs.bs_bmissthreshold = 15;
105 else if (bs.bs_bmissthreshold <= 0)
106 bs.bs_bmissthreshold = 1;
107 }
108
109 /*
110 * Calculate sleep duration. The configuration is given in ms.
111 * We ensure a multiple of the beacon period is used. Also, if the sleep
112 * duration is greater than the DTIM period then it makes senses
113 * to make it a multiple of that.
114 *
115 * XXX fixed at 100ms
116 */
117
118 bs.bs_sleepduration = roundup(IEEE80211_MS_TO_TU(100), sleepduration);
119 if (bs.bs_sleepduration > bs.bs_dtimperiod)
120 bs.bs_sleepduration = bs.bs_dtimperiod;
121
122 /* TSF out of range threshold fixed at 1 second */
123 bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD;
124
125 ath_print(common, ATH_DBG_BEACON, "tsf: %llu tsftu: %u\n", tsf, tsftu);
126 ath_print(common, ATH_DBG_BEACON,
127 "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n",
128 bs.bs_bmissthreshold, bs.bs_sleepduration,
129 bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext);
130
131 /* Set the computed STA beacon timers */
132
133 WMI_CMD(WMI_DISABLE_INTR_CMDID);
134 ath9k_hw_set_sta_beacon_timers(priv->ah, &bs);
135 imask |= ATH9K_INT_BMISS;
136 htc_imask = cpu_to_be32(imask);
137 WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask);
138}
139
140static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv,
141 struct ieee80211_bss_conf *bss_conf)
142{
143 struct ath_common *common = ath9k_hw_common(priv->ah);
144 enum ath9k_int imask = 0;
145 u32 nexttbtt, intval, htc_imask = 0;
146 int ret;
147 u8 cmd_rsp;
148
149 intval = bss_conf->beacon_int & ATH9K_BEACON_PERIOD;
150 nexttbtt = intval;
151 intval |= ATH9K_BEACON_ENA;
152 if (priv->op_flags & OP_ENABLE_BEACON)
153 imask |= ATH9K_INT_SWBA;
154
155 ath_print(common, ATH_DBG_BEACON,
156 "IBSS Beacon config, intval: %d, imask: 0x%x\n",
157 bss_conf->beacon_int, imask);
158
159 WMI_CMD(WMI_DISABLE_INTR_CMDID);
160 ath9k_hw_beaconinit(priv->ah, nexttbtt, intval);
161 priv->bmiss_cnt = 0;
162 htc_imask = cpu_to_be32(imask);
163 WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask);
164}
165
166void ath9k_htc_beacon_update(struct ath9k_htc_priv *priv,
167 struct ieee80211_vif *vif)
168{
169 struct ath_common *common = ath9k_hw_common(priv->ah);
170
171 spin_lock_bh(&priv->beacon_lock);
172
173 if (priv->beacon)
174 dev_kfree_skb_any(priv->beacon);
175
176 priv->beacon = ieee80211_beacon_get(priv->hw, vif);
177 if (!priv->beacon)
178 ath_print(common, ATH_DBG_BEACON,
179 "Unable to allocate beacon\n");
180
181 spin_unlock_bh(&priv->beacon_lock);
182}
183
184void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending)
185{
186 struct ath9k_htc_vif *avp = (void *)priv->vif->drv_priv;
187 struct tx_beacon_header beacon_hdr;
188 struct ath9k_htc_tx_ctl tx_ctl;
189 struct ieee80211_tx_info *info;
190 u8 *tx_fhdr;
191
192 memset(&beacon_hdr, 0, sizeof(struct tx_beacon_header));
193 memset(&tx_ctl, 0, sizeof(struct ath9k_htc_tx_ctl));
194
195 /* FIXME: Handle BMISS */
196 if (beacon_pending != 0) {
197 priv->bmiss_cnt++;
198 return;
199 }
200
201 spin_lock_bh(&priv->beacon_lock);
202
203 if (unlikely(priv->op_flags & OP_SCANNING)) {
204 spin_unlock_bh(&priv->beacon_lock);
205 return;
206 }
207
208 if (unlikely(priv->beacon == NULL)) {
209 spin_unlock_bh(&priv->beacon_lock);
210 return;
211 }
212
213 /* Free the old SKB first */
214 dev_kfree_skb_any(priv->beacon);
215
216 /* Get a new beacon */
217 priv->beacon = ieee80211_beacon_get(priv->hw, priv->vif);
218 if (!priv->beacon) {
219 spin_unlock_bh(&priv->beacon_lock);
220 return;
221 }
222
223 info = IEEE80211_SKB_CB(priv->beacon);
224 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
225 struct ieee80211_hdr *hdr =
226 (struct ieee80211_hdr *) priv->beacon->data;
227 priv->seq_no += 0x10;
228 hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
229 hdr->seq_ctrl |= cpu_to_le16(priv->seq_no);
230 }
231
232 tx_ctl.type = ATH9K_HTC_NORMAL;
233 beacon_hdr.vif_index = avp->index;
234 tx_fhdr = skb_push(priv->beacon, sizeof(beacon_hdr));
235 memcpy(tx_fhdr, (u8 *) &beacon_hdr, sizeof(beacon_hdr));
236
237 htc_send(priv->htc, priv->beacon, priv->beacon_ep, &tx_ctl);
238
239 spin_unlock_bh(&priv->beacon_lock);
240}
241
242void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv,
243 struct ieee80211_vif *vif,
244 struct ieee80211_bss_conf *bss_conf)
245{
246 struct ath_common *common = ath9k_hw_common(priv->ah);
247
248 switch (vif->type) {
249 case NL80211_IFTYPE_STATION:
250 ath9k_htc_beacon_config_sta(priv, bss_conf);
251 break;
252 case NL80211_IFTYPE_ADHOC:
253 ath9k_htc_beacon_config_adhoc(priv, bss_conf);
254 break;
255 default:
256 ath_print(common, ATH_DBG_CONFIG,
257 "Unsupported beaconing mode\n");
258 return;
259 }
260}
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
new file mode 100644
index 00000000000..10c87605d2c
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -0,0 +1,713 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "htc.h"
18
19MODULE_AUTHOR("Atheros Communications");
20MODULE_LICENSE("Dual BSD/GPL");
21MODULE_DESCRIPTION("Atheros driver 802.11n HTC based wireless devices");
22
23static unsigned int ath9k_debug = ATH_DBG_DEFAULT;
24module_param_named(debug, ath9k_debug, uint, 0);
25MODULE_PARM_DESC(debug, "Debugging mask");
26
27int htc_modparam_nohwcrypt;
28module_param_named(nohwcrypt, htc_modparam_nohwcrypt, int, 0444);
29MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
30
31#define CHAN2G(_freq, _idx) { \
32 .center_freq = (_freq), \
33 .hw_value = (_idx), \
34 .max_power = 20, \
35}
36
37static struct ieee80211_channel ath9k_2ghz_channels[] = {
38 CHAN2G(2412, 0), /* Channel 1 */
39 CHAN2G(2417, 1), /* Channel 2 */
40 CHAN2G(2422, 2), /* Channel 3 */
41 CHAN2G(2427, 3), /* Channel 4 */
42 CHAN2G(2432, 4), /* Channel 5 */
43 CHAN2G(2437, 5), /* Channel 6 */
44 CHAN2G(2442, 6), /* Channel 7 */
45 CHAN2G(2447, 7), /* Channel 8 */
46 CHAN2G(2452, 8), /* Channel 9 */
47 CHAN2G(2457, 9), /* Channel 10 */
48 CHAN2G(2462, 10), /* Channel 11 */
49 CHAN2G(2467, 11), /* Channel 12 */
50 CHAN2G(2472, 12), /* Channel 13 */
51 CHAN2G(2484, 13), /* Channel 14 */
52};
53
54/* Atheros hardware rate code addition for short premble */
55#define SHPCHECK(__hw_rate, __flags) \
56 ((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04) : 0)
57
58#define RATE(_bitrate, _hw_rate, _flags) { \
59 .bitrate = (_bitrate), \
60 .flags = (_flags), \
61 .hw_value = (_hw_rate), \
62 .hw_value_short = (SHPCHECK(_hw_rate, _flags)) \
63}
64
65static struct ieee80211_rate ath9k_legacy_rates[] = {
66 RATE(10, 0x1b, 0),
67 RATE(20, 0x1a, IEEE80211_RATE_SHORT_PREAMBLE), /* shortp : 0x1e */
68 RATE(55, 0x19, IEEE80211_RATE_SHORT_PREAMBLE), /* shortp: 0x1d */
69 RATE(110, 0x18, IEEE80211_RATE_SHORT_PREAMBLE), /* short: 0x1c */
70 RATE(60, 0x0b, 0),
71 RATE(90, 0x0f, 0),
72 RATE(120, 0x0a, 0),
73 RATE(180, 0x0e, 0),
74 RATE(240, 0x09, 0),
75 RATE(360, 0x0d, 0),
76 RATE(480, 0x08, 0),
77 RATE(540, 0x0c, 0),
78};
79
80static int ath9k_htc_wait_for_target(struct ath9k_htc_priv *priv)
81{
82 int time_left;
83
84 /* Firmware can take up to 50ms to get ready, to be safe use 1 second */
85 time_left = wait_for_completion_timeout(&priv->htc->target_wait, HZ);
86 if (!time_left) {
87 dev_err(priv->dev, "ath9k_htc: Target is unresponsive\n");
88 return -ETIMEDOUT;
89 }
90
91 return 0;
92}
93
94static void ath9k_deinit_priv(struct ath9k_htc_priv *priv)
95{
96 ath9k_htc_exit_debug(priv->ah);
97 ath9k_hw_deinit(priv->ah);
98 tasklet_kill(&priv->wmi_tasklet);
99 tasklet_kill(&priv->rx_tasklet);
100 tasklet_kill(&priv->tx_tasklet);
101 kfree(priv->ah);
102 priv->ah = NULL;
103}
104
105static void ath9k_deinit_device(struct ath9k_htc_priv *priv)
106{
107 struct ieee80211_hw *hw = priv->hw;
108
109 wiphy_rfkill_stop_polling(hw->wiphy);
110 ath9k_deinit_leds(priv);
111 ieee80211_unregister_hw(hw);
112 ath9k_rx_cleanup(priv);
113 ath9k_tx_cleanup(priv);
114 ath9k_deinit_priv(priv);
115}
116
117static inline int ath9k_htc_connect_svc(struct ath9k_htc_priv *priv,
118 u16 service_id,
119 void (*tx) (void *,
120 struct sk_buff *,
121 enum htc_endpoint_id,
122 bool txok),
123 enum htc_endpoint_id *ep_id)
124{
125 struct htc_service_connreq req;
126
127 memset(&req, 0, sizeof(struct htc_service_connreq));
128
129 req.service_id = service_id;
130 req.ep_callbacks.priv = priv;
131 req.ep_callbacks.rx = ath9k_htc_rxep;
132 req.ep_callbacks.tx = tx;
133
134 return htc_connect_service(priv->htc, &req, ep_id);
135}
136
137static int ath9k_init_htc_services(struct ath9k_htc_priv *priv)
138{
139 int ret;
140
141 /* WMI CMD*/
142 ret = ath9k_wmi_connect(priv->htc, priv->wmi, &priv->wmi_cmd_ep);
143 if (ret)
144 goto err;
145
146 /* Beacon */
147 ret = ath9k_htc_connect_svc(priv, WMI_BEACON_SVC, NULL,
148 &priv->beacon_ep);
149 if (ret)
150 goto err;
151
152 /* CAB */
153 ret = ath9k_htc_connect_svc(priv, WMI_CAB_SVC, ath9k_htc_txep,
154 &priv->cab_ep);
155 if (ret)
156 goto err;
157
158
159 /* UAPSD */
160 ret = ath9k_htc_connect_svc(priv, WMI_UAPSD_SVC, ath9k_htc_txep,
161 &priv->uapsd_ep);
162 if (ret)
163 goto err;
164
165 /* MGMT */
166 ret = ath9k_htc_connect_svc(priv, WMI_MGMT_SVC, ath9k_htc_txep,
167 &priv->mgmt_ep);
168 if (ret)
169 goto err;
170
171 /* DATA BE */
172 ret = ath9k_htc_connect_svc(priv, WMI_DATA_BE_SVC, ath9k_htc_txep,
173 &priv->data_be_ep);
174 if (ret)
175 goto err;
176
177 /* DATA BK */
178 ret = ath9k_htc_connect_svc(priv, WMI_DATA_BK_SVC, ath9k_htc_txep,
179 &priv->data_bk_ep);
180 if (ret)
181 goto err;
182
183 /* DATA VI */
184 ret = ath9k_htc_connect_svc(priv, WMI_DATA_VI_SVC, ath9k_htc_txep,
185 &priv->data_vi_ep);
186 if (ret)
187 goto err;
188
189 /* DATA VO */
190 ret = ath9k_htc_connect_svc(priv, WMI_DATA_VO_SVC, ath9k_htc_txep,
191 &priv->data_vo_ep);
192 if (ret)
193 goto err;
194
195 ret = htc_init(priv->htc);
196 if (ret)
197 goto err;
198
199 return 0;
200
201err:
202 dev_err(priv->dev, "ath9k_htc: Unable to initialize HTC services\n");
203 return ret;
204}
205
206static int ath9k_reg_notifier(struct wiphy *wiphy,
207 struct regulatory_request *request)
208{
209 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
210 struct ath9k_htc_priv *priv = hw->priv;
211
212 return ath_reg_notifier_apply(wiphy, request,
213 ath9k_hw_regulatory(priv->ah));
214}
215
216static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset)
217{
218 struct ath_hw *ah = (struct ath_hw *) hw_priv;
219 struct ath_common *common = ath9k_hw_common(ah);
220 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
221 __be32 val, reg = cpu_to_be32(reg_offset);
222 int r;
223
224 r = ath9k_wmi_cmd(priv->wmi, WMI_REG_READ_CMDID,
225 (u8 *) &reg, sizeof(reg),
226 (u8 *) &val, sizeof(val),
227 100);
228 if (unlikely(r)) {
229 ath_print(common, ATH_DBG_WMI,
230 "REGISTER READ FAILED: (0x%04x, %d)\n",
231 reg_offset, r);
232 return -EIO;
233 }
234
235 return be32_to_cpu(val);
236}
237
238static void ath9k_iowrite32(void *hw_priv, u32 val, u32 reg_offset)
239{
240 struct ath_hw *ah = (struct ath_hw *) hw_priv;
241 struct ath_common *common = ath9k_hw_common(ah);
242 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
243 __be32 buf[2] = {
244 cpu_to_be32(reg_offset),
245 cpu_to_be32(val),
246 };
247 int r;
248
249 r = ath9k_wmi_cmd(priv->wmi, WMI_REG_WRITE_CMDID,
250 (u8 *) &buf, sizeof(buf),
251 (u8 *) &val, sizeof(val),
252 100);
253 if (unlikely(r)) {
254 ath_print(common, ATH_DBG_WMI,
255 "REGISTER WRITE FAILED:(0x%04x, %d)\n",
256 reg_offset, r);
257 }
258}
259
260static const struct ath_ops ath9k_common_ops = {
261 .read = ath9k_ioread32,
262 .write = ath9k_iowrite32,
263};
264
265static void ath_usb_read_cachesize(struct ath_common *common, int *csz)
266{
267 *csz = L1_CACHE_BYTES >> 2;
268}
269
270static bool ath_usb_eeprom_read(struct ath_common *common, u32 off, u16 *data)
271{
272 struct ath_hw *ah = (struct ath_hw *) common->ah;
273
274 (void)REG_READ(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));
275
276 if (!ath9k_hw_wait(ah,
277 AR_EEPROM_STATUS_DATA,
278 AR_EEPROM_STATUS_DATA_BUSY |
279 AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0,
280 AH_WAIT_TIMEOUT))
281 return false;
282
283 *data = MS(REG_READ(ah, AR_EEPROM_STATUS_DATA),
284 AR_EEPROM_STATUS_DATA_VAL);
285
286 return true;
287}
288
289static const struct ath_bus_ops ath9k_usb_bus_ops = {
290 .read_cachesize = ath_usb_read_cachesize,
291 .eeprom_read = ath_usb_eeprom_read,
292};
293
294static void setup_ht_cap(struct ath9k_htc_priv *priv,
295 struct ieee80211_sta_ht_cap *ht_info)
296{
297 ht_info->ht_supported = true;
298 ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
299 IEEE80211_HT_CAP_SM_PS |
300 IEEE80211_HT_CAP_SGI_40 |
301 IEEE80211_HT_CAP_DSSSCCK40;
302
303 ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
304 ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
305
306 memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
307 ht_info->mcs.rx_mask[0] = 0xff;
308 ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
309}
310
311static int ath9k_init_queues(struct ath9k_htc_priv *priv)
312{
313 struct ath_common *common = ath9k_hw_common(priv->ah);
314 int i;
315
316 for (i = 0; i < ARRAY_SIZE(priv->hwq_map); i++)
317 priv->hwq_map[i] = -1;
318
319 if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_BE)) {
320 ath_print(common, ATH_DBG_FATAL,
321 "Unable to setup xmit queue for BE traffic\n");
322 goto err;
323 }
324
325 if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_BK)) {
326 ath_print(common, ATH_DBG_FATAL,
327 "Unable to setup xmit queue for BK traffic\n");
328 goto err;
329 }
330 if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_VI)) {
331 ath_print(common, ATH_DBG_FATAL,
332 "Unable to setup xmit queue for VI traffic\n");
333 goto err;
334 }
335 if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_VO)) {
336 ath_print(common, ATH_DBG_FATAL,
337 "Unable to setup xmit queue for VO traffic\n");
338 goto err;
339 }
340
341 return 0;
342
343err:
344 return -EINVAL;
345}
346
347static void ath9k_init_crypto(struct ath9k_htc_priv *priv)
348{
349 struct ath_common *common = ath9k_hw_common(priv->ah);
350 int i = 0;
351
352 /* Get the hardware key cache size. */
353 common->keymax = priv->ah->caps.keycache_size;
354 if (common->keymax > ATH_KEYMAX) {
355 ath_print(common, ATH_DBG_ANY,
356 "Warning, using only %u entries in %u key cache\n",
357 ATH_KEYMAX, common->keymax);
358 common->keymax = ATH_KEYMAX;
359 }
360
361 /*
362 * Reset the key cache since some parts do not
363 * reset the contents on initial power up.
364 */
365 for (i = 0; i < common->keymax; i++)
366 ath9k_hw_keyreset(priv->ah, (u16) i);
367
368 if (ath9k_hw_getcapability(priv->ah, ATH9K_CAP_CIPHER,
369 ATH9K_CIPHER_TKIP, NULL)) {
370 /*
371 * Whether we should enable h/w TKIP MIC.
372 * XXX: if we don't support WME TKIP MIC, then we wouldn't
373 * report WMM capable, so it's always safe to turn on
374 * TKIP MIC in this case.
375 */
376 ath9k_hw_setcapability(priv->ah, ATH9K_CAP_TKIP_MIC, 0, 1, NULL);
377 }
378
379 /*
380 * Check whether the separate key cache entries
381 * are required to handle both tx+rx MIC keys.
382 * With split mic keys the number of stations is limited
383 * to 27 otherwise 59.
384 */
385 if (ath9k_hw_getcapability(priv->ah, ATH9K_CAP_CIPHER,
386 ATH9K_CIPHER_TKIP, NULL)
387 && ath9k_hw_getcapability(priv->ah, ATH9K_CAP_CIPHER,
388 ATH9K_CIPHER_MIC, NULL)
389 && ath9k_hw_getcapability(priv->ah, ATH9K_CAP_TKIP_SPLIT,
390 0, NULL))
391 common->splitmic = 1;
392
393 /* turn on mcast key search if possible */
394 if (!ath9k_hw_getcapability(priv->ah, ATH9K_CAP_MCAST_KEYSRCH, 0, NULL))
395 (void)ath9k_hw_setcapability(priv->ah, ATH9K_CAP_MCAST_KEYSRCH,
396 1, 1, NULL);
397}
398
399static void ath9k_init_channels_rates(struct ath9k_htc_priv *priv)
400{
401 if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes)) {
402 priv->sbands[IEEE80211_BAND_2GHZ].channels =
403 ath9k_2ghz_channels;
404 priv->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
405 priv->sbands[IEEE80211_BAND_2GHZ].n_channels =
406 ARRAY_SIZE(ath9k_2ghz_channels);
407 priv->sbands[IEEE80211_BAND_2GHZ].bitrates = ath9k_legacy_rates;
408 priv->sbands[IEEE80211_BAND_2GHZ].n_bitrates =
409 ARRAY_SIZE(ath9k_legacy_rates);
410 }
411}
412
413static void ath9k_init_misc(struct ath9k_htc_priv *priv)
414{
415 struct ath_common *common = ath9k_hw_common(priv->ah);
416
417 common->tx_chainmask = priv->ah->caps.tx_chainmask;
418 common->rx_chainmask = priv->ah->caps.rx_chainmask;
419
420 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
421 memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN);
422
423 priv->op_flags |= OP_TXAGGR;
424}
425
426static int ath9k_init_priv(struct ath9k_htc_priv *priv, u16 devid)
427{
428 struct ath_hw *ah = NULL;
429 struct ath_common *common;
430 int ret = 0, csz = 0;
431
432 priv->op_flags |= OP_INVALID;
433
434 ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL);
435 if (!ah)
436 return -ENOMEM;
437
438 ah->hw_version.devid = devid;
439 ah->hw_version.subsysid = 0; /* FIXME */
440 priv->ah = ah;
441
442 common = ath9k_hw_common(ah);
443 common->ops = &ath9k_common_ops;
444 common->bus_ops = &ath9k_usb_bus_ops;
445 common->ah = ah;
446 common->hw = priv->hw;
447 common->priv = priv;
448 common->debug_mask = ath9k_debug;
449
450 spin_lock_init(&priv->wmi->wmi_lock);
451 spin_lock_init(&priv->beacon_lock);
452 mutex_init(&priv->mutex);
453 mutex_init(&priv->aggr_work.mutex);
454 tasklet_init(&priv->wmi_tasklet, ath9k_wmi_tasklet,
455 (unsigned long)priv);
456 tasklet_init(&priv->rx_tasklet, ath9k_rx_tasklet,
457 (unsigned long)priv);
458 tasklet_init(&priv->tx_tasklet, ath9k_tx_tasklet, (unsigned long)priv);
459 INIT_DELAYED_WORK(&priv->ath9k_aggr_work, ath9k_htc_aggr_work);
460 INIT_DELAYED_WORK(&priv->ath9k_ani_work, ath9k_ani_work);
461
462 /*
463 * Cache line size is used to size and align various
464 * structures used to communicate with the hardware.
465 */
466 ath_read_cachesize(common, &csz);
467 common->cachelsz = csz << 2; /* convert to bytes */
468
469 ret = ath9k_hw_init(ah);
470 if (ret) {
471 ath_print(common, ATH_DBG_FATAL,
472 "Unable to initialize hardware; "
473 "initialization status: %d\n", ret);
474 goto err_hw;
475 }
476
477 ret = ath9k_htc_init_debug(ah);
478 if (ret) {
479 ath_print(common, ATH_DBG_FATAL,
480 "Unable to create debugfs files\n");
481 goto err_debug;
482 }
483
484 ret = ath9k_init_queues(priv);
485 if (ret)
486 goto err_queues;
487
488 ath9k_init_crypto(priv);
489 ath9k_init_channels_rates(priv);
490 ath9k_init_misc(priv);
491
492 return 0;
493
494err_queues:
495 ath9k_htc_exit_debug(ah);
496err_debug:
497 ath9k_hw_deinit(ah);
498err_hw:
499
500 kfree(ah);
501 priv->ah = NULL;
502
503 return ret;
504}
505
506static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
507 struct ieee80211_hw *hw)
508{
509 struct ath_common *common = ath9k_hw_common(priv->ah);
510
511 hw->flags = IEEE80211_HW_SIGNAL_DBM |
512 IEEE80211_HW_AMPDU_AGGREGATION |
513 IEEE80211_HW_SPECTRUM_MGMT |
514 IEEE80211_HW_HAS_RATE_CONTROL;
515
516 hw->wiphy->interface_modes =
517 BIT(NL80211_IFTYPE_STATION) |
518 BIT(NL80211_IFTYPE_ADHOC);
519
520 hw->queues = 4;
521 hw->channel_change_time = 5000;
522 hw->max_listen_interval = 10;
523 hw->vif_data_size = sizeof(struct ath9k_htc_vif);
524 hw->sta_data_size = sizeof(struct ath9k_htc_sta);
525
526 /* tx_frame_hdr is larger than tx_mgmt_hdr anyway */
527 hw->extra_tx_headroom = sizeof(struct tx_frame_hdr) +
528 sizeof(struct htc_frame_hdr) + 4;
529
530 if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes))
531 hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
532 &priv->sbands[IEEE80211_BAND_2GHZ];
533
534 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
535 if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes))
536 setup_ht_cap(priv,
537 &priv->sbands[IEEE80211_BAND_2GHZ].ht_cap);
538 }
539
540 SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
541}
542
543static int ath9k_init_device(struct ath9k_htc_priv *priv, u16 devid)
544{
545 struct ieee80211_hw *hw = priv->hw;
546 struct ath_common *common;
547 struct ath_hw *ah;
548 int error = 0;
549 struct ath_regulatory *reg;
550
551 /* Bring up device */
552 error = ath9k_init_priv(priv, devid);
553 if (error != 0)
554 goto err_init;
555
556 ah = priv->ah;
557 common = ath9k_hw_common(ah);
558 ath9k_set_hw_capab(priv, hw);
559
560 /* Initialize regulatory */
561 error = ath_regd_init(&common->regulatory, priv->hw->wiphy,
562 ath9k_reg_notifier);
563 if (error)
564 goto err_regd;
565
566 reg = &common->regulatory;
567
568 /* Setup TX */
569 error = ath9k_tx_init(priv);
570 if (error != 0)
571 goto err_tx;
572
573 /* Setup RX */
574 error = ath9k_rx_init(priv);
575 if (error != 0)
576 goto err_rx;
577
578 /* Register with mac80211 */
579 error = ieee80211_register_hw(hw);
580 if (error)
581 goto err_register;
582
583 /* Handle world regulatory */
584 if (!ath_is_world_regd(reg)) {
585 error = regulatory_hint(hw->wiphy, reg->alpha2);
586 if (error)
587 goto err_world;
588 }
589
590 ath9k_init_leds(priv);
591 ath9k_start_rfkill_poll(priv);
592
593 return 0;
594
595err_world:
596 ieee80211_unregister_hw(hw);
597err_register:
598 ath9k_rx_cleanup(priv);
599err_rx:
600 ath9k_tx_cleanup(priv);
601err_tx:
602 /* Nothing */
603err_regd:
604 ath9k_deinit_priv(priv);
605err_init:
606 return error;
607}
608
609int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
610 u16 devid)
611{
612 struct ieee80211_hw *hw;
613 struct ath9k_htc_priv *priv;
614 int ret;
615
616 hw = ieee80211_alloc_hw(sizeof(struct ath9k_htc_priv), &ath9k_htc_ops);
617 if (!hw)
618 return -ENOMEM;
619
620 priv = hw->priv;
621 priv->hw = hw;
622 priv->htc = htc_handle;
623 priv->dev = dev;
624 htc_handle->drv_priv = priv;
625 SET_IEEE80211_DEV(hw, priv->dev);
626
627 ret = ath9k_htc_wait_for_target(priv);
628 if (ret)
629 goto err_free;
630
631 priv->wmi = ath9k_init_wmi(priv);
632 if (!priv->wmi) {
633 ret = -EINVAL;
634 goto err_free;
635 }
636
637 ret = ath9k_init_htc_services(priv);
638 if (ret)
639 goto err_init;
640
641 ret = ath9k_init_device(priv, devid);
642 if (ret)
643 goto err_init;
644
645 return 0;
646
647err_init:
648 ath9k_deinit_wmi(priv);
649err_free:
650 ieee80211_free_hw(hw);
651 return ret;
652}
653
654void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug)
655{
656 if (htc_handle->drv_priv) {
657 ath9k_deinit_device(htc_handle->drv_priv);
658 ath9k_deinit_wmi(htc_handle->drv_priv);
659 ieee80211_free_hw(htc_handle->drv_priv->hw);
660 }
661}
662
663#ifdef CONFIG_PM
664int ath9k_htc_resume(struct htc_target *htc_handle)
665{
666 int ret;
667
668 ret = ath9k_htc_wait_for_target(htc_handle->drv_priv);
669 if (ret)
670 return ret;
671
672 ret = ath9k_init_htc_services(htc_handle->drv_priv);
673 return ret;
674}
675#endif
676
677static int __init ath9k_htc_init(void)
678{
679 int error;
680
681 error = ath9k_htc_debug_create_root();
682 if (error < 0) {
683 printk(KERN_ERR
684 "ath9k_htc: Unable to create debugfs root: %d\n",
685 error);
686 goto err_dbg;
687 }
688
689 error = ath9k_hif_usb_init();
690 if (error < 0) {
691 printk(KERN_ERR
692 "ath9k_htc: No USB devices found,"
693 " driver not installed.\n");
694 error = -ENODEV;
695 goto err_usb;
696 }
697
698 return 0;
699
700err_usb:
701 ath9k_htc_debug_remove_root();
702err_dbg:
703 return error;
704}
705module_init(ath9k_htc_init);
706
707static void __exit ath9k_htc_exit(void)
708{
709 ath9k_hif_usb_exit();
710 ath9k_htc_debug_remove_root();
711 printk(KERN_INFO "ath9k_htc: Driver unloaded\n");
712}
713module_exit(ath9k_htc_exit);
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
new file mode 100644
index 00000000000..20a2c1341e2
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -0,0 +1,1626 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "htc.h"
18
19#ifdef CONFIG_ATH9K_HTC_DEBUGFS
20static struct dentry *ath9k_debugfs_root;
21#endif
22
23/*************/
24/* Utilities */
25/*************/
26
27static void ath_update_txpow(struct ath9k_htc_priv *priv)
28{
29 struct ath_hw *ah = priv->ah;
30 u32 txpow;
31
32 if (priv->curtxpow != priv->txpowlimit) {
33 ath9k_hw_set_txpowerlimit(ah, priv->txpowlimit);
34 /* read back in case value is clamped */
35 ath9k_hw_getcapability(ah, ATH9K_CAP_TXPOW, 1, &txpow);
36 priv->curtxpow = txpow;
37 }
38}
39
40/* HACK Alert: Use 11NG for 2.4, use 11NA for 5 */
41static enum htc_phymode ath9k_htc_get_curmode(struct ath9k_htc_priv *priv,
42 struct ath9k_channel *ichan)
43{
44 enum htc_phymode mode;
45
46 mode = HTC_MODE_AUTO;
47
48 switch (ichan->chanmode) {
49 case CHANNEL_G:
50 case CHANNEL_G_HT20:
51 case CHANNEL_G_HT40PLUS:
52 case CHANNEL_G_HT40MINUS:
53 mode = HTC_MODE_11NG;
54 break;
55 case CHANNEL_A:
56 case CHANNEL_A_HT20:
57 case CHANNEL_A_HT40PLUS:
58 case CHANNEL_A_HT40MINUS:
59 mode = HTC_MODE_11NA;
60 break;
61 default:
62 break;
63 }
64
65 return mode;
66}
67
68static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
69 struct ieee80211_hw *hw,
70 struct ath9k_channel *hchan)
71{
72 struct ath_hw *ah = priv->ah;
73 struct ath_common *common = ath9k_hw_common(ah);
74 struct ieee80211_conf *conf = &common->hw->conf;
75 bool fastcc = true;
76 struct ieee80211_channel *channel = hw->conf.channel;
77 enum htc_phymode mode;
78 u16 htc_mode;
79 u8 cmd_rsp;
80 int ret;
81
82 if (priv->op_flags & OP_INVALID)
83 return -EIO;
84
85 if (priv->op_flags & OP_FULL_RESET)
86 fastcc = false;
87
88 /* Fiddle around with fastcc later on, for now just use full reset */
89 fastcc = false;
90
91 htc_stop(priv->htc);
92 WMI_CMD(WMI_DISABLE_INTR_CMDID);
93 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
94 WMI_CMD(WMI_STOP_RECV_CMDID);
95
96 ath_print(common, ATH_DBG_CONFIG,
97 "(%u MHz) -> (%u MHz), HT: %d, HT40: %d\n",
98 priv->ah->curchan->channel,
99 channel->center_freq, conf_is_ht(conf), conf_is_ht40(conf));
100
101 ret = ath9k_hw_reset(ah, hchan, fastcc);
102 if (ret) {
103 ath_print(common, ATH_DBG_FATAL,
104 "Unable to reset channel (%u Mhz) "
105 "reset status %d\n", channel->center_freq, ret);
106 goto err;
107 }
108
109 ath_update_txpow(priv);
110
111 WMI_CMD(WMI_START_RECV_CMDID);
112 if (ret)
113 goto err;
114
115 ath9k_host_rx_init(priv);
116
117 mode = ath9k_htc_get_curmode(priv, hchan);
118 htc_mode = cpu_to_be16(mode);
119 WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode);
120 if (ret)
121 goto err;
122
123 WMI_CMD(WMI_ENABLE_INTR_CMDID);
124 if (ret)
125 goto err;
126
127 htc_start(priv->htc);
128
129 priv->op_flags &= ~OP_FULL_RESET;
130err:
131 return ret;
132}
133
134static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv)
135{
136 struct ath_common *common = ath9k_hw_common(priv->ah);
137 struct ath9k_htc_target_vif hvif;
138 int ret = 0;
139 u8 cmd_rsp;
140
141 if (priv->nvifs > 0)
142 return -ENOBUFS;
143
144 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
145 memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
146
147 hvif.opmode = cpu_to_be32(HTC_M_MONITOR);
148 priv->ah->opmode = NL80211_IFTYPE_MONITOR;
149 hvif.index = priv->nvifs;
150
151 WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif);
152 if (ret)
153 return ret;
154
155 priv->nvifs++;
156 return 0;
157}
158
159static int ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)
160{
161 struct ath_common *common = ath9k_hw_common(priv->ah);
162 struct ath9k_htc_target_vif hvif;
163 int ret = 0;
164 u8 cmd_rsp;
165
166 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
167 memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
168 hvif.index = 0; /* Should do for now */
169 WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
170 priv->nvifs--;
171
172 return ret;
173}
174
175static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
176 struct ieee80211_vif *vif,
177 struct ieee80211_sta *sta)
178{
179 struct ath_common *common = ath9k_hw_common(priv->ah);
180 struct ath9k_htc_target_sta tsta;
181 struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *) vif->drv_priv;
182 struct ath9k_htc_sta *ista;
183 int ret;
184 u8 cmd_rsp;
185
186 if (priv->nstations >= ATH9K_HTC_MAX_STA)
187 return -ENOBUFS;
188
189 memset(&tsta, 0, sizeof(struct ath9k_htc_target_sta));
190
191 if (sta) {
192 ista = (struct ath9k_htc_sta *) sta->drv_priv;
193 memcpy(&tsta.macaddr, sta->addr, ETH_ALEN);
194 memcpy(&tsta.bssid, common->curbssid, ETH_ALEN);
195 tsta.associd = common->curaid;
196 tsta.is_vif_sta = 0;
197 tsta.valid = true;
198 ista->index = priv->nstations;
199 } else {
200 memcpy(&tsta.macaddr, vif->addr, ETH_ALEN);
201 tsta.is_vif_sta = 1;
202 }
203
204 tsta.sta_index = priv->nstations;
205 tsta.vif_index = avp->index;
206 tsta.maxampdu = 0xffff;
207 if (sta && sta->ht_cap.ht_supported)
208 tsta.flags = cpu_to_be16(ATH_HTC_STA_HT);
209
210 WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta);
211 if (ret) {
212 if (sta)
213 ath_print(common, ATH_DBG_FATAL,
214 "Unable to add station entry for: %pM\n", sta->addr);
215 return ret;
216 }
217
218 if (sta)
219 ath_print(common, ATH_DBG_CONFIG,
220 "Added a station entry for: %pM (idx: %d)\n",
221 sta->addr, tsta.sta_index);
222
223 priv->nstations++;
224 return 0;
225}
226
227static int ath9k_htc_remove_station(struct ath9k_htc_priv *priv,
228 struct ieee80211_vif *vif,
229 struct ieee80211_sta *sta)
230{
231 struct ath_common *common = ath9k_hw_common(priv->ah);
232 struct ath9k_htc_sta *ista;
233 int ret;
234 u8 cmd_rsp, sta_idx;
235
236 if (sta) {
237 ista = (struct ath9k_htc_sta *) sta->drv_priv;
238 sta_idx = ista->index;
239 } else {
240 sta_idx = 0;
241 }
242
243 WMI_CMD_BUF(WMI_NODE_REMOVE_CMDID, &sta_idx);
244 if (ret) {
245 if (sta)
246 ath_print(common, ATH_DBG_FATAL,
247 "Unable to remove station entry for: %pM\n",
248 sta->addr);
249 return ret;
250 }
251
252 if (sta)
253 ath_print(common, ATH_DBG_CONFIG,
254 "Removed a station entry for: %pM (idx: %d)\n",
255 sta->addr, sta_idx);
256
257 priv->nstations--;
258 return 0;
259}
260
261static int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv)
262{
263 struct ath9k_htc_cap_target tcap;
264 int ret;
265 u8 cmd_rsp;
266
267 memset(&tcap, 0, sizeof(struct ath9k_htc_cap_target));
268
269 /* FIXME: Values are hardcoded */
270 tcap.flags = 0x240c40;
271 tcap.flags_ext = 0x80601000;
272 tcap.ampdu_limit = 0xffff0000;
273 tcap.ampdu_subframes = 20;
274 tcap.tx_chainmask_legacy = 1;
275 tcap.protmode = 1;
276 tcap.tx_chainmask = 1;
277
278 WMI_CMD_BUF(WMI_TARGET_IC_UPDATE_CMDID, &tcap);
279
280 return ret;
281}
282
283static int ath9k_htc_init_rate(struct ath9k_htc_priv *priv,
284 struct ieee80211_vif *vif,
285 struct ieee80211_sta *sta)
286{
287 struct ath_common *common = ath9k_hw_common(priv->ah);
288 struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv;
289 struct ieee80211_supported_band *sband;
290 struct ath9k_htc_target_rate trate;
291 u32 caps = 0;
292 u8 cmd_rsp;
293 int i, j, ret;
294
295 memset(&trate, 0, sizeof(trate));
296
297 /* Only 2GHz is supported */
298 sband = priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ];
299
300 for (i = 0, j = 0; i < sband->n_bitrates; i++) {
301 if (sta->supp_rates[sband->band] & BIT(i)) {
302 priv->tgt_rate.rates.legacy_rates.rs_rates[j]
303 = (sband->bitrates[i].bitrate * 2) / 10;
304 j++;
305 }
306 }
307 priv->tgt_rate.rates.legacy_rates.rs_nrates = j;
308
309 if (sta->ht_cap.ht_supported) {
310 for (i = 0, j = 0; i < 77; i++) {
311 if (sta->ht_cap.mcs.rx_mask[i/8] & (1<<(i%8)))
312 priv->tgt_rate.rates.ht_rates.rs_rates[j++] = i;
313 if (j == ATH_HTC_RATE_MAX)
314 break;
315 }
316 priv->tgt_rate.rates.ht_rates.rs_nrates = j;
317
318 caps = WLAN_RC_HT_FLAG;
319 if (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
320 caps |= WLAN_RC_40_FLAG;
321 if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40)
322 caps |= WLAN_RC_SGI_FLAG;
323
324 }
325
326 priv->tgt_rate.sta_index = ista->index;
327 priv->tgt_rate.isnew = 1;
328 trate = priv->tgt_rate;
329 priv->tgt_rate.capflags = caps;
330 trate.capflags = cpu_to_be32(caps);
331
332 WMI_CMD_BUF(WMI_RC_RATE_UPDATE_CMDID, &trate);
333 if (ret) {
334 ath_print(common, ATH_DBG_FATAL,
335 "Unable to initialize Rate information on target\n");
336 return ret;
337 }
338
339 ath_print(common, ATH_DBG_CONFIG,
340 "Updated target STA: %pM (caps: 0x%x)\n", sta->addr, caps);
341 return 0;
342}
343
344static bool check_rc_update(struct ieee80211_hw *hw, bool *cw40)
345{
346 struct ath9k_htc_priv *priv = hw->priv;
347 struct ieee80211_conf *conf = &hw->conf;
348
349 if (!conf_is_ht(conf))
350 return false;
351
352 if (!(priv->op_flags & OP_ASSOCIATED) ||
353 (priv->op_flags & OP_SCANNING))
354 return false;
355
356 if (conf_is_ht40(conf)) {
357 if (priv->ah->curchan->chanmode &
358 (CHANNEL_HT40PLUS | CHANNEL_HT40MINUS)) {
359 return false;
360 } else {
361 *cw40 = true;
362 return true;
363 }
364 } else { /* ht20 */
365 if (priv->ah->curchan->chanmode & CHANNEL_HT20)
366 return false;
367 else
368 return true;
369 }
370}
371
372static void ath9k_htc_rc_update(struct ath9k_htc_priv *priv, bool is_cw40)
373{
374 struct ath9k_htc_target_rate trate;
375 struct ath_common *common = ath9k_hw_common(priv->ah);
376 int ret;
377 u8 cmd_rsp;
378
379 memset(&trate, 0, sizeof(trate));
380
381 trate = priv->tgt_rate;
382
383 if (is_cw40)
384 priv->tgt_rate.capflags |= WLAN_RC_40_FLAG;
385 else
386 priv->tgt_rate.capflags &= ~WLAN_RC_40_FLAG;
387
388 trate.capflags = cpu_to_be32(priv->tgt_rate.capflags);
389
390 WMI_CMD_BUF(WMI_RC_RATE_UPDATE_CMDID, &trate);
391 if (ret) {
392 ath_print(common, ATH_DBG_FATAL,
393 "Unable to update Rate information on target\n");
394 return;
395 }
396
397 ath_print(common, ATH_DBG_CONFIG, "Rate control updated with "
398 "caps:0x%x on target\n", priv->tgt_rate.capflags);
399}
400
401static int ath9k_htc_aggr_oper(struct ath9k_htc_priv *priv,
402 struct ieee80211_vif *vif,
403 u8 *sta_addr, u8 tid, bool oper)
404{
405 struct ath_common *common = ath9k_hw_common(priv->ah);
406 struct ath9k_htc_target_aggr aggr;
407 struct ieee80211_sta *sta = NULL;
408 struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv;
409 int ret = 0;
410 u8 cmd_rsp;
411
412 if (tid > ATH9K_HTC_MAX_TID)
413 return -EINVAL;
414
415 rcu_read_lock();
416 sta = ieee80211_find_sta(vif, sta_addr);
417 if (sta) {
418 ista = (struct ath9k_htc_sta *) sta->drv_priv;
419 } else {
420 rcu_read_unlock();
421 return -EINVAL;
422 }
423
424 if (!ista) {
425 rcu_read_unlock();
426 return -EINVAL;
427 }
428
429 memset(&aggr, 0, sizeof(struct ath9k_htc_target_aggr));
430
431 aggr.sta_index = ista->index;
432 rcu_read_unlock();
433 aggr.tidno = tid;
434 aggr.aggr_enable = oper;
435
436 if (oper)
437 ista->tid_state[tid] = AGGR_START;
438 else
439 ista->tid_state[tid] = AGGR_STOP;
440
441 WMI_CMD_BUF(WMI_TX_AGGR_ENABLE_CMDID, &aggr);
442 if (ret)
443 ath_print(common, ATH_DBG_CONFIG,
444 "Unable to %s TX aggregation for (%pM, %d)\n",
445 (oper) ? "start" : "stop", sta->addr, tid);
446 else
447 ath_print(common, ATH_DBG_CONFIG,
448 "%s aggregation for (%pM, %d)\n",
449 (oper) ? "Starting" : "Stopping", sta->addr, tid);
450
451 return ret;
452}
453
454void ath9k_htc_aggr_work(struct work_struct *work)
455{
456 int ret = 0;
457 struct ath9k_htc_priv *priv =
458 container_of(work, struct ath9k_htc_priv,
459 ath9k_aggr_work.work);
460 struct ath9k_htc_aggr_work *wk = &priv->aggr_work;
461
462 mutex_lock(&wk->mutex);
463
464 switch (wk->action) {
465 case IEEE80211_AMPDU_TX_START:
466 ret = ath9k_htc_aggr_oper(priv, wk->vif, wk->sta_addr,
467 wk->tid, true);
468 if (!ret)
469 ieee80211_start_tx_ba_cb(wk->vif, wk->sta_addr,
470 wk->tid);
471 break;
472 case IEEE80211_AMPDU_TX_STOP:
473 ath9k_htc_aggr_oper(priv, wk->vif, wk->sta_addr,
474 wk->tid, false);
475 ieee80211_stop_tx_ba_cb(wk->vif, wk->sta_addr, wk->tid);
476 break;
477 default:
478 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_FATAL,
479 "Unknown AMPDU action\n");
480 }
481
482 mutex_unlock(&wk->mutex);
483}
484
485/*********/
486/* DEBUG */
487/*********/
488
489#ifdef CONFIG_ATH9K_HTC_DEBUGFS
490
491static int ath9k_debugfs_open(struct inode *inode, struct file *file)
492{
493 file->private_data = inode->i_private;
494 return 0;
495}
496
497static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf,
498 size_t count, loff_t *ppos)
499{
500 struct ath9k_htc_priv *priv =
501 (struct ath9k_htc_priv *) file->private_data;
502 struct ath9k_htc_target_stats cmd_rsp;
503 char buf[512];
504 unsigned int len = 0;
505 int ret = 0;
506
507 memset(&cmd_rsp, 0, sizeof(cmd_rsp));
508
509 WMI_CMD(WMI_TGT_STATS_CMDID);
510 if (ret)
511 return -EINVAL;
512
513
514 len += snprintf(buf + len, sizeof(buf) - len,
515 "%19s : %10u\n", "TX Short Retries",
516 be32_to_cpu(cmd_rsp.tx_shortretry));
517 len += snprintf(buf + len, sizeof(buf) - len,
518 "%19s : %10u\n", "TX Long Retries",
519 be32_to_cpu(cmd_rsp.tx_longretry));
520 len += snprintf(buf + len, sizeof(buf) - len,
521 "%19s : %10u\n", "TX Xretries",
522 be32_to_cpu(cmd_rsp.tx_xretries));
523 len += snprintf(buf + len, sizeof(buf) - len,
524 "%19s : %10u\n", "TX Unaggr. Xretries",
525 be32_to_cpu(cmd_rsp.ht_txunaggr_xretry));
526 len += snprintf(buf + len, sizeof(buf) - len,
527 "%19s : %10u\n", "TX Xretries (HT)",
528 be32_to_cpu(cmd_rsp.ht_tx_xretries));
529 len += snprintf(buf + len, sizeof(buf) - len,
530 "%19s : %10u\n", "TX Rate", priv->debug.txrate);
531
532 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
533}
534
535static const struct file_operations fops_tgt_stats = {
536 .read = read_file_tgt_stats,
537 .open = ath9k_debugfs_open,
538 .owner = THIS_MODULE
539};
540
541static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
542 size_t count, loff_t *ppos)
543{
544 struct ath9k_htc_priv *priv =
545 (struct ath9k_htc_priv *) file->private_data;
546 char buf[512];
547 unsigned int len = 0;
548
549 len += snprintf(buf + len, sizeof(buf) - len,
550 "%20s : %10u\n", "Buffers queued",
551 priv->debug.tx_stats.buf_queued);
552 len += snprintf(buf + len, sizeof(buf) - len,
553 "%20s : %10u\n", "Buffers completed",
554 priv->debug.tx_stats.buf_completed);
555 len += snprintf(buf + len, sizeof(buf) - len,
556 "%20s : %10u\n", "SKBs queued",
557 priv->debug.tx_stats.skb_queued);
558 len += snprintf(buf + len, sizeof(buf) - len,
559 "%20s : %10u\n", "SKBs completed",
560 priv->debug.tx_stats.skb_completed);
561
562 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
563}
564
565static const struct file_operations fops_xmit = {
566 .read = read_file_xmit,
567 .open = ath9k_debugfs_open,
568 .owner = THIS_MODULE
569};
570
571static ssize_t read_file_recv(struct file *file, char __user *user_buf,
572 size_t count, loff_t *ppos)
573{
574 struct ath9k_htc_priv *priv =
575 (struct ath9k_htc_priv *) file->private_data;
576 char buf[512];
577 unsigned int len = 0;
578
579 len += snprintf(buf + len, sizeof(buf) - len,
580 "%20s : %10u\n", "SKBs allocated",
581 priv->debug.rx_stats.skb_allocated);
582 len += snprintf(buf + len, sizeof(buf) - len,
583 "%20s : %10u\n", "SKBs completed",
584 priv->debug.rx_stats.skb_completed);
585 len += snprintf(buf + len, sizeof(buf) - len,
586 "%20s : %10u\n", "SKBs Dropped",
587 priv->debug.rx_stats.skb_dropped);
588
589 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
590}
591
592static const struct file_operations fops_recv = {
593 .read = read_file_recv,
594 .open = ath9k_debugfs_open,
595 .owner = THIS_MODULE
596};
597
598int ath9k_htc_init_debug(struct ath_hw *ah)
599{
600 struct ath_common *common = ath9k_hw_common(ah);
601 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
602
603 if (!ath9k_debugfs_root)
604 return -ENOENT;
605
606 priv->debug.debugfs_phy = debugfs_create_dir(wiphy_name(priv->hw->wiphy),
607 ath9k_debugfs_root);
608 if (!priv->debug.debugfs_phy)
609 goto err;
610
611 priv->debug.debugfs_tgt_stats = debugfs_create_file("tgt_stats", S_IRUSR,
612 priv->debug.debugfs_phy,
613 priv, &fops_tgt_stats);
614 if (!priv->debug.debugfs_tgt_stats)
615 goto err;
616
617
618 priv->debug.debugfs_xmit = debugfs_create_file("xmit", S_IRUSR,
619 priv->debug.debugfs_phy,
620 priv, &fops_xmit);
621 if (!priv->debug.debugfs_xmit)
622 goto err;
623
624 priv->debug.debugfs_recv = debugfs_create_file("recv", S_IRUSR,
625 priv->debug.debugfs_phy,
626 priv, &fops_recv);
627 if (!priv->debug.debugfs_recv)
628 goto err;
629
630 return 0;
631
632err:
633 ath9k_htc_exit_debug(ah);
634 return -ENOMEM;
635}
636
637void ath9k_htc_exit_debug(struct ath_hw *ah)
638{
639 struct ath_common *common = ath9k_hw_common(ah);
640 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
641
642 debugfs_remove(priv->debug.debugfs_recv);
643 debugfs_remove(priv->debug.debugfs_xmit);
644 debugfs_remove(priv->debug.debugfs_tgt_stats);
645 debugfs_remove(priv->debug.debugfs_phy);
646}
647
648int ath9k_htc_debug_create_root(void)
649{
650 ath9k_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
651 if (!ath9k_debugfs_root)
652 return -ENOENT;
653
654 return 0;
655}
656
657void ath9k_htc_debug_remove_root(void)
658{
659 debugfs_remove(ath9k_debugfs_root);
660 ath9k_debugfs_root = NULL;
661}
662
663#endif /* CONFIG_ATH9K_HTC_DEBUGFS */
664
665/*******/
666/* ANI */
667/*******/
668
669static void ath_start_ani(struct ath9k_htc_priv *priv)
670{
671 struct ath_common *common = ath9k_hw_common(priv->ah);
672 unsigned long timestamp = jiffies_to_msecs(jiffies);
673
674 common->ani.longcal_timer = timestamp;
675 common->ani.shortcal_timer = timestamp;
676 common->ani.checkani_timer = timestamp;
677
678 ieee80211_queue_delayed_work(common->hw, &priv->ath9k_ani_work,
679 msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
680}
681
682void ath9k_ani_work(struct work_struct *work)
683{
684 struct ath9k_htc_priv *priv =
685 container_of(work, struct ath9k_htc_priv,
686 ath9k_ani_work.work);
687 struct ath_hw *ah = priv->ah;
688 struct ath_common *common = ath9k_hw_common(ah);
689 bool longcal = false;
690 bool shortcal = false;
691 bool aniflag = false;
692 unsigned int timestamp = jiffies_to_msecs(jiffies);
693 u32 cal_interval, short_cal_interval;
694
695 short_cal_interval = ATH_STA_SHORT_CALINTERVAL;
696
697 /* Long calibration runs independently of short calibration. */
698 if ((timestamp - common->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) {
699 longcal = true;
700 ath_print(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies);
701 common->ani.longcal_timer = timestamp;
702 }
703
704 /* Short calibration applies only while caldone is false */
705 if (!common->ani.caldone) {
706 if ((timestamp - common->ani.shortcal_timer) >=
707 short_cal_interval) {
708 shortcal = true;
709 ath_print(common, ATH_DBG_ANI,
710 "shortcal @%lu\n", jiffies);
711 common->ani.shortcal_timer = timestamp;
712 common->ani.resetcal_timer = timestamp;
713 }
714 } else {
715 if ((timestamp - common->ani.resetcal_timer) >=
716 ATH_RESTART_CALINTERVAL) {
717 common->ani.caldone = ath9k_hw_reset_calvalid(ah);
718 if (common->ani.caldone)
719 common->ani.resetcal_timer = timestamp;
720 }
721 }
722
723 /* Verify whether we must check ANI */
724 if ((timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) {
725 aniflag = true;
726 common->ani.checkani_timer = timestamp;
727 }
728
729 /* Skip all processing if there's nothing to do. */
730 if (longcal || shortcal || aniflag) {
731 /* Call ANI routine if necessary */
732 if (aniflag)
733 ath9k_hw_ani_monitor(ah, ah->curchan);
734
735 /* Perform calibration if necessary */
736 if (longcal || shortcal) {
737 common->ani.caldone =
738 ath9k_hw_calibrate(ah, ah->curchan,
739 common->rx_chainmask,
740 longcal);
741
742 if (longcal)
743 common->ani.noise_floor =
744 ath9k_hw_getchan_noise(ah, ah->curchan);
745
746 ath_print(common, ATH_DBG_ANI,
747 " calibrate chan %u/%x nf: %d\n",
748 ah->curchan->channel,
749 ah->curchan->channelFlags,
750 common->ani.noise_floor);
751 }
752 }
753
754 /*
755 * Set timer interval based on previous results.
756 * The interval must be the shortest necessary to satisfy ANI,
757 * short calibration and long calibration.
758 */
759 cal_interval = ATH_LONG_CALINTERVAL;
760 if (priv->ah->config.enable_ani)
761 cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL);
762 if (!common->ani.caldone)
763 cal_interval = min(cal_interval, (u32)short_cal_interval);
764
765 ieee80211_queue_delayed_work(common->hw, &priv->ath9k_ani_work,
766 msecs_to_jiffies(cal_interval));
767}
768
769/*******/
770/* LED */
771/*******/
772
773static void ath9k_led_blink_work(struct work_struct *work)
774{
775 struct ath9k_htc_priv *priv = container_of(work, struct ath9k_htc_priv,
776 ath9k_led_blink_work.work);
777
778 if (!(priv->op_flags & OP_LED_ASSOCIATED))
779 return;
780
781 if ((priv->led_on_duration == ATH_LED_ON_DURATION_IDLE) ||
782 (priv->led_off_duration == ATH_LED_OFF_DURATION_IDLE))
783 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0);
784 else
785 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin,
786 (priv->op_flags & OP_LED_ON) ? 1 : 0);
787
788 ieee80211_queue_delayed_work(priv->hw,
789 &priv->ath9k_led_blink_work,
790 (priv->op_flags & OP_LED_ON) ?
791 msecs_to_jiffies(priv->led_off_duration) :
792 msecs_to_jiffies(priv->led_on_duration));
793
794 priv->led_on_duration = priv->led_on_cnt ?
795 max((ATH_LED_ON_DURATION_IDLE - priv->led_on_cnt), 25) :
796 ATH_LED_ON_DURATION_IDLE;
797 priv->led_off_duration = priv->led_off_cnt ?
798 max((ATH_LED_OFF_DURATION_IDLE - priv->led_off_cnt), 10) :
799 ATH_LED_OFF_DURATION_IDLE;
800 priv->led_on_cnt = priv->led_off_cnt = 0;
801
802 if (priv->op_flags & OP_LED_ON)
803 priv->op_flags &= ~OP_LED_ON;
804 else
805 priv->op_flags |= OP_LED_ON;
806}
807
808static void ath9k_led_brightness_work(struct work_struct *work)
809{
810 struct ath_led *led = container_of(work, struct ath_led,
811 brightness_work.work);
812 struct ath9k_htc_priv *priv = led->priv;
813
814 switch (led->brightness) {
815 case LED_OFF:
816 if (led->led_type == ATH_LED_ASSOC ||
817 led->led_type == ATH_LED_RADIO) {
818 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin,
819 (led->led_type == ATH_LED_RADIO));
820 priv->op_flags &= ~OP_LED_ASSOCIATED;
821 if (led->led_type == ATH_LED_RADIO)
822 priv->op_flags &= ~OP_LED_ON;
823 } else {
824 priv->led_off_cnt++;
825 }
826 break;
827 case LED_FULL:
828 if (led->led_type == ATH_LED_ASSOC) {
829 priv->op_flags |= OP_LED_ASSOCIATED;
830 ieee80211_queue_delayed_work(priv->hw,
831 &priv->ath9k_led_blink_work, 0);
832 } else if (led->led_type == ATH_LED_RADIO) {
833 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0);
834 priv->op_flags |= OP_LED_ON;
835 } else {
836 priv->led_on_cnt++;
837 }
838 break;
839 default:
840 break;
841 }
842}
843
844static void ath9k_led_brightness(struct led_classdev *led_cdev,
845 enum led_brightness brightness)
846{
847 struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev);
848 struct ath9k_htc_priv *priv = led->priv;
849
850 led->brightness = brightness;
851 if (!(priv->op_flags & OP_LED_DEINIT))
852 ieee80211_queue_delayed_work(priv->hw,
853 &led->brightness_work, 0);
854}
855
856static void ath9k_led_stop_brightness(struct ath9k_htc_priv *priv)
857{
858 cancel_delayed_work_sync(&priv->radio_led.brightness_work);
859 cancel_delayed_work_sync(&priv->assoc_led.brightness_work);
860 cancel_delayed_work_sync(&priv->tx_led.brightness_work);
861 cancel_delayed_work_sync(&priv->rx_led.brightness_work);
862}
863
864static int ath9k_register_led(struct ath9k_htc_priv *priv, struct ath_led *led,
865 char *trigger)
866{
867 int ret;
868
869 led->priv = priv;
870 led->led_cdev.name = led->name;
871 led->led_cdev.default_trigger = trigger;
872 led->led_cdev.brightness_set = ath9k_led_brightness;
873
874 ret = led_classdev_register(wiphy_dev(priv->hw->wiphy), &led->led_cdev);
875 if (ret)
876 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_FATAL,
877 "Failed to register led:%s", led->name);
878 else
879 led->registered = 1;
880
881 INIT_DELAYED_WORK(&led->brightness_work, ath9k_led_brightness_work);
882
883 return ret;
884}
885
886static void ath9k_unregister_led(struct ath_led *led)
887{
888 if (led->registered) {
889 led_classdev_unregister(&led->led_cdev);
890 led->registered = 0;
891 }
892}
893
894void ath9k_deinit_leds(struct ath9k_htc_priv *priv)
895{
896 priv->op_flags |= OP_LED_DEINIT;
897 ath9k_unregister_led(&priv->assoc_led);
898 priv->op_flags &= ~OP_LED_ASSOCIATED;
899 ath9k_unregister_led(&priv->tx_led);
900 ath9k_unregister_led(&priv->rx_led);
901 ath9k_unregister_led(&priv->radio_led);
902 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 1);
903}
904
905void ath9k_init_leds(struct ath9k_htc_priv *priv)
906{
907 char *trigger;
908 int ret;
909
910 if (AR_SREV_9287(priv->ah))
911 priv->ah->led_pin = ATH_LED_PIN_9287;
912 else if (AR_SREV_9271(priv->ah))
913 priv->ah->led_pin = ATH_LED_PIN_9271;
914 else
915 priv->ah->led_pin = ATH_LED_PIN_DEF;
916
917 /* Configure gpio 1 for output */
918 ath9k_hw_cfg_output(priv->ah, priv->ah->led_pin,
919 AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
920 /* LED off, active low */
921 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 1);
922
923 INIT_DELAYED_WORK(&priv->ath9k_led_blink_work, ath9k_led_blink_work);
924
925 trigger = ieee80211_get_radio_led_name(priv->hw);
926 snprintf(priv->radio_led.name, sizeof(priv->radio_led.name),
927 "ath9k-%s::radio", wiphy_name(priv->hw->wiphy));
928 ret = ath9k_register_led(priv, &priv->radio_led, trigger);
929 priv->radio_led.led_type = ATH_LED_RADIO;
930 if (ret)
931 goto fail;
932
933 trigger = ieee80211_get_assoc_led_name(priv->hw);
934 snprintf(priv->assoc_led.name, sizeof(priv->assoc_led.name),
935 "ath9k-%s::assoc", wiphy_name(priv->hw->wiphy));
936 ret = ath9k_register_led(priv, &priv->assoc_led, trigger);
937 priv->assoc_led.led_type = ATH_LED_ASSOC;
938 if (ret)
939 goto fail;
940
941 trigger = ieee80211_get_tx_led_name(priv->hw);
942 snprintf(priv->tx_led.name, sizeof(priv->tx_led.name),
943 "ath9k-%s::tx", wiphy_name(priv->hw->wiphy));
944 ret = ath9k_register_led(priv, &priv->tx_led, trigger);
945 priv->tx_led.led_type = ATH_LED_TX;
946 if (ret)
947 goto fail;
948
949 trigger = ieee80211_get_rx_led_name(priv->hw);
950 snprintf(priv->rx_led.name, sizeof(priv->rx_led.name),
951 "ath9k-%s::rx", wiphy_name(priv->hw->wiphy));
952 ret = ath9k_register_led(priv, &priv->rx_led, trigger);
953 priv->rx_led.led_type = ATH_LED_RX;
954 if (ret)
955 goto fail;
956
957 priv->op_flags &= ~OP_LED_DEINIT;
958
959 return;
960
961fail:
962 cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
963 ath9k_deinit_leds(priv);
964}
965
966/*******************/
967/* Rfkill */
968/*******************/
969
970static bool ath_is_rfkill_set(struct ath9k_htc_priv *priv)
971{
972 return ath9k_hw_gpio_get(priv->ah, priv->ah->rfkill_gpio) ==
973 priv->ah->rfkill_polarity;
974}
975
976static void ath9k_htc_rfkill_poll_state(struct ieee80211_hw *hw)
977{
978 struct ath9k_htc_priv *priv = hw->priv;
979 bool blocked = !!ath_is_rfkill_set(priv);
980
981 wiphy_rfkill_set_hw_state(hw->wiphy, blocked);
982}
983
984void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv)
985{
986 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
987 wiphy_rfkill_start_polling(priv->hw->wiphy);
988}
989
990/**********************/
991/* mac80211 Callbacks */
992/**********************/
993
994static int ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
995{
996 struct ieee80211_hdr *hdr;
997 struct ath9k_htc_priv *priv = hw->priv;
998 int padpos, padsize;
999
1000 hdr = (struct ieee80211_hdr *) skb->data;
1001
1002 /* Add the padding after the header if this is not already done */
1003 padpos = ath9k_cmn_padpos(hdr->frame_control);
1004 padsize = padpos & 3;
1005 if (padsize && skb->len > padpos) {
1006 if (skb_headroom(skb) < padsize)
1007 return -1;
1008 skb_push(skb, padsize);
1009 memmove(skb->data, skb->data + padsize, padpos);
1010 }
1011
1012 if (ath9k_htc_tx_start(priv, skb) != 0) {
1013 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_XMIT, "Tx failed");
1014 goto fail_tx;
1015 }
1016
1017 return 0;
1018
1019fail_tx:
1020 dev_kfree_skb_any(skb);
1021 return 0;
1022}
1023
1024static int ath9k_htc_start(struct ieee80211_hw *hw)
1025{
1026 struct ath9k_htc_priv *priv = hw->priv;
1027 struct ath_hw *ah = priv->ah;
1028 struct ath_common *common = ath9k_hw_common(ah);
1029 struct ieee80211_channel *curchan = hw->conf.channel;
1030 struct ath9k_channel *init_channel;
1031 int ret = 0;
1032 enum htc_phymode mode;
1033 u16 htc_mode;
1034 u8 cmd_rsp;
1035
1036 ath_print(common, ATH_DBG_CONFIG,
1037 "Starting driver with initial channel: %d MHz\n",
1038 curchan->center_freq);
1039
1040 mutex_lock(&priv->mutex);
1041
1042 /* setup initial channel */
1043 init_channel = ath9k_cmn_get_curchannel(hw, ah);
1044
1045 /* Reset SERDES registers */
1046 ath9k_hw_configpcipowersave(ah, 0, 0);
1047
1048 ath9k_hw_htc_resetinit(ah);
1049 ret = ath9k_hw_reset(ah, init_channel, false);
1050 if (ret) {
1051 ath_print(common, ATH_DBG_FATAL,
1052 "Unable to reset hardware; reset status %d "
1053 "(freq %u MHz)\n", ret, curchan->center_freq);
1054 goto mutex_unlock;
1055 }
1056
1057 ath_update_txpow(priv);
1058
1059 mode = ath9k_htc_get_curmode(priv, init_channel);
1060 htc_mode = cpu_to_be16(mode);
1061 WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode);
1062 if (ret)
1063 goto mutex_unlock;
1064
1065 WMI_CMD(WMI_ATH_INIT_CMDID);
1066 if (ret)
1067 goto mutex_unlock;
1068
1069 WMI_CMD(WMI_START_RECV_CMDID);
1070 if (ret)
1071 goto mutex_unlock;
1072
1073 ath9k_host_rx_init(priv);
1074
1075 priv->op_flags &= ~OP_INVALID;
1076 htc_start(priv->htc);
1077
1078mutex_unlock:
1079 mutex_unlock(&priv->mutex);
1080 return ret;
1081}
1082
1083static void ath9k_htc_stop(struct ieee80211_hw *hw)
1084{
1085 struct ath9k_htc_priv *priv = hw->priv;
1086 struct ath_hw *ah = priv->ah;
1087 struct ath_common *common = ath9k_hw_common(ah);
1088 int ret = 0;
1089 u8 cmd_rsp;
1090
1091 mutex_lock(&priv->mutex);
1092
1093 if (priv->op_flags & OP_INVALID) {
1094 ath_print(common, ATH_DBG_ANY, "Device not present\n");
1095 mutex_unlock(&priv->mutex);
1096 return;
1097 }
1098
1099 htc_stop(priv->htc);
1100 WMI_CMD(WMI_DISABLE_INTR_CMDID);
1101 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
1102 WMI_CMD(WMI_STOP_RECV_CMDID);
1103 ath9k_hw_phy_disable(ah);
1104 ath9k_hw_disable(ah);
1105 ath9k_hw_configpcipowersave(ah, 1, 1);
1106 ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
1107
1108 cancel_delayed_work_sync(&priv->ath9k_ani_work);
1109 cancel_delayed_work_sync(&priv->ath9k_aggr_work);
1110 cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
1111 ath9k_led_stop_brightness(priv);
1112 skb_queue_purge(&priv->tx_queue);
1113
1114 /* Remove monitor interface here */
1115 if (ah->opmode == NL80211_IFTYPE_MONITOR) {
1116 if (ath9k_htc_remove_monitor_interface(priv))
1117 ath_print(common, ATH_DBG_FATAL,
1118 "Unable to remove monitor interface\n");
1119 else
1120 ath_print(common, ATH_DBG_CONFIG,
1121 "Monitor interface removed\n");
1122 }
1123
1124 priv->op_flags |= OP_INVALID;
1125 mutex_unlock(&priv->mutex);
1126
1127 ath_print(common, ATH_DBG_CONFIG, "Driver halt\n");
1128}
1129
1130static int ath9k_htc_add_interface(struct ieee80211_hw *hw,
1131 struct ieee80211_vif *vif)
1132{
1133 struct ath9k_htc_priv *priv = hw->priv;
1134 struct ath9k_htc_vif *avp = (void *)vif->drv_priv;
1135 struct ath_common *common = ath9k_hw_common(priv->ah);
1136 struct ath9k_htc_target_vif hvif;
1137 int ret = 0;
1138 u8 cmd_rsp;
1139
1140 mutex_lock(&priv->mutex);
1141
1142 /* Only one interface for now */
1143 if (priv->nvifs > 0) {
1144 ret = -ENOBUFS;
1145 goto out;
1146 }
1147
1148 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
1149 memcpy(&hvif.myaddr, vif->addr, ETH_ALEN);
1150
1151 switch (vif->type) {
1152 case NL80211_IFTYPE_STATION:
1153 hvif.opmode = cpu_to_be32(HTC_M_STA);
1154 break;
1155 case NL80211_IFTYPE_ADHOC:
1156 hvif.opmode = cpu_to_be32(HTC_M_IBSS);
1157 break;
1158 default:
1159 ath_print(common, ATH_DBG_FATAL,
1160 "Interface type %d not yet supported\n", vif->type);
1161 ret = -EOPNOTSUPP;
1162 goto out;
1163 }
1164
1165 ath_print(common, ATH_DBG_CONFIG,
1166 "Attach a VIF of type: %d\n", vif->type);
1167
1168 priv->ah->opmode = vif->type;
1169
1170 /* Index starts from zero on the target */
1171 avp->index = hvif.index = priv->nvifs;
1172 hvif.rtsthreshold = cpu_to_be16(2304);
1173 WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif);
1174 if (ret)
1175 goto out;
1176
1177 priv->nvifs++;
1178
1179 /*
1180 * We need a node in target to tx mgmt frames
1181 * before association.
1182 */
1183 ret = ath9k_htc_add_station(priv, vif, NULL);
1184 if (ret)
1185 goto out;
1186
1187 ret = ath9k_htc_update_cap_target(priv);
1188 if (ret)
1189 ath_print(common, ATH_DBG_CONFIG, "Failed to update"
1190 " capability in target \n");
1191
1192 priv->vif = vif;
1193out:
1194 mutex_unlock(&priv->mutex);
1195 return ret;
1196}
1197
1198static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
1199 struct ieee80211_vif *vif)
1200{
1201 struct ath9k_htc_priv *priv = hw->priv;
1202 struct ath_common *common = ath9k_hw_common(priv->ah);
1203 struct ath9k_htc_vif *avp = (void *)vif->drv_priv;
1204 struct ath9k_htc_target_vif hvif;
1205 int ret = 0;
1206 u8 cmd_rsp;
1207
1208 ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n");
1209
1210 mutex_lock(&priv->mutex);
1211
1212 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
1213 memcpy(&hvif.myaddr, vif->addr, ETH_ALEN);
1214 hvif.index = avp->index;
1215 WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
1216 priv->nvifs--;
1217
1218 ath9k_htc_remove_station(priv, vif, NULL);
1219
1220 if (vif->type == NL80211_IFTYPE_ADHOC) {
1221 spin_lock_bh(&priv->beacon_lock);
1222 if (priv->beacon)
1223 dev_kfree_skb_any(priv->beacon);
1224 priv->beacon = NULL;
1225 spin_unlock_bh(&priv->beacon_lock);
1226 }
1227
1228 priv->vif = NULL;
1229
1230 mutex_unlock(&priv->mutex);
1231}
1232
1233static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
1234{
1235 struct ath9k_htc_priv *priv = hw->priv;
1236 struct ath_common *common = ath9k_hw_common(priv->ah);
1237 struct ieee80211_conf *conf = &hw->conf;
1238
1239 mutex_lock(&priv->mutex);
1240
1241 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
1242 struct ieee80211_channel *curchan = hw->conf.channel;
1243 int pos = curchan->hw_value;
1244 bool is_cw40 = false;
1245
1246 ath_print(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n",
1247 curchan->center_freq);
1248
1249 if (check_rc_update(hw, &is_cw40))
1250 ath9k_htc_rc_update(priv, is_cw40);
1251
1252 ath9k_cmn_update_ichannel(hw, &priv->ah->channels[pos]);
1253
1254 if (ath9k_htc_set_channel(priv, hw, &priv->ah->channels[pos]) < 0) {
1255 ath_print(common, ATH_DBG_FATAL,
1256 "Unable to set channel\n");
1257 mutex_unlock(&priv->mutex);
1258 return -EINVAL;
1259 }
1260
1261 }
1262
1263 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
1264 if (conf->flags & IEEE80211_CONF_MONITOR) {
1265 if (ath9k_htc_add_monitor_interface(priv))
1266 ath_print(common, ATH_DBG_FATAL,
1267 "Failed to set monitor mode\n");
1268 else
1269 ath_print(common, ATH_DBG_CONFIG,
1270 "HW opmode set to Monitor mode\n");
1271 }
1272 }
1273
1274 mutex_unlock(&priv->mutex);
1275
1276 return 0;
1277}
1278
1279#define SUPPORTED_FILTERS \
1280 (FIF_PROMISC_IN_BSS | \
1281 FIF_ALLMULTI | \
1282 FIF_CONTROL | \
1283 FIF_PSPOLL | \
1284 FIF_OTHER_BSS | \
1285 FIF_BCN_PRBRESP_PROMISC | \
1286 FIF_FCSFAIL)
1287
1288static void ath9k_htc_configure_filter(struct ieee80211_hw *hw,
1289 unsigned int changed_flags,
1290 unsigned int *total_flags,
1291 u64 multicast)
1292{
1293 struct ath9k_htc_priv *priv = hw->priv;
1294 u32 rfilt;
1295
1296 mutex_lock(&priv->mutex);
1297
1298 changed_flags &= SUPPORTED_FILTERS;
1299 *total_flags &= SUPPORTED_FILTERS;
1300
1301 priv->rxfilter = *total_flags;
1302 rfilt = ath9k_cmn_calcrxfilter(hw, priv->ah, priv->rxfilter);
1303 ath9k_hw_setrxfilter(priv->ah, rfilt);
1304
1305 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_CONFIG,
1306 "Set HW RX filter: 0x%x\n", rfilt);
1307
1308 mutex_unlock(&priv->mutex);
1309}
1310
1311static void ath9k_htc_sta_notify(struct ieee80211_hw *hw,
1312 struct ieee80211_vif *vif,
1313 enum sta_notify_cmd cmd,
1314 struct ieee80211_sta *sta)
1315{
1316 struct ath9k_htc_priv *priv = hw->priv;
1317 int ret;
1318
1319 switch (cmd) {
1320 case STA_NOTIFY_ADD:
1321 ret = ath9k_htc_add_station(priv, vif, sta);
1322 if (!ret)
1323 ath9k_htc_init_rate(priv, vif, sta);
1324 break;
1325 case STA_NOTIFY_REMOVE:
1326 ath9k_htc_remove_station(priv, vif, sta);
1327 break;
1328 default:
1329 break;
1330 }
1331}
1332
1333static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, u16 queue,
1334 const struct ieee80211_tx_queue_params *params)
1335{
1336 struct ath9k_htc_priv *priv = hw->priv;
1337 struct ath_common *common = ath9k_hw_common(priv->ah);
1338 struct ath9k_tx_queue_info qi;
1339 int ret = 0, qnum;
1340
1341 if (queue >= WME_NUM_AC)
1342 return 0;
1343
1344 mutex_lock(&priv->mutex);
1345
1346 memset(&qi, 0, sizeof(struct ath9k_tx_queue_info));
1347
1348 qi.tqi_aifs = params->aifs;
1349 qi.tqi_cwmin = params->cw_min;
1350 qi.tqi_cwmax = params->cw_max;
1351 qi.tqi_burstTime = params->txop;
1352
1353 qnum = get_hw_qnum(queue, priv->hwq_map);
1354
1355 ath_print(common, ATH_DBG_CONFIG,
1356 "Configure tx [queue/hwq] [%d/%d], "
1357 "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
1358 queue, qnum, params->aifs, params->cw_min,
1359 params->cw_max, params->txop);
1360
1361 ret = ath_htc_txq_update(priv, qnum, &qi);
1362 if (ret)
1363 ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n");
1364
1365 mutex_unlock(&priv->mutex);
1366
1367 return ret;
1368}
1369
1370static int ath9k_htc_set_key(struct ieee80211_hw *hw,
1371 enum set_key_cmd cmd,
1372 struct ieee80211_vif *vif,
1373 struct ieee80211_sta *sta,
1374 struct ieee80211_key_conf *key)
1375{
1376 struct ath9k_htc_priv *priv = hw->priv;
1377 struct ath_common *common = ath9k_hw_common(priv->ah);
1378 int ret = 0;
1379
1380 if (htc_modparam_nohwcrypt)
1381 return -ENOSPC;
1382
1383 mutex_lock(&priv->mutex);
1384 ath_print(common, ATH_DBG_CONFIG, "Set HW Key\n");
1385
1386 switch (cmd) {
1387 case SET_KEY:
1388 ret = ath9k_cmn_key_config(common, vif, sta, key);
1389 if (ret >= 0) {
1390 key->hw_key_idx = ret;
1391 /* push IV and Michael MIC generation to stack */
1392 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
1393 if (key->alg == ALG_TKIP)
1394 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
1395 if (priv->ah->sw_mgmt_crypto && key->alg == ALG_CCMP)
1396 key->flags |= IEEE80211_KEY_FLAG_SW_MGMT;
1397 ret = 0;
1398 }
1399 break;
1400 case DISABLE_KEY:
1401 ath9k_cmn_key_delete(common, key);
1402 break;
1403 default:
1404 ret = -EINVAL;
1405 }
1406
1407 mutex_unlock(&priv->mutex);
1408
1409 return ret;
1410}
1411
1412static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
1413 struct ieee80211_vif *vif,
1414 struct ieee80211_bss_conf *bss_conf,
1415 u32 changed)
1416{
1417 struct ath9k_htc_priv *priv = hw->priv;
1418 struct ath_hw *ah = priv->ah;
1419 struct ath_common *common = ath9k_hw_common(ah);
1420
1421 mutex_lock(&priv->mutex);
1422
1423 if (changed & BSS_CHANGED_ASSOC) {
1424 common->curaid = bss_conf->assoc ?
1425 bss_conf->aid : 0;
1426 ath_print(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
1427 bss_conf->assoc);
1428
1429 if (bss_conf->assoc) {
1430 priv->op_flags |= OP_ASSOCIATED;
1431 ath_start_ani(priv);
1432 } else {
1433 priv->op_flags &= ~OP_ASSOCIATED;
1434 cancel_delayed_work_sync(&priv->ath9k_ani_work);
1435 }
1436 }
1437
1438 if (changed & BSS_CHANGED_BSSID) {
1439 /* Set BSSID */
1440 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
1441 ath9k_hw_write_associd(ah);
1442
1443 ath_print(common, ATH_DBG_CONFIG,
1444 "BSSID: %pM aid: 0x%x\n",
1445 common->curbssid, common->curaid);
1446 }
1447
1448 if ((changed & BSS_CHANGED_BEACON_INT) ||
1449 (changed & BSS_CHANGED_BEACON) ||
1450 ((changed & BSS_CHANGED_BEACON_ENABLED) &&
1451 bss_conf->enable_beacon)) {
1452 priv->op_flags |= OP_ENABLE_BEACON;
1453 ath9k_htc_beacon_config(priv, vif, bss_conf);
1454 }
1455
1456 if (changed & BSS_CHANGED_BEACON)
1457 ath9k_htc_beacon_update(priv, vif);
1458
1459 if ((changed & BSS_CHANGED_BEACON_ENABLED) &&
1460 !bss_conf->enable_beacon) {
1461 priv->op_flags &= ~OP_ENABLE_BEACON;
1462 ath9k_htc_beacon_config(priv, vif, bss_conf);
1463 }
1464
1465 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
1466 ath_print(common, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n",
1467 bss_conf->use_short_preamble);
1468 if (bss_conf->use_short_preamble)
1469 priv->op_flags |= OP_PREAMBLE_SHORT;
1470 else
1471 priv->op_flags &= ~OP_PREAMBLE_SHORT;
1472 }
1473
1474 if (changed & BSS_CHANGED_ERP_CTS_PROT) {
1475 ath_print(common, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n",
1476 bss_conf->use_cts_prot);
1477 if (bss_conf->use_cts_prot &&
1478 hw->conf.channel->band != IEEE80211_BAND_5GHZ)
1479 priv->op_flags |= OP_PROTECT_ENABLE;
1480 else
1481 priv->op_flags &= ~OP_PROTECT_ENABLE;
1482 }
1483
1484 if (changed & BSS_CHANGED_ERP_SLOT) {
1485 if (bss_conf->use_short_slot)
1486 ah->slottime = 9;
1487 else
1488 ah->slottime = 20;
1489
1490 ath9k_hw_init_global_settings(ah);
1491 }
1492
1493 mutex_unlock(&priv->mutex);
1494}
1495
1496static u64 ath9k_htc_get_tsf(struct ieee80211_hw *hw)
1497{
1498 struct ath9k_htc_priv *priv = hw->priv;
1499 u64 tsf;
1500
1501 mutex_lock(&priv->mutex);
1502 tsf = ath9k_hw_gettsf64(priv->ah);
1503 mutex_unlock(&priv->mutex);
1504
1505 return tsf;
1506}
1507
1508static void ath9k_htc_set_tsf(struct ieee80211_hw *hw, u64 tsf)
1509{
1510 struct ath9k_htc_priv *priv = hw->priv;
1511
1512 mutex_lock(&priv->mutex);
1513 ath9k_hw_settsf64(priv->ah, tsf);
1514 mutex_unlock(&priv->mutex);
1515}
1516
1517static void ath9k_htc_reset_tsf(struct ieee80211_hw *hw)
1518{
1519 struct ath9k_htc_priv *priv = hw->priv;
1520
1521 mutex_lock(&priv->mutex);
1522 ath9k_hw_reset_tsf(priv->ah);
1523 mutex_unlock(&priv->mutex);
1524}
1525
1526static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
1527 struct ieee80211_vif *vif,
1528 enum ieee80211_ampdu_mlme_action action,
1529 struct ieee80211_sta *sta,
1530 u16 tid, u16 *ssn)
1531{
1532 struct ath9k_htc_priv *priv = hw->priv;
1533 struct ath9k_htc_aggr_work *work = &priv->aggr_work;
1534 struct ath9k_htc_sta *ista;
1535
1536 switch (action) {
1537 case IEEE80211_AMPDU_RX_START:
1538 break;
1539 case IEEE80211_AMPDU_RX_STOP:
1540 break;
1541 case IEEE80211_AMPDU_TX_START:
1542 case IEEE80211_AMPDU_TX_STOP:
1543 if (!(priv->op_flags & OP_TXAGGR))
1544 return -ENOTSUPP;
1545 memcpy(work->sta_addr, sta->addr, ETH_ALEN);
1546 work->hw = hw;
1547 work->vif = vif;
1548 work->action = action;
1549 work->tid = tid;
1550 ieee80211_queue_delayed_work(hw, &priv->ath9k_aggr_work, 0);
1551 break;
1552 case IEEE80211_AMPDU_TX_OPERATIONAL:
1553 ista = (struct ath9k_htc_sta *) sta->drv_priv;
1554 ista->tid_state[tid] = AGGR_OPERATIONAL;
1555 break;
1556 default:
1557 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_FATAL,
1558 "Unknown AMPDU action\n");
1559 }
1560
1561 return 0;
1562}
1563
1564static void ath9k_htc_sw_scan_start(struct ieee80211_hw *hw)
1565{
1566 struct ath9k_htc_priv *priv = hw->priv;
1567
1568 mutex_lock(&priv->mutex);
1569 spin_lock_bh(&priv->beacon_lock);
1570 priv->op_flags |= OP_SCANNING;
1571 spin_unlock_bh(&priv->beacon_lock);
1572 cancel_delayed_work_sync(&priv->ath9k_ani_work);
1573 mutex_unlock(&priv->mutex);
1574}
1575
1576static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw)
1577{
1578 struct ath9k_htc_priv *priv = hw->priv;
1579
1580 mutex_lock(&priv->mutex);
1581 spin_lock_bh(&priv->beacon_lock);
1582 priv->op_flags &= ~OP_SCANNING;
1583 spin_unlock_bh(&priv->beacon_lock);
1584 priv->op_flags |= OP_FULL_RESET;
1585 ath_start_ani(priv);
1586 mutex_unlock(&priv->mutex);
1587}
1588
1589static int ath9k_htc_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
1590{
1591 return 0;
1592}
1593
1594static void ath9k_htc_set_coverage_class(struct ieee80211_hw *hw,
1595 u8 coverage_class)
1596{
1597 struct ath9k_htc_priv *priv = hw->priv;
1598
1599 mutex_lock(&priv->mutex);
1600 priv->ah->coverage_class = coverage_class;
1601 ath9k_hw_init_global_settings(priv->ah);
1602 mutex_unlock(&priv->mutex);
1603}
1604
1605struct ieee80211_ops ath9k_htc_ops = {
1606 .tx = ath9k_htc_tx,
1607 .start = ath9k_htc_start,
1608 .stop = ath9k_htc_stop,
1609 .add_interface = ath9k_htc_add_interface,
1610 .remove_interface = ath9k_htc_remove_interface,
1611 .config = ath9k_htc_config,
1612 .configure_filter = ath9k_htc_configure_filter,
1613 .sta_notify = ath9k_htc_sta_notify,
1614 .conf_tx = ath9k_htc_conf_tx,
1615 .bss_info_changed = ath9k_htc_bss_info_changed,
1616 .set_key = ath9k_htc_set_key,
1617 .get_tsf = ath9k_htc_get_tsf,
1618 .set_tsf = ath9k_htc_set_tsf,
1619 .reset_tsf = ath9k_htc_reset_tsf,
1620 .ampdu_action = ath9k_htc_ampdu_action,
1621 .sw_scan_start = ath9k_htc_sw_scan_start,
1622 .sw_scan_complete = ath9k_htc_sw_scan_complete,
1623 .set_rts_threshold = ath9k_htc_set_rts_threshold,
1624 .rfkill_poll = ath9k_htc_rfkill_poll_state,
1625 .set_coverage_class = ath9k_htc_set_coverage_class,
1626};
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
new file mode 100644
index 00000000000..ac66cf0b2d5
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
@@ -0,0 +1,604 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "htc.h"
18
19/******/
20/* TX */
21/******/
22
23int get_hw_qnum(u16 queue, int *hwq_map)
24{
25 switch (queue) {
26 case 0:
27 return hwq_map[ATH9K_WME_AC_VO];
28 case 1:
29 return hwq_map[ATH9K_WME_AC_VI];
30 case 2:
31 return hwq_map[ATH9K_WME_AC_BE];
32 case 3:
33 return hwq_map[ATH9K_WME_AC_BK];
34 default:
35 return hwq_map[ATH9K_WME_AC_BE];
36 }
37}
38
39int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum,
40 struct ath9k_tx_queue_info *qinfo)
41{
42 struct ath_hw *ah = priv->ah;
43 int error = 0;
44 struct ath9k_tx_queue_info qi;
45
46 ath9k_hw_get_txq_props(ah, qnum, &qi);
47
48 qi.tqi_aifs = qinfo->tqi_aifs;
49 qi.tqi_cwmin = qinfo->tqi_cwmin / 2; /* XXX */
50 qi.tqi_cwmax = qinfo->tqi_cwmax;
51 qi.tqi_burstTime = qinfo->tqi_burstTime;
52 qi.tqi_readyTime = qinfo->tqi_readyTime;
53
54 if (!ath9k_hw_set_txq_props(ah, qnum, &qi)) {
55 ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
56 "Unable to update hardware queue %u!\n", qnum);
57 error = -EIO;
58 } else {
59 ath9k_hw_resettxqueue(ah, qnum);
60 }
61
62 return error;
63}
64
65int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb)
66{
67 struct ieee80211_hdr *hdr;
68 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
69 struct ieee80211_sta *sta = tx_info->control.sta;
70 struct ath9k_htc_sta *ista;
71 struct ath9k_htc_vif *avp;
72 struct ath9k_htc_tx_ctl tx_ctl;
73 enum htc_endpoint_id epid;
74 u16 qnum, hw_qnum;
75 __le16 fc;
76 u8 *tx_fhdr;
77 u8 sta_idx;
78
79 hdr = (struct ieee80211_hdr *) skb->data;
80 fc = hdr->frame_control;
81
82 avp = (struct ath9k_htc_vif *) tx_info->control.vif->drv_priv;
83 if (sta) {
84 ista = (struct ath9k_htc_sta *) sta->drv_priv;
85 sta_idx = ista->index;
86 } else {
87 sta_idx = 0;
88 }
89
90 memset(&tx_ctl, 0, sizeof(struct ath9k_htc_tx_ctl));
91
92 if (ieee80211_is_data(fc)) {
93 struct tx_frame_hdr tx_hdr;
94 u8 *qc;
95
96 memset(&tx_hdr, 0, sizeof(struct tx_frame_hdr));
97
98 tx_hdr.node_idx = sta_idx;
99 tx_hdr.vif_idx = avp->index;
100
101 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
102 tx_ctl.type = ATH9K_HTC_AMPDU;
103 tx_hdr.data_type = ATH9K_HTC_AMPDU;
104 } else {
105 tx_ctl.type = ATH9K_HTC_NORMAL;
106 tx_hdr.data_type = ATH9K_HTC_NORMAL;
107 }
108
109 if (ieee80211_is_data(fc)) {
110 qc = ieee80211_get_qos_ctl(hdr);
111 tx_hdr.tidno = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
112 }
113
114 /* Check for RTS protection */
115 if (priv->hw->wiphy->rts_threshold != (u32) -1)
116 if (skb->len > priv->hw->wiphy->rts_threshold)
117 tx_hdr.flags |= ATH9K_HTC_TX_RTSCTS;
118
119 /* CTS-to-self */
120 if (!(tx_hdr.flags & ATH9K_HTC_TX_RTSCTS) &&
121 (priv->op_flags & OP_PROTECT_ENABLE))
122 tx_hdr.flags |= ATH9K_HTC_TX_CTSONLY;
123
124 tx_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb);
125 if (tx_hdr.key_type == ATH9K_KEY_TYPE_CLEAR)
126 tx_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID;
127 else
128 tx_hdr.keyix = tx_info->control.hw_key->hw_key_idx;
129
130 tx_fhdr = skb_push(skb, sizeof(tx_hdr));
131 memcpy(tx_fhdr, (u8 *) &tx_hdr, sizeof(tx_hdr));
132
133 qnum = skb_get_queue_mapping(skb);
134 hw_qnum = get_hw_qnum(qnum, priv->hwq_map);
135
136 switch (hw_qnum) {
137 case 0:
138 epid = priv->data_be_ep;
139 break;
140 case 2:
141 epid = priv->data_vi_ep;
142 break;
143 case 3:
144 epid = priv->data_vo_ep;
145 break;
146 case 1:
147 default:
148 epid = priv->data_bk_ep;
149 break;
150 }
151 } else {
152 struct tx_mgmt_hdr mgmt_hdr;
153
154 memset(&mgmt_hdr, 0, sizeof(struct tx_mgmt_hdr));
155
156 tx_ctl.type = ATH9K_HTC_NORMAL;
157
158 mgmt_hdr.node_idx = sta_idx;
159 mgmt_hdr.vif_idx = avp->index;
160 mgmt_hdr.tidno = 0;
161 mgmt_hdr.flags = 0;
162
163 mgmt_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb);
164 if (mgmt_hdr.key_type == ATH9K_KEY_TYPE_CLEAR)
165 mgmt_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID;
166 else
167 mgmt_hdr.keyix = tx_info->control.hw_key->hw_key_idx;
168
169 tx_fhdr = skb_push(skb, sizeof(mgmt_hdr));
170 memcpy(tx_fhdr, (u8 *) &mgmt_hdr, sizeof(mgmt_hdr));
171 epid = priv->mgmt_ep;
172 }
173
174 return htc_send(priv->htc, skb, epid, &tx_ctl);
175}
176
177void ath9k_tx_tasklet(unsigned long data)
178{
179 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
180 struct ieee80211_sta *sta;
181 struct ieee80211_hdr *hdr;
182 struct ieee80211_tx_info *tx_info;
183 struct sk_buff *skb = NULL;
184 __le16 fc;
185
186 while ((skb = skb_dequeue(&priv->tx_queue)) != NULL) {
187
188 hdr = (struct ieee80211_hdr *) skb->data;
189 fc = hdr->frame_control;
190 tx_info = IEEE80211_SKB_CB(skb);
191 sta = tx_info->control.sta;
192
193 rcu_read_lock();
194
195 if (sta && conf_is_ht(&priv->hw->conf) &&
196 (priv->op_flags & OP_TXAGGR)
197 && !(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
198 if (ieee80211_is_data_qos(fc)) {
199 u8 *qc, tid;
200 struct ath9k_htc_sta *ista;
201
202 qc = ieee80211_get_qos_ctl(hdr);
203 tid = qc[0] & 0xf;
204 ista = (struct ath9k_htc_sta *)sta->drv_priv;
205
206 if ((tid < ATH9K_HTC_MAX_TID) &&
207 ista->tid_state[tid] == AGGR_STOP) {
208 ieee80211_start_tx_ba_session(sta, tid);
209 ista->tid_state[tid] = AGGR_PROGRESS;
210 }
211 }
212 }
213
214 rcu_read_unlock();
215
216 memset(&tx_info->status, 0, sizeof(tx_info->status));
217 ieee80211_tx_status(priv->hw, skb);
218 }
219}
220
221void ath9k_htc_txep(void *drv_priv, struct sk_buff *skb,
222 enum htc_endpoint_id ep_id, bool txok)
223{
224 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) drv_priv;
225 struct ieee80211_tx_info *tx_info;
226
227 if (!skb)
228 return;
229
230 if (ep_id == priv->mgmt_ep)
231 skb_pull(skb, sizeof(struct tx_mgmt_hdr));
232 else
233 /* TODO: Check for cab/uapsd/data */
234 skb_pull(skb, sizeof(struct tx_frame_hdr));
235
236 tx_info = IEEE80211_SKB_CB(skb);
237
238 if (txok)
239 tx_info->flags |= IEEE80211_TX_STAT_ACK;
240
241 skb_queue_tail(&priv->tx_queue, skb);
242 tasklet_schedule(&priv->tx_tasklet);
243}
244
245int ath9k_tx_init(struct ath9k_htc_priv *priv)
246{
247 skb_queue_head_init(&priv->tx_queue);
248 return 0;
249}
250
251void ath9k_tx_cleanup(struct ath9k_htc_priv *priv)
252{
253
254}
255
256bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv,
257 enum ath9k_tx_queue_subtype subtype)
258{
259 struct ath_hw *ah = priv->ah;
260 struct ath_common *common = ath9k_hw_common(ah);
261 struct ath9k_tx_queue_info qi;
262 int qnum;
263
264 memset(&qi, 0, sizeof(qi));
265
266 qi.tqi_subtype = subtype;
267 qi.tqi_aifs = ATH9K_TXQ_USEDEFAULT;
268 qi.tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
269 qi.tqi_cwmax = ATH9K_TXQ_USEDEFAULT;
270 qi.tqi_physCompBuf = 0;
271 qi.tqi_qflags = TXQ_FLAG_TXEOLINT_ENABLE | TXQ_FLAG_TXDESCINT_ENABLE;
272
273 qnum = ath9k_hw_setuptxqueue(priv->ah, ATH9K_TX_QUEUE_DATA, &qi);
274 if (qnum == -1)
275 return false;
276
277 if (qnum >= ARRAY_SIZE(priv->hwq_map)) {
278 ath_print(common, ATH_DBG_FATAL,
279 "qnum %u out of range, max %u!\n",
280 qnum, (unsigned int)ARRAY_SIZE(priv->hwq_map));
281 ath9k_hw_releasetxqueue(ah, qnum);
282 return false;
283 }
284
285 priv->hwq_map[subtype] = qnum;
286 return true;
287}
288
289/******/
290/* RX */
291/******/
292
293void ath9k_host_rx_init(struct ath9k_htc_priv *priv)
294{
295 ath9k_hw_rxena(priv->ah);
296 ath9k_cmn_opmode_init(priv->hw, priv->ah, priv->rxfilter);
297 ath9k_hw_startpcureceive(priv->ah);
298 priv->rx.last_rssi = ATH_RSSI_DUMMY_MARKER;
299}
300
301static void ath9k_process_rate(struct ieee80211_hw *hw,
302 struct ieee80211_rx_status *rxs,
303 u8 rx_rate, u8 rs_flags)
304{
305 struct ieee80211_supported_band *sband;
306 enum ieee80211_band band;
307 unsigned int i = 0;
308
309 if (rx_rate & 0x80) {
310 /* HT rate */
311 rxs->flag |= RX_FLAG_HT;
312 if (rs_flags & ATH9K_RX_2040)
313 rxs->flag |= RX_FLAG_40MHZ;
314 if (rs_flags & ATH9K_RX_GI)
315 rxs->flag |= RX_FLAG_SHORT_GI;
316 rxs->rate_idx = rx_rate & 0x7f;
317 return;
318 }
319
320 band = hw->conf.channel->band;
321 sband = hw->wiphy->bands[band];
322
323 for (i = 0; i < sband->n_bitrates; i++) {
324 if (sband->bitrates[i].hw_value == rx_rate) {
325 rxs->rate_idx = i;
326 return;
327 }
328 if (sband->bitrates[i].hw_value_short == rx_rate) {
329 rxs->rate_idx = i;
330 rxs->flag |= RX_FLAG_SHORTPRE;
331 return;
332 }
333 }
334
335}
336
337static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv,
338 struct ath9k_htc_rxbuf *rxbuf,
339 struct ieee80211_rx_status *rx_status)
340
341{
342 struct ieee80211_hdr *hdr;
343 struct ieee80211_hw *hw = priv->hw;
344 struct sk_buff *skb = rxbuf->skb;
345 struct ath_common *common = ath9k_hw_common(priv->ah);
346 int hdrlen, padpos, padsize;
347 int last_rssi = ATH_RSSI_DUMMY_MARKER;
348 __le16 fc;
349
350 hdr = (struct ieee80211_hdr *)skb->data;
351 fc = hdr->frame_control;
352 hdrlen = ieee80211_get_hdrlen_from_skb(skb);
353
354 padpos = ath9k_cmn_padpos(fc);
355
356 padsize = padpos & 3;
357 if (padsize && skb->len >= padpos+padsize) {
358 memmove(skb->data + padsize, skb->data, padpos);
359 skb_pull(skb, padsize);
360 }
361
362 memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
363
364 if (rxbuf->rxstatus.rs_status != 0) {
365 if (rxbuf->rxstatus.rs_status & ATH9K_RXERR_CRC)
366 rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
367 if (rxbuf->rxstatus.rs_status & ATH9K_RXERR_PHY)
368 goto rx_next;
369
370 if (rxbuf->rxstatus.rs_status & ATH9K_RXERR_DECRYPT) {
371 /* FIXME */
372 } else if (rxbuf->rxstatus.rs_status & ATH9K_RXERR_MIC) {
373 if (ieee80211_is_ctl(fc))
374 /*
375 * Sometimes, we get invalid
376 * MIC failures on valid control frames.
377 * Remove these mic errors.
378 */
379 rxbuf->rxstatus.rs_status &= ~ATH9K_RXERR_MIC;
380 else
381 rx_status->flag |= RX_FLAG_MMIC_ERROR;
382 }
383
384 /*
385 * Reject error frames with the exception of
386 * decryption and MIC failures. For monitor mode,
387 * we also ignore the CRC error.
388 */
389 if (priv->ah->opmode == NL80211_IFTYPE_MONITOR) {
390 if (rxbuf->rxstatus.rs_status &
391 ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC |
392 ATH9K_RXERR_CRC))
393 goto rx_next;
394 } else {
395 if (rxbuf->rxstatus.rs_status &
396 ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC)) {
397 goto rx_next;
398 }
399 }
400 }
401
402 if (!(rxbuf->rxstatus.rs_status & ATH9K_RXERR_DECRYPT)) {
403 u8 keyix;
404 keyix = rxbuf->rxstatus.rs_keyix;
405 if (keyix != ATH9K_RXKEYIX_INVALID) {
406 rx_status->flag |= RX_FLAG_DECRYPTED;
407 } else if (ieee80211_has_protected(fc) &&
408 skb->len >= hdrlen + 4) {
409 keyix = skb->data[hdrlen + 3] >> 6;
410 if (test_bit(keyix, common->keymap))
411 rx_status->flag |= RX_FLAG_DECRYPTED;
412 }
413 }
414
415 ath9k_process_rate(hw, rx_status, rxbuf->rxstatus.rs_rate,
416 rxbuf->rxstatus.rs_flags);
417
418 if (priv->op_flags & OP_ASSOCIATED) {
419 if (rxbuf->rxstatus.rs_rssi != ATH9K_RSSI_BAD &&
420 !rxbuf->rxstatus.rs_moreaggr)
421 ATH_RSSI_LPF(priv->rx.last_rssi,
422 rxbuf->rxstatus.rs_rssi);
423
424 last_rssi = priv->rx.last_rssi;
425
426 if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
427 rxbuf->rxstatus.rs_rssi = ATH_EP_RND(last_rssi,
428 ATH_RSSI_EP_MULTIPLIER);
429
430 if (rxbuf->rxstatus.rs_rssi < 0)
431 rxbuf->rxstatus.rs_rssi = 0;
432
433 if (ieee80211_is_beacon(fc))
434 priv->ah->stats.avgbrssi = rxbuf->rxstatus.rs_rssi;
435 }
436
437 rx_status->mactime = rxbuf->rxstatus.rs_tstamp;
438 rx_status->band = hw->conf.channel->band;
439 rx_status->freq = hw->conf.channel->center_freq;
440 rx_status->signal = rxbuf->rxstatus.rs_rssi + ATH_DEFAULT_NOISE_FLOOR;
441 rx_status->antenna = rxbuf->rxstatus.rs_antenna;
442 rx_status->flag |= RX_FLAG_TSFT;
443
444 return true;
445
446rx_next:
447 return false;
448}
449
450/*
451 * FIXME: Handle FLUSH later on.
452 */
453void ath9k_rx_tasklet(unsigned long data)
454{
455 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
456 struct ath9k_htc_rxbuf *rxbuf = NULL, *tmp_buf = NULL;
457 struct ieee80211_rx_status rx_status;
458 struct sk_buff *skb;
459 unsigned long flags;
460
461
462 do {
463 spin_lock_irqsave(&priv->rx.rxbuflock, flags);
464 list_for_each_entry(tmp_buf, &priv->rx.rxbuf, list) {
465 if (tmp_buf->in_process) {
466 rxbuf = tmp_buf;
467 break;
468 }
469 }
470
471 if (rxbuf == NULL) {
472 spin_unlock_irqrestore(&priv->rx.rxbuflock, flags);
473 break;
474 }
475
476 if (!rxbuf->skb)
477 goto requeue;
478
479 if (!ath9k_rx_prepare(priv, rxbuf, &rx_status)) {
480 dev_kfree_skb_any(rxbuf->skb);
481 goto requeue;
482 }
483
484 memcpy(IEEE80211_SKB_RXCB(rxbuf->skb), &rx_status,
485 sizeof(struct ieee80211_rx_status));
486 skb = rxbuf->skb;
487 spin_unlock_irqrestore(&priv->rx.rxbuflock, flags);
488
489 ieee80211_rx(priv->hw, skb);
490
491 spin_lock_irqsave(&priv->rx.rxbuflock, flags);
492requeue:
493 rxbuf->in_process = false;
494 rxbuf->skb = NULL;
495 list_move_tail(&rxbuf->list, &priv->rx.rxbuf);
496 rxbuf = NULL;
497 spin_unlock_irqrestore(&priv->rx.rxbuflock, flags);
498 } while (1);
499
500}
501
502void ath9k_htc_rxep(void *drv_priv, struct sk_buff *skb,
503 enum htc_endpoint_id ep_id)
504{
505 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)drv_priv;
506 struct ath_hw *ah = priv->ah;
507 struct ath_common *common = ath9k_hw_common(ah);
508 struct ath9k_htc_rxbuf *rxbuf = NULL, *tmp_buf = NULL;
509 struct ath_htc_rx_status *rxstatus;
510 u32 len = 0;
511
512 spin_lock(&priv->rx.rxbuflock);
513 list_for_each_entry(tmp_buf, &priv->rx.rxbuf, list) {
514 if (!tmp_buf->in_process) {
515 rxbuf = tmp_buf;
516 break;
517 }
518 }
519 spin_unlock(&priv->rx.rxbuflock);
520
521 if (rxbuf == NULL) {
522 ath_print(common, ATH_DBG_ANY,
523 "No free RX buffer\n");
524 goto err;
525 }
526
527 len = skb->len;
528 if (len <= HTC_RX_FRAME_HEADER_SIZE) {
529 ath_print(common, ATH_DBG_FATAL,
530 "Corrupted RX frame, dropping\n");
531 goto err;
532 }
533
534 rxstatus = (struct ath_htc_rx_status *)skb->data;
535
536 rxstatus->rs_tstamp = be64_to_cpu(rxstatus->rs_tstamp);
537 rxstatus->rs_datalen = be16_to_cpu(rxstatus->rs_datalen);
538 rxstatus->evm0 = be32_to_cpu(rxstatus->evm0);
539 rxstatus->evm1 = be32_to_cpu(rxstatus->evm1);
540 rxstatus->evm2 = be32_to_cpu(rxstatus->evm2);
541
542 if (rxstatus->rs_datalen - (len - HTC_RX_FRAME_HEADER_SIZE) != 0) {
543 ath_print(common, ATH_DBG_FATAL,
544 "Corrupted RX data len, dropping "
545 "(epid: %d, dlen: %d, skblen: %d)\n",
546 ep_id, rxstatus->rs_datalen, len);
547 goto err;
548 }
549
550 spin_lock(&priv->rx.rxbuflock);
551 memcpy(&rxbuf->rxstatus, rxstatus, HTC_RX_FRAME_HEADER_SIZE);
552 skb_pull(skb, HTC_RX_FRAME_HEADER_SIZE);
553 skb->len = rxstatus->rs_datalen;
554 rxbuf->skb = skb;
555 rxbuf->in_process = true;
556 spin_unlock(&priv->rx.rxbuflock);
557
558 tasklet_schedule(&priv->rx_tasklet);
559 return;
560err:
561 dev_kfree_skb_any(skb);
562 return;
563}
564
565/* FIXME: Locking for cleanup/init */
566
567void ath9k_rx_cleanup(struct ath9k_htc_priv *priv)
568{
569 struct ath9k_htc_rxbuf *rxbuf, *tbuf;
570
571 list_for_each_entry_safe(rxbuf, tbuf, &priv->rx.rxbuf, list) {
572 list_del(&rxbuf->list);
573 if (rxbuf->skb)
574 dev_kfree_skb_any(rxbuf->skb);
575 kfree(rxbuf);
576 }
577}
578
579int ath9k_rx_init(struct ath9k_htc_priv *priv)
580{
581 struct ath_hw *ah = priv->ah;
582 struct ath_common *common = ath9k_hw_common(ah);
583 struct ath9k_htc_rxbuf *rxbuf;
584 int i = 0;
585
586 INIT_LIST_HEAD(&priv->rx.rxbuf);
587 spin_lock_init(&priv->rx.rxbuflock);
588
589 for (i = 0; i < ATH9K_HTC_RXBUF; i++) {
590 rxbuf = kzalloc(sizeof(struct ath9k_htc_rxbuf), GFP_KERNEL);
591 if (rxbuf == NULL) {
592 ath_print(common, ATH_DBG_FATAL,
593 "Unable to allocate RX buffers\n");
594 goto err;
595 }
596 list_add_tail(&rxbuf->list, &priv->rx.rxbuf);
597 }
598
599 return 0;
600
601err:
602 ath9k_rx_cleanup(priv);
603 return -ENOMEM;
604}
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c
new file mode 100644
index 00000000000..9a48999d097
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/htc_hst.c
@@ -0,0 +1,463 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "htc.h"
18
19static int htc_issue_send(struct htc_target *target, struct sk_buff* skb,
20 u16 len, u8 flags, u8 epid,
21 struct ath9k_htc_tx_ctl *tx_ctl)
22{
23 struct htc_frame_hdr *hdr;
24 struct htc_endpoint *endpoint = &target->endpoint[epid];
25 int status;
26
27 hdr = (struct htc_frame_hdr *)
28 skb_push(skb, sizeof(struct htc_frame_hdr));
29 hdr->endpoint_id = epid;
30 hdr->flags = flags;
31 hdr->payload_len = cpu_to_be16(len);
32
33 status = target->hif->send(target->hif_dev, endpoint->ul_pipeid, skb,
34 tx_ctl);
35 return status;
36}
37
38static struct htc_endpoint *get_next_avail_ep(struct htc_endpoint *endpoint)
39{
40 enum htc_endpoint_id avail_epid;
41
42 for (avail_epid = ENDPOINT_MAX; avail_epid > ENDPOINT0; avail_epid--)
43 if (endpoint[avail_epid].service_id == 0)
44 return &endpoint[avail_epid];
45 return NULL;
46}
47
48static u8 service_to_ulpipe(u16 service_id)
49{
50 switch (service_id) {
51 case WMI_CONTROL_SVC:
52 return 4;
53 case WMI_BEACON_SVC:
54 case WMI_CAB_SVC:
55 case WMI_UAPSD_SVC:
56 case WMI_MGMT_SVC:
57 case WMI_DATA_VO_SVC:
58 case WMI_DATA_VI_SVC:
59 case WMI_DATA_BE_SVC:
60 case WMI_DATA_BK_SVC:
61 return 1;
62 default:
63 return 0;
64 }
65}
66
67static u8 service_to_dlpipe(u16 service_id)
68{
69 switch (service_id) {
70 case WMI_CONTROL_SVC:
71 return 3;
72 case WMI_BEACON_SVC:
73 case WMI_CAB_SVC:
74 case WMI_UAPSD_SVC:
75 case WMI_MGMT_SVC:
76 case WMI_DATA_VO_SVC:
77 case WMI_DATA_VI_SVC:
78 case WMI_DATA_BE_SVC:
79 case WMI_DATA_BK_SVC:
80 return 2;
81 default:
82 return 0;
83 }
84}
85
86static void htc_process_target_rdy(struct htc_target *target,
87 void *buf)
88{
89 struct htc_endpoint *endpoint;
90 struct htc_ready_msg *htc_ready_msg = (struct htc_ready_msg *) buf;
91
92 target->credits = be16_to_cpu(htc_ready_msg->credits);
93 target->credit_size = be16_to_cpu(htc_ready_msg->credit_size);
94
95 endpoint = &target->endpoint[ENDPOINT0];
96 endpoint->service_id = HTC_CTRL_RSVD_SVC;
97 endpoint->max_msglen = HTC_MAX_CONTROL_MESSAGE_LENGTH;
98 complete(&target->target_wait);
99}
100
101static void htc_process_conn_rsp(struct htc_target *target,
102 struct htc_frame_hdr *htc_hdr)
103{
104 struct htc_conn_svc_rspmsg *svc_rspmsg;
105 struct htc_endpoint *endpoint, *tmp_endpoint = NULL;
106 u16 service_id;
107 u16 max_msglen;
108 enum htc_endpoint_id epid, tepid;
109
110 svc_rspmsg = (struct htc_conn_svc_rspmsg *)
111 ((void *) htc_hdr + sizeof(struct htc_frame_hdr));
112
113 if (svc_rspmsg->status == HTC_SERVICE_SUCCESS) {
114 epid = svc_rspmsg->endpoint_id;
115 service_id = be16_to_cpu(svc_rspmsg->service_id);
116 max_msglen = be16_to_cpu(svc_rspmsg->max_msg_len);
117 endpoint = &target->endpoint[epid];
118
119 for (tepid = ENDPOINT_MAX; tepid > ENDPOINT0; tepid--) {
120 tmp_endpoint = &target->endpoint[tepid];
121 if (tmp_endpoint->service_id == service_id) {
122 tmp_endpoint->service_id = 0;
123 break;
124 }
125 }
126
127 if (!tmp_endpoint)
128 return;
129
130 endpoint->service_id = service_id;
131 endpoint->max_txqdepth = tmp_endpoint->max_txqdepth;
132 endpoint->ep_callbacks = tmp_endpoint->ep_callbacks;
133 endpoint->ul_pipeid = tmp_endpoint->ul_pipeid;
134 endpoint->dl_pipeid = tmp_endpoint->dl_pipeid;
135 endpoint->max_msglen = max_msglen;
136 target->conn_rsp_epid = epid;
137 complete(&target->cmd_wait);
138 } else {
139 target->conn_rsp_epid = ENDPOINT_UNUSED;
140 }
141}
142
143static int htc_config_pipe_credits(struct htc_target *target)
144{
145 struct sk_buff *skb;
146 struct htc_config_pipe_msg *cp_msg;
147 int ret, time_left;
148
149 skb = dev_alloc_skb(50 + sizeof(struct htc_frame_hdr));
150 if (!skb) {
151 dev_err(target->dev, "failed to allocate send buffer\n");
152 return -ENOMEM;
153 }
154 skb_reserve(skb, sizeof(struct htc_frame_hdr));
155
156 cp_msg = (struct htc_config_pipe_msg *)
157 skb_put(skb, sizeof(struct htc_config_pipe_msg));
158
159 cp_msg->message_id = cpu_to_be16(HTC_MSG_CONFIG_PIPE_ID);
160 cp_msg->pipe_id = USB_WLAN_TX_PIPE;
161 cp_msg->credits = 28;
162
163 target->htc_flags |= HTC_OP_CONFIG_PIPE_CREDITS;
164
165 ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL);
166 if (ret)
167 goto err;
168
169 time_left = wait_for_completion_timeout(&target->cmd_wait, HZ);
170 if (!time_left) {
171 dev_err(target->dev, "HTC credit config timeout\n");
172 return -ETIMEDOUT;
173 }
174
175 return 0;
176err:
177 dev_kfree_skb(skb);
178 return -EINVAL;
179}
180
181static int htc_setup_complete(struct htc_target *target)
182{
183 struct sk_buff *skb;
184 struct htc_comp_msg *comp_msg;
185 int ret = 0, time_left;
186
187 skb = dev_alloc_skb(50 + sizeof(struct htc_frame_hdr));
188 if (!skb) {
189 dev_err(target->dev, "failed to allocate send buffer\n");
190 return -ENOMEM;
191 }
192 skb_reserve(skb, sizeof(struct htc_frame_hdr));
193
194 comp_msg = (struct htc_comp_msg *)
195 skb_put(skb, sizeof(struct htc_comp_msg));
196 comp_msg->msg_id = cpu_to_be16(HTC_MSG_SETUP_COMPLETE_ID);
197
198 target->htc_flags |= HTC_OP_START_WAIT;
199
200 ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL);
201 if (ret)
202 goto err;
203
204 time_left = wait_for_completion_timeout(&target->cmd_wait, HZ);
205 if (!time_left) {
206 dev_err(target->dev, "HTC start timeout\n");
207 return -ETIMEDOUT;
208 }
209
210 return 0;
211
212err:
213 dev_kfree_skb(skb);
214 return -EINVAL;
215}
216
217/* HTC APIs */
218
219int htc_init(struct htc_target *target)
220{
221 int ret;
222
223 ret = htc_config_pipe_credits(target);
224 if (ret)
225 return ret;
226
227 return htc_setup_complete(target);
228}
229
230int htc_connect_service(struct htc_target *target,
231 struct htc_service_connreq *service_connreq,
232 enum htc_endpoint_id *conn_rsp_epid)
233{
234 struct sk_buff *skb;
235 struct htc_endpoint *endpoint;
236 struct htc_conn_svc_msg *conn_msg;
237 int ret, time_left;
238
239 /* Find an available endpoint */
240 endpoint = get_next_avail_ep(target->endpoint);
241 if (!endpoint) {
242 dev_err(target->dev, "Endpoint is not available for"
243 "service %d\n", service_connreq->service_id);
244 return -EINVAL;
245 }
246
247 endpoint->service_id = service_connreq->service_id;
248 endpoint->max_txqdepth = service_connreq->max_send_qdepth;
249 endpoint->ul_pipeid = service_to_ulpipe(service_connreq->service_id);
250 endpoint->dl_pipeid = service_to_dlpipe(service_connreq->service_id);
251 endpoint->ep_callbacks = service_connreq->ep_callbacks;
252
253 skb = dev_alloc_skb(sizeof(struct htc_conn_svc_msg) +
254 sizeof(struct htc_frame_hdr));
255 if (!skb) {
256 dev_err(target->dev, "Failed to allocate buf to send"
257 "service connect req\n");
258 return -ENOMEM;
259 }
260
261 skb_reserve(skb, sizeof(struct htc_frame_hdr));
262
263 conn_msg = (struct htc_conn_svc_msg *)
264 skb_put(skb, sizeof(struct htc_conn_svc_msg));
265 conn_msg->service_id = cpu_to_be16(service_connreq->service_id);
266 conn_msg->msg_id = cpu_to_be16(HTC_MSG_CONNECT_SERVICE_ID);
267 conn_msg->con_flags = cpu_to_be16(service_connreq->con_flags);
268 conn_msg->dl_pipeid = endpoint->dl_pipeid;
269 conn_msg->ul_pipeid = endpoint->ul_pipeid;
270
271 ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL);
272 if (ret)
273 goto err;
274
275 time_left = wait_for_completion_timeout(&target->cmd_wait, HZ);
276 if (!time_left) {
277 dev_err(target->dev, "Service connection timeout for: %d\n",
278 service_connreq->service_id);
279 return -ETIMEDOUT;
280 }
281
282 *conn_rsp_epid = target->conn_rsp_epid;
283 return 0;
284err:
285 dev_kfree_skb(skb);
286 return ret;
287}
288
289int htc_send(struct htc_target *target, struct sk_buff *skb,
290 enum htc_endpoint_id epid, struct ath9k_htc_tx_ctl *tx_ctl)
291{
292 return htc_issue_send(target, skb, skb->len, 0, epid, tx_ctl);
293}
294
295void htc_stop(struct htc_target *target)
296{
297 enum htc_endpoint_id epid;
298 struct htc_endpoint *endpoint;
299
300 for (epid = ENDPOINT0; epid <= ENDPOINT_MAX; epid++) {
301 endpoint = &target->endpoint[epid];
302 if (endpoint->service_id != 0)
303 target->hif->stop(target->hif_dev, endpoint->ul_pipeid);
304 }
305}
306
307void htc_start(struct htc_target *target)
308{
309 enum htc_endpoint_id epid;
310 struct htc_endpoint *endpoint;
311
312 for (epid = ENDPOINT0; epid <= ENDPOINT_MAX; epid++) {
313 endpoint = &target->endpoint[epid];
314 if (endpoint->service_id != 0)
315 target->hif->start(target->hif_dev,
316 endpoint->ul_pipeid);
317 }
318}
319
320void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle,
321 struct sk_buff *skb, bool txok)
322{
323 struct htc_endpoint *endpoint;
324 struct htc_frame_hdr *htc_hdr;
325
326 if (htc_handle->htc_flags & HTC_OP_CONFIG_PIPE_CREDITS) {
327 complete(&htc_handle->cmd_wait);
328 htc_handle->htc_flags &= ~HTC_OP_CONFIG_PIPE_CREDITS;
329 }
330
331 if (htc_handle->htc_flags & HTC_OP_START_WAIT) {
332 complete(&htc_handle->cmd_wait);
333 htc_handle->htc_flags &= ~HTC_OP_START_WAIT;
334 }
335
336 if (skb) {
337 htc_hdr = (struct htc_frame_hdr *) skb->data;
338 endpoint = &htc_handle->endpoint[htc_hdr->endpoint_id];
339 skb_pull(skb, sizeof(struct htc_frame_hdr));
340
341 if (endpoint->ep_callbacks.tx) {
342 endpoint->ep_callbacks.tx(htc_handle->drv_priv, skb,
343 htc_hdr->endpoint_id, txok);
344 }
345 }
346}
347
348/*
349 * HTC Messages are handled directly here and the obtained SKB
350 * is freed.
351 *
352 * Sevice messages (Data, WMI) passed to the corresponding
353 * endpoint RX handlers, which have to free the SKB.
354 */
355void ath9k_htc_rx_msg(struct htc_target *htc_handle,
356 struct sk_buff *skb, u32 len, u8 pipe_id)
357{
358 struct htc_frame_hdr *htc_hdr;
359 enum htc_endpoint_id epid;
360 struct htc_endpoint *endpoint;
361 u16 *msg_id;
362
363 if (!htc_handle || !skb)
364 return;
365
366 htc_hdr = (struct htc_frame_hdr *) skb->data;
367 epid = htc_hdr->endpoint_id;
368
369 if (epid >= ENDPOINT_MAX) {
370 dev_kfree_skb_any(skb);
371 return;
372 }
373
374 if (epid == ENDPOINT0) {
375
376 /* Handle trailer */
377 if (htc_hdr->flags & HTC_FLAGS_RECV_TRAILER) {
378 if (be32_to_cpu(*(u32 *) skb->data) == 0x00C60000)
379 /* Move past the Watchdog pattern */
380 htc_hdr = (struct htc_frame_hdr *) skb->data + 4;
381 }
382
383 /* Get the message ID */
384 msg_id = (u16 *) ((void *) htc_hdr +
385 sizeof(struct htc_frame_hdr));
386
387 /* Now process HTC messages */
388 switch (be16_to_cpu(*msg_id)) {
389 case HTC_MSG_READY_ID:
390 htc_process_target_rdy(htc_handle, htc_hdr);
391 break;
392 case HTC_MSG_CONNECT_SERVICE_RESPONSE_ID:
393 htc_process_conn_rsp(htc_handle, htc_hdr);
394 break;
395 default:
396 break;
397 }
398
399 dev_kfree_skb_any(skb);
400
401 } else {
402 if (htc_hdr->flags & HTC_FLAGS_RECV_TRAILER)
403 skb_trim(skb, len - htc_hdr->control[0]);
404
405 skb_pull(skb, sizeof(struct htc_frame_hdr));
406
407 endpoint = &htc_handle->endpoint[epid];
408 if (endpoint->ep_callbacks.rx)
409 endpoint->ep_callbacks.rx(endpoint->ep_callbacks.priv,
410 skb, epid);
411 }
412}
413
414struct htc_target *ath9k_htc_hw_alloc(void *hif_handle)
415{
416 struct htc_target *target;
417
418 target = kzalloc(sizeof(struct htc_target), GFP_KERNEL);
419 if (!target)
420 printk(KERN_ERR "Unable to allocate memory for"
421 "target device\n");
422
423 return target;
424}
425
426void ath9k_htc_hw_free(struct htc_target *htc)
427{
428 kfree(htc);
429}
430
431int ath9k_htc_hw_init(struct ath9k_htc_hif *hif, struct htc_target *target,
432 void *hif_handle, struct device *dev, u16 devid,
433 enum ath9k_hif_transports transport)
434{
435 struct htc_endpoint *endpoint;
436 int err = 0;
437
438 init_completion(&target->target_wait);
439 init_completion(&target->cmd_wait);
440
441 target->hif = hif;
442 target->hif_dev = hif_handle;
443 target->dev = dev;
444
445 /* Assign control endpoint pipe IDs */
446 endpoint = &target->endpoint[ENDPOINT0];
447 endpoint->ul_pipeid = hif->control_ul_pipe;
448 endpoint->dl_pipeid = hif->control_dl_pipe;
449
450 err = ath9k_htc_probe_device(target, dev, devid);
451 if (err) {
452 printk(KERN_ERR "Failed to initialize the device\n");
453 return -ENODEV;
454 }
455
456 return 0;
457}
458
459void ath9k_htc_hw_deinit(struct htc_target *target, bool hot_unplug)
460{
461 if (target)
462 ath9k_htc_disconnect_device(target, hot_unplug);
463}
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.h b/drivers/net/wireless/ath/ath9k/htc_hst.h
new file mode 100644
index 00000000000..cd7048ffd23
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/htc_hst.h
@@ -0,0 +1,246 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef HTC_HST_H
18#define HTC_HST_H
19
20struct ath9k_htc_priv;
21struct htc_target;
22struct ath9k_htc_tx_ctl;
23
24enum ath9k_hif_transports {
25 ATH9K_HIF_USB,
26};
27
28struct ath9k_htc_hif {
29 struct list_head list;
30 const enum ath9k_hif_transports transport;
31 const char *name;
32
33 u8 control_dl_pipe;
34 u8 control_ul_pipe;
35
36 void (*start) (void *hif_handle, u8 pipe);
37 void (*stop) (void *hif_handle, u8 pipe);
38 int (*send) (void *hif_handle, u8 pipe, struct sk_buff *buf,
39 struct ath9k_htc_tx_ctl *tx_ctl);
40};
41
42enum htc_endpoint_id {
43 ENDPOINT_UNUSED = -1,
44 ENDPOINT0 = 0,
45 ENDPOINT1 = 1,
46 ENDPOINT2 = 2,
47 ENDPOINT3 = 3,
48 ENDPOINT4 = 4,
49 ENDPOINT5 = 5,
50 ENDPOINT6 = 6,
51 ENDPOINT7 = 7,
52 ENDPOINT8 = 8,
53 ENDPOINT_MAX = 22
54};
55
56/* Htc frame hdr flags */
57#define HTC_FLAGS_RECV_TRAILER (1 << 1)
58
59struct htc_frame_hdr {
60 u8 endpoint_id;
61 u8 flags;
62 u16 payload_len;
63 u8 control[4];
64} __packed;
65
66struct htc_ready_msg {
67 u16 message_id;
68 u16 credits;
69 u16 credit_size;
70 u8 max_endpoints;
71 u8 pad;
72} __packed;
73
74struct htc_config_pipe_msg {
75 u16 message_id;
76 u8 pipe_id;
77 u8 credits;
78} __packed;
79
80struct htc_packet {
81 void *pktcontext;
82 u8 *buf;
83 u8 *buf_payload;
84 u32 buflen;
85 u32 payload_len;
86
87 int endpoint;
88 int status;
89
90 void *context;
91 u32 reserved;
92};
93
94struct htc_ep_callbacks {
95 void *priv;
96 void (*tx) (void *, struct sk_buff *, enum htc_endpoint_id, bool txok);
97 void (*rx) (void *, struct sk_buff *, enum htc_endpoint_id);
98};
99
100#define HTC_TX_QUEUE_SIZE 256
101
102struct htc_txq {
103 struct sk_buff *buf[HTC_TX_QUEUE_SIZE];
104 u32 txqdepth;
105 u16 txbuf_cnt;
106 u16 txq_head;
107 u16 txq_tail;
108};
109
110struct htc_endpoint {
111 u16 service_id;
112
113 struct htc_ep_callbacks ep_callbacks;
114 struct htc_txq htc_txq;
115 u32 max_txqdepth;
116 int max_msglen;
117
118 u8 ul_pipeid;
119 u8 dl_pipeid;
120};
121
122#define HTC_MAX_CONTROL_MESSAGE_LENGTH 255
123#define HTC_CONTROL_BUFFER_SIZE \
124 (HTC_MAX_CONTROL_MESSAGE_LENGTH + sizeof(struct htc_frame_hdr))
125
126#define NUM_CONTROL_BUFFERS 8
127#define HST_ENDPOINT_MAX 8
128
129struct htc_control_buf {
130 struct htc_packet htc_pkt;
131 u8 buf[HTC_CONTROL_BUFFER_SIZE];
132};
133
134#define HTC_OP_START_WAIT BIT(0)
135#define HTC_OP_CONFIG_PIPE_CREDITS BIT(1)
136
137struct htc_target {
138 void *hif_dev;
139 struct ath9k_htc_priv *drv_priv;
140 struct device *dev;
141 struct ath9k_htc_hif *hif;
142 struct htc_endpoint endpoint[HST_ENDPOINT_MAX];
143 struct completion target_wait;
144 struct completion cmd_wait;
145 struct list_head list;
146 enum htc_endpoint_id conn_rsp_epid;
147 u16 credits;
148 u16 credit_size;
149 u8 htc_flags;
150};
151
152enum htc_msg_id {
153 HTC_MSG_READY_ID = 1,
154 HTC_MSG_CONNECT_SERVICE_ID,
155 HTC_MSG_CONNECT_SERVICE_RESPONSE_ID,
156 HTC_MSG_SETUP_COMPLETE_ID,
157 HTC_MSG_CONFIG_PIPE_ID,
158 HTC_MSG_CONFIG_PIPE_RESPONSE_ID,
159};
160
161struct htc_service_connreq {
162 u16 service_id;
163 u16 con_flags;
164 u32 max_send_qdepth;
165 struct htc_ep_callbacks ep_callbacks;
166};
167
168/* Current service IDs */
169
170enum htc_service_group_ids{
171 RSVD_SERVICE_GROUP = 0,
172 WMI_SERVICE_GROUP = 1,
173
174 HTC_SERVICE_GROUP_LAST = 255
175};
176
177#define MAKE_SERVICE_ID(group, index) \
178 (int)(((int)group << 8) | (int)(index))
179
180/* NOTE: service ID of 0x0000 is reserved and should never be used */
181#define HTC_CTRL_RSVD_SVC MAKE_SERVICE_ID(RSVD_SERVICE_GROUP, 1)
182#define HTC_LOOPBACK_RSVD_SVC MAKE_SERVICE_ID(RSVD_SERVICE_GROUP, 2)
183
184#define WMI_CONTROL_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 0)
185#define WMI_BEACON_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 1)
186#define WMI_CAB_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 2)
187#define WMI_UAPSD_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 3)
188#define WMI_MGMT_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 4)
189#define WMI_DATA_VO_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 5)
190#define WMI_DATA_VI_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 6)
191#define WMI_DATA_BE_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 7)
192#define WMI_DATA_BK_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 8)
193
194struct htc_conn_svc_msg {
195 u16 msg_id;
196 u16 service_id;
197 u16 con_flags;
198 u8 dl_pipeid;
199 u8 ul_pipeid;
200 u8 svc_meta_len;
201 u8 pad;
202} __packed;
203
204/* connect response status codes */
205#define HTC_SERVICE_SUCCESS 0
206#define HTC_SERVICE_NOT_FOUND 1
207#define HTC_SERVICE_FAILED 2
208#define HTC_SERVICE_NO_RESOURCES 3
209#define HTC_SERVICE_NO_MORE_EP 4
210
211struct htc_conn_svc_rspmsg {
212 u16 msg_id;
213 u16 service_id;
214 u8 status;
215 u8 endpoint_id;
216 u16 max_msg_len;
217 u8 svc_meta_len;
218 u8 pad;
219} __packed;
220
221struct htc_comp_msg {
222 u16 msg_id;
223} __packed;
224
225int htc_init(struct htc_target *target);
226int htc_connect_service(struct htc_target *target,
227 struct htc_service_connreq *service_connreq,
228 enum htc_endpoint_id *conn_rsp_eid);
229int htc_send(struct htc_target *target, struct sk_buff *skb,
230 enum htc_endpoint_id eid, struct ath9k_htc_tx_ctl *tx_ctl);
231void htc_stop(struct htc_target *target);
232void htc_start(struct htc_target *target);
233
234void ath9k_htc_rx_msg(struct htc_target *htc_handle,
235 struct sk_buff *skb, u32 len, u8 pipe_id);
236void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle,
237 struct sk_buff *skb, bool txok);
238
239struct htc_target *ath9k_htc_hw_alloc(void *hif_handle);
240void ath9k_htc_hw_free(struct htc_target *htc);
241int ath9k_htc_hw_init(struct ath9k_htc_hif *hif, struct htc_target *target,
242 void *hif_handle, struct device *dev, u16 devid,
243 enum ath9k_hif_transports transport);
244void ath9k_htc_hw_deinit(struct htc_target *target, bool hot_unplug);
245
246#endif /* HTC_HST_H */
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 78b571129c9..7fdaea3a162 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -500,8 +500,10 @@ static int ath9k_hw_post_init(struct ath_hw *ah)
500{ 500{
501 int ecode; 501 int ecode;
502 502
503 if (!ath9k_hw_chip_test(ah)) 503 if (!AR_SREV_9271(ah)) {
504 return -ENODEV; 504 if (!ath9k_hw_chip_test(ah))
505 return -ENODEV;
506 }
505 507
506 ecode = ath9k_hw_rf_claim(ah); 508 ecode = ath9k_hw_rf_claim(ah);
507 if (ecode != 0) 509 if (ecode != 0)
@@ -604,9 +606,23 @@ static void ath9k_hw_init_mode_regs(struct ath_hw *ah)
604 ARRAY_SIZE(ar9271Modes_9271), 6); 606 ARRAY_SIZE(ar9271Modes_9271), 6);
605 INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271, 607 INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271,
606 ARRAY_SIZE(ar9271Common_9271), 2); 608 ARRAY_SIZE(ar9271Common_9271), 2);
609 INIT_INI_ARRAY(&ah->iniCommon_normal_cck_fir_coeff_9271,
610 ar9271Common_normal_cck_fir_coeff_9271,
611 ARRAY_SIZE(ar9271Common_normal_cck_fir_coeff_9271), 2);
612 INIT_INI_ARRAY(&ah->iniCommon_japan_2484_cck_fir_coeff_9271,
613 ar9271Common_japan_2484_cck_fir_coeff_9271,
614 ARRAY_SIZE(ar9271Common_japan_2484_cck_fir_coeff_9271), 2);
607 INIT_INI_ARRAY(&ah->iniModes_9271_1_0_only, 615 INIT_INI_ARRAY(&ah->iniModes_9271_1_0_only,
608 ar9271Modes_9271_1_0_only, 616 ar9271Modes_9271_1_0_only,
609 ARRAY_SIZE(ar9271Modes_9271_1_0_only), 6); 617 ARRAY_SIZE(ar9271Modes_9271_1_0_only), 6);
618 INIT_INI_ARRAY(&ah->iniModes_9271_ANI_reg, ar9271Modes_9271_ANI_reg,
619 ARRAY_SIZE(ar9271Modes_9271_ANI_reg), 6);
620 INIT_INI_ARRAY(&ah->iniModes_high_power_tx_gain_9271,
621 ar9271Modes_high_power_tx_gain_9271,
622 ARRAY_SIZE(ar9271Modes_high_power_tx_gain_9271), 6);
623 INIT_INI_ARRAY(&ah->iniModes_normal_power_tx_gain_9271,
624 ar9271Modes_normal_power_tx_gain_9271,
625 ARRAY_SIZE(ar9271Modes_normal_power_tx_gain_9271), 6);
610 return; 626 return;
611 } 627 }
612 628
@@ -991,22 +1007,6 @@ static void ath9k_hw_init_qos(struct ath_hw *ah)
991 REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF); 1007 REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF);
992} 1008}
993 1009
994static void ath9k_hw_change_target_baud(struct ath_hw *ah, u32 freq, u32 baud)
995{
996 u32 lcr;
997 u32 baud_divider = freq * 1000 * 1000 / 16 / baud;
998
999 lcr = REG_READ(ah , 0x5100c);
1000 lcr |= 0x80;
1001
1002 REG_WRITE(ah, 0x5100c, lcr);
1003 REG_WRITE(ah, 0x51004, (baud_divider >> 8));
1004 REG_WRITE(ah, 0x51000, (baud_divider & 0xff));
1005
1006 lcr &= ~0x80;
1007 REG_WRITE(ah, 0x5100c, lcr);
1008}
1009
1010static void ath9k_hw_init_pll(struct ath_hw *ah, 1010static void ath9k_hw_init_pll(struct ath_hw *ah,
1011 struct ath9k_channel *chan) 1011 struct ath9k_channel *chan)
1012{ 1012{
@@ -1072,22 +1072,8 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
1072 1072
1073 /* Switch the core clock for ar9271 to 117Mhz */ 1073 /* Switch the core clock for ar9271 to 117Mhz */
1074 if (AR_SREV_9271(ah)) { 1074 if (AR_SREV_9271(ah)) {
1075 if ((pll == 0x142c) || (pll == 0x2850) ) { 1075 udelay(500);
1076 udelay(500); 1076 REG_WRITE(ah, 0x50040, 0x304);
1077 /* set CLKOBS to output AHB clock */
1078 REG_WRITE(ah, 0x7020, 0xe);
1079 /*
1080 * 0x304: 117Mhz, ahb_ratio: 1x1
1081 * 0x306: 40Mhz, ahb_ratio: 1x1
1082 */
1083 REG_WRITE(ah, 0x50040, 0x304);
1084 /*
1085 * makes adjustments for the baud dividor to keep the
1086 * targetted baud rate based on the used core clock.
1087 */
1088 ath9k_hw_change_target_baud(ah, AR9271_CORE_CLOCK,
1089 AR9271_TARGET_BAUD_RATE);
1090 }
1091 } 1077 }
1092 1078
1093 udelay(RTC_PLL_SETTLE_DELAY); 1079 udelay(RTC_PLL_SETTLE_DELAY);
@@ -1152,7 +1138,8 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
1152 ah->mask_reg |= AR_IMR_MIB; 1138 ah->mask_reg |= AR_IMR_MIB;
1153 1139
1154 REG_WRITE(ah, AR_IMR, ah->mask_reg); 1140 REG_WRITE(ah, AR_IMR, ah->mask_reg);
1155 REG_WRITE(ah, AR_IMR_S2, REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_GTT); 1141 ah->imrs2_reg |= AR_IMR_S2_GTT;
1142 REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg);
1156 1143
1157 if (!AR_SREV_9100(ah)) { 1144 if (!AR_SREV_9100(ah)) {
1158 REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF); 1145 REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF);
@@ -1241,7 +1228,7 @@ void ath9k_hw_deinit(struct ath_hw *ah)
1241{ 1228{
1242 struct ath_common *common = ath9k_hw_common(ah); 1229 struct ath_common *common = ath9k_hw_common(ah);
1243 1230
1244 if (common->state <= ATH_HW_INITIALIZED) 1231 if (common->state < ATH_HW_INITIALIZED)
1245 goto free_hw; 1232 goto free_hw;
1246 1233
1247 if (!AR_SREV_9100(ah)) 1234 if (!AR_SREV_9100(ah))
@@ -1252,8 +1239,6 @@ void ath9k_hw_deinit(struct ath_hw *ah)
1252free_hw: 1239free_hw:
1253 if (!AR_SREV_9280_10_OR_LATER(ah)) 1240 if (!AR_SREV_9280_10_OR_LATER(ah))
1254 ath9k_hw_rf_free_ext_banks(ah); 1241 ath9k_hw_rf_free_ext_banks(ah);
1255 kfree(ah);
1256 ah = NULL;
1257} 1242}
1258EXPORT_SYMBOL(ath9k_hw_deinit); 1243EXPORT_SYMBOL(ath9k_hw_deinit);
1259 1244
@@ -1266,26 +1251,6 @@ static void ath9k_hw_override_ini(struct ath_hw *ah,
1266{ 1251{
1267 u32 val; 1252 u32 val;
1268 1253
1269 if (AR_SREV_9271(ah)) {
1270 /*
1271 * Enable spectral scan to solution for issues with stuck
1272 * beacons on AR9271 1.0. The beacon stuck issue is not seeon on
1273 * AR9271 1.1
1274 */
1275 if (AR_SREV_9271_10(ah)) {
1276 val = REG_READ(ah, AR_PHY_SPECTRAL_SCAN) |
1277 AR_PHY_SPECTRAL_SCAN_ENABLE;
1278 REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val);
1279 }
1280 else if (AR_SREV_9271_11(ah))
1281 /*
1282 * change AR_PHY_RF_CTL3 setting to fix MAC issue
1283 * present on AR9271 1.1
1284 */
1285 REG_WRITE(ah, AR_PHY_RF_CTL3, 0x3a020001);
1286 return;
1287 }
1288
1289 /* 1254 /*
1290 * Set the RX_ABORT and RX_DIS and clear if off only after 1255 * Set the RX_ABORT and RX_DIS and clear if off only after
1291 * RXE is set for MAC. This prevents frames with corrupted 1256 * RXE is set for MAC. This prevents frames with corrupted
@@ -1294,8 +1259,10 @@ static void ath9k_hw_override_ini(struct ath_hw *ah,
1294 REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); 1259 REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
1295 1260
1296 if (AR_SREV_9280_10_OR_LATER(ah)) { 1261 if (AR_SREV_9280_10_OR_LATER(ah)) {
1297 val = REG_READ(ah, AR_PCU_MISC_MODE2) & 1262 val = REG_READ(ah, AR_PCU_MISC_MODE2);
1298 (~AR_PCU_MISC_MODE2_HWWAR1); 1263
1264 if (!AR_SREV_9271(ah))
1265 val &= ~AR_PCU_MISC_MODE2_HWWAR1;
1299 1266
1300 if (AR_SREV_9287_10_OR_LATER(ah)) 1267 if (AR_SREV_9287_10_OR_LATER(ah))
1301 val = val & (~AR_PCU_MISC_MODE2_HWWAR2); 1268 val = val & (~AR_PCU_MISC_MODE2_HWWAR2);
@@ -1439,7 +1406,10 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
1439 return -EINVAL; 1406 return -EINVAL;
1440 } 1407 }
1441 1408
1409 /* Set correct baseband to analog shift setting to access analog chips */
1442 REG_WRITE(ah, AR_PHY(0), 0x00000007); 1410 REG_WRITE(ah, AR_PHY(0), 0x00000007);
1411
1412 /* Write ADDAC shifts */
1443 REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO); 1413 REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO);
1444 ah->eep_ops->set_addac(ah, chan); 1414 ah->eep_ops->set_addac(ah, chan);
1445 1415
@@ -1451,9 +1421,11 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
1451 sizeof(u32) * ah->iniAddac.ia_rows * 1421 sizeof(u32) * ah->iniAddac.ia_rows *
1452 ah->iniAddac.ia_columns; 1422 ah->iniAddac.ia_columns;
1453 1423
1424 /* For AR5416 2.0/2.1 */
1454 memcpy(ah->addac5416_21, 1425 memcpy(ah->addac5416_21,
1455 ah->iniAddac.ia_array, addacSize); 1426 ah->iniAddac.ia_array, addacSize);
1456 1427
1428 /* override CLKDRV value at [row, column] = [31, 1] */
1457 (ah->addac5416_21)[31 * ah->iniAddac.ia_columns + 1] = 0; 1429 (ah->addac5416_21)[31 * ah->iniAddac.ia_columns + 1] = 0;
1458 1430
1459 temp.ia_array = ah->addac5416_21; 1431 temp.ia_array = ah->addac5416_21;
@@ -1485,6 +1457,11 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
1485 AR_SREV_9287_10_OR_LATER(ah)) 1457 AR_SREV_9287_10_OR_LATER(ah))
1486 REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites); 1458 REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites);
1487 1459
1460 if (AR_SREV_9271_10(ah))
1461 REG_WRITE_ARRAY(&ah->iniModes_9271_1_0_only,
1462 modesIndex, regWrites);
1463
1464 /* Write common array parameters */
1488 for (i = 0; i < ah->iniCommon.ia_rows; i++) { 1465 for (i = 0; i < ah->iniCommon.ia_rows; i++) {
1489 u32 reg = INI_RA(&ah->iniCommon, i, 0); 1466 u32 reg = INI_RA(&ah->iniCommon, i, 0);
1490 u32 val = INI_RA(&ah->iniCommon, i, 1); 1467 u32 val = INI_RA(&ah->iniCommon, i, 1);
@@ -1499,11 +1476,16 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
1499 DO_DELAY(regWrites); 1476 DO_DELAY(regWrites);
1500 } 1477 }
1501 1478
1502 ath9k_hw_write_regs(ah, freqIndex, regWrites); 1479 if (AR_SREV_9271(ah)) {
1480 if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) == 1)
1481 REG_WRITE_ARRAY(&ah->iniModes_high_power_tx_gain_9271,
1482 modesIndex, regWrites);
1483 else
1484 REG_WRITE_ARRAY(&ah->iniModes_normal_power_tx_gain_9271,
1485 modesIndex, regWrites);
1486 }
1503 1487
1504 if (AR_SREV_9271_10(ah)) 1488 ath9k_hw_write_regs(ah, freqIndex, regWrites);
1505 REG_WRITE_ARRAY(&ah->iniModes_9271_1_0_only,
1506 modesIndex, regWrites);
1507 1489
1508 if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) { 1490 if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) {
1509 REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex, 1491 REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex,
@@ -1517,6 +1499,7 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
1517 if (OLC_FOR_AR9280_20_LATER) 1499 if (OLC_FOR_AR9280_20_LATER)
1518 ath9k_olc_init(ah); 1500 ath9k_olc_init(ah);
1519 1501
1502 /* Set TX power */
1520 ah->eep_ops->set_txpower(ah, chan, 1503 ah->eep_ops->set_txpower(ah, chan,
1521 ath9k_regd_get_ctl(regulatory, chan), 1504 ath9k_regd_get_ctl(regulatory, chan),
1522 channel->max_antenna_gain * 2, 1505 channel->max_antenna_gain * 2,
@@ -1524,6 +1507,7 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
1524 min((u32) MAX_RATE_POWER, 1507 min((u32) MAX_RATE_POWER,
1525 (u32) regulatory->power_limit)); 1508 (u32) regulatory->power_limit));
1526 1509
1510 /* Write analog registers */
1527 if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) { 1511 if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
1528 ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, 1512 ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
1529 "ar5416SetRfRegs failed\n"); 1513 "ar5416SetRfRegs failed\n");
@@ -1966,6 +1950,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1966 1950
1967 ath9k_hw_mark_phy_inactive(ah); 1951 ath9k_hw_mark_phy_inactive(ah);
1968 1952
1953 /* Only required on the first reset */
1969 if (AR_SREV_9271(ah) && ah->htc_reset_init) { 1954 if (AR_SREV_9271(ah) && ah->htc_reset_init) {
1970 REG_WRITE(ah, 1955 REG_WRITE(ah,
1971 AR9271_RESET_POWER_DOWN_CONTROL, 1956 AR9271_RESET_POWER_DOWN_CONTROL,
@@ -1978,6 +1963,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1978 return -EINVAL; 1963 return -EINVAL;
1979 } 1964 }
1980 1965
1966 /* Only required on the first reset */
1981 if (AR_SREV_9271(ah) && ah->htc_reset_init) { 1967 if (AR_SREV_9271(ah) && ah->htc_reset_init) {
1982 ah->htc_reset_init = false; 1968 ah->htc_reset_init = false;
1983 REG_WRITE(ah, 1969 REG_WRITE(ah,
@@ -2438,7 +2424,7 @@ static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip)
2438 if (!AR_SREV_9100(ah)) 2424 if (!AR_SREV_9100(ah))
2439 REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF); 2425 REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
2440 2426
2441 if(!AR_SREV_5416(ah)) 2427 if (!AR_SREV_5416(ah) && !AR_SREV_9271(ah))
2442 REG_CLR_BIT(ah, (AR_RTC_RESET), 2428 REG_CLR_BIT(ah, (AR_RTC_RESET),
2443 AR_RTC_RESET_EN); 2429 AR_RTC_RESET_EN);
2444 } 2430 }
@@ -2921,14 +2907,11 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
2921 2907
2922 ath_print(common, ATH_DBG_INTERRUPT, "new IMR 0x%x\n", mask); 2908 ath_print(common, ATH_DBG_INTERRUPT, "new IMR 0x%x\n", mask);
2923 REG_WRITE(ah, AR_IMR, mask); 2909 REG_WRITE(ah, AR_IMR, mask);
2924 mask = REG_READ(ah, AR_IMR_S2) & ~(AR_IMR_S2_TIM | 2910 ah->imrs2_reg &= ~(AR_IMR_S2_TIM | AR_IMR_S2_DTIM | AR_IMR_S2_DTIMSYNC |
2925 AR_IMR_S2_DTIM | 2911 AR_IMR_S2_CABEND | AR_IMR_S2_CABTO |
2926 AR_IMR_S2_DTIMSYNC | 2912 AR_IMR_S2_TSFOOR | AR_IMR_S2_GTT | AR_IMR_S2_CST);
2927 AR_IMR_S2_CABEND | 2913 ah->imrs2_reg |= mask2;
2928 AR_IMR_S2_CABTO | 2914 REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg);
2929 AR_IMR_S2_TSFOOR |
2930 AR_IMR_S2_GTT | AR_IMR_S2_CST);
2931 REG_WRITE(ah, AR_IMR_S2, mask | mask2);
2932 ah->mask_reg = ints; 2915 ah->mask_reg = ints;
2933 2916
2934 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { 2917 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
@@ -3219,7 +3202,9 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
3219 else 3202 else
3220 pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD; 3203 pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD;
3221 3204
3222 if (AR_SREV_9285_10_OR_LATER(ah)) 3205 if (AR_SREV_9271(ah))
3206 pCap->num_gpio_pins = AR9271_NUM_GPIO;
3207 else if (AR_SREV_9285_10_OR_LATER(ah))
3223 pCap->num_gpio_pins = AR9285_NUM_GPIO; 3208 pCap->num_gpio_pins = AR9285_NUM_GPIO;
3224 else if (AR_SREV_9280_10_OR_LATER(ah)) 3209 else if (AR_SREV_9280_10_OR_LATER(ah))
3225 pCap->num_gpio_pins = AR928X_NUM_GPIO; 3210 pCap->num_gpio_pins = AR928X_NUM_GPIO;
@@ -3455,7 +3440,9 @@ u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio)
3455 if (gpio >= ah->caps.num_gpio_pins) 3440 if (gpio >= ah->caps.num_gpio_pins)
3456 return 0xffffffff; 3441 return 0xffffffff;
3457 3442
3458 if (AR_SREV_9287_10_OR_LATER(ah)) 3443 if (AR_SREV_9271(ah))
3444 return MS_REG_READ(AR9271, gpio) != 0;
3445 else if (AR_SREV_9287_10_OR_LATER(ah))
3459 return MS_REG_READ(AR9287, gpio) != 0; 3446 return MS_REG_READ(AR9287, gpio) != 0;
3460 else if (AR_SREV_9285_10_OR_LATER(ah)) 3447 else if (AR_SREV_9285_10_OR_LATER(ah))
3461 return MS_REG_READ(AR9285, gpio) != 0; 3448 return MS_REG_READ(AR9285, gpio) != 0;
@@ -3484,6 +3471,9 @@ EXPORT_SYMBOL(ath9k_hw_cfg_output);
3484 3471
3485void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val) 3472void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val)
3486{ 3473{
3474 if (AR_SREV_9271(ah))
3475 val = ~val;
3476
3487 REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio), 3477 REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio),
3488 AR_GPIO_BIT(gpio)); 3478 AR_GPIO_BIT(gpio));
3489} 3479}
@@ -3868,6 +3858,16 @@ void ath_gen_timer_isr(struct ath_hw *ah)
3868} 3858}
3869EXPORT_SYMBOL(ath_gen_timer_isr); 3859EXPORT_SYMBOL(ath_gen_timer_isr);
3870 3860
3861/********/
3862/* HTC */
3863/********/
3864
3865void ath9k_hw_htc_resetinit(struct ath_hw *ah)
3866{
3867 ah->htc_reset_init = true;
3868}
3869EXPORT_SYMBOL(ath9k_hw_htc_resetinit);
3870
3871static struct { 3871static struct {
3872 u32 version; 3872 u32 version;
3873 const char * name; 3873 const char * name;
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index dbbf7ca5f97..6b03e1688b2 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;
@@ -598,6 +599,11 @@ struct ath_hw {
598 struct ar5416IniArray iniModes_9271_1_0_only; 599 struct ar5416IniArray iniModes_9271_1_0_only;
599 struct ar5416IniArray iniCckfirNormal; 600 struct ar5416IniArray iniCckfirNormal;
600 struct ar5416IniArray iniCckfirJapan2484; 601 struct ar5416IniArray iniCckfirJapan2484;
602 struct ar5416IniArray iniCommon_normal_cck_fir_coeff_9271;
603 struct ar5416IniArray iniCommon_japan_2484_cck_fir_coeff_9271;
604 struct ar5416IniArray iniModes_9271_ANI_reg;
605 struct ar5416IniArray iniModes_high_power_tx_gain_9271;
606 struct ar5416IniArray iniModes_normal_power_tx_gain_9271;
601 607
602 u32 intr_gen_timer_trigger; 608 u32 intr_gen_timer_trigger;
603 u32 intr_gen_timer_thresh; 609 u32 intr_gen_timer_thresh;
@@ -701,6 +707,9 @@ u32 ath9k_hw_gettsf32(struct ath_hw *ah);
701 707
702void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len); 708void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len);
703 709
710/* HTC */
711void ath9k_hw_htc_resetinit(struct ath_hw *ah);
712
704#define ATH_PCIE_CAP_LINK_CTRL 0x70 713#define ATH_PCIE_CAP_LINK_CTRL 0x70
705#define ATH_PCIE_CAP_LINK_L0S 1 714#define ATH_PCIE_CAP_LINK_L0S 1
706#define ATH_PCIE_CAP_LINK_L1 2 715#define ATH_PCIE_CAP_LINK_L1 2
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 3d4d897add6..b78308c3c4d 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -760,6 +760,9 @@ static void ath9k_deinit_softc(struct ath_softc *sc)
760 760
761 tasklet_kill(&sc->intr_tq); 761 tasklet_kill(&sc->intr_tq);
762 tasklet_kill(&sc->bcon_tasklet); 762 tasklet_kill(&sc->bcon_tasklet);
763
764 kfree(sc->sc_ah);
765 sc->sc_ah = NULL;
763} 766}
764 767
765void ath9k_deinit_device(struct ath_softc *sc) 768void ath9k_deinit_device(struct ath_softc *sc)
diff --git a/drivers/net/wireless/ath/ath9k/initvals.h b/drivers/net/wireless/ath/ath9k/initvals.h
index 8a3bf3ab998..177bdeb84ad 100644
--- a/drivers/net/wireless/ath/ath9k/initvals.h
+++ b/drivers/net/wireless/ath/ath9k/initvals.h
@@ -6441,7 +6441,7 @@ static const u_int32_t ar9271Modes_9271[][6] = {
6441 { 0x00009a44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 }, 6441 { 0x00009a44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 },
6442 { 0x00009a48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 }, 6442 { 0x00009a48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 },
6443 { 0x00009a4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 }, 6443 { 0x00009a4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 },
6444 { 0x00009a50, 0x00000000, 0x00000000, 0x00058220, 0x00058220, 0x00000000 }, 6444 { 0x00009a50, 0x00000000, 0x00000000, 0x00058224, 0x00058224, 0x00000000 },
6445 { 0x00009a54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 }, 6445 { 0x00009a54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 },
6446 { 0x00009a58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 }, 6446 { 0x00009a58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 },
6447 { 0x00009a5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 }, 6447 { 0x00009a5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 },
@@ -6455,8 +6455,8 @@ static const u_int32_t ar9271Modes_9271[][6] = {
6455 { 0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 }, 6455 { 0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 },
6456 { 0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 }, 6456 { 0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 },
6457 { 0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 }, 6457 { 0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 },
6458 { 0x00009a88, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 }, 6458 { 0x00009a88, 0x00000000, 0x00000000, 0x00078b00, 0x00078b00, 0x00000000 },
6459 { 0x00009a8c, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, 6459 { 0x00009a8c, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 },
6460 { 0x00009a90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, 6460 { 0x00009a90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
6461 { 0x00009a94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 }, 6461 { 0x00009a94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 },
6462 { 0x00009a98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 }, 6462 { 0x00009a98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 },
@@ -6569,7 +6569,7 @@ static const u_int32_t ar9271Modes_9271[][6] = {
6569 { 0x0000aa44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 }, 6569 { 0x0000aa44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 },
6570 { 0x0000aa48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 }, 6570 { 0x0000aa48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 },
6571 { 0x0000aa4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 }, 6571 { 0x0000aa4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 },
6572 { 0x0000aa50, 0x00000000, 0x00000000, 0x00058220, 0x00058220, 0x00000000 }, 6572 { 0x0000aa50, 0x00000000, 0x00000000, 0x00058224, 0x00058224, 0x00000000 },
6573 { 0x0000aa54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 }, 6573 { 0x0000aa54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 },
6574 { 0x0000aa58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 }, 6574 { 0x0000aa58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 },
6575 { 0x0000aa5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 }, 6575 { 0x0000aa5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 },
@@ -6583,8 +6583,8 @@ static const u_int32_t ar9271Modes_9271[][6] = {
6583 { 0x0000aa7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 }, 6583 { 0x0000aa7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 },
6584 { 0x0000aa80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 }, 6584 { 0x0000aa80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 },
6585 { 0x0000aa84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 }, 6585 { 0x0000aa84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 },
6586 { 0x0000aa88, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 }, 6586 { 0x0000aa88, 0x00000000, 0x00000000, 0x00078b00, 0x00078b00, 0x00000000 },
6587 { 0x0000aa8c, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, 6587 { 0x0000aa8c, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 },
6588 { 0x0000aa90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, 6588 { 0x0000aa90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
6589 { 0x0000aa94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 }, 6589 { 0x0000aa94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 },
6590 { 0x0000aa98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 }, 6590 { 0x0000aa98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 },
@@ -6683,25 +6683,6 @@ static const u_int32_t ar9271Modes_9271[][6] = {
6683 { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a }, 6683 { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
6684 { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 }, 6684 { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
6685 { 0x0000a250, 0x0004f000, 0x0004f000, 0x0004a000, 0x0004a000, 0x0004a000 }, 6685 { 0x0000a250, 0x0004f000, 0x0004f000, 0x0004a000, 0x0004a000, 0x0004a000 },
6686 { 0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a218652, 0x0a218652, 0x0a22a652 },
6687 { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
6688 { 0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000 },
6689 { 0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000 },
6690 { 0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608, 0x00000000 },
6691 { 0x0000a310, 0x00000000, 0x00000000, 0x0001e610, 0x0001e610, 0x00000000 },
6692 { 0x0000a314, 0x00000000, 0x00000000, 0x0002d6d0, 0x0002d6d0, 0x00000000 },
6693 { 0x0000a318, 0x00000000, 0x00000000, 0x00039758, 0x00039758, 0x00000000 },
6694 { 0x0000a31c, 0x00000000, 0x00000000, 0x0003b759, 0x0003b759, 0x00000000 },
6695 { 0x0000a320, 0x00000000, 0x00000000, 0x0003d75a, 0x0003d75a, 0x00000000 },
6696 { 0x0000a324, 0x00000000, 0x00000000, 0x0004175c, 0x0004175c, 0x00000000 },
6697 { 0x0000a328, 0x00000000, 0x00000000, 0x0004575e, 0x0004575e, 0x00000000 },
6698 { 0x0000a32c, 0x00000000, 0x00000000, 0x0004979f, 0x0004979f, 0x00000000 },
6699 { 0x0000a330, 0x00000000, 0x00000000, 0x0004d7df, 0x0004d7df, 0x00000000 },
6700 { 0x0000a334, 0x000368de, 0x000368de, 0x000368de, 0x000368de, 0x00000000 },
6701 { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 },
6702 { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 },
6703 { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
6704 { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
6705 { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e }, 6686 { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e },
6706}; 6687};
6707 6688
@@ -6879,7 +6860,7 @@ static const u_int32_t ar9271Common_9271[][2] = {
6879 { 0x00008258, 0x00000000 }, 6860 { 0x00008258, 0x00000000 },
6880 { 0x0000825c, 0x400000ff }, 6861 { 0x0000825c, 0x400000ff },
6881 { 0x00008260, 0x00080922 }, 6862 { 0x00008260, 0x00080922 },
6882 { 0x00008264, 0x88a00010 }, 6863 { 0x00008264, 0xa8a00010 },
6883 { 0x00008270, 0x00000000 }, 6864 { 0x00008270, 0x00000000 },
6884 { 0x00008274, 0x40000000 }, 6865 { 0x00008274, 0x40000000 },
6885 { 0x00008278, 0x003e4180 }, 6866 { 0x00008278, 0x003e4180 },
@@ -6910,13 +6891,10 @@ static const u_int32_t ar9271Common_9271[][2] = {
6910 { 0x00007810, 0x71c0d388 }, 6891 { 0x00007810, 0x71c0d388 },
6911 { 0x00007814, 0x924934a8 }, 6892 { 0x00007814, 0x924934a8 },
6912 { 0x0000781c, 0x00000000 }, 6893 { 0x0000781c, 0x00000000 },
6913 { 0x00007820, 0x00000c04 },
6914 { 0x00007824, 0x00d8abff },
6915 { 0x00007828, 0x66964300 }, 6894 { 0x00007828, 0x66964300 },
6916 { 0x0000782c, 0x8db6d961 }, 6895 { 0x0000782c, 0x8db6d961 },
6917 { 0x00007830, 0x8db6d96c }, 6896 { 0x00007830, 0x8db6d96c },
6918 { 0x00007834, 0x6140008b }, 6897 { 0x00007834, 0x6140008b },
6919 { 0x00007838, 0x00000029 },
6920 { 0x0000783c, 0x72ee0a72 }, 6898 { 0x0000783c, 0x72ee0a72 },
6921 { 0x00007840, 0xbbfffffc }, 6899 { 0x00007840, 0xbbfffffc },
6922 { 0x00007844, 0x000c0db6 }, 6900 { 0x00007844, 0x000c0db6 },
@@ -6929,7 +6907,6 @@ static const u_int32_t ar9271Common_9271[][2] = {
6929 { 0x00007860, 0x21084210 }, 6907 { 0x00007860, 0x21084210 },
6930 { 0x00007864, 0xf7d7ffde }, 6908 { 0x00007864, 0xf7d7ffde },
6931 { 0x00007868, 0xc2034080 }, 6909 { 0x00007868, 0xc2034080 },
6932 { 0x0000786c, 0x48609eb4 },
6933 { 0x00007870, 0x10142c00 }, 6910 { 0x00007870, 0x10142c00 },
6934 { 0x00009808, 0x00000000 }, 6911 { 0x00009808, 0x00000000 },
6935 { 0x0000980c, 0xafe68e30 }, 6912 { 0x0000980c, 0xafe68e30 },
@@ -6982,9 +6959,6 @@ static const u_int32_t ar9271Common_9271[][2] = {
6982 { 0x000099e8, 0x3c466478 }, 6959 { 0x000099e8, 0x3c466478 },
6983 { 0x000099ec, 0x0cc80caa }, 6960 { 0x000099ec, 0x0cc80caa },
6984 { 0x000099f0, 0x00000000 }, 6961 { 0x000099f0, 0x00000000 },
6985 { 0x0000a1f4, 0x00000000 },
6986 { 0x0000a1f8, 0x71733d01 },
6987 { 0x0000a1fc, 0xd0ad5c12 },
6988 { 0x0000a208, 0x803e68c8 }, 6962 { 0x0000a208, 0x803e68c8 },
6989 { 0x0000a210, 0x4080a333 }, 6963 { 0x0000a210, 0x4080a333 },
6990 { 0x0000a214, 0x00206c10 }, 6964 { 0x0000a214, 0x00206c10 },
@@ -7004,13 +6978,9 @@ static const u_int32_t ar9271Common_9271[][2] = {
7004 { 0x0000a260, 0xdfa90f01 }, 6978 { 0x0000a260, 0xdfa90f01 },
7005 { 0x0000a268, 0x00000000 }, 6979 { 0x0000a268, 0x00000000 },
7006 { 0x0000a26c, 0x0ebae9e6 }, 6980 { 0x0000a26c, 0x0ebae9e6 },
7007 { 0x0000a278, 0x3bdef7bd },
7008 { 0x0000a27c, 0x050e83bd },
7009 { 0x0000a388, 0x0c000000 }, 6981 { 0x0000a388, 0x0c000000 },
7010 { 0x0000a38c, 0x20202020 }, 6982 { 0x0000a38c, 0x20202020 },
7011 { 0x0000a390, 0x20202020 }, 6983 { 0x0000a390, 0x20202020 },
7012 { 0x0000a394, 0x3bdef7bd },
7013 { 0x0000a398, 0x000003bd },
7014 { 0x0000a39c, 0x00000001 }, 6984 { 0x0000a39c, 0x00000001 },
7015 { 0x0000a3a0, 0x00000000 }, 6985 { 0x0000a3a0, 0x00000000 },
7016 { 0x0000a3a4, 0x00000000 }, 6986 { 0x0000a3a4, 0x00000000 },
@@ -7025,8 +6995,6 @@ static const u_int32_t ar9271Common_9271[][2] = {
7025 { 0x0000a3cc, 0x20202020 }, 6995 { 0x0000a3cc, 0x20202020 },
7026 { 0x0000a3d0, 0x20202020 }, 6996 { 0x0000a3d0, 0x20202020 },
7027 { 0x0000a3d4, 0x20202020 }, 6997 { 0x0000a3d4, 0x20202020 },
7028 { 0x0000a3dc, 0x3bdef7bd },
7029 { 0x0000a3e0, 0x000003bd },
7030 { 0x0000a3e4, 0x00000000 }, 6998 { 0x0000a3e4, 0x00000000 },
7031 { 0x0000a3e8, 0x18c43433 }, 6999 { 0x0000a3e8, 0x18c43433 },
7032 { 0x0000a3ec, 0x00f70081 }, 7000 { 0x0000a3ec, 0x00f70081 },
@@ -7046,7 +7014,102 @@ static const u_int32_t ar9271Common_9271[][2] = {
7046 { 0x0000d384, 0xf3307ff0 }, 7014 { 0x0000d384, 0xf3307ff0 },
7047}; 7015};
7048 7016
7017static const u_int32_t ar9271Common_normal_cck_fir_coeff_9271[][2] = {
7018 { 0x0000a1f4, 0x00fffeff },
7019 { 0x0000a1f8, 0x00f5f9ff },
7020 { 0x0000a1fc, 0xb79f6427 },
7021};
7022
7023static const u_int32_t ar9271Common_japan_2484_cck_fir_coeff_9271[][2] = {
7024 { 0x0000a1f4, 0x00000000 },
7025 { 0x0000a1f8, 0xefff0301 },
7026 { 0x0000a1fc, 0xca9228ee },
7027};
7028
7049static const u_int32_t ar9271Modes_9271_1_0_only[][6] = { 7029static const u_int32_t ar9271Modes_9271_1_0_only[][6] = {
7050 { 0x00009910, 0x30002311, 0x30002311, 0x30002311, 0x30002311, 0x30002311 }, 7030 { 0x00009910, 0x30002311, 0x30002311, 0x30002311, 0x30002311, 0x30002311 },
7051 { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 }, 7031 { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
7052}; 7032};
7033
7034static const u_int32_t ar9271Modes_9271_ANI_reg[][6] = {
7035 { 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2 },
7036 { 0x0000985c, 0x3139605e, 0x3139605e, 0x3137605e, 0x3137605e, 0x3139605e },
7037 { 0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e },
7038 { 0x0000986c, 0x06903881, 0x06903881, 0x06903881, 0x06903881, 0x06903881 },
7039 { 0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0 },
7040 { 0x0000a208, 0x803e68c8, 0x803e68c8, 0x803e68c8, 0x803e68c8, 0x803e68c8 },
7041 { 0x00009924, 0xd00a8007, 0xd00a8007, 0xd00a800d, 0xd00a800d, 0xd00a800d },
7042 { 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 },
7043};
7044
7045static const u_int32_t ar9271Modes_normal_power_tx_gain_9271[][6] = {
7046 { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
7047 { 0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000 },
7048 { 0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000 },
7049 { 0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608, 0x00000000 },
7050 { 0x0000a310, 0x00000000, 0x00000000, 0x0001e610, 0x0001e610, 0x00000000 },
7051 { 0x0000a314, 0x00000000, 0x00000000, 0x0002d6d0, 0x0002d6d0, 0x00000000 },
7052 { 0x0000a318, 0x00000000, 0x00000000, 0x00039758, 0x00039758, 0x00000000 },
7053 { 0x0000a31c, 0x00000000, 0x00000000, 0x0003b759, 0x0003b759, 0x00000000 },
7054 { 0x0000a320, 0x00000000, 0x00000000, 0x0003d75a, 0x0003d75a, 0x00000000 },
7055 { 0x0000a324, 0x00000000, 0x00000000, 0x0004175c, 0x0004175c, 0x00000000 },
7056 { 0x0000a328, 0x00000000, 0x00000000, 0x0004575e, 0x0004575e, 0x00000000 },
7057 { 0x0000a32c, 0x00000000, 0x00000000, 0x0004979f, 0x0004979f, 0x00000000 },
7058 { 0x0000a330, 0x00000000, 0x00000000, 0x0004d7df, 0x0004d7df, 0x00000000 },
7059 { 0x0000a334, 0x000368de, 0x000368de, 0x000368de, 0x000368de, 0x00000000 },
7060 { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 },
7061 { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 },
7062 { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
7063 { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
7064 { 0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
7065 { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
7066 { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
7067 { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
7068 { 0x00007838, 0x00000029, 0x00000029, 0x00000029, 0x00000029, 0x00000029 },
7069 { 0x00007824, 0x00d8abff, 0x00d8abff, 0x00d8abff, 0x00d8abff, 0x00d8abff },
7070 { 0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4 },
7071 { 0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04 },
7072 { 0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a218652, 0x0a218652, 0x0a22a652 },
7073 { 0x0000a278, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd },
7074 { 0x0000a27c, 0x050e83bd, 0x050e83bd, 0x050e83bd, 0x050e83bd, 0x050e83bd },
7075 { 0x0000a394, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd },
7076 { 0x0000a398, 0x000003bd, 0x000003bd, 0x000003bd, 0x000003bd, 0x000003bd },
7077 { 0x0000a3dc, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd },
7078 { 0x0000a3e0, 0x000003bd, 0x000003bd, 0x000003bd, 0x000003bd, 0x000003bd },
7079};
7080
7081static const u_int32_t ar9271Modes_high_power_tx_gain_9271[][6] = {
7082 { 0x0000a300, 0x00000000, 0x00000000, 0x00010000, 0x00010000, 0x00000000 },
7083 { 0x0000a304, 0x00000000, 0x00000000, 0x00016200, 0x00016200, 0x00000000 },
7084 { 0x0000a308, 0x00000000, 0x00000000, 0x00018201, 0x00018201, 0x00000000 },
7085 { 0x0000a30c, 0x00000000, 0x00000000, 0x0001b240, 0x0001b240, 0x00000000 },
7086 { 0x0000a310, 0x00000000, 0x00000000, 0x0001d241, 0x0001d241, 0x00000000 },
7087 { 0x0000a314, 0x00000000, 0x00000000, 0x0001f600, 0x0001f600, 0x00000000 },
7088 { 0x0000a318, 0x00000000, 0x00000000, 0x00022800, 0x00022800, 0x00000000 },
7089 { 0x0000a31c, 0x00000000, 0x00000000, 0x00026802, 0x00026802, 0x00000000 },
7090 { 0x0000a320, 0x00000000, 0x00000000, 0x0002b805, 0x0002b805, 0x00000000 },
7091 { 0x0000a324, 0x00000000, 0x00000000, 0x0002ea41, 0x0002ea41, 0x00000000 },
7092 { 0x0000a328, 0x00000000, 0x00000000, 0x00038b00, 0x00038b00, 0x00000000 },
7093 { 0x0000a32c, 0x00000000, 0x00000000, 0x0003ab40, 0x0003ab40, 0x00000000 },
7094 { 0x0000a330, 0x00000000, 0x00000000, 0x0003cd80, 0x0003cd80, 0x00000000 },
7095 { 0x0000a334, 0x000368de, 0x000368de, 0x000368de, 0x000368de, 0x00000000 },
7096 { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 },
7097 { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 },
7098 { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
7099 { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
7100 { 0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
7101 { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
7102 { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
7103 { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
7104 { 0x00007838, 0x0000002b, 0x0000002b, 0x0000002b, 0x0000002b, 0x0000002b },
7105 { 0x00007824, 0x00d8a7ff, 0x00d8a7ff, 0x00d8a7ff, 0x00d8a7ff, 0x00d8a7ff },
7106 { 0x0000786c, 0x08609eb6, 0x08609eb6, 0x08609eba, 0x08609eba, 0x08609eb6 },
7107 { 0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00 },
7108 { 0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a212652, 0x0a212652, 0x0a22a652 },
7109 { 0x0000a278, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7 },
7110 { 0x0000a27c, 0x05018063, 0x05038063, 0x05018063, 0x05018063, 0x05018063 },
7111 { 0x0000a394, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63 },
7112 { 0x0000a398, 0x00000063, 0x00000063, 0x00000063, 0x00000063, 0x00000063 },
7113 { 0x0000a3dc, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63 },
7114 { 0x0000a3e0, 0x00000063, 0x00000063, 0x00000063, 0x00000063, 0x00000063 },
7115};
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index efc420cd42b..7af823a1527 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
38u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q) 40u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q)
@@ -349,7 +351,7 @@ void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds,
349 351
350 ads->ds_ctl6 = SM(keyType, AR_EncrType); 352 ads->ds_ctl6 = SM(keyType, AR_EncrType);
351 353
352 if (AR_SREV_9285(ah)) { 354 if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) {
353 ads->ds_ctl8 = 0; 355 ads->ds_ctl8 = 0;
354 ads->ds_ctl9 = 0; 356 ads->ds_ctl9 = 0;
355 ads->ds_ctl10 = 0; 357 ads->ds_ctl10 = 0;
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index 29851e6376a..a5e543bd227 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -150,6 +150,32 @@ struct ath_rx_status {
150 u32 evm2; 150 u32 evm2;
151}; 151};
152 152
153struct ath_htc_rx_status {
154 u64 rs_tstamp;
155 u16 rs_datalen;
156 u8 rs_status;
157 u8 rs_phyerr;
158 int8_t rs_rssi;
159 int8_t rs_rssi_ctl0;
160 int8_t rs_rssi_ctl1;
161 int8_t rs_rssi_ctl2;
162 int8_t rs_rssi_ext0;
163 int8_t rs_rssi_ext1;
164 int8_t rs_rssi_ext2;
165 u8 rs_keyix;
166 u8 rs_rate;
167 u8 rs_antenna;
168 u8 rs_more;
169 u8 rs_isaggr;
170 u8 rs_moreaggr;
171 u8 rs_num_delims;
172 u8 rs_flags;
173 u8 rs_dummy;
174 u32 evm0;
175 u32 evm1;
176 u32 evm2;
177};
178
153#define ATH9K_RXERR_CRC 0x01 179#define ATH9K_RXERR_CRC 0x01
154#define ATH9K_RXERR_PHY 0x02 180#define ATH9K_RXERR_PHY 0x02
155#define ATH9K_RXERR_FIFO 0x04 181#define ATH9K_RXERR_FIFO 0x04
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index 244e1c62917..ee81291f2fb 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -1228,8 +1228,12 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
1228 long_retry = rate->count - 1; 1228 long_retry = rate->count - 1;
1229 } 1229 }
1230 1230
1231 if (!priv_sta || !ieee80211_is_data(fc) || 1231 if (!priv_sta || !ieee80211_is_data(fc))
1232 !(tx_info->pad[0] & ATH_TX_INFO_UPDATE_RC)) 1232 return;
1233
1234 /* This packet was aggregated but doesn't carry status info */
1235 if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) &&
1236 !(tx_info->flags & IEEE80211_TX_STAT_AMPDU))
1233 return; 1237 return;
1234 1238
1235 if (tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) 1239 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 4f6d6fd442f..36083dde863 100644
--- a/drivers/net/wireless/ath/ath9k/rc.h
+++ b/drivers/net/wireless/ath/ath9k/rc.h
@@ -110,8 +110,8 @@ struct ath_rate_table {
110 int rate_cnt; 110 int rate_cnt;
111 int mcs_start; 111 int mcs_start;
112 struct { 112 struct {
113 int valid; 113 u8 valid;
114 int valid_single_stream; 114 u8 valid_single_stream;
115 u8 phy; 115 u8 phy;
116 u32 ratekbps; 116 u32 ratekbps;
117 u32 user_ratekbps; 117 u32 user_ratekbps;
@@ -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/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 72cfa8ebd9a..198e41dd38a 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -940,6 +940,7 @@ enum {
940#define AR928X_NUM_GPIO 10 940#define AR928X_NUM_GPIO 10
941#define AR9285_NUM_GPIO 12 941#define AR9285_NUM_GPIO 12
942#define AR9287_NUM_GPIO 11 942#define AR9287_NUM_GPIO 11
943#define AR9271_NUM_GPIO 16
943 944
944#define AR_GPIO_IN_OUT 0x4048 945#define AR_GPIO_IN_OUT 0x4048
945#define AR_GPIO_IN_VAL 0x0FFFC000 946#define AR_GPIO_IN_VAL 0x0FFFC000
@@ -950,6 +951,8 @@ enum {
950#define AR9285_GPIO_IN_VAL_S 12 951#define AR9285_GPIO_IN_VAL_S 12
951#define AR9287_GPIO_IN_VAL 0x003FF800 952#define AR9287_GPIO_IN_VAL 0x003FF800
952#define AR9287_GPIO_IN_VAL_S 11 953#define AR9287_GPIO_IN_VAL_S 11
954#define AR9271_GPIO_IN_VAL 0xFFFF0000
955#define AR9271_GPIO_IN_VAL_S 16
953 956
954#define AR_GPIO_OE_OUT 0x404c 957#define AR_GPIO_OE_OUT 0x404c
955#define AR_GPIO_OE_OUT_DRV 0x3 958#define AR_GPIO_OE_OUT_DRV 0x3
diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c
new file mode 100644
index 00000000000..818dea0164e
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/wmi.c
@@ -0,0 +1,319 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "htc.h"
18
19static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd)
20{
21 switch (wmi_cmd) {
22 case WMI_ECHO_CMDID:
23 return "WMI_ECHO_CMDID";
24 case WMI_ACCESS_MEMORY_CMDID:
25 return "WMI_ACCESS_MEMORY_CMDID";
26 case WMI_DISABLE_INTR_CMDID:
27 return "WMI_DISABLE_INTR_CMDID";
28 case WMI_ENABLE_INTR_CMDID:
29 return "WMI_ENABLE_INTR_CMDID";
30 case WMI_RX_LINK_CMDID:
31 return "WMI_RX_LINK_CMDID";
32 case WMI_ATH_INIT_CMDID:
33 return "WMI_ATH_INIT_CMDID";
34 case WMI_ABORT_TXQ_CMDID:
35 return "WMI_ABORT_TXQ_CMDID";
36 case WMI_STOP_TX_DMA_CMDID:
37 return "WMI_STOP_TX_DMA_CMDID";
38 case WMI_STOP_DMA_RECV_CMDID:
39 return "WMI_STOP_DMA_RECV_CMDID";
40 case WMI_ABORT_TX_DMA_CMDID:
41 return "WMI_ABORT_TX_DMA_CMDID";
42 case WMI_DRAIN_TXQ_CMDID:
43 return "WMI_DRAIN_TXQ_CMDID";
44 case WMI_DRAIN_TXQ_ALL_CMDID:
45 return "WMI_DRAIN_TXQ_ALL_CMDID";
46 case WMI_START_RECV_CMDID:
47 return "WMI_START_RECV_CMDID";
48 case WMI_STOP_RECV_CMDID:
49 return "WMI_STOP_RECV_CMDID";
50 case WMI_FLUSH_RECV_CMDID:
51 return "WMI_FLUSH_RECV_CMDID";
52 case WMI_SET_MODE_CMDID:
53 return "WMI_SET_MODE_CMDID";
54 case WMI_RESET_CMDID:
55 return "WMI_RESET_CMDID";
56 case WMI_NODE_CREATE_CMDID:
57 return "WMI_NODE_CREATE_CMDID";
58 case WMI_NODE_REMOVE_CMDID:
59 return "WMI_NODE_REMOVE_CMDID";
60 case WMI_VAP_REMOVE_CMDID:
61 return "WMI_VAP_REMOVE_CMDID";
62 case WMI_VAP_CREATE_CMDID:
63 return "WMI_VAP_CREATE_CMDID";
64 case WMI_BEACON_UPDATE_CMDID:
65 return "WMI_BEACON_UPDATE_CMDID";
66 case WMI_REG_READ_CMDID:
67 return "WMI_REG_READ_CMDID";
68 case WMI_REG_WRITE_CMDID:
69 return "WMI_REG_WRITE_CMDID";
70 case WMI_RC_STATE_CHANGE_CMDID:
71 return "WMI_RC_STATE_CHANGE_CMDID";
72 case WMI_RC_RATE_UPDATE_CMDID:
73 return "WMI_RC_RATE_UPDATE_CMDID";
74 case WMI_DEBUG_INFO_CMDID:
75 return "WMI_DEBUG_INFO_CMDID";
76 case WMI_HOST_ATTACH:
77 return "WMI_HOST_ATTACH";
78 case WMI_TARGET_IC_UPDATE_CMDID:
79 return "WMI_TARGET_IC_UPDATE_CMDID";
80 case WMI_TGT_STATS_CMDID:
81 return "WMI_TGT_STATS_CMDID";
82 case WMI_TX_AGGR_ENABLE_CMDID:
83 return "WMI_TX_AGGR_ENABLE_CMDID";
84 case WMI_TGT_DETACH_CMDID:
85 return "WMI_TGT_DETACH_CMDID";
86 case WMI_TGT_TXQ_ENABLE_CMDID:
87 return "WMI_TGT_TXQ_ENABLE_CMDID";
88 }
89
90 return "Bogus";
91}
92
93struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv)
94{
95 struct wmi *wmi;
96
97 wmi = kzalloc(sizeof(struct wmi), GFP_KERNEL);
98 if (!wmi)
99 return NULL;
100
101 wmi->drv_priv = priv;
102 wmi->stopped = false;
103 mutex_init(&wmi->op_mutex);
104 init_completion(&wmi->cmd_wait);
105
106 return wmi;
107}
108
109void ath9k_deinit_wmi(struct ath9k_htc_priv *priv)
110{
111 struct wmi *wmi = priv->wmi;
112
113 mutex_lock(&wmi->op_mutex);
114 wmi->stopped = true;
115 mutex_unlock(&wmi->op_mutex);
116
117 kfree(priv->wmi);
118}
119
120void ath9k_wmi_tasklet(unsigned long data)
121{
122 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
123 struct ath_common *common = ath9k_hw_common(priv->ah);
124 struct wmi_cmd_hdr *hdr;
125 struct wmi_swba *swba_hdr;
126 enum wmi_event_id event;
127 struct sk_buff *skb;
128 void *wmi_event;
129 unsigned long flags;
130#ifdef CONFIG_ATH9K_HTC_DEBUGFS
131 u32 txrate;
132#endif
133
134 spin_lock_irqsave(&priv->wmi->wmi_lock, flags);
135 skb = priv->wmi->wmi_skb;
136 spin_unlock_irqrestore(&priv->wmi->wmi_lock, flags);
137
138 hdr = (struct wmi_cmd_hdr *) skb->data;
139 event = be16_to_cpu(hdr->command_id);
140 wmi_event = skb_pull(skb, sizeof(struct wmi_cmd_hdr));
141
142 ath_print(common, ATH_DBG_WMI,
143 "WMI Event: 0x%x\n", event);
144
145 switch (event) {
146 case WMI_TGT_RDY_EVENTID:
147 break;
148 case WMI_SWBA_EVENTID:
149 swba_hdr = (struct wmi_swba *) wmi_event;
150 ath9k_htc_swba(priv, swba_hdr->beacon_pending);
151 break;
152 case WMI_FATAL_EVENTID:
153 break;
154 case WMI_TXTO_EVENTID:
155 break;
156 case WMI_BMISS_EVENTID:
157 break;
158 case WMI_WLAN_TXCOMP_EVENTID:
159 break;
160 case WMI_DELBA_EVENTID:
161 break;
162 case WMI_TXRATE_EVENTID:
163#ifdef CONFIG_ATH9K_HTC_DEBUGFS
164 txrate = ((struct wmi_event_txrate *)wmi_event)->txrate;
165 priv->debug.txrate = be32_to_cpu(txrate);
166#endif
167 break;
168 default:
169 break;
170 }
171
172 dev_kfree_skb_any(skb);
173}
174
175static void ath9k_wmi_rsp_callback(struct wmi *wmi, struct sk_buff *skb)
176{
177 skb_pull(skb, sizeof(struct wmi_cmd_hdr));
178
179 if (wmi->cmd_rsp_buf != NULL && wmi->cmd_rsp_len != 0)
180 memcpy(wmi->cmd_rsp_buf, skb->data, wmi->cmd_rsp_len);
181
182 complete(&wmi->cmd_wait);
183}
184
185static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb,
186 enum htc_endpoint_id epid)
187{
188 struct wmi *wmi = (struct wmi *) priv;
189 struct wmi_cmd_hdr *hdr;
190 u16 cmd_id;
191
192 if (unlikely(wmi->stopped))
193 goto free_skb;
194
195 hdr = (struct wmi_cmd_hdr *) skb->data;
196 cmd_id = be16_to_cpu(hdr->command_id);
197
198 if (cmd_id & 0x1000) {
199 spin_lock(&wmi->wmi_lock);
200 wmi->wmi_skb = skb;
201 spin_unlock(&wmi->wmi_lock);
202 tasklet_schedule(&wmi->drv_priv->wmi_tasklet);
203 return;
204 }
205
206 /* WMI command response */
207 ath9k_wmi_rsp_callback(wmi, skb);
208
209free_skb:
210 dev_kfree_skb_any(skb);
211}
212
213static void ath9k_wmi_ctrl_tx(void *priv, struct sk_buff *skb,
214 enum htc_endpoint_id epid, bool txok)
215{
216 dev_kfree_skb_any(skb);
217}
218
219int ath9k_wmi_connect(struct htc_target *htc, struct wmi *wmi,
220 enum htc_endpoint_id *wmi_ctrl_epid)
221{
222 struct htc_service_connreq connect;
223 int ret;
224
225 wmi->htc = htc;
226
227 memset(&connect, 0, sizeof(connect));
228
229 connect.ep_callbacks.priv = wmi;
230 connect.ep_callbacks.tx = ath9k_wmi_ctrl_tx;
231 connect.ep_callbacks.rx = ath9k_wmi_ctrl_rx;
232 connect.service_id = WMI_CONTROL_SVC;
233
234 ret = htc_connect_service(htc, &connect, &wmi->ctrl_epid);
235 if (ret)
236 return ret;
237
238 *wmi_ctrl_epid = wmi->ctrl_epid;
239
240 return 0;
241}
242
243static int ath9k_wmi_cmd_issue(struct wmi *wmi,
244 struct sk_buff *skb,
245 enum wmi_cmd_id cmd, u16 len)
246{
247 struct wmi_cmd_hdr *hdr;
248
249 hdr = (struct wmi_cmd_hdr *) skb_push(skb, sizeof(struct wmi_cmd_hdr));
250 hdr->command_id = cpu_to_be16(cmd);
251 hdr->seq_no = cpu_to_be16(++wmi->tx_seq_id);
252
253 return htc_send(wmi->htc, skb, wmi->ctrl_epid, NULL);
254}
255
256int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
257 u8 *cmd_buf, u32 cmd_len,
258 u8 *rsp_buf, u32 rsp_len,
259 u32 timeout)
260{
261 struct ath_hw *ah = wmi->drv_priv->ah;
262 struct ath_common *common = ath9k_hw_common(ah);
263 u16 headroom = sizeof(struct htc_frame_hdr) +
264 sizeof(struct wmi_cmd_hdr);
265 struct sk_buff *skb;
266 u8 *data;
267 int time_left, ret = 0;
268
269 if (!wmi)
270 return -EINVAL;
271
272 skb = dev_alloc_skb(headroom + cmd_len);
273 if (!skb)
274 return -ENOMEM;
275
276 skb_reserve(skb, headroom);
277
278 if (cmd_len != 0 && cmd_buf != NULL) {
279 data = (u8 *) skb_put(skb, cmd_len);
280 memcpy(data, cmd_buf, cmd_len);
281 }
282
283 mutex_lock(&wmi->op_mutex);
284
285 /* check if wmi stopped flag is set */
286 if (unlikely(wmi->stopped)) {
287 ret = -EPROTO;
288 goto out;
289 }
290
291 /* record the rsp buffer and length */
292 wmi->cmd_rsp_buf = rsp_buf;
293 wmi->cmd_rsp_len = rsp_len;
294
295 ret = ath9k_wmi_cmd_issue(wmi, skb, cmd_id, cmd_len);
296 if (ret)
297 goto out;
298
299 time_left = wait_for_completion_timeout(&wmi->cmd_wait, timeout);
300 if (!time_left) {
301 ath_print(common, ATH_DBG_WMI,
302 "Timeout waiting for WMI command: %s\n",
303 wmi_cmd_to_name(cmd_id));
304 mutex_unlock(&wmi->op_mutex);
305 return -ETIMEDOUT;
306 }
307
308 mutex_unlock(&wmi->op_mutex);
309
310 return 0;
311
312out:
313 ath_print(common, ATH_DBG_WMI,
314 "WMI failure for: %s\n", wmi_cmd_to_name(cmd_id));
315 mutex_unlock(&wmi->op_mutex);
316 dev_kfree_skb_any(skb);
317
318 return ret;
319}
diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h
new file mode 100644
index 00000000000..39ef926f27c
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/wmi.h
@@ -0,0 +1,126 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef WMI_H
18#define WMI_H
19
20
21struct wmi_event_txrate {
22 u32 txrate;
23 struct {
24 u8 rssi_thresh;
25 u8 per;
26 } rc_stats;
27} __packed;
28
29struct wmi_cmd_hdr {
30 u16 command_id;
31 u16 seq_no;
32} __packed;
33
34struct wmi_swba {
35 u8 beacon_pending;
36} __packed;
37
38enum wmi_cmd_id {
39 WMI_ECHO_CMDID = 0x0001,
40 WMI_ACCESS_MEMORY_CMDID,
41
42 /* Commands to Target */
43 WMI_DISABLE_INTR_CMDID,
44 WMI_ENABLE_INTR_CMDID,
45 WMI_RX_LINK_CMDID,
46 WMI_ATH_INIT_CMDID,
47 WMI_ABORT_TXQ_CMDID,
48 WMI_STOP_TX_DMA_CMDID,
49 WMI_STOP_DMA_RECV_CMDID,
50 WMI_ABORT_TX_DMA_CMDID,
51 WMI_DRAIN_TXQ_CMDID,
52 WMI_DRAIN_TXQ_ALL_CMDID,
53 WMI_START_RECV_CMDID,
54 WMI_STOP_RECV_CMDID,
55 WMI_FLUSH_RECV_CMDID,
56 WMI_SET_MODE_CMDID,
57 WMI_RESET_CMDID,
58 WMI_NODE_CREATE_CMDID,
59 WMI_NODE_REMOVE_CMDID,
60 WMI_VAP_REMOVE_CMDID,
61 WMI_VAP_CREATE_CMDID,
62 WMI_BEACON_UPDATE_CMDID,
63 WMI_REG_READ_CMDID,
64 WMI_REG_WRITE_CMDID,
65 WMI_RC_STATE_CHANGE_CMDID,
66 WMI_RC_RATE_UPDATE_CMDID,
67 WMI_DEBUG_INFO_CMDID,
68 WMI_HOST_ATTACH,
69 WMI_TARGET_IC_UPDATE_CMDID,
70 WMI_TGT_STATS_CMDID,
71 WMI_TX_AGGR_ENABLE_CMDID,
72 WMI_TGT_DETACH_CMDID,
73 WMI_TGT_TXQ_ENABLE_CMDID,
74};
75
76enum wmi_event_id {
77 WMI_TGT_RDY_EVENTID = 0x1001,
78 WMI_SWBA_EVENTID,
79 WMI_FATAL_EVENTID,
80 WMI_TXTO_EVENTID,
81 WMI_BMISS_EVENTID,
82 WMI_WLAN_TXCOMP_EVENTID,
83 WMI_DELBA_EVENTID,
84 WMI_TXRATE_EVENTID,
85};
86
87struct wmi {
88 struct ath9k_htc_priv *drv_priv;
89 struct htc_target *htc;
90 enum htc_endpoint_id ctrl_epid;
91 struct mutex op_mutex;
92 struct completion cmd_wait;
93 u16 tx_seq_id;
94 u8 *cmd_rsp_buf;
95 u32 cmd_rsp_len;
96 bool stopped;
97
98 struct sk_buff *wmi_skb;
99 spinlock_t wmi_lock;
100};
101
102struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv);
103void ath9k_deinit_wmi(struct ath9k_htc_priv *priv);
104int ath9k_wmi_connect(struct htc_target *htc, struct wmi *wmi,
105 enum htc_endpoint_id *wmi_ctrl_epid);
106int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
107 u8 *cmd_buf, u32 cmd_len,
108 u8 *rsp_buf, u32 rsp_len,
109 u32 timeout);
110void ath9k_wmi_tasklet(unsigned long data);
111
112#define WMI_CMD(_wmi_cmd) \
113 do { \
114 ret = ath9k_wmi_cmd(priv->wmi, _wmi_cmd, NULL, 0, \
115 (u8 *) &cmd_rsp, \
116 sizeof(cmd_rsp), HZ); \
117 } while (0)
118
119#define WMI_CMD_BUF(_wmi_cmd, _buf) \
120 do { \
121 ret = ath9k_wmi_cmd(priv->wmi, _wmi_cmd, \
122 (u8 *) _buf, sizeof(*_buf), \
123 &cmd_rsp, sizeof(cmd_rsp), HZ); \
124 } while (0)
125
126#endif /* WMI_H */
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 294b486bc3e..a3b6cf20f8a 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/ath/debug.h b/drivers/net/wireless/ath/debug.h
index 8263633c003..873bf526e11 100644
--- a/drivers/net/wireless/ath/debug.h
+++ b/drivers/net/wireless/ath/debug.h
@@ -59,6 +59,7 @@ enum ATH_DEBUG {
59 ATH_DBG_PS = 0x00000800, 59 ATH_DBG_PS = 0x00000800,
60 ATH_DBG_HWTIMER = 0x00001000, 60 ATH_DBG_HWTIMER = 0x00001000,
61 ATH_DBG_BTCOEX = 0x00002000, 61 ATH_DBG_BTCOEX = 0x00002000,
62 ATH_DBG_WMI = 0x00004000,
62 ATH_DBG_ANY = 0xffffffff 63 ATH_DBG_ANY = 0xffffffff
63}; 64};
64 65