提交 9687c637 编写于 作者: D David S. Miller
...@@ -433,8 +433,18 @@ ...@@ -433,8 +433,18 @@
Insert notes about VLAN interfaces with hw crypto here or Insert notes about VLAN interfaces with hw crypto here or
in the hw crypto chapter. in the hw crypto chapter.
</para> </para>
<section id="ps-client">
<title>support for powersaving clients</title>
!Pinclude/net/mac80211.h AP support for powersaving clients
</section>
!Finclude/net/mac80211.h ieee80211_get_buffered_bc !Finclude/net/mac80211.h ieee80211_get_buffered_bc
!Finclude/net/mac80211.h ieee80211_beacon_get !Finclude/net/mac80211.h ieee80211_beacon_get
!Finclude/net/mac80211.h ieee80211_sta_eosp_irqsafe
!Finclude/net/mac80211.h ieee80211_frame_release_type
!Finclude/net/mac80211.h ieee80211_sta_ps_transition
!Finclude/net/mac80211.h ieee80211_sta_ps_transition_ni
!Finclude/net/mac80211.h ieee80211_sta_set_buffered
!Finclude/net/mac80211.h ieee80211_sta_block_awake
</chapter> </chapter>
<chapter id="multi-iface"> <chapter id="multi-iface">
...@@ -460,7 +470,6 @@ ...@@ -460,7 +470,6 @@
!Finclude/net/mac80211.h sta_notify_cmd !Finclude/net/mac80211.h sta_notify_cmd
!Finclude/net/mac80211.h ieee80211_find_sta !Finclude/net/mac80211.h ieee80211_find_sta
!Finclude/net/mac80211.h ieee80211_find_sta_by_ifaddr !Finclude/net/mac80211.h ieee80211_find_sta_by_ifaddr
!Finclude/net/mac80211.h ieee80211_sta_block_awake
</chapter> </chapter>
<chapter id="hardware-scan-offload"> <chapter id="hardware-scan-offload">
......
...@@ -594,9 +594,18 @@ Why: In 3.0, we can now autodetect internal 3G device and already have ...@@ -594,9 +594,18 @@ Why: In 3.0, we can now autodetect internal 3G device and already have
Who: Lee, Chun-Yi <jlee@novell.com> Who: Lee, Chun-Yi <jlee@novell.com>
---------------------------- ----------------------------
What: The XFS nodelaylog mount option What: The XFS nodelaylog mount option
When: 3.3 When: 3.3
Why: The delaylog mode that has been the default since 2.6.39 has proven Why: The delaylog mode that has been the default since 2.6.39 has proven
stable, and the old code is in the way of additional improvements in stable, and the old code is in the way of additional improvements in
the log code. the log code.
Who: Christoph Hellwig <hch@lst.de> Who: Christoph Hellwig <hch@lst.de>
----------------------------
What: iwlagn alias support
When: 3.5
Why: The iwlagn module has been renamed iwlwifi. The alias will be around
for backward compatibility for several cycles and then dropped.
Who: Don Fry <donald.h.fry@intel.com>
...@@ -60,6 +60,9 @@ static struct usb_device_id btusb_table[] = { ...@@ -60,6 +60,9 @@ static struct usb_device_id btusb_table[] = {
/* Generic Bluetooth USB device */ /* Generic Bluetooth USB device */
{ USB_DEVICE_INFO(0xe0, 0x01, 0x01) }, { USB_DEVICE_INFO(0xe0, 0x01, 0x01) },
/* Broadcom SoftSailing reporting vendor specific */
{ USB_DEVICE(0x05ac, 0x21e1) },
/* Apple MacBookPro 7,1 */ /* Apple MacBookPro 7,1 */
{ USB_DEVICE(0x05ac, 0x8213) }, { USB_DEVICE(0x05ac, 0x8213) },
...@@ -708,8 +711,7 @@ static int btusb_send_frame(struct sk_buff *skb) ...@@ -708,8 +711,7 @@ static int btusb_send_frame(struct sk_buff *skb)
break; break;
case HCI_ACLDATA_PKT: case HCI_ACLDATA_PKT:
if (!data->bulk_tx_ep || (hdev->conn_hash.acl_num < 1 && if (!data->bulk_tx_ep)
hdev->conn_hash.le_num < 1))
return -ENODEV; return -ENODEV;
urb = usb_alloc_urb(0, GFP_ATOMIC); urb = usb_alloc_urb(0, GFP_ATOMIC);
......
...@@ -41,7 +41,7 @@ obj-$(CONFIG_ADM8211) += adm8211.o ...@@ -41,7 +41,7 @@ obj-$(CONFIG_ADM8211) += adm8211.o
obj-$(CONFIG_MWL8K) += mwl8k.o obj-$(CONFIG_MWL8K) += mwl8k.o
obj-$(CONFIG_IWLAGN) += iwlwifi/ obj-$(CONFIG_IWLWIFI) += iwlwifi/
obj-$(CONFIG_IWLWIFI_LEGACY) += iwlegacy/ obj-$(CONFIG_IWLWIFI_LEGACY) += iwlegacy/
obj-$(CONFIG_RT2X00) += rt2x00/ obj-$(CONFIG_RT2X00) += rt2x00/
......
...@@ -500,10 +500,9 @@ static int at76_usbdfu_download(struct usb_device *udev, u8 *buf, u32 size, ...@@ -500,10 +500,9 @@ static int at76_usbdfu_download(struct usb_device *udev, u8 *buf, u32 size,
#define HEX2STR_BUFFERS 4 #define HEX2STR_BUFFERS 4
#define HEX2STR_MAX_LEN 64 #define HEX2STR_MAX_LEN 64
#define BIN2HEX(x) ((x) < 10 ? '0' + (x) : (x) + 'A' - 10)
/* Convert binary data into hex string */ /* Convert binary data into hex string */
static char *hex2str(void *buf, int len) static char *hex2str(void *buf, size_t len)
{ {
static atomic_t a = ATOMIC_INIT(0); static atomic_t a = ATOMIC_INIT(0);
static char bufs[HEX2STR_BUFFERS][3 * HEX2STR_MAX_LEN + 1]; static char bufs[HEX2STR_BUFFERS][3 * HEX2STR_MAX_LEN + 1];
...@@ -514,18 +513,17 @@ static char *hex2str(void *buf, int len) ...@@ -514,18 +513,17 @@ static char *hex2str(void *buf, int len)
if (len > HEX2STR_MAX_LEN) if (len > HEX2STR_MAX_LEN)
len = HEX2STR_MAX_LEN; len = HEX2STR_MAX_LEN;
if (len <= 0) { if (len == 0)
ret[0] = '\0'; goto exit;
return ret;
}
while (len--) { while (len--) {
*obuf++ = BIN2HEX(*ibuf >> 4); obuf = pack_hex_byte(obuf, *ibuf++);
*obuf++ = BIN2HEX(*ibuf & 0xf);
*obuf++ = '-'; *obuf++ = '-';
ibuf++;
} }
*(--obuf) = '\0'; obuf--;
exit:
*obuf = '\0';
return ret; return ret;
} }
......
...@@ -563,7 +563,7 @@ ath5k_get_stats(struct ieee80211_hw *hw, ...@@ -563,7 +563,7 @@ ath5k_get_stats(struct ieee80211_hw *hw,
static int static int
ath5k_conf_tx(struct ieee80211_hw *hw, u16 queue, ath5k_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue,
const struct ieee80211_tx_queue_params *params) const struct ieee80211_tx_queue_params *params)
{ {
struct ath5k_hw *ah = hw->priv; struct ath5k_hw *ah = hw->priv;
......
...@@ -31,5 +31,7 @@ ath6kl-y += init.o ...@@ -31,5 +31,7 @@ ath6kl-y += init.o
ath6kl-y += main.o ath6kl-y += main.o
ath6kl-y += txrx.o ath6kl-y += txrx.o
ath6kl-y += wmi.o ath6kl-y += wmi.o
ath6kl-y += node.o
ath6kl-y += sdio.o ath6kl-y += sdio.o
ath6kl-$(CONFIG_NL80211_TESTMODE) += testmode.o
ccflags-y += -D__CHECK_ENDIAN__
...@@ -62,14 +62,14 @@ static int ath6kl_get_bmi_cmd_credits(struct ath6kl *ar) ...@@ -62,14 +62,14 @@ static int ath6kl_get_bmi_cmd_credits(struct ath6kl *ar)
return 0; return 0;
} }
static int ath6kl_bmi_get_rx_lkahd(struct ath6kl *ar, bool need_timeout) static int ath6kl_bmi_get_rx_lkahd(struct ath6kl *ar)
{ {
unsigned long timeout; unsigned long timeout;
u32 rx_word = 0; u32 rx_word = 0;
int ret = 0; int ret = 0;
timeout = jiffies + msecs_to_jiffies(BMI_COMMUNICATION_TIMEOUT); timeout = jiffies + msecs_to_jiffies(BMI_COMMUNICATION_TIMEOUT);
while ((!need_timeout || time_before(jiffies, timeout)) && !rx_word) { while (time_before(jiffies, timeout) && !rx_word) {
ret = hif_read_write_sync(ar, RX_LOOKAHEAD_VALID_ADDRESS, ret = hif_read_write_sync(ar, RX_LOOKAHEAD_VALID_ADDRESS,
(u8 *)&rx_word, sizeof(rx_word), (u8 *)&rx_word, sizeof(rx_word),
HIF_RD_SYNC_BYTE_INC); HIF_RD_SYNC_BYTE_INC);
...@@ -109,8 +109,7 @@ static int ath6kl_bmi_send_buf(struct ath6kl *ar, u8 *buf, u32 len) ...@@ -109,8 +109,7 @@ static int ath6kl_bmi_send_buf(struct ath6kl *ar, u8 *buf, u32 len)
return ret; return ret;
} }
static int ath6kl_bmi_recv_buf(struct ath6kl *ar, static int ath6kl_bmi_recv_buf(struct ath6kl *ar, u8 *buf, u32 len)
u8 *buf, u32 len, bool want_timeout)
{ {
int ret; int ret;
u32 addr; u32 addr;
...@@ -162,7 +161,7 @@ static int ath6kl_bmi_recv_buf(struct ath6kl *ar, ...@@ -162,7 +161,7 @@ static int ath6kl_bmi_recv_buf(struct ath6kl *ar,
* a function of Host processor speed. * a function of Host processor speed.
*/ */
if (len >= 4) { /* NB: Currently, always true */ if (len >= 4) { /* NB: Currently, always true */
ret = ath6kl_bmi_get_rx_lkahd(ar, want_timeout); ret = ath6kl_bmi_get_rx_lkahd(ar);
if (ret) if (ret)
return ret; return ret;
} }
...@@ -220,7 +219,7 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar, ...@@ -220,7 +219,7 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar,
} }
ret = ath6kl_bmi_recv_buf(ar, (u8 *)&targ_info->version, ret = ath6kl_bmi_recv_buf(ar, (u8 *)&targ_info->version,
sizeof(targ_info->version), true); sizeof(targ_info->version));
if (ret) { if (ret) {
ath6kl_err("Unable to recv target info: %d\n", ret); ath6kl_err("Unable to recv target info: %d\n", ret);
return ret; return ret;
...@@ -230,8 +229,7 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar, ...@@ -230,8 +229,7 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar,
/* Determine how many bytes are in the Target's targ_info */ /* Determine how many bytes are in the Target's targ_info */
ret = ath6kl_bmi_recv_buf(ar, ret = ath6kl_bmi_recv_buf(ar,
(u8 *)&targ_info->byte_count, (u8 *)&targ_info->byte_count,
sizeof(targ_info->byte_count), sizeof(targ_info->byte_count));
true);
if (ret) { if (ret) {
ath6kl_err("unable to read target info byte count: %d\n", ath6kl_err("unable to read target info byte count: %d\n",
ret); ret);
...@@ -252,8 +250,7 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar, ...@@ -252,8 +250,7 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar,
((u8 *)targ_info) + ((u8 *)targ_info) +
sizeof(targ_info->byte_count), sizeof(targ_info->byte_count),
sizeof(*targ_info) - sizeof(*targ_info) -
sizeof(targ_info->byte_count), sizeof(targ_info->byte_count));
true);
if (ret) { if (ret) {
ath6kl_err("Unable to read target info (%d bytes): %d\n", ath6kl_err("Unable to read target info (%d bytes): %d\n",
...@@ -311,7 +308,7 @@ int ath6kl_bmi_read(struct ath6kl *ar, u32 addr, u8 *buf, u32 len) ...@@ -311,7 +308,7 @@ int ath6kl_bmi_read(struct ath6kl *ar, u32 addr, u8 *buf, u32 len)
ret); ret);
return ret; return ret;
} }
ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, rx_len, true); ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, rx_len);
if (ret) { if (ret) {
ath6kl_err("Unable to read from the device: %d\n", ath6kl_err("Unable to read from the device: %d\n",
ret); ret);
...@@ -424,7 +421,7 @@ int ath6kl_bmi_execute(struct ath6kl *ar, u32 addr, u32 *param) ...@@ -424,7 +421,7 @@ int ath6kl_bmi_execute(struct ath6kl *ar, u32 addr, u32 *param)
return ret; return ret;
} }
ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, sizeof(*param), false); ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, sizeof(*param));
if (ret) { if (ret) {
ath6kl_err("Unable to read from the device: %d\n", ret); ath6kl_err("Unable to read from the device: %d\n", ret);
return ret; return ret;
...@@ -504,7 +501,7 @@ int ath6kl_bmi_reg_read(struct ath6kl *ar, u32 addr, u32 *param) ...@@ -504,7 +501,7 @@ int ath6kl_bmi_reg_read(struct ath6kl *ar, u32 addr, u32 *param)
return ret; return ret;
} }
ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, sizeof(*param), true); ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, sizeof(*param));
if (ret) { if (ret) {
ath6kl_err("Unable to read from the device: %d\n", ret); ath6kl_err("Unable to read from the device: %d\n", ret);
return ret; return ret;
......
...@@ -139,8 +139,8 @@ ...@@ -139,8 +139,8 @@
*/ */
#define TARGET_VERSION_SENTINAL 0xffffffff #define TARGET_VERSION_SENTINAL 0xffffffff
#define TARGET_TYPE_AR6003 3 #define TARGET_TYPE_AR6003 3
#define TARGET_TYPE_AR6004 5
#define BMI_ROMPATCH_INSTALL 9 #define BMI_ROMPATCH_INSTALL 9
/* /*
* Semantics: Install a ROM Patch. * Semantics: Install a ROM Patch.
......
...@@ -75,94 +75,11 @@ enum crypto_type { ...@@ -75,94 +75,11 @@ enum crypto_type {
AES_CRYPT = 0x08, AES_CRYPT = 0x08,
}; };
#define ATH6KL_NODE_HASHSIZE 32
/* simple hash is enough for variation of macaddr */
#define ATH6KL_NODE_HASH(addr) \
(((const u8 *)(addr))[ETH_ALEN - 1] % \
ATH6KL_NODE_HASHSIZE)
/*
* Table of ath6kl_node instances. Each ieee80211com
* has at least one for holding the scan candidates.
* When operating as an access point or in ibss mode there
* is a second table for associated stations or neighbors.
*/
struct ath6kl_node_table {
spinlock_t nt_nodelock; /* on node table */
struct bss *nt_node_first; /* information of all nodes */
struct bss *nt_node_last; /* information of all nodes */
struct bss *nt_hash[ATH6KL_NODE_HASHSIZE];
const char *nt_name; /* for debugging */
u32 nt_node_age; /* node aging time */
};
#define WLAN_NODE_INACT_TIMEOUT_MSEC 120000
#define WLAN_NODE_INACT_CNT 4
struct ath6kl_common_ie {
u16 ie_chan;
u8 *ie_tstamp;
u8 *ie_ssid;
u8 *ie_rates;
u8 *ie_xrates;
u8 *ie_country;
u8 *ie_wpa;
u8 *ie_rsn;
u8 *ie_wmm;
u8 *ie_ath;
u16 ie_capInfo;
u16 ie_beaconInt;
u8 *ie_tim;
u8 *ie_chswitch;
u8 ie_erp;
u8 *ie_wsc;
u8 *ie_htcap;
u8 *ie_htop;
};
struct bss {
u8 ni_macaddr[ETH_ALEN];
u8 ni_snr;
s16 ni_rssi;
struct bss *ni_list_next;
struct bss *ni_list_prev;
struct bss *ni_hash_next;
struct bss *ni_hash_prev;
struct ath6kl_common_ie ni_cie;
u8 *ni_buf;
u16 ni_framelen;
struct ath6kl_node_table *ni_table;
u32 ni_refcnt;
u32 ni_tstamp;
u32 ni_actcnt;
};
struct htc_endpoint_credit_dist; struct htc_endpoint_credit_dist;
struct ath6kl; struct ath6kl;
enum htc_credit_dist_reason; enum htc_credit_dist_reason;
struct htc_credit_state_info; struct htc_credit_state_info;
struct bss *wlan_node_alloc(int wh_size);
void wlan_node_free(struct bss *ni);
void wlan_setup_node(struct ath6kl_node_table *nt, struct bss *ni,
const u8 *mac_addr);
struct bss *wlan_find_node(struct ath6kl_node_table *nt,
const u8 *mac_addr);
void wlan_node_reclaim(struct ath6kl_node_table *nt, struct bss *ni);
void wlan_free_allnodes(struct ath6kl_node_table *nt);
void wlan_iterate_nodes(struct ath6kl_node_table *nt, void *arg);
void wlan_node_table_init(struct ath6kl_node_table *nt);
void wlan_node_table_cleanup(struct ath6kl_node_table *nt);
void wlan_refresh_inactive_nodes(struct ath6kl *ar);
struct bss *wlan_find_ssid_node(struct ath6kl_node_table *nt, u8 *ssid,
u32 ssid_len, bool is_wpa2, bool match_ssid);
void wlan_node_return(struct ath6kl_node_table *nt, struct bss *ni);
int ath6k_setup_credit_dist(void *htc_handle, int ath6k_setup_credit_dist(void *htc_handle,
struct htc_credit_state_info *cred_info); struct htc_credit_state_info *cred_info);
void ath6k_credit_distribute(struct htc_credit_state_info *cred_inf, void ath6k_credit_distribute(struct htc_credit_state_info *cred_inf,
......
...@@ -21,10 +21,12 @@ ...@@ -21,10 +21,12 @@
#include <linux/rtnetlink.h> #include <linux/rtnetlink.h>
#include <linux/firmware.h> #include <linux/firmware.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/circ_buf.h>
#include <net/cfg80211.h> #include <net/cfg80211.h>
#include "htc.h" #include "htc.h"
#include "wmi.h" #include "wmi.h"
#include "bmi.h" #include "bmi.h"
#include "target.h"
#define MAX_ATH6KL 1 #define MAX_ATH6KL 1
#define ATH6KL_MAX_RX_BUFFERS 16 #define ATH6KL_MAX_RX_BUFFERS 16
...@@ -42,6 +44,9 @@ ...@@ -42,6 +44,9 @@
#define ATH6KL_MAX_ENDPOINTS 4 #define ATH6KL_MAX_ENDPOINTS 4
#define MAX_NODE_NUM 15 #define MAX_NODE_NUM 15
/* Extra bytes for htc header alignment */
#define ATH6KL_HTC_ALIGN_BYTES 3
/* MAX_HI_COOKIE_NUM are reserved for high priority traffic */ /* MAX_HI_COOKIE_NUM are reserved for high priority traffic */
#define MAX_DEF_COOKIE_NUM 180 #define MAX_DEF_COOKIE_NUM 180
#define MAX_HI_COOKIE_NUM 18 /* 10% of MAX_COOKIE_NUM */ #define MAX_HI_COOKIE_NUM 18 /* 10% of MAX_COOKIE_NUM */
...@@ -53,6 +58,35 @@ ...@@ -53,6 +58,35 @@
#define A_DEFAULT_LISTEN_INTERVAL 100 #define A_DEFAULT_LISTEN_INTERVAL 100
#define A_MAX_WOW_LISTEN_INTERVAL 1000 #define A_MAX_WOW_LISTEN_INTERVAL 1000
/* includes also the null byte */
#define ATH6KL_FIRMWARE_MAGIC "QCA-ATH6KL"
enum ath6kl_fw_ie_type {
ATH6KL_FW_IE_FW_VERSION = 0,
ATH6KL_FW_IE_TIMESTAMP = 1,
ATH6KL_FW_IE_OTP_IMAGE = 2,
ATH6KL_FW_IE_FW_IMAGE = 3,
ATH6KL_FW_IE_PATCH_IMAGE = 4,
ATH6KL_FW_IE_RESERVED_RAM_SIZE = 5,
ATH6KL_FW_IE_CAPABILITIES = 6,
ATH6KL_FW_IE_PATCH_ADDR = 7,
};
enum ath6kl_fw_capability {
ATH6KL_FW_CAPABILITY_HOST_P2P = 0,
/* this needs to be last */
ATH6KL_FW_CAPABILITY_MAX,
};
#define ATH6KL_CAPABILITY_LEN (ALIGN(ATH6KL_FW_CAPABILITY_MAX, 32) / 32)
struct ath6kl_fw_ie {
__le32 id;
__le32 len;
u8 data[0];
};
/* AR6003 1.0 definitions */ /* AR6003 1.0 definitions */
#define AR6003_REV1_VERSION 0x300002ba #define AR6003_REV1_VERSION 0x300002ba
...@@ -61,7 +95,9 @@ ...@@ -61,7 +95,9 @@
#define AR6003_REV2_PATCH_DOWNLOAD_ADDRESS 0x57e910 #define AR6003_REV2_PATCH_DOWNLOAD_ADDRESS 0x57e910
#define AR6003_REV2_OTP_FILE "ath6k/AR6003/hw2.0/otp.bin.z77" #define AR6003_REV2_OTP_FILE "ath6k/AR6003/hw2.0/otp.bin.z77"
#define AR6003_REV2_FIRMWARE_FILE "ath6k/AR6003/hw2.0/athwlan.bin.z77" #define AR6003_REV2_FIRMWARE_FILE "ath6k/AR6003/hw2.0/athwlan.bin.z77"
#define AR6003_REV2_TCMD_FIRMWARE_FILE "ath6k/AR6003/hw2.0/athtcmd_ram.bin"
#define AR6003_REV2_PATCH_FILE "ath6k/AR6003/hw2.0/data.patch.bin" #define AR6003_REV2_PATCH_FILE "ath6k/AR6003/hw2.0/data.patch.bin"
#define AR6003_REV2_FIRMWARE_2_FILE "ath6k/AR6003/hw2.0/fw-2.bin"
#define AR6003_REV2_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.bin" #define AR6003_REV2_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.bin"
#define AR6003_REV2_DEFAULT_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.SD31.bin" #define AR6003_REV2_DEFAULT_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.SD31.bin"
...@@ -69,11 +105,21 @@ ...@@ -69,11 +105,21 @@
#define AR6003_REV3_VERSION 0x30000582 #define AR6003_REV3_VERSION 0x30000582
#define AR6003_REV3_OTP_FILE "ath6k/AR6003/hw2.1.1/otp.bin" #define AR6003_REV3_OTP_FILE "ath6k/AR6003/hw2.1.1/otp.bin"
#define AR6003_REV3_FIRMWARE_FILE "ath6k/AR6003/hw2.1.1/athwlan.bin" #define AR6003_REV3_FIRMWARE_FILE "ath6k/AR6003/hw2.1.1/athwlan.bin"
#define AR6003_REV3_TCMD_FIRMWARE_FILE "ath6k/AR6003/hw2.1.1/athtcmd_ram.bin"
#define AR6003_REV3_PATCH_FILE "ath6k/AR6003/hw2.1.1/data.patch.bin" #define AR6003_REV3_PATCH_FILE "ath6k/AR6003/hw2.1.1/data.patch.bin"
#define AR6003_REV3_FIRMWARE_2_FILE "ath6k/AR6003/hw2.1.1/fw-2.bin"
#define AR6003_REV3_BOARD_DATA_FILE "ath6k/AR6003/hw2.1.1/bdata.bin" #define AR6003_REV3_BOARD_DATA_FILE "ath6k/AR6003/hw2.1.1/bdata.bin"
#define AR6003_REV3_DEFAULT_BOARD_DATA_FILE \ #define AR6003_REV3_DEFAULT_BOARD_DATA_FILE \
"ath6k/AR6003/hw2.1.1/bdata.SD31.bin" "ath6k/AR6003/hw2.1.1/bdata.SD31.bin"
/* AR6004 1.0 definitions */
#define AR6004_REV1_VERSION 0x30000623
#define AR6004_REV1_FIRMWARE_FILE "ath6k/AR6004/hw6.1/fw.ram.bin"
#define AR6004_REV1_FIRMWARE_2_FILE "ath6k/AR6004/hw6.1/fw-2.bin"
#define AR6004_REV1_BOARD_DATA_FILE "ath6k/AR6004/hw6.1/bdata.bin"
#define AR6004_REV1_DEFAULT_BOARD_DATA_FILE "ath6k/AR6004/hw6.1/bdata.DB132.bin"
#define AR6004_REV1_EPPING_FIRMWARE_FILE "ath6k/AR6004/hw6.1/endpointping.bin"
/* Per STA data, used in AP mode */ /* Per STA data, used in AP mode */
#define STA_PS_AWAKE BIT(0) #define STA_PS_AWAKE BIT(0)
#define STA_PS_SLEEP BIT(1) #define STA_PS_SLEEP BIT(1)
...@@ -325,26 +371,13 @@ struct ath6kl_mbox_info { ...@@ -325,26 +371,13 @@ struct ath6kl_mbox_info {
#define ATH6KL_KEY_RECV 0x02 #define ATH6KL_KEY_RECV 0x02
#define ATH6KL_KEY_DEFAULT 0x80 /* default xmit key */ #define ATH6KL_KEY_DEFAULT 0x80 /* default xmit key */
/* /* Initial group key for AP mode */
* WPA/RSN get/set key request. Specify the key/cipher
* type and whether the key is to be used for sending and/or
* receiving. The key index should be set only when working
* with global keys (use IEEE80211_KEYIX_NONE for ``no index'').
* Otherwise a unicast/pairwise key is specified by the bssid
* (on a station) or mac address (on an ap). They key length
* must include any MIC key data; otherwise it should be no
* more than ATH6KL_KEYBUF_SIZE.
*/
struct ath6kl_req_key { struct ath6kl_req_key {
u8 ik_type; /* key/cipher type */ bool valid;
u8 ik_pad; u8 key_index;
u16 ik_keyix; /* key index */ int key_type;
u8 ik_keylen; /* key length in bytes */ u8 key[WLAN_MAX_KEY_LEN];
u8 ik_flags; u8 key_len;
u8 ik_macaddr[ETH_ALEN];
u64 ik_keyrsc; /* key receive sequence counter */
u64 ik_keytsc; /* key transmit sequence counter */
u8 ik_keydata[ATH6KL_KEYBUF_SIZE + ATH6KL_MICBUF_SIZE];
}; };
/* Flag info */ /* Flag info */
...@@ -361,6 +394,9 @@ struct ath6kl_req_key { ...@@ -361,6 +394,9 @@ struct ath6kl_req_key {
#define NETDEV_REGISTERED 10 #define NETDEV_REGISTERED 10
#define SKIP_SCAN 11 #define SKIP_SCAN 11
#define WLAN_ENABLED 12 #define WLAN_ENABLED 12
#define TESTMODE 13
#define CLEAR_BSSFILTER_ON_BEACON 14
#define DTIM_PERIOD_AVAIL 15
struct ath6kl { struct ath6kl {
struct device *dev; struct device *dev;
...@@ -383,7 +419,7 @@ struct ath6kl { ...@@ -383,7 +419,7 @@ struct ath6kl {
u8 prwise_crypto; u8 prwise_crypto;
u8 prwise_crypto_len; u8 prwise_crypto_len;
u8 grp_crypto; u8 grp_crypto;
u8 grp_crpto_len; u8 grp_crypto_len;
u8 def_txkey_index; u8 def_txkey_index;
struct ath6kl_wep_key wep_key_list[WMI_MAX_KEY_INDEX + 1]; struct ath6kl_wep_key wep_key_list[WMI_MAX_KEY_INDEX + 1];
u8 bssid[ETH_ALEN]; u8 bssid[ETH_ALEN];
...@@ -392,6 +428,7 @@ struct ath6kl { ...@@ -392,6 +428,7 @@ struct ath6kl {
u16 bss_ch; u16 bss_ch;
u16 listen_intvl_b; u16 listen_intvl_b;
u16 listen_intvl_t; u16 listen_intvl_t;
u8 lrssi_roam_threshold;
struct ath6kl_version version; struct ath6kl_version version;
u32 target_type; u32 target_type;
u8 tx_pwr; u8 tx_pwr;
...@@ -432,7 +469,18 @@ struct ath6kl { ...@@ -432,7 +469,18 @@ struct ath6kl {
enum wlan_low_pwr_state wlan_pwr_state; enum wlan_low_pwr_state wlan_pwr_state;
struct wmi_scan_params_cmd sc_params; struct wmi_scan_params_cmd sc_params;
#define AR_MCAST_FILTER_MAC_ADDR_SIZE 4 #define AR_MCAST_FILTER_MAC_ADDR_SIZE 4
u8 auto_auth_stage; struct {
void *rx_report;
size_t rx_report_len;
} tm;
struct {
u32 dataset_patch_addr;
u32 app_load_addr;
u32 app_start_override_addr;
u32 board_ext_data_addr;
u32 reserved_ram_size;
} hw;
u16 conf_flags; u16 conf_flags;
wait_queue_head_t event_wq; wait_queue_head_t event_wq;
...@@ -454,9 +502,35 @@ struct ath6kl { ...@@ -454,9 +502,35 @@ struct ath6kl {
u8 *fw_patch; u8 *fw_patch;
size_t fw_patch_len; size_t fw_patch_len;
unsigned long fw_capabilities[ATH6KL_CAPABILITY_LEN];
struct workqueue_struct *ath6kl_wq; struct workqueue_struct *ath6kl_wq;
struct ath6kl_node_table scan_table; struct dentry *debugfs_phy;
u32 send_action_id;
bool probe_req_report;
u16 next_chan;
bool p2p;
u16 assoc_bss_beacon_int;
u8 assoc_bss_dtim_period;
#ifdef CONFIG_ATH6KL_DEBUG
struct {
struct circ_buf fwlog_buf;
spinlock_t fwlog_lock;
void *fwlog_tmp;
u32 fwlog_mask;
unsigned int dbgfs_diag_reg;
u32 diag_reg_addr_wr;
u32 diag_reg_val_wr;
struct {
unsigned int invalid_rate;
} war_stats;
} debug;
#endif /* CONFIG_ATH6KL_DEBUG */
}; };
static inline void *ath6kl_priv(struct net_device *dev) static inline void *ath6kl_priv(struct net_device *dev)
...@@ -474,6 +548,19 @@ static inline void ath6kl_deposit_credit_to_ep(struct htc_credit_state_info ...@@ -474,6 +548,19 @@ static inline void ath6kl_deposit_credit_to_ep(struct htc_credit_state_info
cred_info->cur_free_credits -= credits; cred_info->cur_free_credits -= credits;
} }
static inline u32 ath6kl_get_hi_item_addr(struct ath6kl *ar,
u32 item_offset)
{
u32 addr = 0;
if (ar->target_type == TARGET_TYPE_AR6003)
addr = ATH6KL_AR6003_HI_START_ADDR + item_offset;
else if (ar->target_type == TARGET_TYPE_AR6004)
addr = ATH6KL_AR6004_HI_START_ADDR + item_offset;
return addr;
}
void ath6kl_destroy(struct net_device *dev, unsigned int unregister); void ath6kl_destroy(struct net_device *dev, unsigned int unregister);
int ath6kl_configure_target(struct ath6kl *ar); int ath6kl_configure_target(struct ath6kl *ar);
void ath6kl_detect_error(unsigned long ptr); void ath6kl_detect_error(unsigned long ptr);
...@@ -487,9 +574,11 @@ enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target, ...@@ -487,9 +574,11 @@ enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target,
struct htc_packet *packet); struct htc_packet *packet);
void ath6kl_stop_txrx(struct ath6kl *ar); void ath6kl_stop_txrx(struct ath6kl *ar);
void ath6kl_cleanup_amsdu_rxbufs(struct ath6kl *ar); void ath6kl_cleanup_amsdu_rxbufs(struct ath6kl *ar);
int ath6kl_access_datadiag(struct ath6kl *ar, u32 address, int ath6kl_diag_write32(struct ath6kl *ar, u32 address, __le32 value);
u8 *data, u32 length, bool read); int ath6kl_diag_write(struct ath6kl *ar, u32 address, void *data, u32 length);
int ath6kl_read_reg_diag(struct ath6kl *ar, u32 *address, u32 *data); int ath6kl_diag_read32(struct ath6kl *ar, u32 address, u32 *value);
int ath6kl_diag_read(struct ath6kl *ar, u32 address, void *data, u32 length);
int ath6kl_read_fwlogs(struct ath6kl *ar);
void ath6kl_init_profile_info(struct ath6kl *ar); void ath6kl_init_profile_info(struct ath6kl *ar);
void ath6kl_tx_data_cleanup(struct ath6kl *ar); void ath6kl_tx_data_cleanup(struct ath6kl *ar);
void ath6kl_stop_endpoint(struct net_device *dev, bool keep_profile, void ath6kl_stop_endpoint(struct net_device *dev, bool keep_profile,
...@@ -520,6 +609,10 @@ void ath6kl_connect_event(struct ath6kl *ar, u16 channel, ...@@ -520,6 +609,10 @@ void ath6kl_connect_event(struct ath6kl *ar, u16 channel,
u16 beacon_int, enum network_type net_type, u16 beacon_int, enum network_type net_type,
u8 beacon_ie_len, u8 assoc_req_len, u8 beacon_ie_len, u8 assoc_req_len,
u8 assoc_resp_len, u8 *assoc_info); u8 assoc_resp_len, u8 *assoc_info);
void ath6kl_connect_ap_mode_bss(struct ath6kl *ar, u16 channel);
void ath6kl_connect_ap_mode_sta(struct ath6kl *ar, u16 aid, u8 *mac_addr,
u8 keymgmt, u8 ucipher, u8 auth,
u8 assoc_req_len, u8 *assoc_info);
void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason, void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason,
u8 *bssid, u8 assoc_resp_len, u8 *bssid, u8 assoc_resp_len,
u8 *assoc_info, u16 prot_reason_status); u8 *assoc_info, u16 prot_reason_status);
...@@ -534,11 +627,11 @@ void ath6kl_pspoll_event(struct ath6kl *ar, u8 aid); ...@@ -534,11 +627,11 @@ void ath6kl_pspoll_event(struct ath6kl *ar, u8 aid);
void ath6kl_dtimexpiry_event(struct ath6kl *ar); void ath6kl_dtimexpiry_event(struct ath6kl *ar);
void ath6kl_disconnect(struct ath6kl *ar); void ath6kl_disconnect(struct ath6kl *ar);
void ath6kl_deep_sleep_enable(struct ath6kl *ar);
void aggr_recv_delba_req_evt(struct ath6kl *ar, u8 tid); void aggr_recv_delba_req_evt(struct ath6kl *ar, u8 tid);
void aggr_recv_addba_req_evt(struct ath6kl *ar, u8 tid, u16 seq_no, void aggr_recv_addba_req_evt(struct ath6kl *ar, u8 tid, u16 seq_no,
u8 win_sz); u8 win_sz);
void ath6kl_wakeup_event(void *dev); void ath6kl_wakeup_event(void *dev);
void ath6kl_target_failure(struct ath6kl *ar); void ath6kl_target_failure(struct ath6kl *ar);
void ath6kl_cfg80211_scan_node(struct wiphy *wiphy, struct bss *ni);
#endif /* CORE_H */ #endif /* CORE_H */
...@@ -34,8 +34,12 @@ enum ATH6K_DEBUG_MASK { ...@@ -34,8 +34,12 @@ enum ATH6K_DEBUG_MASK {
ATH6KL_DBG_TRC = BIT(11), /* generic func tracing */ ATH6KL_DBG_TRC = BIT(11), /* generic func tracing */
ATH6KL_DBG_SCATTER = BIT(12), /* hif scatter tracing */ ATH6KL_DBG_SCATTER = BIT(12), /* hif scatter tracing */
ATH6KL_DBG_WLAN_CFG = BIT(13), /* cfg80211 i/f file tracing */ ATH6KL_DBG_WLAN_CFG = BIT(13), /* cfg80211 i/f file tracing */
ATH6KL_DBG_RAW_BYTES = BIT(14), /* dump tx/rx and wmi frames */ ATH6KL_DBG_RAW_BYTES = BIT(14), /* dump tx/rx frames */
ATH6KL_DBG_AGGR = BIT(15), /* aggregation */ ATH6KL_DBG_AGGR = BIT(15), /* aggregation */
ATH6KL_DBG_SDIO = BIT(16),
ATH6KL_DBG_SDIO_DUMP = BIT(17),
ATH6KL_DBG_BOOT = BIT(18), /* driver init and fw boot */
ATH6KL_DBG_WMI_DUMP = BIT(19),
ATH6KL_DBG_ANY = 0xffffffff /* enable all logs */ ATH6KL_DBG_ANY = 0xffffffff /* enable all logs */
}; };
...@@ -52,6 +56,10 @@ extern int ath6kl_printk(const char *level, const char *fmt, ...) ...@@ -52,6 +56,10 @@ extern int ath6kl_printk(const char *level, const char *fmt, ...)
#define AR_DBG_LVL_CHECK(mask) (debug_mask & mask) #define AR_DBG_LVL_CHECK(mask) (debug_mask & mask)
enum ath6kl_war {
ATH6KL_WAR_INVALID_RATE,
};
#ifdef CONFIG_ATH6KL_DEBUG #ifdef CONFIG_ATH6KL_DEBUG
#define ath6kl_dbg(mask, fmt, ...) \ #define ath6kl_dbg(mask, fmt, ...) \
({ \ ({ \
...@@ -65,12 +73,14 @@ extern int ath6kl_printk(const char *level, const char *fmt, ...) ...@@ -65,12 +73,14 @@ extern int ath6kl_printk(const char *level, const char *fmt, ...)
}) })
static inline void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask, static inline void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask,
const char *msg, const void *buf, const char *msg, const char *prefix,
size_t len) const void *buf, size_t len)
{ {
if (debug_mask & mask) { if (debug_mask & mask) {
ath6kl_dbg(mask, "%s\n", msg); if (msg)
print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, buf, len); ath6kl_dbg(mask, "%s\n", msg);
print_hex_dump_bytes(prefix, DUMP_PREFIX_OFFSET, buf, len);
} }
} }
...@@ -78,6 +88,11 @@ void ath6kl_dump_registers(struct ath6kl_device *dev, ...@@ -78,6 +88,11 @@ void ath6kl_dump_registers(struct ath6kl_device *dev,
struct ath6kl_irq_proc_registers *irq_proc_reg, struct ath6kl_irq_proc_registers *irq_proc_reg,
struct ath6kl_irq_enable_reg *irq_en_reg); struct ath6kl_irq_enable_reg *irq_en_reg);
void dump_cred_dist_stats(struct htc_target *target); void dump_cred_dist_stats(struct htc_target *target);
void ath6kl_debug_fwlog_event(struct ath6kl *ar, const void *buf, size_t len);
void ath6kl_debug_war(struct ath6kl *ar, enum ath6kl_war war);
int ath6kl_debug_init(struct ath6kl *ar);
void ath6kl_debug_cleanup(struct ath6kl *ar);
#else #else
static inline int ath6kl_dbg(enum ATH6K_DEBUG_MASK dbg_mask, static inline int ath6kl_dbg(enum ATH6K_DEBUG_MASK dbg_mask,
const char *fmt, ...) const char *fmt, ...)
...@@ -86,8 +101,8 @@ static inline int ath6kl_dbg(enum ATH6K_DEBUG_MASK dbg_mask, ...@@ -86,8 +101,8 @@ static inline int ath6kl_dbg(enum ATH6K_DEBUG_MASK dbg_mask,
} }
static inline void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask, static inline void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask,
const char *msg, const void *buf, const char *msg, const char *prefix,
size_t len) const void *buf, size_t len)
{ {
} }
...@@ -100,6 +115,24 @@ static inline void ath6kl_dump_registers(struct ath6kl_device *dev, ...@@ -100,6 +115,24 @@ static inline void ath6kl_dump_registers(struct ath6kl_device *dev,
static inline void dump_cred_dist_stats(struct htc_target *target) static inline void dump_cred_dist_stats(struct htc_target *target)
{ {
} }
#endif
static inline void ath6kl_debug_fwlog_event(struct ath6kl *ar,
const void *buf, size_t len)
{
}
static inline void ath6kl_debug_war(struct ath6kl *ar, enum ath6kl_war war)
{
}
static inline int ath6kl_debug_init(struct ath6kl *ar)
{
return 0;
}
static inline void ath6kl_debug_cleanup(struct ath6kl *ar)
{
}
#endif
#endif #endif
...@@ -69,4 +69,9 @@ static inline void ath6kl_hif_cleanup_scatter(struct ath6kl *ar) ...@@ -69,4 +69,9 @@ static inline void ath6kl_hif_cleanup_scatter(struct ath6kl *ar)
return ar->hif_ops->cleanup_scatter(ar); return ar->hif_ops->cleanup_scatter(ar);
} }
static inline int ath6kl_hif_suspend(struct ath6kl *ar)
{
return ar->hif_ops->suspend(ar);
}
#endif #endif
...@@ -202,6 +202,7 @@ struct ath6kl_hif_ops { ...@@ -202,6 +202,7 @@ struct ath6kl_hif_ops {
int (*scat_req_rw) (struct ath6kl *ar, int (*scat_req_rw) (struct ath6kl *ar,
struct hif_scatter_req *scat_req); struct hif_scatter_req *scat_req);
void (*cleanup_scatter)(struct ath6kl *ar); void (*cleanup_scatter)(struct ath6kl *ar);
int (*suspend)(struct ath6kl *ar);
}; };
#endif #endif
...@@ -61,7 +61,8 @@ static void ath6kl_add_new_sta(struct ath6kl *ar, u8 *mac, u16 aid, u8 *wpaie, ...@@ -61,7 +61,8 @@ static void ath6kl_add_new_sta(struct ath6kl *ar, u8 *mac, u16 aid, u8 *wpaie,
sta = &ar->sta_list[free_slot]; sta = &ar->sta_list[free_slot];
memcpy(sta->mac, mac, ETH_ALEN); memcpy(sta->mac, mac, ETH_ALEN);
memcpy(sta->wpa_ie, wpaie, ielen); if (ielen <= ATH6KL_MAX_IE)
memcpy(sta->wpa_ie, wpaie, ielen);
sta->aid = aid; sta->aid = aid;
sta->keymgmt = keymgmt; sta->keymgmt = keymgmt;
sta->ucipher = ucipher; sta->ucipher = ucipher;
...@@ -177,8 +178,8 @@ void ath6kl_free_cookie(struct ath6kl *ar, struct ath6kl_cookie *cookie) ...@@ -177,8 +178,8 @@ void ath6kl_free_cookie(struct ath6kl *ar, struct ath6kl_cookie *cookie)
static int ath6kl_set_addrwin_reg(struct ath6kl *ar, u32 reg_addr, u32 addr) static int ath6kl_set_addrwin_reg(struct ath6kl *ar, u32 reg_addr, u32 addr)
{ {
int status; int status;
u8 addr_val[4];
s32 i; s32 i;
__le32 addr_val;
/* /*
* Write bytes 1,2,3 of the register to set the upper address bytes, * Write bytes 1,2,3 of the register to set the upper address bytes,
...@@ -188,16 +189,18 @@ static int ath6kl_set_addrwin_reg(struct ath6kl *ar, u32 reg_addr, u32 addr) ...@@ -188,16 +189,18 @@ static int ath6kl_set_addrwin_reg(struct ath6kl *ar, u32 reg_addr, u32 addr)
for (i = 1; i <= 3; i++) { for (i = 1; i <= 3; i++) {
/* /*
* Fill the buffer with the address byte value we want to * Fill the buffer with the address byte value we want to
* hit 4 times. * hit 4 times. No need to worry about endianness as the
* same byte is copied to all four bytes of addr_val at
* any time.
*/ */
memset(addr_val, ((u8 *)&addr)[i], 4); memset((u8 *)&addr_val, ((u8 *)&addr)[i], 4);
/* /*
* Hit each byte of the register address with a 4-byte * Hit each byte of the register address with a 4-byte
* write operation to the same address, this is a harmless * write operation to the same address, this is a harmless
* operation. * operation.
*/ */
status = hif_read_write_sync(ar, reg_addr + i, addr_val, status = hif_read_write_sync(ar, reg_addr + i, (u8 *)&addr_val,
4, HIF_WR_SYNC_BYTE_FIX); 4, HIF_WR_SYNC_BYTE_FIX);
if (status) if (status)
break; break;
...@@ -215,7 +218,9 @@ static int ath6kl_set_addrwin_reg(struct ath6kl *ar, u32 reg_addr, u32 addr) ...@@ -215,7 +218,9 @@ static int ath6kl_set_addrwin_reg(struct ath6kl *ar, u32 reg_addr, u32 addr)
* cycle to start, the extra 3 byte write to bytes 1,2,3 has no * cycle to start, the extra 3 byte write to bytes 1,2,3 has no
* effect since we are writing the same values again * effect since we are writing the same values again
*/ */
status = hif_read_write_sync(ar, reg_addr, (u8 *)(&addr), addr_val = cpu_to_le32(addr);
status = hif_read_write_sync(ar, reg_addr,
(u8 *)&(addr_val),
4, HIF_WR_SYNC_BYTE_INC); 4, HIF_WR_SYNC_BYTE_INC);
if (status) { if (status) {
...@@ -228,90 +233,193 @@ static int ath6kl_set_addrwin_reg(struct ath6kl *ar, u32 reg_addr, u32 addr) ...@@ -228,90 +233,193 @@ static int ath6kl_set_addrwin_reg(struct ath6kl *ar, u32 reg_addr, u32 addr)
} }
/* /*
* Read from the ATH6KL through its diagnostic window. No cooperation from * Read from the hardware through its diagnostic window. No cooperation
* the Target is required for this. * from the firmware is required for this.
*/ */
int ath6kl_read_reg_diag(struct ath6kl *ar, u32 *address, u32 *data) int ath6kl_diag_read32(struct ath6kl *ar, u32 address, u32 *value)
{ {
int status; int ret;
/* set window register to start read cycle */ /* set window register to start read cycle */
status = ath6kl_set_addrwin_reg(ar, WINDOW_READ_ADDR_ADDRESS, ret = ath6kl_set_addrwin_reg(ar, WINDOW_READ_ADDR_ADDRESS, address);
*address); if (ret)
return ret;
if (status)
return status;
/* read the data */ /* read the data */
status = hif_read_write_sync(ar, WINDOW_DATA_ADDRESS, (u8 *)data, ret = hif_read_write_sync(ar, WINDOW_DATA_ADDRESS, (u8 *) value,
sizeof(u32), HIF_RD_SYNC_BYTE_INC); sizeof(*value), HIF_RD_SYNC_BYTE_INC);
if (status) { if (ret) {
ath6kl_err("failed to read from window data addr\n"); ath6kl_warn("failed to read32 through diagnose window: %d\n",
return status; ret);
return ret;
} }
return status; return 0;
} }
/* /*
* Write to the ATH6KL through its diagnostic window. No cooperation from * Write to the ATH6KL through its diagnostic window. No cooperation from
* the Target is required for this. * the Target is required for this.
*/ */
static int ath6kl_write_reg_diag(struct ath6kl *ar, u32 *address, u32 *data) int ath6kl_diag_write32(struct ath6kl *ar, u32 address, __le32 value)
{ {
int status; int ret;
/* set write data */ /* set write data */
status = hif_read_write_sync(ar, WINDOW_DATA_ADDRESS, (u8 *)data, ret = hif_read_write_sync(ar, WINDOW_DATA_ADDRESS, (u8 *) &value,
sizeof(u32), HIF_WR_SYNC_BYTE_INC); sizeof(value), HIF_WR_SYNC_BYTE_INC);
if (status) { if (ret) {
ath6kl_err("failed to write 0x%x to window data addr\n", *data); ath6kl_err("failed to write 0x%x during diagnose window to 0x%d\n",
return status; address, value);
return ret;
} }
/* set window register, which starts the write cycle */ /* set window register, which starts the write cycle */
return ath6kl_set_addrwin_reg(ar, WINDOW_WRITE_ADDR_ADDRESS, return ath6kl_set_addrwin_reg(ar, WINDOW_WRITE_ADDR_ADDRESS,
*address); address);
} }
int ath6kl_access_datadiag(struct ath6kl *ar, u32 address, int ath6kl_diag_read(struct ath6kl *ar, u32 address, void *data, u32 length)
u8 *data, u32 length, bool read) {
u32 count, *buf = data;
int ret;
if (WARN_ON(length % 4))
return -EINVAL;
for (count = 0; count < length / 4; count++, address += 4) {
ret = ath6kl_diag_read32(ar, address, &buf[count]);
if (ret)
return ret;
}
return 0;
}
int ath6kl_diag_write(struct ath6kl *ar, u32 address, void *data, u32 length)
{ {
u32 count; u32 count;
int status = 0; __le32 *buf = data;
int ret;
for (count = 0; count < length; count += 4, address += 4) { if (WARN_ON(length % 4))
if (read) { return -EINVAL;
status = ath6kl_read_reg_diag(ar, &address,
(u32 *) &data[count]); for (count = 0; count < length / 4; count++, address += 4) {
if (status) ret = ath6kl_diag_write32(ar, address, buf[count]);
break; if (ret)
} else { return ret;
status = ath6kl_write_reg_diag(ar, &address, }
(u32 *) &data[count]);
if (status) return 0;
break; }
}
int ath6kl_read_fwlogs(struct ath6kl *ar)
{
struct ath6kl_dbglog_hdr debug_hdr;
struct ath6kl_dbglog_buf debug_buf;
u32 address, length, dropped, firstbuf, debug_hdr_addr;
int ret = 0, loop;
u8 *buf;
buf = kmalloc(ATH6KL_FWLOG_PAYLOAD_SIZE, GFP_KERNEL);
if (!buf)
return -ENOMEM;
address = TARG_VTOP(ar->target_type,
ath6kl_get_hi_item_addr(ar,
HI_ITEM(hi_dbglog_hdr)));
ret = ath6kl_diag_read32(ar, address, &debug_hdr_addr);
if (ret)
goto out;
/* Get the contents of the ring buffer */
if (debug_hdr_addr == 0) {
ath6kl_warn("Invalid address for debug_hdr_addr\n");
ret = -EINVAL;
goto out;
} }
return status; address = TARG_VTOP(ar->target_type, debug_hdr_addr);
ath6kl_diag_read(ar, address, &debug_hdr, sizeof(debug_hdr));
address = TARG_VTOP(ar->target_type,
le32_to_cpu(debug_hdr.dbuf_addr));
firstbuf = address;
dropped = le32_to_cpu(debug_hdr.dropped);
ath6kl_diag_read(ar, address, &debug_buf, sizeof(debug_buf));
loop = 100;
do {
address = TARG_VTOP(ar->target_type,
le32_to_cpu(debug_buf.buffer_addr));
length = le32_to_cpu(debug_buf.length);
if (length != 0 && (le32_to_cpu(debug_buf.length) <=
le32_to_cpu(debug_buf.bufsize))) {
length = ALIGN(length, 4);
ret = ath6kl_diag_read(ar, address,
buf, length);
if (ret)
goto out;
ath6kl_debug_fwlog_event(ar, buf, length);
}
address = TARG_VTOP(ar->target_type,
le32_to_cpu(debug_buf.next));
ath6kl_diag_read(ar, address, &debug_buf, sizeof(debug_buf));
if (ret)
goto out;
loop--;
if (WARN_ON(loop == 0)) {
ret = -ETIMEDOUT;
goto out;
}
} while (address != firstbuf);
out:
kfree(buf);
return ret;
} }
/* FIXME: move to a better place, target.h? */
#define AR6003_RESET_CONTROL_ADDRESS 0x00004000
#define AR6004_RESET_CONTROL_ADDRESS 0x00004000
static void ath6kl_reset_device(struct ath6kl *ar, u32 target_type, static void ath6kl_reset_device(struct ath6kl *ar, u32 target_type,
bool wait_fot_compltn, bool cold_reset) bool wait_fot_compltn, bool cold_reset)
{ {
int status = 0; int status = 0;
u32 address; u32 address;
u32 data; __le32 data;
if (target_type != TARGET_TYPE_AR6003) if (target_type != TARGET_TYPE_AR6003 &&
target_type != TARGET_TYPE_AR6004)
return; return;
data = cold_reset ? RESET_CONTROL_COLD_RST : RESET_CONTROL_MBOX_RST; data = cold_reset ? cpu_to_le32(RESET_CONTROL_COLD_RST) :
cpu_to_le32(RESET_CONTROL_MBOX_RST);
address = RTC_BASE_ADDRESS; switch (target_type) {
status = ath6kl_write_reg_diag(ar, &address, &data); case TARGET_TYPE_AR6003:
address = AR6003_RESET_CONTROL_ADDRESS;
break;
case TARGET_TYPE_AR6004:
address = AR6004_RESET_CONTROL_ADDRESS;
break;
default:
address = AR6003_RESET_CONTROL_ADDRESS;
break;
}
status = ath6kl_diag_write32(ar, address, data);
if (status) if (status)
ath6kl_err("failed to reset target\n"); ath6kl_err("failed to reset target\n");
...@@ -411,68 +519,107 @@ static void ath6kl_install_static_wep_keys(struct ath6kl *ar) ...@@ -411,68 +519,107 @@ static void ath6kl_install_static_wep_keys(struct ath6kl *ar)
} }
} }
static void ath6kl_connect_ap_mode(struct ath6kl *ar, u16 channel, u8 *bssid, void ath6kl_connect_ap_mode_bss(struct ath6kl *ar, u16 channel)
u16 listen_int, u16 beacon_int,
u8 assoc_resp_len, u8 *assoc_info)
{ {
struct net_device *dev = ar->net_dev;
struct station_info sinfo;
struct ath6kl_req_key *ik; struct ath6kl_req_key *ik;
enum crypto_type keyType = NONE_CRYPT; int res;
u8 key_rsc[ATH6KL_KEY_SEQ_LEN];
if (memcmp(dev->dev_addr, bssid, ETH_ALEN) == 0) { ik = &ar->ap_mode_bkey;
ik = &ar->ap_mode_bkey;
switch (ar->auth_mode) { ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "AP mode started on %u MHz\n", channel);
case NONE_AUTH:
if (ar->prwise_crypto == WEP_CRYPT) switch (ar->auth_mode) {
ath6kl_install_static_wep_keys(ar); case NONE_AUTH:
break; if (ar->prwise_crypto == WEP_CRYPT)
case WPA_PSK_AUTH: ath6kl_install_static_wep_keys(ar);
case WPA2_PSK_AUTH: break;
case (WPA_PSK_AUTH|WPA2_PSK_AUTH): case WPA_PSK_AUTH:
switch (ik->ik_type) { case WPA2_PSK_AUTH:
case ATH6KL_CIPHER_TKIP: case (WPA_PSK_AUTH | WPA2_PSK_AUTH):
keyType = TKIP_CRYPT; if (!ik->valid)
break;
case ATH6KL_CIPHER_AES_CCM:
keyType = AES_CRYPT;
break;
default:
goto skip_key;
}
ath6kl_wmi_addkey_cmd(ar->wmi, ik->ik_keyix, keyType,
GROUP_USAGE, ik->ik_keylen,
(u8 *)&ik->ik_keyrsc,
ik->ik_keydata,
KEY_OP_INIT_VAL, ik->ik_macaddr,
SYNC_BOTH_WMIFLAG);
break; break;
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delayed addkey for "
"the initial group key for AP mode\n");
memset(key_rsc, 0, sizeof(key_rsc));
res = ath6kl_wmi_addkey_cmd(
ar->wmi, ik->key_index, ik->key_type,
GROUP_USAGE, ik->key_len, key_rsc, ik->key,
KEY_OP_INIT_VAL, NULL, SYNC_BOTH_WMIFLAG);
if (res) {
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delayed "
"addkey failed: %d\n", res);
} }
skip_key: break;
set_bit(CONNECTED, &ar->flag);
return;
} }
ath6kl_dbg(ATH6KL_DBG_TRC, "new station %pM aid=%d\n", ath6kl_wmi_bssfilter_cmd(ar->wmi, NONE_BSS_FILTER, 0);
bssid, channel); set_bit(CONNECTED, &ar->flag);
netif_carrier_on(ar->net_dev);
}
void ath6kl_connect_ap_mode_sta(struct ath6kl *ar, u16 aid, u8 *mac_addr,
u8 keymgmt, u8 ucipher, u8 auth,
u8 assoc_req_len, u8 *assoc_info)
{
u8 *ies = NULL, *wpa_ie = NULL, *pos;
size_t ies_len = 0;
struct station_info sinfo;
ath6kl_add_new_sta(ar, bssid, channel, assoc_info, assoc_resp_len, ath6kl_dbg(ATH6KL_DBG_TRC, "new station %pM aid=%d\n", mac_addr, aid);
listen_int & 0xFF, beacon_int,
(listen_int >> 8) & 0xFF); if (assoc_req_len > sizeof(struct ieee80211_hdr_3addr)) {
struct ieee80211_mgmt *mgmt =
(struct ieee80211_mgmt *) assoc_info;
if (ieee80211_is_assoc_req(mgmt->frame_control) &&
assoc_req_len >= sizeof(struct ieee80211_hdr_3addr) +
sizeof(mgmt->u.assoc_req)) {
ies = mgmt->u.assoc_req.variable;
ies_len = assoc_info + assoc_req_len - ies;
} else if (ieee80211_is_reassoc_req(mgmt->frame_control) &&
assoc_req_len >= sizeof(struct ieee80211_hdr_3addr)
+ sizeof(mgmt->u.reassoc_req)) {
ies = mgmt->u.reassoc_req.variable;
ies_len = assoc_info + assoc_req_len - ies;
}
}
pos = ies;
while (pos && pos + 1 < ies + ies_len) {
if (pos + 2 + pos[1] > ies + ies_len)
break;
if (pos[0] == WLAN_EID_RSN)
wpa_ie = pos; /* RSN IE */
else if (pos[0] == WLAN_EID_VENDOR_SPECIFIC &&
pos[1] >= 4 &&
pos[2] == 0x00 && pos[3] == 0x50 && pos[4] == 0xf2) {
if (pos[5] == 0x01)
wpa_ie = pos; /* WPA IE */
else if (pos[5] == 0x04) {
wpa_ie = pos; /* WPS IE */
break; /* overrides WPA/RSN IE */
}
}
pos += 2 + pos[1];
}
ath6kl_add_new_sta(ar, mac_addr, aid, wpa_ie,
wpa_ie ? 2 + wpa_ie[1] : 0,
keymgmt, ucipher, auth);
/* send event to application */ /* send event to application */
memset(&sinfo, 0, sizeof(sinfo)); memset(&sinfo, 0, sizeof(sinfo));
/* TODO: sinfo.generation */ /* TODO: sinfo.generation */
/* TODO: need to deliver (Re)AssocReq IEs somehow.. change in
* cfg80211 needed, e.g., by adding those into sinfo
*/
cfg80211_new_sta(ar->net_dev, bssid, &sinfo, GFP_KERNEL);
netif_wake_queue(ar->net_dev); sinfo.assoc_req_ies = ies;
sinfo.assoc_req_ies_len = ies_len;
sinfo.filled |= STATION_INFO_ASSOC_REQ_IES;
return; cfg80211_new_sta(ar->net_dev, mac_addr, &sinfo, GFP_KERNEL);
netif_wake_queue(ar->net_dev);
} }
/* Functions for Tx credit handling */ /* Functions for Tx credit handling */
...@@ -779,6 +926,41 @@ void ath6kl_disconnect(struct ath6kl *ar) ...@@ -779,6 +926,41 @@ void ath6kl_disconnect(struct ath6kl *ar)
} }
} }
void ath6kl_deep_sleep_enable(struct ath6kl *ar)
{
switch (ar->sme_state) {
case SME_CONNECTING:
cfg80211_connect_result(ar->net_dev, ar->bssid, NULL, 0,
NULL, 0,
WLAN_STATUS_UNSPECIFIED_FAILURE,
GFP_KERNEL);
break;
case SME_CONNECTED:
default:
/*
* FIXME: oddly enough smeState is in DISCONNECTED during
* suspend, why? Need to send disconnected event in that
* state.
*/
cfg80211_disconnected(ar->net_dev, 0, NULL, 0, GFP_KERNEL);
break;
}
if (test_bit(CONNECTED, &ar->flag) ||
test_bit(CONNECT_PEND, &ar->flag))
ath6kl_wmi_disconnect_cmd(ar->wmi);
ar->sme_state = SME_DISCONNECTED;
/* disable scanning */
if (ath6kl_wmi_scanparams_cmd(ar->wmi, 0xFFFF, 0, 0, 0, 0, 0, 0, 0,
0, 0) != 0)
printk(KERN_WARNING "ath6kl: failed to disable scan "
"during suspend\n");
ath6kl_cfg80211_scan_complete_event(ar, -ECANCELED);
}
/* WMI Event handlers */ /* WMI Event handlers */
static const char *get_hw_id_string(u32 id) static const char *get_hw_id_string(u32 id)
...@@ -819,17 +1001,20 @@ void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver) ...@@ -819,17 +1001,20 @@ void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver)
set_bit(WMI_READY, &ar->flag); set_bit(WMI_READY, &ar->flag);
wake_up(&ar->event_wq); wake_up(&ar->event_wq);
ath6kl_info("hw %s fw %s\n", ath6kl_info("hw %s fw %s%s\n",
get_hw_id_string(ar->wdev->wiphy->hw_version), get_hw_id_string(ar->wdev->wiphy->hw_version),
ar->wdev->wiphy->fw_version); ar->wdev->wiphy->fw_version,
test_bit(TESTMODE, &ar->flag) ? " testmode" : "");
} }
void ath6kl_scan_complete_evt(struct ath6kl *ar, int status) void ath6kl_scan_complete_evt(struct ath6kl *ar, int status)
{ {
ath6kl_cfg80211_scan_complete_event(ar, status); ath6kl_cfg80211_scan_complete_event(ar, status);
if (!ar->usr_bss_filter) if (!ar->usr_bss_filter) {
clear_bit(CLEAR_BSSFILTER_ON_BEACON, &ar->flag);
ath6kl_wmi_bssfilter_cmd(ar->wmi, NONE_BSS_FILTER, 0); ath6kl_wmi_bssfilter_cmd(ar->wmi, NONE_BSS_FILTER, 0);
}
ath6kl_dbg(ATH6KL_DBG_WLAN_SCAN, "scan complete: %d\n", status); ath6kl_dbg(ATH6KL_DBG_WLAN_SCAN, "scan complete: %d\n", status);
} }
...@@ -842,13 +1027,6 @@ void ath6kl_connect_event(struct ath6kl *ar, u16 channel, u8 *bssid, ...@@ -842,13 +1027,6 @@ void ath6kl_connect_event(struct ath6kl *ar, u16 channel, u8 *bssid,
{ {
unsigned long flags; unsigned long flags;
if (ar->nw_type == AP_NETWORK) {
ath6kl_connect_ap_mode(ar, channel, bssid, listen_int,
beacon_int, assoc_resp_len,
assoc_info);
return;
}
ath6kl_cfg80211_connect_event(ar, channel, bssid, ath6kl_cfg80211_connect_event(ar, channel, bssid,
listen_int, beacon_int, listen_int, beacon_int,
net_type, beacon_ie_len, net_type, beacon_ie_len,
...@@ -880,8 +1058,10 @@ void ath6kl_connect_event(struct ath6kl *ar, u16 channel, u8 *bssid, ...@@ -880,8 +1058,10 @@ void ath6kl_connect_event(struct ath6kl *ar, u16 channel, u8 *bssid,
ar->next_ep_id = ENDPOINT_2; ar->next_ep_id = ENDPOINT_2;
} }
if (!ar->usr_bss_filter) if (!ar->usr_bss_filter) {
ath6kl_wmi_bssfilter_cmd(ar->wmi, NONE_BSS_FILTER, 0); set_bit(CLEAR_BSSFILTER_ON_BEACON, &ar->flag);
ath6kl_wmi_bssfilter_cmd(ar->wmi, CURRENT_BSS_FILTER, 0);
}
} }
void ath6kl_tkip_micerr_event(struct ath6kl *ar, u8 keyid, bool ismcast) void ath6kl_tkip_micerr_event(struct ath6kl *ar, u8 keyid, bool ismcast)
...@@ -915,26 +1095,11 @@ static void ath6kl_update_target_stats(struct ath6kl *ar, u8 *ptr, u32 len) ...@@ -915,26 +1095,11 @@ static void ath6kl_update_target_stats(struct ath6kl *ar, u8 *ptr, u32 len)
(struct wmi_target_stats *) ptr; (struct wmi_target_stats *) ptr;
struct target_stats *stats = &ar->target_stats; struct target_stats *stats = &ar->target_stats;
struct tkip_ccmp_stats *ccmp_stats; struct tkip_ccmp_stats *ccmp_stats;
struct bss *conn_bss = NULL;
struct cserv_stats *c_stats;
u8 ac; u8 ac;
if (len < sizeof(*tgt_stats)) if (len < sizeof(*tgt_stats))
return; return;
/* update the RSSI of the connected bss */
if (test_bit(CONNECTED, &ar->flag)) {
conn_bss = ath6kl_wmi_find_node(ar->wmi, ar->bssid);
if (conn_bss) {
c_stats = &tgt_stats->cserv_stats;
conn_bss->ni_rssi =
a_sle16_to_cpu(c_stats->cs_ave_beacon_rssi);
conn_bss->ni_snr =
tgt_stats->cserv_stats.cs_ave_beacon_snr;
ath6kl_wmi_node_return(ar->wmi, conn_bss);
}
}
ath6kl_dbg(ATH6KL_DBG_TRC, "updating target stats\n"); ath6kl_dbg(ATH6KL_DBG_TRC, "updating target stats\n");
stats->tx_pkt += le32_to_cpu(tgt_stats->stats.tx.pkt); stats->tx_pkt += le32_to_cpu(tgt_stats->stats.tx.pkt);
...@@ -1165,7 +1330,6 @@ void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid, ...@@ -1165,7 +1330,6 @@ void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid,
u8 assoc_resp_len, u8 *assoc_info, u8 assoc_resp_len, u8 *assoc_info,
u16 prot_reason_status) u16 prot_reason_status)
{ {
struct bss *wmi_ssid_node = NULL;
unsigned long flags; unsigned long flags;
if (ar->nw_type == AP_NETWORK) { if (ar->nw_type == AP_NETWORK) {
...@@ -1188,7 +1352,10 @@ void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid, ...@@ -1188,7 +1352,10 @@ void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid,
cfg80211_del_sta(ar->net_dev, bssid, GFP_KERNEL); cfg80211_del_sta(ar->net_dev, bssid, GFP_KERNEL);
} }
clear_bit(CONNECTED, &ar->flag); if (memcmp(ar->net_dev->dev_addr, bssid, ETH_ALEN) == 0) {
memset(ar->wep_key_list, 0, sizeof(ar->wep_key_list));
clear_bit(CONNECTED, &ar->flag);
}
return; return;
} }
...@@ -1222,33 +1389,6 @@ void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid, ...@@ -1222,33 +1389,6 @@ void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid,
} }
} }
if ((reason == NO_NETWORK_AVAIL) && test_bit(WMI_READY, &ar->flag)) {
ath6kl_wmi_node_free(ar->wmi, bssid);
/*
* In case any other same SSID nodes are present remove it,
* since those nodes also not available now.
*/
do {
/*
* Find the nodes based on SSID and remove it
*
* Note: This case will not work out for
* Hidden-SSID
*/
wmi_ssid_node = ath6kl_wmi_find_ssid_node(ar->wmi,
ar->ssid,
ar->ssid_len,
false,
true);
if (wmi_ssid_node)
ath6kl_wmi_node_free(ar->wmi,
wmi_ssid_node->ni_macaddr);
} while (wmi_ssid_node);
}
/* update connect & link status atomically */ /* update connect & link status atomically */
spin_lock_irqsave(&ar->lock, flags); spin_lock_irqsave(&ar->lock, flags);
clear_bit(CONNECTED, &ar->flag); clear_bit(CONNECTED, &ar->flag);
...@@ -1331,7 +1471,7 @@ void init_netdev(struct net_device *dev) ...@@ -1331,7 +1471,7 @@ void init_netdev(struct net_device *dev)
dev->needed_headroom = ETH_HLEN; dev->needed_headroom = ETH_HLEN;
dev->needed_headroom += sizeof(struct ath6kl_llc_snap_hdr) + dev->needed_headroom += sizeof(struct ath6kl_llc_snap_hdr) +
sizeof(struct wmi_data_hdr) + HTC_HDR_LENGTH sizeof(struct wmi_data_hdr) + HTC_HDR_LENGTH
+ WMI_MAX_TX_META_SZ; + WMI_MAX_TX_META_SZ + ATH6KL_HTC_ALIGN_BYTES;
return; return;
} }
此差异已折叠。
...@@ -20,6 +20,9 @@ ...@@ -20,6 +20,9 @@
#define AR6003_BOARD_DATA_SZ 1024 #define AR6003_BOARD_DATA_SZ 1024
#define AR6003_BOARD_EXT_DATA_SZ 768 #define AR6003_BOARD_EXT_DATA_SZ 768
#define AR6004_BOARD_DATA_SZ 7168
#define AR6004_BOARD_EXT_DATA_SZ 0
#define RESET_CONTROL_ADDRESS 0x00000000 #define RESET_CONTROL_ADDRESS 0x00000000
#define RESET_CONTROL_COLD_RST 0x00000100 #define RESET_CONTROL_COLD_RST 0x00000100
#define RESET_CONTROL_MBOX_RST 0x00000004 #define RESET_CONTROL_MBOX_RST 0x00000004
...@@ -135,7 +138,8 @@ ...@@ -135,7 +138,8 @@
* between the two, and is intended to remain constant (with additions only * between the two, and is intended to remain constant (with additions only
* at the end). * at the end).
*/ */
#define ATH6KL_HI_START_ADDR 0x00540600 #define ATH6KL_AR6003_HI_START_ADDR 0x00540600
#define ATH6KL_AR6004_HI_START_ADDR 0x00400800
/* /*
* These are items that the Host may need to access * These are items that the Host may need to access
...@@ -300,6 +304,11 @@ struct host_interest { ...@@ -300,6 +304,11 @@ struct host_interest {
#define HI_OPTION_FW_MODE_BSS_STA 0x1 #define HI_OPTION_FW_MODE_BSS_STA 0x1
#define HI_OPTION_FW_MODE_AP 0x2 #define HI_OPTION_FW_MODE_AP 0x2
#define HI_OPTION_FW_SUBMODE_NONE 0x0
#define HI_OPTION_FW_SUBMODE_P2PDEV 0x1
#define HI_OPTION_FW_SUBMODE_P2PCLIENT 0x2
#define HI_OPTION_FW_SUBMODE_P2PGO 0x3
#define HI_OPTION_NUM_DEV_SHIFT 0x9 #define HI_OPTION_NUM_DEV_SHIFT 0x9
#define HI_OPTION_FW_BRIDGE_SHIFT 0x04 #define HI_OPTION_FW_BRIDGE_SHIFT 0x04
...@@ -312,20 +321,44 @@ struct host_interest { ...@@ -312,20 +321,44 @@ struct host_interest {
|------------------------------------------------------------------------------| |------------------------------------------------------------------------------|
*/ */
#define HI_OPTION_FW_MODE_SHIFT 0xC #define HI_OPTION_FW_MODE_SHIFT 0xC
#define HI_OPTION_FW_SUBMODE_SHIFT 0x14
/* Convert a Target virtual address into a Target physical address */ /* Convert a Target virtual address into a Target physical address */
#define TARG_VTOP(vaddr) (vaddr & 0x001fffff) #define AR6003_VTOP(vaddr) ((vaddr) & 0x001fffff)
#define AR6004_VTOP(vaddr) (vaddr)
#define TARG_VTOP(target_type, vaddr) \
(((target_type) == TARGET_TYPE_AR6003) ? AR6003_VTOP(vaddr) : \
(((target_type) == TARGET_TYPE_AR6004) ? AR6004_VTOP(vaddr) : 0))
#define AR6003_REV2_APP_START_OVERRIDE 0x944C00
#define AR6003_REV2_APP_LOAD_ADDRESS 0x543180 #define AR6003_REV2_APP_LOAD_ADDRESS 0x543180
#define AR6003_REV2_BOARD_EXT_DATA_ADDRESS 0x57E500 #define AR6003_REV2_BOARD_EXT_DATA_ADDRESS 0x57E500
#define AR6003_REV2_DATASET_PATCH_ADDRESS 0x57e884 #define AR6003_REV2_DATASET_PATCH_ADDRESS 0x57e884
#define AR6003_REV2_RAM_RESERVE_SIZE 6912 #define AR6003_REV2_RAM_RESERVE_SIZE 6912
#define AR6003_REV3_APP_START_OVERRIDE 0x945d00
#define AR6003_REV3_APP_LOAD_ADDRESS 0x545000 #define AR6003_REV3_APP_LOAD_ADDRESS 0x545000
#define AR6003_REV3_BOARD_EXT_DATA_ADDRESS 0x542330 #define AR6003_REV3_BOARD_EXT_DATA_ADDRESS 0x542330
#define AR6003_REV3_DATASET_PATCH_ADDRESS 0x57FF74 #define AR6003_REV3_DATASET_PATCH_ADDRESS 0x57FF74
#define AR6003_REV3_RAM_RESERVE_SIZE 512 #define AR6003_REV3_RAM_RESERVE_SIZE 512
#define AR6004_REV1_BOARD_DATA_ADDRESS 0x435400
#define AR6004_REV1_BOARD_EXT_DATA_ADDRESS 0x437000
#define AR6004_REV1_RAM_RESERVE_SIZE 11264
#define ATH6KL_FWLOG_PAYLOAD_SIZE 1500
struct ath6kl_dbglog_buf {
__le32 next;
__le32 buffer_addr;
__le32 bufsize;
__le32 length;
__le32 count;
__le32 free;
} __packed;
struct ath6kl_dbglog_hdr {
__le32 dbuf_addr;
__le32 dropped;
} __packed;
#endif #endif
此差异已折叠。
此差异已折叠。
...@@ -340,7 +340,8 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); ...@@ -340,7 +340,8 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an); void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an);
bool ath_tx_aggr_sleep(struct ath_softc *sc, struct ath_node *an); void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc,
struct ath_node *an);
/********/ /********/
/* VIFs */ /* VIFs */
......
...@@ -38,6 +38,7 @@ static struct usb_device_id ath9k_hif_usb_ids[] = { ...@@ -38,6 +38,7 @@ static struct usb_device_id ath9k_hif_usb_ids[] = {
{ USB_DEVICE(0x04CA, 0x4605) }, /* Liteon */ { USB_DEVICE(0x04CA, 0x4605) }, /* Liteon */
{ USB_DEVICE(0x040D, 0x3801) }, /* VIA */ { USB_DEVICE(0x040D, 0x3801) }, /* VIA */
{ USB_DEVICE(0x0cf3, 0xb003) }, /* Ubiquiti WifiStation Ext */ { USB_DEVICE(0x0cf3, 0xb003) }, /* Ubiquiti WifiStation Ext */
{ USB_DEVICE(0x057c, 0x8403) }, /* AVM FRITZ!WLAN 11N v2 USB */
{ USB_DEVICE(0x0cf3, 0x7015), { USB_DEVICE(0x0cf3, 0x7015),
.driver_info = AR9287_USB }, /* Atheros */ .driver_info = AR9287_USB }, /* Atheros */
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册