Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
a5abbcb2
K
Kernel
项目概览
openeuler
/
Kernel
接近 2 年 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
a5abbcb2
编写于
10月 03, 2011
作者:
J
John W. Linville
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'for-linville' of
git://github.com/kvalo/ath6kl
上级
49a59543
62c83ac4
变更
21
展开全部
隐藏空白更改
内联
并排
Showing
21 changed file
with
4050 addition
and
1549 deletion
+4050
-1549
drivers/net/wireless/ath/ath6kl/Makefile
drivers/net/wireless/ath/ath6kl/Makefile
+3
-1
drivers/net/wireless/ath/ath6kl/bmi.c
drivers/net/wireless/ath/ath6kl/bmi.c
+10
-13
drivers/net/wireless/ath/ath6kl/bmi.h
drivers/net/wireless/ath/ath6kl/bmi.h
+2
-2
drivers/net/wireless/ath/ath6kl/cfg80211.c
drivers/net/wireless/ath/ath6kl/cfg80211.c
+635
-259
drivers/net/wireless/ath/ath6kl/common.h
drivers/net/wireless/ath/ath6kl/common.h
+0
-83
drivers/net/wireless/ath/ath6kl/core.h
drivers/net/wireless/ath/ath6kl/core.h
+119
-26
drivers/net/wireless/ath/ath6kl/debug.c
drivers/net/wireless/ath/ath6kl/debug.c
+784
-0
drivers/net/wireless/ath/ath6kl/debug.h
drivers/net/wireless/ath/ath6kl/debug.h
+41
-8
drivers/net/wireless/ath/ath6kl/hif-ops.h
drivers/net/wireless/ath/ath6kl/hif-ops.h
+5
-0
drivers/net/wireless/ath/ath6kl/hif.h
drivers/net/wireless/ath/ath6kl/hif.h
+1
-0
drivers/net/wireless/ath/ath6kl/htc.c
drivers/net/wireless/ath/ath6kl/htc.c
+146
-125
drivers/net/wireless/ath/ath6kl/init.c
drivers/net/wireless/ath/ath6kl/init.c
+609
-185
drivers/net/wireless/ath/ath6kl/main.c
drivers/net/wireless/ath/ath6kl/main.c
+294
-154
drivers/net/wireless/ath/ath6kl/node.c
drivers/net/wireless/ath/ath6kl/node.c
+0
-234
drivers/net/wireless/ath/ath6kl/sdio.c
drivers/net/wireless/ath/ath6kl/sdio.c
+58
-21
drivers/net/wireless/ath/ath6kl/target.h
drivers/net/wireless/ath/ath6kl/target.h
+37
-4
drivers/net/wireless/ath/ath6kl/testmode.c
drivers/net/wireless/ath/ath6kl/testmode.c
+167
-0
drivers/net/wireless/ath/ath6kl/testmode.h
drivers/net/wireless/ath/ath6kl/testmode.h
+36
-0
drivers/net/wireless/ath/ath6kl/txrx.c
drivers/net/wireless/ath/ath6kl/txrx.c
+41
-20
drivers/net/wireless/ath/ath6kl/wmi.c
drivers/net/wireless/ath/ath6kl/wmi.c
+755
-371
drivers/net/wireless/ath/ath6kl/wmi.h
drivers/net/wireless/ath/ath6kl/wmi.h
+307
-43
未找到文件。
drivers/net/wireless/ath/ath6kl/Makefile
浏览文件 @
a5abbcb2
...
...
@@ -31,5 +31,7 @@ ath6kl-y += init.o
ath6kl-y
+=
main.o
ath6kl-y
+=
txrx.o
ath6kl-y
+=
wmi.o
ath6kl-y
+=
node.o
ath6kl-y
+=
sdio.o
ath6kl-$(CONFIG_NL80211_TESTMODE)
+=
testmode.o
ccflags-y
+=
-D__CHECK_ENDIAN__
drivers/net/wireless/ath/ath6kl/bmi.c
浏览文件 @
a5abbcb2
...
...
@@ -62,14 +62,14 @@ static int ath6kl_get_bmi_cmd_credits(struct ath6kl *ar)
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
;
u32
rx_word
=
0
;
int
ret
=
0
;
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
,
(
u8
*
)
&
rx_word
,
sizeof
(
rx_word
),
HIF_RD_SYNC_BYTE_INC
);
...
...
@@ -109,8 +109,7 @@ static int ath6kl_bmi_send_buf(struct ath6kl *ar, u8 *buf, u32 len)
return
ret
;
}
static
int
ath6kl_bmi_recv_buf
(
struct
ath6kl
*
ar
,
u8
*
buf
,
u32
len
,
bool
want_timeout
)
static
int
ath6kl_bmi_recv_buf
(
struct
ath6kl
*
ar
,
u8
*
buf
,
u32
len
)
{
int
ret
;
u32
addr
;
...
...
@@ -162,7 +161,7 @@ static int ath6kl_bmi_recv_buf(struct ath6kl *ar,
* a function of Host processor speed.
*/
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
)
return
ret
;
}
...
...
@@ -220,7 +219,7 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar,
}
ret
=
ath6kl_bmi_recv_buf
(
ar
,
(
u8
*
)
&
targ_info
->
version
,
sizeof
(
targ_info
->
version
),
true
);
sizeof
(
targ_info
->
version
)
);
if
(
ret
)
{
ath6kl_err
(
"Unable to recv target info: %d
\n
"
,
ret
);
return
ret
;
...
...
@@ -230,8 +229,7 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar,
/* Determine how many bytes are in the Target's targ_info */
ret
=
ath6kl_bmi_recv_buf
(
ar
,
(
u8
*
)
&
targ_info
->
byte_count
,
sizeof
(
targ_info
->
byte_count
),
true
);
sizeof
(
targ_info
->
byte_count
));
if
(
ret
)
{
ath6kl_err
(
"unable to read target info byte count: %d
\n
"
,
ret
);
...
...
@@ -252,8 +250,7 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar,
((
u8
*
)
targ_info
)
+
sizeof
(
targ_info
->
byte_count
),
sizeof
(
*
targ_info
)
-
sizeof
(
targ_info
->
byte_count
),
true
);
sizeof
(
targ_info
->
byte_count
));
if
(
ret
)
{
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)
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
)
{
ath6kl_err
(
"Unable to read from the device: %d
\n
"
,
ret
);
...
...
@@ -424,7 +421,7 @@ int ath6kl_bmi_execute(struct ath6kl *ar, u32 addr, u32 *param)
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
)
{
ath6kl_err
(
"Unable to read from the device: %d
\n
"
,
ret
);
return
ret
;
...
...
@@ -504,7 +501,7 @@ int ath6kl_bmi_reg_read(struct ath6kl *ar, u32 addr, u32 *param)
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
)
{
ath6kl_err
(
"Unable to read from the device: %d
\n
"
,
ret
);
return
ret
;
...
...
drivers/net/wireless/ath/ath6kl/bmi.h
浏览文件 @
a5abbcb2
...
...
@@ -139,8 +139,8 @@
*/
#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
/*
* Semantics: Install a ROM Patch.
...
...
drivers/net/wireless/ath/ath6kl/cfg80211.c
浏览文件 @
a5abbcb2
此差异已折叠。
点击以展开。
drivers/net/wireless/ath/ath6kl/common.h
浏览文件 @
a5abbcb2
...
...
@@ -75,94 +75,11 @@ enum crypto_type {
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
ath6kl
;
enum
htc_credit_dist_reason
;
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
,
struct
htc_credit_state_info
*
cred_info
);
void
ath6k_credit_distribute
(
struct
htc_credit_state_info
*
cred_inf
,
...
...
drivers/net/wireless/ath/ath6kl/core.h
浏览文件 @
a5abbcb2
...
...
@@ -21,10 +21,12 @@
#include <linux/rtnetlink.h>
#include <linux/firmware.h>
#include <linux/sched.h>
#include <linux/circ_buf.h>
#include <net/cfg80211.h>
#include "htc.h"
#include "wmi.h"
#include "bmi.h"
#include "target.h"
#define MAX_ATH6KL 1
#define ATH6KL_MAX_RX_BUFFERS 16
...
...
@@ -42,6 +44,9 @@
#define ATH6KL_MAX_ENDPOINTS 4
#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 */
#define MAX_DEF_COOKIE_NUM 180
#define MAX_HI_COOKIE_NUM 18
/* 10% of MAX_COOKIE_NUM */
...
...
@@ -53,6 +58,35 @@
#define A_DEFAULT_LISTEN_INTERVAL 100
#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 */
#define AR6003_REV1_VERSION 0x300002ba
...
...
@@ -61,7 +95,9 @@
#define AR6003_REV2_PATCH_DOWNLOAD_ADDRESS 0x57e910
#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_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_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_DEFAULT_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.SD31.bin"
...
...
@@ -69,11 +105,21 @@
#define AR6003_REV3_VERSION 0x30000582
#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_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_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_DEFAULT_BOARD_DATA_FILE \
"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 */
#define STA_PS_AWAKE BIT(0)
#define STA_PS_SLEEP BIT(1)
...
...
@@ -325,26 +371,13 @@ struct ath6kl_mbox_info {
#define ATH6KL_KEY_RECV 0x02
#define ATH6KL_KEY_DEFAULT 0x80
/* default xmit key */
/*
* 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.
*/
/* Initial group key for AP mode */
struct
ath6kl_req_key
{
u8
ik_type
;
/* key/cipher type */
u8
ik_pad
;
u16
ik_keyix
;
/* key index */
u8
ik_keylen
;
/* key length in bytes */
u8
ik_flags
;
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
];
bool
valid
;
u8
key_index
;
int
key_type
;
u8
key
[
WLAN_MAX_KEY_LEN
];
u8
key_len
;
};
/* Flag info */
...
...
@@ -361,6 +394,9 @@ struct ath6kl_req_key {
#define NETDEV_REGISTERED 10
#define SKIP_SCAN 11
#define WLAN_ENABLED 12
#define TESTMODE 13
#define CLEAR_BSSFILTER_ON_BEACON 14
#define DTIM_PERIOD_AVAIL 15
struct
ath6kl
{
struct
device
*
dev
;
...
...
@@ -383,7 +419,7 @@ struct ath6kl {
u8
prwise_crypto
;
u8
prwise_crypto_len
;
u8
grp_crypto
;
u8
grp_crpto_len
;
u8
grp_cr
y
pto_len
;
u8
def_txkey_index
;
struct
ath6kl_wep_key
wep_key_list
[
WMI_MAX_KEY_INDEX
+
1
];
u8
bssid
[
ETH_ALEN
];
...
...
@@ -392,6 +428,7 @@ struct ath6kl {
u16
bss_ch
;
u16
listen_intvl_b
;
u16
listen_intvl_t
;
u8
lrssi_roam_threshold
;
struct
ath6kl_version
version
;
u32
target_type
;
u8
tx_pwr
;
...
...
@@ -432,7 +469,18 @@ struct ath6kl {
enum
wlan_low_pwr_state
wlan_pwr_state
;
struct
wmi_scan_params_cmd
sc_params
;
#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
;
wait_queue_head_t
event_wq
;
...
...
@@ -454,9 +502,35 @@ struct ath6kl {
u8
*
fw_patch
;
size_t
fw_patch_len
;
unsigned
long
fw_capabilities
[
ATH6KL_CAPABILITY_LEN
];
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
)
...
...
@@ -474,6 +548,19 @@ static inline void ath6kl_deposit_credit_to_ep(struct htc_credit_state_info
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
);
int
ath6kl_configure_target
(
struct
ath6kl
*
ar
);
void
ath6kl_detect_error
(
unsigned
long
ptr
);
...
...
@@ -487,9 +574,11 @@ enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target,
struct
htc_packet
*
packet
);
void
ath6kl_stop_txrx
(
struct
ath6kl
*
ar
);
void
ath6kl_cleanup_amsdu_rxbufs
(
struct
ath6kl
*
ar
);
int
ath6kl_access_datadiag
(
struct
ath6kl
*
ar
,
u32
address
,
u8
*
data
,
u32
length
,
bool
read
);
int
ath6kl_read_reg_diag
(
struct
ath6kl
*
ar
,
u32
*
address
,
u32
*
data
);
int
ath6kl_diag_write32
(
struct
ath6kl
*
ar
,
u32
address
,
__le32
value
);
int
ath6kl_diag_write
(
struct
ath6kl
*
ar
,
u32
address
,
void
*
data
,
u32
length
);
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_tx_data_cleanup
(
struct
ath6kl
*
ar
);
void
ath6kl_stop_endpoint
(
struct
net_device
*
dev
,
bool
keep_profile
,
...
...
@@ -520,6 +609,10 @@ void ath6kl_connect_event(struct ath6kl *ar, u16 channel,
u16
beacon_int
,
enum
network_type
net_type
,
u8
beacon_ie_len
,
u8
assoc_req_len
,
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
,
u8
*
bssid
,
u8
assoc_resp_len
,
u8
*
assoc_info
,
u16
prot_reason_status
);
...
...
@@ -534,11 +627,11 @@ void ath6kl_pspoll_event(struct ath6kl *ar, u8 aid);
void
ath6kl_dtimexpiry_event
(
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_addba_req_evt
(
struct
ath6kl
*
ar
,
u8
tid
,
u16
seq_no
,
u8
win_sz
);
void
ath6kl_wakeup_event
(
void
*
dev
);
void
ath6kl_target_failure
(
struct
ath6kl
*
ar
);
void
ath6kl_cfg80211_scan_node
(
struct
wiphy
*
wiphy
,
struct
bss
*
ni
);
#endif
/* CORE_H */
drivers/net/wireless/ath/ath6kl/debug.c
浏览文件 @
a5abbcb2
此差异已折叠。
点击以展开。
drivers/net/wireless/ath/ath6kl/debug.h
浏览文件 @
a5abbcb2
...
...
@@ -34,8 +34,12 @@ enum ATH6K_DEBUG_MASK {
ATH6KL_DBG_TRC
=
BIT
(
11
),
/* generic func tracing */
ATH6KL_DBG_SCATTER
=
BIT
(
12
),
/* hif scatter 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_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 */
};
...
...
@@ -52,6 +56,10 @@ extern int ath6kl_printk(const char *level, const char *fmt, ...)
#define AR_DBG_LVL_CHECK(mask) (debug_mask & mask)
enum
ath6kl_war
{
ATH6KL_WAR_INVALID_RATE
,
};
#ifdef CONFIG_ATH6KL_DEBUG
#define ath6kl_dbg(mask, 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
,
const
char
*
msg
,
const
void
*
buf
,
size_t
len
)
const
char
*
msg
,
const
char
*
prefix
,
const
void
*
buf
,
size_t
len
)
{
if
(
debug_mask
&
mask
)
{
ath6kl_dbg
(
mask
,
"%s
\n
"
,
msg
);
print_hex_dump_bytes
(
""
,
DUMP_PREFIX_OFFSET
,
buf
,
len
);
if
(
msg
)
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,
struct
ath6kl_irq_proc_registers
*
irq_proc_reg
,
struct
ath6kl_irq_enable_reg
*
irq_en_reg
);
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
static
inline
int
ath6kl_dbg
(
enum
ATH6K_DEBUG_MASK
dbg_mask
,
const
char
*
fmt
,
...)
...
...
@@ -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
,
const
char
*
msg
,
const
void
*
buf
,
size_t
len
)
const
char
*
msg
,
const
char
*
prefix
,
const
void
*
buf
,
size_t
len
)
{
}
...
...
@@ -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
)
{
}
#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
drivers/net/wireless/ath/ath6kl/hif-ops.h
浏览文件 @
a5abbcb2
...
...
@@ -69,4 +69,9 @@ static inline void ath6kl_hif_cleanup_scatter(struct ath6kl *ar)
return
ar
->
hif_ops
->
cleanup_scatter
(
ar
);
}
static
inline
int
ath6kl_hif_suspend
(
struct
ath6kl
*
ar
)
{
return
ar
->
hif_ops
->
suspend
(
ar
);
}
#endif
drivers/net/wireless/ath/ath6kl/hif.h
浏览文件 @
a5abbcb2
...
...
@@ -202,6 +202,7 @@ struct ath6kl_hif_ops {
int
(
*
scat_req_rw
)
(
struct
ath6kl
*
ar
,
struct
hif_scatter_req
*
scat_req
);
void
(
*
cleanup_scatter
)(
struct
ath6kl
*
ar
);
int
(
*
suspend
)(
struct
ath6kl
*
ar
);
};
#endif
drivers/net/wireless/ath/ath6kl/htc.c
浏览文件 @
a5abbcb2
此差异已折叠。
点击以展开。
drivers/net/wireless/ath/ath6kl/init.c
浏览文件 @
a5abbcb2
此差异已折叠。
点击以展开。
drivers/net/wireless/ath/ath6kl/main.c
浏览文件 @
a5abbcb2
...
...
@@ -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
];
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
->
keymgmt
=
keymgmt
;
sta
->
ucipher
=
ucipher
;
...
...
@@ -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
)
{
int
status
;
u8
addr_val
[
4
];
s32
i
;
__le32
addr_val
;
/*
* 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)
for
(
i
=
1
;
i
<=
3
;
i
++
)
{
/*
* 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
* write operation to the same address, this is a harmless
* 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
);
if
(
status
)
break
;
...
...
@@ -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
* 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
);
if
(
status
)
{
...
...
@@ -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
*
the Target
is required for this.
* Read from the
hardware through its diagnostic window. No cooperation
*
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 */
status
=
ath6kl_set_addrwin_reg
(
ar
,
WINDOW_READ_ADDR_ADDRESS
,
*
address
);
if
(
status
)
return
status
;
ret
=
ath6kl_set_addrwin_reg
(
ar
,
WINDOW_READ_ADDR_ADDRESS
,
address
);
if
(
ret
)
return
ret
;
/* read the data */
status
=
hif_read_write_sync
(
ar
,
WINDOW_DATA_ADDRESS
,
(
u8
*
)
data
,
sizeof
(
u32
),
HIF_RD_SYNC_BYTE_INC
);
if
(
status
)
{
ath6kl_err
(
"failed to read from window data addr
\n
"
);
return
status
;
ret
=
hif_read_write_sync
(
ar
,
WINDOW_DATA_ADDRESS
,
(
u8
*
)
value
,
sizeof
(
*
value
),
HIF_RD_SYNC_BYTE_INC
);
if
(
ret
)
{
ath6kl_warn
(
"failed to read32 through diagnose window: %d
\n
"
,
ret
);
return
ret
;
}
return
status
;
return
0
;
}
/*
* Write to the ATH6KL through its diagnostic window. No cooperation from
* 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 */
status
=
hif_read_write_sync
(
ar
,
WINDOW_DATA_ADDRESS
,
(
u8
*
)
data
,
sizeof
(
u32
),
HIF_WR_SYNC_BYTE_INC
);
if
(
status
)
{
ath6kl_err
(
"failed to write 0x%x to window data addr
\n
"
,
*
data
);
return
status
;
ret
=
hif_read_write_sync
(
ar
,
WINDOW_DATA_ADDRESS
,
(
u8
*
)
&
value
,
sizeof
(
value
),
HIF_WR_SYNC_BYTE_INC
);
if
(
ret
)
{
ath6kl_err
(
"failed to write 0x%x during diagnose window to 0x%d
\n
"
,
address
,
value
);
return
ret
;
}
/* set window register, which starts the write cycle */
return
ath6kl_set_addrwin_reg
(
ar
,
WINDOW_WRITE_ADDR_ADDRESS
,
*
address
);
address
);
}
int
ath6kl_access_datadiag
(
struct
ath6kl
*
ar
,
u32
address
,
u8
*
data
,
u32
length
,
bool
read
)
int
ath6kl_diag_read
(
struct
ath6kl
*
ar
,
u32
address
,
void
*
data
,
u32
length
)
{
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
;
int
status
=
0
;
__le32
*
buf
=
data
;
int
ret
;
for
(
count
=
0
;
count
<
length
;
count
+=
4
,
address
+=
4
)
{
if
(
read
)
{
status
=
ath6kl_read_reg_diag
(
ar
,
&
address
,
(
u32
*
)
&
data
[
count
]);
if
(
status
)
break
;
}
else
{
status
=
ath6kl_write_reg_diag
(
ar
,
&
address
,
(
u32
*
)
&
data
[
count
]);
if
(
status
)
break
;
}
if
(
WARN_ON
(
length
%
4
))
return
-
EINVAL
;
for
(
count
=
0
;
count
<
length
/
4
;
count
++
,
address
+=
4
)
{
ret
=
ath6kl_diag_write32
(
ar
,
address
,
buf
[
count
]);
if
(
ret
)
return
ret
;
}
return
0
;
}
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
,
bool
wait_fot_compltn
,
bool
cold_reset
)
{
int
status
=
0
;
u32
address
;
u
32
data
;
__le
32
data
;
if
(
target_type
!=
TARGET_TYPE_AR6003
)
if
(
target_type
!=
TARGET_TYPE_AR6003
&&
target_type
!=
TARGET_TYPE_AR6004
)
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
;
status
=
ath6kl_write_reg_diag
(
ar
,
&
address
,
&
data
);
switch
(
target_type
)
{
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
)
ath6kl_err
(
"failed to reset target
\n
"
);
...
...
@@ -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
,
u16
listen_int
,
u16
beacon_int
,
u8
assoc_resp_len
,
u8
*
assoc_info
)
void
ath6kl_connect_ap_mode_bss
(
struct
ath6kl
*
ar
,
u16
channel
)
{
struct
net_device
*
dev
=
ar
->
net_dev
;
struct
station_info
sinfo
;
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
)
{
case
NONE_AUTH
:
if
(
ar
->
prwise_crypto
==
WEP_CRYPT
)
ath6kl_install_static_wep_keys
(
ar
);
break
;
case
WPA_PSK_AUTH
:
case
WPA2_PSK_AUTH
:
case
(
WPA_PSK_AUTH
|
WPA2_PSK_AUTH
):
switch
(
ik
->
ik_type
)
{
case
ATH6KL_CIPHER_TKIP
:
keyType
=
TKIP_CRYPT
;
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
);
ath6kl_dbg
(
ATH6KL_DBG_WLAN_CFG
,
"AP mode started on %u MHz
\n
"
,
channel
);
switch
(
ar
->
auth_mode
)
{
case
NONE_AUTH
:
if
(
ar
->
prwise_crypto
==
WEP_CRYPT
)
ath6kl_install_static_wep_keys
(
ar
);
break
;
case
WPA_PSK_AUTH
:
case
WPA2_PSK_AUTH
:
case
(
WPA_PSK_AUTH
|
WPA2_PSK_AUTH
):
if
(
!
ik
->
valid
)
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:
set_bit
(
CONNECTED
,
&
ar
->
flag
);
return
;
break
;
}
ath6kl_dbg
(
ATH6KL_DBG_TRC
,
"new station %pM aid=%d
\n
"
,
bssid
,
channel
);
ath6kl_wmi_bssfilter_cmd
(
ar
->
wmi
,
NONE_BSS_FILTER
,
0
);
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
,
listen_int
&
0xFF
,
beacon_int
,
(
listen_int
>>
8
)
&
0xFF
);
ath6kl_dbg
(
ATH6KL_DBG_TRC
,
"new station %pM aid=%d
\n
"
,
mac_addr
,
aid
);
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 */
memset
(
&
sinfo
,
0
,
sizeof
(
sinfo
));
/* 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 */
...
...
@@ -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 */
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)
set_bit
(
WMI_READY
,
&
ar
->
flag
);
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
),
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
)
{
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_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,
{
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
,
listen_int
,
beacon_int
,
net_type
,
beacon_ie_len
,
...
...
@@ -880,8 +1058,10 @@ void ath6kl_connect_event(struct ath6kl *ar, u16 channel, u8 *bssid,
ar
->
next_ep_id
=
ENDPOINT_2
;
}
if
(
!
ar
->
usr_bss_filter
)
ath6kl_wmi_bssfilter_cmd
(
ar
->
wmi
,
NONE_BSS_FILTER
,
0
);
if
(
!
ar
->
usr_bss_filter
)
{
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
)
...
...
@@ -915,26 +1095,11 @@ static void ath6kl_update_target_stats(struct ath6kl *ar, u8 *ptr, u32 len)
(
struct
wmi_target_stats
*
)
ptr
;
struct
target_stats
*
stats
=
&
ar
->
target_stats
;
struct
tkip_ccmp_stats
*
ccmp_stats
;
struct
bss
*
conn_bss
=
NULL
;
struct
cserv_stats
*
c_stats
;
u8
ac
;
if
(
len
<
sizeof
(
*
tgt_stats
))
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
"
);
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,
u8
assoc_resp_len
,
u8
*
assoc_info
,
u16
prot_reason_status
)
{
struct
bss
*
wmi_ssid_node
=
NULL
;
unsigned
long
flags
;
if
(
ar
->
nw_type
==
AP_NETWORK
)
{
...
...
@@ -1188,7 +1352,10 @@ void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid,
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
;
}
...
...
@@ -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 */
spin_lock_irqsave
(
&
ar
->
lock
,
flags
);
clear_bit
(
CONNECTED
,
&
ar
->
flag
);
...
...
@@ -1331,7 +1471,7 @@ void init_netdev(struct net_device *dev)
dev
->
needed_headroom
=
ETH_HLEN
;
dev
->
needed_headroom
+=
sizeof
(
struct
ath6kl_llc_snap_hdr
)
+
sizeof
(
struct
wmi_data_hdr
)
+
HTC_HDR_LENGTH
+
WMI_MAX_TX_META_SZ
;
+
WMI_MAX_TX_META_SZ
+
ATH6KL_HTC_ALIGN_BYTES
;
return
;
}
drivers/net/wireless/ath/ath6kl/node.c
已删除
100644 → 0
浏览文件 @
49a59543
此差异已折叠。
点击以展开。
drivers/net/wireless/ath/ath6kl/sdio.c
浏览文件 @
a5abbcb2
...
...
@@ -25,6 +25,7 @@
#include "hif-ops.h"
#include "target.h"
#include "debug.h"
#include "cfg80211.h"
struct
ath6kl_sdio
{
struct
sdio_func
*
func
;
...
...
@@ -134,10 +135,12 @@ static int ath6kl_sdio_io(struct sdio_func *func, u32 request, u32 addr,
int
ret
=
0
;
if
(
request
&
HIF_WRITE
)
{
/* FIXME: looks like ugly workaround for something */
if
(
addr
>=
HIF_MBOX_BASE_ADDR
&&
addr
<=
HIF_MBOX_END_ADDR
)
addr
+=
(
HIF_MBOX_WIDTH
-
len
);
/* FIXME: this also looks like ugly workaround */
if
(
addr
==
HIF_MBOX0_EXT_BASE_ADDR
)
addr
+=
HIF_MBOX0_EXT_WIDTH
-
len
;
...
...
@@ -152,6 +155,11 @@ static int ath6kl_sdio_io(struct sdio_func *func, u32 request, u32 addr,
ret
=
sdio_memcpy_fromio
(
func
,
buf
,
addr
,
len
);
}
ath6kl_dbg
(
ATH6KL_DBG_SDIO
,
"%s addr 0x%x%s buf 0x%p len %d
\n
"
,
request
&
HIF_WRITE
?
"wr"
:
"rd"
,
addr
,
request
&
HIF_FIXED_ADDRESS
?
" (fixed)"
:
""
,
buf
,
len
);
ath6kl_dbg_dump
(
ATH6KL_DBG_SDIO_DUMP
,
NULL
,
"sdio "
,
buf
,
len
);
return
ret
;
}
...
...
@@ -172,7 +180,8 @@ static struct bus_request *ath6kl_sdio_alloc_busreq(struct ath6kl_sdio *ar_sdio)
list_del
(
&
bus_req
->
list
);
spin_unlock_irqrestore
(
&
ar_sdio
->
lock
,
flag
);
ath6kl_dbg
(
ATH6KL_DBG_TRC
,
"%s: bus request 0x%p
\n
"
,
__func__
,
bus_req
);
ath6kl_dbg
(
ATH6KL_DBG_SCATTER
,
"%s: bus request 0x%p
\n
"
,
__func__
,
bus_req
);
return
bus_req
;
}
...
...
@@ -182,7 +191,8 @@ static void ath6kl_sdio_free_bus_req(struct ath6kl_sdio *ar_sdio,
{
unsigned
long
flag
;
ath6kl_dbg
(
ATH6KL_DBG_TRC
,
"%s: bus request 0x%p
\n
"
,
__func__
,
bus_req
);
ath6kl_dbg
(
ATH6KL_DBG_SCATTER
,
"%s: bus request 0x%p
\n
"
,
__func__
,
bus_req
);
spin_lock_irqsave
(
&
ar_sdio
->
lock
,
flag
);
list_add_tail
(
&
bus_req
->
list
,
&
ar_sdio
->
bus_req_freeq
);
...
...
@@ -213,16 +223,6 @@ static void ath6kl_sdio_setup_scat_data(struct hif_scatter_req *scat_req,
/* assemble SG list */
for
(
i
=
0
;
i
<
scat_req
->
scat_entries
;
i
++
,
sg
++
)
{
if
((
unsigned
long
)
scat_req
->
scat_list
[
i
].
buf
&
0x3
)
/*
* Some scatter engines can handle unaligned
* buffers, print this as informational only.
*/
ath6kl_dbg
(
ATH6KL_DBG_SCATTER
,
"(%s) scatter buffer is unaligned 0x%p
\n
"
,
scat_req
->
req
&
HIF_WRITE
?
"WR"
:
"RD"
,
scat_req
->
scat_list
[
i
].
buf
);
ath6kl_dbg
(
ATH6KL_DBG_SCATTER
,
"%d: addr:0x%p, len:%d
\n
"
,
i
,
scat_req
->
scat_list
[
i
].
buf
,
scat_req
->
scat_list
[
i
].
len
);
...
...
@@ -447,6 +447,8 @@ static void ath6kl_sdio_irq_handler(struct sdio_func *func)
int
status
;
struct
ath6kl_sdio
*
ar_sdio
;
ath6kl_dbg
(
ATH6KL_DBG_SDIO
,
"irq
\n
"
);
ar_sdio
=
sdio_get_drvdata
(
func
);
atomic_set
(
&
ar_sdio
->
irq_handling
,
1
);
...
...
@@ -684,7 +686,7 @@ static int ath6kl_sdio_enable_scatter(struct ath6kl *ar)
MAX_SCATTER_REQUESTS
,
virt_scat
);
if
(
!
ret
)
{
ath6kl_dbg
(
ATH6KL_DBG_
ANY
,
ath6kl_dbg
(
ATH6KL_DBG_
SCATTER
,
"hif-scatter enabled: max scatter req : %d entries: %d
\n
"
,
MAX_SCATTER_REQUESTS
,
MAX_SCATTER_ENTRIES_PER_REQ
);
...
...
@@ -709,7 +711,7 @@ static int ath6kl_sdio_enable_scatter(struct ath6kl *ar)
return
ret
;
}
ath6kl_dbg
(
ATH6KL_DBG_
ANY
,
ath6kl_dbg
(
ATH6KL_DBG_
SCATTER
,
"Vitual scatter enabled, max_scat_req:%d, entries:%d
\n
"
,
ATH6KL_SCATTER_REQS
,
ATH6KL_SCATTER_ENTRIES_PER_REQ
);
...
...
@@ -721,6 +723,34 @@ static int ath6kl_sdio_enable_scatter(struct ath6kl *ar)
return
0
;
}
static
int
ath6kl_sdio_suspend
(
struct
ath6kl
*
ar
)
{
struct
ath6kl_sdio
*
ar_sdio
=
ath6kl_sdio_priv
(
ar
);
struct
sdio_func
*
func
=
ar_sdio
->
func
;
mmc_pm_flag_t
flags
;
int
ret
;
flags
=
sdio_get_host_pm_caps
(
func
);
if
(
!
(
flags
&
MMC_PM_KEEP_POWER
))
/* as host doesn't support keep power we need to bail out */
ath6kl_dbg
(
ATH6KL_DBG_SDIO
,
"func %d doesn't support MMC_PM_KEEP_POWER
\n
"
,
func
->
num
);
return
-
EINVAL
;
ret
=
sdio_set_host_pm_flags
(
func
,
MMC_PM_KEEP_POWER
);
if
(
ret
)
{
printk
(
KERN_ERR
"ath6kl: set sdio pm flags failed: %d
\n
"
,
ret
);
return
ret
;
}
ath6kl_deep_sleep_enable
(
ar
);
return
0
;
}
static
const
struct
ath6kl_hif_ops
ath6kl_sdio_ops
=
{
.
read_write_sync
=
ath6kl_sdio_read_write_sync
,
.
write_async
=
ath6kl_sdio_write_async
,
...
...
@@ -731,6 +761,7 @@ static const struct ath6kl_hif_ops ath6kl_sdio_ops = {
.
enable_scatter
=
ath6kl_sdio_enable_scatter
,
.
scat_req_rw
=
ath6kl_sdio_async_rw_scatter
,
.
cleanup_scatter
=
ath6kl_sdio_cleanup_scatter
,
.
suspend
=
ath6kl_sdio_suspend
,
};
static
int
ath6kl_sdio_probe
(
struct
sdio_func
*
func
,
...
...
@@ -741,10 +772,10 @@ static int ath6kl_sdio_probe(struct sdio_func *func,
struct
ath6kl
*
ar
;
int
count
;
ath6kl_dbg
(
ATH6KL_DBG_
TRC
,
"
%s: func: 0x%X, vendor id: 0x%X, dev id: 0x%X, block size: 0x%X/0x%X
\n
"
,
__func__
,
func
->
num
,
func
->
vendor
,
func
->
device
,
func
->
max_blksize
,
func
->
cur_blksize
);
ath6kl_dbg
(
ATH6KL_DBG_
SDIO
,
"
new func %d vendor 0x%x device 0x%x block 0x%x/0x%x
\n
"
,
func
->
num
,
func
->
vendor
,
func
->
device
,
func
->
max_blksize
,
func
->
cur_blksize
);
ar_sdio
=
kzalloc
(
sizeof
(
struct
ath6kl_sdio
),
GFP_KERNEL
);
if
(
!
ar_sdio
)
...
...
@@ -800,10 +831,10 @@ static int ath6kl_sdio_probe(struct sdio_func *func,
ath6kl_err
(
"Failed to enable 4-bit async irq mode %d
\n
"
,
ret
);
sdio_release_host
(
func
);
goto
err_
dma
;
goto
err_
cfg80211
;
}
ath6kl_dbg
(
ATH6KL_DBG_
TRC
,
"4-bit async irq mode enabled
\n
"
);
ath6kl_dbg
(
ATH6KL_DBG_
SDIO
,
"4-bit async irq mode enabled
\n
"
);
}
/* give us some time to enable, in ms */
...
...
@@ -813,7 +844,7 @@ static int ath6kl_sdio_probe(struct sdio_func *func,
ret
=
ath6kl_sdio_power_on
(
ar_sdio
);
if
(
ret
)
goto
err_
dma
;
goto
err_
cfg80211
;
sdio_claim_host
(
func
);
...
...
@@ -837,6 +868,8 @@ static int ath6kl_sdio_probe(struct sdio_func *func,
err_off:
ath6kl_sdio_power_off
(
ar_sdio
);
err_cfg80211:
ath6kl_cfg80211_deinit
(
ar_sdio
->
ar
);
err_dma:
kfree
(
ar_sdio
->
dma_buffer
);
err_hif:
...
...
@@ -849,6 +882,10 @@ static void ath6kl_sdio_remove(struct sdio_func *func)
{
struct
ath6kl_sdio
*
ar_sdio
;
ath6kl_dbg
(
ATH6KL_DBG_SDIO
,
"removed func %d vendor 0x%x device 0x%x
\n
"
,
func
->
num
,
func
->
vendor
,
func
->
device
);
ar_sdio
=
sdio_get_drvdata
(
func
);
ath6kl_stop_txrx
(
ar_sdio
->
ar
);
...
...
drivers/net/wireless/ath/ath6kl/target.h
浏览文件 @
a5abbcb2
此差异已折叠。
点击以展开。
drivers/net/wireless/ath/ath6kl/testmode.c
0 → 100644
浏览文件 @
a5abbcb2
此差异已折叠。
点击以展开。
drivers/net/wireless/ath/ath6kl/testmode.h
0 → 100644
浏览文件 @
a5abbcb2
此差异已折叠。
点击以展开。
drivers/net/wireless/ath/ath6kl/txrx.c
浏览文件 @
a5abbcb2
此差异已折叠。
点击以展开。
drivers/net/wireless/ath/ath6kl/wmi.c
浏览文件 @
a5abbcb2
此差异已折叠。
点击以展开。
drivers/net/wireless/ath/ath6kl/wmi.h
浏览文件 @
a5abbcb2
此差异已折叠。
点击以展开。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录