diff options
Diffstat (limited to 'ANDROID_3.4.5/drivers/net/wireless/ath/carl9170')
22 files changed, 0 insertions, 13439 deletions
diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/Kconfig b/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/Kconfig deleted file mode 100644 index 267d5dcf..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/Kconfig +++ /dev/null @@ -1,55 +0,0 @@ -config CARL9170 - tristate "Linux Community AR9170 802.11n USB support" - depends on USB && MAC80211 && EXPERIMENTAL - select FW_LOADER - select CRC32 - help - This is another driver for the Atheros "otus" 802.11n USB devices. - - This driver provides more features than the original, - but it needs a special firmware (carl9170-1.fw) to do that. - - The firmware can be downloaded from our wiki here: - <http://wireless.kernel.org/en/users/Drivers/carl9170> - - If you choose to build a module, it'll be called carl9170. - -config CARL9170_LEDS - bool "SoftLED Support" - depends on CARL9170 - select MAC80211_LEDS - select LEDS_CLASS - select NEW_LEDS - default y - help - This option is necessary, if you want your device' LEDs to blink - - Say Y, unless you need the LEDs for firmware debugging. - -config CARL9170_DEBUGFS - bool "DebugFS Support" - depends on CARL9170 && DEBUG_FS && MAC80211_DEBUGFS - default n - help - Export several driver and device internals to user space. - - Say N. - -config CARL9170_WPC - bool - depends on CARL9170 && (INPUT = y || INPUT = CARL9170) - default y - -config CARL9170_HWRNG - bool "Random number generator" - depends on CARL9170 && (HW_RANDOM = y || HW_RANDOM = CARL9170) - default n - help - Provides a hardware random number generator to the kernel. - - SECURITY WARNING: It's relatively easy to eavesdrop all - generated random numbers from the transport stream with - usbmon [software] or special usb sniffer hardware. - - Say N, unless your setup[i.e.: embedded system] has no - other rng source and you can afford to take the risk. diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/Makefile b/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/Makefile deleted file mode 100644 index f64ed76a..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -carl9170-objs := main.o usb.o cmd.o mac.o phy.o led.o fw.o tx.o rx.o -carl9170-$(CONFIG_CARL9170_DEBUGFS) += debug.o - -obj-$(CONFIG_CARL9170) += carl9170.o diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/carl9170.h b/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/carl9170.h deleted file mode 100644 index 0cea20e3..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/carl9170.h +++ /dev/null @@ -1,662 +0,0 @@ -/* - * Atheros CARL9170 driver - * - * Driver specific definitions - * - * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> - * Copyright 2009, 2010, Christian Lamparter <chunkeey@googlemail.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, see - * http://www.gnu.org/licenses/. - * - * This file incorporates work covered by the following copyright and - * permission notice: - * Copyright (c) 2007-2008 Atheros Communications, Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -#ifndef __CARL9170_H -#define __CARL9170_H - -#include <linux/kernel.h> -#include <linux/firmware.h> -#include <linux/completion.h> -#include <linux/spinlock.h> -#include <linux/hw_random.h> -#include <net/cfg80211.h> -#include <net/mac80211.h> -#include <linux/usb.h> -#ifdef CONFIG_CARL9170_LEDS -#include <linux/leds.h> -#endif /* CONFIG_CARL9170_LEDS */ -#ifdef CONFIG_CARL9170_WPC -#include <linux/input.h> -#endif /* CONFIG_CARL9170_WPC */ -#include "eeprom.h" -#include "wlan.h" -#include "hw.h" -#include "fwdesc.h" -#include "fwcmd.h" -#include "../regd.h" - -#ifdef CONFIG_CARL9170_DEBUGFS -#include "debug.h" -#endif /* CONFIG_CARL9170_DEBUGFS */ - -#define CARL9170FW_NAME "carl9170-1.fw" - -#define PAYLOAD_MAX (CARL9170_MAX_CMD_LEN / 4 - 1) - -static const u8 ar9170_qmap[__AR9170_NUM_TXQ] = { 3, 2, 1, 0 }; - -enum carl9170_rf_init_mode { - CARL9170_RFI_NONE, - CARL9170_RFI_WARM, - CARL9170_RFI_COLD, -}; - -#define CARL9170_MAX_RX_BUFFER_SIZE 8192 - -enum carl9170_device_state { - CARL9170_UNKNOWN_STATE, - CARL9170_STOPPED, - CARL9170_IDLE, - CARL9170_STARTED, -}; - -#define CARL9170_NUM_TID 16 -#define WME_BA_BMP_SIZE 64 -#define CARL9170_TX_USER_RATE_TRIES 3 - -#define WME_AC_BE 2 -#define WME_AC_BK 3 -#define WME_AC_VI 1 -#define WME_AC_VO 0 - -#define TID_TO_WME_AC(_tid) \ - ((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \ - (((_tid) == 1) || ((_tid) == 2)) ? WME_AC_BK : \ - (((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI : \ - WME_AC_VO) - -#define SEQ_DIFF(_start, _seq) \ - (((_start) - (_seq)) & 0x0fff) -#define SEQ_PREV(_seq) \ - (((_seq) - 1) & 0x0fff) -#define SEQ_NEXT(_seq) \ - (((_seq) + 1) & 0x0fff) -#define BAW_WITHIN(_start, _bawsz, _seqno) \ - ((((_seqno) - (_start)) & 0xfff) < (_bawsz)) - -enum carl9170_tid_state { - CARL9170_TID_STATE_INVALID, - CARL9170_TID_STATE_KILLED, - CARL9170_TID_STATE_SHUTDOWN, - CARL9170_TID_STATE_SUSPEND, - CARL9170_TID_STATE_PROGRESS, - CARL9170_TID_STATE_IDLE, - CARL9170_TID_STATE_XMIT, -}; - -#define CARL9170_BAW_BITS (2 * WME_BA_BMP_SIZE) -#define CARL9170_BAW_SIZE (BITS_TO_LONGS(CARL9170_BAW_BITS)) -#define CARL9170_BAW_LEN (DIV_ROUND_UP(CARL9170_BAW_BITS, BITS_PER_BYTE)) - -struct carl9170_sta_tid { - /* must be the first entry! */ - struct list_head list; - - /* temporary list for RCU unlink procedure */ - struct list_head tmp_list; - - /* lock for the following data structures */ - spinlock_t lock; - - unsigned int counter; - enum carl9170_tid_state state; - u8 tid; /* TID number ( 0 - 15 ) */ - u16 max; /* max. AMPDU size */ - - u16 snx; /* awaiting _next_ frame */ - u16 hsn; /* highest _queued_ sequence */ - u16 bsn; /* base of the tx/agg bitmap */ - unsigned long bitmap[CARL9170_BAW_SIZE]; - - /* Preaggregation reorder queue */ - struct sk_buff_head queue; -}; - -#define CARL9170_QUEUE_TIMEOUT 256 -#define CARL9170_BUMP_QUEUE 1000 -#define CARL9170_TX_TIMEOUT 2500 -#define CARL9170_JANITOR_DELAY 128 -#define CARL9170_QUEUE_STUCK_TIMEOUT 5500 -#define CARL9170_STAT_WORK 30000 - -#define CARL9170_NUM_TX_AGG_MAX 30 - -/* - * Tradeoff between stability/latency and speed. - * - * AR9170_TXQ_DEPTH is devised by dividing the amount of available - * tx buffers with the size of a full ethernet frame + overhead. - * - * Naturally: The higher the limit, the faster the device CAN send. - * However, even a slight over-commitment at the wrong time and the - * hardware is doomed to send all already-queued frames at suboptimal - * rates. This in turn leads to an enormous amount of unsuccessful - * retries => Latency goes up, whereas the throughput goes down. CRASH! - */ -#define CARL9170_NUM_TX_LIMIT_HARD ((AR9170_TXQ_DEPTH * 3) / 2) -#define CARL9170_NUM_TX_LIMIT_SOFT (AR9170_TXQ_DEPTH) - -struct carl9170_tx_queue_stats { - unsigned int count; - unsigned int limit; - unsigned int len; -}; - -struct carl9170_vif { - unsigned int id; - struct ieee80211_vif __rcu *vif; -}; - -struct carl9170_vif_info { - struct list_head list; - bool active; - unsigned int id; - struct sk_buff *beacon; - bool enable_beacon; -}; - -#define AR9170_NUM_RX_URBS 16 -#define AR9170_NUM_RX_URBS_MUL 2 -#define AR9170_NUM_TX_URBS 8 -#define AR9170_NUM_RX_URBS_POOL (AR9170_NUM_RX_URBS_MUL * AR9170_NUM_RX_URBS) - -enum carl9170_device_features { - CARL9170_WPS_BUTTON = BIT(0), - CARL9170_ONE_LED = BIT(1), -}; - -#ifdef CONFIG_CARL9170_LEDS -struct ar9170; - -struct carl9170_led { - struct ar9170 *ar; - struct led_classdev l; - char name[32]; - unsigned int toggled; - bool last_state; - bool registered; -}; -#endif /* CONFIG_CARL9170_LEDS */ - -enum carl9170_restart_reasons { - CARL9170_RR_NO_REASON = 0, - CARL9170_RR_FATAL_FIRMWARE_ERROR, - CARL9170_RR_TOO_MANY_FIRMWARE_ERRORS, - CARL9170_RR_WATCHDOG, - CARL9170_RR_STUCK_TX, - CARL9170_RR_UNRESPONSIVE_DEVICE, - CARL9170_RR_COMMAND_TIMEOUT, - CARL9170_RR_TOO_MANY_PHY_ERRORS, - CARL9170_RR_LOST_RSP, - CARL9170_RR_INVALID_RSP, - CARL9170_RR_USER_REQUEST, - - __CARL9170_RR_LAST, -}; - -enum carl9170_erp_modes { - CARL9170_ERP_INVALID, - CARL9170_ERP_AUTO, - CARL9170_ERP_MAC80211, - CARL9170_ERP_OFF, - CARL9170_ERP_CTS, - CARL9170_ERP_RTS, - __CARL9170_ERP_NUM, -}; - -struct ar9170 { - struct ath_common common; - struct ieee80211_hw *hw; - struct mutex mutex; - enum carl9170_device_state state; - spinlock_t state_lock; - enum carl9170_restart_reasons last_reason; - bool registered; - - /* USB */ - struct usb_device *udev; - struct usb_interface *intf; - struct usb_anchor rx_anch; - struct usb_anchor rx_work; - struct usb_anchor rx_pool; - struct usb_anchor tx_wait; - struct usb_anchor tx_anch; - struct usb_anchor tx_cmd; - struct usb_anchor tx_err; - struct tasklet_struct usb_tasklet; - atomic_t tx_cmd_urbs; - atomic_t tx_anch_urbs; - atomic_t rx_anch_urbs; - atomic_t rx_work_urbs; - atomic_t rx_pool_urbs; - kernel_ulong_t features; - - /* firmware settings */ - struct completion fw_load_wait; - struct completion fw_boot_wait; - struct { - const struct carl9170fw_desc_head *desc; - const struct firmware *fw; - unsigned int offset; - unsigned int address; - unsigned int cmd_bufs; - unsigned int api_version; - unsigned int vif_num; - unsigned int err_counter; - unsigned int bug_counter; - u32 beacon_addr; - unsigned int beacon_max_len; - bool rx_stream; - bool tx_stream; - bool rx_filter; - bool hw_counters; - unsigned int mem_blocks; - unsigned int mem_block_size; - unsigned int rx_size; - unsigned int tx_seq_table; - } fw; - - /* interface configuration combinations */ - struct ieee80211_iface_limit if_comb_limits[1]; - struct ieee80211_iface_combination if_combs[1]; - - /* reset / stuck frames/queue detection */ - struct work_struct restart_work; - struct work_struct ping_work; - unsigned int restart_counter; - unsigned long queue_stop_timeout[__AR9170_NUM_TXQ]; - unsigned long max_queue_stop_timeout[__AR9170_NUM_TXQ]; - bool needs_full_reset; - atomic_t pending_restarts; - - /* interface mode settings */ - struct list_head vif_list; - unsigned long vif_bitmap; - unsigned int vifs; - struct carl9170_vif vif_priv[AR9170_MAX_VIRTUAL_MAC]; - - /* beaconing */ - spinlock_t beacon_lock; - unsigned int global_pretbtt; - unsigned int global_beacon_int; - struct carl9170_vif_info __rcu *beacon_iter; - unsigned int beacon_enabled; - - /* cryptographic engine */ - u64 usedkeys; - bool rx_software_decryption; - bool disable_offload; - - /* filter settings */ - u64 cur_mc_hash; - u32 cur_filter; - unsigned int filter_state; - unsigned int rx_filter_caps; - bool sniffer_enabled; - - /* MAC */ - enum carl9170_erp_modes erp_mode; - - /* PHY */ - struct ieee80211_channel *channel; - unsigned int num_channels; - int noise[4]; - unsigned int chan_fail; - unsigned int total_chan_fail; - u8 heavy_clip; - u8 ht_settings; - struct { - u64 active; /* usec */ - u64 cca; /* usec */ - u64 tx_time; /* usec */ - u64 rx_total; - u64 rx_overrun; - } tally; - struct delayed_work stat_work; - struct survey_info *survey; - - /* power calibration data */ - u8 power_5G_leg[4]; - u8 power_2G_cck[4]; - u8 power_2G_ofdm[4]; - u8 power_5G_ht20[8]; - u8 power_5G_ht40[8]; - u8 power_2G_ht20[8]; - u8 power_2G_ht40[8]; - -#ifdef CONFIG_CARL9170_LEDS - /* LED */ - struct delayed_work led_work; - struct carl9170_led leds[AR9170_NUM_LEDS]; -#endif /* CONFIG_CARL9170_LEDS */ - - /* qos queue settings */ - spinlock_t tx_stats_lock; - struct carl9170_tx_queue_stats tx_stats[__AR9170_NUM_TXQ]; - struct ieee80211_tx_queue_params edcf[5]; - struct completion tx_flush; - - /* CMD */ - int cmd_seq; - int readlen; - u8 *readbuf; - spinlock_t cmd_lock; - struct completion cmd_wait; - union { - __le32 cmd_buf[PAYLOAD_MAX + 1]; - struct carl9170_cmd cmd; - struct carl9170_rsp rsp; - }; - - /* statistics */ - unsigned int tx_dropped; - unsigned int tx_ack_failures; - unsigned int tx_fcs_errors; - unsigned int rx_dropped; - - /* EEPROM */ - struct ar9170_eeprom eeprom; - - /* tx queuing */ - struct sk_buff_head tx_pending[__AR9170_NUM_TXQ]; - struct sk_buff_head tx_status[__AR9170_NUM_TXQ]; - struct delayed_work tx_janitor; - unsigned long tx_janitor_last_run; - bool tx_schedule; - - /* tx ampdu */ - struct work_struct ampdu_work; - spinlock_t tx_ampdu_list_lock; - struct carl9170_sta_tid __rcu *tx_ampdu_iter; - struct list_head tx_ampdu_list; - atomic_t tx_ampdu_upload; - atomic_t tx_ampdu_scheduler; - atomic_t tx_total_pending; - atomic_t tx_total_queued; - unsigned int tx_ampdu_list_len; - int current_density; - int current_factor; - bool tx_ampdu_schedule; - - /* internal memory management */ - spinlock_t mem_lock; - unsigned long *mem_bitmap; - atomic_t mem_free_blocks; - atomic_t mem_allocs; - - /* rxstream mpdu merge */ - struct ar9170_rx_head rx_plcp; - bool rx_has_plcp; - struct sk_buff *rx_failover; - int rx_failover_missing; - -#ifdef CONFIG_CARL9170_WPC - struct { - bool pbc_state; - struct input_dev *pbc; - char name[32]; - char phys[32]; - } wps; -#endif /* CONFIG_CARL9170_WPC */ - -#ifdef CONFIG_CARL9170_DEBUGFS - struct carl9170_debug debug; - struct dentry *debug_dir; -#endif /* CONFIG_CARL9170_DEBUGFS */ - - /* PSM */ - struct work_struct ps_work; - struct { - unsigned int dtim_counter; - unsigned long last_beacon; - unsigned long last_action; - unsigned long last_slept; - unsigned int sleep_ms; - unsigned int off_override; - bool state; - } ps; - -#ifdef CONFIG_CARL9170_HWRNG -# define CARL9170_HWRNG_CACHE_SIZE CARL9170_MAX_CMD_PAYLOAD_LEN - struct { - struct hwrng rng; - bool initialized; - char name[30 + 1]; - u16 cache[CARL9170_HWRNG_CACHE_SIZE / sizeof(u16)]; - unsigned int cache_idx; - } rng; -#endif /* CONFIG_CARL9170_HWRNG */ -}; - -enum carl9170_ps_off_override_reasons { - PS_OFF_VIF = BIT(0), - PS_OFF_BCN = BIT(1), -}; - -struct carl9170_ba_stats { - u8 ampdu_len; - u8 ampdu_ack_len; - bool clear; - bool req; -}; - -struct carl9170_sta_info { - bool ht_sta; - bool sleeping; - atomic_t pending_frames; - unsigned int ampdu_max_len; - struct carl9170_sta_tid __rcu *agg[CARL9170_NUM_TID]; - struct carl9170_ba_stats stats[CARL9170_NUM_TID]; -}; - -struct carl9170_tx_info { - unsigned long timeout; - struct ar9170 *ar; - struct kref ref; -}; - -#define CHK_DEV_STATE(a, s) (((struct ar9170 *)a)->state >= (s)) -#define IS_INITIALIZED(a) (CHK_DEV_STATE(a, CARL9170_STOPPED)) -#define IS_ACCEPTING_CMD(a) (CHK_DEV_STATE(a, CARL9170_IDLE)) -#define IS_STARTED(a) (CHK_DEV_STATE(a, CARL9170_STARTED)) - -static inline void __carl9170_set_state(struct ar9170 *ar, - enum carl9170_device_state newstate) -{ - ar->state = newstate; -} - -static inline void carl9170_set_state(struct ar9170 *ar, - enum carl9170_device_state newstate) -{ - unsigned long flags; - - spin_lock_irqsave(&ar->state_lock, flags); - __carl9170_set_state(ar, newstate); - spin_unlock_irqrestore(&ar->state_lock, flags); -} - -static inline void carl9170_set_state_when(struct ar9170 *ar, - enum carl9170_device_state min, enum carl9170_device_state newstate) -{ - unsigned long flags; - - spin_lock_irqsave(&ar->state_lock, flags); - if (CHK_DEV_STATE(ar, min)) - __carl9170_set_state(ar, newstate); - spin_unlock_irqrestore(&ar->state_lock, flags); -} - -/* exported interface */ -void *carl9170_alloc(size_t priv_size); -int carl9170_register(struct ar9170 *ar); -void carl9170_unregister(struct ar9170 *ar); -void carl9170_free(struct ar9170 *ar); -void carl9170_restart(struct ar9170 *ar, const enum carl9170_restart_reasons r); -void carl9170_ps_check(struct ar9170 *ar); - -/* USB back-end */ -int carl9170_usb_open(struct ar9170 *ar); -void carl9170_usb_stop(struct ar9170 *ar); -void carl9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb); -void carl9170_usb_handle_tx_err(struct ar9170 *ar); -int carl9170_exec_cmd(struct ar9170 *ar, const enum carl9170_cmd_oids, - u32 plen, void *payload, u32 rlen, void *resp); -int __carl9170_exec_cmd(struct ar9170 *ar, struct carl9170_cmd *cmd, - const bool free_buf); -int carl9170_usb_restart(struct ar9170 *ar); -void carl9170_usb_reset(struct ar9170 *ar); - -/* MAC */ -int carl9170_init_mac(struct ar9170 *ar); -int carl9170_set_qos(struct ar9170 *ar); -int carl9170_update_multicast(struct ar9170 *ar, const u64 mc_hast); -int carl9170_mod_virtual_mac(struct ar9170 *ar, const unsigned int id, - const u8 *mac); -int carl9170_set_operating_mode(struct ar9170 *ar); -int carl9170_set_beacon_timers(struct ar9170 *ar); -int carl9170_set_dyn_sifs_ack(struct ar9170 *ar); -int carl9170_set_rts_cts_rate(struct ar9170 *ar); -int carl9170_set_ampdu_settings(struct ar9170 *ar); -int carl9170_set_slot_time(struct ar9170 *ar); -int carl9170_set_mac_rates(struct ar9170 *ar); -int carl9170_set_hwretry_limit(struct ar9170 *ar, const u32 max_retry); -int carl9170_upload_key(struct ar9170 *ar, const u8 id, const u8 *mac, - const u8 ktype, const u8 keyidx, const u8 *keydata, const int keylen); -int carl9170_disable_key(struct ar9170 *ar, const u8 id); -int carl9170_set_mac_tpc(struct ar9170 *ar, struct ieee80211_channel *channel); - -/* RX */ -void carl9170_rx(struct ar9170 *ar, void *buf, unsigned int len); -void carl9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len); - -/* TX */ -void carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb); -void carl9170_tx_janitor(struct work_struct *work); -void carl9170_tx_process_status(struct ar9170 *ar, - const struct carl9170_rsp *cmd); -void carl9170_tx_status(struct ar9170 *ar, struct sk_buff *skb, - const bool success); -void carl9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb); -void carl9170_tx_drop(struct ar9170 *ar, struct sk_buff *skb); -void carl9170_tx_scheduler(struct ar9170 *ar); -void carl9170_tx_get_skb(struct sk_buff *skb); -int carl9170_tx_put_skb(struct sk_buff *skb); -int carl9170_update_beacon(struct ar9170 *ar, const bool submit); - -/* LEDs */ -#ifdef CONFIG_CARL9170_LEDS -int carl9170_led_register(struct ar9170 *ar); -void carl9170_led_unregister(struct ar9170 *ar); -#endif /* CONFIG_CARL9170_LEDS */ -int carl9170_led_init(struct ar9170 *ar); -int carl9170_led_set_state(struct ar9170 *ar, const u32 led_state); - -/* PHY / RF */ -int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel, - enum nl80211_channel_type bw, enum carl9170_rf_init_mode rfi); -int carl9170_get_noisefloor(struct ar9170 *ar); - -/* FW */ -int carl9170_parse_firmware(struct ar9170 *ar); - -extern struct ieee80211_rate __carl9170_ratetable[]; -extern int modparam_noht; - -static inline struct ar9170 *carl9170_get_priv(struct carl9170_vif *carl_vif) -{ - return container_of(carl_vif, struct ar9170, - vif_priv[carl_vif->id]); -} - -static inline struct ieee80211_hdr *carl9170_get_hdr(struct sk_buff *skb) -{ - return (void *)((struct _carl9170_tx_superframe *) - skb->data)->frame_data; -} - -static inline u16 get_seq_h(struct ieee80211_hdr *hdr) -{ - return le16_to_cpu(hdr->seq_ctrl) >> 4; -} - -static inline u16 carl9170_get_seq(struct sk_buff *skb) -{ - return get_seq_h(carl9170_get_hdr(skb)); -} - -static inline u16 get_tid_h(struct ieee80211_hdr *hdr) -{ - return (ieee80211_get_qos_ctl(hdr))[0] & IEEE80211_QOS_CTL_TID_MASK; -} - -static inline u16 carl9170_get_tid(struct sk_buff *skb) -{ - return get_tid_h(carl9170_get_hdr(skb)); -} - -static inline struct ieee80211_vif * -carl9170_get_vif(struct carl9170_vif_info *priv) -{ - return container_of((void *)priv, struct ieee80211_vif, drv_priv); -} - -/* Protected by ar->mutex or RCU */ -static inline struct ieee80211_vif *carl9170_get_main_vif(struct ar9170 *ar) -{ - struct carl9170_vif_info *cvif; - - list_for_each_entry_rcu(cvif, &ar->vif_list, list) { - if (cvif->active) - return carl9170_get_vif(cvif); - } - - return NULL; -} - -static inline bool is_main_vif(struct ar9170 *ar, struct ieee80211_vif *vif) -{ - bool ret; - - rcu_read_lock(); - ret = (carl9170_get_main_vif(ar) == vif); - rcu_read_unlock(); - return ret; -} - -#endif /* __CARL9170_H */ diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/cmd.c b/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/cmd.c deleted file mode 100644 index 195dc653..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/cmd.c +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Atheros CARL9170 driver - * - * Basic HW register/memory/command access functions - * - * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, see - * http://www.gnu.org/licenses/. - * - * This file incorporates work covered by the following copyright and - * permission notice: - * Copyright (c) 2007-2008 Atheros Communications, Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <asm/div64.h> -#include "carl9170.h" -#include "cmd.h" - -int carl9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val) -{ - const __le32 buf[2] = { - cpu_to_le32(reg), - cpu_to_le32(val), - }; - int err; - - err = carl9170_exec_cmd(ar, CARL9170_CMD_WREG, sizeof(buf), - (u8 *) buf, 0, NULL); - if (err) { - if (net_ratelimit()) { - wiphy_err(ar->hw->wiphy, "writing reg %#x " - "(val %#x) failed (%d)\n", reg, val, err); - } - } - return err; -} - -int carl9170_read_mreg(struct ar9170 *ar, const int nregs, - const u32 *regs, u32 *out) -{ - int i, err; - __le32 *offs, *res; - - /* abuse "out" for the register offsets, must be same length */ - offs = (__le32 *)out; - for (i = 0; i < nregs; i++) - offs[i] = cpu_to_le32(regs[i]); - - /* also use the same buffer for the input */ - res = (__le32 *)out; - - err = carl9170_exec_cmd(ar, CARL9170_CMD_RREG, - 4 * nregs, (u8 *)offs, - 4 * nregs, (u8 *)res); - if (err) { - if (net_ratelimit()) { - wiphy_err(ar->hw->wiphy, "reading regs failed (%d)\n", - err); - } - return err; - } - - /* convert result to cpu endian */ - for (i = 0; i < nregs; i++) - out[i] = le32_to_cpu(res[i]); - - return 0; -} - -int carl9170_read_reg(struct ar9170 *ar, u32 reg, u32 *val) -{ - return carl9170_read_mreg(ar, 1, ®, val); -} - -int carl9170_echo_test(struct ar9170 *ar, const u32 v) -{ - u32 echores; - int err; - - err = carl9170_exec_cmd(ar, CARL9170_CMD_ECHO, - 4, (u8 *)&v, - 4, (u8 *)&echores); - if (err) - return err; - - if (v != echores) { - wiphy_info(ar->hw->wiphy, "wrong echo %x != %x", v, echores); - return -EINVAL; - } - - return 0; -} - -struct carl9170_cmd *carl9170_cmd_buf(struct ar9170 *ar, - const enum carl9170_cmd_oids cmd, const unsigned int len) -{ - struct carl9170_cmd *tmp; - - tmp = kzalloc(sizeof(struct carl9170_cmd_head) + len, GFP_ATOMIC); - if (tmp) { - tmp->hdr.cmd = cmd; - tmp->hdr.len = len; - } - - return tmp; -} - -int carl9170_reboot(struct ar9170 *ar) -{ - struct carl9170_cmd *cmd; - int err; - - cmd = carl9170_cmd_buf(ar, CARL9170_CMD_REBOOT_ASYNC, 0); - if (!cmd) - return -ENOMEM; - - err = __carl9170_exec_cmd(ar, (struct carl9170_cmd *)cmd, true); - return err; -} - -int carl9170_mac_reset(struct ar9170 *ar) -{ - return carl9170_exec_cmd(ar, CARL9170_CMD_SWRST, - 0, NULL, 0, NULL); -} - -int carl9170_bcn_ctrl(struct ar9170 *ar, const unsigned int vif_id, - const u32 mode, const u32 addr, const u32 len) -{ - struct carl9170_cmd *cmd; - - cmd = carl9170_cmd_buf(ar, CARL9170_CMD_BCN_CTRL_ASYNC, - sizeof(struct carl9170_bcn_ctrl_cmd)); - if (!cmd) - return -ENOMEM; - - cmd->bcn_ctrl.vif_id = cpu_to_le32(vif_id); - cmd->bcn_ctrl.mode = cpu_to_le32(mode); - cmd->bcn_ctrl.bcn_addr = cpu_to_le32(addr); - cmd->bcn_ctrl.bcn_len = cpu_to_le32(len); - - return __carl9170_exec_cmd(ar, cmd, true); -} - -int carl9170_collect_tally(struct ar9170 *ar) -{ - struct carl9170_tally_rsp tally; - struct survey_info *info; - unsigned int tick; - int err; - - err = carl9170_exec_cmd(ar, CARL9170_CMD_TALLY, 0, NULL, - sizeof(tally), (u8 *)&tally); - if (err) - return err; - - tick = le32_to_cpu(tally.tick); - if (tick) { - ar->tally.active += le32_to_cpu(tally.active) / tick; - ar->tally.cca += le32_to_cpu(tally.cca) / tick; - ar->tally.tx_time += le32_to_cpu(tally.tx_time) / tick; - ar->tally.rx_total += le32_to_cpu(tally.rx_total); - ar->tally.rx_overrun += le32_to_cpu(tally.rx_overrun); - - if (ar->channel) { - info = &ar->survey[ar->channel->hw_value]; - info->channel_time = ar->tally.active; - info->channel_time_busy = ar->tally.cca; - info->channel_time_tx = ar->tally.tx_time; - do_div(info->channel_time, 1000); - do_div(info->channel_time_busy, 1000); - do_div(info->channel_time_tx, 1000); - } - } - return 0; -} - -int carl9170_powersave(struct ar9170 *ar, const bool ps) -{ - struct carl9170_cmd *cmd; - u32 state; - - cmd = carl9170_cmd_buf(ar, CARL9170_CMD_PSM_ASYNC, - sizeof(struct carl9170_psm)); - if (!cmd) - return -ENOMEM; - - if (ps) { - /* Sleep until next TBTT */ - state = CARL9170_PSM_SLEEP | 1; - } else { - /* wake up immediately */ - state = 1; - } - - cmd->psm.state = cpu_to_le32(state); - return __carl9170_exec_cmd(ar, cmd, true); -} diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/cmd.h b/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/cmd.h deleted file mode 100644 index 885c4277..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/cmd.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Atheros CARL9170 driver - * - * Basic HW register/memory/command access functions - * - * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> - * Copyright 2010, Christian Lamparter <chunkeey@googlemail.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, see - * http://www.gnu.org/licenses/. - * - * This file incorporates work covered by the following copyright and - * permission notice: - * Copyright (c) 2007-2008 Atheros Communications, Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -#ifndef __CMD_H -#define __CMD_H - -#include "carl9170.h" - -/* basic HW access */ -int carl9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val); -int carl9170_read_reg(struct ar9170 *ar, const u32 reg, u32 *val); -int carl9170_read_mreg(struct ar9170 *ar, const int nregs, - const u32 *regs, u32 *out); -int carl9170_echo_test(struct ar9170 *ar, u32 v); -int carl9170_reboot(struct ar9170 *ar); -int carl9170_mac_reset(struct ar9170 *ar); -int carl9170_powersave(struct ar9170 *ar, const bool power_on); -int carl9170_collect_tally(struct ar9170 *ar); -int carl9170_bcn_ctrl(struct ar9170 *ar, const unsigned int vif_id, - const u32 mode, const u32 addr, const u32 len); - -static inline int carl9170_flush_cab(struct ar9170 *ar, - const unsigned int vif_id) -{ - return carl9170_bcn_ctrl(ar, vif_id, CARL9170_BCN_CTRL_DRAIN, 0, 0); -} - -static inline int carl9170_rx_filter(struct ar9170 *ar, - const unsigned int _rx_filter) -{ - __le32 rx_filter = cpu_to_le32(_rx_filter); - - return carl9170_exec_cmd(ar, CARL9170_CMD_RX_FILTER, - sizeof(rx_filter), (u8 *)&rx_filter, - 0, NULL); -} - -struct carl9170_cmd *carl9170_cmd_buf(struct ar9170 *ar, - const enum carl9170_cmd_oids cmd, const unsigned int len); - -/* - * Macros to facilitate writing multiple registers in a single - * write-combining USB command. Note that when the first group - * fails the whole thing will fail without any others attempted, - * but you won't know which write in the group failed. - */ -#define carl9170_regwrite_begin(ar) \ -do { \ - int __nreg = 0, __err = 0; \ - struct ar9170 *__ar = ar; - -#define carl9170_regwrite(r, v) do { \ - __ar->cmd_buf[2 * __nreg + 1] = cpu_to_le32(r); \ - __ar->cmd_buf[2 * __nreg + 2] = cpu_to_le32(v); \ - __nreg++; \ - if ((__nreg >= PAYLOAD_MAX / 2)) { \ - if (IS_ACCEPTING_CMD(__ar)) \ - __err = carl9170_exec_cmd(__ar, \ - CARL9170_CMD_WREG, 8 * __nreg, \ - (u8 *) &__ar->cmd_buf[1], 0, NULL); \ - else \ - goto __regwrite_out; \ - \ - __nreg = 0; \ - if (__err) \ - goto __regwrite_out; \ - } \ -} while (0) - -#define carl9170_regwrite_finish() \ -__regwrite_out : \ - if (__err == 0 && __nreg) { \ - if (IS_ACCEPTING_CMD(__ar)) \ - __err = carl9170_exec_cmd(__ar, \ - CARL9170_CMD_WREG, 8 * __nreg, \ - (u8 *) &__ar->cmd_buf[1], 0, NULL); \ - __nreg = 0; \ - } - -#define carl9170_regwrite_result() \ - __err; \ -} while (0); - - -#define carl9170_async_regwrite_get_buf() \ -do { \ - __nreg = 0; \ - __cmd = carl9170_cmd_buf(__carl, CARL9170_CMD_WREG_ASYNC, \ - CARL9170_MAX_CMD_PAYLOAD_LEN); \ - if (__cmd == NULL) { \ - __err = -ENOMEM; \ - goto __async_regwrite_out; \ - } \ -} while (0); - -#define carl9170_async_regwrite_begin(carl) \ -do { \ - struct ar9170 *__carl = carl; \ - struct carl9170_cmd *__cmd; \ - unsigned int __nreg; \ - int __err = 0; \ - carl9170_async_regwrite_get_buf(); \ - -#define carl9170_async_regwrite_flush() \ -do { \ - if (__cmd == NULL || __nreg == 0) \ - break; \ - \ - if (IS_ACCEPTING_CMD(__carl) && __nreg) { \ - __cmd->hdr.len = 8 * __nreg; \ - __err = __carl9170_exec_cmd(__carl, __cmd, true); \ - __cmd = NULL; \ - break; \ - } \ - goto __async_regwrite_out; \ -} while (0) - -#define carl9170_async_regwrite(r, v) do { \ - if (__cmd == NULL) \ - carl9170_async_regwrite_get_buf(); \ - __cmd->wreg.regs[__nreg].addr = cpu_to_le32(r); \ - __cmd->wreg.regs[__nreg].val = cpu_to_le32(v); \ - __nreg++; \ - if ((__nreg >= PAYLOAD_MAX / 2)) \ - carl9170_async_regwrite_flush(); \ -} while (0) - -#define carl9170_async_regwrite_finish() do { \ -__async_regwrite_out: \ - if (__cmd != NULL && __err == 0) \ - carl9170_async_regwrite_flush(); \ - kfree(__cmd); \ -} while (0) \ - -#define carl9170_async_regwrite_result() \ - __err; \ -} while (0); - -#endif /* __CMD_H */ diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/debug.c b/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/debug.c deleted file mode 100644 index 93fe6003..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/debug.c +++ /dev/null @@ -1,897 +0,0 @@ -/* - * Atheros CARL9170 driver - * - * debug(fs) probing - * - * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> - * Copyright 2009, 2010, Christian Lamparter <chunkeey@googlemail.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, see - * http://www.gnu.org/licenses/. - * - * This file incorporates work covered by the following copyright and - * permission notice: - * Copyright (c) 2008-2009 Atheros Communications, Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/seq_file.h> -#include <linux/vmalloc.h> -#include "carl9170.h" -#include "cmd.h" - -#define ADD(buf, off, max, fmt, args...) \ - off += snprintf(&buf[off], max - off, fmt, ##args); - - -struct carl9170_debugfs_fops { - unsigned int read_bufsize; - umode_t attr; - char *(*read)(struct ar9170 *ar, char *buf, size_t bufsize, - ssize_t *len); - ssize_t (*write)(struct ar9170 *aru, const char *buf, size_t size); - const struct file_operations fops; - - enum carl9170_device_state req_dev_state; -}; - -static ssize_t carl9170_debugfs_read(struct file *file, char __user *userbuf, - size_t count, loff_t *ppos) -{ - struct carl9170_debugfs_fops *dfops; - struct ar9170 *ar; - char *buf = NULL, *res_buf = NULL; - ssize_t ret = 0; - int err = 0; - - if (!count) - return 0; - - ar = file->private_data; - - if (!ar) - return -ENODEV; - dfops = container_of(file->f_op, struct carl9170_debugfs_fops, fops); - - if (!dfops->read) - return -ENOSYS; - - if (dfops->read_bufsize) { - buf = vmalloc(dfops->read_bufsize); - if (!buf) - return -ENOMEM; - } - - mutex_lock(&ar->mutex); - if (!CHK_DEV_STATE(ar, dfops->req_dev_state)) { - err = -ENODEV; - res_buf = buf; - goto out_free; - } - - res_buf = dfops->read(ar, buf, dfops->read_bufsize, &ret); - - if (ret > 0) - err = simple_read_from_buffer(userbuf, count, ppos, - res_buf, ret); - else - err = ret; - - WARN_ON_ONCE(dfops->read_bufsize && (res_buf != buf)); - -out_free: - vfree(res_buf); - mutex_unlock(&ar->mutex); - return err; -} - -static ssize_t carl9170_debugfs_write(struct file *file, - const char __user *userbuf, size_t count, loff_t *ppos) -{ - struct carl9170_debugfs_fops *dfops; - struct ar9170 *ar; - char *buf = NULL; - int err = 0; - - if (!count) - return 0; - - if (count > PAGE_SIZE) - return -E2BIG; - - ar = file->private_data; - - if (!ar) - return -ENODEV; - dfops = container_of(file->f_op, struct carl9170_debugfs_fops, fops); - - if (!dfops->write) - return -ENOSYS; - - buf = vmalloc(count); - if (!buf) - return -ENOMEM; - - if (copy_from_user(buf, userbuf, count)) { - err = -EFAULT; - goto out_free; - } - - if (mutex_trylock(&ar->mutex) == 0) { - err = -EAGAIN; - goto out_free; - } - - if (!CHK_DEV_STATE(ar, dfops->req_dev_state)) { - err = -ENODEV; - goto out_unlock; - } - - err = dfops->write(ar, buf, count); - if (err) - goto out_unlock; - -out_unlock: - mutex_unlock(&ar->mutex); - -out_free: - vfree(buf); - return err; -} - -#define __DEBUGFS_DECLARE_FILE(name, _read, _write, _read_bufsize, \ - _attr, _dstate) \ -static const struct carl9170_debugfs_fops carl_debugfs_##name ##_ops = {\ - .read_bufsize = _read_bufsize, \ - .read = _read, \ - .write = _write, \ - .attr = _attr, \ - .req_dev_state = _dstate, \ - .fops = { \ - .open = simple_open, \ - .read = carl9170_debugfs_read, \ - .write = carl9170_debugfs_write, \ - .owner = THIS_MODULE \ - }, \ -} - -#define DEBUGFS_DECLARE_FILE(name, _read, _write, _read_bufsize, _attr) \ - __DEBUGFS_DECLARE_FILE(name, _read, _write, _read_bufsize, \ - _attr, CARL9170_STARTED) \ - -#define DEBUGFS_DECLARE_RO_FILE(name, _read_bufsize) \ - DEBUGFS_DECLARE_FILE(name, carl9170_debugfs_##name ##_read, \ - NULL, _read_bufsize, S_IRUSR) - -#define DEBUGFS_DECLARE_WO_FILE(name) \ - DEBUGFS_DECLARE_FILE(name, NULL, carl9170_debugfs_##name ##_write,\ - 0, S_IWUSR) - -#define DEBUGFS_DECLARE_RW_FILE(name, _read_bufsize) \ - DEBUGFS_DECLARE_FILE(name, carl9170_debugfs_##name ##_read, \ - carl9170_debugfs_##name ##_write, \ - _read_bufsize, S_IRUSR | S_IWUSR) - -#define __DEBUGFS_DECLARE_RW_FILE(name, _read_bufsize, _dstate) \ - __DEBUGFS_DECLARE_FILE(name, carl9170_debugfs_##name ##_read, \ - carl9170_debugfs_##name ##_write, \ - _read_bufsize, S_IRUSR | S_IWUSR, _dstate) - -#define DEBUGFS_READONLY_FILE(name, _read_bufsize, fmt, value...) \ -static char *carl9170_debugfs_ ##name ## _read(struct ar9170 *ar, \ - char *buf, size_t buf_size,\ - ssize_t *len) \ -{ \ - ADD(buf, *len, buf_size, fmt "\n", ##value); \ - return buf; \ -} \ -DEBUGFS_DECLARE_RO_FILE(name, _read_bufsize) - -static char *carl9170_debugfs_mem_usage_read(struct ar9170 *ar, char *buf, - size_t bufsize, ssize_t *len) -{ - ADD(buf, *len, bufsize, "jar: ["); - - spin_lock_bh(&ar->mem_lock); - - *len += bitmap_scnprintf(&buf[*len], bufsize - *len, - ar->mem_bitmap, ar->fw.mem_blocks); - - ADD(buf, *len, bufsize, "]\n"); - - ADD(buf, *len, bufsize, "cookies: used:%3d / total:%3d, allocs:%d\n", - bitmap_weight(ar->mem_bitmap, ar->fw.mem_blocks), - ar->fw.mem_blocks, atomic_read(&ar->mem_allocs)); - - ADD(buf, *len, bufsize, "memory: free:%3d (%3d KiB) / total:%3d KiB)\n", - atomic_read(&ar->mem_free_blocks), - (atomic_read(&ar->mem_free_blocks) * ar->fw.mem_block_size) / 1024, - (ar->fw.mem_blocks * ar->fw.mem_block_size) / 1024); - - spin_unlock_bh(&ar->mem_lock); - - return buf; -} -DEBUGFS_DECLARE_RO_FILE(mem_usage, 512); - -static char *carl9170_debugfs_qos_stat_read(struct ar9170 *ar, char *buf, - size_t bufsize, ssize_t *len) -{ - ADD(buf, *len, bufsize, "%s QoS AC\n", modparam_noht ? "Hardware" : - "Software"); - - ADD(buf, *len, bufsize, "[ VO VI " - " BE BK ]\n"); - - spin_lock_bh(&ar->tx_stats_lock); - ADD(buf, *len, bufsize, "[length/limit length/limit " - "length/limit length/limit ]\n" - "[ %3d/%3d %3d/%3d " - " %3d/%3d %3d/%3d ]\n\n", - ar->tx_stats[0].len, ar->tx_stats[0].limit, - ar->tx_stats[1].len, ar->tx_stats[1].limit, - ar->tx_stats[2].len, ar->tx_stats[2].limit, - ar->tx_stats[3].len, ar->tx_stats[3].limit); - - ADD(buf, *len, bufsize, "[ total total " - " total total ]\n" - "[%10d %10d %10d %10d ]\n\n", - ar->tx_stats[0].count, ar->tx_stats[1].count, - ar->tx_stats[2].count, ar->tx_stats[3].count); - - spin_unlock_bh(&ar->tx_stats_lock); - - ADD(buf, *len, bufsize, "[ pend/waittx pend/waittx " - " pend/waittx pend/waittx]\n" - "[ %3d/%3d %3d/%3d " - " %3d/%3d %3d/%3d ]\n\n", - skb_queue_len(&ar->tx_pending[0]), - skb_queue_len(&ar->tx_status[0]), - skb_queue_len(&ar->tx_pending[1]), - skb_queue_len(&ar->tx_status[1]), - skb_queue_len(&ar->tx_pending[2]), - skb_queue_len(&ar->tx_status[2]), - skb_queue_len(&ar->tx_pending[3]), - skb_queue_len(&ar->tx_status[3])); - - return buf; -} -DEBUGFS_DECLARE_RO_FILE(qos_stat, 512); - -static void carl9170_debugfs_format_frame(struct ar9170 *ar, - struct sk_buff *skb, const char *prefix, char *buf, - ssize_t *off, ssize_t bufsize) -{ - struct _carl9170_tx_superframe *txc = (void *) skb->data; - struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb); - struct carl9170_tx_info *arinfo = (void *) txinfo->rate_driver_data; - struct ieee80211_hdr *hdr = (void *) txc->frame_data; - - ADD(buf, *off, bufsize, "%s %p, c:%2x, DA:%pM, sq:%4d, mc:%.4x, " - "pc:%.8x, to:%d ms\n", prefix, skb, txc->s.cookie, - ieee80211_get_DA(hdr), get_seq_h(hdr), - le16_to_cpu(txc->f.mac_control), le32_to_cpu(txc->f.phy_control), - jiffies_to_msecs(jiffies - arinfo->timeout)); -} - - -static char *carl9170_debugfs_ampdu_state_read(struct ar9170 *ar, char *buf, - size_t bufsize, ssize_t *len) -{ - struct carl9170_sta_tid *iter; - struct sk_buff *skb; - int cnt = 0, fc; - int offset; - - rcu_read_lock(); - list_for_each_entry_rcu(iter, &ar->tx_ampdu_list, list) { - - spin_lock_bh(&iter->lock); - ADD(buf, *len, bufsize, "Entry: #%2d TID:%1d, BSN:%4d, " - "SNX:%4d, HSN:%4d, BAW:%2d, state:%1d, toggles:%d\n", - cnt, iter->tid, iter->bsn, iter->snx, iter->hsn, - iter->max, iter->state, iter->counter); - - ADD(buf, *len, bufsize, "\tWindow: ["); - - *len += bitmap_scnprintf(&buf[*len], bufsize - *len, - iter->bitmap, CARL9170_BAW_BITS); - -#define BM_STR_OFF(offset) \ - ((CARL9170_BAW_BITS - (offset) - 1) / 4 + \ - (CARL9170_BAW_BITS - (offset) - 1) / 32 + 1) - - ADD(buf, *len, bufsize, ",W]\n"); - - offset = BM_STR_OFF(0); - ADD(buf, *len, bufsize, "\tBase Seq: %*s\n", offset, "T"); - - offset = BM_STR_OFF(SEQ_DIFF(iter->snx, iter->bsn)); - ADD(buf, *len, bufsize, "\tNext Seq: %*s\n", offset, "W"); - - offset = BM_STR_OFF(((int)iter->hsn - (int)iter->bsn) % - CARL9170_BAW_BITS); - ADD(buf, *len, bufsize, "\tLast Seq: %*s\n", offset, "N"); - - ADD(buf, *len, bufsize, "\tPre-Aggregation reorder buffer: " - " currently queued:%d\n", skb_queue_len(&iter->queue)); - - fc = 0; - skb_queue_walk(&iter->queue, skb) { - char prefix[32]; - - snprintf(prefix, sizeof(prefix), "\t\t%3d :", fc); - carl9170_debugfs_format_frame(ar, skb, prefix, buf, - len, bufsize); - - fc++; - } - spin_unlock_bh(&iter->lock); - cnt++; - } - rcu_read_unlock(); - - return buf; -} -DEBUGFS_DECLARE_RO_FILE(ampdu_state, 8000); - -static void carl9170_debugfs_queue_dump(struct ar9170 *ar, char *buf, - ssize_t *len, size_t bufsize, struct sk_buff_head *queue) -{ - struct sk_buff *skb; - char prefix[16]; - int fc = 0; - - spin_lock_bh(&queue->lock); - skb_queue_walk(queue, skb) { - snprintf(prefix, sizeof(prefix), "%3d :", fc); - carl9170_debugfs_format_frame(ar, skb, prefix, buf, - len, bufsize); - fc++; - } - spin_unlock_bh(&queue->lock); -} - -#define DEBUGFS_QUEUE_DUMP(q, qi) \ -static char *carl9170_debugfs_##q ##_##qi ##_read(struct ar9170 *ar, \ - char *buf, size_t bufsize, ssize_t *len) \ -{ \ - carl9170_debugfs_queue_dump(ar, buf, len, bufsize, &ar->q[qi]); \ - return buf; \ -} \ -DEBUGFS_DECLARE_RO_FILE(q##_##qi, 8000); - -static char *carl9170_debugfs_sta_psm_read(struct ar9170 *ar, char *buf, - size_t bufsize, ssize_t *len) -{ - ADD(buf, *len, bufsize, "psm state: %s\n", (ar->ps.off_override ? - "FORCE CAM" : (ar->ps.state ? "PSM" : "CAM"))); - - ADD(buf, *len, bufsize, "sleep duration: %d ms.\n", ar->ps.sleep_ms); - ADD(buf, *len, bufsize, "last power-state transition: %d ms ago.\n", - jiffies_to_msecs(jiffies - ar->ps.last_action)); - ADD(buf, *len, bufsize, "last CAM->PSM transition: %d ms ago.\n", - jiffies_to_msecs(jiffies - ar->ps.last_slept)); - - return buf; -} -DEBUGFS_DECLARE_RO_FILE(sta_psm, 160); - -static char *carl9170_debugfs_tx_stuck_read(struct ar9170 *ar, char *buf, - size_t bufsize, ssize_t *len) -{ - int i; - - for (i = 0; i < ar->hw->queues; i++) { - ADD(buf, *len, bufsize, "TX queue [%d]: %10d max:%10d ms.\n", - i, ieee80211_queue_stopped(ar->hw, i) ? - jiffies_to_msecs(jiffies - ar->queue_stop_timeout[i]) : 0, - jiffies_to_msecs(ar->max_queue_stop_timeout[i])); - - ar->max_queue_stop_timeout[i] = 0; - } - - return buf; -} -DEBUGFS_DECLARE_RO_FILE(tx_stuck, 180); - -static char *carl9170_debugfs_phy_noise_read(struct ar9170 *ar, char *buf, - size_t bufsize, ssize_t *len) -{ - int err; - - err = carl9170_get_noisefloor(ar); - if (err) { - *len = err; - return buf; - } - - ADD(buf, *len, bufsize, "Chain 0: %10d dBm, ext. chan.:%10d dBm\n", - ar->noise[0], ar->noise[2]); - ADD(buf, *len, bufsize, "Chain 2: %10d dBm, ext. chan.:%10d dBm\n", - ar->noise[1], ar->noise[3]); - - return buf; -} -DEBUGFS_DECLARE_RO_FILE(phy_noise, 180); - -static char *carl9170_debugfs_vif_dump_read(struct ar9170 *ar, char *buf, - size_t bufsize, ssize_t *len) -{ - struct carl9170_vif_info *iter; - int i = 0; - - ADD(buf, *len, bufsize, "registered VIFs:%d \\ %d\n", - ar->vifs, ar->fw.vif_num); - - ADD(buf, *len, bufsize, "VIF bitmap: ["); - - *len += bitmap_scnprintf(&buf[*len], bufsize - *len, - &ar->vif_bitmap, ar->fw.vif_num); - - ADD(buf, *len, bufsize, "]\n"); - - rcu_read_lock(); - list_for_each_entry_rcu(iter, &ar->vif_list, list) { - struct ieee80211_vif *vif = carl9170_get_vif(iter); - ADD(buf, *len, bufsize, "\t%d = [%s VIF, id:%d, type:%x " - " mac:%pM %s]\n", i, (carl9170_get_main_vif(ar) == vif ? - "Master" : " Slave"), iter->id, vif->type, vif->addr, - iter->enable_beacon ? "beaconing " : ""); - i++; - } - rcu_read_unlock(); - - return buf; -} -DEBUGFS_DECLARE_RO_FILE(vif_dump, 8000); - -#define UPDATE_COUNTER(ar, name) ({ \ - u32 __tmp[ARRAY_SIZE(name##_regs)]; \ - unsigned int __i, __err = -ENODEV; \ - \ - for (__i = 0; __i < ARRAY_SIZE(name##_regs); __i++) { \ - __tmp[__i] = name##_regs[__i].reg; \ - ar->debug.stats.name##_counter[__i] = 0; \ - } \ - \ - if (IS_STARTED(ar)) \ - __err = carl9170_read_mreg(ar, ARRAY_SIZE(name##_regs), \ - __tmp, ar->debug.stats.name##_counter); \ - (__err); }) - -#define TALLY_SUM_UP(ar, name) do { \ - unsigned int __i; \ - \ - for (__i = 0; __i < ARRAY_SIZE(name##_regs); __i++) { \ - ar->debug.stats.name##_sum[__i] += \ - ar->debug.stats.name##_counter[__i]; \ - } \ -} while (0) - -#define DEBUGFS_HW_TALLY_FILE(name, f) \ -static char *carl9170_debugfs_##name ## _read(struct ar9170 *ar, \ - char *dum, size_t bufsize, ssize_t *ret) \ -{ \ - char *buf; \ - int i, max_len, err; \ - \ - max_len = ARRAY_SIZE(name##_regs) * 80; \ - buf = vmalloc(max_len); \ - if (!buf) \ - return NULL; \ - \ - err = UPDATE_COUNTER(ar, name); \ - if (err) { \ - *ret = err; \ - return buf; \ - } \ - \ - TALLY_SUM_UP(ar, name); \ - \ - for (i = 0; i < ARRAY_SIZE(name##_regs); i++) { \ - ADD(buf, *ret, max_len, "%22s = %" f "[+%" f "]\n", \ - name##_regs[i].nreg, ar->debug.stats.name ##_sum[i],\ - ar->debug.stats.name ##_counter[i]); \ - } \ - \ - return buf; \ -} \ -DEBUGFS_DECLARE_RO_FILE(name, 0); - -#define DEBUGFS_HW_REG_FILE(name, f) \ -static char *carl9170_debugfs_##name ## _read(struct ar9170 *ar, \ - char *dum, size_t bufsize, ssize_t *ret) \ -{ \ - char *buf; \ - int i, max_len, err; \ - \ - max_len = ARRAY_SIZE(name##_regs) * 80; \ - buf = vmalloc(max_len); \ - if (!buf) \ - return NULL; \ - \ - err = UPDATE_COUNTER(ar, name); \ - if (err) { \ - *ret = err; \ - return buf; \ - } \ - \ - for (i = 0; i < ARRAY_SIZE(name##_regs); i++) { \ - ADD(buf, *ret, max_len, "%22s = %" f "\n", \ - name##_regs[i].nreg, \ - ar->debug.stats.name##_counter[i]); \ - } \ - \ - return buf; \ -} \ -DEBUGFS_DECLARE_RO_FILE(name, 0); - -static ssize_t carl9170_debugfs_hw_ioread32_write(struct ar9170 *ar, - const char *buf, size_t count) -{ - int err = 0, i, n = 0, max_len = 32, res; - unsigned int reg, tmp; - - if (!count) - return 0; - - if (count > max_len) - return -E2BIG; - - res = sscanf(buf, "0x%X %d", ®, &n); - if (res < 1) { - err = -EINVAL; - goto out; - } - - if (res == 1) - n = 1; - - if (n > 15) { - err = -EMSGSIZE; - goto out; - } - - if ((reg >= 0x280000) || ((reg + (n << 2)) >= 0x280000)) { - err = -EADDRNOTAVAIL; - goto out; - } - - if (reg & 3) { - err = -EINVAL; - goto out; - } - - for (i = 0; i < n; i++) { - err = carl9170_read_reg(ar, reg + (i << 2), &tmp); - if (err) - goto out; - - ar->debug.ring[ar->debug.ring_tail].reg = reg + (i << 2); - ar->debug.ring[ar->debug.ring_tail].value = tmp; - ar->debug.ring_tail++; - ar->debug.ring_tail %= CARL9170_DEBUG_RING_SIZE; - } - -out: - return err ? err : count; -} - -static char *carl9170_debugfs_hw_ioread32_read(struct ar9170 *ar, char *buf, - size_t bufsize, ssize_t *ret) -{ - int i = 0; - - while (ar->debug.ring_head != ar->debug.ring_tail) { - ADD(buf, *ret, bufsize, "%.8x = %.8x\n", - ar->debug.ring[ar->debug.ring_head].reg, - ar->debug.ring[ar->debug.ring_head].value); - - ar->debug.ring_head++; - ar->debug.ring_head %= CARL9170_DEBUG_RING_SIZE; - - if (i++ == 64) - break; - } - ar->debug.ring_head = ar->debug.ring_tail; - return buf; -} -DEBUGFS_DECLARE_RW_FILE(hw_ioread32, CARL9170_DEBUG_RING_SIZE * 40); - -static ssize_t carl9170_debugfs_bug_write(struct ar9170 *ar, const char *buf, - size_t count) -{ - int err; - - if (count < 1) - return -EINVAL; - - switch (buf[0]) { - case 'F': - ar->needs_full_reset = true; - break; - - case 'R': - if (!IS_STARTED(ar)) { - err = -EAGAIN; - goto out; - } - - ar->needs_full_reset = false; - break; - - case 'M': - err = carl9170_mac_reset(ar); - if (err < 0) - count = err; - - goto out; - - case 'P': - err = carl9170_set_channel(ar, ar->hw->conf.channel, - ar->hw->conf.channel_type, CARL9170_RFI_COLD); - if (err < 0) - count = err; - - goto out; - - default: - return -EINVAL; - } - - carl9170_restart(ar, CARL9170_RR_USER_REQUEST); - -out: - return count; -} - -static char *carl9170_debugfs_bug_read(struct ar9170 *ar, char *buf, - size_t bufsize, ssize_t *ret) -{ - ADD(buf, *ret, bufsize, "[P]hy reinit, [R]estart, [F]ull usb reset, " - "[M]ac reset\n"); - ADD(buf, *ret, bufsize, "firmware restarts:%d, last reason:%d\n", - ar->restart_counter, ar->last_reason); - ADD(buf, *ret, bufsize, "phy reinit errors:%d (%d)\n", - ar->total_chan_fail, ar->chan_fail); - ADD(buf, *ret, bufsize, "reported firmware errors:%d\n", - ar->fw.err_counter); - ADD(buf, *ret, bufsize, "reported firmware BUGs:%d\n", - ar->fw.bug_counter); - ADD(buf, *ret, bufsize, "pending restart requests:%d\n", - atomic_read(&ar->pending_restarts)); - return buf; -} -__DEBUGFS_DECLARE_RW_FILE(bug, 400, CARL9170_STOPPED); - -static const char *const erp_modes[] = { - [CARL9170_ERP_INVALID] = "INVALID", - [CARL9170_ERP_AUTO] = "Automatic", - [CARL9170_ERP_MAC80211] = "Set by MAC80211", - [CARL9170_ERP_OFF] = "Force Off", - [CARL9170_ERP_RTS] = "Force RTS", - [CARL9170_ERP_CTS] = "Force CTS" -}; - -static char *carl9170_debugfs_erp_read(struct ar9170 *ar, char *buf, - size_t bufsize, ssize_t *ret) -{ - ADD(buf, *ret, bufsize, "ERP Setting: (%d) -> %s\n", ar->erp_mode, - erp_modes[ar->erp_mode]); - return buf; -} - -static ssize_t carl9170_debugfs_erp_write(struct ar9170 *ar, const char *buf, - size_t count) -{ - int res, val; - - if (count < 1) - return -EINVAL; - - res = sscanf(buf, "%d", &val); - if (res != 1) - return -EINVAL; - - if (!((val > CARL9170_ERP_INVALID) && - (val < __CARL9170_ERP_NUM))) - return -EINVAL; - - ar->erp_mode = val; - return count; -} - -DEBUGFS_DECLARE_RW_FILE(erp, 80); - -static ssize_t carl9170_debugfs_hw_iowrite32_write(struct ar9170 *ar, - const char *buf, size_t count) -{ - int err = 0, max_len = 22, res; - u32 reg, val; - - if (!count) - return 0; - - if (count > max_len) - return -E2BIG; - - res = sscanf(buf, "0x%X 0x%X", ®, &val); - if (res != 2) { - err = -EINVAL; - goto out; - } - - if (reg <= 0x100000 || reg >= 0x280000) { - err = -EADDRNOTAVAIL; - goto out; - } - - if (reg & 3) { - err = -EINVAL; - goto out; - } - - err = carl9170_write_reg(ar, reg, val); - if (err) - goto out; - -out: - return err ? err : count; -} -DEBUGFS_DECLARE_WO_FILE(hw_iowrite32); - -DEBUGFS_HW_TALLY_FILE(hw_tx_tally, "u"); -DEBUGFS_HW_TALLY_FILE(hw_rx_tally, "u"); -DEBUGFS_HW_TALLY_FILE(hw_phy_errors, "u"); -DEBUGFS_HW_REG_FILE(hw_wlan_queue, ".8x"); -DEBUGFS_HW_REG_FILE(hw_pta_queue, ".8x"); -DEBUGFS_HW_REG_FILE(hw_ampdu_info, ".8x"); -DEBUGFS_QUEUE_DUMP(tx_status, 0); -DEBUGFS_QUEUE_DUMP(tx_status, 1); -DEBUGFS_QUEUE_DUMP(tx_status, 2); -DEBUGFS_QUEUE_DUMP(tx_status, 3); -DEBUGFS_QUEUE_DUMP(tx_pending, 0); -DEBUGFS_QUEUE_DUMP(tx_pending, 1); -DEBUGFS_QUEUE_DUMP(tx_pending, 2); -DEBUGFS_QUEUE_DUMP(tx_pending, 3); -DEBUGFS_READONLY_FILE(usb_tx_anch_urbs, 20, "%d", - atomic_read(&ar->tx_anch_urbs)); -DEBUGFS_READONLY_FILE(usb_rx_anch_urbs, 20, "%d", - atomic_read(&ar->rx_anch_urbs)); -DEBUGFS_READONLY_FILE(usb_rx_work_urbs, 20, "%d", - atomic_read(&ar->rx_work_urbs)); -DEBUGFS_READONLY_FILE(usb_rx_pool_urbs, 20, "%d", - atomic_read(&ar->rx_pool_urbs)); - -DEBUGFS_READONLY_FILE(tx_total_queued, 20, "%d", - atomic_read(&ar->tx_total_queued)); -DEBUGFS_READONLY_FILE(tx_ampdu_scheduler, 20, "%d", - atomic_read(&ar->tx_ampdu_scheduler)); - -DEBUGFS_READONLY_FILE(tx_total_pending, 20, "%d", - atomic_read(&ar->tx_total_pending)); - -DEBUGFS_READONLY_FILE(tx_ampdu_list_len, 20, "%d", - ar->tx_ampdu_list_len); - -DEBUGFS_READONLY_FILE(tx_ampdu_upload, 20, "%d", - atomic_read(&ar->tx_ampdu_upload)); - -DEBUGFS_READONLY_FILE(tx_janitor_last_run, 64, "last run:%d ms ago", - jiffies_to_msecs(jiffies - ar->tx_janitor_last_run)); - -DEBUGFS_READONLY_FILE(tx_dropped, 20, "%d", ar->tx_dropped); - -DEBUGFS_READONLY_FILE(rx_dropped, 20, "%d", ar->rx_dropped); - -DEBUGFS_READONLY_FILE(sniffer_enabled, 20, "%d", ar->sniffer_enabled); -DEBUGFS_READONLY_FILE(rx_software_decryption, 20, "%d", - ar->rx_software_decryption); -DEBUGFS_READONLY_FILE(ampdu_factor, 20, "%d", - ar->current_factor); -DEBUGFS_READONLY_FILE(ampdu_density, 20, "%d", - ar->current_density); - -DEBUGFS_READONLY_FILE(beacon_int, 20, "%d TU", ar->global_beacon_int); -DEBUGFS_READONLY_FILE(pretbtt, 20, "%d TU", ar->global_pretbtt); - -void carl9170_debugfs_register(struct ar9170 *ar) -{ - ar->debug_dir = debugfs_create_dir(KBUILD_MODNAME, - ar->hw->wiphy->debugfsdir); - -#define DEBUGFS_ADD(name) \ - debugfs_create_file(#name, carl_debugfs_##name ##_ops.attr, \ - ar->debug_dir, ar, \ - &carl_debugfs_##name ## _ops.fops); - - DEBUGFS_ADD(usb_tx_anch_urbs); - DEBUGFS_ADD(usb_rx_pool_urbs); - DEBUGFS_ADD(usb_rx_anch_urbs); - DEBUGFS_ADD(usb_rx_work_urbs); - - DEBUGFS_ADD(tx_total_queued); - DEBUGFS_ADD(tx_total_pending); - DEBUGFS_ADD(tx_dropped); - DEBUGFS_ADD(tx_stuck); - DEBUGFS_ADD(tx_ampdu_upload); - DEBUGFS_ADD(tx_ampdu_scheduler); - DEBUGFS_ADD(tx_ampdu_list_len); - - DEBUGFS_ADD(rx_dropped); - DEBUGFS_ADD(sniffer_enabled); - DEBUGFS_ADD(rx_software_decryption); - - DEBUGFS_ADD(mem_usage); - DEBUGFS_ADD(qos_stat); - DEBUGFS_ADD(sta_psm); - DEBUGFS_ADD(ampdu_state); - - DEBUGFS_ADD(hw_tx_tally); - DEBUGFS_ADD(hw_rx_tally); - DEBUGFS_ADD(hw_phy_errors); - DEBUGFS_ADD(phy_noise); - - DEBUGFS_ADD(hw_wlan_queue); - DEBUGFS_ADD(hw_pta_queue); - DEBUGFS_ADD(hw_ampdu_info); - - DEBUGFS_ADD(ampdu_density); - DEBUGFS_ADD(ampdu_factor); - - DEBUGFS_ADD(tx_janitor_last_run); - - DEBUGFS_ADD(tx_status_0); - DEBUGFS_ADD(tx_status_1); - DEBUGFS_ADD(tx_status_2); - DEBUGFS_ADD(tx_status_3); - - DEBUGFS_ADD(tx_pending_0); - DEBUGFS_ADD(tx_pending_1); - DEBUGFS_ADD(tx_pending_2); - DEBUGFS_ADD(tx_pending_3); - - DEBUGFS_ADD(hw_ioread32); - DEBUGFS_ADD(hw_iowrite32); - DEBUGFS_ADD(bug); - - DEBUGFS_ADD(erp); - - DEBUGFS_ADD(vif_dump); - - DEBUGFS_ADD(beacon_int); - DEBUGFS_ADD(pretbtt); - -#undef DEBUGFS_ADD -} - -void carl9170_debugfs_unregister(struct ar9170 *ar) -{ - debugfs_remove_recursive(ar->debug_dir); -} diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/debug.h b/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/debug.h deleted file mode 100644 index ea4b9752..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/debug.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Atheros CARL9170 driver - * - * debug header - * - * Copyright 2010, Christian Lamparter <chunkeey@googlemail.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, see - * http://www.gnu.org/licenses/. - * - * This file incorporates work covered by the following copyright and - * permission notice: - * Copyright (c) 2007-2008 Atheros Communications, Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -#ifndef __DEBUG_H -#define __DEBUG_H - -#include "eeprom.h" -#include "wlan.h" -#include "hw.h" -#include "fwdesc.h" -#include "fwcmd.h" -#include "../regd.h" - -struct hw_stat_reg_entry { - u32 reg; - char nreg[32]; -}; - -#define STAT_MAC_REG(reg) \ - { (AR9170_MAC_REG_##reg), #reg } - -#define STAT_PTA_REG(reg) \ - { (AR9170_PTA_REG_##reg), #reg } - -#define STAT_USB_REG(reg) \ - { (AR9170_USB_REG_##reg), #reg } - -static const struct hw_stat_reg_entry hw_rx_tally_regs[] = { - STAT_MAC_REG(RX_CRC32), STAT_MAC_REG(RX_CRC16), - STAT_MAC_REG(RX_TIMEOUT_COUNT), STAT_MAC_REG(RX_ERR_DECRYPTION_UNI), - STAT_MAC_REG(RX_ERR_DECRYPTION_MUL), STAT_MAC_REG(RX_MPDU), - STAT_MAC_REG(RX_DROPPED_MPDU), STAT_MAC_REG(RX_DEL_MPDU), -}; - -static const struct hw_stat_reg_entry hw_phy_errors_regs[] = { - STAT_MAC_REG(RX_PHY_MISC_ERROR), STAT_MAC_REG(RX_PHY_XR_ERROR), - STAT_MAC_REG(RX_PHY_OFDM_ERROR), STAT_MAC_REG(RX_PHY_CCK_ERROR), - STAT_MAC_REG(RX_PHY_HT_ERROR), STAT_MAC_REG(RX_PHY_TOTAL), -}; - -static const struct hw_stat_reg_entry hw_tx_tally_regs[] = { - STAT_MAC_REG(TX_TOTAL), STAT_MAC_REG(TX_UNDERRUN), - STAT_MAC_REG(TX_RETRY), -}; - -static const struct hw_stat_reg_entry hw_wlan_queue_regs[] = { - STAT_MAC_REG(DMA_STATUS), STAT_MAC_REG(DMA_TRIGGER), - STAT_MAC_REG(DMA_TXQ0_ADDR), STAT_MAC_REG(DMA_TXQ0_CURR_ADDR), - STAT_MAC_REG(DMA_TXQ1_ADDR), STAT_MAC_REG(DMA_TXQ1_CURR_ADDR), - STAT_MAC_REG(DMA_TXQ2_ADDR), STAT_MAC_REG(DMA_TXQ2_CURR_ADDR), - STAT_MAC_REG(DMA_TXQ3_ADDR), STAT_MAC_REG(DMA_TXQ3_CURR_ADDR), - STAT_MAC_REG(DMA_RXQ_ADDR), STAT_MAC_REG(DMA_RXQ_CURR_ADDR), -}; - -static const struct hw_stat_reg_entry hw_ampdu_info_regs[] = { - STAT_MAC_REG(AMPDU_DENSITY), STAT_MAC_REG(AMPDU_FACTOR), -}; - -static const struct hw_stat_reg_entry hw_pta_queue_regs[] = { - STAT_PTA_REG(DN_CURR_ADDRH), STAT_PTA_REG(DN_CURR_ADDRL), - STAT_PTA_REG(UP_CURR_ADDRH), STAT_PTA_REG(UP_CURR_ADDRL), - STAT_PTA_REG(DMA_STATUS), STAT_PTA_REG(DMA_MODE_CTRL), -}; - -#define DEFINE_TALLY(name) \ - u32 name##_sum[ARRAY_SIZE(name##_regs)], \ - name##_counter[ARRAY_SIZE(name##_regs)] \ - -#define DEFINE_STAT(name) \ - u32 name##_counter[ARRAY_SIZE(name##_regs)] \ - -struct ath_stats { - DEFINE_TALLY(hw_tx_tally); - DEFINE_TALLY(hw_rx_tally); - DEFINE_TALLY(hw_phy_errors); - DEFINE_STAT(hw_wlan_queue); - DEFINE_STAT(hw_pta_queue); - DEFINE_STAT(hw_ampdu_info); -}; - -struct carl9170_debug_mem_rbe { - u32 reg; - u32 value; -}; - -#define CARL9170_DEBUG_RING_SIZE 64 - -struct carl9170_debug { - struct ath_stats stats; - struct carl9170_debug_mem_rbe ring[CARL9170_DEBUG_RING_SIZE]; - struct mutex ring_lock; - unsigned int ring_head, ring_tail; - struct delayed_work update_tally; -}; - -struct ar9170; - -void carl9170_debugfs_register(struct ar9170 *ar); -void carl9170_debugfs_unregister(struct ar9170 *ar); -#endif /* __DEBUG_H */ diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/eeprom.h b/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/eeprom.h deleted file mode 100644 index 7cff40ac..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/eeprom.h +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Shared Atheros AR9170 Header - * - * EEPROM layout - * - * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, see - * http://www.gnu.org/licenses/. - * - * This file incorporates work covered by the following copyright and - * permission notice: - * Copyright (c) 2007-2008 Atheros Communications, Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -#ifndef __CARL9170_SHARED_EEPROM_H -#define __CARL9170_SHARED_EEPROM_H - -#define AR9170_EEPROM_START 0x1600 - -#define AR5416_MAX_CHAINS 2 -#define AR5416_MODAL_SPURS 5 - -struct ar9170_eeprom_modal { - __le32 antCtrlChain[AR5416_MAX_CHAINS]; - __le32 antCtrlCommon; - s8 antennaGainCh[AR5416_MAX_CHAINS]; - u8 switchSettling; - u8 txRxAttenCh[AR5416_MAX_CHAINS]; - u8 rxTxMarginCh[AR5416_MAX_CHAINS]; - s8 adcDesiredSize; - s8 pgaDesiredSize; - u8 xlnaGainCh[AR5416_MAX_CHAINS]; - u8 txEndToXpaOff; - u8 txEndToRxOn; - u8 txFrameToXpaOn; - u8 thresh62; - s8 noiseFloorThreshCh[AR5416_MAX_CHAINS]; - u8 xpdGain; - u8 xpd; - s8 iqCalICh[AR5416_MAX_CHAINS]; - s8 iqCalQCh[AR5416_MAX_CHAINS]; - u8 pdGainOverlap; - u8 ob; - u8 db; - u8 xpaBiasLvl; - u8 pwrDecreaseFor2Chain; - u8 pwrDecreaseFor3Chain; - u8 txFrameToDataStart; - u8 txFrameToPaOn; - u8 ht40PowerIncForPdadc; - u8 bswAtten[AR5416_MAX_CHAINS]; - u8 bswMargin[AR5416_MAX_CHAINS]; - u8 swSettleHt40; - u8 reserved[22]; - struct spur_channel { - __le16 spurChan; - u8 spurRangeLow; - u8 spurRangeHigh; - } __packed spur_channels[AR5416_MODAL_SPURS]; -} __packed; - -#define AR5416_NUM_PD_GAINS 4 -#define AR5416_PD_GAIN_ICEPTS 5 - -struct ar9170_calibration_data_per_freq { - u8 pwr_pdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS]; - u8 vpd_pdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS]; -} __packed; - -#define AR5416_NUM_5G_CAL_PIERS 8 -#define AR5416_NUM_2G_CAL_PIERS 4 - -#define AR5416_NUM_5G_TARGET_PWRS 8 -#define AR5416_NUM_2G_CCK_TARGET_PWRS 3 -#define AR5416_NUM_2G_OFDM_TARGET_PWRS 4 -#define AR5416_MAX_NUM_TGT_PWRS 8 - -struct ar9170_calibration_target_power_legacy { - u8 freq; - u8 power[4]; -} __packed; - -struct ar9170_calibration_target_power_ht { - u8 freq; - u8 power[8]; -} __packed; - -#define AR5416_NUM_CTLS 24 - -struct ar9170_calctl_edges { - u8 channel; -#define AR9170_CALCTL_EDGE_FLAGS 0xC0 - u8 power_flags; -} __packed; - -#define AR5416_NUM_BAND_EDGES 8 - -struct ar9170_calctl_data { - struct ar9170_calctl_edges - control_edges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES]; -} __packed; - -struct ar9170_eeprom { - __le16 length; - __le16 checksum; - __le16 version; - u8 operating_flags; -#define AR9170_OPFLAG_5GHZ 1 -#define AR9170_OPFLAG_2GHZ 2 - u8 misc; - __le16 reg_domain[2]; - u8 mac_address[6]; - u8 rx_mask; - u8 tx_mask; - __le16 rf_silent; - __le16 bluetooth_options; - __le16 device_capabilities; - __le32 build_number; - u8 deviceType; - u8 reserved[33]; - - u8 customer_data[64]; - - struct ar9170_eeprom_modal - modal_header[2]; - - u8 cal_freq_pier_5G[AR5416_NUM_5G_CAL_PIERS]; - u8 cal_freq_pier_2G[AR5416_NUM_2G_CAL_PIERS]; - - struct ar9170_calibration_data_per_freq - cal_pier_data_5G[AR5416_MAX_CHAINS][AR5416_NUM_5G_CAL_PIERS], - cal_pier_data_2G[AR5416_MAX_CHAINS][AR5416_NUM_2G_CAL_PIERS]; - - /* power calibration data */ - struct ar9170_calibration_target_power_legacy - cal_tgt_pwr_5G[AR5416_NUM_5G_TARGET_PWRS]; - struct ar9170_calibration_target_power_ht - cal_tgt_pwr_5G_ht20[AR5416_NUM_5G_TARGET_PWRS], - cal_tgt_pwr_5G_ht40[AR5416_NUM_5G_TARGET_PWRS]; - - struct ar9170_calibration_target_power_legacy - cal_tgt_pwr_2G_cck[AR5416_NUM_2G_CCK_TARGET_PWRS], - cal_tgt_pwr_2G_ofdm[AR5416_NUM_2G_OFDM_TARGET_PWRS]; - struct ar9170_calibration_target_power_ht - cal_tgt_pwr_2G_ht20[AR5416_NUM_2G_OFDM_TARGET_PWRS], - cal_tgt_pwr_2G_ht40[AR5416_NUM_2G_OFDM_TARGET_PWRS]; - - /* conformance testing limits */ - u8 ctl_index[AR5416_NUM_CTLS]; - struct ar9170_calctl_data - ctl_data[AR5416_NUM_CTLS]; - - u8 pad; - __le16 subsystem_id; -} __packed; - -#define AR9170_LED_MODE_POWER_ON 0x0001 -#define AR9170_LED_MODE_RESERVED 0x0002 -#define AR9170_LED_MODE_DISABLE_STATE 0x0004 -#define AR9170_LED_MODE_OFF_IN_PSM 0x0008 - -/* AR9170_LED_MODE BIT is set */ -#define AR9170_LED_MODE_FREQUENCY_S 4 -#define AR9170_LED_MODE_FREQUENCY 0x0030 -#define AR9170_LED_MODE_FREQUENCY_1HZ 0x0000 -#define AR9170_LED_MODE_FREQUENCY_0_5HZ 0x0010 -#define AR9170_LED_MODE_FREQUENCY_0_25HZ 0x0020 -#define AR9170_LED_MODE_FREQUENCY_0_125HZ 0x0030 - -/* AR9170_LED_MODE BIT is not set */ -#define AR9170_LED_MODE_CONN_STATE_S 4 -#define AR9170_LED_MODE_CONN_STATE 0x0030 -#define AR9170_LED_MODE_CONN_STATE_FORCE_OFF 0x0000 -#define AR9170_LED_MODE_CONN_STATE_FORCE_ON 0x0010 -/* Idle off / Active on */ -#define AR9170_LED_MODE_CONN_STATE_IOFF_AON 0x0020 -/* Idle on / Active off */ -#define AR9170_LED_MODE_CONN_STATE_ION_AOFF 0x0010 - -#define AR9170_LED_MODE_MODE 0x0040 -#define AR9170_LED_MODE_RESERVED2 0x0080 - -#define AR9170_LED_MODE_TON_SCAN_S 8 -#define AR9170_LED_MODE_TON_SCAN 0x0f00 - -#define AR9170_LED_MODE_TOFF_SCAN_S 12 -#define AR9170_LED_MODE_TOFF_SCAN 0xf000 - -struct ar9170_led_mode { - __le16 led; -}; - -#endif /* __CARL9170_SHARED_EEPROM_H */ diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/fw.c b/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/fw.c deleted file mode 100644 index cffde8d9..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/fw.c +++ /dev/null @@ -1,429 +0,0 @@ -/* - * Atheros CARL9170 driver - * - * firmware parser - * - * Copyright 2009, 2010, Christian Lamparter <chunkeey@googlemail.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, see - * http://www.gnu.org/licenses/. - */ - -#include <linux/kernel.h> -#include <linux/firmware.h> -#include <linux/crc32.h> -#include <linux/module.h> -#include "carl9170.h" -#include "fwcmd.h" -#include "version.h" - -#define MAKE_STR(symbol) #symbol -#define TO_STR(symbol) MAKE_STR(symbol) -#define CARL9170FW_API_VER_STR TO_STR(CARL9170FW_API_MAX_VER) -MODULE_VERSION(CARL9170FW_API_VER_STR ":" CARL9170FW_VERSION_GIT); - -static const u8 otus_magic[4] = { OTUS_MAGIC }; - -static const void *carl9170_fw_find_desc(struct ar9170 *ar, const u8 descid[4], - const unsigned int len, const u8 compatible_revision) -{ - const struct carl9170fw_desc_head *iter; - - carl9170fw_for_each_hdr(iter, ar->fw.desc) { - if (carl9170fw_desc_cmp(iter, descid, len, - compatible_revision)) - return (void *)iter; - } - - /* needed to find the LAST desc */ - if (carl9170fw_desc_cmp(iter, descid, len, - compatible_revision)) - return (void *)iter; - - return NULL; -} - -static int carl9170_fw_verify_descs(struct ar9170 *ar, - const struct carl9170fw_desc_head *head, unsigned int max_len) -{ - const struct carl9170fw_desc_head *pos; - unsigned long pos_addr, end_addr; - unsigned int pos_length; - - if (max_len < sizeof(*pos)) - return -ENODATA; - - max_len = min_t(unsigned int, CARL9170FW_DESC_MAX_LENGTH, max_len); - - pos = head; - pos_addr = (unsigned long) pos; - end_addr = pos_addr + max_len; - - while (pos_addr < end_addr) { - if (pos_addr + sizeof(*head) > end_addr) - return -E2BIG; - - pos_length = le16_to_cpu(pos->length); - - if (pos_length < sizeof(*head)) - return -EBADMSG; - - if (pos_length > max_len) - return -EOVERFLOW; - - if (pos_addr + pos_length > end_addr) - return -EMSGSIZE; - - if (carl9170fw_desc_cmp(pos, LAST_MAGIC, - CARL9170FW_LAST_DESC_SIZE, - CARL9170FW_LAST_DESC_CUR_VER)) - return 0; - - pos_addr += pos_length; - pos = (void *)pos_addr; - max_len -= pos_length; - } - return -EINVAL; -} - -static void carl9170_fw_info(struct ar9170 *ar) -{ - const struct carl9170fw_motd_desc *motd_desc; - unsigned int str_ver_len; - u32 fw_date; - - dev_info(&ar->udev->dev, "driver API: %s 2%03d-%02d-%02d [%d-%d]\n", - CARL9170FW_VERSION_GIT, CARL9170FW_VERSION_YEAR, - CARL9170FW_VERSION_MONTH, CARL9170FW_VERSION_DAY, - CARL9170FW_API_MIN_VER, CARL9170FW_API_MAX_VER); - - motd_desc = carl9170_fw_find_desc(ar, MOTD_MAGIC, - sizeof(*motd_desc), CARL9170FW_MOTD_DESC_CUR_VER); - - if (motd_desc) { - str_ver_len = strnlen(motd_desc->release, - CARL9170FW_MOTD_RELEASE_LEN); - - fw_date = le32_to_cpu(motd_desc->fw_year_month_day); - - dev_info(&ar->udev->dev, "firmware API: %.*s 2%03d-%02d-%02d\n", - str_ver_len, motd_desc->release, - CARL9170FW_GET_YEAR(fw_date), - CARL9170FW_GET_MONTH(fw_date), - CARL9170FW_GET_DAY(fw_date)); - - strlcpy(ar->hw->wiphy->fw_version, motd_desc->release, - sizeof(ar->hw->wiphy->fw_version)); - } -} - -static bool valid_dma_addr(const u32 address) -{ - if (address >= AR9170_SRAM_OFFSET && - address < (AR9170_SRAM_OFFSET + AR9170_SRAM_SIZE)) - return true; - - return false; -} - -static bool valid_cpu_addr(const u32 address) -{ - if (valid_dma_addr(address) || (address >= AR9170_PRAM_OFFSET && - address < (AR9170_PRAM_OFFSET + AR9170_PRAM_SIZE))) - return true; - - return false; -} - -static int carl9170_fw_checksum(struct ar9170 *ar, const __u8 *data, - size_t len) -{ - const struct carl9170fw_otus_desc *otus_desc; - const struct carl9170fw_last_desc *last_desc; - const struct carl9170fw_chk_desc *chk_desc; - unsigned long fin, diff; - unsigned int dsc_len; - u32 crc32; - - last_desc = carl9170_fw_find_desc(ar, LAST_MAGIC, - sizeof(*last_desc), CARL9170FW_LAST_DESC_CUR_VER); - if (!last_desc) - return -EINVAL; - - otus_desc = carl9170_fw_find_desc(ar, OTUS_MAGIC, - sizeof(*otus_desc), CARL9170FW_OTUS_DESC_CUR_VER); - if (!otus_desc) { - dev_err(&ar->udev->dev, "failed to find compatible firmware " - "descriptor.\n"); - return -ENODATA; - } - - chk_desc = carl9170_fw_find_desc(ar, CHK_MAGIC, - sizeof(*chk_desc), CARL9170FW_CHK_DESC_CUR_VER); - - if (!chk_desc) { - dev_warn(&ar->udev->dev, "Unprotected firmware image.\n"); - return 0; - } - - dsc_len = min_t(unsigned int, len, - (unsigned long)chk_desc - (unsigned long)otus_desc); - - fin = (unsigned long) last_desc + sizeof(*last_desc); - diff = fin - (unsigned long) otus_desc; - - if (diff < len) - len -= diff; - - if (len < 256) - return -EIO; - - crc32 = crc32_le(~0, data, len); - if (cpu_to_le32(crc32) != chk_desc->fw_crc32) { - dev_err(&ar->udev->dev, "fw checksum test failed.\n"); - return -ENOEXEC; - } - - crc32 = crc32_le(crc32, (void *)otus_desc, dsc_len); - if (cpu_to_le32(crc32) != chk_desc->hdr_crc32) { - dev_err(&ar->udev->dev, "descriptor check failed.\n"); - return -EINVAL; - } - return 0; -} - -static int carl9170_fw_tx_sequence(struct ar9170 *ar) -{ - const struct carl9170fw_txsq_desc *txsq_desc; - - txsq_desc = carl9170_fw_find_desc(ar, TXSQ_MAGIC, sizeof(*txsq_desc), - CARL9170FW_TXSQ_DESC_CUR_VER); - if (txsq_desc) { - ar->fw.tx_seq_table = le32_to_cpu(txsq_desc->seq_table_addr); - if (!valid_cpu_addr(ar->fw.tx_seq_table)) - return -EINVAL; - } else { - ar->fw.tx_seq_table = 0; - } - - return 0; -} - -static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) -{ - const struct carl9170fw_otus_desc *otus_desc; - int err; - u16 if_comb_types; - - err = carl9170_fw_checksum(ar, data, len); - if (err) - return err; - - otus_desc = carl9170_fw_find_desc(ar, OTUS_MAGIC, - sizeof(*otus_desc), CARL9170FW_OTUS_DESC_CUR_VER); - if (!otus_desc) { - return -ENODATA; - } - -#define SUPP(feat) \ - (carl9170fw_supports(otus_desc->feature_set, feat)) - - if (!SUPP(CARL9170FW_DUMMY_FEATURE)) { - dev_err(&ar->udev->dev, "invalid firmware descriptor " - "format detected.\n"); - return -EINVAL; - } - - ar->fw.api_version = otus_desc->api_ver; - - if (ar->fw.api_version < CARL9170FW_API_MIN_VER || - ar->fw.api_version > CARL9170FW_API_MAX_VER) { - dev_err(&ar->udev->dev, "unsupported firmware api version.\n"); - return -EINVAL; - } - - if (!SUPP(CARL9170FW_COMMAND_PHY) || SUPP(CARL9170FW_UNUSABLE) || - !SUPP(CARL9170FW_HANDLE_BACK_REQ)) { - dev_err(&ar->udev->dev, "firmware does support " - "mandatory features.\n"); - return -ECANCELED; - } - - if (ilog2(le32_to_cpu(otus_desc->feature_set)) >= - __CARL9170FW_FEATURE_NUM) { - dev_warn(&ar->udev->dev, "driver does not support all " - "firmware features.\n"); - } - - if (!SUPP(CARL9170FW_COMMAND_CAM)) { - dev_info(&ar->udev->dev, "crypto offloading is disabled " - "by firmware.\n"); - ar->disable_offload = true; - } - - if (SUPP(CARL9170FW_PSM) && SUPP(CARL9170FW_FIXED_5GHZ_PSM)) - ar->hw->flags |= IEEE80211_HW_SUPPORTS_PS; - - if (!SUPP(CARL9170FW_USB_INIT_FIRMWARE)) { - dev_err(&ar->udev->dev, "firmware does not provide " - "mandatory interfaces.\n"); - return -EINVAL; - } - - if (SUPP(CARL9170FW_MINIBOOT)) - ar->fw.offset = le16_to_cpu(otus_desc->miniboot_size); - else - ar->fw.offset = 0; - - if (SUPP(CARL9170FW_USB_DOWN_STREAM)) { - ar->hw->extra_tx_headroom += sizeof(struct ar9170_stream); - ar->fw.tx_stream = true; - } - - if (SUPP(CARL9170FW_USB_UP_STREAM)) - ar->fw.rx_stream = true; - - if (SUPP(CARL9170FW_RX_FILTER)) { - ar->fw.rx_filter = true; - ar->rx_filter_caps = FIF_FCSFAIL | FIF_PLCPFAIL | - FIF_CONTROL | FIF_PSPOLL | FIF_OTHER_BSS | - FIF_PROMISC_IN_BSS; - } - - if (SUPP(CARL9170FW_HW_COUNTERS)) - ar->fw.hw_counters = true; - - if (SUPP(CARL9170FW_WOL)) - device_set_wakeup_enable(&ar->udev->dev, true); - - if_comb_types = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_P2P_CLIENT); - - ar->fw.vif_num = otus_desc->vif_num; - ar->fw.cmd_bufs = otus_desc->cmd_bufs; - ar->fw.address = le32_to_cpu(otus_desc->fw_address); - ar->fw.rx_size = le16_to_cpu(otus_desc->rx_max_frame_len); - ar->fw.mem_blocks = min_t(unsigned int, otus_desc->tx_descs, 0xfe); - atomic_set(&ar->mem_free_blocks, ar->fw.mem_blocks); - ar->fw.mem_block_size = le16_to_cpu(otus_desc->tx_frag_len); - - if (ar->fw.vif_num >= AR9170_MAX_VIRTUAL_MAC || !ar->fw.vif_num || - ar->fw.mem_blocks < 16 || !ar->fw.cmd_bufs || - ar->fw.mem_block_size < 64 || ar->fw.mem_block_size > 512 || - ar->fw.rx_size > 32768 || ar->fw.rx_size < 4096 || - !valid_cpu_addr(ar->fw.address)) { - dev_err(&ar->udev->dev, "firmware shows obvious signs of " - "malicious tampering.\n"); - return -EINVAL; - } - - ar->fw.beacon_addr = le32_to_cpu(otus_desc->bcn_addr); - ar->fw.beacon_max_len = le16_to_cpu(otus_desc->bcn_len); - - if (valid_dma_addr(ar->fw.beacon_addr) && ar->fw.beacon_max_len >= - AR9170_MAC_BCN_LENGTH_MAX) { - ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC); - - if (SUPP(CARL9170FW_WLANTX_CAB)) { - if_comb_types |= - BIT(NL80211_IFTYPE_AP) | - BIT(NL80211_IFTYPE_P2P_GO); - } - } - - ar->if_comb_limits[0].max = ar->fw.vif_num; - ar->if_comb_limits[0].types = if_comb_types; - - ar->if_combs[0].num_different_channels = 1; - ar->if_combs[0].max_interfaces = ar->fw.vif_num; - ar->if_combs[0].limits = ar->if_comb_limits; - ar->if_combs[0].n_limits = ARRAY_SIZE(ar->if_comb_limits); - - ar->hw->wiphy->iface_combinations = ar->if_combs; - ar->hw->wiphy->n_iface_combinations = ARRAY_SIZE(ar->if_combs); - - ar->hw->wiphy->interface_modes |= if_comb_types; - -#undef SUPPORTED - return carl9170_fw_tx_sequence(ar); -} - -static struct carl9170fw_desc_head * -carl9170_find_fw_desc(struct ar9170 *ar, const __u8 *fw_data, const size_t len) - -{ - int scan = 0, found = 0; - - if (!carl9170fw_size_check(len)) { - dev_err(&ar->udev->dev, "firmware size is out of bound.\n"); - return NULL; - } - - while (scan < len - sizeof(struct carl9170fw_desc_head)) { - if (fw_data[scan++] == otus_magic[found]) - found++; - else - found = 0; - - if (scan >= len) - break; - - if (found == sizeof(otus_magic)) - break; - } - - if (found != sizeof(otus_magic)) - return NULL; - - return (void *)&fw_data[scan - found]; -} - -int carl9170_parse_firmware(struct ar9170 *ar) -{ - const struct carl9170fw_desc_head *fw_desc = NULL; - const struct firmware *fw = ar->fw.fw; - unsigned long header_offset = 0; - int err; - - if (WARN_ON(!fw)) - return -EINVAL; - - fw_desc = carl9170_find_fw_desc(ar, fw->data, fw->size); - - if (!fw_desc) { - dev_err(&ar->udev->dev, "unsupported firmware.\n"); - return -ENODATA; - } - - header_offset = (unsigned long)fw_desc - (unsigned long)fw->data; - - err = carl9170_fw_verify_descs(ar, fw_desc, fw->size - header_offset); - if (err) { - dev_err(&ar->udev->dev, "damaged firmware (%d).\n", err); - return err; - } - - ar->fw.desc = fw_desc; - - carl9170_fw_info(ar); - - err = carl9170_fw(ar, fw->data, fw->size); - if (err) { - dev_err(&ar->udev->dev, "failed to parse firmware (%d).\n", - err); - return err; - } - - return 0; -} diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/fwcmd.h b/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/fwcmd.h deleted file mode 100644 index 9443c802..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/fwcmd.h +++ /dev/null @@ -1,318 +0,0 @@ -/* - * Shared Atheros AR9170 Header - * - * Firmware command interface definitions - * - * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> - * Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, see - * http://www.gnu.org/licenses/. - * - * This file incorporates work covered by the following copyright and - * permission notice: - * Copyright (c) 2007-2008 Atheros Communications, Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef __CARL9170_SHARED_FWCMD_H -#define __CARL9170_SHARED_FWCMD_H - -#define CARL9170_MAX_CMD_LEN 64 -#define CARL9170_MAX_CMD_PAYLOAD_LEN 60 - -#define CARL9170FW_API_MIN_VER 1 -#define CARL9170FW_API_MAX_VER 1 - -enum carl9170_cmd_oids { - CARL9170_CMD_RREG = 0x00, - CARL9170_CMD_WREG = 0x01, - CARL9170_CMD_ECHO = 0x02, - CARL9170_CMD_SWRST = 0x03, - CARL9170_CMD_REBOOT = 0x04, - CARL9170_CMD_BCN_CTRL = 0x05, - CARL9170_CMD_READ_TSF = 0x06, - CARL9170_CMD_RX_FILTER = 0x07, - CARL9170_CMD_WOL = 0x08, - CARL9170_CMD_TALLY = 0x09, - - /* CAM */ - CARL9170_CMD_EKEY = 0x10, - CARL9170_CMD_DKEY = 0x11, - - /* RF / PHY */ - CARL9170_CMD_FREQUENCY = 0x20, - CARL9170_CMD_RF_INIT = 0x21, - CARL9170_CMD_SYNTH = 0x22, - CARL9170_CMD_FREQ_START = 0x23, - CARL9170_CMD_PSM = 0x24, - - /* Asychronous command flag */ - CARL9170_CMD_ASYNC_FLAG = 0x40, - CARL9170_CMD_WREG_ASYNC = (CARL9170_CMD_WREG | - CARL9170_CMD_ASYNC_FLAG), - CARL9170_CMD_REBOOT_ASYNC = (CARL9170_CMD_REBOOT | - CARL9170_CMD_ASYNC_FLAG), - CARL9170_CMD_BCN_CTRL_ASYNC = (CARL9170_CMD_BCN_CTRL | - CARL9170_CMD_ASYNC_FLAG), - CARL9170_CMD_PSM_ASYNC = (CARL9170_CMD_PSM | - CARL9170_CMD_ASYNC_FLAG), - - /* responses and traps */ - CARL9170_RSP_FLAG = 0xc0, - CARL9170_RSP_PRETBTT = 0xc0, - CARL9170_RSP_TXCOMP = 0xc1, - CARL9170_RSP_BEACON_CONFIG = 0xc2, - CARL9170_RSP_ATIM = 0xc3, - CARL9170_RSP_WATCHDOG = 0xc6, - CARL9170_RSP_TEXT = 0xca, - CARL9170_RSP_HEXDUMP = 0xcc, - CARL9170_RSP_RADAR = 0xcd, - CARL9170_RSP_GPIO = 0xce, - CARL9170_RSP_BOOT = 0xcf, -}; - -struct carl9170_set_key_cmd { - __le16 user; - __le16 keyId; - __le16 type; - u8 macAddr[6]; - u32 key[4]; -} __packed __aligned(4); -#define CARL9170_SET_KEY_CMD_SIZE 28 - -struct carl9170_disable_key_cmd { - __le16 user; - __le16 padding; -} __packed __aligned(4); -#define CARL9170_DISABLE_KEY_CMD_SIZE 4 - -struct carl9170_u32_list { - u32 vals[0]; -} __packed; - -struct carl9170_reg_list { - __le32 regs[0]; -} __packed; - -struct carl9170_write_reg { - struct { - __le32 addr; - __le32 val; - } regs[0] __packed; -} __packed; - -#define CARL9170FW_PHY_HT_ENABLE 0x4 -#define CARL9170FW_PHY_HT_DYN2040 0x8 -#define CARL9170FW_PHY_HT_EXT_CHAN_OFF 0x3 -#define CARL9170FW_PHY_HT_EXT_CHAN_OFF_S 2 - -struct carl9170_rf_init { - __le32 freq; - u8 ht_settings; - u8 padding2[3]; - __le32 delta_slope_coeff_exp; - __le32 delta_slope_coeff_man; - __le32 delta_slope_coeff_exp_shgi; - __le32 delta_slope_coeff_man_shgi; - __le32 finiteLoopCount; -} __packed; -#define CARL9170_RF_INIT_SIZE 28 - -struct carl9170_rf_init_result { - __le32 ret; /* AR9170_PHY_REG_AGC_CONTROL */ -} __packed; -#define CARL9170_RF_INIT_RESULT_SIZE 4 - -#define CARL9170_PSM_SLEEP 0x1000 -#define CARL9170_PSM_SOFTWARE 0 -#define CARL9170_PSM_WAKE 0 /* internally used. */ -#define CARL9170_PSM_COUNTER 0xfff -#define CARL9170_PSM_COUNTER_S 0 - -struct carl9170_psm { - __le32 state; -} __packed; -#define CARL9170_PSM_SIZE 4 - -struct carl9170_rx_filter_cmd { - __le32 rx_filter; -} __packed; -#define CARL9170_RX_FILTER_CMD_SIZE 4 - -#define CARL9170_RX_FILTER_BAD 0x01 -#define CARL9170_RX_FILTER_OTHER_RA 0x02 -#define CARL9170_RX_FILTER_DECRY_FAIL 0x04 -#define CARL9170_RX_FILTER_CTL_OTHER 0x08 -#define CARL9170_RX_FILTER_CTL_PSPOLL 0x10 -#define CARL9170_RX_FILTER_CTL_BACKR 0x20 -#define CARL9170_RX_FILTER_MGMT 0x40 -#define CARL9170_RX_FILTER_DATA 0x80 -#define CARL9170_RX_FILTER_EVERYTHING (~0) - -struct carl9170_bcn_ctrl_cmd { - __le32 vif_id; - __le32 mode; - __le32 bcn_addr; - __le32 bcn_len; -} __packed; -#define CARL9170_BCN_CTRL_CMD_SIZE 16 - -#define CARL9170_BCN_CTRL_DRAIN 0 -#define CARL9170_BCN_CTRL_CAB_TRIGGER 1 - -struct carl9170_wol_cmd { - __le32 flags; - u8 mac[6]; - u8 bssid[6]; - __le32 null_interval; - __le32 free_for_use2; - __le32 mask; - u8 pattern[32]; -} __packed; - -#define CARL9170_WOL_CMD_SIZE 60 - -#define CARL9170_WOL_DISCONNECT 1 -#define CARL9170_WOL_MAGIC_PKT 2 - -struct carl9170_cmd_head { - union { - struct { - u8 len; - u8 cmd; - u8 seq; - u8 ext; - } __packed; - - u32 hdr_data; - } __packed; -} __packed; - -struct carl9170_cmd { - struct carl9170_cmd_head hdr; - union { - struct carl9170_set_key_cmd setkey; - struct carl9170_disable_key_cmd disablekey; - struct carl9170_u32_list echo; - struct carl9170_reg_list rreg; - struct carl9170_write_reg wreg; - struct carl9170_rf_init rf_init; - struct carl9170_psm psm; - struct carl9170_wol_cmd wol; - struct carl9170_bcn_ctrl_cmd bcn_ctrl; - struct carl9170_rx_filter_cmd rx_filter; - u8 data[CARL9170_MAX_CMD_PAYLOAD_LEN]; - } __packed; -} __packed __aligned(4); - -#define CARL9170_TX_STATUS_QUEUE 3 -#define CARL9170_TX_STATUS_QUEUE_S 0 -#define CARL9170_TX_STATUS_RIX_S 2 -#define CARL9170_TX_STATUS_RIX (3 << CARL9170_TX_STATUS_RIX_S) -#define CARL9170_TX_STATUS_TRIES_S 4 -#define CARL9170_TX_STATUS_TRIES (7 << CARL9170_TX_STATUS_TRIES_S) -#define CARL9170_TX_STATUS_SUCCESS 0x80 - -#ifdef __CARL9170FW__ -/* - * NOTE: - * Both structs [carl9170_tx_status and _carl9170_tx_status] - * need to be "bit for bit" in sync. - */ -struct carl9170_tx_status { - /* - * Beware of compiler bugs in all gcc pre 4.4! - */ - - u8 cookie; - u8 queue:2; - u8 rix:2; - u8 tries:3; - u8 success:1; -} __packed; -#endif /* __CARL9170FW__ */ - -struct _carl9170_tx_status { - /* - * This version should be immune to all alignment bugs. - */ - - u8 cookie; - u8 info; -} __packed; -#define CARL9170_TX_STATUS_SIZE 2 - -#define CARL9170_RSP_TX_STATUS_NUM (CARL9170_MAX_CMD_PAYLOAD_LEN / \ - sizeof(struct _carl9170_tx_status)) - -#define CARL9170_TX_MAX_RATE_TRIES 7 - -#define CARL9170_TX_MAX_RATES 4 -#define CARL9170_TX_MAX_RETRY_RATES (CARL9170_TX_MAX_RATES - 1) -#define CARL9170_ERR_MAGIC "ERR:" -#define CARL9170_BUG_MAGIC "BUG:" - -struct carl9170_gpio { - __le32 gpio; -} __packed; -#define CARL9170_GPIO_SIZE 4 - -struct carl9170_tsf_rsp { - union { - __le32 tsf[2]; - __le64 tsf_64; - } __packed; -} __packed; -#define CARL9170_TSF_RSP_SIZE 8 - -struct carl9170_tally_rsp { - __le32 active; - __le32 cca; - __le32 tx_time; - __le32 rx_total; - __le32 rx_overrun; - __le32 tick; -} __packed; - -struct carl9170_rsp { - struct carl9170_cmd_head hdr; - - union { - struct carl9170_rf_init_result rf_init_res; - struct carl9170_u32_list rreg_res; - struct carl9170_u32_list echo; -#ifdef __CARL9170FW__ - struct carl9170_tx_status tx_status[0]; -#endif /* __CARL9170FW__ */ - struct _carl9170_tx_status _tx_status[0]; - struct carl9170_gpio gpio; - struct carl9170_tsf_rsp tsf; - struct carl9170_psm psm; - struct carl9170_tally_rsp tally; - u8 data[CARL9170_MAX_CMD_PAYLOAD_LEN]; - } __packed; -} __packed __aligned(4); - -#endif /* __CARL9170_SHARED_FWCMD_H */ diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/fwdesc.h b/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/fwdesc.h deleted file mode 100644 index 6d9c0891..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/fwdesc.h +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Shared CARL9170 Header - * - * Firmware descriptor format - * - * Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, see - * http://www.gnu.org/licenses/. - */ - -#ifndef __CARL9170_SHARED_FWDESC_H -#define __CARL9170_SHARED_FWDESC_H - -/* NOTE: Don't mess with the order of the flags! */ -enum carl9170fw_feature_list { - /* Always set */ - CARL9170FW_DUMMY_FEATURE, - - /* - * Indicates that this image has special boot block which prevents - * legacy drivers to drive the firmware. - */ - CARL9170FW_MINIBOOT, - - /* usb registers are initialized by the firmware */ - CARL9170FW_USB_INIT_FIRMWARE, - - /* command traps & notifications are send through EP2 */ - CARL9170FW_USB_RESP_EP2, - - /* usb download (app -> fw) stream */ - CARL9170FW_USB_DOWN_STREAM, - - /* usb upload (fw -> app) stream */ - CARL9170FW_USB_UP_STREAM, - - /* unusable - reserved to flag non-functional debug firmwares */ - CARL9170FW_UNUSABLE, - - /* AR9170_CMD_RF_INIT, AR9170_CMD_FREQ_START, AR9170_CMD_FREQUENCY */ - CARL9170FW_COMMAND_PHY, - - /* AR9170_CMD_EKEY, AR9170_CMD_DKEY */ - CARL9170FW_COMMAND_CAM, - - /* Firmware has a software Content After Beacon Queueing mechanism */ - CARL9170FW_WLANTX_CAB, - - /* The firmware is capable of responding to incoming BAR frames */ - CARL9170FW_HANDLE_BACK_REQ, - - /* GPIO Interrupt | CARL9170_RSP_GPIO */ - CARL9170FW_GPIO_INTERRUPT, - - /* Firmware PSM support | CARL9170_CMD_PSM */ - CARL9170FW_PSM, - - /* Firmware RX filter | CARL9170_CMD_RX_FILTER */ - CARL9170FW_RX_FILTER, - - /* Wake up on WLAN */ - CARL9170FW_WOL, - - /* Firmware supports PSM in the 5GHZ Band */ - CARL9170FW_FIXED_5GHZ_PSM, - - /* HW (ANI, CCA, MIB) tally counters */ - CARL9170FW_HW_COUNTERS, - - /* KEEP LAST */ - __CARL9170FW_FEATURE_NUM -}; - -#define OTUS_MAGIC "OTAR" -#define MOTD_MAGIC "MOTD" -#define FIX_MAGIC "FIX\0" -#define DBG_MAGIC "DBG\0" -#define CHK_MAGIC "CHK\0" -#define TXSQ_MAGIC "TXSQ" -#define WOL_MAGIC "WOL\0" -#define LAST_MAGIC "LAST" - -#define CARL9170FW_SET_DAY(d) (((d) - 1) % 31) -#define CARL9170FW_SET_MONTH(m) ((((m) - 1) % 12) * 31) -#define CARL9170FW_SET_YEAR(y) (((y) - 10) * 372) - -#define CARL9170FW_GET_DAY(d) (((d) % 31) + 1) -#define CARL9170FW_GET_MONTH(m) ((((m) / 31) % 12) + 1) -#define CARL9170FW_GET_YEAR(y) ((y) / 372 + 10) - -#define CARL9170FW_MAGIC_SIZE 4 - -struct carl9170fw_desc_head { - u8 magic[CARL9170FW_MAGIC_SIZE]; - __le16 length; - u8 min_ver; - u8 cur_ver; -} __packed; -#define CARL9170FW_DESC_HEAD_SIZE \ - (sizeof(struct carl9170fw_desc_head)) - -#define CARL9170FW_OTUS_DESC_MIN_VER 6 -#define CARL9170FW_OTUS_DESC_CUR_VER 7 -struct carl9170fw_otus_desc { - struct carl9170fw_desc_head head; - __le32 feature_set; - __le32 fw_address; - __le32 bcn_addr; - __le16 bcn_len; - __le16 miniboot_size; - __le16 tx_frag_len; - __le16 rx_max_frame_len; - u8 tx_descs; - u8 cmd_bufs; - u8 api_ver; - u8 vif_num; -} __packed; -#define CARL9170FW_OTUS_DESC_SIZE \ - (sizeof(struct carl9170fw_otus_desc)) - -#define CARL9170FW_MOTD_STRING_LEN 24 -#define CARL9170FW_MOTD_RELEASE_LEN 20 -#define CARL9170FW_MOTD_DESC_MIN_VER 1 -#define CARL9170FW_MOTD_DESC_CUR_VER 2 -struct carl9170fw_motd_desc { - struct carl9170fw_desc_head head; - __le32 fw_year_month_day; - char desc[CARL9170FW_MOTD_STRING_LEN]; - char release[CARL9170FW_MOTD_RELEASE_LEN]; -} __packed; -#define CARL9170FW_MOTD_DESC_SIZE \ - (sizeof(struct carl9170fw_motd_desc)) - -#define CARL9170FW_FIX_DESC_MIN_VER 1 -#define CARL9170FW_FIX_DESC_CUR_VER 2 -struct carl9170fw_fix_entry { - __le32 address; - __le32 mask; - __le32 value; -} __packed; - -struct carl9170fw_fix_desc { - struct carl9170fw_desc_head head; - struct carl9170fw_fix_entry data[0]; -} __packed; -#define CARL9170FW_FIX_DESC_SIZE \ - (sizeof(struct carl9170fw_fix_desc)) - -#define CARL9170FW_DBG_DESC_MIN_VER 1 -#define CARL9170FW_DBG_DESC_CUR_VER 3 -struct carl9170fw_dbg_desc { - struct carl9170fw_desc_head head; - - __le32 bogoclock_addr; - __le32 counter_addr; - __le32 rx_total_addr; - __le32 rx_overrun_addr; - __le32 rx_filter; - - /* Put your debugging definitions here */ -} __packed; -#define CARL9170FW_DBG_DESC_SIZE \ - (sizeof(struct carl9170fw_dbg_desc)) - -#define CARL9170FW_CHK_DESC_MIN_VER 1 -#define CARL9170FW_CHK_DESC_CUR_VER 2 -struct carl9170fw_chk_desc { - struct carl9170fw_desc_head head; - __le32 fw_crc32; - __le32 hdr_crc32; -} __packed; -#define CARL9170FW_CHK_DESC_SIZE \ - (sizeof(struct carl9170fw_chk_desc)) - -#define CARL9170FW_TXSQ_DESC_MIN_VER 1 -#define CARL9170FW_TXSQ_DESC_CUR_VER 1 -struct carl9170fw_txsq_desc { - struct carl9170fw_desc_head head; - - __le32 seq_table_addr; -} __packed; -#define CARL9170FW_TXSQ_DESC_SIZE \ - (sizeof(struct carl9170fw_txsq_desc)) - -#define CARL9170FW_WOL_DESC_MIN_VER 1 -#define CARL9170FW_WOL_DESC_CUR_VER 1 -struct carl9170fw_wol_desc { - struct carl9170fw_desc_head head; - - __le32 supported_triggers; /* CARL9170_WOL_ */ -} __packed; -#define CARL9170FW_WOL_DESC_SIZE \ - (sizeof(struct carl9170fw_wol_desc)) - -#define CARL9170FW_LAST_DESC_MIN_VER 1 -#define CARL9170FW_LAST_DESC_CUR_VER 2 -struct carl9170fw_last_desc { - struct carl9170fw_desc_head head; -} __packed; -#define CARL9170FW_LAST_DESC_SIZE \ - (sizeof(struct carl9170fw_fix_desc)) - -#define CARL9170FW_DESC_MAX_LENGTH 8192 - -#define CARL9170FW_FILL_DESC(_magic, _length, _min_ver, _cur_ver) \ - .head = { \ - .magic = _magic, \ - .length = cpu_to_le16(_length), \ - .min_ver = _min_ver, \ - .cur_ver = _cur_ver, \ - } - -static inline void carl9170fw_fill_desc(struct carl9170fw_desc_head *head, - u8 magic[CARL9170FW_MAGIC_SIZE], - __le16 length, u8 min_ver, u8 cur_ver) -{ - head->magic[0] = magic[0]; - head->magic[1] = magic[1]; - head->magic[2] = magic[2]; - head->magic[3] = magic[3]; - - head->length = length; - head->min_ver = min_ver; - head->cur_ver = cur_ver; -} - -#define carl9170fw_for_each_hdr(desc, fw_desc) \ - for (desc = fw_desc; \ - memcmp(desc->magic, LAST_MAGIC, CARL9170FW_MAGIC_SIZE) && \ - le16_to_cpu(desc->length) >= CARL9170FW_DESC_HEAD_SIZE && \ - le16_to_cpu(desc->length) < CARL9170FW_DESC_MAX_LENGTH; \ - desc = (void *)((unsigned long)desc + le16_to_cpu(desc->length))) - -#define CHECK_HDR_VERSION(head, _min_ver) \ - (((head)->cur_ver < _min_ver) || ((head)->min_ver > _min_ver)) \ - -static inline bool carl9170fw_supports(__le32 list, u8 feature) -{ - return le32_to_cpu(list) & BIT(feature); -} - -static inline bool carl9170fw_desc_cmp(const struct carl9170fw_desc_head *head, - const u8 descid[CARL9170FW_MAGIC_SIZE], - u16 min_len, u8 compatible_revision) -{ - if (descid[0] == head->magic[0] && descid[1] == head->magic[1] && - descid[2] == head->magic[2] && descid[3] == head->magic[3] && - !CHECK_HDR_VERSION(head, compatible_revision) && - (le16_to_cpu(head->length) >= min_len)) - return true; - - return false; -} - -#define CARL9170FW_MIN_SIZE 32 -#define CARL9170FW_MAX_SIZE 16384 - -static inline bool carl9170fw_size_check(unsigned int len) -{ - return (len <= CARL9170FW_MAX_SIZE && len >= CARL9170FW_MIN_SIZE); -} - -#endif /* __CARL9170_SHARED_FWDESC_H */ diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/hw.h b/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/hw.h deleted file mode 100644 index fa834c14..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/hw.h +++ /dev/null @@ -1,817 +0,0 @@ -/* - * Shared Atheros AR9170 Header - * - * Register map, hardware-specific definitions - * - * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> - * Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, see - * http://www.gnu.org/licenses/. - * - * This file incorporates work covered by the following copyright and - * permission notice: - * Copyright (c) 2007-2008 Atheros Communications, Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef __CARL9170_SHARED_HW_H -#define __CARL9170_SHARED_HW_H - -/* High Speed UART */ -#define AR9170_UART_REG_BASE 0x1c0000 - -/* Definitions of interrupt registers */ -#define AR9170_UART_REG_RX_BUFFER (AR9170_UART_REG_BASE + 0x000) -#define AR9170_UART_REG_TX_HOLDING (AR9170_UART_REG_BASE + 0x004) -#define AR9170_UART_REG_FIFO_CONTROL (AR9170_UART_REG_BASE + 0x010) -#define AR9170_UART_FIFO_CTRL_RESET_RX_FIFO 0x02 -#define AR9170_UART_FIFO_CTRL_RESET_TX_FIFO 0x04 - -#define AR9170_UART_REG_LINE_CONTROL (AR9170_UART_REG_BASE + 0x014) -#define AR9170_UART_REG_MODEM_CONTROL (AR9170_UART_REG_BASE + 0x018) -#define AR9170_UART_MODEM_CTRL_DTR_BIT 0x01 -#define AR9170_UART_MODEM_CTRL_RTS_BIT 0x02 -#define AR9170_UART_MODEM_CTRL_INTERNAL_LOOP_BACK 0x10 -#define AR9170_UART_MODEM_CTRL_AUTO_RTS 0x20 -#define AR9170_UART_MODEM_CTRL_AUTO_CTR 0x40 - -#define AR9170_UART_REG_LINE_STATUS (AR9170_UART_REG_BASE + 0x01c) -#define AR9170_UART_LINE_STS_RX_DATA_READY 0x01 -#define AR9170_UART_LINE_STS_RX_BUFFER_OVERRUN 0x02 -#define AR9170_UART_LINE_STS_RX_BREAK_IND 0x10 -#define AR9170_UART_LINE_STS_TX_FIFO_NEAR_EMPTY 0x20 -#define AR9170_UART_LINE_STS_TRANSMITTER_EMPTY 0x40 - -#define AR9170_UART_REG_MODEM_STATUS (AR9170_UART_REG_BASE + 0x020) -#define AR9170_UART_MODEM_STS_CTS_CHANGE 0x01 -#define AR9170_UART_MODEM_STS_DSR_CHANGE 0x02 -#define AR9170_UART_MODEM_STS_DCD_CHANGE 0x08 -#define AR9170_UART_MODEM_STS_CTS_COMPL 0x10 -#define AR9170_UART_MODEM_STS_DSR_COMPL 0x20 -#define AR9170_UART_MODEM_STS_DCD_COMPL 0x80 - -#define AR9170_UART_REG_SCRATCH (AR9170_UART_REG_BASE + 0x024) -#define AR9170_UART_REG_DIVISOR_LSB (AR9170_UART_REG_BASE + 0x028) -#define AR9170_UART_REG_DIVISOR_MSB (AR9170_UART_REG_BASE + 0x02c) -#define AR9170_UART_REG_WORD_RX_BUFFER (AR9170_UART_REG_BASE + 0x034) -#define AR9170_UART_REG_WORD_TX_HOLDING (AR9170_UART_REG_BASE + 0x038) -#define AR9170_UART_REG_FIFO_COUNT (AR9170_UART_REG_BASE + 0x03c) -#define AR9170_UART_REG_REMAINDER (AR9170_UART_REG_BASE + 0x04c) - -/* Timer */ -#define AR9170_TIMER_REG_BASE 0x1c1000 - -#define AR9170_TIMER_REG_WATCH_DOG (AR9170_TIMER_REG_BASE + 0x000) -#define AR9170_TIMER_REG_TIMER0 (AR9170_TIMER_REG_BASE + 0x010) -#define AR9170_TIMER_REG_TIMER1 (AR9170_TIMER_REG_BASE + 0x014) -#define AR9170_TIMER_REG_TIMER2 (AR9170_TIMER_REG_BASE + 0x018) -#define AR9170_TIMER_REG_TIMER3 (AR9170_TIMER_REG_BASE + 0x01c) -#define AR9170_TIMER_REG_TIMER4 (AR9170_TIMER_REG_BASE + 0x020) -#define AR9170_TIMER_REG_CONTROL (AR9170_TIMER_REG_BASE + 0x024) -#define AR9170_TIMER_CTRL_DISABLE_CLOCK 0x100 - -#define AR9170_TIMER_REG_INTERRUPT (AR9170_TIMER_REG_BASE + 0x028) -#define AR9170_TIMER_INT_TIMER0 0x001 -#define AR9170_TIMER_INT_TIMER1 0x002 -#define AR9170_TIMER_INT_TIMER2 0x004 -#define AR9170_TIMER_INT_TIMER3 0x008 -#define AR9170_TIMER_INT_TIMER4 0x010 -#define AR9170_TIMER_INT_TICK_TIMER 0x100 - -#define AR9170_TIMER_REG_TICK_TIMER (AR9170_TIMER_REG_BASE + 0x030) -#define AR9170_TIMER_REG_CLOCK_LOW (AR9170_TIMER_REG_BASE + 0x040) -#define AR9170_TIMER_REG_CLOCK_HIGH (AR9170_TIMER_REG_BASE + 0x044) - -#define AR9170_MAC_REG_BASE 0x1c3000 - -#define AR9170_MAC_REG_POWER_STATE_CTRL (AR9170_MAC_REG_BASE + 0x500) -#define AR9170_MAC_POWER_STATE_CTRL_RESET 0x20 - -#define AR9170_MAC_REG_MAC_POWER_STATE_CTRL (AR9170_MAC_REG_BASE + 0x50c) - -#define AR9170_MAC_REG_INT_CTRL (AR9170_MAC_REG_BASE + 0x510) -#define AR9170_MAC_INT_TXC BIT(0) -#define AR9170_MAC_INT_RXC BIT(1) -#define AR9170_MAC_INT_RETRY_FAIL BIT(2) -#define AR9170_MAC_INT_WAKEUP BIT(3) -#define AR9170_MAC_INT_ATIM BIT(4) -#define AR9170_MAC_INT_DTIM BIT(5) -#define AR9170_MAC_INT_CFG_BCN BIT(6) -#define AR9170_MAC_INT_ABORT BIT(7) -#define AR9170_MAC_INT_QOS BIT(8) -#define AR9170_MAC_INT_MIMO_PS BIT(9) -#define AR9170_MAC_INT_KEY_GEN BIT(10) -#define AR9170_MAC_INT_DECRY_NOUSER BIT(11) -#define AR9170_MAC_INT_RADAR BIT(12) -#define AR9170_MAC_INT_QUIET_FRAME BIT(13) -#define AR9170_MAC_INT_PRETBTT BIT(14) - -#define AR9170_MAC_REG_TSF_L (AR9170_MAC_REG_BASE + 0x514) -#define AR9170_MAC_REG_TSF_H (AR9170_MAC_REG_BASE + 0x518) - -#define AR9170_MAC_REG_ATIM_WINDOW (AR9170_MAC_REG_BASE + 0x51c) -#define AR9170_MAC_ATIM_PERIOD_S 0 -#define AR9170_MAC_ATIM_PERIOD 0x0000ffff - -#define AR9170_MAC_REG_BCN_PERIOD (AR9170_MAC_REG_BASE + 0x520) -#define AR9170_MAC_BCN_PERIOD_S 0 -#define AR9170_MAC_BCN_PERIOD 0x0000ffff -#define AR9170_MAC_BCN_DTIM_S 16 -#define AR9170_MAC_BCN_DTIM 0x00ff0000 -#define AR9170_MAC_BCN_AP_MODE BIT(24) -#define AR9170_MAC_BCN_IBSS_MODE BIT(25) -#define AR9170_MAC_BCN_PWR_MGT BIT(26) -#define AR9170_MAC_BCN_STA_PS BIT(27) - -#define AR9170_MAC_REG_PRETBTT (AR9170_MAC_REG_BASE + 0x524) -#define AR9170_MAC_PRETBTT_S 0 -#define AR9170_MAC_PRETBTT 0x0000ffff -#define AR9170_MAC_PRETBTT2_S 16 -#define AR9170_MAC_PRETBTT2 0xffff0000 - -#define AR9170_MAC_REG_MAC_ADDR_L (AR9170_MAC_REG_BASE + 0x610) -#define AR9170_MAC_REG_MAC_ADDR_H (AR9170_MAC_REG_BASE + 0x614) -#define AR9170_MAC_REG_BSSID_L (AR9170_MAC_REG_BASE + 0x618) -#define AR9170_MAC_REG_BSSID_H (AR9170_MAC_REG_BASE + 0x61c) - -#define AR9170_MAC_REG_GROUP_HASH_TBL_L (AR9170_MAC_REG_BASE + 0x624) -#define AR9170_MAC_REG_GROUP_HASH_TBL_H (AR9170_MAC_REG_BASE + 0x628) - -#define AR9170_MAC_REG_RX_TIMEOUT (AR9170_MAC_REG_BASE + 0x62c) - -#define AR9170_MAC_REG_BASIC_RATE (AR9170_MAC_REG_BASE + 0x630) -#define AR9170_MAC_REG_MANDATORY_RATE (AR9170_MAC_REG_BASE + 0x634) -#define AR9170_MAC_REG_RTS_CTS_RATE (AR9170_MAC_REG_BASE + 0x638) -#define AR9170_MAC_REG_BACKOFF_PROTECT (AR9170_MAC_REG_BASE + 0x63c) -#define AR9170_MAC_REG_RX_THRESHOLD (AR9170_MAC_REG_BASE + 0x640) -#define AR9170_MAC_REG_AFTER_PNP (AR9170_MAC_REG_BASE + 0x648) -#define AR9170_MAC_REG_RX_PE_DELAY (AR9170_MAC_REG_BASE + 0x64c) - -#define AR9170_MAC_REG_DYNAMIC_SIFS_ACK (AR9170_MAC_REG_BASE + 0x658) -#define AR9170_MAC_REG_SNIFFER (AR9170_MAC_REG_BASE + 0x674) -#define AR9170_MAC_SNIFFER_ENABLE_PROMISC BIT(0) -#define AR9170_MAC_SNIFFER_DEFAULTS 0x02000000 -#define AR9170_MAC_REG_ENCRYPTION (AR9170_MAC_REG_BASE + 0x678) -#define AR9170_MAC_ENCRYPTION_MGMT_RX_SOFTWARE BIT(2) -#define AR9170_MAC_ENCRYPTION_RX_SOFTWARE BIT(3) -#define AR9170_MAC_ENCRYPTION_DEFAULTS 0x70 - -#define AR9170_MAC_REG_MISC_680 (AR9170_MAC_REG_BASE + 0x680) -#define AR9170_MAC_REG_MISC_684 (AR9170_MAC_REG_BASE + 0x684) -#define AR9170_MAC_REG_TX_UNDERRUN (AR9170_MAC_REG_BASE + 0x688) - -#define AR9170_MAC_REG_FRAMETYPE_FILTER (AR9170_MAC_REG_BASE + 0x68c) -#define AR9170_MAC_FTF_ASSOC_REQ BIT(0) -#define AR9170_MAC_FTF_ASSOC_RESP BIT(1) -#define AR9170_MAC_FTF_REASSOC_REQ BIT(2) -#define AR9170_MAC_FTF_REASSOC_RESP BIT(3) -#define AR9170_MAC_FTF_PRB_REQ BIT(4) -#define AR9170_MAC_FTF_PRB_RESP BIT(5) -#define AR9170_MAC_FTF_BIT6 BIT(6) -#define AR9170_MAC_FTF_BIT7 BIT(7) -#define AR9170_MAC_FTF_BEACON BIT(8) -#define AR9170_MAC_FTF_ATIM BIT(9) -#define AR9170_MAC_FTF_DEASSOC BIT(10) -#define AR9170_MAC_FTF_AUTH BIT(11) -#define AR9170_MAC_FTF_DEAUTH BIT(12) -#define AR9170_MAC_FTF_BIT13 BIT(13) -#define AR9170_MAC_FTF_BIT14 BIT(14) -#define AR9170_MAC_FTF_BIT15 BIT(15) -#define AR9170_MAC_FTF_BAR BIT(24) -#define AR9170_MAC_FTF_BA BIT(25) -#define AR9170_MAC_FTF_PSPOLL BIT(26) -#define AR9170_MAC_FTF_RTS BIT(27) -#define AR9170_MAC_FTF_CTS BIT(28) -#define AR9170_MAC_FTF_ACK BIT(29) -#define AR9170_MAC_FTF_CFE BIT(30) -#define AR9170_MAC_FTF_CFE_ACK BIT(31) -#define AR9170_MAC_FTF_DEFAULTS 0x0500ffff -#define AR9170_MAC_FTF_MONITOR 0xff00ffff - -#define AR9170_MAC_REG_ACK_EXTENSION (AR9170_MAC_REG_BASE + 0x690) -#define AR9170_MAC_REG_ACK_TPC (AR9170_MAC_REG_BASE + 0x694) -#define AR9170_MAC_REG_EIFS_AND_SIFS (AR9170_MAC_REG_BASE + 0x698) -#define AR9170_MAC_REG_RX_TIMEOUT_COUNT (AR9170_MAC_REG_BASE + 0x69c) -#define AR9170_MAC_REG_RX_TOTAL (AR9170_MAC_REG_BASE + 0x6a0) -#define AR9170_MAC_REG_RX_CRC32 (AR9170_MAC_REG_BASE + 0x6a4) -#define AR9170_MAC_REG_RX_CRC16 (AR9170_MAC_REG_BASE + 0x6a8) -#define AR9170_MAC_REG_RX_ERR_DECRYPTION_UNI (AR9170_MAC_REG_BASE + 0x6ac) -#define AR9170_MAC_REG_RX_OVERRUN (AR9170_MAC_REG_BASE + 0x6b0) -#define AR9170_MAC_REG_RX_ERR_DECRYPTION_MUL (AR9170_MAC_REG_BASE + 0x6bc) -#define AR9170_MAC_REG_TX_BLOCKACKS (AR9170_MAC_REG_BASE + 0x6c0) -#define AR9170_MAC_REG_NAV_COUNT (AR9170_MAC_REG_BASE + 0x6c4) -#define AR9170_MAC_REG_BACKOFF_STATUS (AR9170_MAC_REG_BASE + 0x6c8) -#define AR9170_MAC_BACKOFF_CCA BIT(24) -#define AR9170_MAC_BACKOFF_TX_PEX BIT(25) -#define AR9170_MAC_BACKOFF_RX_PE BIT(26) -#define AR9170_MAC_BACKOFF_MD_READY BIT(27) -#define AR9170_MAC_BACKOFF_TX_PE BIT(28) - -#define AR9170_MAC_REG_TX_RETRY (AR9170_MAC_REG_BASE + 0x6cc) - -#define AR9170_MAC_REG_TX_COMPLETE (AR9170_MAC_REG_BASE + 0x6d4) - -#define AR9170_MAC_REG_CHANNEL_BUSY (AR9170_MAC_REG_BASE + 0x6e8) -#define AR9170_MAC_REG_EXT_BUSY (AR9170_MAC_REG_BASE + 0x6ec) - -#define AR9170_MAC_REG_SLOT_TIME (AR9170_MAC_REG_BASE + 0x6f0) -#define AR9170_MAC_REG_TX_TOTAL (AR9170_MAC_REG_BASE + 0x6f4) -#define AR9170_MAC_REG_ACK_FC (AR9170_MAC_REG_BASE + 0x6f8) - -#define AR9170_MAC_REG_CAM_MODE (AR9170_MAC_REG_BASE + 0x700) -#define AR9170_MAC_CAM_IBSS 0xe0 -#define AR9170_MAC_CAM_AP 0xa1 -#define AR9170_MAC_CAM_STA 0x2 -#define AR9170_MAC_CAM_AP_WDS 0x3 -#define AR9170_MAC_CAM_DEFAULTS (0xf << 24) -#define AR9170_MAC_CAM_HOST_PENDING 0x80000000 - -#define AR9170_MAC_REG_CAM_ROLL_CALL_TBL_L (AR9170_MAC_REG_BASE + 0x704) -#define AR9170_MAC_REG_CAM_ROLL_CALL_TBL_H (AR9170_MAC_REG_BASE + 0x708) - -#define AR9170_MAC_REG_CAM_ADDR (AR9170_MAC_REG_BASE + 0x70c) -#define AR9170_MAC_CAM_ADDR_WRITE 0x80000000 -#define AR9170_MAC_REG_CAM_DATA0 (AR9170_MAC_REG_BASE + 0x720) -#define AR9170_MAC_REG_CAM_DATA1 (AR9170_MAC_REG_BASE + 0x724) -#define AR9170_MAC_REG_CAM_DATA2 (AR9170_MAC_REG_BASE + 0x728) -#define AR9170_MAC_REG_CAM_DATA3 (AR9170_MAC_REG_BASE + 0x72c) - -#define AR9170_MAC_REG_CAM_DBG0 (AR9170_MAC_REG_BASE + 0x730) -#define AR9170_MAC_REG_CAM_DBG1 (AR9170_MAC_REG_BASE + 0x734) -#define AR9170_MAC_REG_CAM_DBG2 (AR9170_MAC_REG_BASE + 0x738) -#define AR9170_MAC_REG_CAM_STATE (AR9170_MAC_REG_BASE + 0x73c) -#define AR9170_MAC_CAM_STATE_READ_PENDING 0x40000000 -#define AR9170_MAC_CAM_STATE_WRITE_PENDING 0x80000000 - -#define AR9170_MAC_REG_CAM_TXKEY (AR9170_MAC_REG_BASE + 0x740) -#define AR9170_MAC_REG_CAM_RXKEY (AR9170_MAC_REG_BASE + 0x750) - -#define AR9170_MAC_REG_CAM_TX_ENC_TYPE (AR9170_MAC_REG_BASE + 0x760) -#define AR9170_MAC_REG_CAM_RX_ENC_TYPE (AR9170_MAC_REG_BASE + 0x770) -#define AR9170_MAC_REG_CAM_TX_SERACH_HIT (AR9170_MAC_REG_BASE + 0x780) -#define AR9170_MAC_REG_CAM_RX_SERACH_HIT (AR9170_MAC_REG_BASE + 0x790) - -#define AR9170_MAC_REG_AC0_CW (AR9170_MAC_REG_BASE + 0xb00) -#define AR9170_MAC_REG_AC1_CW (AR9170_MAC_REG_BASE + 0xb04) -#define AR9170_MAC_REG_AC2_CW (AR9170_MAC_REG_BASE + 0xb08) -#define AR9170_MAC_REG_AC3_CW (AR9170_MAC_REG_BASE + 0xb0c) -#define AR9170_MAC_REG_AC4_CW (AR9170_MAC_REG_BASE + 0xb10) -#define AR9170_MAC_REG_AC2_AC1_AC0_AIFS (AR9170_MAC_REG_BASE + 0xb14) -#define AR9170_MAC_REG_AC4_AC3_AC2_AIFS (AR9170_MAC_REG_BASE + 0xb18) -#define AR9170_MAC_REG_TXOP_ACK_EXTENSION (AR9170_MAC_REG_BASE + 0xb1c) -#define AR9170_MAC_REG_TXOP_ACK_INTERVAL (AR9170_MAC_REG_BASE + 0xb20) -#define AR9170_MAC_REG_CONTENTION_POINT (AR9170_MAC_REG_BASE + 0xb24) -#define AR9170_MAC_REG_RETRY_MAX (AR9170_MAC_REG_BASE + 0xb28) -#define AR9170_MAC_REG_TID_CFACK_CFEND_RATE (AR9170_MAC_REG_BASE + 0xb2c) -#define AR9170_MAC_REG_TXOP_NOT_ENOUGH_IND (AR9170_MAC_REG_BASE + 0xb30) -#define AR9170_MAC_REG_TKIP_TSC (AR9170_MAC_REG_BASE + 0xb34) -#define AR9170_MAC_REG_TXOP_DURATION (AR9170_MAC_REG_BASE + 0xb38) -#define AR9170_MAC_REG_TX_QOS_THRESHOLD (AR9170_MAC_REG_BASE + 0xb3c) -#define AR9170_MAC_REG_QOS_PRIORITY_VIRTUAL_CCA (AR9170_MAC_REG_BASE + 0xb40) -#define AR9170_MAC_VIRTUAL_CCA_Q0 BIT(15) -#define AR9170_MAC_VIRTUAL_CCA_Q1 BIT(16) -#define AR9170_MAC_VIRTUAL_CCA_Q2 BIT(17) -#define AR9170_MAC_VIRTUAL_CCA_Q3 BIT(18) -#define AR9170_MAC_VIRTUAL_CCA_Q4 BIT(19) -#define AR9170_MAC_VIRTUAL_CCA_ALL (0xf8000) - -#define AR9170_MAC_REG_AC1_AC0_TXOP (AR9170_MAC_REG_BASE + 0xb44) -#define AR9170_MAC_REG_AC3_AC2_TXOP (AR9170_MAC_REG_BASE + 0xb48) - -#define AR9170_MAC_REG_AMPDU_COUNT (AR9170_MAC_REG_BASE + 0xb88) -#define AR9170_MAC_REG_MPDU_COUNT (AR9170_MAC_REG_BASE + 0xb8c) - -#define AR9170_MAC_REG_AMPDU_FACTOR (AR9170_MAC_REG_BASE + 0xb9c) -#define AR9170_MAC_AMPDU_FACTOR 0x7f0000 -#define AR9170_MAC_AMPDU_FACTOR_S 16 -#define AR9170_MAC_REG_AMPDU_DENSITY (AR9170_MAC_REG_BASE + 0xba0) -#define AR9170_MAC_AMPDU_DENSITY 0x7 -#define AR9170_MAC_AMPDU_DENSITY_S 0 - -#define AR9170_MAC_REG_FCS_SELECT (AR9170_MAC_REG_BASE + 0xbb0) -#define AR9170_MAC_FCS_SWFCS 0x1 -#define AR9170_MAC_FCS_FIFO_PROT 0x4 - -#define AR9170_MAC_REG_RTS_CTS_TPC (AR9170_MAC_REG_BASE + 0xbb4) -#define AR9170_MAC_REG_CFEND_QOSNULL_TPC (AR9170_MAC_REG_BASE + 0xbb8) - -#define AR9170_MAC_REG_ACK_TABLE (AR9170_MAC_REG_BASE + 0xc00) -#define AR9170_MAC_REG_RX_CONTROL (AR9170_MAC_REG_BASE + 0xc40) -#define AR9170_MAC_RX_CTRL_DEAGG 0x1 -#define AR9170_MAC_RX_CTRL_SHORT_FILTER 0x2 -#define AR9170_MAC_RX_CTRL_SA_DA_SEARCH 0x20 -#define AR9170_MAC_RX_CTRL_PASS_TO_HOST BIT(28) -#define AR9170_MAC_RX_CTRL_ACK_IN_SNIFFER BIT(30) - -#define AR9170_MAC_REG_RX_CONTROL_1 (AR9170_MAC_REG_BASE + 0xc44) - -#define AR9170_MAC_REG_AMPDU_RX_THRESH (AR9170_MAC_REG_BASE + 0xc50) - -#define AR9170_MAC_REG_RX_MPDU (AR9170_MAC_REG_BASE + 0xca0) -#define AR9170_MAC_REG_RX_DROPPED_MPDU (AR9170_MAC_REG_BASE + 0xca4) -#define AR9170_MAC_REG_RX_DEL_MPDU (AR9170_MAC_REG_BASE + 0xca8) -#define AR9170_MAC_REG_RX_PHY_MISC_ERROR (AR9170_MAC_REG_BASE + 0xcac) -#define AR9170_MAC_REG_RX_PHY_XR_ERROR (AR9170_MAC_REG_BASE + 0xcb0) -#define AR9170_MAC_REG_RX_PHY_OFDM_ERROR (AR9170_MAC_REG_BASE + 0xcb4) -#define AR9170_MAC_REG_RX_PHY_CCK_ERROR (AR9170_MAC_REG_BASE + 0xcb8) -#define AR9170_MAC_REG_RX_PHY_HT_ERROR (AR9170_MAC_REG_BASE + 0xcbc) -#define AR9170_MAC_REG_RX_PHY_TOTAL (AR9170_MAC_REG_BASE + 0xcc0) - -#define AR9170_MAC_REG_DMA_TXQ_ADDR (AR9170_MAC_REG_BASE + 0xd00) -#define AR9170_MAC_REG_DMA_TXQ_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd04) -#define AR9170_MAC_REG_DMA_TXQ0_ADDR (AR9170_MAC_REG_BASE + 0xd00) -#define AR9170_MAC_REG_DMA_TXQ0_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd04) -#define AR9170_MAC_REG_DMA_TXQ1_ADDR (AR9170_MAC_REG_BASE + 0xd08) -#define AR9170_MAC_REG_DMA_TXQ1_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd0c) -#define AR9170_MAC_REG_DMA_TXQ2_ADDR (AR9170_MAC_REG_BASE + 0xd10) -#define AR9170_MAC_REG_DMA_TXQ2_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd14) -#define AR9170_MAC_REG_DMA_TXQ3_ADDR (AR9170_MAC_REG_BASE + 0xd18) -#define AR9170_MAC_REG_DMA_TXQ3_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd1c) -#define AR9170_MAC_REG_DMA_TXQ4_ADDR (AR9170_MAC_REG_BASE + 0xd20) -#define AR9170_MAC_REG_DMA_TXQ4_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd24) -#define AR9170_MAC_REG_DMA_RXQ_ADDR (AR9170_MAC_REG_BASE + 0xd28) -#define AR9170_MAC_REG_DMA_RXQ_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd2c) - -#define AR9170_MAC_REG_DMA_TRIGGER (AR9170_MAC_REG_BASE + 0xd30) -#define AR9170_DMA_TRIGGER_TXQ0 BIT(0) -#define AR9170_DMA_TRIGGER_TXQ1 BIT(1) -#define AR9170_DMA_TRIGGER_TXQ2 BIT(2) -#define AR9170_DMA_TRIGGER_TXQ3 BIT(3) -#define AR9170_DMA_TRIGGER_TXQ4 BIT(4) -#define AR9170_DMA_TRIGGER_RXQ BIT(8) - -#define AR9170_MAC_REG_DMA_WLAN_STATUS (AR9170_MAC_REG_BASE + 0xd38) -#define AR9170_MAC_REG_DMA_STATUS (AR9170_MAC_REG_BASE + 0xd3c) -#define AR9170_MAC_REG_DMA_TXQ_LAST_ADDR (AR9170_MAC_REG_BASE + 0xd40) -#define AR9170_MAC_REG_DMA_TXQ0_LAST_ADDR (AR9170_MAC_REG_BASE + 0xd40) -#define AR9170_MAC_REG_DMA_TXQ1_LAST_ADDR (AR9170_MAC_REG_BASE + 0xd44) -#define AR9170_MAC_REG_DMA_TXQ2_LAST_ADDR (AR9170_MAC_REG_BASE + 0xd48) -#define AR9170_MAC_REG_DMA_TXQ3_LAST_ADDR (AR9170_MAC_REG_BASE + 0xd4c) -#define AR9170_MAC_REG_DMA_TXQ4_LAST_ADDR (AR9170_MAC_REG_BASE + 0xd50) -#define AR9170_MAC_REG_DMA_TXQ0Q1_LEN (AR9170_MAC_REG_BASE + 0xd54) -#define AR9170_MAC_REG_DMA_TXQ2Q3_LEN (AR9170_MAC_REG_BASE + 0xd58) -#define AR9170_MAC_REG_DMA_TXQ4_LEN (AR9170_MAC_REG_BASE + 0xd5c) - -#define AR9170_MAC_REG_DMA_TXQX_LAST_ADDR (AR9170_MAC_REG_BASE + 0xd74) -#define AR9170_MAC_REG_DMA_TXQX_FAIL_ADDR (AR9170_MAC_REG_BASE + 0xd78) -#define AR9170_MAC_REG_TXRX_MPI (AR9170_MAC_REG_BASE + 0xd7c) -#define AR9170_MAC_TXRX_MPI_TX_MPI_MASK 0x0000000f -#define AR9170_MAC_TXRX_MPI_TX_TO_MASK 0x0000fff0 -#define AR9170_MAC_TXRX_MPI_RX_MPI_MASK 0x000f0000 -#define AR9170_MAC_TXRX_MPI_RX_TO_MASK 0xfff00000 - -#define AR9170_MAC_REG_BCN_ADDR (AR9170_MAC_REG_BASE + 0xd84) -#define AR9170_MAC_REG_BCN_LENGTH (AR9170_MAC_REG_BASE + 0xd88) -#define AR9170_MAC_BCN_LENGTH_MAX 256 - -#define AR9170_MAC_REG_BCN_STATUS (AR9170_MAC_REG_BASE + 0xd8c) - -#define AR9170_MAC_REG_BCN_PLCP (AR9170_MAC_REG_BASE + 0xd90) -#define AR9170_MAC_REG_BCN_CTRL (AR9170_MAC_REG_BASE + 0xd94) -#define AR9170_BCN_CTRL_READY 0x01 -#define AR9170_BCN_CTRL_LOCK 0x02 - -#define AR9170_MAC_REG_BCN_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd98) -#define AR9170_MAC_REG_BCN_COUNT (AR9170_MAC_REG_BASE + 0xd9c) -#define AR9170_MAC_REG_BCN_HT1 (AR9170_MAC_REG_BASE + 0xda0) -#define AR9170_MAC_BCN_HT1_HT_EN BIT(0) -#define AR9170_MAC_BCN_HT1_GF_PMB BIT(1) -#define AR9170_MAC_BCN_HT1_SP_EXP BIT(2) -#define AR9170_MAC_BCN_HT1_TX_BF BIT(3) -#define AR9170_MAC_BCN_HT1_PWR_CTRL_S 4 -#define AR9170_MAC_BCN_HT1_PWR_CTRL 0x70 -#define AR9170_MAC_BCN_HT1_TX_ANT1 BIT(7) -#define AR9170_MAC_BCN_HT1_TX_ANT0 BIT(8) -#define AR9170_MAC_BCN_HT1_NUM_LFT_S 9 -#define AR9170_MAC_BCN_HT1_NUM_LFT 0x600 -#define AR9170_MAC_BCN_HT1_BWC_20M_EXT BIT(16) -#define AR9170_MAC_BCN_HT1_BWC_40M_SHARED BIT(17) -#define AR9170_MAC_BCN_HT1_BWC_40M_DUP (BIT(16) | BIT(17)) -#define AR9170_MAC_BCN_HT1_BF_MCS_S 18 -#define AR9170_MAC_BCN_HT1_BF_MCS 0x1c0000 -#define AR9170_MAC_BCN_HT1_TPC_S 21 -#define AR9170_MAC_BCN_HT1_TPC 0x7e00000 -#define AR9170_MAC_BCN_HT1_CHAIN_MASK_S 27 -#define AR9170_MAC_BCN_HT1_CHAIN_MASK 0x38000000 - -#define AR9170_MAC_REG_BCN_HT2 (AR9170_MAC_REG_BASE + 0xda4) -#define AR9170_MAC_BCN_HT2_MCS_S 0 -#define AR9170_MAC_BCN_HT2_MCS 0x7f -#define AR9170_MAC_BCN_HT2_BW40 BIT(8) -#define AR9170_MAC_BCN_HT2_SMOOTHING BIT(9) -#define AR9170_MAC_BCN_HT2_SS BIT(10) -#define AR9170_MAC_BCN_HT2_NSS BIT(11) -#define AR9170_MAC_BCN_HT2_STBC_S 12 -#define AR9170_MAC_BCN_HT2_STBC 0x3000 -#define AR9170_MAC_BCN_HT2_ADV_COD BIT(14) -#define AR9170_MAC_BCN_HT2_SGI BIT(15) -#define AR9170_MAC_BCN_HT2_LEN_S 16 -#define AR9170_MAC_BCN_HT2_LEN 0xffff0000 - -#define AR9170_MAC_REG_DMA_TXQX_ADDR_CURR (AR9170_MAC_REG_BASE + 0xdc0) - -/* Random number generator */ -#define AR9170_RAND_REG_BASE 0x1d0000 - -#define AR9170_RAND_REG_NUM (AR9170_RAND_REG_BASE + 0x000) -#define AR9170_RAND_REG_MODE (AR9170_RAND_REG_BASE + 0x004) -#define AR9170_RAND_MODE_MANUAL 0x000 -#define AR9170_RAND_MODE_FREE 0x001 - -/* GPIO */ -#define AR9170_GPIO_REG_BASE 0x1d0100 -#define AR9170_GPIO_REG_PORT_TYPE (AR9170_GPIO_REG_BASE + 0x000) -#define AR9170_GPIO_REG_PORT_DATA (AR9170_GPIO_REG_BASE + 0x004) -#define AR9170_GPIO_PORT_LED_0 1 -#define AR9170_GPIO_PORT_LED_1 2 -/* WPS Button GPIO for TP-Link TL-WN821N */ -#define AR9170_GPIO_PORT_WPS_BUTTON_PRESSED 4 - -/* Memory Controller */ -#define AR9170_MC_REG_BASE 0x1d1000 - -#define AR9170_MC_REG_FLASH_WAIT_STATE (AR9170_MC_REG_BASE + 0x000) -#define AR9170_MC_REG_SEEPROM_WP0 (AR9170_MC_REG_BASE + 0x400) -#define AR9170_MC_REG_SEEPROM_WP1 (AR9170_MC_REG_BASE + 0x404) -#define AR9170_MC_REG_SEEPROM_WP2 (AR9170_MC_REG_BASE + 0x408) - -/* Interrupt Controller */ -#define AR9170_MAX_INT_SRC 9 -#define AR9170_INT_REG_BASE 0x1d2000 - -#define AR9170_INT_REG_FLAG (AR9170_INT_REG_BASE + 0x000) -#define AR9170_INT_REG_FIQ_MASK (AR9170_INT_REG_BASE + 0x004) -#define AR9170_INT_REG_IRQ_MASK (AR9170_INT_REG_BASE + 0x008) -/* INT_REG_FLAG, INT_REG_FIQ_MASK and INT_REG_IRQ_MASK */ -#define AR9170_INT_FLAG_WLAN 0x001 -#define AR9170_INT_FLAG_PTAB_BIT 0x002 -#define AR9170_INT_FLAG_SE_BIT 0x004 -#define AR9170_INT_FLAG_UART_BIT 0x008 -#define AR9170_INT_FLAG_TIMER_BIT 0x010 -#define AR9170_INT_FLAG_EXT_BIT 0x020 -#define AR9170_INT_FLAG_SW_BIT 0x040 -#define AR9170_INT_FLAG_USB_BIT 0x080 -#define AR9170_INT_FLAG_ETHERNET_BIT 0x100 - -#define AR9170_INT_REG_PRIORITY1 (AR9170_INT_REG_BASE + 0x00c) -#define AR9170_INT_REG_PRIORITY2 (AR9170_INT_REG_BASE + 0x010) -#define AR9170_INT_REG_PRIORITY3 (AR9170_INT_REG_BASE + 0x014) -#define AR9170_INT_REG_EXT_INT_CONTROL (AR9170_INT_REG_BASE + 0x018) -#define AR9170_INT_REG_SW_INT_CONTROL (AR9170_INT_REG_BASE + 0x01c) -#define AR9170_INT_SW_INT_ENABLE 0x1 - -#define AR9170_INT_REG_FIQ_ENCODE (AR9170_INT_REG_BASE + 0x020) -#define AR9170_INT_INT_IRQ_ENCODE (AR9170_INT_REG_BASE + 0x024) - -/* Power Management */ -#define AR9170_PWR_REG_BASE 0x1d4000 - -#define AR9170_PWR_REG_POWER_STATE (AR9170_PWR_REG_BASE + 0x000) - -#define AR9170_PWR_REG_RESET (AR9170_PWR_REG_BASE + 0x004) -#define AR9170_PWR_RESET_COMMIT_RESET_MASK BIT(0) -#define AR9170_PWR_RESET_WLAN_MASK BIT(1) -#define AR9170_PWR_RESET_DMA_MASK BIT(2) -#define AR9170_PWR_RESET_BRIDGE_MASK BIT(3) -#define AR9170_PWR_RESET_AHB_MASK BIT(9) -#define AR9170_PWR_RESET_BB_WARM_RESET BIT(10) -#define AR9170_PWR_RESET_BB_COLD_RESET BIT(11) -#define AR9170_PWR_RESET_ADDA_CLK_COLD_RESET BIT(12) -#define AR9170_PWR_RESET_PLL BIT(13) -#define AR9170_PWR_RESET_USB_PLL BIT(14) - -#define AR9170_PWR_REG_CLOCK_SEL (AR9170_PWR_REG_BASE + 0x008) -#define AR9170_PWR_CLK_AHB_40MHZ 0 -#define AR9170_PWR_CLK_AHB_20_22MHZ 1 -#define AR9170_PWR_CLK_AHB_40_44MHZ 2 -#define AR9170_PWR_CLK_AHB_80_88MHZ 3 -#define AR9170_PWR_CLK_DAC_160_INV_DLY 0x70 - -#define AR9170_PWR_REG_CHIP_REVISION (AR9170_PWR_REG_BASE + 0x010) -#define AR9170_PWR_REG_PLL_ADDAC (AR9170_PWR_REG_BASE + 0x014) -#define AR9170_PWR_PLL_ADDAC_DIV_S 2 -#define AR9170_PWR_PLL_ADDAC_DIV 0xffc -#define AR9170_PWR_REG_WATCH_DOG_MAGIC (AR9170_PWR_REG_BASE + 0x020) - -/* Faraday USB Controller */ -#define AR9170_USB_REG_BASE 0x1e1000 - -#define AR9170_USB_REG_MAIN_CTRL (AR9170_USB_REG_BASE + 0x000) -#define AR9170_USB_MAIN_CTRL_REMOTE_WAKEUP BIT(0) -#define AR9170_USB_MAIN_CTRL_ENABLE_GLOBAL_INT BIT(2) -#define AR9170_USB_MAIN_CTRL_GO_TO_SUSPEND BIT(3) -#define AR9170_USB_MAIN_CTRL_RESET BIT(4) -#define AR9170_USB_MAIN_CTRL_CHIP_ENABLE BIT(5) -#define AR9170_USB_MAIN_CTRL_HIGHSPEED BIT(6) - -#define AR9170_USB_REG_DEVICE_ADDRESS (AR9170_USB_REG_BASE + 0x001) -#define AR9170_USB_DEVICE_ADDRESS_CONFIGURE BIT(7) - -#define AR9170_USB_REG_TEST (AR9170_USB_REG_BASE + 0x002) -#define AR9170_USB_REG_PHY_TEST_SELECT (AR9170_USB_REG_BASE + 0x008) -#define AR9170_USB_REG_CX_CONFIG_STATUS (AR9170_USB_REG_BASE + 0x00b) -#define AR9170_USB_REG_EP0_DATA (AR9170_USB_REG_BASE + 0x00c) -#define AR9170_USB_REG_EP0_DATA1 (AR9170_USB_REG_BASE + 0x00c) -#define AR9170_USB_REG_EP0_DATA2 (AR9170_USB_REG_BASE + 0x00d) - -#define AR9170_USB_REG_INTR_MASK_BYTE_0 (AR9170_USB_REG_BASE + 0x011) -#define AR9170_USB_REG_INTR_MASK_BYTE_1 (AR9170_USB_REG_BASE + 0x012) -#define AR9170_USB_REG_INTR_MASK_BYTE_2 (AR9170_USB_REG_BASE + 0x013) -#define AR9170_USB_REG_INTR_MASK_BYTE_3 (AR9170_USB_REG_BASE + 0x014) -#define AR9170_USB_REG_INTR_MASK_BYTE_4 (AR9170_USB_REG_BASE + 0x015) -#define AR9170_USB_INTR_DISABLE_OUT_INT (BIT(7) | BIT(6)) - -#define AR9170_USB_REG_INTR_MASK_BYTE_5 (AR9170_USB_REG_BASE + 0x016) -#define AR9170_USB_REG_INTR_MASK_BYTE_6 (AR9170_USB_REG_BASE + 0x017) -#define AR9170_USB_INTR_DISABLE_IN_INT BIT(6) - -#define AR9170_USB_REG_INTR_MASK_BYTE_7 (AR9170_USB_REG_BASE + 0x018) - -#define AR9170_USB_REG_INTR_GROUP (AR9170_USB_REG_BASE + 0x020) - -#define AR9170_USB_REG_INTR_SOURCE_0 (AR9170_USB_REG_BASE + 0x021) -#define AR9170_USB_INTR_SRC0_SETUP BIT(0) -#define AR9170_USB_INTR_SRC0_IN BIT(1) -#define AR9170_USB_INTR_SRC0_OUT BIT(2) -#define AR9170_USB_INTR_SRC0_FAIL BIT(3) /* ??? */ -#define AR9170_USB_INTR_SRC0_END BIT(4) /* ??? */ -#define AR9170_USB_INTR_SRC0_ABORT BIT(7) - -#define AR9170_USB_REG_INTR_SOURCE_1 (AR9170_USB_REG_BASE + 0x022) -#define AR9170_USB_REG_INTR_SOURCE_2 (AR9170_USB_REG_BASE + 0x023) -#define AR9170_USB_REG_INTR_SOURCE_3 (AR9170_USB_REG_BASE + 0x024) -#define AR9170_USB_REG_INTR_SOURCE_4 (AR9170_USB_REG_BASE + 0x025) -#define AR9170_USB_REG_INTR_SOURCE_5 (AR9170_USB_REG_BASE + 0x026) -#define AR9170_USB_REG_INTR_SOURCE_6 (AR9170_USB_REG_BASE + 0x027) -#define AR9170_USB_REG_INTR_SOURCE_7 (AR9170_USB_REG_BASE + 0x028) -#define AR9170_USB_INTR_SRC7_USB_RESET BIT(1) -#define AR9170_USB_INTR_SRC7_USB_SUSPEND BIT(2) -#define AR9170_USB_INTR_SRC7_USB_RESUME BIT(3) -#define AR9170_USB_INTR_SRC7_ISO_SEQ_ERR BIT(4) -#define AR9170_USB_INTR_SRC7_ISO_SEQ_ABORT BIT(5) -#define AR9170_USB_INTR_SRC7_TX0BYTE BIT(6) -#define AR9170_USB_INTR_SRC7_RX0BYTE BIT(7) - -#define AR9170_USB_REG_IDLE_COUNT (AR9170_USB_REG_BASE + 0x02f) - -#define AR9170_USB_REG_EP_MAP (AR9170_USB_REG_BASE + 0x030) -#define AR9170_USB_REG_EP1_MAP (AR9170_USB_REG_BASE + 0x030) -#define AR9170_USB_REG_EP2_MAP (AR9170_USB_REG_BASE + 0x031) -#define AR9170_USB_REG_EP3_MAP (AR9170_USB_REG_BASE + 0x032) -#define AR9170_USB_REG_EP4_MAP (AR9170_USB_REG_BASE + 0x033) -#define AR9170_USB_REG_EP5_MAP (AR9170_USB_REG_BASE + 0x034) -#define AR9170_USB_REG_EP6_MAP (AR9170_USB_REG_BASE + 0x035) -#define AR9170_USB_REG_EP7_MAP (AR9170_USB_REG_BASE + 0x036) -#define AR9170_USB_REG_EP8_MAP (AR9170_USB_REG_BASE + 0x037) -#define AR9170_USB_REG_EP9_MAP (AR9170_USB_REG_BASE + 0x038) -#define AR9170_USB_REG_EP10_MAP (AR9170_USB_REG_BASE + 0x039) - -#define AR9170_USB_REG_EP_IN_MAX_SIZE_HIGH (AR9170_USB_REG_BASE + 0x03f) -#define AR9170_USB_EP_IN_TOGGLE 0x10 - -#define AR9170_USB_REG_EP_IN_MAX_SIZE_LOW (AR9170_USB_REG_BASE + 0x03e) - -#define AR9170_USB_REG_EP_OUT_MAX_SIZE_HIGH (AR9170_USB_REG_BASE + 0x05f) -#define AR9170_USB_EP_OUT_TOGGLE 0x10 - -#define AR9170_USB_REG_EP_OUT_MAX_SIZE_LOW (AR9170_USB_REG_BASE + 0x05e) - -#define AR9170_USB_REG_EP3_BYTE_COUNT_HIGH (AR9170_USB_REG_BASE + 0x0ae) -#define AR9170_USB_REG_EP3_BYTE_COUNT_LOW (AR9170_USB_REG_BASE + 0x0be) -#define AR9170_USB_REG_EP4_BYTE_COUNT_HIGH (AR9170_USB_REG_BASE + 0x0af) -#define AR9170_USB_REG_EP4_BYTE_COUNT_LOW (AR9170_USB_REG_BASE + 0x0bf) - -#define AR9170_USB_REG_FIFO_MAP (AR9170_USB_REG_BASE + 0x080) -#define AR9170_USB_REG_FIFO0_MAP (AR9170_USB_REG_BASE + 0x080) -#define AR9170_USB_REG_FIFO1_MAP (AR9170_USB_REG_BASE + 0x081) -#define AR9170_USB_REG_FIFO2_MAP (AR9170_USB_REG_BASE + 0x082) -#define AR9170_USB_REG_FIFO3_MAP (AR9170_USB_REG_BASE + 0x083) -#define AR9170_USB_REG_FIFO4_MAP (AR9170_USB_REG_BASE + 0x084) -#define AR9170_USB_REG_FIFO5_MAP (AR9170_USB_REG_BASE + 0x085) -#define AR9170_USB_REG_FIFO6_MAP (AR9170_USB_REG_BASE + 0x086) -#define AR9170_USB_REG_FIFO7_MAP (AR9170_USB_REG_BASE + 0x087) -#define AR9170_USB_REG_FIFO8_MAP (AR9170_USB_REG_BASE + 0x088) -#define AR9170_USB_REG_FIFO9_MAP (AR9170_USB_REG_BASE + 0x089) - -#define AR9170_USB_REG_FIFO_CONFIG (AR9170_USB_REG_BASE + 0x090) -#define AR9170_USB_REG_FIFO0_CONFIG (AR9170_USB_REG_BASE + 0x090) -#define AR9170_USB_REG_FIFO1_CONFIG (AR9170_USB_REG_BASE + 0x091) -#define AR9170_USB_REG_FIFO2_CONFIG (AR9170_USB_REG_BASE + 0x092) -#define AR9170_USB_REG_FIFO3_CONFIG (AR9170_USB_REG_BASE + 0x093) -#define AR9170_USB_REG_FIFO4_CONFIG (AR9170_USB_REG_BASE + 0x094) -#define AR9170_USB_REG_FIFO5_CONFIG (AR9170_USB_REG_BASE + 0x095) -#define AR9170_USB_REG_FIFO6_CONFIG (AR9170_USB_REG_BASE + 0x096) -#define AR9170_USB_REG_FIFO7_CONFIG (AR9170_USB_REG_BASE + 0x097) -#define AR9170_USB_REG_FIFO8_CONFIG (AR9170_USB_REG_BASE + 0x098) -#define AR9170_USB_REG_FIFO9_CONFIG (AR9170_USB_REG_BASE + 0x099) - -#define AR9170_USB_REG_EP3_DATA (AR9170_USB_REG_BASE + 0x0f8) -#define AR9170_USB_REG_EP4_DATA (AR9170_USB_REG_BASE + 0x0fc) - -#define AR9170_USB_REG_FIFO_SIZE (AR9170_USB_REG_BASE + 0x100) -#define AR9170_USB_REG_DMA_CTL (AR9170_USB_REG_BASE + 0x108) -#define AR9170_USB_DMA_CTL_ENABLE_TO_DEVICE BIT(0) -#define AR9170_USB_DMA_CTL_ENABLE_FROM_DEVICE BIT(1) -#define AR9170_USB_DMA_CTL_HIGH_SPEED BIT(2) -#define AR9170_USB_DMA_CTL_UP_PACKET_MODE BIT(3) -#define AR9170_USB_DMA_CTL_UP_STREAM_S 4 -#define AR9170_USB_DMA_CTL_UP_STREAM (BIT(4) | BIT(5)) -#define AR9170_USB_DMA_CTL_UP_STREAM_4K (0) -#define AR9170_USB_DMA_CTL_UP_STREAM_8K BIT(4) -#define AR9170_USB_DMA_CTL_UP_STREAM_16K BIT(5) -#define AR9170_USB_DMA_CTL_UP_STREAM_32K (BIT(4) | BIT(5)) -#define AR9170_USB_DMA_CTL_DOWN_STREAM BIT(6) - -#define AR9170_USB_REG_DMA_STATUS (AR9170_USB_REG_BASE + 0x10c) -#define AR9170_USB_DMA_STATUS_UP_IDLE BIT(8) -#define AR9170_USB_DMA_STATUS_DN_IDLE BIT(16) - -#define AR9170_USB_REG_MAX_AGG_UPLOAD (AR9170_USB_REG_BASE + 0x110) -#define AR9170_USB_REG_UPLOAD_TIME_CTL (AR9170_USB_REG_BASE + 0x114) - -#define AR9170_USB_REG_WAKE_UP (AR9170_USB_REG_BASE + 0x120) -#define AR9170_USB_WAKE_UP_WAKE BIT(0) - -#define AR9170_USB_REG_CBUS_CTRL (AR9170_USB_REG_BASE + 0x1f0) -#define AR9170_USB_CBUS_CTRL_BUFFER_END (BIT(1)) - -/* PCI/USB to AHB Bridge */ -#define AR9170_PTA_REG_BASE 0x1e2000 - -#define AR9170_PTA_REG_CMD (AR9170_PTA_REG_BASE + 0x000) -#define AR9170_PTA_REG_PARAM1 (AR9170_PTA_REG_BASE + 0x004) -#define AR9170_PTA_REG_PARAM2 (AR9170_PTA_REG_BASE + 0x008) -#define AR9170_PTA_REG_PARAM3 (AR9170_PTA_REG_BASE + 0x00c) -#define AR9170_PTA_REG_RSP (AR9170_PTA_REG_BASE + 0x010) -#define AR9170_PTA_REG_STATUS1 (AR9170_PTA_REG_BASE + 0x014) -#define AR9170_PTA_REG_STATUS2 (AR9170_PTA_REG_BASE + 0x018) -#define AR9170_PTA_REG_STATUS3 (AR9170_PTA_REG_BASE + 0x01c) -#define AR9170_PTA_REG_AHB_INT_FLAG (AR9170_PTA_REG_BASE + 0x020) -#define AR9170_PTA_REG_AHB_INT_MASK (AR9170_PTA_REG_BASE + 0x024) -#define AR9170_PTA_REG_AHB_INT_ACK (AR9170_PTA_REG_BASE + 0x028) -#define AR9170_PTA_REG_AHB_SCRATCH1 (AR9170_PTA_REG_BASE + 0x030) -#define AR9170_PTA_REG_AHB_SCRATCH2 (AR9170_PTA_REG_BASE + 0x034) -#define AR9170_PTA_REG_AHB_SCRATCH3 (AR9170_PTA_REG_BASE + 0x038) -#define AR9170_PTA_REG_AHB_SCRATCH4 (AR9170_PTA_REG_BASE + 0x03c) - -#define AR9170_PTA_REG_SHARE_MEM_CTRL (AR9170_PTA_REG_BASE + 0x124) - -/* - * PCI to AHB Bridge - */ - -#define AR9170_PTA_REG_INT_FLAG (AR9170_PTA_REG_BASE + 0x100) -#define AR9170_PTA_INT_FLAG_DN 0x01 -#define AR9170_PTA_INT_FLAG_UP 0x02 -#define AR9170_PTA_INT_FLAG_CMD 0x04 - -#define AR9170_PTA_REG_INT_MASK (AR9170_PTA_REG_BASE + 0x104) -#define AR9170_PTA_REG_DN_DMA_ADDRL (AR9170_PTA_REG_BASE + 0x108) -#define AR9170_PTA_REG_DN_DMA_ADDRH (AR9170_PTA_REG_BASE + 0x10c) -#define AR9170_PTA_REG_UP_DMA_ADDRL (AR9170_PTA_REG_BASE + 0x110) -#define AR9170_PTA_REG_UP_DMA_ADDRH (AR9170_PTA_REG_BASE + 0x114) -#define AR9170_PTA_REG_DN_PEND_TIME (AR9170_PTA_REG_BASE + 0x118) -#define AR9170_PTA_REG_UP_PEND_TIME (AR9170_PTA_REG_BASE + 0x11c) -#define AR9170_PTA_REG_CONTROL (AR9170_PTA_REG_BASE + 0x120) -#define AR9170_PTA_CTRL_4_BEAT_BURST 0x00 -#define AR9170_PTA_CTRL_8_BEAT_BURST 0x01 -#define AR9170_PTA_CTRL_16_BEAT_BURST 0x02 -#define AR9170_PTA_CTRL_LOOPBACK_MODE 0x10 - -#define AR9170_PTA_REG_MEM_CTRL (AR9170_PTA_REG_BASE + 0x124) -#define AR9170_PTA_REG_MEM_ADDR (AR9170_PTA_REG_BASE + 0x128) -#define AR9170_PTA_REG_DN_DMA_TRIGGER (AR9170_PTA_REG_BASE + 0x12c) -#define AR9170_PTA_REG_UP_DMA_TRIGGER (AR9170_PTA_REG_BASE + 0x130) -#define AR9170_PTA_REG_DMA_STATUS (AR9170_PTA_REG_BASE + 0x134) -#define AR9170_PTA_REG_DN_CURR_ADDRL (AR9170_PTA_REG_BASE + 0x138) -#define AR9170_PTA_REG_DN_CURR_ADDRH (AR9170_PTA_REG_BASE + 0x13c) -#define AR9170_PTA_REG_UP_CURR_ADDRL (AR9170_PTA_REG_BASE + 0x140) -#define AR9170_PTA_REG_UP_CURR_ADDRH (AR9170_PTA_REG_BASE + 0x144) -#define AR9170_PTA_REG_DMA_MODE_CTRL (AR9170_PTA_REG_BASE + 0x148) -#define AR9170_PTA_DMA_MODE_CTRL_RESET BIT(0) -#define AR9170_PTA_DMA_MODE_CTRL_DISABLE_USB BIT(1) - -/* Protocol Controller Module */ -#define AR9170_MAC_REG_PC_REG_BASE (AR9170_MAC_REG_BASE + 0xe00) - - -#define AR9170_NUM_LEDS 2 - -/* CAM */ -#define AR9170_CAM_MAX_USER 64 -#define AR9170_CAM_MAX_KEY_LENGTH 16 - -#define AR9170_SRAM_OFFSET 0x100000 -#define AR9170_SRAM_SIZE 0x18000 - -#define AR9170_PRAM_OFFSET 0x200000 -#define AR9170_PRAM_SIZE 0x8000 - -enum cpu_clock { - AHB_STATIC_40MHZ = 0, - AHB_GMODE_22MHZ = 1, - AHB_AMODE_20MHZ = 1, - AHB_GMODE_44MHZ = 2, - AHB_AMODE_40MHZ = 2, - AHB_GMODE_88MHZ = 3, - AHB_AMODE_80MHZ = 3 -}; - -/* USB endpoints */ -enum ar9170_usb_ep { - /* - * Control EP is always EP 0 (USB SPEC) - * - * The weird thing is: the original firmware has a few - * comments that suggest that the actual EP numbers - * are in the 1 to 10 range?! - */ - AR9170_USB_EP_CTRL = 0, - - AR9170_USB_EP_TX, - AR9170_USB_EP_RX, - AR9170_USB_EP_IRQ, - AR9170_USB_EP_CMD, - AR9170_USB_NUM_EXTRA_EP = 4, - - __AR9170_USB_NUM_EP, - - __AR9170_USB_NUM_MAX_EP = 10 -}; - -enum ar9170_usb_fifo { - __AR9170_USB_NUM_MAX_FIFO = 10 -}; - -enum ar9170_tx_queues { - AR9170_TXQ0 = 0, - AR9170_TXQ1, - AR9170_TXQ2, - AR9170_TXQ3, - AR9170_TXQ_SPECIAL, - - /* keep last */ - __AR9170_NUM_TX_QUEUES = 5 -}; - -#define AR9170_TX_STREAM_TAG 0x697e -#define AR9170_RX_STREAM_TAG 0x4e00 -#define AR9170_RX_STREAM_MAX_SIZE 0xffff - -struct ar9170_stream { - __le16 length; - __le16 tag; - - u8 payload[0]; -} __packed __aligned(4); -#define AR9170_STREAM_LEN 4 - -#define AR9170_MAX_ACKTABLE_ENTRIES 8 -#define AR9170_MAX_VIRTUAL_MAC 7 - -#define AR9170_USB_EP_CTRL_MAX 64 -#define AR9170_USB_EP_TX_MAX 512 -#define AR9170_USB_EP_RX_MAX 512 -#define AR9170_USB_EP_IRQ_MAX 64 -#define AR9170_USB_EP_CMD_MAX 64 - -/* Trigger PRETBTT interrupt 6 Kus earlier */ -#define CARL9170_PRETBTT_KUS 6 - -#define AR5416_MAX_RATE_POWER 63 - -#define SET_VAL(reg, value, newvalue) \ - (value = ((value) & ~reg) | (((newvalue) << reg##_S) & reg)) - -#define SET_CONSTVAL(reg, newvalue) \ - (((newvalue) << reg##_S) & reg) - -#define MOD_VAL(reg, value, newvalue) \ - (((value) & ~reg) | (((newvalue) << reg##_S) & reg)) - -#define GET_VAL(reg, value) \ - (((value) & reg) >> reg##_S) - -#endif /* __CARL9170_SHARED_HW_H */ diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/led.c b/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/led.c deleted file mode 100644 index 78dadc79..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/led.c +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Atheros CARL9170 driver - * - * LED handling - * - * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> - * Copyright 2009, 2010, Christian Lamparer <chunkeey@googlemail.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, see - * http://www.gnu.org/licenses/. - * - * This file incorporates work covered by the following copyright and - * permission notice: - * Copyright (c) 2007-2008 Atheros Communications, Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "carl9170.h" -#include "cmd.h" - -int carl9170_led_set_state(struct ar9170 *ar, const u32 led_state) -{ - return carl9170_write_reg(ar, AR9170_GPIO_REG_PORT_DATA, led_state); -} - -int carl9170_led_init(struct ar9170 *ar) -{ - int err; - - /* disable LEDs */ - /* GPIO [0/1 mode: output, 2/3: input] */ - err = carl9170_write_reg(ar, AR9170_GPIO_REG_PORT_TYPE, 3); - if (err) - goto out; - - /* GPIO 0/1 value: off */ - err = carl9170_led_set_state(ar, 0); - -out: - return err; -} - -#ifdef CONFIG_CARL9170_LEDS -static void carl9170_led_update(struct work_struct *work) -{ - struct ar9170 *ar = container_of(work, struct ar9170, led_work.work); - int i, tmp = 300, blink_delay = 1000; - u32 led_val = 0; - bool rerun = false; - - if (!IS_ACCEPTING_CMD(ar)) - return; - - mutex_lock(&ar->mutex); - for (i = 0; i < AR9170_NUM_LEDS; i++) { - if (ar->leds[i].registered) { - if (ar->leds[i].last_state || - ar->leds[i].toggled) { - - if (ar->leds[i].toggled) - tmp = 70 + 200 / (ar->leds[i].toggled); - - if (tmp < blink_delay) - blink_delay = tmp; - - led_val |= 1 << i; - ar->leds[i].toggled = 0; - rerun = true; - } - } - } - - carl9170_led_set_state(ar, led_val); - mutex_unlock(&ar->mutex); - - if (!rerun) - return; - - ieee80211_queue_delayed_work(ar->hw, - &ar->led_work, - msecs_to_jiffies(blink_delay)); -} - -static void carl9170_led_set_brightness(struct led_classdev *led, - enum led_brightness brightness) -{ - struct carl9170_led *arl = container_of(led, struct carl9170_led, l); - struct ar9170 *ar = arl->ar; - - if (!arl->registered) - return; - - if (arl->last_state != !!brightness) { - arl->toggled++; - arl->last_state = !!brightness; - } - - if (likely(IS_ACCEPTING_CMD(ar) && arl->toggled)) - ieee80211_queue_delayed_work(ar->hw, &ar->led_work, HZ / 10); -} - -static int carl9170_led_register_led(struct ar9170 *ar, int i, char *name, - char *trigger) -{ - int err; - - snprintf(ar->leds[i].name, sizeof(ar->leds[i].name), - "carl9170-%s::%s", wiphy_name(ar->hw->wiphy), name); - - ar->leds[i].ar = ar; - ar->leds[i].l.name = ar->leds[i].name; - ar->leds[i].l.brightness_set = carl9170_led_set_brightness; - ar->leds[i].l.brightness = 0; - ar->leds[i].l.default_trigger = trigger; - - err = led_classdev_register(wiphy_dev(ar->hw->wiphy), - &ar->leds[i].l); - if (err) { - wiphy_err(ar->hw->wiphy, "failed to register %s LED (%d).\n", - ar->leds[i].name, err); - } else { - ar->leds[i].registered = true; - } - - return err; -} - -void carl9170_led_unregister(struct ar9170 *ar) -{ - int i; - - for (i = 0; i < AR9170_NUM_LEDS; i++) - if (ar->leds[i].registered) { - led_classdev_unregister(&ar->leds[i].l); - ar->leds[i].registered = false; - ar->leds[i].toggled = 0; - } - - cancel_delayed_work_sync(&ar->led_work); -} - -int carl9170_led_register(struct ar9170 *ar) -{ - int err; - - INIT_DELAYED_WORK(&ar->led_work, carl9170_led_update); - - err = carl9170_led_register_led(ar, 0, "tx", - ieee80211_get_tx_led_name(ar->hw)); - if (err) - goto fail; - - if (ar->features & CARL9170_ONE_LED) - return 0; - - err = carl9170_led_register_led(ar, 1, "assoc", - ieee80211_get_assoc_led_name(ar->hw)); - if (err) - goto fail; - - return 0; - -fail: - carl9170_led_unregister(ar); - return err; -} - -#endif /* CONFIG_CARL9170_LEDS */ diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/mac.c b/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/mac.c deleted file mode 100644 index 53415bfd..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/mac.c +++ /dev/null @@ -1,522 +0,0 @@ -/* - * Atheros CARL9170 driver - * - * MAC programming - * - * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, see - * http://www.gnu.org/licenses/. - * - * This file incorporates work covered by the following copyright and - * permission notice: - * Copyright (c) 2007-2008 Atheros Communications, Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <asm/unaligned.h> - -#include "carl9170.h" -#include "cmd.h" - -int carl9170_set_dyn_sifs_ack(struct ar9170 *ar) -{ - u32 val; - - if (conf_is_ht40(&ar->hw->conf)) - val = 0x010a; - else { - if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) - val = 0x105; - else - val = 0x104; - } - - return carl9170_write_reg(ar, AR9170_MAC_REG_DYNAMIC_SIFS_ACK, val); -} - -int carl9170_set_rts_cts_rate(struct ar9170 *ar) -{ - u32 rts_rate, cts_rate; - - if (conf_is_ht(&ar->hw->conf)) { - /* 12 mbit OFDM */ - rts_rate = 0x1da; - cts_rate = 0x10a; - } else { - if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) { - /* 11 mbit CCK */ - rts_rate = 033; - cts_rate = 003; - } else { - /* 6 mbit OFDM */ - rts_rate = 0x1bb; - cts_rate = 0x10b; - } - } - - return carl9170_write_reg(ar, AR9170_MAC_REG_RTS_CTS_RATE, - rts_rate | (cts_rate) << 16); -} - -int carl9170_set_slot_time(struct ar9170 *ar) -{ - struct ieee80211_vif *vif; - u32 slottime = 20; - - rcu_read_lock(); - vif = carl9170_get_main_vif(ar); - if (!vif) { - rcu_read_unlock(); - return 0; - } - - if ((ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ) || - vif->bss_conf.use_short_slot) - slottime = 9; - - rcu_read_unlock(); - - return carl9170_write_reg(ar, AR9170_MAC_REG_SLOT_TIME, - slottime << 10); -} - -int carl9170_set_mac_rates(struct ar9170 *ar) -{ - struct ieee80211_vif *vif; - u32 basic, mandatory; - - rcu_read_lock(); - vif = carl9170_get_main_vif(ar); - - if (!vif) { - rcu_read_unlock(); - return 0; - } - - basic = (vif->bss_conf.basic_rates & 0xf); - basic |= (vif->bss_conf.basic_rates & 0xff0) << 4; - rcu_read_unlock(); - - if (ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ) - mandatory = 0xff00; /* OFDM 6/9/12/18/24/36/48/54 */ - else - mandatory = 0xff0f; /* OFDM (6/9../54) + CCK (1/2/5.5/11) */ - - carl9170_regwrite_begin(ar); - carl9170_regwrite(AR9170_MAC_REG_BASIC_RATE, basic); - carl9170_regwrite(AR9170_MAC_REG_MANDATORY_RATE, mandatory); - carl9170_regwrite_finish(); - - return carl9170_regwrite_result(); -} - -int carl9170_set_qos(struct ar9170 *ar) -{ - carl9170_regwrite_begin(ar); - - carl9170_regwrite(AR9170_MAC_REG_AC0_CW, ar->edcf[0].cw_min | - (ar->edcf[0].cw_max << 16)); - carl9170_regwrite(AR9170_MAC_REG_AC1_CW, ar->edcf[1].cw_min | - (ar->edcf[1].cw_max << 16)); - carl9170_regwrite(AR9170_MAC_REG_AC2_CW, ar->edcf[2].cw_min | - (ar->edcf[2].cw_max << 16)); - carl9170_regwrite(AR9170_MAC_REG_AC3_CW, ar->edcf[3].cw_min | - (ar->edcf[3].cw_max << 16)); - carl9170_regwrite(AR9170_MAC_REG_AC4_CW, ar->edcf[4].cw_min | - (ar->edcf[4].cw_max << 16)); - - carl9170_regwrite(AR9170_MAC_REG_AC2_AC1_AC0_AIFS, - ((ar->edcf[0].aifs * 9 + 10)) | - ((ar->edcf[1].aifs * 9 + 10) << 12) | - ((ar->edcf[2].aifs * 9 + 10) << 24)); - carl9170_regwrite(AR9170_MAC_REG_AC4_AC3_AC2_AIFS, - ((ar->edcf[2].aifs * 9 + 10) >> 8) | - ((ar->edcf[3].aifs * 9 + 10) << 4) | - ((ar->edcf[4].aifs * 9 + 10) << 16)); - - carl9170_regwrite(AR9170_MAC_REG_AC1_AC0_TXOP, - ar->edcf[0].txop | ar->edcf[1].txop << 16); - carl9170_regwrite(AR9170_MAC_REG_AC3_AC2_TXOP, - ar->edcf[2].txop | ar->edcf[3].txop << 16 | - ar->edcf[4].txop << 24); - - carl9170_regwrite_finish(); - - return carl9170_regwrite_result(); -} - -int carl9170_init_mac(struct ar9170 *ar) -{ - carl9170_regwrite_begin(ar); - - /* switch MAC to OTUS interface */ - carl9170_regwrite(0x1c3600, 0x3); - - carl9170_regwrite(AR9170_MAC_REG_ACK_EXTENSION, 0x40); - - carl9170_regwrite(AR9170_MAC_REG_RETRY_MAX, 0x0); - - carl9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER, - AR9170_MAC_FTF_MONITOR); - - /* enable MMIC */ - carl9170_regwrite(AR9170_MAC_REG_SNIFFER, - AR9170_MAC_SNIFFER_DEFAULTS); - - carl9170_regwrite(AR9170_MAC_REG_RX_THRESHOLD, 0xc1f80); - - carl9170_regwrite(AR9170_MAC_REG_RX_PE_DELAY, 0x70); - carl9170_regwrite(AR9170_MAC_REG_EIFS_AND_SIFS, 0xa144000); - carl9170_regwrite(AR9170_MAC_REG_SLOT_TIME, 9 << 10); - - /* CF-END & CF-ACK rate => 24M OFDM */ - carl9170_regwrite(AR9170_MAC_REG_TID_CFACK_CFEND_RATE, 0x59900000); - - /* NAV protects ACK only (in TXOP) */ - carl9170_regwrite(AR9170_MAC_REG_TXOP_DURATION, 0x201); - - /* Set Beacon PHY CTRL's TPC to 0x7, TA1=1 */ - /* OTUS set AM to 0x1 */ - carl9170_regwrite(AR9170_MAC_REG_BCN_HT1, 0x8000170); - - carl9170_regwrite(AR9170_MAC_REG_BACKOFF_PROTECT, 0x105); - - /* Aggregation MAX number and timeout */ - carl9170_regwrite(AR9170_MAC_REG_AMPDU_FACTOR, 0x8000a); - carl9170_regwrite(AR9170_MAC_REG_AMPDU_DENSITY, 0x140a07); - - carl9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER, - AR9170_MAC_FTF_DEFAULTS); - - carl9170_regwrite(AR9170_MAC_REG_RX_CONTROL, - AR9170_MAC_RX_CTRL_DEAGG | - AR9170_MAC_RX_CTRL_SHORT_FILTER); - - /* rate sets */ - carl9170_regwrite(AR9170_MAC_REG_BASIC_RATE, 0x150f); - carl9170_regwrite(AR9170_MAC_REG_MANDATORY_RATE, 0x150f); - carl9170_regwrite(AR9170_MAC_REG_RTS_CTS_RATE, 0x0030033); - - /* MIMO response control */ - carl9170_regwrite(AR9170_MAC_REG_ACK_TPC, 0x4003c1e); - - carl9170_regwrite(AR9170_MAC_REG_AMPDU_RX_THRESH, 0xffff); - - /* set PHY register read timeout (??) */ - carl9170_regwrite(AR9170_MAC_REG_MISC_680, 0xf00008); - - /* Disable Rx TimeOut, workaround for BB. */ - carl9170_regwrite(AR9170_MAC_REG_RX_TIMEOUT, 0x0); - - /* Set WLAN DMA interrupt mode: generate int per packet */ - carl9170_regwrite(AR9170_MAC_REG_TXRX_MPI, 0x110011); - - carl9170_regwrite(AR9170_MAC_REG_FCS_SELECT, - AR9170_MAC_FCS_FIFO_PROT); - - /* Disables the CF_END frame, undocumented register */ - carl9170_regwrite(AR9170_MAC_REG_TXOP_NOT_ENOUGH_IND, - 0x141e0f48); - - /* reset group hash table */ - carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L, 0xffffffff); - carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H, 0xffffffff); - - /* disable PRETBTT interrupt */ - carl9170_regwrite(AR9170_MAC_REG_PRETBTT, 0x0); - carl9170_regwrite(AR9170_MAC_REG_BCN_PERIOD, 0x0); - - carl9170_regwrite_finish(); - - return carl9170_regwrite_result(); -} - -static int carl9170_set_mac_reg(struct ar9170 *ar, - const u32 reg, const u8 *mac) -{ - static const u8 zero[ETH_ALEN] = { 0 }; - - if (!mac) - mac = zero; - - carl9170_regwrite_begin(ar); - - carl9170_regwrite(reg, get_unaligned_le32(mac)); - carl9170_regwrite(reg + 4, get_unaligned_le16(mac + 4)); - - carl9170_regwrite_finish(); - - return carl9170_regwrite_result(); -} - -int carl9170_mod_virtual_mac(struct ar9170 *ar, const unsigned int id, - const u8 *mac) -{ - if (WARN_ON(id >= ar->fw.vif_num)) - return -EINVAL; - - return carl9170_set_mac_reg(ar, - AR9170_MAC_REG_ACK_TABLE + (id - 1) * 8, mac); -} - -int carl9170_update_multicast(struct ar9170 *ar, const u64 mc_hash) -{ - int err; - - carl9170_regwrite_begin(ar); - carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H, mc_hash >> 32); - carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L, mc_hash); - carl9170_regwrite_finish(); - err = carl9170_regwrite_result(); - if (err) - return err; - - ar->cur_mc_hash = mc_hash; - return 0; -} - -int carl9170_set_operating_mode(struct ar9170 *ar) -{ - struct ieee80211_vif *vif; - struct ath_common *common = &ar->common; - u8 *mac_addr, *bssid; - u32 cam_mode = AR9170_MAC_CAM_DEFAULTS; - u32 enc_mode = AR9170_MAC_ENCRYPTION_DEFAULTS; - u32 rx_ctrl = AR9170_MAC_RX_CTRL_DEAGG | - AR9170_MAC_RX_CTRL_SHORT_FILTER; - u32 sniffer = AR9170_MAC_SNIFFER_DEFAULTS; - int err = 0; - - rcu_read_lock(); - vif = carl9170_get_main_vif(ar); - - if (vif) { - mac_addr = common->macaddr; - bssid = common->curbssid; - - switch (vif->type) { - case NL80211_IFTYPE_MESH_POINT: - case NL80211_IFTYPE_ADHOC: - cam_mode |= AR9170_MAC_CAM_IBSS; - break; - case NL80211_IFTYPE_AP: - cam_mode |= AR9170_MAC_CAM_AP; - - /* iwlagn 802.11n STA Workaround */ - rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST; - break; - case NL80211_IFTYPE_WDS: - cam_mode |= AR9170_MAC_CAM_AP_WDS; - rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST; - break; - case NL80211_IFTYPE_STATION: - cam_mode |= AR9170_MAC_CAM_STA; - rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST; - break; - default: - WARN(1, "Unsupported operation mode %x\n", vif->type); - err = -EOPNOTSUPP; - break; - } - } else { - mac_addr = NULL; - bssid = NULL; - } - rcu_read_unlock(); - - if (err) - return err; - - if (ar->rx_software_decryption) - enc_mode |= AR9170_MAC_ENCRYPTION_RX_SOFTWARE; - - if (ar->sniffer_enabled) { - rx_ctrl |= AR9170_MAC_RX_CTRL_ACK_IN_SNIFFER; - sniffer |= AR9170_MAC_SNIFFER_ENABLE_PROMISC; - enc_mode |= AR9170_MAC_ENCRYPTION_RX_SOFTWARE; - } - - err = carl9170_set_mac_reg(ar, AR9170_MAC_REG_MAC_ADDR_L, mac_addr); - if (err) - return err; - - err = carl9170_set_mac_reg(ar, AR9170_MAC_REG_BSSID_L, bssid); - if (err) - return err; - - carl9170_regwrite_begin(ar); - carl9170_regwrite(AR9170_MAC_REG_SNIFFER, sniffer); - carl9170_regwrite(AR9170_MAC_REG_CAM_MODE, cam_mode); - carl9170_regwrite(AR9170_MAC_REG_ENCRYPTION, enc_mode); - carl9170_regwrite(AR9170_MAC_REG_RX_CONTROL, rx_ctrl); - carl9170_regwrite_finish(); - - return carl9170_regwrite_result(); -} - -int carl9170_set_hwretry_limit(struct ar9170 *ar, const unsigned int max_retry) -{ - u32 tmp = min_t(u32, 0x33333, max_retry * 0x11111); - - return carl9170_write_reg(ar, AR9170_MAC_REG_RETRY_MAX, tmp); -} - -int carl9170_set_beacon_timers(struct ar9170 *ar) -{ - struct ieee80211_vif *vif; - u32 v = 0; - u32 pretbtt = 0; - - rcu_read_lock(); - vif = carl9170_get_main_vif(ar); - - if (vif) { - struct carl9170_vif_info *mvif; - mvif = (void *) vif->drv_priv; - - if (mvif->enable_beacon && !WARN_ON(!ar->beacon_enabled)) { - ar->global_beacon_int = vif->bss_conf.beacon_int / - ar->beacon_enabled; - - SET_VAL(AR9170_MAC_BCN_DTIM, v, - vif->bss_conf.dtim_period); - - switch (vif->type) { - case NL80211_IFTYPE_MESH_POINT: - case NL80211_IFTYPE_ADHOC: - v |= AR9170_MAC_BCN_IBSS_MODE; - break; - case NL80211_IFTYPE_AP: - v |= AR9170_MAC_BCN_AP_MODE; - break; - default: - WARN_ON_ONCE(1); - break; - } - } else if (vif->type == NL80211_IFTYPE_STATION) { - ar->global_beacon_int = vif->bss_conf.beacon_int; - - SET_VAL(AR9170_MAC_BCN_DTIM, v, - ar->hw->conf.ps_dtim_period); - - v |= AR9170_MAC_BCN_STA_PS | - AR9170_MAC_BCN_PWR_MGT; - } - - if (ar->global_beacon_int) { - if (ar->global_beacon_int < 15) { - rcu_read_unlock(); - return -ERANGE; - } - - ar->global_pretbtt = ar->global_beacon_int - - CARL9170_PRETBTT_KUS; - } else { - ar->global_pretbtt = 0; - } - } else { - ar->global_beacon_int = 0; - ar->global_pretbtt = 0; - } - - rcu_read_unlock(); - - SET_VAL(AR9170_MAC_BCN_PERIOD, v, ar->global_beacon_int); - SET_VAL(AR9170_MAC_PRETBTT, pretbtt, ar->global_pretbtt); - SET_VAL(AR9170_MAC_PRETBTT2, pretbtt, ar->global_pretbtt); - - carl9170_regwrite_begin(ar); - carl9170_regwrite(AR9170_MAC_REG_PRETBTT, pretbtt); - carl9170_regwrite(AR9170_MAC_REG_BCN_PERIOD, v); - carl9170_regwrite_finish(); - return carl9170_regwrite_result(); -} - -int carl9170_upload_key(struct ar9170 *ar, const u8 id, const u8 *mac, - const u8 ktype, const u8 keyidx, const u8 *keydata, - const int keylen) -{ - struct carl9170_set_key_cmd key = { }; - static const u8 bcast[ETH_ALEN] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; - - mac = mac ? : bcast; - - key.user = cpu_to_le16(id); - key.keyId = cpu_to_le16(keyidx); - key.type = cpu_to_le16(ktype); - memcpy(&key.macAddr, mac, ETH_ALEN); - if (keydata) - memcpy(&key.key, keydata, keylen); - - return carl9170_exec_cmd(ar, CARL9170_CMD_EKEY, - sizeof(key), (u8 *)&key, 0, NULL); -} - -int carl9170_disable_key(struct ar9170 *ar, const u8 id) -{ - struct carl9170_disable_key_cmd key = { }; - - key.user = cpu_to_le16(id); - - return carl9170_exec_cmd(ar, CARL9170_CMD_DKEY, - sizeof(key), (u8 *)&key, 0, NULL); -} - -int carl9170_set_mac_tpc(struct ar9170 *ar, struct ieee80211_channel *channel) -{ - unsigned int power, chains; - - if (ar->eeprom.tx_mask != 1) - chains = AR9170_TX_PHY_TXCHAIN_2; - else - chains = AR9170_TX_PHY_TXCHAIN_1; - - switch (channel->band) { - case IEEE80211_BAND_2GHZ: - power = ar->power_2G_ofdm[0] & 0x3f; - break; - case IEEE80211_BAND_5GHZ: - power = ar->power_5G_leg[0] & 0x3f; - break; - default: - BUG_ON(1); - } - - power = min_t(unsigned int, power, ar->hw->conf.power_level * 2); - - carl9170_regwrite_begin(ar); - carl9170_regwrite(AR9170_MAC_REG_ACK_TPC, - 0x3c1e | power << 20 | chains << 26); - carl9170_regwrite(AR9170_MAC_REG_RTS_CTS_TPC, - power << 5 | chains << 11 | - power << 21 | chains << 27); - carl9170_regwrite(AR9170_MAC_REG_CFEND_QOSNULL_TPC, - power << 5 | chains << 11 | - power << 21 | chains << 27); - carl9170_regwrite_finish(); - return carl9170_regwrite_result(); -} diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/main.c b/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/main.c deleted file mode 100644 index 8d2523b3..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/main.c +++ /dev/null @@ -1,2052 +0,0 @@ -/* - * Atheros CARL9170 driver - * - * mac80211 interaction code - * - * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> - * Copyright 2009, 2010, Christian Lamparter <chunkeey@googlemail.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, see - * http://www.gnu.org/licenses/. - * - * This file incorporates work covered by the following copyright and - * permission notice: - * Copyright (c) 2007-2008 Atheros Communications, Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/etherdevice.h> -#include <linux/random.h> -#include <net/mac80211.h> -#include <net/cfg80211.h> -#include "hw.h" -#include "carl9170.h" -#include "cmd.h" - -static bool modparam_nohwcrypt; -module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); -MODULE_PARM_DESC(nohwcrypt, "Disable hardware crypto offload."); - -int modparam_noht; -module_param_named(noht, modparam_noht, int, S_IRUGO); -MODULE_PARM_DESC(noht, "Disable MPDU aggregation."); - -#define RATE(_bitrate, _hw_rate, _txpidx, _flags) { \ - .bitrate = (_bitrate), \ - .flags = (_flags), \ - .hw_value = (_hw_rate) | (_txpidx) << 4, \ -} - -struct ieee80211_rate __carl9170_ratetable[] = { - RATE(10, 0, 0, 0), - RATE(20, 1, 1, IEEE80211_RATE_SHORT_PREAMBLE), - RATE(55, 2, 2, IEEE80211_RATE_SHORT_PREAMBLE), - RATE(110, 3, 3, IEEE80211_RATE_SHORT_PREAMBLE), - RATE(60, 0xb, 0, 0), - RATE(90, 0xf, 0, 0), - RATE(120, 0xa, 0, 0), - RATE(180, 0xe, 0, 0), - RATE(240, 0x9, 0, 0), - RATE(360, 0xd, 1, 0), - RATE(480, 0x8, 2, 0), - RATE(540, 0xc, 3, 0), -}; -#undef RATE - -#define carl9170_g_ratetable (__carl9170_ratetable + 0) -#define carl9170_g_ratetable_size 12 -#define carl9170_a_ratetable (__carl9170_ratetable + 4) -#define carl9170_a_ratetable_size 8 - -/* - * NB: The hw_value is used as an index into the carl9170_phy_freq_params - * array in phy.c so that we don't have to do frequency lookups! - */ -#define CHAN(_freq, _idx) { \ - .center_freq = (_freq), \ - .hw_value = (_idx), \ - .max_power = 18, /* XXX */ \ -} - -static struct ieee80211_channel carl9170_2ghz_chantable[] = { - CHAN(2412, 0), - CHAN(2417, 1), - CHAN(2422, 2), - CHAN(2427, 3), - CHAN(2432, 4), - CHAN(2437, 5), - CHAN(2442, 6), - CHAN(2447, 7), - CHAN(2452, 8), - CHAN(2457, 9), - CHAN(2462, 10), - CHAN(2467, 11), - CHAN(2472, 12), - CHAN(2484, 13), -}; - -static struct ieee80211_channel carl9170_5ghz_chantable[] = { - CHAN(4920, 14), - CHAN(4940, 15), - CHAN(4960, 16), - CHAN(4980, 17), - CHAN(5040, 18), - CHAN(5060, 19), - CHAN(5080, 20), - CHAN(5180, 21), - CHAN(5200, 22), - CHAN(5220, 23), - CHAN(5240, 24), - CHAN(5260, 25), - CHAN(5280, 26), - CHAN(5300, 27), - CHAN(5320, 28), - CHAN(5500, 29), - CHAN(5520, 30), - CHAN(5540, 31), - CHAN(5560, 32), - CHAN(5580, 33), - CHAN(5600, 34), - CHAN(5620, 35), - CHAN(5640, 36), - CHAN(5660, 37), - CHAN(5680, 38), - CHAN(5700, 39), - CHAN(5745, 40), - CHAN(5765, 41), - CHAN(5785, 42), - CHAN(5805, 43), - CHAN(5825, 44), - CHAN(5170, 45), - CHAN(5190, 46), - CHAN(5210, 47), - CHAN(5230, 48), -}; -#undef CHAN - -#define CARL9170_HT_CAP \ -{ \ - .ht_supported = true, \ - .cap = IEEE80211_HT_CAP_MAX_AMSDU | \ - IEEE80211_HT_CAP_SUP_WIDTH_20_40 | \ - IEEE80211_HT_CAP_SGI_40 | \ - IEEE80211_HT_CAP_DSSSCCK40 | \ - IEEE80211_HT_CAP_SM_PS, \ - .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, \ - .ampdu_density = IEEE80211_HT_MPDU_DENSITY_8, \ - .mcs = { \ - .rx_mask = { 0xff, 0xff, 0, 0, 0x1, 0, 0, 0, 0, 0, }, \ - .rx_highest = cpu_to_le16(300), \ - .tx_params = IEEE80211_HT_MCS_TX_DEFINED, \ - }, \ -} - -static struct ieee80211_supported_band carl9170_band_2GHz = { - .channels = carl9170_2ghz_chantable, - .n_channels = ARRAY_SIZE(carl9170_2ghz_chantable), - .bitrates = carl9170_g_ratetable, - .n_bitrates = carl9170_g_ratetable_size, - .ht_cap = CARL9170_HT_CAP, -}; - -static struct ieee80211_supported_band carl9170_band_5GHz = { - .channels = carl9170_5ghz_chantable, - .n_channels = ARRAY_SIZE(carl9170_5ghz_chantable), - .bitrates = carl9170_a_ratetable, - .n_bitrates = carl9170_a_ratetable_size, - .ht_cap = CARL9170_HT_CAP, -}; - -static void carl9170_ampdu_gc(struct ar9170 *ar) -{ - struct carl9170_sta_tid *tid_info; - LIST_HEAD(tid_gc); - - rcu_read_lock(); - list_for_each_entry_rcu(tid_info, &ar->tx_ampdu_list, list) { - spin_lock_bh(&ar->tx_ampdu_list_lock); - if (tid_info->state == CARL9170_TID_STATE_SHUTDOWN) { - tid_info->state = CARL9170_TID_STATE_KILLED; - list_del_rcu(&tid_info->list); - ar->tx_ampdu_list_len--; - list_add_tail(&tid_info->tmp_list, &tid_gc); - } - spin_unlock_bh(&ar->tx_ampdu_list_lock); - - } - rcu_assign_pointer(ar->tx_ampdu_iter, tid_info); - rcu_read_unlock(); - - synchronize_rcu(); - - while (!list_empty(&tid_gc)) { - struct sk_buff *skb; - tid_info = list_first_entry(&tid_gc, struct carl9170_sta_tid, - tmp_list); - - while ((skb = __skb_dequeue(&tid_info->queue))) - carl9170_tx_status(ar, skb, false); - - list_del_init(&tid_info->tmp_list); - kfree(tid_info); - } -} - -static void carl9170_flush(struct ar9170 *ar, bool drop_queued) -{ - if (drop_queued) { - int i; - - /* - * We can only drop frames which have not been uploaded - * to the device yet. - */ - - for (i = 0; i < ar->hw->queues; i++) { - struct sk_buff *skb; - - while ((skb = skb_dequeue(&ar->tx_pending[i]))) { - struct ieee80211_tx_info *info; - - info = IEEE80211_SKB_CB(skb); - if (info->flags & IEEE80211_TX_CTL_AMPDU) - atomic_dec(&ar->tx_ampdu_upload); - - carl9170_tx_status(ar, skb, false); - } - } - } - - /* Wait for all other outstanding frames to timeout. */ - if (atomic_read(&ar->tx_total_queued)) - WARN_ON(wait_for_completion_timeout(&ar->tx_flush, HZ) == 0); -} - -static void carl9170_flush_ba(struct ar9170 *ar) -{ - struct sk_buff_head free; - struct carl9170_sta_tid *tid_info; - struct sk_buff *skb; - - __skb_queue_head_init(&free); - - rcu_read_lock(); - spin_lock_bh(&ar->tx_ampdu_list_lock); - list_for_each_entry_rcu(tid_info, &ar->tx_ampdu_list, list) { - if (tid_info->state > CARL9170_TID_STATE_SUSPEND) { - tid_info->state = CARL9170_TID_STATE_SUSPEND; - - spin_lock(&tid_info->lock); - while ((skb = __skb_dequeue(&tid_info->queue))) - __skb_queue_tail(&free, skb); - spin_unlock(&tid_info->lock); - } - } - spin_unlock_bh(&ar->tx_ampdu_list_lock); - rcu_read_unlock(); - - while ((skb = __skb_dequeue(&free))) - carl9170_tx_status(ar, skb, false); -} - -static void carl9170_zap_queues(struct ar9170 *ar) -{ - struct carl9170_vif_info *cvif; - unsigned int i; - - carl9170_ampdu_gc(ar); - - carl9170_flush_ba(ar); - carl9170_flush(ar, true); - - for (i = 0; i < ar->hw->queues; i++) { - spin_lock_bh(&ar->tx_status[i].lock); - while (!skb_queue_empty(&ar->tx_status[i])) { - struct sk_buff *skb; - - skb = skb_peek(&ar->tx_status[i]); - carl9170_tx_get_skb(skb); - spin_unlock_bh(&ar->tx_status[i].lock); - carl9170_tx_drop(ar, skb); - spin_lock_bh(&ar->tx_status[i].lock); - carl9170_tx_put_skb(skb); - } - spin_unlock_bh(&ar->tx_status[i].lock); - } - - BUILD_BUG_ON(CARL9170_NUM_TX_LIMIT_SOFT < 1); - BUILD_BUG_ON(CARL9170_NUM_TX_LIMIT_HARD < CARL9170_NUM_TX_LIMIT_SOFT); - BUILD_BUG_ON(CARL9170_NUM_TX_LIMIT_HARD >= CARL9170_BAW_BITS); - - /* reinitialize queues statistics */ - memset(&ar->tx_stats, 0, sizeof(ar->tx_stats)); - for (i = 0; i < ar->hw->queues; i++) - ar->tx_stats[i].limit = CARL9170_NUM_TX_LIMIT_HARD; - - for (i = 0; i < DIV_ROUND_UP(ar->fw.mem_blocks, BITS_PER_LONG); i++) - ar->mem_bitmap[i] = 0; - - rcu_read_lock(); - list_for_each_entry_rcu(cvif, &ar->vif_list, list) { - spin_lock_bh(&ar->beacon_lock); - dev_kfree_skb_any(cvif->beacon); - cvif->beacon = NULL; - spin_unlock_bh(&ar->beacon_lock); - } - rcu_read_unlock(); - - atomic_set(&ar->tx_ampdu_upload, 0); - atomic_set(&ar->tx_ampdu_scheduler, 0); - atomic_set(&ar->tx_total_pending, 0); - atomic_set(&ar->tx_total_queued, 0); - atomic_set(&ar->mem_free_blocks, ar->fw.mem_blocks); -} - -#define CARL9170_FILL_QUEUE(queue, ai_fs, cwmin, cwmax, _txop) \ -do { \ - queue.aifs = ai_fs; \ - queue.cw_min = cwmin; \ - queue.cw_max = cwmax; \ - queue.txop = _txop; \ -} while (0) - -static int carl9170_op_start(struct ieee80211_hw *hw) -{ - struct ar9170 *ar = hw->priv; - int err, i; - - mutex_lock(&ar->mutex); - - carl9170_zap_queues(ar); - - /* reset QoS defaults */ - CARL9170_FILL_QUEUE(ar->edcf[AR9170_TXQ_VO], 2, 3, 7, 47); - CARL9170_FILL_QUEUE(ar->edcf[AR9170_TXQ_VI], 2, 7, 15, 94); - CARL9170_FILL_QUEUE(ar->edcf[AR9170_TXQ_BE], 3, 15, 1023, 0); - CARL9170_FILL_QUEUE(ar->edcf[AR9170_TXQ_BK], 7, 15, 1023, 0); - CARL9170_FILL_QUEUE(ar->edcf[AR9170_TXQ_SPECIAL], 2, 3, 7, 0); - - ar->current_factor = ar->current_density = -1; - /* "The first key is unique." */ - ar->usedkeys = 1; - ar->filter_state = 0; - ar->ps.last_action = jiffies; - ar->ps.last_slept = jiffies; - ar->erp_mode = CARL9170_ERP_AUTO; - ar->rx_software_decryption = false; - ar->disable_offload = false; - - for (i = 0; i < ar->hw->queues; i++) { - ar->queue_stop_timeout[i] = jiffies; - ar->max_queue_stop_timeout[i] = 0; - } - - atomic_set(&ar->mem_allocs, 0); - - err = carl9170_usb_open(ar); - if (err) - goto out; - - err = carl9170_init_mac(ar); - if (err) - goto out; - - err = carl9170_set_qos(ar); - if (err) - goto out; - - if (ar->fw.rx_filter) { - err = carl9170_rx_filter(ar, CARL9170_RX_FILTER_OTHER_RA | - CARL9170_RX_FILTER_CTL_OTHER | CARL9170_RX_FILTER_BAD); - if (err) - goto out; - } - - err = carl9170_write_reg(ar, AR9170_MAC_REG_DMA_TRIGGER, - AR9170_DMA_TRIGGER_RXQ); - if (err) - goto out; - - /* Clear key-cache */ - for (i = 0; i < AR9170_CAM_MAX_USER + 4; i++) { - err = carl9170_upload_key(ar, i, NULL, AR9170_ENC_ALG_NONE, - 0, NULL, 0); - if (err) - goto out; - - err = carl9170_upload_key(ar, i, NULL, AR9170_ENC_ALG_NONE, - 1, NULL, 0); - if (err) - goto out; - - if (i < AR9170_CAM_MAX_USER) { - err = carl9170_disable_key(ar, i); - if (err) - goto out; - } - } - - carl9170_set_state_when(ar, CARL9170_IDLE, CARL9170_STARTED); - - ieee80211_queue_delayed_work(ar->hw, &ar->stat_work, - round_jiffies(msecs_to_jiffies(CARL9170_STAT_WORK))); - - ieee80211_wake_queues(ar->hw); - err = 0; - -out: - mutex_unlock(&ar->mutex); - return err; -} - -static void carl9170_cancel_worker(struct ar9170 *ar) -{ - cancel_delayed_work_sync(&ar->stat_work); - cancel_delayed_work_sync(&ar->tx_janitor); -#ifdef CONFIG_CARL9170_LEDS - cancel_delayed_work_sync(&ar->led_work); -#endif /* CONFIG_CARL9170_LEDS */ - cancel_work_sync(&ar->ps_work); - cancel_work_sync(&ar->ping_work); - cancel_work_sync(&ar->ampdu_work); -} - -static void carl9170_op_stop(struct ieee80211_hw *hw) -{ - struct ar9170 *ar = hw->priv; - - carl9170_set_state_when(ar, CARL9170_STARTED, CARL9170_IDLE); - - ieee80211_stop_queues(ar->hw); - - mutex_lock(&ar->mutex); - if (IS_ACCEPTING_CMD(ar)) { - RCU_INIT_POINTER(ar->beacon_iter, NULL); - - carl9170_led_set_state(ar, 0); - - /* stop DMA */ - carl9170_write_reg(ar, AR9170_MAC_REG_DMA_TRIGGER, 0); - carl9170_usb_stop(ar); - } - - carl9170_zap_queues(ar); - mutex_unlock(&ar->mutex); - - carl9170_cancel_worker(ar); -} - -static void carl9170_restart_work(struct work_struct *work) -{ - struct ar9170 *ar = container_of(work, struct ar9170, - restart_work); - int err; - - ar->usedkeys = 0; - ar->filter_state = 0; - carl9170_cancel_worker(ar); - - mutex_lock(&ar->mutex); - err = carl9170_usb_restart(ar); - if (net_ratelimit()) { - if (err) { - dev_err(&ar->udev->dev, "Failed to restart device " - " (%d).\n", err); - } else { - dev_info(&ar->udev->dev, "device restarted " - "successfully.\n"); - } - } - - carl9170_zap_queues(ar); - mutex_unlock(&ar->mutex); - if (!err) { - ar->restart_counter++; - atomic_set(&ar->pending_restarts, 0); - - ieee80211_restart_hw(ar->hw); - } else { - /* - * The reset was unsuccessful and the device seems to - * be dead. But there's still one option: a low-level - * usb subsystem reset... - */ - - carl9170_usb_reset(ar); - } -} - -void carl9170_restart(struct ar9170 *ar, const enum carl9170_restart_reasons r) -{ - carl9170_set_state_when(ar, CARL9170_STARTED, CARL9170_IDLE); - - /* - * Sometimes, an error can trigger several different reset events. - * By ignoring these *surplus* reset events, the device won't be - * killed again, right after it has recovered. - */ - if (atomic_inc_return(&ar->pending_restarts) > 1) { - dev_dbg(&ar->udev->dev, "ignoring restart (%d)\n", r); - return; - } - - ieee80211_stop_queues(ar->hw); - - dev_err(&ar->udev->dev, "restart device (%d)\n", r); - - if (!WARN_ON(r == CARL9170_RR_NO_REASON) || - !WARN_ON(r >= __CARL9170_RR_LAST)) - ar->last_reason = r; - - if (!ar->registered) - return; - - if (IS_ACCEPTING_CMD(ar) && !ar->needs_full_reset) - ieee80211_queue_work(ar->hw, &ar->restart_work); - else - carl9170_usb_reset(ar); - - /* - * At this point, the device instance might have vanished/disabled. - * So, don't put any code which access the ar9170 struct - * without proper protection. - */ -} - -static void carl9170_ping_work(struct work_struct *work) -{ - struct ar9170 *ar = container_of(work, struct ar9170, ping_work); - int err; - - if (!IS_STARTED(ar)) - return; - - mutex_lock(&ar->mutex); - err = carl9170_echo_test(ar, 0xdeadbeef); - if (err) - carl9170_restart(ar, CARL9170_RR_UNRESPONSIVE_DEVICE); - mutex_unlock(&ar->mutex); -} - -static int carl9170_init_interface(struct ar9170 *ar, - struct ieee80211_vif *vif) -{ - struct ath_common *common = &ar->common; - int err; - - if (!vif) { - WARN_ON_ONCE(IS_STARTED(ar)); - return 0; - } - - memcpy(common->macaddr, vif->addr, ETH_ALEN); - - if (modparam_nohwcrypt || - ((vif->type != NL80211_IFTYPE_STATION) && - (vif->type != NL80211_IFTYPE_AP))) { - ar->rx_software_decryption = true; - ar->disable_offload = true; - } - - err = carl9170_set_operating_mode(ar); - return err; -} - -static int carl9170_op_add_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) -{ - struct carl9170_vif_info *vif_priv = (void *) vif->drv_priv; - struct ieee80211_vif *main_vif; - struct ar9170 *ar = hw->priv; - int vif_id = -1, err = 0; - - mutex_lock(&ar->mutex); - rcu_read_lock(); - if (vif_priv->active) { - /* - * Skip the interface structure initialization, - * if the vif survived the _restart call. - */ - vif_id = vif_priv->id; - vif_priv->enable_beacon = false; - - spin_lock_bh(&ar->beacon_lock); - dev_kfree_skb_any(vif_priv->beacon); - vif_priv->beacon = NULL; - spin_unlock_bh(&ar->beacon_lock); - - goto init; - } - - main_vif = carl9170_get_main_vif(ar); - - if (main_vif) { - switch (main_vif->type) { - case NL80211_IFTYPE_STATION: - if (vif->type == NL80211_IFTYPE_STATION) - break; - - err = -EBUSY; - rcu_read_unlock(); - - goto unlock; - - case NL80211_IFTYPE_AP: - if ((vif->type == NL80211_IFTYPE_STATION) || - (vif->type == NL80211_IFTYPE_WDS) || - (vif->type == NL80211_IFTYPE_AP)) - break; - - err = -EBUSY; - rcu_read_unlock(); - goto unlock; - - default: - rcu_read_unlock(); - goto unlock; - } - } - - vif_id = bitmap_find_free_region(&ar->vif_bitmap, ar->fw.vif_num, 0); - - if (vif_id < 0) { - rcu_read_unlock(); - - err = -ENOSPC; - goto unlock; - } - - BUG_ON(ar->vif_priv[vif_id].id != vif_id); - - vif_priv->active = true; - vif_priv->id = vif_id; - vif_priv->enable_beacon = false; - ar->vifs++; - list_add_tail_rcu(&vif_priv->list, &ar->vif_list); - rcu_assign_pointer(ar->vif_priv[vif_id].vif, vif); - -init: - if (carl9170_get_main_vif(ar) == vif) { - rcu_assign_pointer(ar->beacon_iter, vif_priv); - rcu_read_unlock(); - - err = carl9170_init_interface(ar, vif); - if (err) - goto unlock; - } else { - rcu_read_unlock(); - err = carl9170_mod_virtual_mac(ar, vif_id, vif->addr); - - if (err) - goto unlock; - } - - if (ar->fw.tx_seq_table) { - err = carl9170_write_reg(ar, ar->fw.tx_seq_table + vif_id * 4, - 0); - if (err) - goto unlock; - } - -unlock: - if (err && (vif_id >= 0)) { - vif_priv->active = false; - bitmap_release_region(&ar->vif_bitmap, vif_id, 0); - ar->vifs--; - RCU_INIT_POINTER(ar->vif_priv[vif_id].vif, NULL); - list_del_rcu(&vif_priv->list); - mutex_unlock(&ar->mutex); - synchronize_rcu(); - } else { - if (ar->vifs > 1) - ar->ps.off_override |= PS_OFF_VIF; - - mutex_unlock(&ar->mutex); - } - - return err; -} - -static void carl9170_op_remove_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) -{ - struct carl9170_vif_info *vif_priv = (void *) vif->drv_priv; - struct ieee80211_vif *main_vif; - struct ar9170 *ar = hw->priv; - unsigned int id; - - mutex_lock(&ar->mutex); - - if (WARN_ON_ONCE(!vif_priv->active)) - goto unlock; - - ar->vifs--; - - rcu_read_lock(); - main_vif = carl9170_get_main_vif(ar); - - id = vif_priv->id; - - vif_priv->active = false; - WARN_ON(vif_priv->enable_beacon); - vif_priv->enable_beacon = false; - list_del_rcu(&vif_priv->list); - RCU_INIT_POINTER(ar->vif_priv[id].vif, NULL); - - if (vif == main_vif) { - rcu_read_unlock(); - - if (ar->vifs) { - WARN_ON(carl9170_init_interface(ar, - carl9170_get_main_vif(ar))); - } else { - carl9170_set_operating_mode(ar); - } - } else { - rcu_read_unlock(); - - WARN_ON(carl9170_mod_virtual_mac(ar, id, NULL)); - } - - carl9170_update_beacon(ar, false); - carl9170_flush_cab(ar, id); - - spin_lock_bh(&ar->beacon_lock); - dev_kfree_skb_any(vif_priv->beacon); - vif_priv->beacon = NULL; - spin_unlock_bh(&ar->beacon_lock); - - bitmap_release_region(&ar->vif_bitmap, id, 0); - - carl9170_set_beacon_timers(ar); - - if (ar->vifs == 1) - ar->ps.off_override &= ~PS_OFF_VIF; - -unlock: - mutex_unlock(&ar->mutex); - - synchronize_rcu(); -} - -void carl9170_ps_check(struct ar9170 *ar) -{ - ieee80211_queue_work(ar->hw, &ar->ps_work); -} - -/* caller must hold ar->mutex */ -static int carl9170_ps_update(struct ar9170 *ar) -{ - bool ps = false; - int err = 0; - - if (!ar->ps.off_override) - ps = (ar->hw->conf.flags & IEEE80211_CONF_PS); - - if (ps != ar->ps.state) { - err = carl9170_powersave(ar, ps); - if (err) - return err; - - if (ar->ps.state && !ps) { - ar->ps.sleep_ms = jiffies_to_msecs(jiffies - - ar->ps.last_action); - } - - if (ps) - ar->ps.last_slept = jiffies; - - ar->ps.last_action = jiffies; - ar->ps.state = ps; - } - - return 0; -} - -static void carl9170_ps_work(struct work_struct *work) -{ - struct ar9170 *ar = container_of(work, struct ar9170, - ps_work); - mutex_lock(&ar->mutex); - if (IS_STARTED(ar)) - WARN_ON_ONCE(carl9170_ps_update(ar) != 0); - mutex_unlock(&ar->mutex); -} - -static int carl9170_update_survey(struct ar9170 *ar, bool flush, bool noise) -{ - int err; - - if (noise) { - err = carl9170_get_noisefloor(ar); - if (err) - return err; - } - - if (ar->fw.hw_counters) { - err = carl9170_collect_tally(ar); - if (err) - return err; - } - - if (flush) - memset(&ar->tally, 0, sizeof(ar->tally)); - - return 0; -} - -static void carl9170_stat_work(struct work_struct *work) -{ - struct ar9170 *ar = container_of(work, struct ar9170, stat_work.work); - int err; - - mutex_lock(&ar->mutex); - err = carl9170_update_survey(ar, false, true); - mutex_unlock(&ar->mutex); - - if (err) - return; - - ieee80211_queue_delayed_work(ar->hw, &ar->stat_work, - round_jiffies(msecs_to_jiffies(CARL9170_STAT_WORK))); -} - -static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed) -{ - struct ar9170 *ar = hw->priv; - int err = 0; - - mutex_lock(&ar->mutex); - if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { - /* TODO */ - err = 0; - } - - if (changed & IEEE80211_CONF_CHANGE_PS) { - err = carl9170_ps_update(ar); - if (err) - goto out; - } - - if (changed & IEEE80211_CONF_CHANGE_SMPS) { - /* TODO */ - err = 0; - } - - if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { - /* adjust slot time for 5 GHz */ - err = carl9170_set_slot_time(ar); - if (err) - goto out; - - err = carl9170_update_survey(ar, true, false); - if (err) - goto out; - - err = carl9170_set_channel(ar, hw->conf.channel, - hw->conf.channel_type, CARL9170_RFI_NONE); - if (err) - goto out; - - err = carl9170_update_survey(ar, false, true); - if (err) - goto out; - - err = carl9170_set_dyn_sifs_ack(ar); - if (err) - goto out; - - err = carl9170_set_rts_cts_rate(ar); - if (err) - goto out; - } - - if (changed & IEEE80211_CONF_CHANGE_POWER) { - err = carl9170_set_mac_tpc(ar, ar->hw->conf.channel); - if (err) - goto out; - } - -out: - mutex_unlock(&ar->mutex); - return err; -} - -static u64 carl9170_op_prepare_multicast(struct ieee80211_hw *hw, - struct netdev_hw_addr_list *mc_list) -{ - struct netdev_hw_addr *ha; - u64 mchash; - - /* always get broadcast frames */ - mchash = 1ULL << (0xff >> 2); - - netdev_hw_addr_list_for_each(ha, mc_list) - mchash |= 1ULL << (ha->addr[5] >> 2); - - return mchash; -} - -static void carl9170_op_configure_filter(struct ieee80211_hw *hw, - unsigned int changed_flags, - unsigned int *new_flags, - u64 multicast) -{ - struct ar9170 *ar = hw->priv; - - /* mask supported flags */ - *new_flags &= FIF_ALLMULTI | ar->rx_filter_caps; - - if (!IS_ACCEPTING_CMD(ar)) - return; - - mutex_lock(&ar->mutex); - - ar->filter_state = *new_flags; - /* - * We can support more by setting the sniffer bit and - * then checking the error flags, later. - */ - - if (*new_flags & FIF_ALLMULTI) - multicast = ~0ULL; - - if (multicast != ar->cur_mc_hash) - WARN_ON(carl9170_update_multicast(ar, multicast)); - - if (changed_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS)) { - ar->sniffer_enabled = !!(*new_flags & - (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS)); - - WARN_ON(carl9170_set_operating_mode(ar)); - } - - if (ar->fw.rx_filter && changed_flags & ar->rx_filter_caps) { - u32 rx_filter = 0; - - if (!(*new_flags & (FIF_FCSFAIL | FIF_PLCPFAIL))) - rx_filter |= CARL9170_RX_FILTER_BAD; - - if (!(*new_flags & FIF_CONTROL)) - rx_filter |= CARL9170_RX_FILTER_CTL_OTHER; - - if (!(*new_flags & FIF_PSPOLL)) - rx_filter |= CARL9170_RX_FILTER_CTL_PSPOLL; - - if (!(*new_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS))) { - rx_filter |= CARL9170_RX_FILTER_OTHER_RA; - rx_filter |= CARL9170_RX_FILTER_DECRY_FAIL; - } - - WARN_ON(carl9170_rx_filter(ar, rx_filter)); - } - - mutex_unlock(&ar->mutex); -} - - -static void carl9170_op_bss_info_changed(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_bss_conf *bss_conf, - u32 changed) -{ - struct ar9170 *ar = hw->priv; - struct ath_common *common = &ar->common; - int err = 0; - struct carl9170_vif_info *vif_priv; - struct ieee80211_vif *main_vif; - - mutex_lock(&ar->mutex); - vif_priv = (void *) vif->drv_priv; - main_vif = carl9170_get_main_vif(ar); - if (WARN_ON(!main_vif)) - goto out; - - if (changed & BSS_CHANGED_BEACON_ENABLED) { - struct carl9170_vif_info *iter; - int i = 0; - - vif_priv->enable_beacon = bss_conf->enable_beacon; - rcu_read_lock(); - list_for_each_entry_rcu(iter, &ar->vif_list, list) { - if (iter->active && iter->enable_beacon) - i++; - - } - rcu_read_unlock(); - - ar->beacon_enabled = i; - } - - if (changed & BSS_CHANGED_BEACON) { - err = carl9170_update_beacon(ar, false); - if (err) - goto out; - } - - if (changed & (BSS_CHANGED_BEACON_ENABLED | BSS_CHANGED_BEACON | - BSS_CHANGED_BEACON_INT)) { - - if (main_vif != vif) { - bss_conf->beacon_int = main_vif->bss_conf.beacon_int; - bss_conf->dtim_period = main_vif->bss_conf.dtim_period; - } - - /* - * Therefore a hard limit for the broadcast traffic should - * prevent false alarms. - */ - if (vif->type != NL80211_IFTYPE_STATION && - (bss_conf->beacon_int * bss_conf->dtim_period >= - (CARL9170_QUEUE_STUCK_TIMEOUT / 2))) { - err = -EINVAL; - goto out; - } - - err = carl9170_set_beacon_timers(ar); - if (err) - goto out; - } - - if (changed & BSS_CHANGED_HT) { - /* TODO */ - err = 0; - if (err) - goto out; - } - - if (main_vif != vif) - goto out; - - /* - * The following settings can only be changed by the - * master interface. - */ - - if (changed & BSS_CHANGED_BSSID) { - memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); - err = carl9170_set_operating_mode(ar); - if (err) - goto out; - } - - if (changed & BSS_CHANGED_ASSOC) { - ar->common.curaid = bss_conf->aid; - err = carl9170_set_beacon_timers(ar); - if (err) - goto out; - } - - if (changed & BSS_CHANGED_ERP_SLOT) { - err = carl9170_set_slot_time(ar); - if (err) - goto out; - } - - if (changed & BSS_CHANGED_BASIC_RATES) { - err = carl9170_set_mac_rates(ar); - if (err) - goto out; - } - -out: - WARN_ON_ONCE(err && IS_STARTED(ar)); - mutex_unlock(&ar->mutex); -} - -static u64 carl9170_op_get_tsf(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) -{ - struct ar9170 *ar = hw->priv; - struct carl9170_tsf_rsp tsf; - int err; - - mutex_lock(&ar->mutex); - err = carl9170_exec_cmd(ar, CARL9170_CMD_READ_TSF, - 0, NULL, sizeof(tsf), &tsf); - mutex_unlock(&ar->mutex); - if (WARN_ON(err)) - return 0; - - return le64_to_cpu(tsf.tsf_64); -} - -static int carl9170_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta, - struct ieee80211_key_conf *key) -{ - struct ar9170 *ar = hw->priv; - int err = 0, i; - u8 ktype; - - if (ar->disable_offload || !vif) - return -EOPNOTSUPP; - - /* - * We have to fall back to software encryption, whenever - * the user choose to participates in an IBSS or is connected - * to more than one network. - * - * This is very unfortunate, because some machines cannot handle - * the high througput speed in 802.11n networks. - */ - - if (!is_main_vif(ar, vif)) { - mutex_lock(&ar->mutex); - goto err_softw; - } - - /* - * While the hardware supports *catch-all* key, for offloading - * group-key en-/de-cryption. The way of how the hardware - * decides which keyId maps to which key, remains a mystery... - */ - if ((vif->type != NL80211_IFTYPE_STATION && - vif->type != NL80211_IFTYPE_ADHOC) && - !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) - return -EOPNOTSUPP; - - switch (key->cipher) { - case WLAN_CIPHER_SUITE_WEP40: - ktype = AR9170_ENC_ALG_WEP64; - break; - case WLAN_CIPHER_SUITE_WEP104: - ktype = AR9170_ENC_ALG_WEP128; - break; - case WLAN_CIPHER_SUITE_TKIP: - ktype = AR9170_ENC_ALG_TKIP; - break; - case WLAN_CIPHER_SUITE_CCMP: - ktype = AR9170_ENC_ALG_AESCCMP; - break; - default: - return -EOPNOTSUPP; - } - - mutex_lock(&ar->mutex); - if (cmd == SET_KEY) { - if (!IS_STARTED(ar)) { - err = -EOPNOTSUPP; - goto out; - } - - if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { - sta = NULL; - - i = 64 + key->keyidx; - } else { - for (i = 0; i < 64; i++) - if (!(ar->usedkeys & BIT(i))) - break; - if (i == 64) - goto err_softw; - } - - key->hw_key_idx = i; - - err = carl9170_upload_key(ar, i, sta ? sta->addr : NULL, - ktype, 0, key->key, - min_t(u8, 16, key->keylen)); - if (err) - goto out; - - if (key->cipher == WLAN_CIPHER_SUITE_TKIP) { - err = carl9170_upload_key(ar, i, sta ? sta->addr : - NULL, ktype, 1, - key->key + 16, 16); - if (err) - goto out; - - /* - * hardware is not capable generating MMIC - * of fragmented frames! - */ - key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; - } - - if (i < 64) - ar->usedkeys |= BIT(i); - - key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; - } else { - if (!IS_STARTED(ar)) { - /* The device is gone... together with the key ;-) */ - err = 0; - goto out; - } - - if (key->hw_key_idx < 64) { - ar->usedkeys &= ~BIT(key->hw_key_idx); - } else { - err = carl9170_upload_key(ar, key->hw_key_idx, NULL, - AR9170_ENC_ALG_NONE, 0, - NULL, 0); - if (err) - goto out; - - if (key->cipher == WLAN_CIPHER_SUITE_TKIP) { - err = carl9170_upload_key(ar, key->hw_key_idx, - NULL, - AR9170_ENC_ALG_NONE, - 1, NULL, 0); - if (err) - goto out; - } - - } - - err = carl9170_disable_key(ar, key->hw_key_idx); - if (err) - goto out; - } - -out: - mutex_unlock(&ar->mutex); - return err; - -err_softw: - if (!ar->rx_software_decryption) { - ar->rx_software_decryption = true; - carl9170_set_operating_mode(ar); - } - mutex_unlock(&ar->mutex); - return -ENOSPC; -} - -static int carl9170_op_sta_add(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta) -{ - struct carl9170_sta_info *sta_info = (void *) sta->drv_priv; - unsigned int i; - - atomic_set(&sta_info->pending_frames, 0); - - if (sta->ht_cap.ht_supported) { - if (sta->ht_cap.ampdu_density > 6) { - /* - * HW does support 16us AMPDU density. - * No HT-Xmit for station. - */ - - return 0; - } - - for (i = 0; i < CARL9170_NUM_TID; i++) - RCU_INIT_POINTER(sta_info->agg[i], NULL); - - sta_info->ampdu_max_len = 1 << (3 + sta->ht_cap.ampdu_factor); - sta_info->ht_sta = true; - } - - return 0; -} - -static int carl9170_op_sta_remove(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta) -{ - struct ar9170 *ar = hw->priv; - struct carl9170_sta_info *sta_info = (void *) sta->drv_priv; - unsigned int i; - bool cleanup = false; - - if (sta->ht_cap.ht_supported) { - - sta_info->ht_sta = false; - - rcu_read_lock(); - for (i = 0; i < CARL9170_NUM_TID; i++) { - struct carl9170_sta_tid *tid_info; - - tid_info = rcu_dereference(sta_info->agg[i]); - RCU_INIT_POINTER(sta_info->agg[i], NULL); - - if (!tid_info) - continue; - - spin_lock_bh(&ar->tx_ampdu_list_lock); - if (tid_info->state > CARL9170_TID_STATE_SHUTDOWN) - tid_info->state = CARL9170_TID_STATE_SHUTDOWN; - spin_unlock_bh(&ar->tx_ampdu_list_lock); - cleanup = true; - } - rcu_read_unlock(); - - if (cleanup) - carl9170_ampdu_gc(ar); - } - - return 0; -} - -static int carl9170_op_conf_tx(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, u16 queue, - const struct ieee80211_tx_queue_params *param) -{ - struct ar9170 *ar = hw->priv; - int ret; - - mutex_lock(&ar->mutex); - if (queue < ar->hw->queues) { - memcpy(&ar->edcf[ar9170_qmap[queue]], param, sizeof(*param)); - ret = carl9170_set_qos(ar); - } else { - ret = -EINVAL; - } - - mutex_unlock(&ar->mutex); - return ret; -} - -static void carl9170_ampdu_work(struct work_struct *work) -{ - struct ar9170 *ar = container_of(work, struct ar9170, - ampdu_work); - - if (!IS_STARTED(ar)) - return; - - mutex_lock(&ar->mutex); - carl9170_ampdu_gc(ar); - mutex_unlock(&ar->mutex); -} - -static int carl9170_op_ampdu_action(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - enum ieee80211_ampdu_mlme_action action, - struct ieee80211_sta *sta, - u16 tid, u16 *ssn, u8 buf_size) -{ - struct ar9170 *ar = hw->priv; - struct carl9170_sta_info *sta_info = (void *) sta->drv_priv; - struct carl9170_sta_tid *tid_info; - - if (modparam_noht) - return -EOPNOTSUPP; - - switch (action) { - case IEEE80211_AMPDU_TX_START: - if (!sta_info->ht_sta) - return -EOPNOTSUPP; - - rcu_read_lock(); - if (rcu_dereference(sta_info->agg[tid])) { - rcu_read_unlock(); - return -EBUSY; - } - - tid_info = kzalloc(sizeof(struct carl9170_sta_tid), - GFP_ATOMIC); - if (!tid_info) { - rcu_read_unlock(); - return -ENOMEM; - } - - tid_info->hsn = tid_info->bsn = tid_info->snx = (*ssn); - tid_info->state = CARL9170_TID_STATE_PROGRESS; - tid_info->tid = tid; - tid_info->max = sta_info->ampdu_max_len; - - INIT_LIST_HEAD(&tid_info->list); - INIT_LIST_HEAD(&tid_info->tmp_list); - skb_queue_head_init(&tid_info->queue); - spin_lock_init(&tid_info->lock); - - spin_lock_bh(&ar->tx_ampdu_list_lock); - ar->tx_ampdu_list_len++; - list_add_tail_rcu(&tid_info->list, &ar->tx_ampdu_list); - rcu_assign_pointer(sta_info->agg[tid], tid_info); - spin_unlock_bh(&ar->tx_ampdu_list_lock); - rcu_read_unlock(); - - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); - break; - - case IEEE80211_AMPDU_TX_STOP: - rcu_read_lock(); - tid_info = rcu_dereference(sta_info->agg[tid]); - if (tid_info) { - spin_lock_bh(&ar->tx_ampdu_list_lock); - if (tid_info->state > CARL9170_TID_STATE_SHUTDOWN) - tid_info->state = CARL9170_TID_STATE_SHUTDOWN; - spin_unlock_bh(&ar->tx_ampdu_list_lock); - } - - RCU_INIT_POINTER(sta_info->agg[tid], NULL); - rcu_read_unlock(); - - ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); - ieee80211_queue_work(ar->hw, &ar->ampdu_work); - break; - - case IEEE80211_AMPDU_TX_OPERATIONAL: - rcu_read_lock(); - tid_info = rcu_dereference(sta_info->agg[tid]); - - sta_info->stats[tid].clear = true; - sta_info->stats[tid].req = false; - - if (tid_info) { - bitmap_zero(tid_info->bitmap, CARL9170_BAW_SIZE); - tid_info->state = CARL9170_TID_STATE_IDLE; - } - rcu_read_unlock(); - - if (WARN_ON_ONCE(!tid_info)) - return -EFAULT; - - break; - - case IEEE80211_AMPDU_RX_START: - case IEEE80211_AMPDU_RX_STOP: - /* Handled by hardware */ - break; - - default: - return -EOPNOTSUPP; - } - - return 0; -} - -#ifdef CONFIG_CARL9170_WPC -static int carl9170_register_wps_button(struct ar9170 *ar) -{ - struct input_dev *input; - int err; - - if (!(ar->features & CARL9170_WPS_BUTTON)) - return 0; - - input = input_allocate_device(); - if (!input) - return -ENOMEM; - - snprintf(ar->wps.name, sizeof(ar->wps.name), "%s WPS Button", - wiphy_name(ar->hw->wiphy)); - - snprintf(ar->wps.phys, sizeof(ar->wps.phys), - "ieee80211/%s/input0", wiphy_name(ar->hw->wiphy)); - - input->name = ar->wps.name; - input->phys = ar->wps.phys; - input->id.bustype = BUS_USB; - input->dev.parent = &ar->hw->wiphy->dev; - - input_set_capability(input, EV_KEY, KEY_WPS_BUTTON); - - err = input_register_device(input); - if (err) { - input_free_device(input); - return err; - } - - ar->wps.pbc = input; - return 0; -} -#endif /* CONFIG_CARL9170_WPC */ - -#ifdef CONFIG_CARL9170_HWRNG -static int carl9170_rng_get(struct ar9170 *ar) -{ - -#define RW (CARL9170_MAX_CMD_PAYLOAD_LEN / sizeof(u32)) -#define RB (CARL9170_MAX_CMD_PAYLOAD_LEN) - - static const __le32 rng_load[RW] = { - [0 ... (RW - 1)] = cpu_to_le32(AR9170_RAND_REG_NUM)}; - - u32 buf[RW]; - - unsigned int i, off = 0, transfer, count; - int err; - - BUILD_BUG_ON(RB > CARL9170_MAX_CMD_PAYLOAD_LEN); - - if (!IS_ACCEPTING_CMD(ar) || !ar->rng.initialized) - return -EAGAIN; - - count = ARRAY_SIZE(ar->rng.cache); - while (count) { - err = carl9170_exec_cmd(ar, CARL9170_CMD_RREG, - RB, (u8 *) rng_load, - RB, (u8 *) buf); - if (err) - return err; - - transfer = min_t(unsigned int, count, RW); - for (i = 0; i < transfer; i++) - ar->rng.cache[off + i] = buf[i]; - - off += transfer; - count -= transfer; - } - - ar->rng.cache_idx = 0; - -#undef RW -#undef RB - return 0; -} - -static int carl9170_rng_read(struct hwrng *rng, u32 *data) -{ - struct ar9170 *ar = (struct ar9170 *)rng->priv; - int ret = -EIO; - - mutex_lock(&ar->mutex); - if (ar->rng.cache_idx >= ARRAY_SIZE(ar->rng.cache)) { - ret = carl9170_rng_get(ar); - if (ret) { - mutex_unlock(&ar->mutex); - return ret; - } - } - - *data = ar->rng.cache[ar->rng.cache_idx++]; - mutex_unlock(&ar->mutex); - - return sizeof(u16); -} - -static void carl9170_unregister_hwrng(struct ar9170 *ar) -{ - if (ar->rng.initialized) { - hwrng_unregister(&ar->rng.rng); - ar->rng.initialized = false; - } -} - -static int carl9170_register_hwrng(struct ar9170 *ar) -{ - int err; - - snprintf(ar->rng.name, ARRAY_SIZE(ar->rng.name), - "%s_%s", KBUILD_MODNAME, wiphy_name(ar->hw->wiphy)); - ar->rng.rng.name = ar->rng.name; - ar->rng.rng.data_read = carl9170_rng_read; - ar->rng.rng.priv = (unsigned long)ar; - - if (WARN_ON(ar->rng.initialized)) - return -EALREADY; - - err = hwrng_register(&ar->rng.rng); - if (err) { - dev_err(&ar->udev->dev, "Failed to register the random " - "number generator (%d)\n", err); - return err; - } - - ar->rng.initialized = true; - - err = carl9170_rng_get(ar); - if (err) { - carl9170_unregister_hwrng(ar); - return err; - } - - return 0; -} -#endif /* CONFIG_CARL9170_HWRNG */ - -static int carl9170_op_get_survey(struct ieee80211_hw *hw, int idx, - struct survey_info *survey) -{ - struct ar9170 *ar = hw->priv; - struct ieee80211_channel *chan; - struct ieee80211_supported_band *band; - int err, b, i; - - chan = ar->channel; - if (!chan) - return -ENODEV; - - if (idx == chan->hw_value) { - mutex_lock(&ar->mutex); - err = carl9170_update_survey(ar, false, true); - mutex_unlock(&ar->mutex); - if (err) - return err; - } - - for (b = 0; b < IEEE80211_NUM_BANDS; b++) { - band = ar->hw->wiphy->bands[b]; - - if (!band) - continue; - - for (i = 0; i < band->n_channels; i++) { - if (band->channels[i].hw_value == idx) { - chan = &band->channels[i]; - goto found; - } - } - } - return -ENOENT; - -found: - memcpy(survey, &ar->survey[idx], sizeof(*survey)); - - survey->channel = chan; - survey->filled = SURVEY_INFO_NOISE_DBM; - - if (ar->channel == chan) - survey->filled |= SURVEY_INFO_IN_USE; - - if (ar->fw.hw_counters) { - survey->filled |= SURVEY_INFO_CHANNEL_TIME | - SURVEY_INFO_CHANNEL_TIME_BUSY | - SURVEY_INFO_CHANNEL_TIME_TX; - } - - return 0; -} - -static void carl9170_op_flush(struct ieee80211_hw *hw, bool drop) -{ - struct ar9170 *ar = hw->priv; - unsigned int vid; - - mutex_lock(&ar->mutex); - for_each_set_bit(vid, &ar->vif_bitmap, ar->fw.vif_num) - carl9170_flush_cab(ar, vid); - - carl9170_flush(ar, drop); - mutex_unlock(&ar->mutex); -} - -static int carl9170_op_get_stats(struct ieee80211_hw *hw, - struct ieee80211_low_level_stats *stats) -{ - struct ar9170 *ar = hw->priv; - - memset(stats, 0, sizeof(*stats)); - stats->dot11ACKFailureCount = ar->tx_ack_failures; - stats->dot11FCSErrorCount = ar->tx_fcs_errors; - return 0; -} - -static void carl9170_op_sta_notify(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - enum sta_notify_cmd cmd, - struct ieee80211_sta *sta) -{ - struct carl9170_sta_info *sta_info = (void *) sta->drv_priv; - - switch (cmd) { - case STA_NOTIFY_SLEEP: - sta_info->sleeping = true; - if (atomic_read(&sta_info->pending_frames)) - ieee80211_sta_block_awake(hw, sta, true); - break; - - case STA_NOTIFY_AWAKE: - sta_info->sleeping = false; - break; - } -} - -static bool carl9170_tx_frames_pending(struct ieee80211_hw *hw) -{ - struct ar9170 *ar = hw->priv; - - return !!atomic_read(&ar->tx_total_queued); -} - -static const struct ieee80211_ops carl9170_ops = { - .start = carl9170_op_start, - .stop = carl9170_op_stop, - .tx = carl9170_op_tx, - .flush = carl9170_op_flush, - .add_interface = carl9170_op_add_interface, - .remove_interface = carl9170_op_remove_interface, - .config = carl9170_op_config, - .prepare_multicast = carl9170_op_prepare_multicast, - .configure_filter = carl9170_op_configure_filter, - .conf_tx = carl9170_op_conf_tx, - .bss_info_changed = carl9170_op_bss_info_changed, - .get_tsf = carl9170_op_get_tsf, - .set_key = carl9170_op_set_key, - .sta_add = carl9170_op_sta_add, - .sta_remove = carl9170_op_sta_remove, - .sta_notify = carl9170_op_sta_notify, - .get_survey = carl9170_op_get_survey, - .get_stats = carl9170_op_get_stats, - .ampdu_action = carl9170_op_ampdu_action, - .tx_frames_pending = carl9170_tx_frames_pending, -}; - -void *carl9170_alloc(size_t priv_size) -{ - struct ieee80211_hw *hw; - struct ar9170 *ar; - struct sk_buff *skb; - int i; - - /* - * this buffer is used for rx stream reconstruction. - * Under heavy load this device (or the transport layer?) - * tends to split the streams into separate rx descriptors. - */ - - skb = __dev_alloc_skb(AR9170_RX_STREAM_MAX_SIZE, GFP_KERNEL); - if (!skb) - goto err_nomem; - - hw = ieee80211_alloc_hw(priv_size, &carl9170_ops); - if (!hw) - goto err_nomem; - - ar = hw->priv; - ar->hw = hw; - ar->rx_failover = skb; - - memset(&ar->rx_plcp, 0, sizeof(struct ar9170_rx_head)); - ar->rx_has_plcp = false; - - /* - * Here's a hidden pitfall! - * - * All 4 AC queues work perfectly well under _legacy_ operation. - * However as soon as aggregation is enabled, the traffic flow - * gets very bumpy. Therefore we have to _switch_ to a - * software AC with a single HW queue. - */ - hw->queues = __AR9170_NUM_TXQ; - - mutex_init(&ar->mutex); - spin_lock_init(&ar->beacon_lock); - spin_lock_init(&ar->cmd_lock); - spin_lock_init(&ar->tx_stats_lock); - spin_lock_init(&ar->tx_ampdu_list_lock); - spin_lock_init(&ar->mem_lock); - spin_lock_init(&ar->state_lock); - atomic_set(&ar->pending_restarts, 0); - ar->vifs = 0; - for (i = 0; i < ar->hw->queues; i++) { - skb_queue_head_init(&ar->tx_status[i]); - skb_queue_head_init(&ar->tx_pending[i]); - } - INIT_WORK(&ar->ps_work, carl9170_ps_work); - INIT_WORK(&ar->ping_work, carl9170_ping_work); - INIT_WORK(&ar->restart_work, carl9170_restart_work); - INIT_WORK(&ar->ampdu_work, carl9170_ampdu_work); - INIT_DELAYED_WORK(&ar->stat_work, carl9170_stat_work); - INIT_DELAYED_WORK(&ar->tx_janitor, carl9170_tx_janitor); - INIT_LIST_HEAD(&ar->tx_ampdu_list); - rcu_assign_pointer(ar->tx_ampdu_iter, - (struct carl9170_sta_tid *) &ar->tx_ampdu_list); - - bitmap_zero(&ar->vif_bitmap, ar->fw.vif_num); - INIT_LIST_HEAD(&ar->vif_list); - init_completion(&ar->tx_flush); - - /* firmware decides which modes we support */ - hw->wiphy->interface_modes = 0; - - hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS | - IEEE80211_HW_REPORTS_TX_ACK_STATUS | - IEEE80211_HW_SUPPORTS_PS | - IEEE80211_HW_PS_NULLFUNC_STACK | - IEEE80211_HW_NEED_DTIM_PERIOD | - IEEE80211_HW_SIGNAL_DBM; - - if (!modparam_noht) { - /* - * see the comment above, why we allow the user - * to disable HT by a module parameter. - */ - hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION; - } - - hw->extra_tx_headroom = sizeof(struct _carl9170_tx_superframe); - hw->sta_data_size = sizeof(struct carl9170_sta_info); - hw->vif_data_size = sizeof(struct carl9170_vif_info); - - hw->max_rates = CARL9170_TX_MAX_RATES; - hw->max_rate_tries = CARL9170_TX_USER_RATE_TRIES; - - for (i = 0; i < ARRAY_SIZE(ar->noise); i++) - ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */ - - hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; - - /* As IBSS Encryption is software-based, IBSS RSN is supported. */ - hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; - return ar; - -err_nomem: - kfree_skb(skb); - return ERR_PTR(-ENOMEM); -} - -static int carl9170_read_eeprom(struct ar9170 *ar) -{ -#define RW 8 /* number of words to read at once */ -#define RB (sizeof(u32) * RW) - u8 *eeprom = (void *)&ar->eeprom; - __le32 offsets[RW]; - int i, j, err; - - BUILD_BUG_ON(sizeof(ar->eeprom) & 3); - - BUILD_BUG_ON(RB > CARL9170_MAX_CMD_LEN - 4); -#ifndef __CHECKER__ - /* don't want to handle trailing remains */ - BUILD_BUG_ON(sizeof(ar->eeprom) % RB); -#endif - - for (i = 0; i < sizeof(ar->eeprom) / RB; i++) { - for (j = 0; j < RW; j++) - offsets[j] = cpu_to_le32(AR9170_EEPROM_START + - RB * i + 4 * j); - - err = carl9170_exec_cmd(ar, CARL9170_CMD_RREG, - RB, (u8 *) &offsets, - RB, eeprom + RB * i); - if (err) - return err; - } - -#undef RW -#undef RB - return 0; -} - -static int carl9170_parse_eeprom(struct ar9170 *ar) -{ - struct ath_regulatory *regulatory = &ar->common.regulatory; - unsigned int rx_streams, tx_streams, tx_params = 0; - int bands = 0; - int chans = 0; - - if (ar->eeprom.length == cpu_to_le16(0xffff)) - return -ENODATA; - - rx_streams = hweight8(ar->eeprom.rx_mask); - tx_streams = hweight8(ar->eeprom.tx_mask); - - if (rx_streams != tx_streams) { - tx_params = IEEE80211_HT_MCS_TX_RX_DIFF; - - WARN_ON(!(tx_streams >= 1 && tx_streams <= - IEEE80211_HT_MCS_TX_MAX_STREAMS)); - - tx_params = (tx_streams - 1) << - IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT; - - carl9170_band_2GHz.ht_cap.mcs.tx_params |= tx_params; - carl9170_band_5GHz.ht_cap.mcs.tx_params |= tx_params; - } - - if (ar->eeprom.operating_flags & AR9170_OPFLAG_2GHZ) { - ar->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = - &carl9170_band_2GHz; - chans += carl9170_band_2GHz.n_channels; - bands++; - } - if (ar->eeprom.operating_flags & AR9170_OPFLAG_5GHZ) { - ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = - &carl9170_band_5GHz; - chans += carl9170_band_5GHz.n_channels; - bands++; - } - - if (!bands) - return -EINVAL; - - ar->survey = kzalloc(sizeof(struct survey_info) * chans, GFP_KERNEL); - if (!ar->survey) - return -ENOMEM; - ar->num_channels = chans; - - /* - * I measured this, a bandswitch takes roughly - * 135 ms and a frequency switch about 80. - * - * FIXME: measure these values again once EEPROM settings - * are used, that will influence them! - */ - if (bands == 2) - ar->hw->channel_change_time = 135 * 1000; - else - ar->hw->channel_change_time = 80 * 1000; - - regulatory->current_rd = le16_to_cpu(ar->eeprom.reg_domain[0]); - - /* second part of wiphy init */ - SET_IEEE80211_PERM_ADDR(ar->hw, ar->eeprom.mac_address); - - return 0; -} - -static int carl9170_reg_notifier(struct wiphy *wiphy, - struct regulatory_request *request) -{ - struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); - struct ar9170 *ar = hw->priv; - - return ath_reg_notifier_apply(wiphy, request, &ar->common.regulatory); -} - -int carl9170_register(struct ar9170 *ar) -{ - struct ath_regulatory *regulatory = &ar->common.regulatory; - int err = 0, i; - - if (WARN_ON(ar->mem_bitmap)) - return -EINVAL; - - ar->mem_bitmap = kzalloc(roundup(ar->fw.mem_blocks, BITS_PER_LONG) * - sizeof(unsigned long), GFP_KERNEL); - - if (!ar->mem_bitmap) - return -ENOMEM; - - /* try to read EEPROM, init MAC addr */ - err = carl9170_read_eeprom(ar); - if (err) - return err; - - err = carl9170_parse_eeprom(ar); - if (err) - return err; - - err = ath_regd_init(regulatory, ar->hw->wiphy, - carl9170_reg_notifier); - if (err) - return err; - - if (modparam_noht) { - carl9170_band_2GHz.ht_cap.ht_supported = false; - carl9170_band_5GHz.ht_cap.ht_supported = false; - } - - for (i = 0; i < ar->fw.vif_num; i++) { - ar->vif_priv[i].id = i; - ar->vif_priv[i].vif = NULL; - } - - err = ieee80211_register_hw(ar->hw); - if (err) - return err; - - /* mac80211 interface is now registered */ - ar->registered = true; - - if (!ath_is_world_regd(regulatory)) - regulatory_hint(ar->hw->wiphy, regulatory->alpha2); - -#ifdef CONFIG_CARL9170_DEBUGFS - carl9170_debugfs_register(ar); -#endif /* CONFIG_CARL9170_DEBUGFS */ - - err = carl9170_led_init(ar); - if (err) - goto err_unreg; - -#ifdef CONFIG_CARL9170_LEDS - err = carl9170_led_register(ar); - if (err) - goto err_unreg; -#endif /* CONFIG_CARL9170_LEDS */ - -#ifdef CONFIG_CARL9170_WPC - err = carl9170_register_wps_button(ar); - if (err) - goto err_unreg; -#endif /* CONFIG_CARL9170_WPC */ - -#ifdef CONFIG_CARL9170_HWRNG - err = carl9170_register_hwrng(ar); - if (err) - goto err_unreg; -#endif /* CONFIG_CARL9170_HWRNG */ - - dev_info(&ar->udev->dev, "Atheros AR9170 is registered as '%s'\n", - wiphy_name(ar->hw->wiphy)); - - return 0; - -err_unreg: - carl9170_unregister(ar); - return err; -} - -void carl9170_unregister(struct ar9170 *ar) -{ - if (!ar->registered) - return; - - ar->registered = false; - -#ifdef CONFIG_CARL9170_LEDS - carl9170_led_unregister(ar); -#endif /* CONFIG_CARL9170_LEDS */ - -#ifdef CONFIG_CARL9170_DEBUGFS - carl9170_debugfs_unregister(ar); -#endif /* CONFIG_CARL9170_DEBUGFS */ - -#ifdef CONFIG_CARL9170_WPC - if (ar->wps.pbc) { - input_unregister_device(ar->wps.pbc); - ar->wps.pbc = NULL; - } -#endif /* CONFIG_CARL9170_WPC */ - -#ifdef CONFIG_CARL9170_HWRNG - carl9170_unregister_hwrng(ar); -#endif /* CONFIG_CARL9170_HWRNG */ - - carl9170_cancel_worker(ar); - cancel_work_sync(&ar->restart_work); - - ieee80211_unregister_hw(ar->hw); -} - -void carl9170_free(struct ar9170 *ar) -{ - WARN_ON(ar->registered); - WARN_ON(IS_INITIALIZED(ar)); - - kfree_skb(ar->rx_failover); - ar->rx_failover = NULL; - - kfree(ar->mem_bitmap); - ar->mem_bitmap = NULL; - - kfree(ar->survey); - ar->survey = NULL; - - mutex_destroy(&ar->mutex); - - ieee80211_free_hw(ar->hw); -} diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/phy.c b/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/phy.c deleted file mode 100644 index b72c09cf..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/phy.c +++ /dev/null @@ -1,1763 +0,0 @@ -/* - * Atheros CARL9170 driver - * - * PHY and RF code - * - * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, see - * http://www.gnu.org/licenses/. - * - * This file incorporates work covered by the following copyright and - * permission notice: - * Copyright (c) 2007-2008 Atheros Communications, Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <linux/bitrev.h> -#include "carl9170.h" -#include "cmd.h" -#include "phy.h" - -static int carl9170_init_power_cal(struct ar9170 *ar) -{ - carl9170_regwrite_begin(ar); - - carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE_MAX, 0x7f); - carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE1, 0x3f3f3f3f); - carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE2, 0x3f3f3f3f); - carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE3, 0x3f3f3f3f); - carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE4, 0x3f3f3f3f); - carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE5, 0x3f3f3f3f); - carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE6, 0x3f3f3f3f); - carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE7, 0x3f3f3f3f); - carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE8, 0x3f3f3f3f); - carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE9, 0x3f3f3f3f); - - carl9170_regwrite_finish(); - return carl9170_regwrite_result(); -} - -struct carl9170_phy_init { - u32 reg, _5ghz_20, _5ghz_40, _2ghz_40, _2ghz_20; -}; - -static struct carl9170_phy_init ar5416_phy_init[] = { - { 0x1c5800, 0x00000007, 0x00000007, 0x00000007, 0x00000007, }, - { 0x1c5804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, }, - { 0x1c5808, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c580c, 0xad848e19, 0xad848e19, 0xad848e19, 0xad848e19, }, - { 0x1c5810, 0x7d14e000, 0x7d14e000, 0x7d14e000, 0x7d14e000, }, - { 0x1c5814, 0x9c0a9f6b, 0x9c0a9f6b, 0x9c0a9f6b, 0x9c0a9f6b, }, - { 0x1c5818, 0x00000090, 0x00000090, 0x00000090, 0x00000090, }, - { 0x1c581c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, }, - { 0x1c5824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, }, - { 0x1c5828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, }, - { 0x1c582c, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, }, - { 0x1c5830, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, }, - { 0x1c5838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, }, - { 0x1c583c, 0x00200400, 0x00200400, 0x00200400, 0x00200400, }, - { 0x1c5840, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e, }, - { 0x1c5844, 0x1372161e, 0x13721c1e, 0x13721c24, 0x137216a4, }, - { 0x1c5848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, }, - { 0x1c584c, 0x1284233c, 0x1284233c, 0x1284233c, 0x1284233c, }, - { 0x1c5850, 0x6c48b4e4, 0x6d48b4e4, 0x6d48b0e4, 0x6c48b0e4, }, - { 0x1c5854, 0x00000859, 0x00000859, 0x00000859, 0x00000859, }, - { 0x1c5858, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, }, - { 0x1c585c, 0x31395c5e, 0x3139605e, 0x3139605e, 0x31395c5e, }, - { 0x1c5860, 0x0004dd10, 0x0004dd10, 0x0004dd20, 0x0004dd20, }, - { 0x1c5864, 0x0001c600, 0x0001c600, 0x0001c600, 0x0001c600, }, - { 0x1c5868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, }, - { 0x1c586c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, }, - { 0x1c5900, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5904, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5908, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c590c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, }, - { 0x1c5918, 0x00000118, 0x00000230, 0x00000268, 0x00000134, }, - { 0x1c591c, 0x10000fff, 0x10000fff, 0x10000fff, 0x10000fff, }, - { 0x1c5920, 0x0510081c, 0x0510081c, 0x0510001c, 0x0510001c, }, - { 0x1c5924, 0xd0058a15, 0xd0058a15, 0xd0058a15, 0xd0058a15, }, - { 0x1c5928, 0x00000001, 0x00000001, 0x00000001, 0x00000001, }, - { 0x1c592c, 0x00000004, 0x00000004, 0x00000004, 0x00000004, }, - { 0x1c5934, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, - { 0x1c5938, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, - { 0x1c593c, 0x0000007f, 0x0000007f, 0x0000007f, 0x0000007f, }, - { 0x1c5944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, }, - { 0x1c5948, 0x9280b212, 0x9280b212, 0x9280b212, 0x9280b212, }, - { 0x1c594c, 0x00020028, 0x00020028, 0x00020028, 0x00020028, }, - { 0x1c5954, 0x5d50e188, 0x5d50e188, 0x5d50e188, 0x5d50e188, }, - { 0x1c5958, 0x00081fff, 0x00081fff, 0x00081fff, 0x00081fff, }, - { 0x1c5960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, }, - { 0x1c5964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, }, - { 0x1c5970, 0x190fb515, 0x190fb515, 0x190fb515, 0x190fb515, }, - { 0x1c5974, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5978, 0x00000001, 0x00000001, 0x00000001, 0x00000001, }, - { 0x1c597c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5980, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5984, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5988, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c598c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5990, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5994, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5998, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c599c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c59a0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c59a4, 0x00000007, 0x00000007, 0x00000007, 0x00000007, }, - { 0x1c59a8, 0x001fff00, 0x001fff00, 0x001fff00, 0x001fff00, }, - { 0x1c59ac, 0x006f00c4, 0x006f00c4, 0x006f00c4, 0x006f00c4, }, - { 0x1c59b0, 0x03051000, 0x03051000, 0x03051000, 0x03051000, }, - { 0x1c59b4, 0x00000820, 0x00000820, 0x00000820, 0x00000820, }, - { 0x1c59bc, 0x00181400, 0x00181400, 0x00181400, 0x00181400, }, - { 0x1c59c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, }, - { 0x1c59c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, }, - { 0x1c59c8, 0x6af6532c, 0x6af6532c, 0x6af6532c, 0x6af6532c, }, - { 0x1c59cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, }, - { 0x1c59d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, }, - { 0x1c59d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c59d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c59dc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c59e0, 0x00000200, 0x00000200, 0x00000200, 0x00000200, }, - { 0x1c59e4, 0x64646464, 0x64646464, 0x64646464, 0x64646464, }, - { 0x1c59e8, 0x3c787878, 0x3c787878, 0x3c787878, 0x3c787878, }, - { 0x1c59ec, 0x000000aa, 0x000000aa, 0x000000aa, 0x000000aa, }, - { 0x1c59f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c59fc, 0x00001042, 0x00001042, 0x00001042, 0x00001042, }, - { 0x1c5a00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5a04, 0x00000040, 0x00000040, 0x00000040, 0x00000040, }, - { 0x1c5a08, 0x00000080, 0x00000080, 0x00000080, 0x00000080, }, - { 0x1c5a0c, 0x000001a1, 0x000001a1, 0x00000141, 0x00000141, }, - { 0x1c5a10, 0x000001e1, 0x000001e1, 0x00000181, 0x00000181, }, - { 0x1c5a14, 0x00000021, 0x00000021, 0x000001c1, 0x000001c1, }, - { 0x1c5a18, 0x00000061, 0x00000061, 0x00000001, 0x00000001, }, - { 0x1c5a1c, 0x00000168, 0x00000168, 0x00000041, 0x00000041, }, - { 0x1c5a20, 0x000001a8, 0x000001a8, 0x000001a8, 0x000001a8, }, - { 0x1c5a24, 0x000001e8, 0x000001e8, 0x000001e8, 0x000001e8, }, - { 0x1c5a28, 0x00000028, 0x00000028, 0x00000028, 0x00000028, }, - { 0x1c5a2c, 0x00000068, 0x00000068, 0x00000068, 0x00000068, }, - { 0x1c5a30, 0x00000189, 0x00000189, 0x000000a8, 0x000000a8, }, - { 0x1c5a34, 0x000001c9, 0x000001c9, 0x00000169, 0x00000169, }, - { 0x1c5a38, 0x00000009, 0x00000009, 0x000001a9, 0x000001a9, }, - { 0x1c5a3c, 0x00000049, 0x00000049, 0x000001e9, 0x000001e9, }, - { 0x1c5a40, 0x00000089, 0x00000089, 0x00000029, 0x00000029, }, - { 0x1c5a44, 0x00000170, 0x00000170, 0x00000069, 0x00000069, }, - { 0x1c5a48, 0x000001b0, 0x000001b0, 0x00000190, 0x00000190, }, - { 0x1c5a4c, 0x000001f0, 0x000001f0, 0x000001d0, 0x000001d0, }, - { 0x1c5a50, 0x00000030, 0x00000030, 0x00000010, 0x00000010, }, - { 0x1c5a54, 0x00000070, 0x00000070, 0x00000050, 0x00000050, }, - { 0x1c5a58, 0x00000191, 0x00000191, 0x00000090, 0x00000090, }, - { 0x1c5a5c, 0x000001d1, 0x000001d1, 0x00000151, 0x00000151, }, - { 0x1c5a60, 0x00000011, 0x00000011, 0x00000191, 0x00000191, }, - { 0x1c5a64, 0x00000051, 0x00000051, 0x000001d1, 0x000001d1, }, - { 0x1c5a68, 0x00000091, 0x00000091, 0x00000011, 0x00000011, }, - { 0x1c5a6c, 0x000001b8, 0x000001b8, 0x00000051, 0x00000051, }, - { 0x1c5a70, 0x000001f8, 0x000001f8, 0x00000198, 0x00000198, }, - { 0x1c5a74, 0x00000038, 0x00000038, 0x000001d8, 0x000001d8, }, - { 0x1c5a78, 0x00000078, 0x00000078, 0x00000018, 0x00000018, }, - { 0x1c5a7c, 0x00000199, 0x00000199, 0x00000058, 0x00000058, }, - { 0x1c5a80, 0x000001d9, 0x000001d9, 0x00000098, 0x00000098, }, - { 0x1c5a84, 0x00000019, 0x00000019, 0x00000159, 0x00000159, }, - { 0x1c5a88, 0x00000059, 0x00000059, 0x00000199, 0x00000199, }, - { 0x1c5a8c, 0x00000099, 0x00000099, 0x000001d9, 0x000001d9, }, - { 0x1c5a90, 0x000000d9, 0x000000d9, 0x00000019, 0x00000019, }, - { 0x1c5a94, 0x000000f9, 0x000000f9, 0x00000059, 0x00000059, }, - { 0x1c5a98, 0x000000f9, 0x000000f9, 0x00000099, 0x00000099, }, - { 0x1c5a9c, 0x000000f9, 0x000000f9, 0x000000d9, 0x000000d9, }, - { 0x1c5aa0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5aa4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5aa8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5aac, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5ab0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5ab4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5ab8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5abc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5ac0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5ac4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5ac8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5acc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5ad0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5ad4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5ad8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5adc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5ae0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5ae4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5ae8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5aec, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5af0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5af4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5af8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5afc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5b00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5b04, 0x00000001, 0x00000001, 0x00000001, 0x00000001, }, - { 0x1c5b08, 0x00000002, 0x00000002, 0x00000002, 0x00000002, }, - { 0x1c5b0c, 0x00000003, 0x00000003, 0x00000003, 0x00000003, }, - { 0x1c5b10, 0x00000004, 0x00000004, 0x00000004, 0x00000004, }, - { 0x1c5b14, 0x00000005, 0x00000005, 0x00000005, 0x00000005, }, - { 0x1c5b18, 0x00000008, 0x00000008, 0x00000008, 0x00000008, }, - { 0x1c5b1c, 0x00000009, 0x00000009, 0x00000009, 0x00000009, }, - { 0x1c5b20, 0x0000000a, 0x0000000a, 0x0000000a, 0x0000000a, }, - { 0x1c5b24, 0x0000000b, 0x0000000b, 0x0000000b, 0x0000000b, }, - { 0x1c5b28, 0x0000000c, 0x0000000c, 0x0000000c, 0x0000000c, }, - { 0x1c5b2c, 0x0000000d, 0x0000000d, 0x0000000d, 0x0000000d, }, - { 0x1c5b30, 0x00000010, 0x00000010, 0x00000010, 0x00000010, }, - { 0x1c5b34, 0x00000011, 0x00000011, 0x00000011, 0x00000011, }, - { 0x1c5b38, 0x00000012, 0x00000012, 0x00000012, 0x00000012, }, - { 0x1c5b3c, 0x00000013, 0x00000013, 0x00000013, 0x00000013, }, - { 0x1c5b40, 0x00000014, 0x00000014, 0x00000014, 0x00000014, }, - { 0x1c5b44, 0x00000015, 0x00000015, 0x00000015, 0x00000015, }, - { 0x1c5b48, 0x00000018, 0x00000018, 0x00000018, 0x00000018, }, - { 0x1c5b4c, 0x00000019, 0x00000019, 0x00000019, 0x00000019, }, - { 0x1c5b50, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, }, - { 0x1c5b54, 0x0000001b, 0x0000001b, 0x0000001b, 0x0000001b, }, - { 0x1c5b58, 0x0000001c, 0x0000001c, 0x0000001c, 0x0000001c, }, - { 0x1c5b5c, 0x0000001d, 0x0000001d, 0x0000001d, 0x0000001d, }, - { 0x1c5b60, 0x00000020, 0x00000020, 0x00000020, 0x00000020, }, - { 0x1c5b64, 0x00000021, 0x00000021, 0x00000021, 0x00000021, }, - { 0x1c5b68, 0x00000022, 0x00000022, 0x00000022, 0x00000022, }, - { 0x1c5b6c, 0x00000023, 0x00000023, 0x00000023, 0x00000023, }, - { 0x1c5b70, 0x00000024, 0x00000024, 0x00000024, 0x00000024, }, - { 0x1c5b74, 0x00000025, 0x00000025, 0x00000025, 0x00000025, }, - { 0x1c5b78, 0x00000028, 0x00000028, 0x00000028, 0x00000028, }, - { 0x1c5b7c, 0x00000029, 0x00000029, 0x00000029, 0x00000029, }, - { 0x1c5b80, 0x0000002a, 0x0000002a, 0x0000002a, 0x0000002a, }, - { 0x1c5b84, 0x0000002b, 0x0000002b, 0x0000002b, 0x0000002b, }, - { 0x1c5b88, 0x0000002c, 0x0000002c, 0x0000002c, 0x0000002c, }, - { 0x1c5b8c, 0x0000002d, 0x0000002d, 0x0000002d, 0x0000002d, }, - { 0x1c5b90, 0x00000030, 0x00000030, 0x00000030, 0x00000030, }, - { 0x1c5b94, 0x00000031, 0x00000031, 0x00000031, 0x00000031, }, - { 0x1c5b98, 0x00000032, 0x00000032, 0x00000032, 0x00000032, }, - { 0x1c5b9c, 0x00000033, 0x00000033, 0x00000033, 0x00000033, }, - { 0x1c5ba0, 0x00000034, 0x00000034, 0x00000034, 0x00000034, }, - { 0x1c5ba4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, - { 0x1c5ba8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, - { 0x1c5bac, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, - { 0x1c5bb0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, - { 0x1c5bb4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, - { 0x1c5bb8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, - { 0x1c5bbc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, - { 0x1c5bc0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, - { 0x1c5bc4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, - { 0x1c5bc8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, - { 0x1c5bcc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, - { 0x1c5bd0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, - { 0x1c5bd4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, - { 0x1c5bd8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, - { 0x1c5bdc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, - { 0x1c5be0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, - { 0x1c5be4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, - { 0x1c5be8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, - { 0x1c5bec, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, - { 0x1c5bf0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, - { 0x1c5bf4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, - { 0x1c5bf8, 0x00000010, 0x00000010, 0x00000010, 0x00000010, }, - { 0x1c5bfc, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, }, - { 0x1c5c00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5c0c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5c10, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5c14, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5c18, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5c1c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5c20, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5c24, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5c28, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5c2c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5c30, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5c34, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5c38, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5c3c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5cf0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5cf4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5cf8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5cfc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c6200, 0x00000008, 0x00000008, 0x0000000e, 0x0000000e, }, - { 0x1c6204, 0x00000440, 0x00000440, 0x00000440, 0x00000440, }, - { 0x1c6208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, }, - { 0x1c620c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, }, - { 0x1c6210, 0x40806333, 0x40806333, 0x40806333, 0x40806333, }, - { 0x1c6214, 0x00106c10, 0x00106c10, 0x00106c10, 0x00106c10, }, - { 0x1c6218, 0x009c4060, 0x009c4060, 0x009c4060, 0x009c4060, }, - { 0x1c621c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, }, - { 0x1c6220, 0x018830c6, 0x018830c6, 0x018830c6, 0x018830c6, }, - { 0x1c6224, 0x00000400, 0x00000400, 0x00000400, 0x00000400, }, - { 0x1c6228, 0x000009b5, 0x000009b5, 0x000009b5, 0x000009b5, }, - { 0x1c622c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c6230, 0x00000108, 0x00000210, 0x00000210, 0x00000108, }, - { 0x1c6234, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, - { 0x1c6238, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, - { 0x1c623c, 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af, }, - { 0x1c6240, 0x38490a20, 0x38490a20, 0x38490a20, 0x38490a20, }, - { 0x1c6244, 0x00007bb6, 0x00007bb6, 0x00007bb6, 0x00007bb6, }, - { 0x1c6248, 0x0fff3ffc, 0x0fff3ffc, 0x0fff3ffc, 0x0fff3ffc, }, - { 0x1c624c, 0x00000001, 0x00000001, 0x00000001, 0x00000001, }, - { 0x1c6250, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, }, - { 0x1c6254, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c6258, 0x0cc75380, 0x0cc75380, 0x0cc75380, 0x0cc75380, }, - { 0x1c625c, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, }, - { 0x1c6260, 0xdfa91f01, 0xdfa91f01, 0xdfa91f01, 0xdfa91f01, }, - { 0x1c6264, 0x00418a11, 0x00418a11, 0x00418a11, 0x00418a11, }, - { 0x1c6268, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c626c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, }, - { 0x1c6274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, }, - { 0x1c6278, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, }, - { 0x1c627c, 0x051701ce, 0x051701ce, 0x051701ce, 0x051701ce, }, - { 0x1c6300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, }, - { 0x1c6304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, }, - { 0x1c6308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, }, - { 0x1c630c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, }, - { 0x1c6310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, }, - { 0x1c6314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, }, - { 0x1c6318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, }, - { 0x1c631c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, }, - { 0x1c6320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, }, - { 0x1c6324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, }, - { 0x1c6328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, }, - { 0x1c632c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c6330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c6334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c6338, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c633c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c6340, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c6344, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c6348, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, }, - { 0x1c634c, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, }, - { 0x1c6350, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, }, - { 0x1c6354, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, }, - { 0x1c6358, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, }, - { 0x1c6388, 0x08000000, 0x08000000, 0x08000000, 0x08000000, }, - { 0x1c638c, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, - { 0x1c6390, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, - { 0x1c6394, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, }, - { 0x1c6398, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce, }, - { 0x1c639c, 0x00000007, 0x00000007, 0x00000007, 0x00000007, }, - { 0x1c63a0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c63a4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c63a8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c63ac, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c63b0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c63b4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c63b8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c63bc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c63c0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c63c4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c63c8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c63cc, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, - { 0x1c63d0, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, - { 0x1c63d4, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, - { 0x1c63d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c63dc, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, }, - { 0x1c63e0, 0x000000c0, 0x000000c0, 0x000000c0, 0x000000c0, }, - { 0x1c6848, 0x00180a65, 0x00180a65, 0x00180a68, 0x00180a68, }, - { 0x1c6920, 0x0510001c, 0x0510001c, 0x0510001c, 0x0510001c, }, - { 0x1c6960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, }, - { 0x1c720c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, }, - { 0x1c726c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, }, - { 0x1c7848, 0x00180a65, 0x00180a65, 0x00180a68, 0x00180a68, }, - { 0x1c7920, 0x0510001c, 0x0510001c, 0x0510001c, 0x0510001c, }, - { 0x1c7960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, }, - { 0x1c820c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, }, - { 0x1c826c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, }, -/* { 0x1c8864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, }, */ - { 0x1c8864, 0x0001c600, 0x0001c600, 0x0001c600, 0x0001c600, }, - { 0x1c895c, 0x004b6a8e, 0x004b6a8e, 0x004b6a8e, 0x004b6a8e, }, - { 0x1c8968, 0x000003ce, 0x000003ce, 0x000003ce, 0x000003ce, }, - { 0x1c89bc, 0x00181400, 0x00181400, 0x00181400, 0x00181400, }, - { 0x1c9270, 0x00820820, 0x00820820, 0x00820820, 0x00820820, }, - { 0x1c935c, 0x066c420f, 0x066c420f, 0x066c420f, 0x066c420f, }, - { 0x1c9360, 0x0f282207, 0x0f282207, 0x0f282207, 0x0f282207, }, - { 0x1c9364, 0x17601685, 0x17601685, 0x17601685, 0x17601685, }, - { 0x1c9368, 0x1f801104, 0x1f801104, 0x1f801104, 0x1f801104, }, - { 0x1c936c, 0x37a00c03, 0x37a00c03, 0x37a00c03, 0x37a00c03, }, - { 0x1c9370, 0x3fc40883, 0x3fc40883, 0x3fc40883, 0x3fc40883, }, - { 0x1c9374, 0x57c00803, 0x57c00803, 0x57c00803, 0x57c00803, }, - { 0x1c9378, 0x5fd80682, 0x5fd80682, 0x5fd80682, 0x5fd80682, }, - { 0x1c937c, 0x7fe00482, 0x7fe00482, 0x7fe00482, 0x7fe00482, }, - { 0x1c9380, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, }, - { 0x1c9384, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, } -}; - -/* - * look up a certain register in ar5416_phy_init[] and return the init. value - * for the band and bandwidth given. Return 0 if register address not found. - */ -static u32 carl9170_def_val(u32 reg, bool is_2ghz, bool is_40mhz) -{ - unsigned int i; - for (i = 0; i < ARRAY_SIZE(ar5416_phy_init); i++) { - if (ar5416_phy_init[i].reg != reg) - continue; - - if (is_2ghz) { - if (is_40mhz) - return ar5416_phy_init[i]._2ghz_40; - else - return ar5416_phy_init[i]._2ghz_20; - } else { - if (is_40mhz) - return ar5416_phy_init[i]._5ghz_40; - else - return ar5416_phy_init[i]._5ghz_20; - } - } - return 0; -} - -/* - * initialize some phy regs from eeprom values in modal_header[] - * acc. to band and bandwidth - */ -static int carl9170_init_phy_from_eeprom(struct ar9170 *ar, - bool is_2ghz, bool is_40mhz) -{ - static const u8 xpd2pd[16] = { - 0x2, 0x2, 0x2, 0x1, 0x2, 0x2, 0x6, 0x2, - 0x2, 0x3, 0x7, 0x2, 0xb, 0x2, 0x2, 0x2 - }; - /* pointer to the modal_header acc. to band */ - struct ar9170_eeprom_modal *m = &ar->eeprom.modal_header[is_2ghz]; - u32 val; - - carl9170_regwrite_begin(ar); - - /* ant common control (index 0) */ - carl9170_regwrite(AR9170_PHY_REG_SWITCH_COM, - le32_to_cpu(m->antCtrlCommon)); - - /* ant control chain 0 (index 1) */ - carl9170_regwrite(AR9170_PHY_REG_SWITCH_CHAIN_0, - le32_to_cpu(m->antCtrlChain[0])); - - /* ant control chain 2 (index 2) */ - carl9170_regwrite(AR9170_PHY_REG_SWITCH_CHAIN_2, - le32_to_cpu(m->antCtrlChain[1])); - - /* SwSettle (index 3) */ - if (!is_40mhz) { - val = carl9170_def_val(AR9170_PHY_REG_SETTLING, - is_2ghz, is_40mhz); - SET_VAL(AR9170_PHY_SETTLING_SWITCH, val, m->switchSettling); - carl9170_regwrite(AR9170_PHY_REG_SETTLING, val); - } - - /* adcDesired, pdaDesired (index 4) */ - val = carl9170_def_val(AR9170_PHY_REG_DESIRED_SZ, is_2ghz, is_40mhz); - SET_VAL(AR9170_PHY_DESIRED_SZ_PGA, val, m->pgaDesiredSize); - SET_VAL(AR9170_PHY_DESIRED_SZ_ADC, val, m->adcDesiredSize); - carl9170_regwrite(AR9170_PHY_REG_DESIRED_SZ, val); - - /* TxEndToXpaOff, TxFrameToXpaOn (index 5) */ - val = carl9170_def_val(AR9170_PHY_REG_RF_CTL4, is_2ghz, is_40mhz); - SET_VAL(AR9170_PHY_RF_CTL4_TX_END_XPAB_OFF, val, m->txEndToXpaOff); - SET_VAL(AR9170_PHY_RF_CTL4_TX_END_XPAA_OFF, val, m->txEndToXpaOff); - SET_VAL(AR9170_PHY_RF_CTL4_FRAME_XPAB_ON, val, m->txFrameToXpaOn); - SET_VAL(AR9170_PHY_RF_CTL4_FRAME_XPAA_ON, val, m->txFrameToXpaOn); - carl9170_regwrite(AR9170_PHY_REG_RF_CTL4, val); - - /* TxEndToRxOn (index 6) */ - val = carl9170_def_val(AR9170_PHY_REG_RF_CTL3, is_2ghz, is_40mhz); - SET_VAL(AR9170_PHY_RF_CTL3_TX_END_TO_A2_RX_ON, val, m->txEndToRxOn); - carl9170_regwrite(AR9170_PHY_REG_RF_CTL3, val); - - /* thresh62 (index 7) */ - val = carl9170_def_val(0x1c8864, is_2ghz, is_40mhz); - val = (val & ~0x7f000) | (m->thresh62 << 12); - carl9170_regwrite(0x1c8864, val); - - /* tx/rx attenuation chain 0 (index 8) */ - val = carl9170_def_val(AR9170_PHY_REG_RXGAIN, is_2ghz, is_40mhz); - SET_VAL(AR9170_PHY_RXGAIN_TXRX_ATTEN, val, m->txRxAttenCh[0]); - carl9170_regwrite(AR9170_PHY_REG_RXGAIN, val); - - /* tx/rx attenuation chain 2 (index 9) */ - val = carl9170_def_val(AR9170_PHY_REG_RXGAIN_CHAIN_2, - is_2ghz, is_40mhz); - SET_VAL(AR9170_PHY_RXGAIN_TXRX_ATTEN, val, m->txRxAttenCh[1]); - carl9170_regwrite(AR9170_PHY_REG_RXGAIN_CHAIN_2, val); - - /* tx/rx margin chain 0 (index 10) */ - val = carl9170_def_val(AR9170_PHY_REG_GAIN_2GHZ, is_2ghz, is_40mhz); - SET_VAL(AR9170_PHY_GAIN_2GHZ_RXTX_MARGIN, val, m->rxTxMarginCh[0]); - /* bsw margin chain 0 for 5GHz only */ - if (!is_2ghz) - SET_VAL(AR9170_PHY_GAIN_2GHZ_BSW_MARGIN, val, m->bswMargin[0]); - carl9170_regwrite(AR9170_PHY_REG_GAIN_2GHZ, val); - - /* tx/rx margin chain 2 (index 11) */ - val = carl9170_def_val(AR9170_PHY_REG_GAIN_2GHZ_CHAIN_2, - is_2ghz, is_40mhz); - SET_VAL(AR9170_PHY_GAIN_2GHZ_RXTX_MARGIN, val, m->rxTxMarginCh[1]); - carl9170_regwrite(AR9170_PHY_REG_GAIN_2GHZ_CHAIN_2, val); - - /* iqCall, iqCallq chain 0 (index 12) */ - val = carl9170_def_val(AR9170_PHY_REG_TIMING_CTRL4(0), - is_2ghz, is_40mhz); - SET_VAL(AR9170_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF, val, m->iqCalICh[0]); - SET_VAL(AR9170_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF, val, m->iqCalQCh[0]); - carl9170_regwrite(AR9170_PHY_REG_TIMING_CTRL4(0), val); - - /* iqCall, iqCallq chain 2 (index 13) */ - val = carl9170_def_val(AR9170_PHY_REG_TIMING_CTRL4(2), - is_2ghz, is_40mhz); - SET_VAL(AR9170_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF, val, m->iqCalICh[1]); - SET_VAL(AR9170_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF, val, m->iqCalQCh[1]); - carl9170_regwrite(AR9170_PHY_REG_TIMING_CTRL4(2), val); - - /* xpd gain mask (index 14) */ - val = carl9170_def_val(AR9170_PHY_REG_TPCRG1, is_2ghz, is_40mhz); - SET_VAL(AR9170_PHY_TPCRG1_PD_GAIN_1, val, - xpd2pd[m->xpdGain & 0xf] & 3); - SET_VAL(AR9170_PHY_TPCRG1_PD_GAIN_2, val, - xpd2pd[m->xpdGain & 0xf] >> 2); - carl9170_regwrite(AR9170_PHY_REG_TPCRG1, val); - - carl9170_regwrite(AR9170_PHY_REG_RX_CHAINMASK, ar->eeprom.rx_mask); - carl9170_regwrite(AR9170_PHY_REG_CAL_CHAINMASK, ar->eeprom.rx_mask); - - carl9170_regwrite_finish(); - return carl9170_regwrite_result(); -} - -static int carl9170_init_phy(struct ar9170 *ar, enum ieee80211_band band) -{ - int i, err; - u32 val; - bool is_2ghz = band == IEEE80211_BAND_2GHZ; - bool is_40mhz = conf_is_ht40(&ar->hw->conf); - - carl9170_regwrite_begin(ar); - - for (i = 0; i < ARRAY_SIZE(ar5416_phy_init); i++) { - if (is_40mhz) { - if (is_2ghz) - val = ar5416_phy_init[i]._2ghz_40; - else - val = ar5416_phy_init[i]._5ghz_40; - } else { - if (is_2ghz) - val = ar5416_phy_init[i]._2ghz_20; - else - val = ar5416_phy_init[i]._5ghz_20; - } - - carl9170_regwrite(ar5416_phy_init[i].reg, val); - } - - carl9170_regwrite_finish(); - err = carl9170_regwrite_result(); - if (err) - return err; - - err = carl9170_init_phy_from_eeprom(ar, is_2ghz, is_40mhz); - if (err) - return err; - - err = carl9170_init_power_cal(ar); - if (err) - return err; - - if (!ar->fw.hw_counters) { - err = carl9170_write_reg(ar, AR9170_PWR_REG_PLL_ADDAC, - is_2ghz ? 0x5163 : 0x5143); - } - - return err; -} - -struct carl9170_rf_initvals { - u32 reg, _5ghz, _2ghz; -}; - -static struct carl9170_rf_initvals carl9170_rf_initval[] = { - /* bank 0 */ - { 0x1c58b0, 0x1e5795e5, 0x1e5795e5}, - { 0x1c58e0, 0x02008020, 0x02008020}, - /* bank 1 */ - { 0x1c58b0, 0x02108421, 0x02108421}, - { 0x1c58ec, 0x00000008, 0x00000008}, - /* bank 2 */ - { 0x1c58b0, 0x0e73ff17, 0x0e73ff17}, - { 0x1c58e0, 0x00000420, 0x00000420}, - /* bank 3 */ - { 0x1c58f0, 0x01400018, 0x01c00018}, - /* bank 4 */ - { 0x1c58b0, 0x000001a1, 0x000001a1}, - { 0x1c58e8, 0x00000001, 0x00000001}, - /* bank 5 */ - { 0x1c58b0, 0x00000013, 0x00000013}, - { 0x1c58e4, 0x00000002, 0x00000002}, - /* bank 6 */ - { 0x1c58b0, 0x00000000, 0x00000000}, - { 0x1c58b0, 0x00000000, 0x00000000}, - { 0x1c58b0, 0x00000000, 0x00000000}, - { 0x1c58b0, 0x00000000, 0x00000000}, - { 0x1c58b0, 0x00000000, 0x00000000}, - { 0x1c58b0, 0x00004000, 0x00004000}, - { 0x1c58b0, 0x00006c00, 0x00006c00}, - { 0x1c58b0, 0x00002c00, 0x00002c00}, - { 0x1c58b0, 0x00004800, 0x00004800}, - { 0x1c58b0, 0x00004000, 0x00004000}, - { 0x1c58b0, 0x00006000, 0x00006000}, - { 0x1c58b0, 0x00001000, 0x00001000}, - { 0x1c58b0, 0x00004000, 0x00004000}, - { 0x1c58b0, 0x00007c00, 0x00007c00}, - { 0x1c58b0, 0x00007c00, 0x00007c00}, - { 0x1c58b0, 0x00007c00, 0x00007c00}, - { 0x1c58b0, 0x00007c00, 0x00007c00}, - { 0x1c58b0, 0x00007c00, 0x00007c00}, - { 0x1c58b0, 0x00087c00, 0x00087c00}, - { 0x1c58b0, 0x00007c00, 0x00007c00}, - { 0x1c58b0, 0x00005400, 0x00005400}, - { 0x1c58b0, 0x00000c00, 0x00000c00}, - { 0x1c58b0, 0x00001800, 0x00001800}, - { 0x1c58b0, 0x00007c00, 0x00007c00}, - { 0x1c58b0, 0x00006c00, 0x00006c00}, - { 0x1c58b0, 0x00006c00, 0x00006c00}, - { 0x1c58b0, 0x00007c00, 0x00007c00}, - { 0x1c58b0, 0x00002c00, 0x00002c00}, - { 0x1c58b0, 0x00003c00, 0x00003c00}, - { 0x1c58b0, 0x00003800, 0x00003800}, - { 0x1c58b0, 0x00001c00, 0x00001c00}, - { 0x1c58b0, 0x00000800, 0x00000800}, - { 0x1c58b0, 0x00000408, 0x00000408}, - { 0x1c58b0, 0x00004c15, 0x00004c15}, - { 0x1c58b0, 0x00004188, 0x00004188}, - { 0x1c58b0, 0x0000201e, 0x0000201e}, - { 0x1c58b0, 0x00010408, 0x00010408}, - { 0x1c58b0, 0x00000801, 0x00000801}, - { 0x1c58b0, 0x00000c08, 0x00000c08}, - { 0x1c58b0, 0x0000181e, 0x0000181e}, - { 0x1c58b0, 0x00001016, 0x00001016}, - { 0x1c58b0, 0x00002800, 0x00002800}, - { 0x1c58b0, 0x00004010, 0x00004010}, - { 0x1c58b0, 0x0000081c, 0x0000081c}, - { 0x1c58b0, 0x00000115, 0x00000115}, - { 0x1c58b0, 0x00000015, 0x00000015}, - { 0x1c58b0, 0x00000066, 0x00000066}, - { 0x1c58b0, 0x0000001c, 0x0000001c}, - { 0x1c58b0, 0x00000000, 0x00000000}, - { 0x1c58b0, 0x00000004, 0x00000004}, - { 0x1c58b0, 0x00000015, 0x00000015}, - { 0x1c58b0, 0x0000001f, 0x0000001f}, - { 0x1c58e0, 0x00000000, 0x00000400}, - /* bank 7 */ - { 0x1c58b0, 0x000000a0, 0x000000a0}, - { 0x1c58b0, 0x00000000, 0x00000000}, - { 0x1c58b0, 0x00000040, 0x00000040}, - { 0x1c58f0, 0x0000001c, 0x0000001c}, -}; - -static int carl9170_init_rf_banks_0_7(struct ar9170 *ar, bool band5ghz) -{ - int err, i; - - carl9170_regwrite_begin(ar); - - for (i = 0; i < ARRAY_SIZE(carl9170_rf_initval); i++) - carl9170_regwrite(carl9170_rf_initval[i].reg, - band5ghz ? carl9170_rf_initval[i]._5ghz - : carl9170_rf_initval[i]._2ghz); - - carl9170_regwrite_finish(); - err = carl9170_regwrite_result(); - if (err) - wiphy_err(ar->hw->wiphy, "rf init failed\n"); - - return err; -} - -struct carl9170_phy_freq_params { - u8 coeff_exp; - u16 coeff_man; - u8 coeff_exp_shgi; - u16 coeff_man_shgi; -}; - -enum carl9170_bw { - CARL9170_BW_20, - CARL9170_BW_40_BELOW, - CARL9170_BW_40_ABOVE, - - __CARL9170_NUM_BW, -}; - -struct carl9170_phy_freq_entry { - u16 freq; - struct carl9170_phy_freq_params params[__CARL9170_NUM_BW]; -}; - -/* NB: must be in sync with channel tables in main! */ -static const struct carl9170_phy_freq_entry carl9170_phy_freq_params[] = { -/* - * freq, - * 20MHz, - * 40MHz (below), - * 40Mhz (above), - */ - { 2412, { - { 3, 21737, 3, 19563, }, - { 3, 21827, 3, 19644, }, - { 3, 21647, 3, 19482, }, - } }, - { 2417, { - { 3, 21692, 3, 19523, }, - { 3, 21782, 3, 19604, }, - { 3, 21602, 3, 19442, }, - } }, - { 2422, { - { 3, 21647, 3, 19482, }, - { 3, 21737, 3, 19563, }, - { 3, 21558, 3, 19402, }, - } }, - { 2427, { - { 3, 21602, 3, 19442, }, - { 3, 21692, 3, 19523, }, - { 3, 21514, 3, 19362, }, - } }, - { 2432, { - { 3, 21558, 3, 19402, }, - { 3, 21647, 3, 19482, }, - { 3, 21470, 3, 19323, }, - } }, - { 2437, { - { 3, 21514, 3, 19362, }, - { 3, 21602, 3, 19442, }, - { 3, 21426, 3, 19283, }, - } }, - { 2442, { - { 3, 21470, 3, 19323, }, - { 3, 21558, 3, 19402, }, - { 3, 21382, 3, 19244, }, - } }, - { 2447, { - { 3, 21426, 3, 19283, }, - { 3, 21514, 3, 19362, }, - { 3, 21339, 3, 19205, }, - } }, - { 2452, { - { 3, 21382, 3, 19244, }, - { 3, 21470, 3, 19323, }, - { 3, 21295, 3, 19166, }, - } }, - { 2457, { - { 3, 21339, 3, 19205, }, - { 3, 21426, 3, 19283, }, - { 3, 21252, 3, 19127, }, - } }, - { 2462, { - { 3, 21295, 3, 19166, }, - { 3, 21382, 3, 19244, }, - { 3, 21209, 3, 19088, }, - } }, - { 2467, { - { 3, 21252, 3, 19127, }, - { 3, 21339, 3, 19205, }, - { 3, 21166, 3, 19050, }, - } }, - { 2472, { - { 3, 21209, 3, 19088, }, - { 3, 21295, 3, 19166, }, - { 3, 21124, 3, 19011, }, - } }, - { 2484, { - { 3, 21107, 3, 18996, }, - { 3, 21192, 3, 19073, }, - { 3, 21022, 3, 18920, }, - } }, - { 4920, { - { 4, 21313, 4, 19181, }, - { 4, 21356, 4, 19220, }, - { 4, 21269, 4, 19142, }, - } }, - { 4940, { - { 4, 21226, 4, 19104, }, - { 4, 21269, 4, 19142, }, - { 4, 21183, 4, 19065, }, - } }, - { 4960, { - { 4, 21141, 4, 19027, }, - { 4, 21183, 4, 19065, }, - { 4, 21098, 4, 18988, }, - } }, - { 4980, { - { 4, 21056, 4, 18950, }, - { 4, 21098, 4, 18988, }, - { 4, 21014, 4, 18912, }, - } }, - { 5040, { - { 4, 20805, 4, 18725, }, - { 4, 20846, 4, 18762, }, - { 4, 20764, 4, 18687, }, - } }, - { 5060, { - { 4, 20723, 4, 18651, }, - { 4, 20764, 4, 18687, }, - { 4, 20682, 4, 18614, }, - } }, - { 5080, { - { 4, 20641, 4, 18577, }, - { 4, 20682, 4, 18614, }, - { 4, 20601, 4, 18541, }, - } }, - { 5180, { - { 4, 20243, 4, 18219, }, - { 4, 20282, 4, 18254, }, - { 4, 20204, 4, 18183, }, - } }, - { 5200, { - { 4, 20165, 4, 18148, }, - { 4, 20204, 4, 18183, }, - { 4, 20126, 4, 18114, }, - } }, - { 5220, { - { 4, 20088, 4, 18079, }, - { 4, 20126, 4, 18114, }, - { 4, 20049, 4, 18044, }, - } }, - { 5240, { - { 4, 20011, 4, 18010, }, - { 4, 20049, 4, 18044, }, - { 4, 19973, 4, 17976, }, - } }, - { 5260, { - { 4, 19935, 4, 17941, }, - { 4, 19973, 4, 17976, }, - { 4, 19897, 4, 17907, }, - } }, - { 5280, { - { 4, 19859, 4, 17873, }, - { 4, 19897, 4, 17907, }, - { 4, 19822, 4, 17840, }, - } }, - { 5300, { - { 4, 19784, 4, 17806, }, - { 4, 19822, 4, 17840, }, - { 4, 19747, 4, 17772, }, - } }, - { 5320, { - { 4, 19710, 4, 17739, }, - { 4, 19747, 4, 17772, }, - { 4, 19673, 4, 17706, }, - } }, - { 5500, { - { 4, 19065, 4, 17159, }, - { 4, 19100, 4, 17190, }, - { 4, 19030, 4, 17127, }, - } }, - { 5520, { - { 4, 18996, 4, 17096, }, - { 4, 19030, 4, 17127, }, - { 4, 18962, 4, 17065, }, - } }, - { 5540, { - { 4, 18927, 4, 17035, }, - { 4, 18962, 4, 17065, }, - { 4, 18893, 4, 17004, }, - } }, - { 5560, { - { 4, 18859, 4, 16973, }, - { 4, 18893, 4, 17004, }, - { 4, 18825, 4, 16943, }, - } }, - { 5580, { - { 4, 18792, 4, 16913, }, - { 4, 18825, 4, 16943, }, - { 4, 18758, 4, 16882, }, - } }, - { 5600, { - { 4, 18725, 4, 16852, }, - { 4, 18758, 4, 16882, }, - { 4, 18691, 4, 16822, }, - } }, - { 5620, { - { 4, 18658, 4, 16792, }, - { 4, 18691, 4, 16822, }, - { 4, 18625, 4, 16762, }, - } }, - { 5640, { - { 4, 18592, 4, 16733, }, - { 4, 18625, 4, 16762, }, - { 4, 18559, 4, 16703, }, - } }, - { 5660, { - { 4, 18526, 4, 16673, }, - { 4, 18559, 4, 16703, }, - { 4, 18493, 4, 16644, }, - } }, - { 5680, { - { 4, 18461, 4, 16615, }, - { 4, 18493, 4, 16644, }, - { 4, 18428, 4, 16586, }, - } }, - { 5700, { - { 4, 18396, 4, 16556, }, - { 4, 18428, 4, 16586, }, - { 4, 18364, 4, 16527, }, - } }, - { 5745, { - { 4, 18252, 4, 16427, }, - { 4, 18284, 4, 16455, }, - { 4, 18220, 4, 16398, }, - } }, - { 5765, { - { 4, 18189, 5, 32740, }, - { 4, 18220, 4, 16398, }, - { 4, 18157, 5, 32683, }, - } }, - { 5785, { - { 4, 18126, 5, 32626, }, - { 4, 18157, 5, 32683, }, - { 4, 18094, 5, 32570, }, - } }, - { 5805, { - { 4, 18063, 5, 32514, }, - { 4, 18094, 5, 32570, }, - { 4, 18032, 5, 32458, }, - } }, - { 5825, { - { 4, 18001, 5, 32402, }, - { 4, 18032, 5, 32458, }, - { 4, 17970, 5, 32347, }, - } }, - { 5170, { - { 4, 20282, 4, 18254, }, - { 4, 20321, 4, 18289, }, - { 4, 20243, 4, 18219, }, - } }, - { 5190, { - { 4, 20204, 4, 18183, }, - { 4, 20243, 4, 18219, }, - { 4, 20165, 4, 18148, }, - } }, - { 5210, { - { 4, 20126, 4, 18114, }, - { 4, 20165, 4, 18148, }, - { 4, 20088, 4, 18079, }, - } }, - { 5230, { - { 4, 20049, 4, 18044, }, - { 4, 20088, 4, 18079, }, - { 4, 20011, 4, 18010, }, - } }, -}; - -static int carl9170_init_rf_bank4_pwr(struct ar9170 *ar, bool band5ghz, - u32 freq, enum carl9170_bw bw) -{ - int err; - u32 d0, d1, td0, td1, fd0, fd1; - u8 chansel; - u8 refsel0 = 1, refsel1 = 0; - u8 lf_synth = 0; - - switch (bw) { - case CARL9170_BW_40_ABOVE: - freq += 10; - break; - case CARL9170_BW_40_BELOW: - freq -= 10; - break; - case CARL9170_BW_20: - break; - default: - BUG(); - return -ENOSYS; - } - - if (band5ghz) { - if (freq % 10) { - chansel = (freq - 4800) / 5; - } else { - chansel = ((freq - 4800) / 10) * 2; - refsel0 = 0; - refsel1 = 1; - } - chansel = byte_rev_table[chansel]; - } else { - if (freq == 2484) { - chansel = 10 + (freq - 2274) / 5; - lf_synth = 1; - } else - chansel = 16 + (freq - 2272) / 5; - chansel *= 4; - chansel = byte_rev_table[chansel]; - } - - d1 = chansel; - d0 = 0x21 | - refsel0 << 3 | - refsel1 << 2 | - lf_synth << 1; - td0 = d0 & 0x1f; - td1 = d1 & 0x1f; - fd0 = td1 << 5 | td0; - - td0 = (d0 >> 5) & 0x7; - td1 = (d1 >> 5) & 0x7; - fd1 = td1 << 5 | td0; - - carl9170_regwrite_begin(ar); - - carl9170_regwrite(0x1c58b0, fd0); - carl9170_regwrite(0x1c58e8, fd1); - - carl9170_regwrite_finish(); - err = carl9170_regwrite_result(); - if (err) - return err; - - return 0; -} - -static const struct carl9170_phy_freq_params * -carl9170_get_hw_dyn_params(struct ieee80211_channel *channel, - enum carl9170_bw bw) -{ - unsigned int chanidx = 0; - u16 freq = 2412; - - if (channel) { - chanidx = channel->hw_value; - freq = channel->center_freq; - } - - BUG_ON(chanidx >= ARRAY_SIZE(carl9170_phy_freq_params)); - - BUILD_BUG_ON(__CARL9170_NUM_BW != 3); - - WARN_ON(carl9170_phy_freq_params[chanidx].freq != freq); - - return &carl9170_phy_freq_params[chanidx].params[bw]; -} - -static int carl9170_find_freq_idx(int nfreqs, u8 *freqs, u8 f) -{ - int idx = nfreqs - 2; - - while (idx >= 0) { - if (f >= freqs[idx]) - return idx; - idx--; - } - - return 0; -} - -static s32 carl9170_interpolate_s32(s32 x, s32 x1, s32 y1, s32 x2, s32 y2) -{ - /* nothing to interpolate, it's horizontal */ - if (y2 == y1) - return y1; - - /* check if we hit one of the edges */ - if (x == x1) - return y1; - if (x == x2) - return y2; - - /* x1 == x2 is bad, hopefully == x */ - if (x2 == x1) - return y1; - - return y1 + (((y2 - y1) * (x - x1)) / (x2 - x1)); -} - -static u8 carl9170_interpolate_u8(u8 x, u8 x1, u8 y1, u8 x2, u8 y2) -{ -#define SHIFT 8 - s32 y; - - y = carl9170_interpolate_s32(x << SHIFT, x1 << SHIFT, - y1 << SHIFT, x2 << SHIFT, y2 << SHIFT); - - /* - * XXX: unwrap this expression - * Isn't it just DIV_ROUND_UP(y, 1<<SHIFT)? - * Can we rely on the compiler to optimise away the div? - */ - return (y >> SHIFT) + ((y & (1 << (SHIFT - 1))) >> (SHIFT - 1)); -#undef SHIFT -} - -static u8 carl9170_interpolate_val(u8 x, u8 *x_array, u8 *y_array) -{ - int i; - - for (i = 0; i < 3; i++) { - if (x <= x_array[i + 1]) - break; - } - - return carl9170_interpolate_u8(x, x_array[i], y_array[i], - x_array[i + 1], y_array[i + 1]); -} - -static int carl9170_set_freq_cal_data(struct ar9170 *ar, - struct ieee80211_channel *channel) -{ - u8 *cal_freq_pier; - u8 vpds[2][AR5416_PD_GAIN_ICEPTS]; - u8 pwrs[2][AR5416_PD_GAIN_ICEPTS]; - int chain, idx, i; - u32 phy_data = 0; - u8 f, tmp; - - switch (channel->band) { - case IEEE80211_BAND_2GHZ: - f = channel->center_freq - 2300; - cal_freq_pier = ar->eeprom.cal_freq_pier_2G; - i = AR5416_NUM_2G_CAL_PIERS - 1; - break; - - case IEEE80211_BAND_5GHZ: - f = (channel->center_freq - 4800) / 5; - cal_freq_pier = ar->eeprom.cal_freq_pier_5G; - i = AR5416_NUM_5G_CAL_PIERS - 1; - break; - - default: - return -EINVAL; - break; - } - - for (; i >= 0; i--) { - if (cal_freq_pier[i] != 0xff) - break; - } - if (i < 0) - return -EINVAL; - - idx = carl9170_find_freq_idx(i, cal_freq_pier, f); - - carl9170_regwrite_begin(ar); - - for (chain = 0; chain < AR5416_MAX_CHAINS; chain++) { - for (i = 0; i < AR5416_PD_GAIN_ICEPTS; i++) { - struct ar9170_calibration_data_per_freq *cal_pier_data; - int j; - - switch (channel->band) { - case IEEE80211_BAND_2GHZ: - cal_pier_data = &ar->eeprom. - cal_pier_data_2G[chain][idx]; - break; - - case IEEE80211_BAND_5GHZ: - cal_pier_data = &ar->eeprom. - cal_pier_data_5G[chain][idx]; - break; - - default: - return -EINVAL; - } - - for (j = 0; j < 2; j++) { - vpds[j][i] = carl9170_interpolate_u8(f, - cal_freq_pier[idx], - cal_pier_data->vpd_pdg[j][i], - cal_freq_pier[idx + 1], - cal_pier_data[1].vpd_pdg[j][i]); - - pwrs[j][i] = carl9170_interpolate_u8(f, - cal_freq_pier[idx], - cal_pier_data->pwr_pdg[j][i], - cal_freq_pier[idx + 1], - cal_pier_data[1].pwr_pdg[j][i]) / 2; - } - } - - for (i = 0; i < 76; i++) { - if (i < 25) { - tmp = carl9170_interpolate_val(i, &pwrs[0][0], - &vpds[0][0]); - } else { - tmp = carl9170_interpolate_val(i - 12, - &pwrs[1][0], - &vpds[1][0]); - } - - phy_data |= tmp << ((i & 3) << 3); - if ((i & 3) == 3) { - carl9170_regwrite(0x1c6280 + chain * 0x1000 + - (i & ~3), phy_data); - phy_data = 0; - } - } - - for (i = 19; i < 32; i++) - carl9170_regwrite(0x1c6280 + chain * 0x1000 + (i << 2), - 0x0); - } - - carl9170_regwrite_finish(); - return carl9170_regwrite_result(); -} - -static u8 carl9170_get_max_edge_power(struct ar9170 *ar, - u32 freq, struct ar9170_calctl_edges edges[]) -{ - int i; - u8 rc = AR5416_MAX_RATE_POWER; - u8 f; - if (freq < 3000) - f = freq - 2300; - else - f = (freq - 4800) / 5; - - for (i = 0; i < AR5416_NUM_BAND_EDGES; i++) { - if (edges[i].channel == 0xff) - break; - if (f == edges[i].channel) { - /* exact freq match */ - rc = edges[i].power_flags & ~AR9170_CALCTL_EDGE_FLAGS; - break; - } - if (i > 0 && f < edges[i].channel) { - if (f > edges[i - 1].channel && - edges[i - 1].power_flags & - AR9170_CALCTL_EDGE_FLAGS) { - /* lower channel has the inband flag set */ - rc = edges[i - 1].power_flags & - ~AR9170_CALCTL_EDGE_FLAGS; - } - break; - } - } - - if (i == AR5416_NUM_BAND_EDGES) { - if (f > edges[i - 1].channel && - edges[i - 1].power_flags & AR9170_CALCTL_EDGE_FLAGS) { - /* lower channel has the inband flag set */ - rc = edges[i - 1].power_flags & - ~AR9170_CALCTL_EDGE_FLAGS; - } - } - return rc; -} - -static u8 carl9170_get_heavy_clip(struct ar9170 *ar, u32 freq, - enum carl9170_bw bw, struct ar9170_calctl_edges edges[]) -{ - u8 f; - int i; - u8 rc = 0; - - if (freq < 3000) - f = freq - 2300; - else - f = (freq - 4800) / 5; - - if (bw == CARL9170_BW_40_BELOW || bw == CARL9170_BW_40_ABOVE) - rc |= 0xf0; - - for (i = 0; i < AR5416_NUM_BAND_EDGES; i++) { - if (edges[i].channel == 0xff) - break; - if (f == edges[i].channel) { - if (!(edges[i].power_flags & AR9170_CALCTL_EDGE_FLAGS)) - rc |= 0x0f; - break; - } - } - - return rc; -} - -/* - * calculate the conformance test limits and the heavy clip parameter - * and apply them to ar->power* (derived from otus hal/hpmain.c, line 3706) - */ -static void carl9170_calc_ctl(struct ar9170 *ar, u32 freq, enum carl9170_bw bw) -{ - u8 ctl_grp; /* CTL group */ - u8 ctl_idx; /* CTL index */ - int i, j; - struct ctl_modes { - u8 ctl_mode; - u8 max_power; - u8 *pwr_cal_data; - int pwr_cal_len; - } *modes; - - /* - * order is relevant in the mode_list_*: we fall back to the - * lower indices if any mode is missed in the EEPROM. - */ - struct ctl_modes mode_list_2ghz[] = { - { CTL_11B, 0, ar->power_2G_cck, 4 }, - { CTL_11G, 0, ar->power_2G_ofdm, 4 }, - { CTL_2GHT20, 0, ar->power_2G_ht20, 8 }, - { CTL_2GHT40, 0, ar->power_2G_ht40, 8 }, - }; - struct ctl_modes mode_list_5ghz[] = { - { CTL_11A, 0, ar->power_5G_leg, 4 }, - { CTL_5GHT20, 0, ar->power_5G_ht20, 8 }, - { CTL_5GHT40, 0, ar->power_5G_ht40, 8 }, - }; - int nr_modes; - -#define EDGES(c, n) (ar->eeprom.ctl_data[c].control_edges[n]) - - ar->heavy_clip = 0; - - /* - * TODO: investigate the differences between OTUS' - * hpreg.c::zfHpGetRegulatoryDomain() and - * ath/regd.c::ath_regd_get_band_ctl() - - * e.g. for FCC3_WORLD the OTUS procedure - * always returns CTL_FCC, while the one in ath/ delivers - * CTL_ETSI for 2GHz and CTL_FCC for 5GHz. - */ - ctl_grp = ath_regd_get_band_ctl(&ar->common.regulatory, - ar->hw->conf.channel->band); - - /* ctl group not found - either invalid band (NO_CTL) or ww roaming */ - if (ctl_grp == NO_CTL || ctl_grp == SD_NO_CTL) - ctl_grp = CTL_FCC; - - if (ctl_grp != CTL_FCC) - /* skip CTL and heavy clip for CTL_MKK and CTL_ETSI */ - return; - - if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) { - modes = mode_list_2ghz; - nr_modes = ARRAY_SIZE(mode_list_2ghz); - } else { - modes = mode_list_5ghz; - nr_modes = ARRAY_SIZE(mode_list_5ghz); - } - - for (i = 0; i < nr_modes; i++) { - u8 c = ctl_grp | modes[i].ctl_mode; - for (ctl_idx = 0; ctl_idx < AR5416_NUM_CTLS; ctl_idx++) - if (c == ar->eeprom.ctl_index[ctl_idx]) - break; - if (ctl_idx < AR5416_NUM_CTLS) { - int f_off = 0; - - /* - * determine heavy clip parameter - * from the 11G edges array - */ - if (modes[i].ctl_mode == CTL_11G) { - ar->heavy_clip = - carl9170_get_heavy_clip(ar, - freq, bw, EDGES(ctl_idx, 1)); - } - - /* adjust freq for 40MHz */ - if (modes[i].ctl_mode == CTL_2GHT40 || - modes[i].ctl_mode == CTL_5GHT40) { - if (bw == CARL9170_BW_40_BELOW) - f_off = -10; - else - f_off = 10; - } - - modes[i].max_power = - carl9170_get_max_edge_power(ar, - freq + f_off, EDGES(ctl_idx, 1)); - - /* - * TODO: check if the regulatory max. power is - * controlled by cfg80211 for DFS. - * (hpmain applies it to max_power itself for DFS freq) - */ - - } else { - /* - * Workaround in otus driver, hpmain.c, line 3906: - * if no data for 5GHT20 are found, take the - * legacy 5G value. We extend this here to fallback - * from any other HT* or 11G, too. - */ - int k = i; - - modes[i].max_power = AR5416_MAX_RATE_POWER; - while (k-- > 0) { - if (modes[k].max_power != - AR5416_MAX_RATE_POWER) { - modes[i].max_power = modes[k].max_power; - break; - } - } - } - - /* apply max power to pwr_cal_data (ar->power_*) */ - for (j = 0; j < modes[i].pwr_cal_len; j++) { - modes[i].pwr_cal_data[j] = min(modes[i].pwr_cal_data[j], - modes[i].max_power); - } - } - - if (ar->heavy_clip & 0xf0) { - ar->power_2G_ht40[0]--; - ar->power_2G_ht40[1]--; - ar->power_2G_ht40[2]--; - } - if (ar->heavy_clip & 0xf) { - ar->power_2G_ht20[0]++; - ar->power_2G_ht20[1]++; - ar->power_2G_ht20[2]++; - } - -#undef EDGES -} - -static void carl9170_set_power_cal(struct ar9170 *ar, u32 freq, - enum carl9170_bw bw) -{ - struct ar9170_calibration_target_power_legacy *ctpl; - struct ar9170_calibration_target_power_ht *ctph; - u8 *ctpres; - int ntargets; - int idx, i, n; - u8 f; - u8 pwr_freqs[AR5416_MAX_NUM_TGT_PWRS]; - - if (freq < 3000) - f = freq - 2300; - else - f = (freq - 4800) / 5; - - /* - * cycle through the various modes - * - * legacy modes first: 5G, 2G CCK, 2G OFDM - */ - for (i = 0; i < 3; i++) { - switch (i) { - case 0: /* 5 GHz legacy */ - ctpl = &ar->eeprom.cal_tgt_pwr_5G[0]; - ntargets = AR5416_NUM_5G_TARGET_PWRS; - ctpres = ar->power_5G_leg; - break; - case 1: /* 2.4 GHz CCK */ - ctpl = &ar->eeprom.cal_tgt_pwr_2G_cck[0]; - ntargets = AR5416_NUM_2G_CCK_TARGET_PWRS; - ctpres = ar->power_2G_cck; - break; - case 2: /* 2.4 GHz OFDM */ - ctpl = &ar->eeprom.cal_tgt_pwr_2G_ofdm[0]; - ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS; - ctpres = ar->power_2G_ofdm; - break; - default: - BUG(); - } - - for (n = 0; n < ntargets; n++) { - if (ctpl[n].freq == 0xff) - break; - pwr_freqs[n] = ctpl[n].freq; - } - ntargets = n; - idx = carl9170_find_freq_idx(ntargets, pwr_freqs, f); - for (n = 0; n < 4; n++) - ctpres[n] = carl9170_interpolate_u8(f, - ctpl[idx + 0].freq, ctpl[idx + 0].power[n], - ctpl[idx + 1].freq, ctpl[idx + 1].power[n]); - } - - /* HT modes now: 5G HT20, 5G HT40, 2G CCK, 2G OFDM, 2G HT20, 2G HT40 */ - for (i = 0; i < 4; i++) { - switch (i) { - case 0: /* 5 GHz HT 20 */ - ctph = &ar->eeprom.cal_tgt_pwr_5G_ht20[0]; - ntargets = AR5416_NUM_5G_TARGET_PWRS; - ctpres = ar->power_5G_ht20; - break; - case 1: /* 5 GHz HT 40 */ - ctph = &ar->eeprom.cal_tgt_pwr_5G_ht40[0]; - ntargets = AR5416_NUM_5G_TARGET_PWRS; - ctpres = ar->power_5G_ht40; - break; - case 2: /* 2.4 GHz HT 20 */ - ctph = &ar->eeprom.cal_tgt_pwr_2G_ht20[0]; - ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS; - ctpres = ar->power_2G_ht20; - break; - case 3: /* 2.4 GHz HT 40 */ - ctph = &ar->eeprom.cal_tgt_pwr_2G_ht40[0]; - ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS; - ctpres = ar->power_2G_ht40; - break; - default: - BUG(); - } - - for (n = 0; n < ntargets; n++) { - if (ctph[n].freq == 0xff) - break; - pwr_freqs[n] = ctph[n].freq; - } - ntargets = n; - idx = carl9170_find_freq_idx(ntargets, pwr_freqs, f); - for (n = 0; n < 8; n++) - ctpres[n] = carl9170_interpolate_u8(f, - ctph[idx + 0].freq, ctph[idx + 0].power[n], - ctph[idx + 1].freq, ctph[idx + 1].power[n]); - } - - /* calc. conformance test limits and apply to ar->power*[] */ - carl9170_calc_ctl(ar, freq, bw); -} - -int carl9170_get_noisefloor(struct ar9170 *ar) -{ - static const u32 phy_regs[] = { - AR9170_PHY_REG_CCA, AR9170_PHY_REG_CH2_CCA, - AR9170_PHY_REG_EXT_CCA, AR9170_PHY_REG_CH2_EXT_CCA }; - u32 phy_res[ARRAY_SIZE(phy_regs)]; - int err, i; - - BUILD_BUG_ON(ARRAY_SIZE(phy_regs) != ARRAY_SIZE(ar->noise)); - - err = carl9170_read_mreg(ar, ARRAY_SIZE(phy_regs), phy_regs, phy_res); - if (err) - return err; - - for (i = 0; i < 2; i++) { - ar->noise[i] = sign_extend32(GET_VAL( - AR9170_PHY_CCA_MIN_PWR, phy_res[i]), 8); - - ar->noise[i + 2] = sign_extend32(GET_VAL( - AR9170_PHY_EXT_CCA_MIN_PWR, phy_res[i + 2]), 8); - } - - if (ar->channel) - ar->survey[ar->channel->hw_value].noise = ar->noise[0]; - - return 0; -} - -static enum carl9170_bw nl80211_to_carl(enum nl80211_channel_type type) -{ - switch (type) { - case NL80211_CHAN_NO_HT: - case NL80211_CHAN_HT20: - return CARL9170_BW_20; - case NL80211_CHAN_HT40MINUS: - return CARL9170_BW_40_BELOW; - case NL80211_CHAN_HT40PLUS: - return CARL9170_BW_40_ABOVE; - default: - BUG(); - } -} - -int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel, - enum nl80211_channel_type _bw, - enum carl9170_rf_init_mode rfi) -{ - const struct carl9170_phy_freq_params *freqpar; - struct carl9170_rf_init_result rf_res; - struct carl9170_rf_init rf; - u32 cmd, tmp, offs = 0, new_ht = 0; - int err; - enum carl9170_bw bw; - bool warm_reset; - struct ieee80211_channel *old_channel = NULL; - - bw = nl80211_to_carl(_bw); - - if (conf_is_ht(&ar->hw->conf)) - new_ht |= CARL9170FW_PHY_HT_ENABLE; - - if (conf_is_ht40(&ar->hw->conf)) - new_ht |= CARL9170FW_PHY_HT_DYN2040; - - /* may be NULL at first setup */ - if (ar->channel) { - old_channel = ar->channel; - warm_reset = (old_channel->band != channel->band) || - (old_channel->center_freq == - channel->center_freq) || - (ar->ht_settings != new_ht); - - ar->channel = NULL; - } else { - warm_reset = true; - } - - /* HW workaround */ - if (!ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] && - channel->center_freq <= 2417) - warm_reset = true; - - if (rfi != CARL9170_RFI_NONE || warm_reset) { - u32 val; - - if (rfi == CARL9170_RFI_COLD) - val = AR9170_PWR_RESET_BB_COLD_RESET; - else - val = AR9170_PWR_RESET_BB_WARM_RESET; - - /* warm/cold reset BB/ADDA */ - err = carl9170_write_reg(ar, AR9170_PWR_REG_RESET, val); - if (err) - return err; - - err = carl9170_write_reg(ar, AR9170_PWR_REG_RESET, 0x0); - if (err) - return err; - - err = carl9170_init_phy(ar, channel->band); - if (err) - return err; - - err = carl9170_init_rf_banks_0_7(ar, - channel->band == IEEE80211_BAND_5GHZ); - if (err) - return err; - - cmd = CARL9170_CMD_RF_INIT; - } else { - cmd = CARL9170_CMD_FREQUENCY; - } - - err = carl9170_exec_cmd(ar, CARL9170_CMD_FREQ_START, 0, NULL, 0, NULL); - if (err) - return err; - - err = carl9170_write_reg(ar, AR9170_PHY_REG_HEAVY_CLIP_ENABLE, - 0x200); - if (err) - return err; - - err = carl9170_init_rf_bank4_pwr(ar, - channel->band == IEEE80211_BAND_5GHZ, - channel->center_freq, bw); - if (err) - return err; - - tmp = AR9170_PHY_TURBO_FC_SINGLE_HT_LTF1 | - AR9170_PHY_TURBO_FC_HT_EN; - - switch (bw) { - case CARL9170_BW_20: - break; - case CARL9170_BW_40_BELOW: - tmp |= AR9170_PHY_TURBO_FC_DYN2040_EN | - AR9170_PHY_TURBO_FC_SHORT_GI_40; - offs = 3; - break; - case CARL9170_BW_40_ABOVE: - tmp |= AR9170_PHY_TURBO_FC_DYN2040_EN | - AR9170_PHY_TURBO_FC_SHORT_GI_40 | - AR9170_PHY_TURBO_FC_DYN2040_PRI_CH; - offs = 1; - break; - default: - BUG(); - return -ENOSYS; - } - - if (ar->eeprom.tx_mask != 1) - tmp |= AR9170_PHY_TURBO_FC_WALSH; - - err = carl9170_write_reg(ar, AR9170_PHY_REG_TURBO, tmp); - if (err) - return err; - - err = carl9170_set_freq_cal_data(ar, channel); - if (err) - return err; - - carl9170_set_power_cal(ar, channel->center_freq, bw); - - err = carl9170_set_mac_tpc(ar, channel); - if (err) - return err; - - freqpar = carl9170_get_hw_dyn_params(channel, bw); - - rf.ht_settings = new_ht; - if (conf_is_ht40(&ar->hw->conf)) - SET_VAL(CARL9170FW_PHY_HT_EXT_CHAN_OFF, rf.ht_settings, offs); - - rf.freq = cpu_to_le32(channel->center_freq * 1000); - rf.delta_slope_coeff_exp = cpu_to_le32(freqpar->coeff_exp); - rf.delta_slope_coeff_man = cpu_to_le32(freqpar->coeff_man); - rf.delta_slope_coeff_exp_shgi = cpu_to_le32(freqpar->coeff_exp_shgi); - rf.delta_slope_coeff_man_shgi = cpu_to_le32(freqpar->coeff_man_shgi); - - if (rfi != CARL9170_RFI_NONE) - rf.finiteLoopCount = cpu_to_le32(2000); - else - rf.finiteLoopCount = cpu_to_le32(1000); - - err = carl9170_exec_cmd(ar, cmd, sizeof(rf), &rf, - sizeof(rf_res), &rf_res); - if (err) - return err; - - err = le32_to_cpu(rf_res.ret); - if (err != 0) { - ar->chan_fail++; - ar->total_chan_fail++; - - wiphy_err(ar->hw->wiphy, "channel change: %d -> %d " - "failed (%d).\n", old_channel ? - old_channel->center_freq : -1, channel->center_freq, - err); - - if ((rfi == CARL9170_RFI_COLD) || (ar->chan_fail > 3)) { - /* - * We have tried very hard to change to _another_ - * channel and we've failed to do so! - * Chances are that the PHY/RF is no longer - * operable (due to corruptions/fatal events/bugs?) - * and we need to reset at a higher level. - */ - carl9170_restart(ar, CARL9170_RR_TOO_MANY_PHY_ERRORS); - return 0; - } - - err = carl9170_set_channel(ar, channel, _bw, - CARL9170_RFI_COLD); - if (err) - return err; - } else { - ar->chan_fail = 0; - } - - if (ar->heavy_clip) { - err = carl9170_write_reg(ar, AR9170_PHY_REG_HEAVY_CLIP_ENABLE, - 0x200 | ar->heavy_clip); - if (err) { - if (net_ratelimit()) { - wiphy_err(ar->hw->wiphy, "failed to set " - "heavy clip\n"); - } - - return err; - } - } - - ar->channel = channel; - ar->ht_settings = new_ht; - return 0; -} diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/phy.h b/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/phy.h deleted file mode 100644 index 024fb42b..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/phy.h +++ /dev/null @@ -1,564 +0,0 @@ -/* - * Shared Atheros AR9170 Header - * - * PHY register map - * - * Copyright (c) 2008-2009 Atheros Communications Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef __CARL9170_SHARED_PHY_H -#define __CARL9170_SHARED_PHY_H - -#define AR9170_PHY_REG_BASE (0x1bc000 + 0x9800) -#define AR9170_PHY_REG(_n) (AR9170_PHY_REG_BASE + \ - ((_n) << 2)) - -#define AR9170_PHY_REG_TEST (AR9170_PHY_REG_BASE + 0x0000) -#define AR9170_PHY_TEST_AGC_CLR 0x10000000 -#define AR9170_PHY_TEST_RFSILENT_BB 0x00002000 - -#define AR9170_PHY_REG_TURBO (AR9170_PHY_REG_BASE + 0x0004) -#define AR9170_PHY_TURBO_FC_TURBO_MODE 0x00000001 -#define AR9170_PHY_TURBO_FC_TURBO_SHORT 0x00000002 -#define AR9170_PHY_TURBO_FC_DYN2040_EN 0x00000004 -#define AR9170_PHY_TURBO_FC_DYN2040_PRI_ONLY 0x00000008 -#define AR9170_PHY_TURBO_FC_DYN2040_PRI_CH 0x00000010 -/* For 25 MHz channel spacing -- not used but supported by hw */ -#define AR9170_PHY_TURBO_FC_DYN2040_EXT_CH 0x00000020 -#define AR9170_PHY_TURBO_FC_HT_EN 0x00000040 -#define AR9170_PHY_TURBO_FC_SHORT_GI_40 0x00000080 -#define AR9170_PHY_TURBO_FC_WALSH 0x00000100 -#define AR9170_PHY_TURBO_FC_SINGLE_HT_LTF1 0x00000200 -#define AR9170_PHY_TURBO_FC_ENABLE_DAC_FIFO 0x00000800 - -#define AR9170_PHY_REG_TEST2 (AR9170_PHY_REG_BASE + 0x0008) - -#define AR9170_PHY_REG_TIMING2 (AR9170_PHY_REG_BASE + 0x0010) -#define AR9170_PHY_TIMING2_USE_FORCE 0x00001000 -#define AR9170_PHY_TIMING2_FORCE 0x00000fff -#define AR9170_PHY_TIMING2_FORCE_S 0 - -#define AR9170_PHY_REG_TIMING3 (AR9170_PHY_REG_BASE + 0x0014) -#define AR9170_PHY_TIMING3_DSC_EXP 0x0001e000 -#define AR9170_PHY_TIMING3_DSC_EXP_S 13 -#define AR9170_PHY_TIMING3_DSC_MAN 0xfffe0000 -#define AR9170_PHY_TIMING3_DSC_MAN_S 17 - -#define AR9170_PHY_REG_CHIP_ID (AR9170_PHY_REG_BASE + 0x0018) -#define AR9170_PHY_CHIP_ID_REV_0 0x80 -#define AR9170_PHY_CHIP_ID_REV_1 0x81 -#define AR9170_PHY_CHIP_ID_9160_REV_0 0xb0 - -#define AR9170_PHY_REG_ACTIVE (AR9170_PHY_REG_BASE + 0x001c) -#define AR9170_PHY_ACTIVE_EN 0x00000001 -#define AR9170_PHY_ACTIVE_DIS 0x00000000 - -#define AR9170_PHY_REG_RF_CTL2 (AR9170_PHY_REG_BASE + 0x0024) -#define AR9170_PHY_RF_CTL2_TX_END_DATA_START 0x000000ff -#define AR9170_PHY_RF_CTL2_TX_END_DATA_START_S 0 -#define AR9170_PHY_RF_CTL2_TX_END_PA_ON 0x0000ff00 -#define AR9170_PHY_RF_CTL2_TX_END_PA_ON_S 8 - -#define AR9170_PHY_REG_RF_CTL3 (AR9170_PHY_REG_BASE + 0x0028) -#define AR9170_PHY_RF_CTL3_TX_END_TO_A2_RX_ON 0x00ff0000 -#define AR9170_PHY_RF_CTL3_TX_END_TO_A2_RX_ON_S 16 - -#define AR9170_PHY_REG_ADC_CTL (AR9170_PHY_REG_BASE + 0x002c) -#define AR9170_PHY_ADC_CTL_OFF_INBUFGAIN 0x00000003 -#define AR9170_PHY_ADC_CTL_OFF_INBUFGAIN_S 0 -#define AR9170_PHY_ADC_CTL_OFF_PWDDAC 0x00002000 -#define AR9170_PHY_ADC_CTL_OFF_PWDBANDGAP 0x00004000 -#define AR9170_PHY_ADC_CTL_OFF_PWDADC 0x00008000 -#define AR9170_PHY_ADC_CTL_ON_INBUFGAIN 0x00030000 -#define AR9170_PHY_ADC_CTL_ON_INBUFGAIN_S 16 - -#define AR9170_PHY_REG_ADC_SERIAL_CTL (AR9170_PHY_REG_BASE + 0x0030) -#define AR9170_PHY_ADC_SCTL_SEL_INTERNAL_ADDAC 0x00000000 -#define AR9170_PHY_ADC_SCTL_SEL_EXTERNAL_RADIO 0x00000001 - -#define AR9170_PHY_REG_RF_CTL4 (AR9170_PHY_REG_BASE + 0x0034) -#define AR9170_PHY_RF_CTL4_TX_END_XPAB_OFF 0xff000000 -#define AR9170_PHY_RF_CTL4_TX_END_XPAB_OFF_S 24 -#define AR9170_PHY_RF_CTL4_TX_END_XPAA_OFF 0x00ff0000 -#define AR9170_PHY_RF_CTL4_TX_END_XPAA_OFF_S 16 -#define AR9170_PHY_RF_CTL4_FRAME_XPAB_ON 0x0000ff00 -#define AR9170_PHY_RF_CTL4_FRAME_XPAB_ON_S 8 -#define AR9170_PHY_RF_CTL4_FRAME_XPAA_ON 0x000000ff -#define AR9170_PHY_RF_CTL4_FRAME_XPAA_ON_S 0 - -#define AR9170_PHY_REG_TSTDAC_CONST (AR9170_PHY_REG_BASE + 0x003c) - -#define AR9170_PHY_REG_SETTLING (AR9170_PHY_REG_BASE + 0x0044) -#define AR9170_PHY_SETTLING_SWITCH 0x00003f80 -#define AR9170_PHY_SETTLING_SWITCH_S 7 - -#define AR9170_PHY_REG_RXGAIN (AR9170_PHY_REG_BASE + 0x0048) -#define AR9170_PHY_REG_RXGAIN_CHAIN_2 (AR9170_PHY_REG_BASE + 0x2048) -#define AR9170_PHY_RXGAIN_TXRX_ATTEN 0x0003f000 -#define AR9170_PHY_RXGAIN_TXRX_ATTEN_S 12 -#define AR9170_PHY_RXGAIN_TXRX_RF_MAX 0x007c0000 -#define AR9170_PHY_RXGAIN_TXRX_RF_MAX_S 18 - -#define AR9170_PHY_REG_DESIRED_SZ (AR9170_PHY_REG_BASE + 0x0050) -#define AR9170_PHY_DESIRED_SZ_ADC 0x000000ff -#define AR9170_PHY_DESIRED_SZ_ADC_S 0 -#define AR9170_PHY_DESIRED_SZ_PGA 0x0000ff00 -#define AR9170_PHY_DESIRED_SZ_PGA_S 8 -#define AR9170_PHY_DESIRED_SZ_TOT_DES 0x0ff00000 -#define AR9170_PHY_DESIRED_SZ_TOT_DES_S 20 - -#define AR9170_PHY_REG_FIND_SIG (AR9170_PHY_REG_BASE + 0x0058) -#define AR9170_PHY_FIND_SIG_FIRSTEP 0x0003f000 -#define AR9170_PHY_FIND_SIG_FIRSTEP_S 12 -#define AR9170_PHY_FIND_SIG_FIRPWR 0x03fc0000 -#define AR9170_PHY_FIND_SIG_FIRPWR_S 18 - -#define AR9170_PHY_REG_AGC_CTL1 (AR9170_PHY_REG_BASE + 0x005c) -#define AR9170_PHY_AGC_CTL1_COARSE_LOW 0x00007f80 -#define AR9170_PHY_AGC_CTL1_COARSE_LOW_S 7 -#define AR9170_PHY_AGC_CTL1_COARSE_HIGH 0x003f8000 -#define AR9170_PHY_AGC_CTL1_COARSE_HIGH_S 15 - -#define AR9170_PHY_REG_AGC_CONTROL (AR9170_PHY_REG_BASE + 0x0060) -#define AR9170_PHY_AGC_CONTROL_CAL 0x00000001 -#define AR9170_PHY_AGC_CONTROL_NF 0x00000002 -#define AR9170_PHY_AGC_CONTROL_ENABLE_NF 0x00008000 -#define AR9170_PHY_AGC_CONTROL_FLTR_CAL 0x00010000 -#define AR9170_PHY_AGC_CONTROL_NO_UPDATE_NF 0x00020000 - -#define AR9170_PHY_REG_CCA (AR9170_PHY_REG_BASE + 0x0064) -#define AR9170_PHY_CCA_MIN_PWR 0x0ff80000 -#define AR9170_PHY_CCA_MIN_PWR_S 19 -#define AR9170_PHY_CCA_THRESH62 0x0007f000 -#define AR9170_PHY_CCA_THRESH62_S 12 - -#define AR9170_PHY_REG_SFCORR (AR9170_PHY_REG_BASE + 0x0068) -#define AR9170_PHY_SFCORR_M2COUNT_THR 0x0000001f -#define AR9170_PHY_SFCORR_M2COUNT_THR_S 0 -#define AR9170_PHY_SFCORR_M1_THRESH 0x00fe0000 -#define AR9170_PHY_SFCORR_M1_THRESH_S 17 -#define AR9170_PHY_SFCORR_M2_THRESH 0x7f000000 -#define AR9170_PHY_SFCORR_M2_THRESH_S 24 - -#define AR9170_PHY_REG_SFCORR_LOW (AR9170_PHY_REG_BASE + 0x006c) -#define AR9170_PHY_SFCORR_LOW_USE_SELF_CORR_LOW 0x00000001 -#define AR9170_PHY_SFCORR_LOW_M2COUNT_THR_LOW 0x00003f00 -#define AR9170_PHY_SFCORR_LOW_M2COUNT_THR_LOW_S 8 -#define AR9170_PHY_SFCORR_LOW_M1_THRESH_LOW 0x001fc000 -#define AR9170_PHY_SFCORR_LOW_M1_THRESH_LOW_S 14 -#define AR9170_PHY_SFCORR_LOW_M2_THRESH_LOW 0x0fe00000 -#define AR9170_PHY_SFCORR_LOW_M2_THRESH_LOW_S 21 - -#define AR9170_PHY_REG_SLEEP_CTR_CONTROL (AR9170_PHY_REG_BASE + 0x0070) -#define AR9170_PHY_REG_SLEEP_CTR_LIMIT (AR9170_PHY_REG_BASE + 0x0074) -#define AR9170_PHY_REG_SLEEP_SCAL (AR9170_PHY_REG_BASE + 0x0078) - -#define AR9170_PHY_REG_PLL_CTL (AR9170_PHY_REG_BASE + 0x007c) -#define AR9170_PHY_PLL_CTL_40 0xaa -#define AR9170_PHY_PLL_CTL_40_5413 0x04 -#define AR9170_PHY_PLL_CTL_44 0xab -#define AR9170_PHY_PLL_CTL_44_2133 0xeb -#define AR9170_PHY_PLL_CTL_40_2133 0xea - -#define AR9170_PHY_REG_BIN_MASK_1 (AR9170_PHY_REG_BASE + 0x0100) -#define AR9170_PHY_REG_BIN_MASK_2 (AR9170_PHY_REG_BASE + 0x0104) -#define AR9170_PHY_REG_BIN_MASK_3 (AR9170_PHY_REG_BASE + 0x0108) -#define AR9170_PHY_REG_MASK_CTL (AR9170_PHY_REG_BASE + 0x010c) - -/* analogue power on time (100ns) */ -#define AR9170_PHY_REG_RX_DELAY (AR9170_PHY_REG_BASE + 0x0114) -#define AR9170_PHY_REG_SEARCH_START_DELAY (AR9170_PHY_REG_BASE + 0x0118) -#define AR9170_PHY_RX_DELAY_DELAY 0x00003fff - -#define AR9170_PHY_REG_TIMING_CTRL4(_i) (AR9170_PHY_REG_BASE + \ - (0x0120 + ((_i) << 12))) -#define AR9170_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF 0x01f -#define AR9170_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF_S 0 -#define AR9170_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF 0x7e0 -#define AR9170_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF_S 5 -#define AR9170_PHY_TIMING_CTRL4_IQCORR_ENABLE 0x800 -#define AR9170_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX 0xf000 -#define AR9170_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX_S 12 -#define AR9170_PHY_TIMING_CTRL4_DO_IQCAL 0x10000 -#define AR9170_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI 0x80000000 -#define AR9170_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER 0x40000000 -#define AR9170_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK 0x20000000 -#define AR9170_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK 0x10000000 - -#define AR9170_PHY_REG_TIMING5 (AR9170_PHY_REG_BASE + 0x0124) -#define AR9170_PHY_TIMING5_CYCPWR_THR1 0x000000fe -#define AR9170_PHY_TIMING5_CYCPWR_THR1_S 1 - -#define AR9170_PHY_REG_POWER_TX_RATE1 (AR9170_PHY_REG_BASE + 0x0134) -#define AR9170_PHY_REG_POWER_TX_RATE2 (AR9170_PHY_REG_BASE + 0x0138) -#define AR9170_PHY_REG_POWER_TX_RATE_MAX (AR9170_PHY_REG_BASE + 0x013c) -#define AR9170_PHY_POWER_TX_RATE_MAX_TPC_ENABLE 0x00000040 - -#define AR9170_PHY_REG_FRAME_CTL (AR9170_PHY_REG_BASE + 0x0144) -#define AR9170_PHY_FRAME_CTL_TX_CLIP 0x00000038 -#define AR9170_PHY_FRAME_CTL_TX_CLIP_S 3 - -#define AR9170_PHY_REG_SPUR_REG (AR9170_PHY_REG_BASE + 0x014c) -#define AR9170_PHY_SPUR_REG_MASK_RATE_CNTL (0xff << 18) -#define AR9170_PHY_SPUR_REG_MASK_RATE_CNTL_S 18 -#define AR9170_PHY_SPUR_REG_ENABLE_MASK_PPM 0x20000 -#define AR9170_PHY_SPUR_REG_MASK_RATE_SELECT (0xff << 9) -#define AR9170_PHY_SPUR_REG_MASK_RATE_SELECT_S 9 -#define AR9170_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI 0x100 -#define AR9170_PHY_SPUR_REG_SPUR_RSSI_THRESH 0x7f -#define AR9170_PHY_SPUR_REG_SPUR_RSSI_THRESH_S 0 - -#define AR9170_PHY_REG_RADAR_EXT (AR9170_PHY_REG_BASE + 0x0140) -#define AR9170_PHY_RADAR_EXT_ENA 0x00004000 - -#define AR9170_PHY_REG_RADAR_0 (AR9170_PHY_REG_BASE + 0x0154) -#define AR9170_PHY_RADAR_0_ENA 0x00000001 -#define AR9170_PHY_RADAR_0_FFT_ENA 0x80000000 -/* inband pulse threshold */ -#define AR9170_PHY_RADAR_0_INBAND 0x0000003e -#define AR9170_PHY_RADAR_0_INBAND_S 1 -/* pulse RSSI threshold */ -#define AR9170_PHY_RADAR_0_PRSSI 0x00000fc0 -#define AR9170_PHY_RADAR_0_PRSSI_S 6 -/* pulse height threshold */ -#define AR9170_PHY_RADAR_0_HEIGHT 0x0003f000 -#define AR9170_PHY_RADAR_0_HEIGHT_S 12 -/* radar RSSI threshold */ -#define AR9170_PHY_RADAR_0_RRSSI 0x00fc0000 -#define AR9170_PHY_RADAR_0_RRSSI_S 18 -/* radar firepower threshold */ -#define AR9170_PHY_RADAR_0_FIRPWR 0x7f000000 -#define AR9170_PHY_RADAR_0_FIRPWR_S 24 - -#define AR9170_PHY_REG_RADAR_1 (AR9170_PHY_REG_BASE + 0x0158) -#define AR9170_PHY_RADAR_1_RELPWR_ENA 0x00800000 -#define AR9170_PHY_RADAR_1_USE_FIR128 0x00400000 -#define AR9170_PHY_RADAR_1_RELPWR_THRESH 0x003f0000 -#define AR9170_PHY_RADAR_1_RELPWR_THRESH_S 16 -#define AR9170_PHY_RADAR_1_BLOCK_CHECK 0x00008000 -#define AR9170_PHY_RADAR_1_MAX_RRSSI 0x00004000 -#define AR9170_PHY_RADAR_1_RELSTEP_CHECK 0x00002000 -#define AR9170_PHY_RADAR_1_RELSTEP_THRESH 0x00001f00 -#define AR9170_PHY_RADAR_1_RELSTEP_THRESH_S 8 -#define AR9170_PHY_RADAR_1_MAXLEN 0x000000ff -#define AR9170_PHY_RADAR_1_MAXLEN_S 0 - -#define AR9170_PHY_REG_SWITCH_CHAIN_0 (AR9170_PHY_REG_BASE + 0x0160) -#define AR9170_PHY_REG_SWITCH_CHAIN_2 (AR9170_PHY_REG_BASE + 0x2160) - -#define AR9170_PHY_REG_SWITCH_COM (AR9170_PHY_REG_BASE + 0x0164) - -#define AR9170_PHY_REG_CCA_THRESHOLD (AR9170_PHY_REG_BASE + 0x0168) - -#define AR9170_PHY_REG_SIGMA_DELTA (AR9170_PHY_REG_BASE + 0x016c) -#define AR9170_PHY_SIGMA_DELTA_ADC_SEL 0x00000003 -#define AR9170_PHY_SIGMA_DELTA_ADC_SEL_S 0 -#define AR9170_PHY_SIGMA_DELTA_FILT2 0x000000f8 -#define AR9170_PHY_SIGMA_DELTA_FILT2_S 3 -#define AR9170_PHY_SIGMA_DELTA_FILT1 0x00001f00 -#define AR9170_PHY_SIGMA_DELTA_FILT1_S 8 -#define AR9170_PHY_SIGMA_DELTA_ADC_CLIP 0x01ffe000 -#define AR9170_PHY_SIGMA_DELTA_ADC_CLIP_S 13 - -#define AR9170_PHY_REG_RESTART (AR9170_PHY_REG_BASE + 0x0170) -#define AR9170_PHY_RESTART_DIV_GC 0x001c0000 -#define AR9170_PHY_RESTART_DIV_GC_S 18 - -#define AR9170_PHY_REG_RFBUS_REQ (AR9170_PHY_REG_BASE + 0x017c) -#define AR9170_PHY_RFBUS_REQ_EN 0x00000001 - -#define AR9170_PHY_REG_TIMING7 (AR9170_PHY_REG_BASE + 0x0180) -#define AR9170_PHY_REG_TIMING8 (AR9170_PHY_REG_BASE + 0x0184) -#define AR9170_PHY_TIMING8_PILOT_MASK_2 0x000fffff -#define AR9170_PHY_TIMING8_PILOT_MASK_2_S 0 - -#define AR9170_PHY_REG_BIN_MASK2_1 (AR9170_PHY_REG_BASE + 0x0188) -#define AR9170_PHY_REG_BIN_MASK2_2 (AR9170_PHY_REG_BASE + 0x018c) -#define AR9170_PHY_REG_BIN_MASK2_3 (AR9170_PHY_REG_BASE + 0x0190) -#define AR9170_PHY_REG_BIN_MASK2_4 (AR9170_PHY_REG_BASE + 0x0194) -#define AR9170_PHY_BIN_MASK2_4_MASK_4 0x00003fff -#define AR9170_PHY_BIN_MASK2_4_MASK_4_S 0 - -#define AR9170_PHY_REG_TIMING9 (AR9170_PHY_REG_BASE + 0x0198) -#define AR9170_PHY_REG_TIMING10 (AR9170_PHY_REG_BASE + 0x019c) -#define AR9170_PHY_TIMING10_PILOT_MASK_2 0x000fffff -#define AR9170_PHY_TIMING10_PILOT_MASK_2_S 0 - -#define AR9170_PHY_REG_TIMING11 (AR9170_PHY_REG_BASE + 0x01a0) -#define AR9170_PHY_TIMING11_SPUR_DELTA_PHASE 0x000fffff -#define AR9170_PHY_TIMING11_SPUR_DELTA_PHASE_S 0 -#define AR9170_PHY_TIMING11_SPUR_FREQ_SD 0x3ff00000 -#define AR9170_PHY_TIMING11_SPUR_FREQ_SD_S 20 -#define AR9170_PHY_TIMING11_USE_SPUR_IN_AGC 0x40000000 -#define AR9170_PHY_TIMING11_USE_SPUR_IN_SELFCOR 0x80000000 - -#define AR9170_PHY_REG_RX_CHAINMASK (AR9170_PHY_REG_BASE + 0x01a4) -#define AR9170_PHY_REG_NEW_ADC_DC_GAIN_CORR(_i) (AR9170_PHY_REG_BASE + \ - 0x01b4 + ((_i) << 12)) -#define AR9170_PHY_NEW_ADC_GAIN_CORR_ENABLE 0x40000000 -#define AR9170_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE 0x80000000 - -#define AR9170_PHY_REG_MULTICHAIN_GAIN_CTL (AR9170_PHY_REG_BASE + 0x01ac) -#define AR9170_PHY_9285_ANT_DIV_CTL_ALL 0x7f000000 -#define AR9170_PHY_9285_ANT_DIV_CTL 0x01000000 -#define AR9170_PHY_9285_ANT_DIV_CTL_S 24 -#define AR9170_PHY_9285_ANT_DIV_ALT_LNACONF 0x06000000 -#define AR9170_PHY_9285_ANT_DIV_ALT_LNACONF_S 25 -#define AR9170_PHY_9285_ANT_DIV_MAIN_LNACONF 0x18000000 -#define AR9170_PHY_9285_ANT_DIV_MAIN_LNACONF_S 27 -#define AR9170_PHY_9285_ANT_DIV_ALT_GAINTB 0x20000000 -#define AR9170_PHY_9285_ANT_DIV_ALT_GAINTB_S 29 -#define AR9170_PHY_9285_ANT_DIV_MAIN_GAINTB 0x40000000 -#define AR9170_PHY_9285_ANT_DIV_MAIN_GAINTB_S 30 -#define AR9170_PHY_9285_ANT_DIV_LNA1 2 -#define AR9170_PHY_9285_ANT_DIV_LNA2 1 -#define AR9170_PHY_9285_ANT_DIV_LNA1_PLUS_LNA2 3 -#define AR9170_PHY_9285_ANT_DIV_LNA1_MINUS_LNA2 0 -#define AR9170_PHY_9285_ANT_DIV_GAINTB_0 0 -#define AR9170_PHY_9285_ANT_DIV_GAINTB_1 1 - -#define AR9170_PHY_REG_EXT_CCA0 (AR9170_PHY_REG_BASE + 0x01b8) -#define AR9170_PHY_REG_EXT_CCA0_THRESH62 0x000000ff -#define AR9170_PHY_REG_EXT_CCA0_THRESH62_S 0 - -#define AR9170_PHY_REG_EXT_CCA (AR9170_PHY_REG_BASE + 0x01bc) -#define AR9170_PHY_EXT_CCA_CYCPWR_THR1 0x0000fe00 -#define AR9170_PHY_EXT_CCA_CYCPWR_THR1_S 9 -#define AR9170_PHY_EXT_CCA_THRESH62 0x007f0000 -#define AR9170_PHY_EXT_CCA_THRESH62_S 16 -#define AR9170_PHY_EXT_CCA_MIN_PWR 0xff800000 -#define AR9170_PHY_EXT_CCA_MIN_PWR_S 23 - -#define AR9170_PHY_REG_SFCORR_EXT (AR9170_PHY_REG_BASE + 0x01c0) -#define AR9170_PHY_SFCORR_EXT_M1_THRESH 0x0000007f -#define AR9170_PHY_SFCORR_EXT_M1_THRESH_S 0 -#define AR9170_PHY_SFCORR_EXT_M2_THRESH 0x00003f80 -#define AR9170_PHY_SFCORR_EXT_M2_THRESH_S 7 -#define AR9170_PHY_SFCORR_EXT_M1_THRESH_LOW 0x001fc000 -#define AR9170_PHY_SFCORR_EXT_M1_THRESH_LOW_S 14 -#define AR9170_PHY_SFCORR_EXT_M2_THRESH_LOW 0x0fe00000 -#define AR9170_PHY_SFCORR_EXT_M2_THRESH_LOW_S 21 -#define AR9170_PHY_SFCORR_SPUR_SUBCHNL_SD_S 28 - -#define AR9170_PHY_REG_HALFGI (AR9170_PHY_REG_BASE + 0x01d0) -#define AR9170_PHY_HALFGI_DSC_MAN 0x0007fff0 -#define AR9170_PHY_HALFGI_DSC_MAN_S 4 -#define AR9170_PHY_HALFGI_DSC_EXP 0x0000000f -#define AR9170_PHY_HALFGI_DSC_EXP_S 0 - -#define AR9170_PHY_REG_CHANNEL_MASK_01_30 (AR9170_PHY_REG_BASE + 0x01d4) -#define AR9170_PHY_REG_CHANNEL_MASK_31_60 (AR9170_PHY_REG_BASE + 0x01d8) - -#define AR9170_PHY_REG_CHAN_INFO_MEMORY (AR9170_PHY_REG_BASE + 0x01dc) -#define AR9170_PHY_CHAN_INFO_MEMORY_CAPTURE_MASK 0x0001 - -#define AR9170_PHY_REG_HEAVY_CLIP_ENABLE (AR9170_PHY_REG_BASE + 0x01e0) -#define AR9170_PHY_REG_HEAVY_CLIP_FACTOR_RIFS (AR9170_PHY_REG_BASE + 0x01ec) -#define AR9170_PHY_RIFS_INIT_DELAY 0x03ff0000 - -#define AR9170_PHY_REG_CALMODE (AR9170_PHY_REG_BASE + 0x01f0) -#define AR9170_PHY_CALMODE_IQ 0x00000000 -#define AR9170_PHY_CALMODE_ADC_GAIN 0x00000001 -#define AR9170_PHY_CALMODE_ADC_DC_PER 0x00000002 -#define AR9170_PHY_CALMODE_ADC_DC_INIT 0x00000003 - -#define AR9170_PHY_REG_REFCLKDLY (AR9170_PHY_REG_BASE + 0x01f4) -#define AR9170_PHY_REG_REFCLKPD (AR9170_PHY_REG_BASE + 0x01f8) - - -#define AR9170_PHY_REG_CAL_MEAS_0(_i) (AR9170_PHY_REG_BASE + \ - 0x0410 + ((_i) << 12)) -#define AR9170_PHY_REG_CAL_MEAS_1(_i) (AR9170_PHY_REG_BASE + \ - 0x0414 \ + ((_i) << 12)) -#define AR9170_PHY_REG_CAL_MEAS_2(_i) (AR9170_PHY_REG_BASE + \ - 0x0418 + ((_i) << 12)) -#define AR9170_PHY_REG_CAL_MEAS_3(_i) (AR9170_PHY_REG_BASE + \ - 0x041c + ((_i) << 12)) - -#define AR9170_PHY_REG_CURRENT_RSSI (AR9170_PHY_REG_BASE + 0x041c) - -#define AR9170_PHY_REG_RFBUS_GRANT (AR9170_PHY_REG_BASE + 0x0420) -#define AR9170_PHY_RFBUS_GRANT_EN 0x00000001 - -#define AR9170_PHY_REG_CHAN_INFO_GAIN_DIFF (AR9170_PHY_REG_BASE + 0x04f4) -#define AR9170_PHY_CHAN_INFO_GAIN_DIFF_UPPER_LIMIT 320 - -#define AR9170_PHY_REG_CHAN_INFO_GAIN (AR9170_PHY_REG_BASE + 0x04fc) - -#define AR9170_PHY_REG_MODE (AR9170_PHY_REG_BASE + 0x0a00) -#define AR9170_PHY_MODE_ASYNCFIFO 0x80 -#define AR9170_PHY_MODE_AR2133 0x08 -#define AR9170_PHY_MODE_AR5111 0x00 -#define AR9170_PHY_MODE_AR5112 0x08 -#define AR9170_PHY_MODE_DYNAMIC 0x04 -#define AR9170_PHY_MODE_RF2GHZ 0x02 -#define AR9170_PHY_MODE_RF5GHZ 0x00 -#define AR9170_PHY_MODE_CCK 0x01 -#define AR9170_PHY_MODE_OFDM 0x00 -#define AR9170_PHY_MODE_DYN_CCK_DISABLE 0x100 - -#define AR9170_PHY_REG_CCK_TX_CTRL (AR9170_PHY_REG_BASE + 0x0a04) -#define AR9170_PHY_CCK_TX_CTRL_JAPAN 0x00000010 -#define AR9170_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK 0x0000000c -#define AR9170_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK_S 2 - -#define AR9170_PHY_REG_CCK_DETECT (AR9170_PHY_REG_BASE + 0x0a08) -#define AR9170_PHY_CCK_DETECT_WEAK_SIG_THR_CCK 0x0000003f -#define AR9170_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_S 0 -/* [12:6] settling time for antenna switch */ -#define AR9170_PHY_CCK_DETECT_ANT_SWITCH_TIME 0x00001fc0 -#define AR9170_PHY_CCK_DETECT_ANT_SWITCH_TIME_S 6 -#define AR9170_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV 0x2000 -#define AR9170_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV_S 13 - -#define AR9170_PHY_REG_GAIN_2GHZ (AR9170_PHY_REG_BASE + 0x0a0c) -#define AR9170_PHY_REG_GAIN_2GHZ_CHAIN_2 (AR9170_PHY_REG_BASE + 0x2a0c) -#define AR9170_PHY_GAIN_2GHZ_RXTX_MARGIN 0x00fc0000 -#define AR9170_PHY_GAIN_2GHZ_RXTX_MARGIN_S 18 -#define AR9170_PHY_GAIN_2GHZ_BSW_MARGIN 0x00003c00 -#define AR9170_PHY_GAIN_2GHZ_BSW_MARGIN_S 10 -#define AR9170_PHY_GAIN_2GHZ_BSW_ATTEN 0x0000001f -#define AR9170_PHY_GAIN_2GHZ_BSW_ATTEN_S 0 -#define AR9170_PHY_GAIN_2GHZ_XATTEN2_MARGIN 0x003e0000 -#define AR9170_PHY_GAIN_2GHZ_XATTEN2_MARGIN_S 17 -#define AR9170_PHY_GAIN_2GHZ_XATTEN1_MARGIN 0x0001f000 -#define AR9170_PHY_GAIN_2GHZ_XATTEN1_MARGIN_S 12 -#define AR9170_PHY_GAIN_2GHZ_XATTEN2_DB 0x00000fc0 -#define AR9170_PHY_GAIN_2GHZ_XATTEN2_DB_S 6 -#define AR9170_PHY_GAIN_2GHZ_XATTEN1_DB 0x0000003f -#define AR9170_PHY_GAIN_2GHZ_XATTEN1_DB_S 0 - -#define AR9170_PHY_REG_CCK_RXCTRL4 (AR9170_PHY_REG_BASE + 0x0a1c) -#define AR9170_PHY_CCK_RXCTRL4_FREQ_EST_SHORT 0x01f80000 -#define AR9170_PHY_CCK_RXCTRL4_FREQ_EST_SHORT_S 19 - -#define AR9170_PHY_REG_DAG_CTRLCCK (AR9170_PHY_REG_BASE + 0x0a28) -#define AR9170_REG_DAG_CTRLCCK_EN_RSSI_THR 0x00000200 -#define AR9170_REG_DAG_CTRLCCK_RSSI_THR 0x0001fc00 -#define AR9170_REG_DAG_CTRLCCK_RSSI_THR_S 10 - -#define AR9170_PHY_REG_FORCE_CLKEN_CCK (AR9170_PHY_REG_BASE + 0x0a2c) -#define AR9170_FORCE_CLKEN_CCK_MRC_MUX 0x00000040 - -#define AR9170_PHY_REG_POWER_TX_RATE3 (AR9170_PHY_REG_BASE + 0x0a34) -#define AR9170_PHY_REG_POWER_TX_RATE4 (AR9170_PHY_REG_BASE + 0x0a38) - -#define AR9170_PHY_REG_SCRM_SEQ_XR (AR9170_PHY_REG_BASE + 0x0a3c) -#define AR9170_PHY_REG_HEADER_DETECT_XR (AR9170_PHY_REG_BASE + 0x0a40) -#define AR9170_PHY_REG_CHIRP_DETECTED_XR (AR9170_PHY_REG_BASE + 0x0a44) -#define AR9170_PHY_REG_BLUETOOTH (AR9170_PHY_REG_BASE + 0x0a54) - -#define AR9170_PHY_REG_TPCRG1 (AR9170_PHY_REG_BASE + 0x0a58) -#define AR9170_PHY_TPCRG1_NUM_PD_GAIN 0x0000c000 -#define AR9170_PHY_TPCRG1_NUM_PD_GAIN_S 14 -#define AR9170_PHY_TPCRG1_PD_GAIN_1 0x00030000 -#define AR9170_PHY_TPCRG1_PD_GAIN_1_S 16 -#define AR9170_PHY_TPCRG1_PD_GAIN_2 0x000c0000 -#define AR9170_PHY_TPCRG1_PD_GAIN_2_S 18 -#define AR9170_PHY_TPCRG1_PD_GAIN_3 0x00300000 -#define AR9170_PHY_TPCRG1_PD_GAIN_3_S 20 -#define AR9170_PHY_TPCRG1_PD_CAL_ENABLE 0x00400000 -#define AR9170_PHY_TPCRG1_PD_CAL_ENABLE_S 22 - -#define AR9170_PHY_REG_TX_PWRCTRL4 (AR9170_PHY_REG_BASE + 0x0a64) -#define AR9170_PHY_TX_PWRCTRL_PD_AVG_VALID 0x00000001 -#define AR9170_PHY_TX_PWRCTRL_PD_AVG_VALID_S 0 -#define AR9170_PHY_TX_PWRCTRL_PD_AVG_OUT 0x000001fe -#define AR9170_PHY_TX_PWRCTRL_PD_AVG_OUT_S 1 - -#define AR9170_PHY_REG_ANALOG_SWAP (AR9170_PHY_REG_BASE + 0x0a68) -#define AR9170_PHY_ANALOG_SWAP_AB 0x0001 -#define AR9170_PHY_ANALOG_SWAP_ALT_CHAIN 0x00000040 - -#define AR9170_PHY_REG_TPCRG5 (AR9170_PHY_REG_BASE + 0x0a6c) -#define AR9170_PHY_TPCRG5_PD_GAIN_OVERLAP 0x0000000f -#define AR9170_PHY_TPCRG5_PD_GAIN_OVERLAP_S 0 -#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_1 0x000003f0 -#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_1_S 4 -#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_2 0x0000fc00 -#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_2_S 10 -#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_3 0x003f0000 -#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_3_S 16 -#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_4 0x0fc00000 -#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_4_S 22 - -#define AR9170_PHY_REG_TX_PWRCTRL6_0 (AR9170_PHY_REG_BASE + 0x0a70) -#define AR9170_PHY_REG_TX_PWRCTRL6_1 (AR9170_PHY_REG_BASE + 0x1a70) -#define AR9170_PHY_TX_PWRCTRL_ERR_EST_MODE 0x03000000 -#define AR9170_PHY_TX_PWRCTRL_ERR_EST_MODE_S 24 - -#define AR9170_PHY_REG_TX_PWRCTRL7 (AR9170_PHY_REG_BASE + 0x0a74) -#define AR9170_PHY_TX_PWRCTRL_INIT_TX_GAIN 0x01f80000 -#define AR9170_PHY_TX_PWRCTRL_INIT_TX_GAIN_S 19 - -#define AR9170_PHY_REG_TX_PWRCTRL9 (AR9170_PHY_REG_BASE + 0x0a7c) -#define AR9170_PHY_TX_DESIRED_SCALE_CCK 0x00007c00 -#define AR9170_PHY_TX_DESIRED_SCALE_CCK_S 10 -#define AR9170_PHY_TX_PWRCTRL9_RES_DC_REMOVAL 0x80000000 -#define AR9170_PHY_TX_PWRCTRL9_RES_DC_REMOVAL_S 31 - -#define AR9170_PHY_REG_TX_GAIN_TBL1 (AR9170_PHY_REG_BASE + 0x0b00) -#define AR9170_PHY_TX_GAIN 0x0007f000 -#define AR9170_PHY_TX_GAIN_S 12 - -/* Carrier leak calibration control, do it after AGC calibration */ -#define AR9170_PHY_REG_CL_CAL_CTL (AR9170_PHY_REG_BASE + 0x0b58) -#define AR9170_PHY_CL_CAL_ENABLE 0x00000002 -#define AR9170_PHY_CL_CAL_PARALLEL_CAL_ENABLE 0x00000001 - -#define AR9170_PHY_REG_POWER_TX_RATE5 (AR9170_PHY_REG_BASE + 0x0b8c) -#define AR9170_PHY_REG_POWER_TX_RATE6 (AR9170_PHY_REG_BASE + 0x0b90) - -#define AR9170_PHY_REG_CH0_TX_PWRCTRL11 (AR9170_PHY_REG_BASE + 0x0b98) -#define AR9170_PHY_REG_CH1_TX_PWRCTRL11 (AR9170_PHY_REG_BASE + 0x1b98) -#define AR9170_PHY_TX_CHX_PWRCTRL_OLPC_TEMP_COMP 0x0000fc00 -#define AR9170_PHY_TX_CHX_PWRCTRL_OLPC_TEMP_COMP_S 10 - -#define AR9170_PHY_REG_CAL_CHAINMASK (AR9170_PHY_REG_BASE + 0x0b9c) -#define AR9170_PHY_REG_VIT_MASK2_M_46_61 (AR9170_PHY_REG_BASE + 0x0ba0) -#define AR9170_PHY_REG_MASK2_M_31_45 (AR9170_PHY_REG_BASE + 0x0ba4) -#define AR9170_PHY_REG_MASK2_M_16_30 (AR9170_PHY_REG_BASE + 0x0ba8) -#define AR9170_PHY_REG_MASK2_M_00_15 (AR9170_PHY_REG_BASE + 0x0bac) -#define AR9170_PHY_REG_PILOT_MASK_01_30 (AR9170_PHY_REG_BASE + 0x0bb0) -#define AR9170_PHY_REG_PILOT_MASK_31_60 (AR9170_PHY_REG_BASE + 0x0bb4) -#define AR9170_PHY_REG_MASK2_P_15_01 (AR9170_PHY_REG_BASE + 0x0bb8) -#define AR9170_PHY_REG_MASK2_P_30_16 (AR9170_PHY_REG_BASE + 0x0bbc) -#define AR9170_PHY_REG_MASK2_P_45_31 (AR9170_PHY_REG_BASE + 0x0bc0) -#define AR9170_PHY_REG_MASK2_P_61_45 (AR9170_PHY_REG_BASE + 0x0bc4) -#define AR9170_PHY_REG_POWER_TX_SUB (AR9170_PHY_REG_BASE + 0x0bc8) -#define AR9170_PHY_REG_POWER_TX_RATE7 (AR9170_PHY_REG_BASE + 0x0bcc) -#define AR9170_PHY_REG_POWER_TX_RATE8 (AR9170_PHY_REG_BASE + 0x0bd0) -#define AR9170_PHY_REG_POWER_TX_RATE9 (AR9170_PHY_REG_BASE + 0x0bd4) -#define AR9170_PHY_REG_XPA_CFG (AR9170_PHY_REG_BASE + 0x0bd8) -#define AR9170_PHY_FORCE_XPA_CFG 0x000000001 -#define AR9170_PHY_FORCE_XPA_CFG_S 0 - -#define AR9170_PHY_REG_CH1_CCA (AR9170_PHY_REG_BASE + 0x1064) -#define AR9170_PHY_CH1_CCA_MIN_PWR 0x0ff80000 -#define AR9170_PHY_CH1_CCA_MIN_PWR_S 19 - -#define AR9170_PHY_REG_CH2_CCA (AR9170_PHY_REG_BASE + 0x2064) -#define AR9170_PHY_CH2_CCA_MIN_PWR 0x0ff80000 -#define AR9170_PHY_CH2_CCA_MIN_PWR_S 19 - -#define AR9170_PHY_REG_CH1_EXT_CCA (AR9170_PHY_REG_BASE + 0x11bc) -#define AR9170_PHY_CH1_EXT_CCA_MIN_PWR 0xff800000 -#define AR9170_PHY_CH1_EXT_CCA_MIN_PWR_S 23 - -#define AR9170_PHY_REG_CH2_EXT_CCA (AR9170_PHY_REG_BASE + 0x21bc) -#define AR9170_PHY_CH2_EXT_CCA_MIN_PWR 0xff800000 -#define AR9170_PHY_CH2_EXT_CCA_MIN_PWR_S 23 - -#endif /* __CARL9170_SHARED_PHY_H */ diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/rx.c b/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/rx.c deleted file mode 100644 index dc99030e..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/rx.c +++ /dev/null @@ -1,938 +0,0 @@ -/* - * Atheros CARL9170 driver - * - * 802.11 & command trap routines - * - * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> - * Copyright 2009, 2010, Christian Lamparter <chunkeey@googlemail.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, see - * http://www.gnu.org/licenses/. - * - * This file incorporates work covered by the following copyright and - * permission notice: - * Copyright (c) 2007-2008 Atheros Communications, Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/etherdevice.h> -#include <linux/crc32.h> -#include <net/mac80211.h> -#include "carl9170.h" -#include "hw.h" -#include "cmd.h" - -static void carl9170_dbg_message(struct ar9170 *ar, const char *buf, u32 len) -{ - bool restart = false; - enum carl9170_restart_reasons reason = CARL9170_RR_NO_REASON; - - if (len > 3) { - if (memcmp(buf, CARL9170_ERR_MAGIC, 3) == 0) { - ar->fw.err_counter++; - if (ar->fw.err_counter > 3) { - restart = true; - reason = CARL9170_RR_TOO_MANY_FIRMWARE_ERRORS; - } - } - - if (memcmp(buf, CARL9170_BUG_MAGIC, 3) == 0) { - ar->fw.bug_counter++; - restart = true; - reason = CARL9170_RR_FATAL_FIRMWARE_ERROR; - } - } - - wiphy_info(ar->hw->wiphy, "FW: %.*s\n", len, buf); - - if (restart) - carl9170_restart(ar, reason); -} - -static void carl9170_handle_ps(struct ar9170 *ar, struct carl9170_rsp *rsp) -{ - u32 ps; - bool new_ps; - - ps = le32_to_cpu(rsp->psm.state); - - new_ps = (ps & CARL9170_PSM_COUNTER) != CARL9170_PSM_WAKE; - if (ar->ps.state != new_ps) { - if (!new_ps) { - ar->ps.sleep_ms = jiffies_to_msecs(jiffies - - ar->ps.last_action); - } - - ar->ps.last_action = jiffies; - - ar->ps.state = new_ps; - } -} - -static int carl9170_check_sequence(struct ar9170 *ar, unsigned int seq) -{ - if (ar->cmd_seq < -1) - return 0; - - /* - * Initialize Counter - */ - if (ar->cmd_seq < 0) - ar->cmd_seq = seq; - - /* - * The sequence is strictly monotonic increasing and it never skips! - * - * Therefore we can safely assume that whenever we received an - * unexpected sequence we have lost some valuable data. - */ - if (seq != ar->cmd_seq) { - int count; - - count = (seq - ar->cmd_seq) % ar->fw.cmd_bufs; - - wiphy_err(ar->hw->wiphy, "lost %d command responses/traps! " - "w:%d g:%d\n", count, ar->cmd_seq, seq); - - carl9170_restart(ar, CARL9170_RR_LOST_RSP); - return -EIO; - } - - ar->cmd_seq = (ar->cmd_seq + 1) % ar->fw.cmd_bufs; - return 0; -} - -static void carl9170_cmd_callback(struct ar9170 *ar, u32 len, void *buffer) -{ - /* - * Some commands may have a variable response length - * and we cannot predict the correct length in advance. - * So we only check if we provided enough space for the data. - */ - if (unlikely(ar->readlen != (len - 4))) { - dev_warn(&ar->udev->dev, "received invalid command response:" - "got %d, instead of %d\n", len - 4, ar->readlen); - print_hex_dump_bytes("carl9170 cmd:", DUMP_PREFIX_OFFSET, - ar->cmd_buf, (ar->cmd.hdr.len + 4) & 0x3f); - print_hex_dump_bytes("carl9170 rsp:", DUMP_PREFIX_OFFSET, - buffer, len); - /* - * Do not complete. The command times out, - * and we get a stack trace from there. - */ - carl9170_restart(ar, CARL9170_RR_INVALID_RSP); - } - - spin_lock(&ar->cmd_lock); - if (ar->readbuf) { - if (len >= 4) - memcpy(ar->readbuf, buffer + 4, len - 4); - - ar->readbuf = NULL; - } - complete(&ar->cmd_wait); - spin_unlock(&ar->cmd_lock); -} - -void carl9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len) -{ - struct carl9170_rsp *cmd = (void *) buf; - struct ieee80211_vif *vif; - - if (carl9170_check_sequence(ar, cmd->hdr.seq)) - return; - - if ((cmd->hdr.cmd & CARL9170_RSP_FLAG) != CARL9170_RSP_FLAG) { - if (!(cmd->hdr.cmd & CARL9170_CMD_ASYNC_FLAG)) - carl9170_cmd_callback(ar, len, buf); - - return; - } - - if (unlikely(cmd->hdr.len != (len - 4))) { - if (net_ratelimit()) { - wiphy_err(ar->hw->wiphy, "FW: received over-/under" - "sized event %x (%d, but should be %d).\n", - cmd->hdr.cmd, cmd->hdr.len, len - 4); - - print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, - buf, len); - } - - return; - } - - /* hardware event handlers */ - switch (cmd->hdr.cmd) { - case CARL9170_RSP_PRETBTT: - /* pre-TBTT event */ - rcu_read_lock(); - vif = carl9170_get_main_vif(ar); - - if (!vif) { - rcu_read_unlock(); - break; - } - - switch (vif->type) { - case NL80211_IFTYPE_STATION: - carl9170_handle_ps(ar, cmd); - break; - - case NL80211_IFTYPE_AP: - case NL80211_IFTYPE_ADHOC: - carl9170_update_beacon(ar, true); - break; - - default: - break; - } - rcu_read_unlock(); - - break; - - - case CARL9170_RSP_TXCOMP: - /* TX status notification */ - carl9170_tx_process_status(ar, cmd); - break; - - case CARL9170_RSP_BEACON_CONFIG: - /* - * (IBSS) beacon send notification - * bytes: 04 c2 XX YY B4 B3 B2 B1 - * - * XX always 80 - * YY always 00 - * B1-B4 "should" be the number of send out beacons. - */ - break; - - case CARL9170_RSP_ATIM: - /* End of Atim Window */ - break; - - case CARL9170_RSP_WATCHDOG: - /* Watchdog Interrupt */ - carl9170_restart(ar, CARL9170_RR_WATCHDOG); - break; - - case CARL9170_RSP_TEXT: - /* firmware debug */ - carl9170_dbg_message(ar, (char *)buf + 4, len - 4); - break; - - case CARL9170_RSP_HEXDUMP: - wiphy_dbg(ar->hw->wiphy, "FW: HD %d\n", len - 4); - print_hex_dump_bytes("FW:", DUMP_PREFIX_NONE, - (char *)buf + 4, len - 4); - break; - - case CARL9170_RSP_RADAR: - if (!net_ratelimit()) - break; - - wiphy_info(ar->hw->wiphy, "FW: RADAR! Please report this " - "incident to linux-wireless@vger.kernel.org !\n"); - break; - - case CARL9170_RSP_GPIO: -#ifdef CONFIG_CARL9170_WPC - if (ar->wps.pbc) { - bool state = !!(cmd->gpio.gpio & cpu_to_le32( - AR9170_GPIO_PORT_WPS_BUTTON_PRESSED)); - - if (state != ar->wps.pbc_state) { - ar->wps.pbc_state = state; - input_report_key(ar->wps.pbc, KEY_WPS_BUTTON, - state); - input_sync(ar->wps.pbc); - } - } -#endif /* CONFIG_CARL9170_WPC */ - break; - - case CARL9170_RSP_BOOT: - complete(&ar->fw_boot_wait); - break; - - default: - wiphy_err(ar->hw->wiphy, "FW: received unhandled event %x\n", - cmd->hdr.cmd); - print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, buf, len); - break; - } -} - -static int carl9170_rx_mac_status(struct ar9170 *ar, - struct ar9170_rx_head *head, struct ar9170_rx_macstatus *mac, - struct ieee80211_rx_status *status) -{ - struct ieee80211_channel *chan; - u8 error, decrypt; - - BUILD_BUG_ON(sizeof(struct ar9170_rx_head) != 12); - BUILD_BUG_ON(sizeof(struct ar9170_rx_macstatus) != 4); - - error = mac->error; - - if (error & AR9170_RX_ERROR_WRONG_RA) { - if (!ar->sniffer_enabled) - return -EINVAL; - } - - if (error & AR9170_RX_ERROR_PLCP) { - if (!(ar->filter_state & FIF_PLCPFAIL)) - return -EINVAL; - - status->flag |= RX_FLAG_FAILED_PLCP_CRC; - } - - if (error & AR9170_RX_ERROR_FCS) { - ar->tx_fcs_errors++; - - if (!(ar->filter_state & FIF_FCSFAIL)) - return -EINVAL; - - status->flag |= RX_FLAG_FAILED_FCS_CRC; - } - - decrypt = ar9170_get_decrypt_type(mac); - if (!(decrypt & AR9170_RX_ENC_SOFTWARE) && - decrypt != AR9170_ENC_ALG_NONE) { - if ((decrypt == AR9170_ENC_ALG_TKIP) && - (error & AR9170_RX_ERROR_MMIC)) - status->flag |= RX_FLAG_MMIC_ERROR; - - status->flag |= RX_FLAG_DECRYPTED; - } - - if (error & AR9170_RX_ERROR_DECRYPT && !ar->sniffer_enabled) - return -ENODATA; - - error &= ~(AR9170_RX_ERROR_MMIC | - AR9170_RX_ERROR_FCS | - AR9170_RX_ERROR_WRONG_RA | - AR9170_RX_ERROR_DECRYPT | - AR9170_RX_ERROR_PLCP); - - /* drop any other error frames */ - if (unlikely(error)) { - /* TODO: update netdevice's RX dropped/errors statistics */ - - if (net_ratelimit()) - wiphy_dbg(ar->hw->wiphy, "received frame with " - "suspicious error code (%#x).\n", error); - - return -EINVAL; - } - - chan = ar->channel; - if (chan) { - status->band = chan->band; - status->freq = chan->center_freq; - } - - switch (mac->status & AR9170_RX_STATUS_MODULATION) { - case AR9170_RX_STATUS_MODULATION_CCK: - if (mac->status & AR9170_RX_STATUS_SHORT_PREAMBLE) - status->flag |= RX_FLAG_SHORTPRE; - switch (head->plcp[0]) { - case AR9170_RX_PHY_RATE_CCK_1M: - status->rate_idx = 0; - break; - case AR9170_RX_PHY_RATE_CCK_2M: - status->rate_idx = 1; - break; - case AR9170_RX_PHY_RATE_CCK_5M: - status->rate_idx = 2; - break; - case AR9170_RX_PHY_RATE_CCK_11M: - status->rate_idx = 3; - break; - default: - if (net_ratelimit()) { - wiphy_err(ar->hw->wiphy, "invalid plcp cck " - "rate (%x).\n", head->plcp[0]); - } - - return -EINVAL; - } - break; - - case AR9170_RX_STATUS_MODULATION_DUPOFDM: - case AR9170_RX_STATUS_MODULATION_OFDM: - switch (head->plcp[0] & 0xf) { - case AR9170_TXRX_PHY_RATE_OFDM_6M: - status->rate_idx = 0; - break; - case AR9170_TXRX_PHY_RATE_OFDM_9M: - status->rate_idx = 1; - break; - case AR9170_TXRX_PHY_RATE_OFDM_12M: - status->rate_idx = 2; - break; - case AR9170_TXRX_PHY_RATE_OFDM_18M: - status->rate_idx = 3; - break; - case AR9170_TXRX_PHY_RATE_OFDM_24M: - status->rate_idx = 4; - break; - case AR9170_TXRX_PHY_RATE_OFDM_36M: - status->rate_idx = 5; - break; - case AR9170_TXRX_PHY_RATE_OFDM_48M: - status->rate_idx = 6; - break; - case AR9170_TXRX_PHY_RATE_OFDM_54M: - status->rate_idx = 7; - break; - default: - if (net_ratelimit()) { - wiphy_err(ar->hw->wiphy, "invalid plcp ofdm " - "rate (%x).\n", head->plcp[0]); - } - - return -EINVAL; - } - if (status->band == IEEE80211_BAND_2GHZ) - status->rate_idx += 4; - break; - - case AR9170_RX_STATUS_MODULATION_HT: - if (head->plcp[3] & 0x80) - status->flag |= RX_FLAG_40MHZ; - if (head->plcp[6] & 0x80) - status->flag |= RX_FLAG_SHORT_GI; - - status->rate_idx = clamp(0, 75, head->plcp[3] & 0x7f); - status->flag |= RX_FLAG_HT; - break; - - default: - BUG(); - return -ENOSYS; - } - - return 0; -} - -static void carl9170_rx_phy_status(struct ar9170 *ar, - struct ar9170_rx_phystatus *phy, struct ieee80211_rx_status *status) -{ - int i; - - BUILD_BUG_ON(sizeof(struct ar9170_rx_phystatus) != 20); - - for (i = 0; i < 3; i++) - if (phy->rssi[i] != 0x80) - status->antenna |= BIT(i); - - /* post-process RSSI */ - for (i = 0; i < 7; i++) - if (phy->rssi[i] & 0x80) - phy->rssi[i] = ((phy->rssi[i] & 0x7f) + 1) & 0x7f; - - /* TODO: we could do something with phy_errors */ - status->signal = ar->noise[0] + phy->rssi_combined; -} - -static struct sk_buff *carl9170_rx_copy_data(u8 *buf, int len) -{ - struct sk_buff *skb; - int reserved = 0; - struct ieee80211_hdr *hdr = (void *) buf; - - if (ieee80211_is_data_qos(hdr->frame_control)) { - u8 *qc = ieee80211_get_qos_ctl(hdr); - reserved += NET_IP_ALIGN; - - if (*qc & IEEE80211_QOS_CTL_A_MSDU_PRESENT) - reserved += NET_IP_ALIGN; - } - - if (ieee80211_has_a4(hdr->frame_control)) - reserved += NET_IP_ALIGN; - - reserved = 32 + (reserved & NET_IP_ALIGN); - - skb = dev_alloc_skb(len + reserved); - if (likely(skb)) { - skb_reserve(skb, reserved); - memcpy(skb_put(skb, len), buf, len); - } - - return skb; -} - -static u8 *carl9170_find_ie(u8 *data, unsigned int len, u8 ie) -{ - struct ieee80211_mgmt *mgmt = (void *)data; - u8 *pos, *end; - - pos = (u8 *)mgmt->u.beacon.variable; - end = data + len; - while (pos < end) { - if (pos + 2 + pos[1] > end) - return NULL; - - if (pos[0] == ie) - return pos; - - pos += 2 + pos[1]; - } - return NULL; -} - -/* - * NOTE: - * - * The firmware is in charge of waking up the device just before - * the AP is expected to transmit the next beacon. - * - * This leaves the driver with the important task of deciding when - * to set the PHY back to bed again. - */ -static void carl9170_ps_beacon(struct ar9170 *ar, void *data, unsigned int len) -{ - struct ieee80211_hdr *hdr = (void *) data; - struct ieee80211_tim_ie *tim_ie; - u8 *tim; - u8 tim_len; - bool cam; - - if (likely(!(ar->hw->conf.flags & IEEE80211_CONF_PS))) - return; - - /* check if this really is a beacon */ - if (!ieee80211_is_beacon(hdr->frame_control)) - return; - - /* min. beacon length + FCS_LEN */ - if (len <= 40 + FCS_LEN) - return; - - /* and only beacons from the associated BSSID, please */ - if (compare_ether_addr(hdr->addr3, ar->common.curbssid) || - !ar->common.curaid) - return; - - ar->ps.last_beacon = jiffies; - - tim = carl9170_find_ie(data, len - FCS_LEN, WLAN_EID_TIM); - if (!tim) - return; - - if (tim[1] < sizeof(*tim_ie)) - return; - - tim_len = tim[1]; - tim_ie = (struct ieee80211_tim_ie *) &tim[2]; - - if (!WARN_ON_ONCE(!ar->hw->conf.ps_dtim_period)) - ar->ps.dtim_counter = (tim_ie->dtim_count - 1) % - ar->hw->conf.ps_dtim_period; - - /* Check whenever the PHY can be turned off again. */ - - /* 1. What about buffered unicast traffic for our AID? */ - cam = ieee80211_check_tim(tim_ie, tim_len, ar->common.curaid); - - /* 2. Maybe the AP wants to send multicast/broadcast data? */ - cam |= !!(tim_ie->bitmap_ctrl & 0x01); - - if (!cam) { - /* back to low-power land. */ - ar->ps.off_override &= ~PS_OFF_BCN; - carl9170_ps_check(ar); - } else { - /* force CAM */ - ar->ps.off_override |= PS_OFF_BCN; - } -} - -static bool carl9170_ampdu_check(struct ar9170 *ar, u8 *buf, u8 ms) -{ - __le16 fc; - - if ((ms & AR9170_RX_STATUS_MPDU) == AR9170_RX_STATUS_MPDU_SINGLE) { - /* - * This frame is not part of an aMPDU. - * Therefore it is not subjected to any - * of the following content restrictions. - */ - return true; - } - - /* - * "802.11n - 7.4a.3 A-MPDU contents" describes in which contexts - * certain frame types can be part of an aMPDU. - * - * In order to keep the processing cost down, I opted for a - * stateless filter solely based on the frame control field. - */ - - fc = ((struct ieee80211_hdr *)buf)->frame_control; - if (ieee80211_is_data_qos(fc) && ieee80211_is_data_present(fc)) - return true; - - if (ieee80211_is_ack(fc) || ieee80211_is_back(fc) || - ieee80211_is_back_req(fc)) - return true; - - if (ieee80211_is_action(fc)) - return true; - - return false; -} - -/* - * If the frame alignment is right (or the kernel has - * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS), and there - * is only a single MPDU in the USB frame, then we could - * submit to mac80211 the SKB directly. However, since - * there may be multiple packets in one SKB in stream - * mode, and we need to observe the proper ordering, - * this is non-trivial. - */ - -static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len) -{ - struct ar9170_rx_head *head; - struct ar9170_rx_macstatus *mac; - struct ar9170_rx_phystatus *phy = NULL; - struct ieee80211_rx_status status; - struct sk_buff *skb; - int mpdu_len; - u8 mac_status; - - if (!IS_STARTED(ar)) - return; - - if (unlikely(len < sizeof(*mac))) - goto drop; - - mpdu_len = len - sizeof(*mac); - - mac = (void *)(buf + mpdu_len); - mac_status = mac->status; - switch (mac_status & AR9170_RX_STATUS_MPDU) { - case AR9170_RX_STATUS_MPDU_FIRST: - /* Aggregated MPDUs start with an PLCP header */ - if (likely(mpdu_len >= sizeof(struct ar9170_rx_head))) { - head = (void *) buf; - - /* - * The PLCP header needs to be cached for the - * following MIDDLE + LAST A-MPDU packets. - * - * So, if you are wondering why all frames seem - * to share a common RX status information, - * then you have the answer right here... - */ - memcpy(&ar->rx_plcp, (void *) buf, - sizeof(struct ar9170_rx_head)); - - mpdu_len -= sizeof(struct ar9170_rx_head); - buf += sizeof(struct ar9170_rx_head); - - ar->rx_has_plcp = true; - } else { - if (net_ratelimit()) { - wiphy_err(ar->hw->wiphy, "plcp info " - "is clipped.\n"); - } - - goto drop; - } - break; - - case AR9170_RX_STATUS_MPDU_LAST: - /* - * The last frame of an A-MPDU has an extra tail - * which does contain the phy status of the whole - * aggregate. - */ - - if (likely(mpdu_len >= sizeof(struct ar9170_rx_phystatus))) { - mpdu_len -= sizeof(struct ar9170_rx_phystatus); - phy = (void *)(buf + mpdu_len); - } else { - if (net_ratelimit()) { - wiphy_err(ar->hw->wiphy, "frame tail " - "is clipped.\n"); - } - - goto drop; - } - - case AR9170_RX_STATUS_MPDU_MIDDLE: - /* These are just data + mac status */ - if (unlikely(!ar->rx_has_plcp)) { - if (!net_ratelimit()) - return; - - wiphy_err(ar->hw->wiphy, "rx stream does not start " - "with a first_mpdu frame tag.\n"); - - goto drop; - } - - head = &ar->rx_plcp; - break; - - case AR9170_RX_STATUS_MPDU_SINGLE: - /* single mpdu has both: plcp (head) and phy status (tail) */ - head = (void *) buf; - - mpdu_len -= sizeof(struct ar9170_rx_head); - mpdu_len -= sizeof(struct ar9170_rx_phystatus); - - buf += sizeof(struct ar9170_rx_head); - phy = (void *)(buf + mpdu_len); - break; - - default: - BUG_ON(1); - break; - } - - /* FC + DU + RA + FCS */ - if (unlikely(mpdu_len < (2 + 2 + ETH_ALEN + FCS_LEN))) - goto drop; - - memset(&status, 0, sizeof(status)); - if (unlikely(carl9170_rx_mac_status(ar, head, mac, &status))) - goto drop; - - if (!carl9170_ampdu_check(ar, buf, mac_status)) - goto drop; - - if (phy) - carl9170_rx_phy_status(ar, phy, &status); - - carl9170_ps_beacon(ar, buf, mpdu_len); - - skb = carl9170_rx_copy_data(buf, mpdu_len); - if (!skb) - goto drop; - - memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status)); - ieee80211_rx(ar->hw, skb); - return; - -drop: - ar->rx_dropped++; -} - -static void carl9170_rx_untie_cmds(struct ar9170 *ar, const u8 *respbuf, - const unsigned int resplen) -{ - struct carl9170_rsp *cmd; - int i = 0; - - while (i < resplen) { - cmd = (void *) &respbuf[i]; - - i += cmd->hdr.len + 4; - if (unlikely(i > resplen)) - break; - - carl9170_handle_command_response(ar, cmd, cmd->hdr.len + 4); - } - - if (unlikely(i != resplen)) { - if (!net_ratelimit()) - return; - - wiphy_err(ar->hw->wiphy, "malformed firmware trap:\n"); - print_hex_dump_bytes("rxcmd:", DUMP_PREFIX_OFFSET, - respbuf, resplen); - } -} - -static void __carl9170_rx(struct ar9170 *ar, u8 *buf, unsigned int len) -{ - unsigned int i = 0; - - /* weird thing, but this is the same in the original driver */ - while (len > 2 && i < 12 && buf[0] == 0xff && buf[1] == 0xff) { - i += 2; - len -= 2; - buf += 2; - } - - if (unlikely(len < 4)) - return; - - /* found the 6 * 0xffff marker? */ - if (i == 12) - carl9170_rx_untie_cmds(ar, buf, len); - else - carl9170_handle_mpdu(ar, buf, len); -} - -static void carl9170_rx_stream(struct ar9170 *ar, void *buf, unsigned int len) -{ - unsigned int tlen, wlen = 0, clen = 0; - struct ar9170_stream *rx_stream; - u8 *tbuf; - - tbuf = buf; - tlen = len; - - while (tlen >= 4) { - rx_stream = (void *) tbuf; - clen = le16_to_cpu(rx_stream->length); - wlen = ALIGN(clen, 4); - - /* check if this is stream has a valid tag.*/ - if (rx_stream->tag != cpu_to_le16(AR9170_RX_STREAM_TAG)) { - /* - * TODO: handle the highly unlikely event that the - * corrupted stream has the TAG at the right position. - */ - - /* check if the frame can be repaired. */ - if (!ar->rx_failover_missing) { - - /* this is not "short read". */ - if (net_ratelimit()) { - wiphy_err(ar->hw->wiphy, - "missing tag!\n"); - } - - __carl9170_rx(ar, tbuf, tlen); - return; - } - - if (ar->rx_failover_missing > tlen) { - if (net_ratelimit()) { - wiphy_err(ar->hw->wiphy, - "possible multi " - "stream corruption!\n"); - goto err_telluser; - } else { - goto err_silent; - } - } - - memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen); - ar->rx_failover_missing -= tlen; - - if (ar->rx_failover_missing <= 0) { - /* - * nested carl9170_rx_stream call! - * - * termination is guaranteed, even when the - * combined frame also have an element with - * a bad tag. - */ - - ar->rx_failover_missing = 0; - carl9170_rx_stream(ar, ar->rx_failover->data, - ar->rx_failover->len); - - skb_reset_tail_pointer(ar->rx_failover); - skb_trim(ar->rx_failover, 0); - } - - return; - } - - /* check if stream is clipped */ - if (wlen > tlen - 4) { - if (ar->rx_failover_missing) { - /* TODO: handle double stream corruption. */ - if (net_ratelimit()) { - wiphy_err(ar->hw->wiphy, "double rx " - "stream corruption!\n"); - goto err_telluser; - } else { - goto err_silent; - } - } - - /* - * save incomplete data set. - * the firmware will resend the missing bits when - * the rx - descriptor comes round again. - */ - - memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen); - ar->rx_failover_missing = clen - tlen; - return; - } - __carl9170_rx(ar, rx_stream->payload, clen); - - tbuf += wlen + 4; - tlen -= wlen + 4; - } - - if (tlen) { - if (net_ratelimit()) { - wiphy_err(ar->hw->wiphy, "%d bytes of unprocessed " - "data left in rx stream!\n", tlen); - } - - goto err_telluser; - } - - return; - -err_telluser: - wiphy_err(ar->hw->wiphy, "damaged RX stream data [want:%d, " - "data:%d, rx:%d, pending:%d ]\n", clen, wlen, tlen, - ar->rx_failover_missing); - - if (ar->rx_failover_missing) - print_hex_dump_bytes("rxbuf:", DUMP_PREFIX_OFFSET, - ar->rx_failover->data, - ar->rx_failover->len); - - print_hex_dump_bytes("stream:", DUMP_PREFIX_OFFSET, - buf, len); - - wiphy_err(ar->hw->wiphy, "please check your hardware and cables, if " - "you see this message frequently.\n"); - -err_silent: - if (ar->rx_failover_missing) { - skb_reset_tail_pointer(ar->rx_failover); - skb_trim(ar->rx_failover, 0); - ar->rx_failover_missing = 0; - } -} - -void carl9170_rx(struct ar9170 *ar, void *buf, unsigned int len) -{ - if (ar->fw.rx_stream) - carl9170_rx_stream(ar, buf, len); - else - __carl9170_rx(ar, buf, len); -} diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/tx.c b/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/tx.c deleted file mode 100644 index aed30517..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/tx.c +++ /dev/null @@ -1,1602 +0,0 @@ -/* - * Atheros CARL9170 driver - * - * 802.11 xmit & status routines - * - * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> - * Copyright 2009, 2010, Christian Lamparter <chunkeey@googlemail.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, see - * http://www.gnu.org/licenses/. - * - * This file incorporates work covered by the following copyright and - * permission notice: - * Copyright (c) 2007-2008 Atheros Communications, Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/etherdevice.h> -#include <net/mac80211.h> -#include "carl9170.h" -#include "hw.h" -#include "cmd.h" - -static inline unsigned int __carl9170_get_queue(struct ar9170 *ar, - unsigned int queue) -{ - if (unlikely(modparam_noht)) { - return queue; - } else { - /* - * This is just another workaround, until - * someone figures out how to get QoS and - * AMPDU to play nicely together. - */ - - return 2; /* AC_BE */ - } -} - -static inline unsigned int carl9170_get_queue(struct ar9170 *ar, - struct sk_buff *skb) -{ - return __carl9170_get_queue(ar, skb_get_queue_mapping(skb)); -} - -static bool is_mem_full(struct ar9170 *ar) -{ - return (DIV_ROUND_UP(IEEE80211_MAX_FRAME_LEN, ar->fw.mem_block_size) > - atomic_read(&ar->mem_free_blocks)); -} - -static void carl9170_tx_accounting(struct ar9170 *ar, struct sk_buff *skb) -{ - int queue, i; - bool mem_full; - - atomic_inc(&ar->tx_total_queued); - - queue = skb_get_queue_mapping(skb); - spin_lock_bh(&ar->tx_stats_lock); - - /* - * The driver has to accept the frame, regardless if the queue is - * full to the brim, or not. We have to do the queuing internally, - * since mac80211 assumes that a driver which can operate with - * aggregated frames does not reject frames for this reason. - */ - ar->tx_stats[queue].len++; - ar->tx_stats[queue].count++; - - mem_full = is_mem_full(ar); - for (i = 0; i < ar->hw->queues; i++) { - if (mem_full || ar->tx_stats[i].len >= ar->tx_stats[i].limit) { - ieee80211_stop_queue(ar->hw, i); - ar->queue_stop_timeout[i] = jiffies; - } - } - - spin_unlock_bh(&ar->tx_stats_lock); -} - -/* needs rcu_read_lock */ -static struct ieee80211_sta *__carl9170_get_tx_sta(struct ar9170 *ar, - struct sk_buff *skb) -{ - struct _carl9170_tx_superframe *super = (void *) skb->data; - struct ieee80211_hdr *hdr = (void *) super->frame_data; - struct ieee80211_vif *vif; - unsigned int vif_id; - - vif_id = (super->s.misc & CARL9170_TX_SUPER_MISC_VIF_ID) >> - CARL9170_TX_SUPER_MISC_VIF_ID_S; - - if (WARN_ON_ONCE(vif_id >= AR9170_MAX_VIRTUAL_MAC)) - return NULL; - - vif = rcu_dereference(ar->vif_priv[vif_id].vif); - if (unlikely(!vif)) - return NULL; - - /* - * Normally we should use wrappers like ieee80211_get_DA to get - * the correct peer ieee80211_sta. - * - * But there is a problem with indirect traffic (broadcasts, or - * data which is designated for other stations) in station mode. - * The frame will be directed to the AP for distribution and not - * to the actual destination. - */ - - return ieee80211_find_sta(vif, hdr->addr1); -} - -static void carl9170_tx_ps_unblock(struct ar9170 *ar, struct sk_buff *skb) -{ - struct ieee80211_sta *sta; - struct carl9170_sta_info *sta_info; - - rcu_read_lock(); - sta = __carl9170_get_tx_sta(ar, skb); - if (unlikely(!sta)) - goto out_rcu; - - sta_info = (struct carl9170_sta_info *) sta->drv_priv; - if (atomic_dec_return(&sta_info->pending_frames) == 0) - ieee80211_sta_block_awake(ar->hw, sta, false); - -out_rcu: - rcu_read_unlock(); -} - -static void carl9170_tx_accounting_free(struct ar9170 *ar, struct sk_buff *skb) -{ - int queue; - - queue = skb_get_queue_mapping(skb); - - spin_lock_bh(&ar->tx_stats_lock); - - ar->tx_stats[queue].len--; - - if (!is_mem_full(ar)) { - unsigned int i; - for (i = 0; i < ar->hw->queues; i++) { - if (ar->tx_stats[i].len >= CARL9170_NUM_TX_LIMIT_SOFT) - continue; - - if (ieee80211_queue_stopped(ar->hw, i)) { - unsigned long tmp; - - tmp = jiffies - ar->queue_stop_timeout[i]; - if (tmp > ar->max_queue_stop_timeout[i]) - ar->max_queue_stop_timeout[i] = tmp; - } - - ieee80211_wake_queue(ar->hw, i); - } - } - - spin_unlock_bh(&ar->tx_stats_lock); - - if (atomic_dec_and_test(&ar->tx_total_queued)) - complete(&ar->tx_flush); -} - -static int carl9170_alloc_dev_space(struct ar9170 *ar, struct sk_buff *skb) -{ - struct _carl9170_tx_superframe *super = (void *) skb->data; - unsigned int chunks; - int cookie = -1; - - atomic_inc(&ar->mem_allocs); - - chunks = DIV_ROUND_UP(skb->len, ar->fw.mem_block_size); - if (unlikely(atomic_sub_return(chunks, &ar->mem_free_blocks) < 0)) { - atomic_add(chunks, &ar->mem_free_blocks); - return -ENOSPC; - } - - spin_lock_bh(&ar->mem_lock); - cookie = bitmap_find_free_region(ar->mem_bitmap, ar->fw.mem_blocks, 0); - spin_unlock_bh(&ar->mem_lock); - - if (unlikely(cookie < 0)) { - atomic_add(chunks, &ar->mem_free_blocks); - return -ENOSPC; - } - - super = (void *) skb->data; - - /* - * Cookie #0 serves two special purposes: - * 1. The firmware might use it generate BlockACK frames - * in responds of an incoming BlockAckReqs. - * - * 2. Prevent double-free bugs. - */ - super->s.cookie = (u8) cookie + 1; - return 0; -} - -static void carl9170_release_dev_space(struct ar9170 *ar, struct sk_buff *skb) -{ - struct _carl9170_tx_superframe *super = (void *) skb->data; - int cookie; - - /* make a local copy of the cookie */ - cookie = super->s.cookie; - /* invalidate cookie */ - super->s.cookie = 0; - - /* - * Do a out-of-bounds check on the cookie: - * - * * cookie "0" is reserved and won't be assigned to any - * out-going frame. Internally however, it is used to - * mark no longer/un-accounted frames and serves as a - * cheap way of preventing frames from being freed - * twice by _accident_. NB: There is a tiny race... - * - * * obviously, cookie number is limited by the amount - * of available memory blocks, so the number can - * never execeed the mem_blocks count. - */ - if (unlikely(WARN_ON_ONCE(cookie == 0) || - WARN_ON_ONCE(cookie > ar->fw.mem_blocks))) - return; - - atomic_add(DIV_ROUND_UP(skb->len, ar->fw.mem_block_size), - &ar->mem_free_blocks); - - spin_lock_bh(&ar->mem_lock); - bitmap_release_region(ar->mem_bitmap, cookie - 1, 0); - spin_unlock_bh(&ar->mem_lock); -} - -/* Called from any context */ -static void carl9170_tx_release(struct kref *ref) -{ - struct ar9170 *ar; - struct carl9170_tx_info *arinfo; - struct ieee80211_tx_info *txinfo; - struct sk_buff *skb; - - arinfo = container_of(ref, struct carl9170_tx_info, ref); - txinfo = container_of((void *) arinfo, struct ieee80211_tx_info, - rate_driver_data); - skb = container_of((void *) txinfo, struct sk_buff, cb); - - ar = arinfo->ar; - if (WARN_ON_ONCE(!ar)) - return; - - BUILD_BUG_ON( - offsetof(struct ieee80211_tx_info, status.ampdu_ack_len) != 23); - - memset(&txinfo->status.ampdu_ack_len, 0, - sizeof(struct ieee80211_tx_info) - - offsetof(struct ieee80211_tx_info, status.ampdu_ack_len)); - - if (atomic_read(&ar->tx_total_queued)) - ar->tx_schedule = true; - - if (txinfo->flags & IEEE80211_TX_CTL_AMPDU) { - if (!atomic_read(&ar->tx_ampdu_upload)) - ar->tx_ampdu_schedule = true; - - if (txinfo->flags & IEEE80211_TX_STAT_AMPDU) { - struct _carl9170_tx_superframe *super; - - super = (void *)skb->data; - txinfo->status.ampdu_len = super->s.rix; - txinfo->status.ampdu_ack_len = super->s.cnt; - } else if ((txinfo->flags & IEEE80211_TX_STAT_ACK) && - !(txinfo->flags & IEEE80211_TX_CTL_REQ_TX_STATUS)) { - /* - * drop redundant tx_status reports: - * - * 1. ampdu_ack_len of the final tx_status does - * include the feedback of this particular frame. - * - * 2. tx_status_irqsafe only queues up to 128 - * tx feedback reports and discards the rest. - * - * 3. minstrel_ht is picky, it only accepts - * reports of frames with the TX_STATUS_AMPDU flag. - * - * 4. mac80211 is not particularly interested in - * feedback either [CTL_REQ_TX_STATUS not set] - */ - - ieee80211_free_txskb(ar->hw, skb); - return; - } else { - /* - * Either the frame transmission has failed or - * mac80211 requested tx status. - */ - } - } - - skb_pull(skb, sizeof(struct _carl9170_tx_superframe)); - ieee80211_tx_status_irqsafe(ar->hw, skb); -} - -void carl9170_tx_get_skb(struct sk_buff *skb) -{ - struct carl9170_tx_info *arinfo = (void *) - (IEEE80211_SKB_CB(skb))->rate_driver_data; - kref_get(&arinfo->ref); -} - -int carl9170_tx_put_skb(struct sk_buff *skb) -{ - struct carl9170_tx_info *arinfo = (void *) - (IEEE80211_SKB_CB(skb))->rate_driver_data; - - return kref_put(&arinfo->ref, carl9170_tx_release); -} - -/* Caller must hold the tid_info->lock & rcu_read_lock */ -static void carl9170_tx_shift_bm(struct ar9170 *ar, - struct carl9170_sta_tid *tid_info, u16 seq) -{ - u16 off; - - off = SEQ_DIFF(seq, tid_info->bsn); - - if (WARN_ON_ONCE(off >= CARL9170_BAW_BITS)) - return; - - /* - * Sanity check. For each MPDU we set the bit in bitmap and - * clear it once we received the tx_status. - * But if the bit is already cleared then we've been bitten - * by a bug. - */ - WARN_ON_ONCE(!test_and_clear_bit(off, tid_info->bitmap)); - - off = SEQ_DIFF(tid_info->snx, tid_info->bsn); - if (WARN_ON_ONCE(off >= CARL9170_BAW_BITS)) - return; - - if (!bitmap_empty(tid_info->bitmap, off)) - off = find_first_bit(tid_info->bitmap, off); - - tid_info->bsn += off; - tid_info->bsn &= 0x0fff; - - bitmap_shift_right(tid_info->bitmap, tid_info->bitmap, - off, CARL9170_BAW_BITS); -} - -static void carl9170_tx_status_process_ampdu(struct ar9170 *ar, - struct sk_buff *skb, struct ieee80211_tx_info *txinfo) -{ - struct _carl9170_tx_superframe *super = (void *) skb->data; - struct ieee80211_hdr *hdr = (void *) super->frame_data; - struct ieee80211_sta *sta; - struct carl9170_sta_info *sta_info; - struct carl9170_sta_tid *tid_info; - u8 tid; - - if (!(txinfo->flags & IEEE80211_TX_CTL_AMPDU) || - txinfo->flags & IEEE80211_TX_CTL_INJECTED || - (!(super->f.mac_control & cpu_to_le16(AR9170_TX_MAC_AGGR)))) - return; - - rcu_read_lock(); - sta = __carl9170_get_tx_sta(ar, skb); - if (unlikely(!sta)) - goto out_rcu; - - tid = get_tid_h(hdr); - - sta_info = (void *) sta->drv_priv; - tid_info = rcu_dereference(sta_info->agg[tid]); - if (!tid_info) - goto out_rcu; - - spin_lock_bh(&tid_info->lock); - if (likely(tid_info->state >= CARL9170_TID_STATE_IDLE)) - carl9170_tx_shift_bm(ar, tid_info, get_seq_h(hdr)); - - if (sta_info->stats[tid].clear) { - sta_info->stats[tid].clear = false; - sta_info->stats[tid].req = false; - sta_info->stats[tid].ampdu_len = 0; - sta_info->stats[tid].ampdu_ack_len = 0; - } - - sta_info->stats[tid].ampdu_len++; - if (txinfo->status.rates[0].count == 1) - sta_info->stats[tid].ampdu_ack_len++; - - if (!(txinfo->flags & IEEE80211_TX_STAT_ACK)) - sta_info->stats[tid].req = true; - - if (super->f.mac_control & cpu_to_le16(AR9170_TX_MAC_IMM_BA)) { - super->s.rix = sta_info->stats[tid].ampdu_len; - super->s.cnt = sta_info->stats[tid].ampdu_ack_len; - txinfo->flags |= IEEE80211_TX_STAT_AMPDU; - if (sta_info->stats[tid].req) - txinfo->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; - - sta_info->stats[tid].clear = true; - } - spin_unlock_bh(&tid_info->lock); - -out_rcu: - rcu_read_unlock(); -} - -void carl9170_tx_status(struct ar9170 *ar, struct sk_buff *skb, - const bool success) -{ - struct ieee80211_tx_info *txinfo; - - carl9170_tx_accounting_free(ar, skb); - - txinfo = IEEE80211_SKB_CB(skb); - - if (success) - txinfo->flags |= IEEE80211_TX_STAT_ACK; - else - ar->tx_ack_failures++; - - if (txinfo->flags & IEEE80211_TX_CTL_AMPDU) - carl9170_tx_status_process_ampdu(ar, skb, txinfo); - - carl9170_tx_ps_unblock(ar, skb); - carl9170_tx_put_skb(skb); -} - -/* This function may be called form any context */ -void carl9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb) -{ - struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb); - - atomic_dec(&ar->tx_total_pending); - - if (txinfo->flags & IEEE80211_TX_CTL_AMPDU) - atomic_dec(&ar->tx_ampdu_upload); - - if (carl9170_tx_put_skb(skb)) - tasklet_hi_schedule(&ar->usb_tasklet); -} - -static struct sk_buff *carl9170_get_queued_skb(struct ar9170 *ar, u8 cookie, - struct sk_buff_head *queue) -{ - struct sk_buff *skb; - - spin_lock_bh(&queue->lock); - skb_queue_walk(queue, skb) { - struct _carl9170_tx_superframe *txc = (void *) skb->data; - - if (txc->s.cookie != cookie) - continue; - - __skb_unlink(skb, queue); - spin_unlock_bh(&queue->lock); - - carl9170_release_dev_space(ar, skb); - return skb; - } - spin_unlock_bh(&queue->lock); - - return NULL; -} - -static void carl9170_tx_fill_rateinfo(struct ar9170 *ar, unsigned int rix, - unsigned int tries, struct ieee80211_tx_info *txinfo) -{ - unsigned int i; - - for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { - if (txinfo->status.rates[i].idx < 0) - break; - - if (i == rix) { - txinfo->status.rates[i].count = tries; - i++; - break; - } - } - - for (; i < IEEE80211_TX_MAX_RATES; i++) { - txinfo->status.rates[i].idx = -1; - txinfo->status.rates[i].count = 0; - } -} - -static void carl9170_check_queue_stop_timeout(struct ar9170 *ar) -{ - int i; - struct sk_buff *skb; - struct ieee80211_tx_info *txinfo; - struct carl9170_tx_info *arinfo; - bool restart = false; - - for (i = 0; i < ar->hw->queues; i++) { - spin_lock_bh(&ar->tx_status[i].lock); - - skb = skb_peek(&ar->tx_status[i]); - - if (!skb) - goto next; - - txinfo = IEEE80211_SKB_CB(skb); - arinfo = (void *) txinfo->rate_driver_data; - - if (time_is_before_jiffies(arinfo->timeout + - msecs_to_jiffies(CARL9170_QUEUE_STUCK_TIMEOUT)) == true) - restart = true; - -next: - spin_unlock_bh(&ar->tx_status[i].lock); - } - - if (restart) { - /* - * At least one queue has been stuck for long enough. - * Give the device a kick and hope it gets back to - * work. - * - * possible reasons may include: - * - frames got lost/corrupted (bad connection to the device) - * - stalled rx processing/usb controller hiccups - * - firmware errors/bugs - * - every bug you can think of. - * - all bugs you can't... - * - ... - */ - carl9170_restart(ar, CARL9170_RR_STUCK_TX); - } -} - -static void carl9170_tx_ampdu_timeout(struct ar9170 *ar) -{ - struct carl9170_sta_tid *iter; - struct sk_buff *skb; - struct ieee80211_tx_info *txinfo; - struct carl9170_tx_info *arinfo; - struct ieee80211_sta *sta; - - rcu_read_lock(); - list_for_each_entry_rcu(iter, &ar->tx_ampdu_list, list) { - if (iter->state < CARL9170_TID_STATE_IDLE) - continue; - - spin_lock_bh(&iter->lock); - skb = skb_peek(&iter->queue); - if (!skb) - goto unlock; - - txinfo = IEEE80211_SKB_CB(skb); - arinfo = (void *)txinfo->rate_driver_data; - if (time_is_after_jiffies(arinfo->timeout + - msecs_to_jiffies(CARL9170_QUEUE_TIMEOUT))) - goto unlock; - - sta = __carl9170_get_tx_sta(ar, skb); - if (WARN_ON(!sta)) - goto unlock; - - ieee80211_stop_tx_ba_session(sta, iter->tid); -unlock: - spin_unlock_bh(&iter->lock); - - } - rcu_read_unlock(); -} - -void carl9170_tx_janitor(struct work_struct *work) -{ - struct ar9170 *ar = container_of(work, struct ar9170, - tx_janitor.work); - if (!IS_STARTED(ar)) - return; - - ar->tx_janitor_last_run = jiffies; - - carl9170_check_queue_stop_timeout(ar); - carl9170_tx_ampdu_timeout(ar); - - if (!atomic_read(&ar->tx_total_queued)) - return; - - ieee80211_queue_delayed_work(ar->hw, &ar->tx_janitor, - msecs_to_jiffies(CARL9170_TX_TIMEOUT)); -} - -static void __carl9170_tx_process_status(struct ar9170 *ar, - const uint8_t cookie, const uint8_t info) -{ - struct sk_buff *skb; - struct ieee80211_tx_info *txinfo; - unsigned int r, t, q; - bool success = true; - - q = ar9170_qmap[info & CARL9170_TX_STATUS_QUEUE]; - - skb = carl9170_get_queued_skb(ar, cookie, &ar->tx_status[q]); - if (!skb) { - /* - * We have lost the race to another thread. - */ - - return ; - } - - txinfo = IEEE80211_SKB_CB(skb); - - if (!(info & CARL9170_TX_STATUS_SUCCESS)) - success = false; - - r = (info & CARL9170_TX_STATUS_RIX) >> CARL9170_TX_STATUS_RIX_S; - t = (info & CARL9170_TX_STATUS_TRIES) >> CARL9170_TX_STATUS_TRIES_S; - - carl9170_tx_fill_rateinfo(ar, r, t, txinfo); - carl9170_tx_status(ar, skb, success); -} - -void carl9170_tx_process_status(struct ar9170 *ar, - const struct carl9170_rsp *cmd) -{ - unsigned int i; - - for (i = 0; i < cmd->hdr.ext; i++) { - if (WARN_ON(i > ((cmd->hdr.len / 2) + 1))) { - print_hex_dump_bytes("UU:", DUMP_PREFIX_NONE, - (void *) cmd, cmd->hdr.len + 4); - break; - } - - __carl9170_tx_process_status(ar, cmd->_tx_status[i].cookie, - cmd->_tx_status[i].info); - } -} - -static void carl9170_tx_rate_tpc_chains(struct ar9170 *ar, - struct ieee80211_tx_info *info, struct ieee80211_tx_rate *txrate, - unsigned int *phyrate, unsigned int *tpc, unsigned int *chains) -{ - struct ieee80211_rate *rate = NULL; - u8 *txpower; - unsigned int idx; - - idx = txrate->idx; - *tpc = 0; - *phyrate = 0; - - if (txrate->flags & IEEE80211_TX_RC_MCS) { - if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) { - /* +1 dBm for HT40 */ - *tpc += 2; - - if (info->band == IEEE80211_BAND_2GHZ) - txpower = ar->power_2G_ht40; - else - txpower = ar->power_5G_ht40; - } else { - if (info->band == IEEE80211_BAND_2GHZ) - txpower = ar->power_2G_ht20; - else - txpower = ar->power_5G_ht20; - } - - *phyrate = txrate->idx; - *tpc += txpower[idx & 7]; - } else { - if (info->band == IEEE80211_BAND_2GHZ) { - if (idx < 4) - txpower = ar->power_2G_cck; - else - txpower = ar->power_2G_ofdm; - } else { - txpower = ar->power_5G_leg; - idx += 4; - } - - rate = &__carl9170_ratetable[idx]; - *tpc += txpower[(rate->hw_value & 0x30) >> 4]; - *phyrate = rate->hw_value & 0xf; - } - - if (ar->eeprom.tx_mask == 1) { - *chains = AR9170_TX_PHY_TXCHAIN_1; - } else { - if (!(txrate->flags & IEEE80211_TX_RC_MCS) && - rate && rate->bitrate >= 360) - *chains = AR9170_TX_PHY_TXCHAIN_1; - else - *chains = AR9170_TX_PHY_TXCHAIN_2; - } - - *tpc = min_t(unsigned int, *tpc, ar->hw->conf.power_level * 2); -} - -static __le32 carl9170_tx_physet(struct ar9170 *ar, - struct ieee80211_tx_info *info, struct ieee80211_tx_rate *txrate) -{ - unsigned int power = 0, chains = 0, phyrate = 0; - __le32 tmp; - - tmp = cpu_to_le32(0); - - if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) - tmp |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ << - AR9170_TX_PHY_BW_S); - /* this works because 40 MHz is 2 and dup is 3 */ - if (txrate->flags & IEEE80211_TX_RC_DUP_DATA) - tmp |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ_DUP << - AR9170_TX_PHY_BW_S); - - if (txrate->flags & IEEE80211_TX_RC_SHORT_GI) - tmp |= cpu_to_le32(AR9170_TX_PHY_SHORT_GI); - - if (txrate->flags & IEEE80211_TX_RC_MCS) { - SET_VAL(AR9170_TX_PHY_MCS, phyrate, txrate->idx); - - /* heavy clip control */ - tmp |= cpu_to_le32((txrate->idx & 0x7) << - AR9170_TX_PHY_TX_HEAVY_CLIP_S); - - tmp |= cpu_to_le32(AR9170_TX_PHY_MOD_HT); - - /* - * green field preamble does not work. - * - * if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD) - * tmp |= cpu_to_le32(AR9170_TX_PHY_GREENFIELD); - */ - } else { - if (info->band == IEEE80211_BAND_2GHZ) { - if (txrate->idx <= AR9170_TX_PHY_RATE_CCK_11M) - tmp |= cpu_to_le32(AR9170_TX_PHY_MOD_CCK); - else - tmp |= cpu_to_le32(AR9170_TX_PHY_MOD_OFDM); - } else { - tmp |= cpu_to_le32(AR9170_TX_PHY_MOD_OFDM); - } - - /* - * short preamble seems to be broken too. - * - * if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) - * tmp |= cpu_to_le32(AR9170_TX_PHY_SHORT_PREAMBLE); - */ - } - carl9170_tx_rate_tpc_chains(ar, info, txrate, - &phyrate, &power, &chains); - - tmp |= cpu_to_le32(SET_CONSTVAL(AR9170_TX_PHY_MCS, phyrate)); - tmp |= cpu_to_le32(SET_CONSTVAL(AR9170_TX_PHY_TX_PWR, power)); - tmp |= cpu_to_le32(SET_CONSTVAL(AR9170_TX_PHY_TXCHAIN, chains)); - return tmp; -} - -static bool carl9170_tx_rts_check(struct ar9170 *ar, - struct ieee80211_tx_rate *rate, - bool ampdu, bool multi) -{ - switch (ar->erp_mode) { - case CARL9170_ERP_AUTO: - if (ampdu) - break; - - case CARL9170_ERP_MAC80211: - if (!(rate->flags & IEEE80211_TX_RC_USE_RTS_CTS)) - break; - - case CARL9170_ERP_RTS: - if (likely(!multi)) - return true; - - default: - break; - } - - return false; -} - -static bool carl9170_tx_cts_check(struct ar9170 *ar, - struct ieee80211_tx_rate *rate) -{ - switch (ar->erp_mode) { - case CARL9170_ERP_AUTO: - case CARL9170_ERP_MAC80211: - if (!(rate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)) - break; - - case CARL9170_ERP_CTS: - return true; - - default: - break; - } - - return false; -} - -static int carl9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb) -{ - struct ieee80211_hdr *hdr; - struct _carl9170_tx_superframe *txc; - struct carl9170_vif_info *cvif; - struct ieee80211_tx_info *info; - struct ieee80211_tx_rate *txrate; - struct ieee80211_sta *sta; - struct carl9170_tx_info *arinfo; - unsigned int hw_queue; - int i; - __le16 mac_tmp; - u16 len; - bool ampdu, no_ack; - - BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data)); - BUILD_BUG_ON(sizeof(struct _carl9170_tx_superdesc) != - CARL9170_TX_SUPERDESC_LEN); - - BUILD_BUG_ON(sizeof(struct _ar9170_tx_hwdesc) != - AR9170_TX_HWDESC_LEN); - - BUILD_BUG_ON(IEEE80211_TX_MAX_RATES < CARL9170_TX_MAX_RATES); - - BUILD_BUG_ON(AR9170_MAX_VIRTUAL_MAC > - ((CARL9170_TX_SUPER_MISC_VIF_ID >> - CARL9170_TX_SUPER_MISC_VIF_ID_S) + 1)); - - hw_queue = ar9170_qmap[carl9170_get_queue(ar, skb)]; - - hdr = (void *)skb->data; - info = IEEE80211_SKB_CB(skb); - len = skb->len; - - /* - * Note: If the frame was sent through a monitor interface, - * the ieee80211_vif pointer can be NULL. - */ - if (likely(info->control.vif)) - cvif = (void *) info->control.vif->drv_priv; - else - cvif = NULL; - - sta = info->control.sta; - - txc = (void *)skb_push(skb, sizeof(*txc)); - memset(txc, 0, sizeof(*txc)); - - SET_VAL(CARL9170_TX_SUPER_MISC_QUEUE, txc->s.misc, hw_queue); - - if (likely(cvif)) - SET_VAL(CARL9170_TX_SUPER_MISC_VIF_ID, txc->s.misc, cvif->id); - - if (unlikely(info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM)) - txc->s.misc |= CARL9170_TX_SUPER_MISC_CAB; - - if (unlikely(info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)) - txc->s.misc |= CARL9170_TX_SUPER_MISC_ASSIGN_SEQ; - - if (unlikely(ieee80211_is_probe_resp(hdr->frame_control))) - txc->s.misc |= CARL9170_TX_SUPER_MISC_FILL_IN_TSF; - - mac_tmp = cpu_to_le16(AR9170_TX_MAC_HW_DURATION | - AR9170_TX_MAC_BACKOFF); - mac_tmp |= cpu_to_le16((hw_queue << AR9170_TX_MAC_QOS_S) & - AR9170_TX_MAC_QOS); - - no_ack = !!(info->flags & IEEE80211_TX_CTL_NO_ACK); - if (unlikely(no_ack)) - mac_tmp |= cpu_to_le16(AR9170_TX_MAC_NO_ACK); - - if (info->control.hw_key) { - len += info->control.hw_key->icv_len; - - switch (info->control.hw_key->cipher) { - case WLAN_CIPHER_SUITE_WEP40: - case WLAN_CIPHER_SUITE_WEP104: - case WLAN_CIPHER_SUITE_TKIP: - mac_tmp |= cpu_to_le16(AR9170_TX_MAC_ENCR_RC4); - break; - case WLAN_CIPHER_SUITE_CCMP: - mac_tmp |= cpu_to_le16(AR9170_TX_MAC_ENCR_AES); - break; - default: - WARN_ON(1); - goto err_out; - } - } - - ampdu = !!(info->flags & IEEE80211_TX_CTL_AMPDU); - if (ampdu) { - unsigned int density, factor; - - if (unlikely(!sta || !cvif)) - goto err_out; - - factor = min_t(unsigned int, 1u, sta->ht_cap.ampdu_factor); - density = sta->ht_cap.ampdu_density; - - if (density) { - /* - * Watch out! - * - * Otus uses slightly different density values than - * those from the 802.11n spec. - */ - - density = max_t(unsigned int, density + 1, 7u); - } - - SET_VAL(CARL9170_TX_SUPER_AMPDU_DENSITY, - txc->s.ampdu_settings, density); - - SET_VAL(CARL9170_TX_SUPER_AMPDU_FACTOR, - txc->s.ampdu_settings, factor); - - for (i = 0; i < CARL9170_TX_MAX_RATES; i++) { - txrate = &info->control.rates[i]; - if (txrate->idx >= 0) { - txc->s.ri[i] = - CARL9170_TX_SUPER_RI_AMPDU; - - if (WARN_ON(!(txrate->flags & - IEEE80211_TX_RC_MCS))) { - /* - * Not sure if it's even possible - * to aggregate non-ht rates with - * this HW. - */ - goto err_out; - } - continue; - } - - txrate->idx = 0; - txrate->count = ar->hw->max_rate_tries; - } - - mac_tmp |= cpu_to_le16(AR9170_TX_MAC_AGGR); - } - - /* - * NOTE: For the first rate, the ERP & AMPDU flags are directly - * taken from mac_control. For all fallback rate, the firmware - * updates the mac_control flags from the rate info field. - */ - for (i = 1; i < CARL9170_TX_MAX_RATES; i++) { - txrate = &info->control.rates[i]; - if (txrate->idx < 0) - break; - - SET_VAL(CARL9170_TX_SUPER_RI_TRIES, txc->s.ri[i], - txrate->count); - - if (carl9170_tx_rts_check(ar, txrate, ampdu, no_ack)) - txc->s.ri[i] |= (AR9170_TX_MAC_PROT_RTS << - CARL9170_TX_SUPER_RI_ERP_PROT_S); - else if (carl9170_tx_cts_check(ar, txrate)) - txc->s.ri[i] |= (AR9170_TX_MAC_PROT_CTS << - CARL9170_TX_SUPER_RI_ERP_PROT_S); - - txc->s.rr[i - 1] = carl9170_tx_physet(ar, info, txrate); - } - - txrate = &info->control.rates[0]; - SET_VAL(CARL9170_TX_SUPER_RI_TRIES, txc->s.ri[0], txrate->count); - - if (carl9170_tx_rts_check(ar, txrate, ampdu, no_ack)) - mac_tmp |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS); - else if (carl9170_tx_cts_check(ar, txrate)) - mac_tmp |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS); - - txc->s.len = cpu_to_le16(skb->len); - txc->f.length = cpu_to_le16(len + FCS_LEN); - txc->f.mac_control = mac_tmp; - txc->f.phy_control = carl9170_tx_physet(ar, info, txrate); - - arinfo = (void *)info->rate_driver_data; - arinfo->timeout = jiffies; - arinfo->ar = ar; - kref_init(&arinfo->ref); - return 0; - -err_out: - skb_pull(skb, sizeof(*txc)); - return -EINVAL; -} - -static void carl9170_set_immba(struct ar9170 *ar, struct sk_buff *skb) -{ - struct _carl9170_tx_superframe *super; - - super = (void *) skb->data; - super->f.mac_control |= cpu_to_le16(AR9170_TX_MAC_IMM_BA); -} - -static void carl9170_set_ampdu_params(struct ar9170 *ar, struct sk_buff *skb) -{ - struct _carl9170_tx_superframe *super; - int tmp; - - super = (void *) skb->data; - - tmp = (super->s.ampdu_settings & CARL9170_TX_SUPER_AMPDU_DENSITY) << - CARL9170_TX_SUPER_AMPDU_DENSITY_S; - - /* - * If you haven't noticed carl9170_tx_prepare has already filled - * in all ampdu spacing & factor parameters. - * Now it's the time to check whenever the settings have to be - * updated by the firmware, or if everything is still the same. - * - * There's no sane way to handle different density values with - * this hardware, so we may as well just do the compare in the - * driver. - */ - - if (tmp != ar->current_density) { - ar->current_density = tmp; - super->s.ampdu_settings |= - CARL9170_TX_SUPER_AMPDU_COMMIT_DENSITY; - } - - tmp = (super->s.ampdu_settings & CARL9170_TX_SUPER_AMPDU_FACTOR) << - CARL9170_TX_SUPER_AMPDU_FACTOR_S; - - if (tmp != ar->current_factor) { - ar->current_factor = tmp; - super->s.ampdu_settings |= - CARL9170_TX_SUPER_AMPDU_COMMIT_FACTOR; - } -} - -static bool carl9170_tx_rate_check(struct ar9170 *ar, struct sk_buff *_dest, - struct sk_buff *_src) -{ - struct _carl9170_tx_superframe *dest, *src; - - dest = (void *) _dest->data; - src = (void *) _src->data; - - /* - * The mac80211 rate control algorithm expects that all MPDUs in - * an AMPDU share the same tx vectors. - * This is not really obvious right now, because the hardware - * does the AMPDU setup according to its own rulebook. - * Our nicely assembled, strictly monotonic increasing mpdu - * chains will be broken up, mashed back together... - */ - - return (dest->f.phy_control == src->f.phy_control); -} - -static void carl9170_tx_ampdu(struct ar9170 *ar) -{ - struct sk_buff_head agg; - struct carl9170_sta_tid *tid_info; - struct sk_buff *skb, *first; - unsigned int i = 0, done_ampdus = 0; - u16 seq, queue, tmpssn; - - atomic_inc(&ar->tx_ampdu_scheduler); - ar->tx_ampdu_schedule = false; - - if (atomic_read(&ar->tx_ampdu_upload)) - return; - - if (!ar->tx_ampdu_list_len) - return; - - __skb_queue_head_init(&agg); - - rcu_read_lock(); - tid_info = rcu_dereference(ar->tx_ampdu_iter); - if (WARN_ON_ONCE(!tid_info)) { - rcu_read_unlock(); - return; - } - -retry: - list_for_each_entry_continue_rcu(tid_info, &ar->tx_ampdu_list, list) { - i++; - - if (tid_info->state < CARL9170_TID_STATE_PROGRESS) - continue; - - queue = TID_TO_WME_AC(tid_info->tid); - - spin_lock_bh(&tid_info->lock); - if (tid_info->state != CARL9170_TID_STATE_XMIT) - goto processed; - - tid_info->counter++; - first = skb_peek(&tid_info->queue); - tmpssn = carl9170_get_seq(first); - seq = tid_info->snx; - - if (unlikely(tmpssn != seq)) { - tid_info->state = CARL9170_TID_STATE_IDLE; - - goto processed; - } - - while ((skb = skb_peek(&tid_info->queue))) { - /* strict 0, 1, ..., n - 1, n frame sequence order */ - if (unlikely(carl9170_get_seq(skb) != seq)) - break; - - /* don't upload more than AMPDU FACTOR allows. */ - if (unlikely(SEQ_DIFF(tid_info->snx, tid_info->bsn) >= - (tid_info->max - 1))) - break; - - if (!carl9170_tx_rate_check(ar, skb, first)) - break; - - atomic_inc(&ar->tx_ampdu_upload); - tid_info->snx = seq = SEQ_NEXT(seq); - __skb_unlink(skb, &tid_info->queue); - - __skb_queue_tail(&agg, skb); - - if (skb_queue_len(&agg) >= CARL9170_NUM_TX_AGG_MAX) - break; - } - - if (skb_queue_empty(&tid_info->queue) || - carl9170_get_seq(skb_peek(&tid_info->queue)) != - tid_info->snx) { - /* - * stop TID, if A-MPDU frames are still missing, - * or whenever the queue is empty. - */ - - tid_info->state = CARL9170_TID_STATE_IDLE; - } - done_ampdus++; - -processed: - spin_unlock_bh(&tid_info->lock); - - if (skb_queue_empty(&agg)) - continue; - - /* apply ampdu spacing & factor settings */ - carl9170_set_ampdu_params(ar, skb_peek(&agg)); - - /* set aggregation push bit */ - carl9170_set_immba(ar, skb_peek_tail(&agg)); - - spin_lock_bh(&ar->tx_pending[queue].lock); - skb_queue_splice_tail_init(&agg, &ar->tx_pending[queue]); - spin_unlock_bh(&ar->tx_pending[queue].lock); - ar->tx_schedule = true; - } - if ((done_ampdus++ == 0) && (i++ == 0)) - goto retry; - - rcu_assign_pointer(ar->tx_ampdu_iter, tid_info); - rcu_read_unlock(); -} - -static struct sk_buff *carl9170_tx_pick_skb(struct ar9170 *ar, - struct sk_buff_head *queue) -{ - struct sk_buff *skb; - struct ieee80211_tx_info *info; - struct carl9170_tx_info *arinfo; - - BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data)); - - spin_lock_bh(&queue->lock); - skb = skb_peek(queue); - if (unlikely(!skb)) - goto err_unlock; - - if (carl9170_alloc_dev_space(ar, skb)) - goto err_unlock; - - __skb_unlink(skb, queue); - spin_unlock_bh(&queue->lock); - - info = IEEE80211_SKB_CB(skb); - arinfo = (void *) info->rate_driver_data; - - arinfo->timeout = jiffies; - return skb; - -err_unlock: - spin_unlock_bh(&queue->lock); - return NULL; -} - -void carl9170_tx_drop(struct ar9170 *ar, struct sk_buff *skb) -{ - struct _carl9170_tx_superframe *super; - uint8_t q = 0; - - ar->tx_dropped++; - - super = (void *)skb->data; - SET_VAL(CARL9170_TX_SUPER_MISC_QUEUE, q, - ar9170_qmap[carl9170_get_queue(ar, skb)]); - __carl9170_tx_process_status(ar, super->s.cookie, q); -} - -static bool carl9170_tx_ps_drop(struct ar9170 *ar, struct sk_buff *skb) -{ - struct ieee80211_sta *sta; - struct carl9170_sta_info *sta_info; - struct ieee80211_tx_info *tx_info; - - rcu_read_lock(); - sta = __carl9170_get_tx_sta(ar, skb); - if (!sta) - goto out_rcu; - - sta_info = (void *) sta->drv_priv; - tx_info = IEEE80211_SKB_CB(skb); - - if (unlikely(sta_info->sleeping) && - !(tx_info->flags & (IEEE80211_TX_CTL_NO_PS_BUFFER | - IEEE80211_TX_CTL_CLEAR_PS_FILT))) { - rcu_read_unlock(); - - if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) - atomic_dec(&ar->tx_ampdu_upload); - - tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; - carl9170_release_dev_space(ar, skb); - carl9170_tx_status(ar, skb, false); - return true; - } - -out_rcu: - rcu_read_unlock(); - return false; -} - -static void carl9170_tx(struct ar9170 *ar) -{ - struct sk_buff *skb; - unsigned int i, q; - bool schedule_garbagecollector = false; - - ar->tx_schedule = false; - - if (unlikely(!IS_STARTED(ar))) - return; - - carl9170_usb_handle_tx_err(ar); - - for (i = 0; i < ar->hw->queues; i++) { - while (!skb_queue_empty(&ar->tx_pending[i])) { - skb = carl9170_tx_pick_skb(ar, &ar->tx_pending[i]); - if (unlikely(!skb)) - break; - - if (unlikely(carl9170_tx_ps_drop(ar, skb))) - continue; - - atomic_inc(&ar->tx_total_pending); - - q = __carl9170_get_queue(ar, i); - /* - * NB: tx_status[i] vs. tx_status[q], - * TODO: Move into pick_skb or alloc_dev_space. - */ - skb_queue_tail(&ar->tx_status[q], skb); - - /* - * increase ref count to "2". - * Ref counting is the easiest way to solve the - * race between the urb's completion routine: - * carl9170_tx_callback - * and wlan tx status functions: - * carl9170_tx_status/janitor. - */ - carl9170_tx_get_skb(skb); - - carl9170_usb_tx(ar, skb); - schedule_garbagecollector = true; - } - } - - if (!schedule_garbagecollector) - return; - - ieee80211_queue_delayed_work(ar->hw, &ar->tx_janitor, - msecs_to_jiffies(CARL9170_TX_TIMEOUT)); -} - -static bool carl9170_tx_ampdu_queue(struct ar9170 *ar, - struct ieee80211_sta *sta, struct sk_buff *skb) -{ - struct _carl9170_tx_superframe *super = (void *) skb->data; - struct carl9170_sta_info *sta_info; - struct carl9170_sta_tid *agg; - struct sk_buff *iter; - u16 tid, seq, qseq, off; - bool run = false; - - tid = carl9170_get_tid(skb); - seq = carl9170_get_seq(skb); - sta_info = (void *) sta->drv_priv; - - rcu_read_lock(); - agg = rcu_dereference(sta_info->agg[tid]); - - if (!agg) - goto err_unlock_rcu; - - spin_lock_bh(&agg->lock); - if (unlikely(agg->state < CARL9170_TID_STATE_IDLE)) - goto err_unlock; - - /* check if sequence is within the BA window */ - if (unlikely(!BAW_WITHIN(agg->bsn, CARL9170_BAW_BITS, seq))) - goto err_unlock; - - if (WARN_ON_ONCE(!BAW_WITHIN(agg->snx, CARL9170_BAW_BITS, seq))) - goto err_unlock; - - off = SEQ_DIFF(seq, agg->bsn); - if (WARN_ON_ONCE(test_and_set_bit(off, agg->bitmap))) - goto err_unlock; - - if (likely(BAW_WITHIN(agg->hsn, CARL9170_BAW_BITS, seq))) { - __skb_queue_tail(&agg->queue, skb); - agg->hsn = seq; - goto queued; - } - - skb_queue_reverse_walk(&agg->queue, iter) { - qseq = carl9170_get_seq(iter); - - if (BAW_WITHIN(qseq, CARL9170_BAW_BITS, seq)) { - __skb_queue_after(&agg->queue, iter, skb); - goto queued; - } - } - - __skb_queue_head(&agg->queue, skb); -queued: - - if (unlikely(agg->state != CARL9170_TID_STATE_XMIT)) { - if (agg->snx == carl9170_get_seq(skb_peek(&agg->queue))) { - agg->state = CARL9170_TID_STATE_XMIT; - run = true; - } - } - - spin_unlock_bh(&agg->lock); - rcu_read_unlock(); - - return run; - -err_unlock: - spin_unlock_bh(&agg->lock); - -err_unlock_rcu: - rcu_read_unlock(); - super->f.mac_control &= ~cpu_to_le16(AR9170_TX_MAC_AGGR); - carl9170_tx_status(ar, skb, false); - ar->tx_dropped++; - return false; -} - -void carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) -{ - struct ar9170 *ar = hw->priv; - struct ieee80211_tx_info *info; - struct ieee80211_sta *sta; - bool run; - - if (unlikely(!IS_STARTED(ar))) - goto err_free; - - info = IEEE80211_SKB_CB(skb); - sta = info->control.sta; - - if (unlikely(carl9170_tx_prepare(ar, skb))) - goto err_free; - - carl9170_tx_accounting(ar, skb); - /* - * from now on, one has to use carl9170_tx_status to free - * all ressouces which are associated with the frame. - */ - - if (sta) { - struct carl9170_sta_info *stai = (void *) sta->drv_priv; - atomic_inc(&stai->pending_frames); - } - - if (info->flags & IEEE80211_TX_CTL_AMPDU) { - run = carl9170_tx_ampdu_queue(ar, sta, skb); - if (run) - carl9170_tx_ampdu(ar); - - } else { - unsigned int queue = skb_get_queue_mapping(skb); - - skb_queue_tail(&ar->tx_pending[queue], skb); - } - - carl9170_tx(ar); - return; - -err_free: - ar->tx_dropped++; - ieee80211_free_txskb(ar->hw, skb); -} - -void carl9170_tx_scheduler(struct ar9170 *ar) -{ - - if (ar->tx_ampdu_schedule) - carl9170_tx_ampdu(ar); - - if (ar->tx_schedule) - carl9170_tx(ar); -} - -int carl9170_update_beacon(struct ar9170 *ar, const bool submit) -{ - struct sk_buff *skb = NULL; - struct carl9170_vif_info *cvif; - struct ieee80211_tx_info *txinfo; - struct ieee80211_tx_rate *rate; - __le32 *data, *old = NULL; - unsigned int plcp, power, chains; - u32 word, ht1, off, addr, len; - int i = 0, err = 0; - - rcu_read_lock(); - cvif = rcu_dereference(ar->beacon_iter); -retry: - if (ar->vifs == 0 || !cvif) - goto out_unlock; - - list_for_each_entry_continue_rcu(cvif, &ar->vif_list, list) { - if (cvif->active && cvif->enable_beacon) - goto found; - } - - if (!ar->beacon_enabled || i++) - goto out_unlock; - - goto retry; - -found: - rcu_assign_pointer(ar->beacon_iter, cvif); - - skb = ieee80211_beacon_get_tim(ar->hw, carl9170_get_vif(cvif), - NULL, NULL); - - if (!skb) { - err = -ENOMEM; - goto err_free; - } - - txinfo = IEEE80211_SKB_CB(skb); - spin_lock_bh(&ar->beacon_lock); - data = (__le32 *)skb->data; - if (cvif->beacon) - old = (__le32 *)cvif->beacon->data; - - off = cvif->id * AR9170_MAC_BCN_LENGTH_MAX; - addr = ar->fw.beacon_addr + off; - len = roundup(skb->len + FCS_LEN, 4); - - if ((off + len) > ar->fw.beacon_max_len) { - if (net_ratelimit()) { - wiphy_err(ar->hw->wiphy, "beacon does not " - "fit into device memory!\n"); - } - err = -EINVAL; - goto err_unlock; - } - - if (len > AR9170_MAC_BCN_LENGTH_MAX) { - if (net_ratelimit()) { - wiphy_err(ar->hw->wiphy, "no support for beacons " - "bigger than %d (yours:%d).\n", - AR9170_MAC_BCN_LENGTH_MAX, len); - } - - err = -EMSGSIZE; - goto err_unlock; - } - - ht1 = AR9170_MAC_BCN_HT1_TX_ANT0; - rate = &txinfo->control.rates[0]; - carl9170_tx_rate_tpc_chains(ar, txinfo, rate, &plcp, &power, &chains); - if (!(txinfo->control.rates[0].flags & IEEE80211_TX_RC_MCS)) { - if (plcp <= AR9170_TX_PHY_RATE_CCK_11M) - plcp |= ((skb->len + FCS_LEN) << (3 + 16)) + 0x0400; - else - plcp |= ((skb->len + FCS_LEN) << 16) + 0x0010; - } else { - ht1 |= AR9170_MAC_BCN_HT1_HT_EN; - if (rate->flags & IEEE80211_TX_RC_SHORT_GI) - plcp |= AR9170_MAC_BCN_HT2_SGI; - - if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) { - ht1 |= AR9170_MAC_BCN_HT1_BWC_40M_SHARED; - plcp |= AR9170_MAC_BCN_HT2_BW40; - } - if (rate->flags & IEEE80211_TX_RC_DUP_DATA) { - ht1 |= AR9170_MAC_BCN_HT1_BWC_40M_DUP; - plcp |= AR9170_MAC_BCN_HT2_BW40; - } - - SET_VAL(AR9170_MAC_BCN_HT2_LEN, plcp, skb->len + FCS_LEN); - } - - SET_VAL(AR9170_MAC_BCN_HT1_PWR_CTRL, ht1, 7); - SET_VAL(AR9170_MAC_BCN_HT1_TPC, ht1, power); - SET_VAL(AR9170_MAC_BCN_HT1_CHAIN_MASK, ht1, chains); - if (chains == AR9170_TX_PHY_TXCHAIN_2) - ht1 |= AR9170_MAC_BCN_HT1_TX_ANT1; - - carl9170_async_regwrite_begin(ar); - carl9170_async_regwrite(AR9170_MAC_REG_BCN_HT1, ht1); - if (!(txinfo->control.rates[0].flags & IEEE80211_TX_RC_MCS)) - carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP, plcp); - else - carl9170_async_regwrite(AR9170_MAC_REG_BCN_HT2, plcp); - - for (i = 0; i < DIV_ROUND_UP(skb->len, 4); i++) { - /* - * XXX: This accesses beyond skb data for up - * to the last 3 bytes!! - */ - - if (old && (data[i] == old[i])) - continue; - - word = le32_to_cpu(data[i]); - carl9170_async_regwrite(addr + 4 * i, word); - } - carl9170_async_regwrite_finish(); - - dev_kfree_skb_any(cvif->beacon); - cvif->beacon = NULL; - - err = carl9170_async_regwrite_result(); - if (!err) - cvif->beacon = skb; - spin_unlock_bh(&ar->beacon_lock); - if (err) - goto err_free; - - if (submit) { - err = carl9170_bcn_ctrl(ar, cvif->id, - CARL9170_BCN_CTRL_CAB_TRIGGER, - addr, skb->len + FCS_LEN); - - if (err) - goto err_free; - } -out_unlock: - rcu_read_unlock(); - return 0; - -err_unlock: - spin_unlock_bh(&ar->beacon_lock); - -err_free: - rcu_read_unlock(); - dev_kfree_skb_any(skb); - return err; -} diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/usb.c b/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/usb.c deleted file mode 100644 index 89821e48..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/usb.c +++ /dev/null @@ -1,1164 +0,0 @@ -/* - * Atheros CARL9170 driver - * - * USB - frontend - * - * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> - * Copyright 2009, 2010, Christian Lamparter <chunkeey@googlemail.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, see - * http://www.gnu.org/licenses/. - * - * This file incorporates work covered by the following copyright and - * permission notice: - * Copyright (c) 2007-2008 Atheros Communications, Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/usb.h> -#include <linux/firmware.h> -#include <linux/etherdevice.h> -#include <linux/device.h> -#include <net/mac80211.h> -#include "carl9170.h" -#include "cmd.h" -#include "hw.h" -#include "fwcmd.h" - -MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>"); -MODULE_AUTHOR("Christian Lamparter <chunkeey@googlemail.com>"); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Atheros AR9170 802.11n USB wireless"); -MODULE_FIRMWARE(CARL9170FW_NAME); -MODULE_ALIAS("ar9170usb"); -MODULE_ALIAS("arusb_lnx"); - -/* - * Note: - * - * Always update our wiki's device list (located at: - * http://wireless.kernel.org/en/users/Drivers/ar9170/devices ), - * whenever you add a new device. - */ -static struct usb_device_id carl9170_usb_ids[] = { - /* Atheros 9170 */ - { USB_DEVICE(0x0cf3, 0x9170) }, - /* Atheros TG121N */ - { USB_DEVICE(0x0cf3, 0x1001) }, - /* TP-Link TL-WN821N v2 */ - { USB_DEVICE(0x0cf3, 0x1002), .driver_info = CARL9170_WPS_BUTTON | - CARL9170_ONE_LED }, - /* 3Com Dual Band 802.11n USB Adapter */ - { USB_DEVICE(0x0cf3, 0x1010) }, - /* H3C Dual Band 802.11n USB Adapter */ - { USB_DEVICE(0x0cf3, 0x1011) }, - /* Cace Airpcap NX */ - { USB_DEVICE(0xcace, 0x0300) }, - /* D-Link DWA 160 A1 */ - { USB_DEVICE(0x07d1, 0x3c10) }, - /* D-Link DWA 160 A2 */ - { USB_DEVICE(0x07d1, 0x3a09) }, - /* D-Link DWA 130 D */ - { USB_DEVICE(0x07d1, 0x3a0f) }, - /* Netgear WNA1000 */ - { USB_DEVICE(0x0846, 0x9040) }, - /* Netgear WNDA3100 (v1) */ - { USB_DEVICE(0x0846, 0x9010) }, - /* Netgear WN111 v2 */ - { USB_DEVICE(0x0846, 0x9001), .driver_info = CARL9170_ONE_LED }, - /* Zydas ZD1221 */ - { USB_DEVICE(0x0ace, 0x1221) }, - /* Proxim ORiNOCO 802.11n USB */ - { USB_DEVICE(0x1435, 0x0804) }, - /* WNC Generic 11n USB Dongle */ - { USB_DEVICE(0x1435, 0x0326) }, - /* ZyXEL NWD271N */ - { USB_DEVICE(0x0586, 0x3417) }, - /* Z-Com UB81 BG */ - { USB_DEVICE(0x0cde, 0x0023) }, - /* Z-Com UB82 ABG */ - { USB_DEVICE(0x0cde, 0x0026) }, - /* Sphairon Homelink 1202 */ - { USB_DEVICE(0x0cde, 0x0027) }, - /* Arcadyan WN7512 */ - { USB_DEVICE(0x083a, 0xf522) }, - /* Planex GWUS300 */ - { USB_DEVICE(0x2019, 0x5304) }, - /* IO-Data WNGDNUS2 */ - { USB_DEVICE(0x04bb, 0x093f) }, - /* NEC WL300NU-G */ - { USB_DEVICE(0x0409, 0x0249) }, - /* NEC WL300NU-AG */ - { USB_DEVICE(0x0409, 0x02b4) }, - /* AVM FRITZ!WLAN USB Stick N */ - { USB_DEVICE(0x057c, 0x8401) }, - /* AVM FRITZ!WLAN USB Stick N 2.4 */ - { USB_DEVICE(0x057c, 0x8402) }, - /* Qwest/Actiontec 802AIN Wireless N USB Network Adapter */ - { USB_DEVICE(0x1668, 0x1200) }, - /* Airlive X.USB a/b/g/n */ - { USB_DEVICE(0x1b75, 0x9170) }, - - /* terminate */ - {} -}; -MODULE_DEVICE_TABLE(usb, carl9170_usb_ids); - -static void carl9170_usb_submit_data_urb(struct ar9170 *ar) -{ - struct urb *urb; - int err; - - if (atomic_inc_return(&ar->tx_anch_urbs) > AR9170_NUM_TX_URBS) - goto err_acc; - - urb = usb_get_from_anchor(&ar->tx_wait); - if (!urb) - goto err_acc; - - usb_anchor_urb(urb, &ar->tx_anch); - - err = usb_submit_urb(urb, GFP_ATOMIC); - if (unlikely(err)) { - if (net_ratelimit()) { - dev_err(&ar->udev->dev, "tx submit failed (%d)\n", - urb->status); - } - - usb_unanchor_urb(urb); - usb_anchor_urb(urb, &ar->tx_err); - } - - usb_free_urb(urb); - - if (likely(err == 0)) - return; - -err_acc: - atomic_dec(&ar->tx_anch_urbs); -} - -static void carl9170_usb_tx_data_complete(struct urb *urb) -{ - struct ar9170 *ar = usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)); - - if (WARN_ON_ONCE(!ar)) { - dev_kfree_skb_irq(urb->context); - return; - } - - atomic_dec(&ar->tx_anch_urbs); - - switch (urb->status) { - /* everything is fine */ - case 0: - carl9170_tx_callback(ar, (void *)urb->context); - break; - - /* disconnect */ - case -ENOENT: - case -ECONNRESET: - case -ENODEV: - case -ESHUTDOWN: - /* - * Defer the frame clean-up to the tasklet worker. - * This is necessary, because carl9170_tx_drop - * does not work in an irqsave context. - */ - usb_anchor_urb(urb, &ar->tx_err); - return; - - /* a random transmission error has occurred? */ - default: - if (net_ratelimit()) { - dev_err(&ar->udev->dev, "tx failed (%d)\n", - urb->status); - } - - usb_anchor_urb(urb, &ar->tx_err); - break; - } - - if (likely(IS_STARTED(ar))) - carl9170_usb_submit_data_urb(ar); -} - -static int carl9170_usb_submit_cmd_urb(struct ar9170 *ar) -{ - struct urb *urb; - int err; - - if (atomic_inc_return(&ar->tx_cmd_urbs) != 1) { - atomic_dec(&ar->tx_cmd_urbs); - return 0; - } - - urb = usb_get_from_anchor(&ar->tx_cmd); - if (!urb) { - atomic_dec(&ar->tx_cmd_urbs); - return 0; - } - - usb_anchor_urb(urb, &ar->tx_anch); - err = usb_submit_urb(urb, GFP_ATOMIC); - if (unlikely(err)) { - usb_unanchor_urb(urb); - atomic_dec(&ar->tx_cmd_urbs); - } - usb_free_urb(urb); - - return err; -} - -static void carl9170_usb_cmd_complete(struct urb *urb) -{ - struct ar9170 *ar = urb->context; - int err = 0; - - if (WARN_ON_ONCE(!ar)) - return; - - atomic_dec(&ar->tx_cmd_urbs); - - switch (urb->status) { - /* everything is fine */ - case 0: - break; - - /* disconnect */ - case -ENOENT: - case -ECONNRESET: - case -ENODEV: - case -ESHUTDOWN: - return; - - default: - err = urb->status; - break; - } - - if (!IS_INITIALIZED(ar)) - return; - - if (err) - dev_err(&ar->udev->dev, "submit cmd cb failed (%d).\n", err); - - err = carl9170_usb_submit_cmd_urb(ar); - if (err) - dev_err(&ar->udev->dev, "submit cmd failed (%d).\n", err); -} - -static void carl9170_usb_rx_irq_complete(struct urb *urb) -{ - struct ar9170 *ar = urb->context; - - if (WARN_ON_ONCE(!ar)) - return; - - switch (urb->status) { - /* everything is fine */ - case 0: - break; - - /* disconnect */ - case -ENOENT: - case -ECONNRESET: - case -ENODEV: - case -ESHUTDOWN: - return; - - default: - goto resubmit; - } - - carl9170_handle_command_response(ar, urb->transfer_buffer, - urb->actual_length); - -resubmit: - usb_anchor_urb(urb, &ar->rx_anch); - if (unlikely(usb_submit_urb(urb, GFP_ATOMIC))) - usb_unanchor_urb(urb); -} - -static int carl9170_usb_submit_rx_urb(struct ar9170 *ar, gfp_t gfp) -{ - struct urb *urb; - int err = 0, runs = 0; - - while ((atomic_read(&ar->rx_anch_urbs) < AR9170_NUM_RX_URBS) && - (runs++ < AR9170_NUM_RX_URBS)) { - err = -ENOSPC; - urb = usb_get_from_anchor(&ar->rx_pool); - if (urb) { - usb_anchor_urb(urb, &ar->rx_anch); - err = usb_submit_urb(urb, gfp); - if (unlikely(err)) { - usb_unanchor_urb(urb); - usb_anchor_urb(urb, &ar->rx_pool); - } else { - atomic_dec(&ar->rx_pool_urbs); - atomic_inc(&ar->rx_anch_urbs); - } - usb_free_urb(urb); - } - } - - return err; -} - -static void carl9170_usb_rx_work(struct ar9170 *ar) -{ - struct urb *urb; - int i; - - for (i = 0; i < AR9170_NUM_RX_URBS_POOL; i++) { - urb = usb_get_from_anchor(&ar->rx_work); - if (!urb) - break; - - atomic_dec(&ar->rx_work_urbs); - if (IS_INITIALIZED(ar)) { - carl9170_rx(ar, urb->transfer_buffer, - urb->actual_length); - } - - usb_anchor_urb(urb, &ar->rx_pool); - atomic_inc(&ar->rx_pool_urbs); - - usb_free_urb(urb); - - carl9170_usb_submit_rx_urb(ar, GFP_ATOMIC); - } -} - -void carl9170_usb_handle_tx_err(struct ar9170 *ar) -{ - struct urb *urb; - - while ((urb = usb_get_from_anchor(&ar->tx_err))) { - struct sk_buff *skb = (void *)urb->context; - - carl9170_tx_drop(ar, skb); - carl9170_tx_callback(ar, skb); - usb_free_urb(urb); - } -} - -static void carl9170_usb_tasklet(unsigned long data) -{ - struct ar9170 *ar = (struct ar9170 *) data; - - if (!IS_INITIALIZED(ar)) - return; - - carl9170_usb_rx_work(ar); - - /* - * Strictly speaking: The tx scheduler is not part of the USB system. - * But the rx worker returns frames back to the mac80211-stack and - * this is the _perfect_ place to generate the next transmissions. - */ - if (IS_STARTED(ar)) - carl9170_tx_scheduler(ar); -} - -static void carl9170_usb_rx_complete(struct urb *urb) -{ - struct ar9170 *ar = (struct ar9170 *)urb->context; - int err; - - if (WARN_ON_ONCE(!ar)) - return; - - atomic_dec(&ar->rx_anch_urbs); - - switch (urb->status) { - case 0: - /* rx path */ - usb_anchor_urb(urb, &ar->rx_work); - atomic_inc(&ar->rx_work_urbs); - break; - - case -ENOENT: - case -ECONNRESET: - case -ENODEV: - case -ESHUTDOWN: - /* handle disconnect events*/ - return; - - default: - /* handle all other errors */ - usb_anchor_urb(urb, &ar->rx_pool); - atomic_inc(&ar->rx_pool_urbs); - break; - } - - err = carl9170_usb_submit_rx_urb(ar, GFP_ATOMIC); - if (unlikely(err)) { - /* - * usb_submit_rx_urb reported a problem. - * In case this is due to a rx buffer shortage, - * elevate the tasklet worker priority to - * the highest available level. - */ - tasklet_hi_schedule(&ar->usb_tasklet); - - if (atomic_read(&ar->rx_anch_urbs) == 0) { - /* - * The system is too slow to cope with - * the enormous workload. We have simply - * run out of active rx urbs and this - * unfortunately leads to an unpredictable - * device. - */ - - ieee80211_queue_work(ar->hw, &ar->ping_work); - } - } else { - /* - * Using anything less than _high_ priority absolutely - * kills the rx performance my UP-System... - */ - tasklet_hi_schedule(&ar->usb_tasklet); - } -} - -static struct urb *carl9170_usb_alloc_rx_urb(struct ar9170 *ar, gfp_t gfp) -{ - struct urb *urb; - void *buf; - - buf = kmalloc(ar->fw.rx_size, gfp); - if (!buf) - return NULL; - - urb = usb_alloc_urb(0, gfp); - if (!urb) { - kfree(buf); - return NULL; - } - - usb_fill_bulk_urb(urb, ar->udev, usb_rcvbulkpipe(ar->udev, - AR9170_USB_EP_RX), buf, ar->fw.rx_size, - carl9170_usb_rx_complete, ar); - - urb->transfer_flags |= URB_FREE_BUFFER; - - return urb; -} - -static int carl9170_usb_send_rx_irq_urb(struct ar9170 *ar) -{ - struct urb *urb = NULL; - void *ibuf; - int err = -ENOMEM; - - urb = usb_alloc_urb(0, GFP_KERNEL); - if (!urb) - goto out; - - ibuf = kmalloc(AR9170_USB_EP_CTRL_MAX, GFP_KERNEL); - if (!ibuf) - goto out; - - usb_fill_int_urb(urb, ar->udev, usb_rcvintpipe(ar->udev, - AR9170_USB_EP_IRQ), ibuf, AR9170_USB_EP_CTRL_MAX, - carl9170_usb_rx_irq_complete, ar, 1); - - urb->transfer_flags |= URB_FREE_BUFFER; - - usb_anchor_urb(urb, &ar->rx_anch); - err = usb_submit_urb(urb, GFP_KERNEL); - if (err) - usb_unanchor_urb(urb); - -out: - usb_free_urb(urb); - return err; -} - -static int carl9170_usb_init_rx_bulk_urbs(struct ar9170 *ar) -{ - struct urb *urb; - int i, err = -EINVAL; - - /* - * The driver actively maintains a second shadow - * pool for inactive, but fully-prepared rx urbs. - * - * The pool should help the driver to master huge - * workload spikes without running the risk of - * undersupplying the hardware or wasting time by - * processing rx data (streams) inside the urb - * completion (hardirq context). - */ - for (i = 0; i < AR9170_NUM_RX_URBS_POOL; i++) { - urb = carl9170_usb_alloc_rx_urb(ar, GFP_KERNEL); - if (!urb) { - err = -ENOMEM; - goto err_out; - } - - usb_anchor_urb(urb, &ar->rx_pool); - atomic_inc(&ar->rx_pool_urbs); - usb_free_urb(urb); - } - - err = carl9170_usb_submit_rx_urb(ar, GFP_KERNEL); - if (err) - goto err_out; - - /* the device now waiting for the firmware. */ - carl9170_set_state_when(ar, CARL9170_STOPPED, CARL9170_IDLE); - return 0; - -err_out: - - usb_scuttle_anchored_urbs(&ar->rx_pool); - usb_scuttle_anchored_urbs(&ar->rx_work); - usb_kill_anchored_urbs(&ar->rx_anch); - return err; -} - -static int carl9170_usb_flush(struct ar9170 *ar) -{ - struct urb *urb; - int ret, err = 0; - - while ((urb = usb_get_from_anchor(&ar->tx_wait))) { - struct sk_buff *skb = (void *)urb->context; - carl9170_tx_drop(ar, skb); - carl9170_tx_callback(ar, skb); - usb_free_urb(urb); - } - - ret = usb_wait_anchor_empty_timeout(&ar->tx_cmd, 1000); - if (ret == 0) - err = -ETIMEDOUT; - - /* lets wait a while until the tx - queues are dried out */ - ret = usb_wait_anchor_empty_timeout(&ar->tx_anch, 1000); - if (ret == 0) - err = -ETIMEDOUT; - - usb_kill_anchored_urbs(&ar->tx_anch); - carl9170_usb_handle_tx_err(ar); - - return err; -} - -static void carl9170_usb_cancel_urbs(struct ar9170 *ar) -{ - int err; - - carl9170_set_state(ar, CARL9170_UNKNOWN_STATE); - - err = carl9170_usb_flush(ar); - if (err) - dev_err(&ar->udev->dev, "stuck tx urbs!\n"); - - usb_poison_anchored_urbs(&ar->tx_anch); - carl9170_usb_handle_tx_err(ar); - usb_poison_anchored_urbs(&ar->rx_anch); - - tasklet_kill(&ar->usb_tasklet); - - usb_scuttle_anchored_urbs(&ar->rx_work); - usb_scuttle_anchored_urbs(&ar->rx_pool); - usb_scuttle_anchored_urbs(&ar->tx_cmd); -} - -int __carl9170_exec_cmd(struct ar9170 *ar, struct carl9170_cmd *cmd, - const bool free_buf) -{ - struct urb *urb; - int err = 0; - - if (!IS_INITIALIZED(ar)) { - err = -EPERM; - goto err_free; - } - - if (WARN_ON(cmd->hdr.len > CARL9170_MAX_CMD_LEN - 4)) { - err = -EINVAL; - goto err_free; - } - - urb = usb_alloc_urb(0, GFP_ATOMIC); - if (!urb) { - err = -ENOMEM; - goto err_free; - } - - usb_fill_int_urb(urb, ar->udev, usb_sndintpipe(ar->udev, - AR9170_USB_EP_CMD), cmd, cmd->hdr.len + 4, - carl9170_usb_cmd_complete, ar, 1); - - if (free_buf) - urb->transfer_flags |= URB_FREE_BUFFER; - - usb_anchor_urb(urb, &ar->tx_cmd); - usb_free_urb(urb); - - return carl9170_usb_submit_cmd_urb(ar); - -err_free: - if (free_buf) - kfree(cmd); - - return err; -} - -int carl9170_exec_cmd(struct ar9170 *ar, const enum carl9170_cmd_oids cmd, - unsigned int plen, void *payload, unsigned int outlen, void *out) -{ - int err = -ENOMEM; - - if (!IS_ACCEPTING_CMD(ar)) - return -EIO; - - if (!(cmd & CARL9170_CMD_ASYNC_FLAG)) - might_sleep(); - - ar->cmd.hdr.len = plen; - ar->cmd.hdr.cmd = cmd; - /* writing multiple regs fills this buffer already */ - if (plen && payload != (u8 *)(ar->cmd.data)) - memcpy(ar->cmd.data, payload, plen); - - spin_lock_bh(&ar->cmd_lock); - ar->readbuf = (u8 *)out; - ar->readlen = outlen; - spin_unlock_bh(&ar->cmd_lock); - - err = __carl9170_exec_cmd(ar, &ar->cmd, false); - - if (!(cmd & CARL9170_CMD_ASYNC_FLAG)) { - err = wait_for_completion_timeout(&ar->cmd_wait, HZ); - if (err == 0) { - err = -ETIMEDOUT; - goto err_unbuf; - } - - if (ar->readlen != outlen) { - err = -EMSGSIZE; - goto err_unbuf; - } - } - - return 0; - -err_unbuf: - /* Maybe the device was removed in the moment we were waiting? */ - if (IS_STARTED(ar)) { - dev_err(&ar->udev->dev, "no command feedback " - "received (%d).\n", err); - - /* provide some maybe useful debug information */ - print_hex_dump_bytes("carl9170 cmd: ", DUMP_PREFIX_NONE, - &ar->cmd, plen + 4); - - carl9170_restart(ar, CARL9170_RR_COMMAND_TIMEOUT); - } - - /* invalidate to avoid completing the next command prematurely */ - spin_lock_bh(&ar->cmd_lock); - ar->readbuf = NULL; - ar->readlen = 0; - spin_unlock_bh(&ar->cmd_lock); - - return err; -} - -void carl9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb) -{ - struct urb *urb; - struct ar9170_stream *tx_stream; - void *data; - unsigned int len; - - if (!IS_STARTED(ar)) - goto err_drop; - - urb = usb_alloc_urb(0, GFP_ATOMIC); - if (!urb) - goto err_drop; - - if (ar->fw.tx_stream) { - tx_stream = (void *) (skb->data - sizeof(*tx_stream)); - - len = skb->len + sizeof(*tx_stream); - tx_stream->length = cpu_to_le16(len); - tx_stream->tag = cpu_to_le16(AR9170_TX_STREAM_TAG); - data = tx_stream; - } else { - data = skb->data; - len = skb->len; - } - - usb_fill_bulk_urb(urb, ar->udev, usb_sndbulkpipe(ar->udev, - AR9170_USB_EP_TX), data, len, - carl9170_usb_tx_data_complete, skb); - - urb->transfer_flags |= URB_ZERO_PACKET; - - usb_anchor_urb(urb, &ar->tx_wait); - - usb_free_urb(urb); - - carl9170_usb_submit_data_urb(ar); - return; - -err_drop: - carl9170_tx_drop(ar, skb); - carl9170_tx_callback(ar, skb); -} - -static void carl9170_release_firmware(struct ar9170 *ar) -{ - if (ar->fw.fw) { - release_firmware(ar->fw.fw); - memset(&ar->fw, 0, sizeof(ar->fw)); - } -} - -void carl9170_usb_stop(struct ar9170 *ar) -{ - int ret; - - carl9170_set_state_when(ar, CARL9170_IDLE, CARL9170_STOPPED); - - ret = carl9170_usb_flush(ar); - if (ret) - dev_err(&ar->udev->dev, "kill pending tx urbs.\n"); - - usb_poison_anchored_urbs(&ar->tx_anch); - carl9170_usb_handle_tx_err(ar); - - /* kill any pending command */ - spin_lock_bh(&ar->cmd_lock); - ar->readlen = 0; - spin_unlock_bh(&ar->cmd_lock); - complete_all(&ar->cmd_wait); - - /* This is required to prevent an early completion on _start */ - INIT_COMPLETION(ar->cmd_wait); - - /* - * Note: - * So far we freed all tx urbs, but we won't dare to touch any rx urbs. - * Else we would end up with a unresponsive device... - */ -} - -int carl9170_usb_open(struct ar9170 *ar) -{ - usb_unpoison_anchored_urbs(&ar->tx_anch); - - carl9170_set_state_when(ar, CARL9170_STOPPED, CARL9170_IDLE); - return 0; -} - -static int carl9170_usb_load_firmware(struct ar9170 *ar) -{ - const u8 *data; - u8 *buf; - unsigned int transfer; - size_t len; - u32 addr; - int err = 0; - - buf = kmalloc(4096, GFP_KERNEL); - if (!buf) { - err = -ENOMEM; - goto err_out; - } - - data = ar->fw.fw->data; - len = ar->fw.fw->size; - addr = ar->fw.address; - - /* this removes the miniboot image */ - data += ar->fw.offset; - len -= ar->fw.offset; - - while (len) { - transfer = min_t(unsigned int, len, 4096u); - memcpy(buf, data, transfer); - - err = usb_control_msg(ar->udev, usb_sndctrlpipe(ar->udev, 0), - 0x30 /* FW DL */, 0x40 | USB_DIR_OUT, - addr >> 8, 0, buf, transfer, 100); - - if (err < 0) { - kfree(buf); - goto err_out; - } - - len -= transfer; - data += transfer; - addr += transfer; - } - kfree(buf); - - err = usb_control_msg(ar->udev, usb_sndctrlpipe(ar->udev, 0), - 0x31 /* FW DL COMPLETE */, - 0x40 | USB_DIR_OUT, 0, 0, NULL, 0, 200); - - if (wait_for_completion_timeout(&ar->fw_boot_wait, HZ) == 0) { - err = -ETIMEDOUT; - goto err_out; - } - - err = carl9170_echo_test(ar, 0x4a110123); - if (err) - goto err_out; - - /* now, start the command response counter */ - ar->cmd_seq = -1; - - return 0; - -err_out: - dev_err(&ar->udev->dev, "firmware upload failed (%d).\n", err); - return err; -} - -int carl9170_usb_restart(struct ar9170 *ar) -{ - int err = 0; - - if (ar->intf->condition != USB_INTERFACE_BOUND) - return 0; - - /* - * Disable the command response sequence counter check. - * We already know that the device/firmware is in a bad state. - * So, no extra points are awarded to anyone who reminds the - * driver about that. - */ - ar->cmd_seq = -2; - - err = carl9170_reboot(ar); - - carl9170_usb_stop(ar); - - if (err) - goto err_out; - - tasklet_schedule(&ar->usb_tasklet); - - /* The reboot procedure can take quite a while to complete. */ - msleep(1100); - - err = carl9170_usb_open(ar); - if (err) - goto err_out; - - err = carl9170_usb_load_firmware(ar); - if (err) - goto err_out; - - return 0; - -err_out: - carl9170_usb_cancel_urbs(ar); - return err; -} - -void carl9170_usb_reset(struct ar9170 *ar) -{ - /* - * This is the last resort to get the device going again - * without any *user replugging action*. - * - * But there is a catch: usb_reset really is like a physical - * *reconnect*. The mac80211 state will be lost in the process. - * Therefore a userspace application, which is monitoring - * the link must step in. - */ - carl9170_usb_cancel_urbs(ar); - - carl9170_usb_stop(ar); - - usb_queue_reset_device(ar->intf); -} - -static int carl9170_usb_init_device(struct ar9170 *ar) -{ - int err; - - /* - * The carl9170 firmware let's the driver know when it's - * ready for action. But we have to be prepared to gracefully - * handle all spurious [flushed] messages after each (re-)boot. - * Thus the command response counter remains disabled until it - * can be safely synchronized. - */ - ar->cmd_seq = -2; - - err = carl9170_usb_send_rx_irq_urb(ar); - if (err) - goto err_out; - - err = carl9170_usb_init_rx_bulk_urbs(ar); - if (err) - goto err_unrx; - - err = carl9170_usb_open(ar); - if (err) - goto err_unrx; - - mutex_lock(&ar->mutex); - err = carl9170_usb_load_firmware(ar); - mutex_unlock(&ar->mutex); - if (err) - goto err_stop; - - return 0; - -err_stop: - carl9170_usb_stop(ar); - -err_unrx: - carl9170_usb_cancel_urbs(ar); - -err_out: - return err; -} - -static void carl9170_usb_firmware_failed(struct ar9170 *ar) -{ - struct device *parent = ar->udev->dev.parent; - struct usb_device *udev; - - /* - * Store a copy of the usb_device pointer locally. - * This is because device_release_driver initiates - * carl9170_usb_disconnect, which in turn frees our - * driver context (ar). - */ - udev = ar->udev; - - complete(&ar->fw_load_wait); - - /* unbind anything failed */ - if (parent) - device_lock(parent); - - device_release_driver(&udev->dev); - if (parent) - device_unlock(parent); - - usb_put_dev(udev); -} - -static void carl9170_usb_firmware_finish(struct ar9170 *ar) -{ - int err; - - err = carl9170_parse_firmware(ar); - if (err) - goto err_freefw; - - err = carl9170_usb_init_device(ar); - if (err) - goto err_freefw; - - err = carl9170_register(ar); - - carl9170_usb_stop(ar); - if (err) - goto err_unrx; - - complete(&ar->fw_load_wait); - usb_put_dev(ar->udev); - return; - -err_unrx: - carl9170_usb_cancel_urbs(ar); - -err_freefw: - carl9170_release_firmware(ar); - carl9170_usb_firmware_failed(ar); -} - -static void carl9170_usb_firmware_step2(const struct firmware *fw, - void *context) -{ - struct ar9170 *ar = context; - - if (fw) { - ar->fw.fw = fw; - carl9170_usb_firmware_finish(ar); - return; - } - - dev_err(&ar->udev->dev, "firmware not found.\n"); - carl9170_usb_firmware_failed(ar); -} - -static int carl9170_usb_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - struct ar9170 *ar; - struct usb_device *udev; - int err; - - err = usb_reset_device(interface_to_usbdev(intf)); - if (err) - return err; - - ar = carl9170_alloc(sizeof(*ar)); - if (IS_ERR(ar)) - return PTR_ERR(ar); - - udev = interface_to_usbdev(intf); - usb_get_dev(udev); - ar->udev = udev; - ar->intf = intf; - ar->features = id->driver_info; - - usb_set_intfdata(intf, ar); - SET_IEEE80211_DEV(ar->hw, &intf->dev); - - init_usb_anchor(&ar->rx_anch); - init_usb_anchor(&ar->rx_pool); - init_usb_anchor(&ar->rx_work); - init_usb_anchor(&ar->tx_wait); - init_usb_anchor(&ar->tx_anch); - init_usb_anchor(&ar->tx_cmd); - init_usb_anchor(&ar->tx_err); - init_completion(&ar->cmd_wait); - init_completion(&ar->fw_boot_wait); - init_completion(&ar->fw_load_wait); - tasklet_init(&ar->usb_tasklet, carl9170_usb_tasklet, - (unsigned long)ar); - - atomic_set(&ar->tx_cmd_urbs, 0); - atomic_set(&ar->tx_anch_urbs, 0); - atomic_set(&ar->rx_work_urbs, 0); - atomic_set(&ar->rx_anch_urbs, 0); - atomic_set(&ar->rx_pool_urbs, 0); - - usb_get_dev(ar->udev); - - carl9170_set_state(ar, CARL9170_STOPPED); - - return request_firmware_nowait(THIS_MODULE, 1, CARL9170FW_NAME, - &ar->udev->dev, GFP_KERNEL, ar, carl9170_usb_firmware_step2); -} - -static void carl9170_usb_disconnect(struct usb_interface *intf) -{ - struct ar9170 *ar = usb_get_intfdata(intf); - struct usb_device *udev; - - if (WARN_ON(!ar)) - return; - - udev = ar->udev; - wait_for_completion(&ar->fw_load_wait); - - if (IS_INITIALIZED(ar)) { - carl9170_reboot(ar); - carl9170_usb_stop(ar); - } - - carl9170_usb_cancel_urbs(ar); - carl9170_unregister(ar); - - usb_set_intfdata(intf, NULL); - - carl9170_release_firmware(ar); - carl9170_free(ar); - usb_put_dev(udev); -} - -#ifdef CONFIG_PM -static int carl9170_usb_suspend(struct usb_interface *intf, - pm_message_t message) -{ - struct ar9170 *ar = usb_get_intfdata(intf); - - if (!ar) - return -ENODEV; - - carl9170_usb_cancel_urbs(ar); - - return 0; -} - -static int carl9170_usb_resume(struct usb_interface *intf) -{ - struct ar9170 *ar = usb_get_intfdata(intf); - int err; - - if (!ar) - return -ENODEV; - - usb_unpoison_anchored_urbs(&ar->rx_anch); - carl9170_set_state(ar, CARL9170_STOPPED); - - /* - * The USB documentation demands that [for suspend] all traffic - * to and from the device has to stop. This would be fine, but - * there's a catch: the device[usb phy] does not come back. - * - * Upon resume the firmware will "kill" itself and the - * boot-code sorts out the magic voodoo. - * Not very nice, but there's not much what could go wrong. - */ - msleep(1100); - - err = carl9170_usb_init_device(ar); - if (err) - goto err_unrx; - - return 0; - -err_unrx: - carl9170_usb_cancel_urbs(ar); - - return err; -} -#endif /* CONFIG_PM */ - -static struct usb_driver carl9170_driver = { - .name = KBUILD_MODNAME, - .probe = carl9170_usb_probe, - .disconnect = carl9170_usb_disconnect, - .id_table = carl9170_usb_ids, - .soft_unbind = 1, -#ifdef CONFIG_PM - .suspend = carl9170_usb_suspend, - .resume = carl9170_usb_resume, - .reset_resume = carl9170_usb_resume, -#endif /* CONFIG_PM */ -}; - -module_usb_driver(carl9170_driver); diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/version.h b/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/version.h deleted file mode 100644 index e651db85..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/version.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __CARL9170_SHARED_VERSION_H -#define __CARL9170_SHARED_VERSION_H -#define CARL9170FW_VERSION_YEAR 11 -#define CARL9170FW_VERSION_MONTH 8 -#define CARL9170FW_VERSION_DAY 15 -#define CARL9170FW_VERSION_GIT "1.9.4" -#endif /* __CARL9170_SHARED_VERSION_H */ diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/wlan.h b/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/wlan.h deleted file mode 100644 index ea17995b..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/carl9170/wlan.h +++ /dev/null @@ -1,435 +0,0 @@ -/* - * Shared Atheros AR9170 Header - * - * RX/TX meta descriptor format - * - * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> - * Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, see - * http://www.gnu.org/licenses/. - * - * This file incorporates work covered by the following copyright and - * permission notice: - * Copyright (c) 2007-2008 Atheros Communications, Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef __CARL9170_SHARED_WLAN_H -#define __CARL9170_SHARED_WLAN_H - -#include "fwcmd.h" - -#define AR9170_RX_PHY_RATE_CCK_1M 0x0a -#define AR9170_RX_PHY_RATE_CCK_2M 0x14 -#define AR9170_RX_PHY_RATE_CCK_5M 0x37 -#define AR9170_RX_PHY_RATE_CCK_11M 0x6e - -#define AR9170_ENC_ALG_NONE 0x0 -#define AR9170_ENC_ALG_WEP64 0x1 -#define AR9170_ENC_ALG_TKIP 0x2 -#define AR9170_ENC_ALG_AESCCMP 0x4 -#define AR9170_ENC_ALG_WEP128 0x5 -#define AR9170_ENC_ALG_WEP256 0x6 -#define AR9170_ENC_ALG_CENC 0x7 - -#define AR9170_RX_ENC_SOFTWARE 0x8 - -#define AR9170_RX_STATUS_MODULATION 0x03 -#define AR9170_RX_STATUS_MODULATION_S 0 -#define AR9170_RX_STATUS_MODULATION_CCK 0x00 -#define AR9170_RX_STATUS_MODULATION_OFDM 0x01 -#define AR9170_RX_STATUS_MODULATION_HT 0x02 -#define AR9170_RX_STATUS_MODULATION_DUPOFDM 0x03 - -/* depends on modulation */ -#define AR9170_RX_STATUS_SHORT_PREAMBLE 0x08 -#define AR9170_RX_STATUS_GREENFIELD 0x08 - -#define AR9170_RX_STATUS_MPDU 0x30 -#define AR9170_RX_STATUS_MPDU_S 4 -#define AR9170_RX_STATUS_MPDU_SINGLE 0x00 -#define AR9170_RX_STATUS_MPDU_FIRST 0x20 -#define AR9170_RX_STATUS_MPDU_MIDDLE 0x30 -#define AR9170_RX_STATUS_MPDU_LAST 0x10 - -#define AR9170_RX_STATUS_CONT_AGGR 0x40 -#define AR9170_RX_STATUS_TOTAL_ERROR 0x80 - -#define AR9170_RX_ERROR_RXTO 0x01 -#define AR9170_RX_ERROR_OVERRUN 0x02 -#define AR9170_RX_ERROR_DECRYPT 0x04 -#define AR9170_RX_ERROR_FCS 0x08 -#define AR9170_RX_ERROR_WRONG_RA 0x10 -#define AR9170_RX_ERROR_PLCP 0x20 -#define AR9170_RX_ERROR_MMIC 0x40 - -/* these are either-or */ -#define AR9170_TX_MAC_PROT_RTS 0x0001 -#define AR9170_TX_MAC_PROT_CTS 0x0002 -#define AR9170_TX_MAC_PROT 0x0003 - -#define AR9170_TX_MAC_NO_ACK 0x0004 -/* if unset, MAC will only do SIFS space before frame */ -#define AR9170_TX_MAC_BACKOFF 0x0008 -#define AR9170_TX_MAC_BURST 0x0010 -#define AR9170_TX_MAC_AGGR 0x0020 - -/* encryption is a two-bit field */ -#define AR9170_TX_MAC_ENCR_NONE 0x0000 -#define AR9170_TX_MAC_ENCR_RC4 0x0040 -#define AR9170_TX_MAC_ENCR_CENC 0x0080 -#define AR9170_TX_MAC_ENCR_AES 0x00c0 - -#define AR9170_TX_MAC_MMIC 0x0100 -#define AR9170_TX_MAC_HW_DURATION 0x0200 -#define AR9170_TX_MAC_QOS_S 10 -#define AR9170_TX_MAC_QOS 0x0c00 -#define AR9170_TX_MAC_DISABLE_TXOP 0x1000 -#define AR9170_TX_MAC_TXOP_RIFS 0x2000 -#define AR9170_TX_MAC_IMM_BA 0x4000 - -/* either-or */ -#define AR9170_TX_PHY_MOD_CCK 0x00000000 -#define AR9170_TX_PHY_MOD_OFDM 0x00000001 -#define AR9170_TX_PHY_MOD_HT 0x00000002 - -/* depends on modulation */ -#define AR9170_TX_PHY_SHORT_PREAMBLE 0x00000004 -#define AR9170_TX_PHY_GREENFIELD 0x00000004 - -#define AR9170_TX_PHY_BW_S 3 -#define AR9170_TX_PHY_BW (3 << AR9170_TX_PHY_BW_SHIFT) -#define AR9170_TX_PHY_BW_20MHZ 0 -#define AR9170_TX_PHY_BW_40MHZ 2 -#define AR9170_TX_PHY_BW_40MHZ_DUP 3 - -#define AR9170_TX_PHY_TX_HEAVY_CLIP_S 6 -#define AR9170_TX_PHY_TX_HEAVY_CLIP (7 << \ - AR9170_TX_PHY_TX_HEAVY_CLIP_S) - -#define AR9170_TX_PHY_TX_PWR_S 9 -#define AR9170_TX_PHY_TX_PWR (0x3f << \ - AR9170_TX_PHY_TX_PWR_S) - -#define AR9170_TX_PHY_TXCHAIN_S 15 -#define AR9170_TX_PHY_TXCHAIN (7 << \ - AR9170_TX_PHY_TXCHAIN_S) -#define AR9170_TX_PHY_TXCHAIN_1 1 -/* use for cck, ofdm 6/9/12/18/24 and HT if capable */ -#define AR9170_TX_PHY_TXCHAIN_2 5 - -#define AR9170_TX_PHY_MCS_S 18 -#define AR9170_TX_PHY_MCS (0x7f << \ - AR9170_TX_PHY_MCS_S) - -#define AR9170_TX_PHY_RATE_CCK_1M 0x0 -#define AR9170_TX_PHY_RATE_CCK_2M 0x1 -#define AR9170_TX_PHY_RATE_CCK_5M 0x2 -#define AR9170_TX_PHY_RATE_CCK_11M 0x3 - -/* same as AR9170_RX_PHY_RATE */ -#define AR9170_TXRX_PHY_RATE_OFDM_6M 0xb -#define AR9170_TXRX_PHY_RATE_OFDM_9M 0xf -#define AR9170_TXRX_PHY_RATE_OFDM_12M 0xa -#define AR9170_TXRX_PHY_RATE_OFDM_18M 0xe -#define AR9170_TXRX_PHY_RATE_OFDM_24M 0x9 -#define AR9170_TXRX_PHY_RATE_OFDM_36M 0xd -#define AR9170_TXRX_PHY_RATE_OFDM_48M 0x8 -#define AR9170_TXRX_PHY_RATE_OFDM_54M 0xc - -#define AR9170_TXRX_PHY_RATE_HT_MCS0 0x0 -#define AR9170_TXRX_PHY_RATE_HT_MCS1 0x1 -#define AR9170_TXRX_PHY_RATE_HT_MCS2 0x2 -#define AR9170_TXRX_PHY_RATE_HT_MCS3 0x3 -#define AR9170_TXRX_PHY_RATE_HT_MCS4 0x4 -#define AR9170_TXRX_PHY_RATE_HT_MCS5 0x5 -#define AR9170_TXRX_PHY_RATE_HT_MCS6 0x6 -#define AR9170_TXRX_PHY_RATE_HT_MCS7 0x7 -#define AR9170_TXRX_PHY_RATE_HT_MCS8 0x8 -#define AR9170_TXRX_PHY_RATE_HT_MCS9 0x9 -#define AR9170_TXRX_PHY_RATE_HT_MCS10 0xa -#define AR9170_TXRX_PHY_RATE_HT_MCS11 0xb -#define AR9170_TXRX_PHY_RATE_HT_MCS12 0xc -#define AR9170_TXRX_PHY_RATE_HT_MCS13 0xd -#define AR9170_TXRX_PHY_RATE_HT_MCS14 0xe -#define AR9170_TXRX_PHY_RATE_HT_MCS15 0xf - -#define AR9170_TX_PHY_SHORT_GI 0x80000000 - -#ifdef __CARL9170FW__ -struct ar9170_tx_hw_mac_control { - union { - struct { - /* - * Beware of compiler bugs in all gcc pre 4.4! - */ - - u8 erp_prot:2; - u8 no_ack:1; - u8 backoff:1; - u8 burst:1; - u8 ampdu:1; - - u8 enc_mode:2; - - u8 hw_mmic:1; - u8 hw_duration:1; - - u8 qos_queue:2; - - u8 disable_txop:1; - u8 txop_rifs:1; - - u8 ba_end:1; - u8 probe:1; - } __packed; - - __le16 set; - } __packed; -} __packed; - -struct ar9170_tx_hw_phy_control { - union { - struct { - /* - * Beware of compiler bugs in all gcc pre 4.4! - */ - - u8 modulation:2; - u8 preamble:1; - u8 bandwidth:2; - u8:1; - u8 heavy_clip:3; - u8 tx_power:6; - u8 chains:3; - u8 mcs:7; - u8:6; - u8 short_gi:1; - } __packed; - - __le32 set; - } __packed; -} __packed; - -struct ar9170_tx_rate_info { - u8 tries:3; - u8 erp_prot:2; - u8 ampdu:1; - u8 free:2; /* free for use (e.g.:RIFS/TXOP/AMPDU) */ -} __packed; - -struct carl9170_tx_superdesc { - __le16 len; - u8 rix; - u8 cnt; - u8 cookie; - u8 ampdu_density:3; - u8 ampdu_factor:2; - u8 ampdu_commit_density:1; - u8 ampdu_commit_factor:1; - u8 ampdu_unused_bit:1; - u8 queue:2; - u8 assign_seq:1; - u8 vif_id:3; - u8 fill_in_tsf:1; - u8 cab:1; - u8 padding2; - struct ar9170_tx_rate_info ri[CARL9170_TX_MAX_RATES]; - struct ar9170_tx_hw_phy_control rr[CARL9170_TX_MAX_RETRY_RATES]; -} __packed; - -struct ar9170_tx_hwdesc { - __le16 length; - struct ar9170_tx_hw_mac_control mac; - struct ar9170_tx_hw_phy_control phy; -} __packed; - -struct ar9170_tx_frame { - struct ar9170_tx_hwdesc hdr; - - union { - struct ieee80211_hdr i3e; - u8 payload[0]; - } data; -} __packed; - -struct carl9170_tx_superframe { - struct carl9170_tx_superdesc s; - struct ar9170_tx_frame f; -} __packed __aligned(4); - -#endif /* __CARL9170FW__ */ - -struct _ar9170_tx_hwdesc { - __le16 length; - __le16 mac_control; - __le32 phy_control; -} __packed; - -#define CARL9170_TX_SUPER_AMPDU_DENSITY_S 0 -#define CARL9170_TX_SUPER_AMPDU_DENSITY 0x7 -#define CARL9170_TX_SUPER_AMPDU_FACTOR 0x18 -#define CARL9170_TX_SUPER_AMPDU_FACTOR_S 3 -#define CARL9170_TX_SUPER_AMPDU_COMMIT_DENSITY 0x20 -#define CARL9170_TX_SUPER_AMPDU_COMMIT_DENSITY_S 5 -#define CARL9170_TX_SUPER_AMPDU_COMMIT_FACTOR 0x40 -#define CARL9170_TX_SUPER_AMPDU_COMMIT_FACTOR_S 6 - -#define CARL9170_TX_SUPER_MISC_QUEUE 0x3 -#define CARL9170_TX_SUPER_MISC_QUEUE_S 0 -#define CARL9170_TX_SUPER_MISC_ASSIGN_SEQ 0x4 -#define CARL9170_TX_SUPER_MISC_VIF_ID 0x38 -#define CARL9170_TX_SUPER_MISC_VIF_ID_S 3 -#define CARL9170_TX_SUPER_MISC_FILL_IN_TSF 0x40 -#define CARL9170_TX_SUPER_MISC_CAB 0x80 - -#define CARL9170_TX_SUPER_RI_TRIES 0x7 -#define CARL9170_TX_SUPER_RI_TRIES_S 0 -#define CARL9170_TX_SUPER_RI_ERP_PROT 0x18 -#define CARL9170_TX_SUPER_RI_ERP_PROT_S 3 -#define CARL9170_TX_SUPER_RI_AMPDU 0x20 -#define CARL9170_TX_SUPER_RI_AMPDU_S 5 - -struct _carl9170_tx_superdesc { - __le16 len; - u8 rix; - u8 cnt; - u8 cookie; - u8 ampdu_settings; - u8 misc; - u8 padding; - u8 ri[CARL9170_TX_MAX_RATES]; - __le32 rr[CARL9170_TX_MAX_RETRY_RATES]; -} __packed; - -struct _carl9170_tx_superframe { - struct _carl9170_tx_superdesc s; - struct _ar9170_tx_hwdesc f; - u8 frame_data[0]; -} __packed __aligned(4); - -#define CARL9170_TX_SUPERDESC_LEN 24 -#define AR9170_TX_HWDESC_LEN 8 -#define CARL9170_TX_SUPERFRAME_LEN (CARL9170_TX_SUPERDESC_LEN + \ - AR9170_TX_HWDESC_LEN) - -struct ar9170_rx_head { - u8 plcp[12]; -} __packed; - -#define AR9170_RX_HEAD_LEN 12 - -struct ar9170_rx_phystatus { - union { - struct { - u8 rssi_ant0, rssi_ant1, rssi_ant2, - rssi_ant0x, rssi_ant1x, rssi_ant2x, - rssi_combined; - } __packed; - u8 rssi[7]; - } __packed; - - u8 evm_stream0[6], evm_stream1[6]; - u8 phy_err; -} __packed; - -#define AR9170_RX_PHYSTATUS_LEN 20 - -struct ar9170_rx_macstatus { - u8 SAidx, DAidx; - u8 error; - u8 status; -} __packed; - -#define AR9170_RX_MACSTATUS_LEN 4 - -struct ar9170_rx_frame_single { - struct ar9170_rx_head phy_head; - struct ieee80211_hdr i3e; - struct ar9170_rx_phystatus phy_tail; - struct ar9170_rx_macstatus macstatus; -} __packed; - -struct ar9170_rx_frame_head { - struct ar9170_rx_head phy_head; - struct ieee80211_hdr i3e; - struct ar9170_rx_macstatus macstatus; -} __packed; - -struct ar9170_rx_frame_middle { - struct ieee80211_hdr i3e; - struct ar9170_rx_macstatus macstatus; -} __packed; - -struct ar9170_rx_frame_tail { - struct ieee80211_hdr i3e; - struct ar9170_rx_phystatus phy_tail; - struct ar9170_rx_macstatus macstatus; -} __packed; - -struct ar9170_rx_frame { - union { - struct ar9170_rx_frame_single single; - struct ar9170_rx_frame_head head; - struct ar9170_rx_frame_middle middle; - struct ar9170_rx_frame_tail tail; - } __packed; -} __packed; - -static inline u8 ar9170_get_decrypt_type(struct ar9170_rx_macstatus *t) -{ - return (t->SAidx & 0xc0) >> 4 | - (t->DAidx & 0xc0) >> 6; -} - -/* - * This is an workaround for several undocumented bugs. - * Don't mess with the QoS/AC <-> HW Queue map, if you don't - * know what you are doing. - * - * Known problems [hardware]: - * * The MAC does not aggregate frames on anything other - * than the first HW queue. - * * when an AMPDU is placed [in the first hw queue] and - * additional frames are already queued on a different - * hw queue, the MAC will ALWAYS freeze. - * - * In a nutshell: The hardware can either do QoS or - * Aggregation but not both at the same time. As a - * result, this makes the device pretty much useless - * for any serious 802.11n setup. - */ -enum ar9170_txq { - AR9170_TXQ_BK = 0, /* TXQ0 */ - AR9170_TXQ_BE, /* TXQ1 */ - AR9170_TXQ_VI, /* TXQ2 */ - AR9170_TXQ_VO, /* TXQ3 */ - - __AR9170_NUM_TXQ, -}; - -#define AR9170_TXQ_DEPTH 32 - -#endif /* __CARL9170_SHARED_WLAN_H */ |