Resguardo inicial

This commit is contained in:
lastdragon
2026-09-06 12:53:21 -06:00
parent 662efe3c2a
commit ad2088d178
94853 changed files with 43200404 additions and 0 deletions
@@ -0,0 +1,53 @@
# SPDX-License-Identifier: GPL-2.0-only
config CARL9170
tristate "Linux Community AR9170 802.11n USB support"
depends on USB && MAC80211
select ATH_COMMON
select FW_LOADER
select CRC32
help
This is the mainline driver for the Atheros "otus" 802.11n USB devices.
It needs a special firmware (carl9170-1.fw), which can be downloaded
from our wiki here:
<https://wireless.wiki.kernel.org/en/users/Drivers/carl9170>
If you choose to build a module, it'll be called carl9170.
config CARL9170_LEDS
bool "SoftLED Support"
default y
depends on CARL9170
depends on MAC80211_LEDS
help
This option is necessary, if you want your device's 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.
@@ -0,0 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-only
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
@@ -0,0 +1,669 @@
/*
* 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 inline u8 ar9170_qmap(u8 idx)
{
return 3 - idx; /* { 3, 2, 1, 0 } */
}
#define CARL9170_MAX_RX_BUFFER_SIZE 8192
enum carl9170_device_state {
CARL9170_UNKNOWN_STATE,
CARL9170_STOPPED,
CARL9170_IDLE,
CARL9170_STARTED,
};
#define WME_BA_BMP_SIZE 64
#define CARL9170_TX_USER_RATE_TRIES 3
#define TID_TO_WME_AC(_tid) \
((((_tid) == 0) || ((_tid) == 3)) ? IEEE80211_AC_BE : \
(((_tid) == 1) || ((_tid) == 2)) ? IEEE80211_AC_BK : \
(((_tid) == 4) || ((_tid) == 5)) ? IEEE80211_AC_VI : \
IEEE80211_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;
struct ieee80211_sta *sta;
struct ieee80211_vif *vif;
};
#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;
bool usb_ep_cmd_is_bulk;
/* 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;
bool ba_filter;
bool disable_offload_fw;
} 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;
bool force_usb_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;
/* 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;
u32 ampdu_ref;
/* FIFO for collecting outstanding BlockAckRequest */
struct list_head bar_list[__AR9170_NUM_TXQ];
spinlock_t bar_list_lock[__AR9170_NUM_TXQ];
#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;
char name[30 + 1];
u16 cache[CARL9170_HWRNG_CACHE_SIZE / sizeof(u16)];
unsigned int cache_idx;
} rng;
#endif /* CONFIG_CARL9170_HWRNG */
/* Must be last as it ends in a flexible-array member. */
union {
__le32 cmd_buf[PAYLOAD_MAX + 1];
struct carl9170_cmd cmd;
struct carl9170_rsp rsp;
};
};
enum carl9170_ps_off_override_reasons {
PS_OFF_VIF = BIT(0),
PS_OFF_BCN = BIT(1),
};
struct carl9170_bar_list_entry {
struct list_head list;
struct rcu_head head;
struct sk_buff *skb;
};
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[IEEE80211_NUM_TIDS];
struct carl9170_ba_stats stats[IEEE80211_NUM_TIDS];
};
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 ieee80211_tx_control *control,
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);
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 carl9170_get_tid(struct sk_buff *skb)
{
return ieee80211_get_tid(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 */
@@ -0,0 +1,222 @@
/*
* 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, &reg, 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_obj(*tmp, 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, 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->time = ar->tally.active;
info->time_busy = ar->tally.cca;
info->time_tx = ar->tally.tx_time;
do_div(info->time, 1000);
do_div(info->time_busy, 1000);
do_div(info->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);
}
@@ -0,0 +1,174 @@
/*
* 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 */
@@ -0,0 +1,882 @@
/*
* 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/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 += scnprintf(&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);
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)
{
const 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 = debugfs_get_aux(file);
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)
{
const 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 = debugfs_get_aux(file);
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;
}
static struct debugfs_short_fops debugfs_fops = {
.read = carl9170_debugfs_read,
.write = carl9170_debugfs_write,
};
#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, \
}
#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, 0400)
#define DEBUGFS_DECLARE_WO_FILE(name) \
DEBUGFS_DECLARE_FILE(name, NULL, carl9170_debugfs_##name ##_write,\
0, 0200)
#define DEBUGFS_DECLARE_RW_FILE(name, _read_bufsize) \
DEBUGFS_DECLARE_FILE(name, carl9170_debugfs_##name ##_read, \
carl9170_debugfs_##name ##_write, \
_read_bufsize, 0600)
#define __DEBUGFS_DECLARE_RW_FILE(name, _read_bufsize, _dstate) \
__DEBUGFS_DECLARE_FILE(name, carl9170_debugfs_##name ##_read, \
carl9170_debugfs_##name ##_write, \
_read_bufsize, 0600, _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)
{
spin_lock_bh(&ar->mem_lock);
ADD(buf, *len, bufsize, "jar: [%*pb]\n",
ar->fw.mem_blocks, ar->mem_bitmap);
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: [%*pb,W]\n",
CARL9170_BAW_BITS, iter->bitmap);
#define BM_STR_OFF(offset) \
((CARL9170_BAW_BITS - (offset) - 1) / 4 + \
(CARL9170_BAW_BITS - (offset) - 1) / 32 + 1)
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: [%*pb]\n",
ar->fw.vif_num, &ar->vif_bitmap);
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", &reg, &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.chandef.chan,
cfg80211_get_chandef_type(&ar->hw->conf.chandef));
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", &reg, &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_aux(#name, carl_debugfs_##name ##_ops.attr, \
ar->debug_dir, ar, &carl_debugfs_##name ## _ops, \
&debugfs_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);
}
@@ -0,0 +1,134 @@
/*
* 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 */
@@ -0,0 +1,216 @@
/*
* 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 */
@@ -0,0 +1,431 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Atheros CARL9170 driver
*
* firmware parser
*
* Copyright 2009, 2010, Christian Lamparter <chunkeey@googlemail.com>
*/
#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"
static const u8 otus_magic[4] __nonstring = { 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));
strscpy(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 void carl9170_fw_set_if_combinations(struct ar9170 *ar,
u16 if_comb_types)
{
if (ar->fw.vif_num < 2)
return;
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);
}
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->fw.disable_offload_fw = true;
}
if (SUPP(CARL9170FW_PSM) && SUPP(CARL9170FW_FIXED_5GHZ_PSM))
ieee80211_hw_set(ar->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;
}
if (SUPP(CARL9170FW_HW_COUNTERS))
ar->fw.hw_counters = true;
if (SUPP(CARL9170FW_WOL))
device_set_wakeup_enable(&ar->udev->dev, true);
if (SUPP(CARL9170FW_RX_BA_FILTER))
ar->fw.ba_filter = 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);
#ifdef CONFIG_MAC80211_MESH
if_comb_types |=
BIT(NL80211_IFTYPE_MESH_POINT);
#endif /* CONFIG_MAC80211_MESH */
}
}
carl9170_fw_set_if_combinations(ar, if_comb_types);
ar->hw->wiphy->interface_modes |= if_comb_types;
ar->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
/* As IBSS Encryption is software-based, IBSS RSN is supported. */
ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
WIPHY_FLAG_IBSS_RSN | WIPHY_FLAG_SUPPORTS_TDLS;
#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;
}
@@ -0,0 +1,334 @@
/*
* 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,
CARL9170_CMD_WREGB = 0x0a,
/* 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 {
DECLARE_FLEX_ARRAY(struct {
__le32 addr;
__le32 val;
} __packed, regs);
} __packed;
struct carl9170_write_reg_byte {
__le32 addr;
__le32 count;
u8 val[];
} __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
/*
* Note: If a bit in rx_filter is set, then it
* means that the particular frames which matches
* the condition are FILTERED/REMOVED/DISCARDED!
* (This is can be a bit confusing, especially
* because someone people think it's the exact
* opposite way, so watch out!)
*/
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_write_reg_byte wregb;
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 __aligned(4);
} __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__
DECLARE_FLEX_ARRAY(struct carl9170_tx_status, tx_status);
#endif /* __CARL9170FW__ */
DECLARE_FLEX_ARRAY(struct _carl9170_tx_status, _tx_status);
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 */
@@ -0,0 +1,271 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Shared CARL9170 Header
*
* Firmware descriptor format
*
* Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com>
*/
#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,
/* Firmware will pass BA when BARs are queued */
CARL9170FW_RX_BA_FILTER,
/* Firmware has support to write a byte at a time */
CARL9170FW_HAS_WREGB_CMD,
/* Pattern generator */
CARL9170FW_PATTERN_GENERATOR,
/* 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[];
} __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 */
@@ -0,0 +1,884 @@
/*
* 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 (512 - 32)
#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_SPI_REG_BASE (AR9170_MC_REG_BASE + 0x200)
#define AR9170_SPI_REG_CONTROL0 (AR9170_SPI_REG_BASE + 0x000)
#define AR9170_SPI_CONTROL0_BUSY BIT(0)
#define AR9170_SPI_CONTROL0_CMD_GO BIT(1)
#define AR9170_SPI_CONTROL0_PAGE_WR BIT(2)
#define AR9170_SPI_CONTROL0_SEQ_RD BIT(3)
#define AR9170_SPI_CONTROL0_CMD_ABORT BIT(4)
#define AR9170_SPI_CONTROL0_CMD_LEN_S 8
#define AR9170_SPI_CONTROL0_CMD_LEN 0x00000f00
#define AR9170_SPI_CONTROL0_RD_LEN_S 12
#define AR9170_SPI_CONTROL0_RD_LEN 0x00007000
#define AR9170_SPI_REG_CONTROL1 (AR9170_SPI_REG_BASE + 0x004)
#define AR9170_SPI_CONTROL1_SCK_RATE BIT(0)
#define AR9170_SPI_CONTROL1_DRIVE_SDO BIT(1)
#define AR9170_SPI_CONTROL1_MODE_SEL_S 2
#define AR9170_SPI_CONTROL1_MODE_SEL 0x000000c0
#define AR9170_SPI_CONTROL1_WRITE_PROTECT BIT(4)
#define AR9170_SPI_REG_COMMAND_PORT0 (AR9170_SPI_REG_BASE + 0x008)
#define AR9170_SPI_COMMAND_PORT0_CMD0_S 0
#define AR9170_SPI_COMMAND_PORT0_CMD0 0x000000ff
#define AR9170_SPI_COMMAND_PORT0_CMD1_S 8
#define AR9170_SPI_COMMAND_PORT0_CMD1 0x0000ff00
#define AR9170_SPI_COMMAND_PORT0_CMD2_S 16
#define AR9170_SPI_COMMAND_PORT0_CMD2 0x00ff0000
#define AR9170_SPI_COMMAND_PORT0_CMD3_S 24
#define AR9170_SPI_COMMAND_PORT0_CMD3 0xff000000
#define AR9170_SPI_REG_COMMAND_PORT1 (AR9170_SPI_REG_BASE + 0x00C)
#define AR9170_SPI_COMMAND_PORT1_CMD4_S 0
#define AR9170_SPI_COMMAND_PORT1_CMD4 0x000000ff
#define AR9170_SPI_COMMAND_PORT1_CMD5_S 8
#define AR9170_SPI_COMMAND_PORT1_CMD5 0x0000ff00
#define AR9170_SPI_COMMAND_PORT1_CMD6_S 16
#define AR9170_SPI_COMMAND_PORT1_CMD6 0x00ff0000
#define AR9170_SPI_COMMAND_PORT1_CMD7_S 24
#define AR9170_SPI_COMMAND_PORT1_CMD7 0xff000000
#define AR9170_SPI_REG_DATA_PORT (AR9170_SPI_REG_BASE + 0x010)
#define AR9170_SPI_REG_PAGE_WRITE_LEN (AR9170_SPI_REG_BASE + 0x014)
#define AR9170_EEPROM_REG_BASE (AR9170_MC_REG_BASE + 0x400)
#define AR9170_EEPROM_REG_WP_MAGIC1 (AR9170_EEPROM_REG_BASE + 0x000)
#define AR9170_EEPROM_WP_MAGIC1 0x12345678
#define AR9170_EEPROM_REG_WP_MAGIC2 (AR9170_EEPROM_REG_BASE + 0x004)
#define AR9170_EEPROM_WP_MAGIC2 0x55aa00ff
#define AR9170_EEPROM_REG_WP_MAGIC3 (AR9170_EEPROM_REG_BASE + 0x008)
#define AR9170_EEPROM_WP_MAGIC3 0x13579ace
#define AR9170_EEPROM_REG_CLOCK_DIV (AR9170_EEPROM_REG_BASE + 0x00C)
#define AR9170_EEPROM_CLOCK_DIV_FAC_S 0
#define AR9170_EEPROM_CLOCK_DIV_FAC 0x000001ff
#define AR9170_EEPROM_CLOCK_DIV_FAC_39KHZ 0xff
#define AR9170_EEPROM_CLOCK_DIV_FAC_78KHZ 0x7f
#define AR9170_EEPROM_CLOCK_DIV_FAC_312KHZ 0x1f
#define AR9170_EEPROM_CLOCK_DIV_FAC_10MHZ 0x0
#define AR9170_EEPROM_CLOCK_DIV_SOFT_RST BIT(9)
#define AR9170_EEPROM_REG_MODE (AR9170_EEPROM_REG_BASE + 0x010)
#define AR9170_EEPROM_MODE_EEPROM_SIZE_16K_PLUS BIT(31)
#define AR9170_EEPROM_REG_WRITE_PROTECT (AR9170_EEPROM_REG_BASE + 0x014)
#define AR9170_EEPROM_WRITE_PROTECT_WP_STATUS BIT(0)
#define AR9170_EEPROM_WRITE_PROTECT_WP_SET BIT(8)
/* 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_STALL 0x8
#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_STALL 0x8
#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[];
} __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 */
@@ -0,0 +1,190 @@
/*
* 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,
const 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 */
@@ -0,0 +1,534 @@
/*
* 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 <linux/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.chandef.chan->band == NL80211_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.chandef.chan->band == NL80211_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.chandef.chan->band == NL80211_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.chandef.chan->band == NL80211_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 |
AR9170_MAC_ENCRYPTION_MGMT_RX_SOFTWARE;
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_ADHOC:
cam_mode |= AR9170_MAC_CAM_IBSS;
break;
case NL80211_IFTYPE_MESH_POINT:
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_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 {
/*
* Enable monitor mode
*
* rx_ctrl |= AR9170_MAC_RX_CTRL_ACK_IN_SNIFFER;
* sniffer |= AR9170_MAC_SNIFFER_ENABLE_PROMISC;
*
* When the hardware is in SNIFFER_PROMISC mode,
* it generates spurious ACKs for every incoming
* frame. This confuses every peer in the
* vicinity and the network throughput will suffer
* badly.
*
* Hence, the hardware will be put into station
* mode and just the rx filters are disabled.
*/
cam_mode |= AR9170_MAC_CAM_STA;
rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST;
mac_addr = common->macaddr;
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) {
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 NL80211_BAND_2GHZ:
power = ar->power_2G_ofdm[0] & 0x3f;
break;
case NL80211_BAND_5GHZ:
power = ar->power_5G_leg[0] & 0x3f;
break;
default:
BUG();
}
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();
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,564 @@
/*
* 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 */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __CARL9170_SHARED_VERSION_H
#define __CARL9170_SHARED_VERSION_H
#define CARL9170FW_VERSION_YEAR 16
#define CARL9170FW_VERSION_MONTH 2
#define CARL9170FW_VERSION_DAY 15
#define CARL9170FW_VERSION_GIT "1.9.9"
#endif /* __CARL9170_SHARED_VERSION_H */
@@ -0,0 +1,435 @@
/*
* 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;
DECLARE_FLEX_ARRAY(u8, payload);
} 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[];
} __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 __packed __aligned(2);
struct ar9170_rx_phystatus phy_tail;
struct ar9170_rx_macstatus macstatus;
};
struct ar9170_rx_frame_head {
struct ar9170_rx_head phy_head;
struct ieee80211_hdr i3e __packed __aligned(2);
struct ar9170_rx_macstatus macstatus;
};
struct ar9170_rx_frame_middle {
struct ieee80211_hdr i3e __packed __aligned(2);
struct ar9170_rx_macstatus macstatus;
};
struct ar9170_rx_frame_tail {
struct ieee80211_hdr i3e __packed __aligned(2);
struct ar9170_rx_phystatus phy_tail;
struct ar9170_rx_macstatus macstatus;
};
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;
};
};
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 */