Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
cbdbc5eb
K
Kernel
项目概览
openeuler
/
Kernel
1 年多 前同步成功
通知
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看板
提交
cbdbc5eb
编写于
1月 28, 2011
作者:
J
John W. Linville
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'for-linville' of
git://git.kernel.org/pub/scm/linux/kernel/git/luca/wl12xx
上级
8d8d3fdc
e5e2f24b
变更
21
展开全部
隐藏空白更改
内联
并排
Showing
21 changed file
with
2175 addition
and
459 deletion
+2175
-459
MAINTAINERS
MAINTAINERS
+3
-3
drivers/net/wireless/wl12xx/acx.c
drivers/net/wireless/wl12xx/acx.c
+151
-9
drivers/net/wireless/wl12xx/acx.h
drivers/net/wireless/wl12xx/acx.h
+87
-4
drivers/net/wireless/wl12xx/boot.c
drivers/net/wireless/wl12xx/boot.c
+29
-6
drivers/net/wireless/wl12xx/cmd.c
drivers/net/wireless/wl12xx/cmd.c
+296
-12
drivers/net/wireless/wl12xx/cmd.h
drivers/net/wireless/wl12xx/cmd.h
+141
-6
drivers/net/wireless/wl12xx/conf.h
drivers/net/wireless/wl12xx/conf.h
+65
-11
drivers/net/wireless/wl12xx/debugfs.c
drivers/net/wireless/wl12xx/debugfs.c
+19
-30
drivers/net/wireless/wl12xx/event.c
drivers/net/wireless/wl12xx/event.c
+4
-3
drivers/net/wireless/wl12xx/event.h
drivers/net/wireless/wl12xx/event.h
+7
-1
drivers/net/wireless/wl12xx/init.c
drivers/net/wireless/wl12xx/init.c
+316
-71
drivers/net/wireless/wl12xx/init.h
drivers/net/wireless/wl12xx/init.h
+1
-1
drivers/net/wireless/wl12xx/main.c
drivers/net/wireless/wl12xx/main.c
+844
-271
drivers/net/wireless/wl12xx/rx.c
drivers/net/wireless/wl12xx/rx.c
+12
-2
drivers/net/wireless/wl12xx/rx.h
drivers/net/wireless/wl12xx/rx.h
+8
-3
drivers/net/wireless/wl12xx/sdio.c
drivers/net/wireless/wl12xx/sdio.c
+1
-0
drivers/net/wireless/wl12xx/spi.c
drivers/net/wireless/wl12xx/spi.c
+2
-1
drivers/net/wireless/wl12xx/tx.c
drivers/net/wireless/wl12xx/tx.c
+90
-15
drivers/net/wireless/wl12xx/tx.h
drivers/net/wireless/wl12xx/tx.h
+8
-2
drivers/net/wireless/wl12xx/wl12xx.h
drivers/net/wireless/wl12xx/wl12xx.h
+83
-5
drivers/net/wireless/wl12xx/wl12xx_80211.h
drivers/net/wireless/wl12xx/wl12xx_80211.h
+8
-3
未找到文件。
MAINTAINERS
浏览文件 @
cbdbc5eb
...
...
@@ -6742,12 +6742,12 @@ S: Maintained
F: drivers/net/wireless/wl1251/*
WL1271 WIRELESS DRIVER
M: Luciano Coelho <
luciano.coelho@nokia
.com>
M: Luciano Coelho <
coelho@ti
.com>
L: linux-wireless@vger.kernel.org
W: http://wireless.kernel.org
W: http://wireless.kernel.org
/en/users/Drivers/wl12xx
T: git git://git.kernel.org/pub/scm/linux/kernel/git/luca/wl12xx.git
S: Maintained
F: drivers/net/wireless/wl12xx/
wl1271*
F: drivers/net/wireless/wl12xx/
F: include/linux/wl12xx.h
WL3501 WIRELESS PCMCIA CARD DRIVER
...
...
drivers/net/wireless/wl12xx/acx.c
浏览文件 @
cbdbc5eb
...
...
@@ -751,10 +751,10 @@ int wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats)
return
0
;
}
int
wl1271_acx_rate_policies
(
struct
wl1271
*
wl
)
int
wl1271_acx_
sta_
rate_policies
(
struct
wl1271
*
wl
)
{
struct
acx_rate_policy
*
acx
;
struct
conf_tx_rate_class
*
c
=
&
wl
->
conf
.
tx
.
rc_conf
;
struct
acx_
sta_
rate_policy
*
acx
;
struct
conf_tx_rate_class
*
c
=
&
wl
->
conf
.
tx
.
sta_
rc_conf
;
int
idx
=
0
;
int
ret
=
0
;
...
...
@@ -794,6 +794,38 @@ int wl1271_acx_rate_policies(struct wl1271 *wl)
return
ret
;
}
int
wl1271_acx_ap_rate_policy
(
struct
wl1271
*
wl
,
struct
conf_tx_rate_class
*
c
,
u8
idx
)
{
struct
acx_ap_rate_policy
*
acx
;
int
ret
=
0
;
wl1271_debug
(
DEBUG_ACX
,
"acx ap rate policy"
);
acx
=
kzalloc
(
sizeof
(
*
acx
),
GFP_KERNEL
);
if
(
!
acx
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
acx
->
rate_policy
.
enabled_rates
=
cpu_to_le32
(
c
->
enabled_rates
);
acx
->
rate_policy
.
short_retry_limit
=
c
->
short_retry_limit
;
acx
->
rate_policy
.
long_retry_limit
=
c
->
long_retry_limit
;
acx
->
rate_policy
.
aflags
=
c
->
aflags
;
acx
->
rate_policy_idx
=
cpu_to_le32
(
idx
);
ret
=
wl1271_cmd_configure
(
wl
,
ACX_RATE_POLICY
,
acx
,
sizeof
(
*
acx
));
if
(
ret
<
0
)
{
wl1271_warning
(
"Setting of ap rate policy failed: %d"
,
ret
);
goto
out
;
}
out:
kfree
(
acx
);
return
ret
;
}
int
wl1271_acx_ac_cfg
(
struct
wl1271
*
wl
,
u8
ac
,
u8
cw_min
,
u16
cw_max
,
u8
aifsn
,
u16
txop
)
{
...
...
@@ -1233,6 +1265,7 @@ int wl1271_acx_set_ht_capabilities(struct wl1271 *wl,
struct
wl1271_acx_ht_capabilities
*
acx
;
u8
mac_address
[
ETH_ALEN
]
=
{
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
};
int
ret
=
0
;
u32
ht_capabilites
=
0
;
wl1271_debug
(
DEBUG_ACX
,
"acx ht capabilities setting"
);
...
...
@@ -1244,16 +1277,16 @@ int wl1271_acx_set_ht_capabilities(struct wl1271 *wl,
/* Allow HT Operation ? */
if
(
allow_ht_operation
)
{
acx
->
ht_capabilites
=
ht_capabilites
=
WL1271_ACX_FW_CAP_HT_OPERATION
;
if
(
ht_cap
->
cap
&
IEEE80211_HT_CAP_GRN_FLD
)
acx
->
ht_capabilites
|=
ht_capabilites
|=
WL1271_ACX_FW_CAP_GREENFIELD_FRAME_FORMAT
;
if
(
ht_cap
->
cap
&
IEEE80211_HT_CAP_SGI_20
)
acx
->
ht_capabilites
|=
ht_capabilites
|=
WL1271_ACX_FW_CAP_SHORT_GI_FOR_20MHZ_PACKETS
;
if
(
ht_cap
->
cap
&
IEEE80211_HT_CAP_LSIG_TXOP_PROT
)
acx
->
ht_capabilites
|=
ht_capabilites
|=
WL1271_ACX_FW_CAP_LSIG_TXOP_PROTECTION
;
/* get data from A-MPDU parameters field */
...
...
@@ -1261,10 +1294,10 @@ int wl1271_acx_set_ht_capabilities(struct wl1271 *wl,
acx
->
ampdu_min_spacing
=
ht_cap
->
ampdu_density
;
memcpy
(
acx
->
mac_address
,
mac_address
,
ETH_ALEN
);
}
else
{
/* HT operations are not allowed */
acx
->
ht_capabilites
=
0
;
}
acx
->
ht_capabilites
=
cpu_to_le32
(
ht_capabilites
);
ret
=
wl1271_cmd_configure
(
wl
,
ACX_PEER_HT_CAP
,
acx
,
sizeof
(
*
acx
));
if
(
ret
<
0
)
{
wl1271_warning
(
"acx ht capabilities setting failed: %d"
,
ret
);
...
...
@@ -1309,6 +1342,91 @@ int wl1271_acx_set_ht_information(struct wl1271 *wl,
return
ret
;
}
/* Configure BA session initiator/receiver parameters setting in the FW. */
int
wl1271_acx_set_ba_session
(
struct
wl1271
*
wl
,
enum
ieee80211_back_parties
direction
,
u8
tid_index
,
u8
policy
)
{
struct
wl1271_acx_ba_session_policy
*
acx
;
int
ret
;
wl1271_debug
(
DEBUG_ACX
,
"acx ba session setting"
);
acx
=
kzalloc
(
sizeof
(
*
acx
),
GFP_KERNEL
);
if
(
!
acx
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
/* ANY role */
acx
->
role_id
=
0xff
;
acx
->
tid
=
tid_index
;
acx
->
enable
=
policy
;
acx
->
ba_direction
=
direction
;
switch
(
direction
)
{
case
WLAN_BACK_INITIATOR
:
acx
->
win_size
=
wl
->
conf
.
ht
.
tx_ba_win_size
;
acx
->
inactivity_timeout
=
wl
->
conf
.
ht
.
inactivity_timeout
;
break
;
case
WLAN_BACK_RECIPIENT
:
acx
->
win_size
=
RX_BA_WIN_SIZE
;
acx
->
inactivity_timeout
=
0
;
break
;
default:
wl1271_error
(
"Incorrect acx command id=%x
\n
"
,
direction
);
ret
=
-
EINVAL
;
goto
out
;
}
ret
=
wl1271_cmd_configure
(
wl
,
ACX_BA_SESSION_POLICY_CFG
,
acx
,
sizeof
(
*
acx
));
if
(
ret
<
0
)
{
wl1271_warning
(
"acx ba session setting failed: %d"
,
ret
);
goto
out
;
}
out:
kfree
(
acx
);
return
ret
;
}
/* setup BA session receiver setting in the FW. */
int
wl1271_acx_set_ba_receiver_session
(
struct
wl1271
*
wl
,
u8
tid_index
,
u16
ssn
,
bool
enable
)
{
struct
wl1271_acx_ba_receiver_setup
*
acx
;
int
ret
;
wl1271_debug
(
DEBUG_ACX
,
"acx ba receiver session setting"
);
acx
=
kzalloc
(
sizeof
(
*
acx
),
GFP_KERNEL
);
if
(
!
acx
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
/* Single link for now */
acx
->
link_id
=
1
;
acx
->
tid
=
tid_index
;
acx
->
enable
=
enable
;
acx
->
win_size
=
0
;
acx
->
ssn
=
ssn
;
ret
=
wl1271_cmd_configure
(
wl
,
ACX_BA_SESSION_RX_SETUP
,
acx
,
sizeof
(
*
acx
));
if
(
ret
<
0
)
{
wl1271_warning
(
"acx ba receiver session failed: %d"
,
ret
);
goto
out
;
}
out:
kfree
(
acx
);
return
ret
;
}
int
wl1271_acx_tsf_info
(
struct
wl1271
*
wl
,
u64
*
mactime
)
{
struct
wl1271_acx_fw_tsf_information
*
tsf_info
;
...
...
@@ -1334,3 +1452,27 @@ int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime)
kfree
(
tsf_info
);
return
ret
;
}
int
wl1271_acx_max_tx_retry
(
struct
wl1271
*
wl
)
{
struct
wl1271_acx_max_tx_retry
*
acx
=
NULL
;
int
ret
;
wl1271_debug
(
DEBUG_ACX
,
"acx max tx retry"
);
acx
=
kzalloc
(
sizeof
(
*
acx
),
GFP_KERNEL
);
if
(
!
acx
)
return
-
ENOMEM
;
acx
->
max_tx_retry
=
cpu_to_le16
(
wl
->
conf
.
tx
.
ap_max_tx_retries
);
ret
=
wl1271_cmd_configure
(
wl
,
ACX_MAX_TX_FAILURE
,
acx
,
sizeof
(
*
acx
));
if
(
ret
<
0
)
{
wl1271_warning
(
"acx max tx retry failed: %d"
,
ret
);
goto
out
;
}
out:
kfree
(
acx
);
return
ret
;
}
drivers/net/wireless/wl12xx/acx.h
浏览文件 @
cbdbc5eb
...
...
@@ -747,13 +747,23 @@ struct acx_rate_class {
#define ACX_TX_BASIC_RATE 0
#define ACX_TX_AP_FULL_RATE 1
#define ACX_TX_RATE_POLICY_CNT 2
struct
acx_rate_policy
{
struct
acx_
sta_
rate_policy
{
struct
acx_header
header
;
__le32
rate_class_cnt
;
struct
acx_rate_class
rate_class
[
CONF_TX_MAX_RATE_CLASSES
];
}
__packed
;
#define ACX_TX_AP_MODE_MGMT_RATE 4
#define ACX_TX_AP_MODE_BCST_RATE 5
struct
acx_ap_rate_policy
{
struct
acx_header
header
;
__le32
rate_policy_idx
;
struct
acx_rate_class
rate_policy
;
}
__packed
;
struct
acx_ac_cfg
{
struct
acx_header
header
;
u8
ac
;
...
...
@@ -1051,6 +1061,59 @@ struct wl1271_acx_ht_information {
u8
padding
[
3
];
}
__packed
;
#define RX_BA_WIN_SIZE 8
struct
wl1271_acx_ba_session_policy
{
struct
acx_header
header
;
/*
* Specifies role Id, Range 0-7, 0xFF means ANY role.
* Future use. For now this field is irrelevant
*/
u8
role_id
;
/*
* Specifies Link Id, Range 0-31, 0xFF means ANY Link Id.
* Not applicable if Role Id is set to ANY.
*/
u8
link_id
;
u8
tid
;
u8
enable
;
/* Windows size in number of packets */
u16
win_size
;
/*
* As initiator inactivity timeout in time units(TU) of 1024us.
* As receiver reserved
*/
u16
inactivity_timeout
;
/* Initiator = 1/Receiver = 0 */
u8
ba_direction
;
u8
padding
[
3
];
}
__packed
;
struct
wl1271_acx_ba_receiver_setup
{
struct
acx_header
header
;
/* Specifies Link Id, Range 0-31, 0xFF means ANY Link Id */
u8
link_id
;
u8
tid
;
u8
enable
;
u8
padding
[
1
];
/* Windows size in number of packets */
u16
win_size
;
/* BA session starting sequence number. RANGE 0-FFF */
u16
ssn
;
}
__packed
;
struct
wl1271_acx_fw_tsf_information
{
struct
acx_header
header
;
...
...
@@ -1062,6 +1125,17 @@ struct wl1271_acx_fw_tsf_information {
u8
padding
[
3
];
}
__packed
;
struct
wl1271_acx_max_tx_retry
{
struct
acx_header
header
;
/*
* the number of frames transmission failures before
* issuing the aging event.
*/
__le16
max_tx_retry
;
u8
padding_1
[
2
];
}
__packed
;
enum
{
ACX_WAKE_UP_CONDITIONS
=
0x0002
,
ACX_MEM_CFG
=
0x0003
,
...
...
@@ -1113,12 +1187,13 @@ enum {
ACX_RSSI_SNR_WEIGHTS
=
0x0052
,
ACX_KEEP_ALIVE_MODE
=
0x0053
,
ACX_SET_KEEP_ALIVE_CONFIG
=
0x0054
,
ACX_BA_SESSION_
RESPONDER_POLICY
=
0x0055
,
ACX_BA_SESSION_
INITIATOR_POLICY
=
0x0056
,
ACX_BA_SESSION_
POLICY_CFG
=
0x0055
,
ACX_BA_SESSION_
RX_SETUP
=
0x0056
,
ACX_PEER_HT_CAP
=
0x0057
,
ACX_HT_BSS_OPERATION
=
0x0058
,
ACX_COEX_ACTIVITY
=
0x0059
,
ACX_SET_DCO_ITRIM_PARAMS
=
0x0061
,
ACX_MAX_TX_FAILURE
=
0x0072
,
DOT11_RX_MSDU_LIFE_TIME
=
0x1004
,
DOT11_CUR_TX_PWR
=
0x100D
,
DOT11_RX_DOT11_MODE
=
0x1012
,
...
...
@@ -1160,7 +1235,9 @@ int wl1271_acx_set_preamble(struct wl1271 *wl, enum acx_preamble_type preamble);
int
wl1271_acx_cts_protect
(
struct
wl1271
*
wl
,
enum
acx_ctsprotect_type
ctsprotect
);
int
wl1271_acx_statistics
(
struct
wl1271
*
wl
,
struct
acx_statistics
*
stats
);
int
wl1271_acx_rate_policies
(
struct
wl1271
*
wl
);
int
wl1271_acx_sta_rate_policies
(
struct
wl1271
*
wl
);
int
wl1271_acx_ap_rate_policy
(
struct
wl1271
*
wl
,
struct
conf_tx_rate_class
*
c
,
u8
idx
);
int
wl1271_acx_ac_cfg
(
struct
wl1271
*
wl
,
u8
ac
,
u8
cw_min
,
u16
cw_max
,
u8
aifsn
,
u16
txop
);
int
wl1271_acx_tid_cfg
(
struct
wl1271
*
wl
,
u8
queue_id
,
u8
channel_type
,
...
...
@@ -1185,6 +1262,12 @@ int wl1271_acx_set_ht_capabilities(struct wl1271 *wl,
bool
allow_ht_operation
);
int
wl1271_acx_set_ht_information
(
struct
wl1271
*
wl
,
u16
ht_operation_mode
);
int
wl1271_acx_set_ba_session
(
struct
wl1271
*
wl
,
enum
ieee80211_back_parties
direction
,
u8
tid_index
,
u8
policy
);
int
wl1271_acx_set_ba_receiver_session
(
struct
wl1271
*
wl
,
u8
tid_index
,
u16
ssn
,
bool
enable
);
int
wl1271_acx_tsf_info
(
struct
wl1271
*
wl
,
u64
*
mactime
);
int
wl1271_acx_max_tx_retry
(
struct
wl1271
*
wl
);
#endif
/* __WL1271_ACX_H__ */
drivers/net/wireless/wl12xx/boot.c
浏览文件 @
cbdbc5eb
...
...
@@ -28,6 +28,7 @@
#include "boot.h"
#include "io.h"
#include "event.h"
#include "rx.h"
static
struct
wl1271_partition_set
part_table
[
PART_TABLE_LEN
]
=
{
[
PART_DOWN
]
=
{
...
...
@@ -100,6 +101,22 @@ static void wl1271_boot_set_ecpu_ctrl(struct wl1271 *wl, u32 flag)
wl1271_write32
(
wl
,
ACX_REG_ECPU_CONTROL
,
cpu_ctrl
);
}
static
void
wl1271_parse_fw_ver
(
struct
wl1271
*
wl
)
{
int
ret
;
ret
=
sscanf
(
wl
->
chip
.
fw_ver_str
+
4
,
"%u.%u.%u.%u.%u"
,
&
wl
->
chip
.
fw_ver
[
0
],
&
wl
->
chip
.
fw_ver
[
1
],
&
wl
->
chip
.
fw_ver
[
2
],
&
wl
->
chip
.
fw_ver
[
3
],
&
wl
->
chip
.
fw_ver
[
4
]);
if
(
ret
!=
5
)
{
wl1271_warning
(
"fw version incorrect value"
);
memset
(
wl
->
chip
.
fw_ver
,
0
,
sizeof
(
wl
->
chip
.
fw_ver
));
return
;
}
}
static
void
wl1271_boot_fw_version
(
struct
wl1271
*
wl
)
{
struct
wl1271_static_data
static_data
;
...
...
@@ -107,11 +124,13 @@ static void wl1271_boot_fw_version(struct wl1271 *wl)
wl1271_read
(
wl
,
wl
->
cmd_box_addr
,
&
static_data
,
sizeof
(
static_data
),
false
);
strncpy
(
wl
->
chip
.
fw_ver
,
static_data
.
fw_version
,
sizeof
(
wl
->
chip
.
fw_ver
));
strncpy
(
wl
->
chip
.
fw_ver
_str
,
static_data
.
fw_version
,
sizeof
(
wl
->
chip
.
fw_ver
_str
));
/* make sure the string is NULL-terminated */
wl
->
chip
.
fw_ver
[
sizeof
(
wl
->
chip
.
fw_ver
)
-
1
]
=
'\0'
;
wl
->
chip
.
fw_ver_str
[
sizeof
(
wl
->
chip
.
fw_ver_str
)
-
1
]
=
'\0'
;
wl1271_parse_fw_ver
(
wl
);
}
static
int
wl1271_boot_upload_firmware_chunk
(
struct
wl1271
*
wl
,
void
*
buf
,
...
...
@@ -231,7 +250,9 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl)
*/
if
(
wl
->
nvs_len
==
sizeof
(
struct
wl1271_nvs_file
)
||
wl
->
nvs_len
==
WL1271_INI_LEGACY_NVS_FILE_SIZE
)
{
if
(
wl
->
nvs
->
general_params
.
dual_mode_select
)
/* for now 11a is unsupported in AP mode */
if
(
wl
->
bss_type
!=
BSS_TYPE_AP_BSS
&&
wl
->
nvs
->
general_params
.
dual_mode_select
)
wl
->
enable_11a
=
true
;
}
...
...
@@ -431,6 +452,9 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl)
PSPOLL_DELIVERY_FAILURE_EVENT_ID
|
SOFT_GEMINI_SENSE_EVENT_ID
;
if
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
)
wl
->
event_mask
|=
STA_REMOVE_COMPLETE_EVENT_ID
;
ret
=
wl1271_event_unmask
(
wl
);
if
(
ret
<
0
)
{
wl1271_error
(
"EVENT mask setting failed"
);
...
...
@@ -595,8 +619,7 @@ int wl1271_boot(struct wl1271 *wl)
wl1271_boot_enable_interrupts
(
wl
);
/* set the wl1271 default filters */
wl
->
rx_config
=
WL1271_DEFAULT_RX_CONFIG
;
wl
->
rx_filter
=
WL1271_DEFAULT_RX_FILTER
;
wl1271_set_default_filters
(
wl
);
wl1271_event_mbox_config
(
wl
);
...
...
drivers/net/wireless/wl12xx/cmd.c
浏览文件 @
cbdbc5eb
...
...
@@ -36,6 +36,7 @@
#include "wl12xx_80211.h"
#include "cmd.h"
#include "event.h"
#include "tx.h"
#define WL1271_CMD_FAST_POLL_COUNT 50
...
...
@@ -221,7 +222,7 @@ int wl1271_cmd_ext_radio_parms(struct wl1271 *wl)
* Poll the mailbox event field until any of the bits in the mask is set or a
* timeout occurs (WL1271_EVENT_TIMEOUT in msecs)
*/
static
int
wl1271_cmd_wait_for_event
(
struct
wl1271
*
wl
,
u32
mask
)
static
int
wl1271_cmd_wait_for_event
_or_timeout
(
struct
wl1271
*
wl
,
u32
mask
)
{
u32
events_vector
,
event
;
unsigned
long
timeout
;
...
...
@@ -230,7 +231,8 @@ static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask)
do
{
if
(
time_after
(
jiffies
,
timeout
))
{
ieee80211_queue_work
(
wl
->
hw
,
&
wl
->
recovery_work
);
wl1271_debug
(
DEBUG_CMD
,
"timeout waiting for event %d"
,
(
int
)
mask
);
return
-
ETIMEDOUT
;
}
...
...
@@ -248,6 +250,19 @@ static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask)
return
0
;
}
static
int
wl1271_cmd_wait_for_event
(
struct
wl1271
*
wl
,
u32
mask
)
{
int
ret
;
ret
=
wl1271_cmd_wait_for_event_or_timeout
(
wl
,
mask
);
if
(
ret
!=
0
)
{
ieee80211_queue_work
(
wl
->
hw
,
&
wl
->
recovery_work
);
return
ret
;
}
return
0
;
}
int
wl1271_cmd_join
(
struct
wl1271
*
wl
,
u8
bss_type
)
{
struct
wl1271_cmd_join
*
join
;
...
...
@@ -490,8 +505,8 @@ int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
cmd
->
len
=
cpu_to_le16
(
buf_len
);
cmd
->
template_type
=
template_id
;
cmd
->
enabled_rates
=
cpu_to_le32
(
rates
);
cmd
->
short_retry_limit
=
wl
->
conf
.
tx
.
rc_conf
.
short_retry_limit
;
cmd
->
long_retry_limit
=
wl
->
conf
.
tx
.
rc_conf
.
long_retry_limit
;
cmd
->
short_retry_limit
=
wl
->
conf
.
tx
.
tmpl_
short_retry_limit
;
cmd
->
long_retry_limit
=
wl
->
conf
.
tx
.
tmpl_
long_retry_limit
;
cmd
->
index
=
index
;
if
(
buf
)
...
...
@@ -659,15 +674,15 @@ int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, __be32 ip_addr)
/* llc layer */
memcpy
(
tmpl
.
llc_hdr
,
rfc1042_header
,
sizeof
(
rfc1042_header
));
tmpl
.
llc_type
=
htons
(
ETH_P_ARP
);
tmpl
.
llc_type
=
cpu_to_be16
(
ETH_P_ARP
);
/* arp header */
arp_hdr
=
&
tmpl
.
arp_hdr
;
arp_hdr
->
ar_hrd
=
htons
(
ARPHRD_ETHER
);
arp_hdr
->
ar_pro
=
htons
(
ETH_P_IP
);
arp_hdr
->
ar_hrd
=
cpu_to_be16
(
ARPHRD_ETHER
);
arp_hdr
->
ar_pro
=
cpu_to_be16
(
ETH_P_IP
);
arp_hdr
->
ar_hln
=
ETH_ALEN
;
arp_hdr
->
ar_pln
=
4
;
arp_hdr
->
ar_op
=
htons
(
ARPOP_REPLY
);
arp_hdr
->
ar_op
=
cpu_to_be16
(
ARPOP_REPLY
);
/* arp payload */
memcpy
(
tmpl
.
sender_hw
,
wl
->
vif
->
addr
,
ETH_ALEN
);
...
...
@@ -702,9 +717,9 @@ int wl1271_build_qos_null_data(struct wl1271 *wl)
wl
->
basic_rate
);
}
int
wl1271_cmd_set_default_wep_key
(
struct
wl1271
*
wl
,
u8
id
)
int
wl1271_cmd_set_
sta_
default_wep_key
(
struct
wl1271
*
wl
,
u8
id
)
{
struct
wl1271_cmd_set_keys
*
cmd
;
struct
wl1271_cmd_set_
sta_
keys
*
cmd
;
int
ret
=
0
;
wl1271_debug
(
DEBUG_CMD
,
"cmd set_default_wep_key %d"
,
id
);
...
...
@@ -731,11 +746,42 @@ int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id)
return
ret
;
}
int
wl1271_cmd_set_key
(
struct
wl1271
*
wl
,
u16
action
,
u8
id
,
u8
key_type
,
int
wl1271_cmd_set_ap_default_wep_key
(
struct
wl1271
*
wl
,
u8
id
)
{
struct
wl1271_cmd_set_ap_keys
*
cmd
;
int
ret
=
0
;
wl1271_debug
(
DEBUG_CMD
,
"cmd set_ap_default_wep_key %d"
,
id
);
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
cmd
->
hlid
=
WL1271_AP_BROADCAST_HLID
;
cmd
->
key_id
=
id
;
cmd
->
lid_key_type
=
WEP_DEFAULT_LID_TYPE
;
cmd
->
key_action
=
cpu_to_le16
(
KEY_SET_ID
);
cmd
->
key_type
=
KEY_WEP
;
ret
=
wl1271_cmd_send
(
wl
,
CMD_SET_KEYS
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_warning
(
"cmd set_ap_default_wep_key failed: %d"
,
ret
);
goto
out
;
}
out:
kfree
(
cmd
);
return
ret
;
}
int
wl1271_cmd_set_sta_key
(
struct
wl1271
*
wl
,
u16
action
,
u8
id
,
u8
key_type
,
u8
key_size
,
const
u8
*
key
,
const
u8
*
addr
,
u32
tx_seq_32
,
u16
tx_seq_16
)
{
struct
wl1271_cmd_set_keys
*
cmd
;
struct
wl1271_cmd_set_
sta_
keys
*
cmd
;
int
ret
=
0
;
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
...
...
@@ -788,6 +834,67 @@ int wl1271_cmd_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
return
ret
;
}
int
wl1271_cmd_set_ap_key
(
struct
wl1271
*
wl
,
u16
action
,
u8
id
,
u8
key_type
,
u8
key_size
,
const
u8
*
key
,
u8
hlid
,
u32
tx_seq_32
,
u16
tx_seq_16
)
{
struct
wl1271_cmd_set_ap_keys
*
cmd
;
int
ret
=
0
;
u8
lid_type
;
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
return
-
ENOMEM
;
if
(
hlid
==
WL1271_AP_BROADCAST_HLID
)
{
if
(
key_type
==
KEY_WEP
)
lid_type
=
WEP_DEFAULT_LID_TYPE
;
else
lid_type
=
BROADCAST_LID_TYPE
;
}
else
{
lid_type
=
UNICAST_LID_TYPE
;
}
wl1271_debug
(
DEBUG_CRYPT
,
"ap key action: %d id: %d lid: %d type: %d"
" hlid: %d"
,
(
int
)
action
,
(
int
)
id
,
(
int
)
lid_type
,
(
int
)
key_type
,
(
int
)
hlid
);
cmd
->
lid_key_type
=
lid_type
;
cmd
->
hlid
=
hlid
;
cmd
->
key_action
=
cpu_to_le16
(
action
);
cmd
->
key_size
=
key_size
;
cmd
->
key_type
=
key_type
;
cmd
->
key_id
=
id
;
cmd
->
ac_seq_num16
[
0
]
=
cpu_to_le16
(
tx_seq_16
);
cmd
->
ac_seq_num32
[
0
]
=
cpu_to_le32
(
tx_seq_32
);
if
(
key_type
==
KEY_TKIP
)
{
/*
* We get the key in the following form:
* TKIP (16 bytes) - TX MIC (8 bytes) - RX MIC (8 bytes)
* but the target is expecting:
* TKIP - RX MIC - TX MIC
*/
memcpy
(
cmd
->
key
,
key
,
16
);
memcpy
(
cmd
->
key
+
16
,
key
+
24
,
8
);
memcpy
(
cmd
->
key
+
24
,
key
+
16
,
8
);
}
else
{
memcpy
(
cmd
->
key
,
key
,
key_size
);
}
wl1271_dump
(
DEBUG_CRYPT
,
"TARGET AP KEY: "
,
cmd
,
sizeof
(
*
cmd
));
ret
=
wl1271_cmd_send
(
wl
,
CMD_SET_KEYS
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_warning
(
"could not set ap keys"
);
goto
out
;
}
out:
kfree
(
cmd
);
return
ret
;
}
int
wl1271_cmd_disconnect
(
struct
wl1271
*
wl
)
{
struct
wl1271_cmd_disconnect
*
cmd
;
...
...
@@ -850,3 +957,180 @@ int wl1271_cmd_set_sta_state(struct wl1271 *wl)
out:
return
ret
;
}
int
wl1271_cmd_start_bss
(
struct
wl1271
*
wl
)
{
struct
wl1271_cmd_bss_start
*
cmd
;
struct
ieee80211_bss_conf
*
bss_conf
=
&
wl
->
vif
->
bss_conf
;
int
ret
;
wl1271_debug
(
DEBUG_CMD
,
"cmd start bss"
);
/*
* FIXME: We currently do not support hidden SSID. The real SSID
* should be fetched from mac80211 first.
*/
if
(
wl
->
ssid_len
==
0
)
{
wl1271_warning
(
"Hidden SSID currently not supported for AP"
);
ret
=
-
EINVAL
;
goto
out
;
}
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
memcpy
(
cmd
->
bssid
,
bss_conf
->
bssid
,
ETH_ALEN
);
cmd
->
aging_period
=
cpu_to_le16
(
WL1271_AP_DEF_INACTIV_SEC
);
cmd
->
bss_index
=
WL1271_AP_BSS_INDEX
;
cmd
->
global_hlid
=
WL1271_AP_GLOBAL_HLID
;
cmd
->
broadcast_hlid
=
WL1271_AP_BROADCAST_HLID
;
cmd
->
basic_rate_set
=
cpu_to_le32
(
wl
->
basic_rate_set
);
cmd
->
beacon_interval
=
cpu_to_le16
(
wl
->
beacon_int
);
cmd
->
dtim_interval
=
bss_conf
->
dtim_period
;
cmd
->
beacon_expiry
=
WL1271_AP_DEF_BEACON_EXP
;
cmd
->
channel
=
wl
->
channel
;
cmd
->
ssid_len
=
wl
->
ssid_len
;
cmd
->
ssid_type
=
SSID_TYPE_PUBLIC
;
memcpy
(
cmd
->
ssid
,
wl
->
ssid
,
wl
->
ssid_len
);
switch
(
wl
->
band
)
{
case
IEEE80211_BAND_2GHZ
:
cmd
->
band
=
RADIO_BAND_2_4GHZ
;
break
;
case
IEEE80211_BAND_5GHZ
:
cmd
->
band
=
RADIO_BAND_5GHZ
;
break
;
default:
wl1271_warning
(
"bss start - unknown band: %d"
,
(
int
)
wl
->
band
);
cmd
->
band
=
RADIO_BAND_2_4GHZ
;
break
;
}
ret
=
wl1271_cmd_send
(
wl
,
CMD_BSS_START
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to initiate cmd start bss"
);
goto
out_free
;
}
out_free:
kfree
(
cmd
);
out:
return
ret
;
}
int
wl1271_cmd_stop_bss
(
struct
wl1271
*
wl
)
{
struct
wl1271_cmd_bss_start
*
cmd
;
int
ret
;
wl1271_debug
(
DEBUG_CMD
,
"cmd stop bss"
);
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
cmd
->
bss_index
=
WL1271_AP_BSS_INDEX
;
ret
=
wl1271_cmd_send
(
wl
,
CMD_BSS_STOP
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to initiate cmd stop bss"
);
goto
out_free
;
}
out_free:
kfree
(
cmd
);
out:
return
ret
;
}
int
wl1271_cmd_add_sta
(
struct
wl1271
*
wl
,
struct
ieee80211_sta
*
sta
,
u8
hlid
)
{
struct
wl1271_cmd_add_sta
*
cmd
;
int
ret
;
wl1271_debug
(
DEBUG_CMD
,
"cmd add sta %d"
,
(
int
)
hlid
);
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
/* currently we don't support UAPSD */
cmd
->
sp_len
=
0
;
memcpy
(
cmd
->
addr
,
sta
->
addr
,
ETH_ALEN
);
cmd
->
bss_index
=
WL1271_AP_BSS_INDEX
;
cmd
->
aid
=
sta
->
aid
;
cmd
->
hlid
=
hlid
;
/*
* FIXME: Does STA support QOS? We need to propagate this info from
* hostapd. Currently not that important since this is only used for
* sending the correct flavor of null-data packet in response to a
* trigger.
*/
cmd
->
wmm
=
0
;
cmd
->
supported_rates
=
cpu_to_le32
(
wl1271_tx_enabled_rates_get
(
wl
,
sta
->
supp_rates
[
wl
->
band
]));
wl1271_debug
(
DEBUG_CMD
,
"new sta rates: 0x%x"
,
cmd
->
supported_rates
);
ret
=
wl1271_cmd_send
(
wl
,
CMD_ADD_STA
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to initiate cmd add sta"
);
goto
out_free
;
}
out_free:
kfree
(
cmd
);
out:
return
ret
;
}
int
wl1271_cmd_remove_sta
(
struct
wl1271
*
wl
,
u8
hlid
)
{
struct
wl1271_cmd_remove_sta
*
cmd
;
int
ret
;
wl1271_debug
(
DEBUG_CMD
,
"cmd remove sta %d"
,
(
int
)
hlid
);
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
cmd
->
hlid
=
hlid
;
/* We never send a deauth, mac80211 is in charge of this */
cmd
->
reason_opcode
=
0
;
cmd
->
send_deauth_flag
=
0
;
ret
=
wl1271_cmd_send
(
wl
,
CMD_REMOVE_STA
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to initiate cmd remove sta"
);
goto
out_free
;
}
/*
* We are ok with a timeout here. The event is sometimes not sent
* due to a firmware bug.
*/
wl1271_cmd_wait_for_event_or_timeout
(
wl
,
STA_REMOVE_COMPLETE_EVENT_ID
);
out_free:
kfree
(
cmd
);
out:
return
ret
;
}
drivers/net/wireless/wl12xx/cmd.h
浏览文件 @
cbdbc5eb
...
...
@@ -54,12 +54,20 @@ struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl,
int
wl1271_cmd_build_arp_rsp
(
struct
wl1271
*
wl
,
__be32
ip_addr
);
int
wl1271_build_qos_null_data
(
struct
wl1271
*
wl
);
int
wl1271_cmd_build_klv_null_data
(
struct
wl1271
*
wl
);
int
wl1271_cmd_set_default_wep_key
(
struct
wl1271
*
wl
,
u8
id
);
int
wl1271_cmd_set_key
(
struct
wl1271
*
wl
,
u16
action
,
u8
id
,
u8
key_type
,
u8
key_size
,
const
u8
*
key
,
const
u8
*
addr
,
u32
tx_seq_32
,
u16
tx_seq_16
);
int
wl1271_cmd_set_sta_default_wep_key
(
struct
wl1271
*
wl
,
u8
id
);
int
wl1271_cmd_set_ap_default_wep_key
(
struct
wl1271
*
wl
,
u8
id
);
int
wl1271_cmd_set_sta_key
(
struct
wl1271
*
wl
,
u16
action
,
u8
id
,
u8
key_type
,
u8
key_size
,
const
u8
*
key
,
const
u8
*
addr
,
u32
tx_seq_32
,
u16
tx_seq_16
);
int
wl1271_cmd_set_ap_key
(
struct
wl1271
*
wl
,
u16
action
,
u8
id
,
u8
key_type
,
u8
key_size
,
const
u8
*
key
,
u8
hlid
,
u32
tx_seq_32
,
u16
tx_seq_16
);
int
wl1271_cmd_disconnect
(
struct
wl1271
*
wl
);
int
wl1271_cmd_set_sta_state
(
struct
wl1271
*
wl
);
int
wl1271_cmd_start_bss
(
struct
wl1271
*
wl
);
int
wl1271_cmd_stop_bss
(
struct
wl1271
*
wl
);
int
wl1271_cmd_add_sta
(
struct
wl1271
*
wl
,
struct
ieee80211_sta
*
sta
,
u8
hlid
);
int
wl1271_cmd_remove_sta
(
struct
wl1271
*
wl
,
u8
hlid
);
enum
wl1271_commands
{
CMD_INTERROGATE
=
1
,
/*use this to read information elements*/
...
...
@@ -98,6 +106,12 @@ enum wl1271_commands {
CMD_STOP_PERIODIC_SCAN
=
51
,
CMD_SET_STA_STATE
=
52
,
/* AP mode commands */
CMD_BSS_START
=
60
,
CMD_BSS_STOP
=
61
,
CMD_ADD_STA
=
62
,
CMD_REMOVE_STA
=
63
,
NUM_COMMANDS
,
MAX_COMMAND_ID
=
0xFFFF
,
};
...
...
@@ -126,6 +140,13 @@ enum cmd_templ {
* For CTS-to-self (FastCTS) mechanism
* for BT/WLAN coexistence (SoftGemini). */
CMD_TEMPL_ARP_RSP
,
/* AP-mode specific */
CMD_TEMPL_AP_BEACON
=
13
,
CMD_TEMPL_AP_PROBE_RESPONSE
,
CMD_TEMPL_AP_ARP_RSP
,
CMD_TEMPL_DEAUTH_AP
,
CMD_TEMPL_MAX
=
0xff
};
...
...
@@ -270,7 +291,6 @@ struct wl1271_cmd_ps_params {
/* HW encryption keys */
#define NUM_ACCESS_CATEGORIES_COPY 4
#define MAX_KEY_SIZE 32
enum
wl1271_cmd_key_action
{
KEY_ADD_OR_REPLACE
=
1
,
...
...
@@ -289,7 +309,7 @@ enum wl1271_cmd_key_type {
/* FIXME: Add description for key-types */
struct
wl1271_cmd_set_keys
{
struct
wl1271_cmd_set_
sta_
keys
{
struct
wl1271_cmd_header
header
;
/* Ignored for default WEP key */
...
...
@@ -318,6 +338,57 @@ struct wl1271_cmd_set_keys {
__le32
ac_seq_num32
[
NUM_ACCESS_CATEGORIES_COPY
];
}
__packed
;
enum
wl1271_cmd_lid_key_type
{
UNICAST_LID_TYPE
=
0
,
BROADCAST_LID_TYPE
=
1
,
WEP_DEFAULT_LID_TYPE
=
2
};
struct
wl1271_cmd_set_ap_keys
{
struct
wl1271_cmd_header
header
;
/*
* Indicates whether the HLID is a unicast key set
* or broadcast key set. A special value 0xFF is
* used to indicate that the HLID is on WEP-default
* (multi-hlids). of type wl1271_cmd_lid_key_type.
*/
u8
hlid
;
/*
* In WEP-default network (hlid == 0xFF) used to
* indicate which network STA/IBSS/AP role should be
* changed
*/
u8
lid_key_type
;
/*
* Key ID - For TKIP and AES key types, this field
* indicates the value that should be inserted into
* the KeyID field of frames transmitted using this
* key entry. For broadcast keys the index use as a
* marker for TX/RX key.
* For WEP default network (HLID=0xFF), this field
* indicates the ID of the key to add or remove.
*/
u8
key_id
;
u8
reserved_1
;
/* key_action_e */
__le16
key_action
;
/* key size in bytes */
u8
key_size
;
/* key_type_e */
u8
key_type
;
/* This field holds the security key data to add to the STA table */
u8
key
[
MAX_KEY_SIZE
];
__le16
ac_seq_num16
[
NUM_ACCESS_CATEGORIES_COPY
];
__le32
ac_seq_num32
[
NUM_ACCESS_CATEGORIES_COPY
];
}
__packed
;
struct
wl1271_cmd_test_header
{
u8
id
;
u8
padding
[
3
];
...
...
@@ -412,4 +483,68 @@ struct wl1271_cmd_set_sta_state {
u8
padding
[
3
];
}
__packed
;
enum
wl1271_ssid_type
{
SSID_TYPE_PUBLIC
=
0
,
SSID_TYPE_HIDDEN
=
1
};
struct
wl1271_cmd_bss_start
{
struct
wl1271_cmd_header
header
;
/* wl1271_ssid_type */
u8
ssid_type
;
u8
ssid_len
;
u8
ssid
[
IW_ESSID_MAX_SIZE
];
u8
padding_1
[
2
];
/* Basic rate set */
__le32
basic_rate_set
;
/* Aging period in seconds*/
__le16
aging_period
;
/*
* This field specifies the time between target beacon
* transmission times (TBTTs), in time units (TUs).
* Valid values are 1 to 1024.
*/
__le16
beacon_interval
;
u8
bssid
[
ETH_ALEN
];
u8
bss_index
;
/* Radio band */
u8
band
;
u8
channel
;
/* The host link id for the AP's global queue */
u8
global_hlid
;
/* The host link id for the AP's broadcast queue */
u8
broadcast_hlid
;
/* DTIM count */
u8
dtim_interval
;
/* Beacon expiry time in ms */
u8
beacon_expiry
;
u8
padding_2
[
3
];
}
__packed
;
struct
wl1271_cmd_add_sta
{
struct
wl1271_cmd_header
header
;
u8
addr
[
ETH_ALEN
];
u8
hlid
;
u8
aid
;
u8
psd_type
[
NUM_ACCESS_CATEGORIES_COPY
];
__le32
supported_rates
;
u8
bss_index
;
u8
sp_len
;
u8
wmm
;
u8
padding1
;
}
__packed
;
struct
wl1271_cmd_remove_sta
{
struct
wl1271_cmd_header
header
;
u8
hlid
;
u8
reason_opcode
;
u8
send_deauth_flag
;
u8
padding1
;
}
__packed
;
#endif
/* __WL1271_CMD_H__ */
drivers/net/wireless/wl12xx/conf.h
浏览文件 @
cbdbc5eb
...
...
@@ -496,6 +496,26 @@ struct conf_rx_settings {
CONF_HW_BIT_RATE_2MBPS)
#define CONF_TX_RATE_RETRY_LIMIT 10
/*
* Rates supported for data packets when operating as AP. Note the absense
* of the 22Mbps rate. There is a FW limitation on 12 rates so we must drop
* one. The rate dropped is not mandatory under any operating mode.
*/
#define CONF_TX_AP_ENABLED_RATES (CONF_HW_BIT_RATE_1MBPS | \
CONF_HW_BIT_RATE_2MBPS | CONF_HW_BIT_RATE_5_5MBPS | \
CONF_HW_BIT_RATE_6MBPS | CONF_HW_BIT_RATE_9MBPS | \
CONF_HW_BIT_RATE_11MBPS | CONF_HW_BIT_RATE_12MBPS | \
CONF_HW_BIT_RATE_18MBPS | CONF_HW_BIT_RATE_24MBPS | \
CONF_HW_BIT_RATE_36MBPS | CONF_HW_BIT_RATE_48MBPS | \
CONF_HW_BIT_RATE_54MBPS)
/*
* Default rates for management traffic when operating in AP mode. This
* should be configured according to the basic rate set of the AP
*/
#define CONF_TX_AP_DEFAULT_MGMT_RATES (CONF_HW_BIT_RATE_1MBPS | \
CONF_HW_BIT_RATE_2MBPS | CONF_HW_BIT_RATE_5_5MBPS)
struct
conf_tx_rate_class
{
/*
...
...
@@ -636,9 +656,9 @@ struct conf_tx_settings {
/*
* Configuration for rate classes for TX (currently only one
* rate class supported
.)
* rate class supported
). Used in non-AP mode.
*/
struct
conf_tx_rate_class
rc_conf
;
struct
conf_tx_rate_class
sta_
rc_conf
;
/*
* Configuration for access categories for TX rate control.
...
...
@@ -646,6 +666,28 @@ struct conf_tx_settings {
u8
ac_conf_count
;
struct
conf_tx_ac_category
ac_conf
[
CONF_TX_MAX_AC_COUNT
];
/*
* Configuration for rate classes in AP-mode. These rate classes
* are for the AC TX queues
*/
struct
conf_tx_rate_class
ap_rc_conf
[
CONF_TX_MAX_AC_COUNT
];
/*
* Management TX rate class for AP-mode.
*/
struct
conf_tx_rate_class
ap_mgmt_conf
;
/*
* Broadcast TX rate class for AP-mode.
*/
struct
conf_tx_rate_class
ap_bcst_conf
;
/*
* AP-mode - allow this number of TX retries to a station before an
* event is triggered from FW.
*/
u16
ap_max_tx_retries
;
/*
* Configuration for TID parameters.
*/
...
...
@@ -687,6 +729,12 @@ struct conf_tx_settings {
* Range: CONF_HW_BIT_RATE_* bit mask
*/
u32
basic_rate_5
;
/*
* TX retry limits for templates
*/
u8
tmpl_short_retry_limit
;
u8
tmpl_long_retry_limit
;
};
enum
{
...
...
@@ -1036,30 +1084,30 @@ struct conf_scan_settings {
/*
* The minimum time to wait on each channel for active scans
*
* Range:
0 - 65536 tu
* Range:
u32 tu/1000
*/
u
16
min_dwell_time_active
;
u
32
min_dwell_time_active
;
/*
* The maximum time to wait on each channel for active scans
*
* Range:
0 - 65536 tu
* Range:
u32 tu/1000
*/
u
16
max_dwell_time_active
;
u
32
max_dwell_time_active
;
/*
* The m
ax
imum time to wait on each channel for passive scans
* The m
in
imum time to wait on each channel for passive scans
*
* Range:
0 - 65536 tu
* Range:
u32 tu/1000
*/
u
16
min_dwell_time_passive
;
u
32
min_dwell_time_passive
;
/*
* The maximum time to wait on each channel for passive scans
*
* Range:
0 - 65536 tu
* Range:
u32 tu/1000
*/
u
16
max_dwell_time_passive
;
u
32
max_dwell_time_passive
;
/*
* Number of probe requests to transmit on each active scan channel
...
...
@@ -1090,6 +1138,11 @@ struct conf_rf_settings {
u8
tx_per_channel_power_compensation_5
[
CONF_TX_PWR_COMPENSATION_LEN_5
];
};
struct
conf_ht_setting
{
u16
tx_ba_win_size
;
u16
inactivity_timeout
;
};
struct
conf_drv_settings
{
struct
conf_sg_settings
sg
;
struct
conf_rx_settings
rx
;
...
...
@@ -1100,6 +1153,7 @@ struct conf_drv_settings {
struct
conf_roam_trigger_settings
roam_trigger
;
struct
conf_scan_settings
scan
;
struct
conf_rf_settings
rf
;
struct
conf_ht_setting
ht
;
};
#endif
drivers/net/wireless/wl12xx/debugfs.c
浏览文件 @
cbdbc5eb
...
...
@@ -261,27 +261,25 @@ static ssize_t gpio_power_write(struct file *file,
unsigned
long
value
;
int
ret
;
mutex_lock
(
&
wl
->
mutex
);
len
=
min
(
count
,
sizeof
(
buf
)
-
1
);
if
(
copy_from_user
(
buf
,
user_buf
,
len
))
{
ret
=
-
EFAULT
;
goto
out
;
return
-
EFAULT
;
}
buf
[
len
]
=
'\0'
;
ret
=
strict_strtoul
(
buf
,
0
,
&
value
);
if
(
ret
<
0
)
{
wl1271_warning
(
"illegal value in gpio_power"
);
goto
out
;
return
-
EINVAL
;
}
mutex_lock
(
&
wl
->
mutex
);
if
(
value
)
wl1271_power_on
(
wl
);
else
wl1271_power_off
(
wl
);
out:
mutex_unlock
(
&
wl
->
mutex
);
return
count
;
}
...
...
@@ -293,12 +291,13 @@ static const struct file_operations gpio_power_ops = {
.
llseek
=
default_llseek
,
};
static
int
wl1271_debugfs_add_files
(
struct
wl1271
*
wl
)
static
int
wl1271_debugfs_add_files
(
struct
wl1271
*
wl
,
struct
dentry
*
rootdir
)
{
int
ret
=
0
;
struct
dentry
*
entry
,
*
stats
;
stats
=
debugfs_create_dir
(
"fw-statistics"
,
wl
->
rootdir
);
stats
=
debugfs_create_dir
(
"fw-statistics"
,
rootdir
);
if
(
!
stats
||
IS_ERR
(
stats
))
{
entry
=
stats
;
goto
err
;
...
...
@@ -395,16 +394,11 @@ static int wl1271_debugfs_add_files(struct wl1271 *wl)
DEBUGFS_FWSTATS_ADD
(
rxpipe
,
missed_beacon_host_int_trig_rx_data
);
DEBUGFS_FWSTATS_ADD
(
rxpipe
,
tx_xfr_host_int_trig_rx_data
);
DEBUGFS_ADD
(
tx_queue_len
,
wl
->
rootdir
);
DEBUGFS_ADD
(
retry_count
,
wl
->
rootdir
);
DEBUGFS_ADD
(
excessive_retries
,
wl
->
rootdir
);
DEBUGFS_ADD
(
gpio_power
,
wl
->
rootdir
);
DEBUGFS_ADD
(
tx_queue_len
,
rootdir
);
DEBUGFS_ADD
(
retry_count
,
rootdir
);
DEBUGFS_ADD
(
excessive_retries
,
rootdir
);
entry
=
debugfs_create_x32
(
"debug_level"
,
0600
,
wl
->
rootdir
,
&
wl12xx_debug_level
);
if
(
!
entry
||
IS_ERR
(
entry
))
goto
err
;
DEBUGFS_ADD
(
gpio_power
,
rootdir
);
return
0
;
...
...
@@ -419,7 +413,7 @@ static int wl1271_debugfs_add_files(struct wl1271 *wl)
void
wl1271_debugfs_reset
(
struct
wl1271
*
wl
)
{
if
(
!
wl
->
rootdir
)
if
(
!
wl
->
stats
.
fw_stats
)
return
;
memset
(
wl
->
stats
.
fw_stats
,
0
,
sizeof
(
*
wl
->
stats
.
fw_stats
));
...
...
@@ -430,13 +424,13 @@ void wl1271_debugfs_reset(struct wl1271 *wl)
int
wl1271_debugfs_init
(
struct
wl1271
*
wl
)
{
int
ret
;
struct
dentry
*
rootdir
;
wl
->
rootdir
=
debugfs_create_dir
(
KBUILD_MODNAME
,
wl
->
hw
->
wiphy
->
debugfsdir
);
rootdir
=
debugfs_create_dir
(
KBUILD_MODNAME
,
wl
->
hw
->
wiphy
->
debugfsdir
);
if
(
IS_ERR
(
wl
->
rootdir
))
{
ret
=
PTR_ERR
(
wl
->
rootdir
);
wl
->
rootdir
=
NULL
;
if
(
IS_ERR
(
rootdir
))
{
ret
=
PTR_ERR
(
rootdir
);
goto
err
;
}
...
...
@@ -450,7 +444,7 @@ int wl1271_debugfs_init(struct wl1271 *wl)
wl
->
stats
.
fw_stats_update
=
jiffies
;
ret
=
wl1271_debugfs_add_files
(
wl
);
ret
=
wl1271_debugfs_add_files
(
wl
,
rootdir
);
if
(
ret
<
0
)
goto
err_file
;
...
...
@@ -462,8 +456,7 @@ int wl1271_debugfs_init(struct wl1271 *wl)
wl
->
stats
.
fw_stats
=
NULL
;
err_fw:
debugfs_remove_recursive
(
wl
->
rootdir
);
wl
->
rootdir
=
NULL
;
debugfs_remove_recursive
(
rootdir
);
err:
return
ret
;
...
...
@@ -473,8 +466,4 @@ void wl1271_debugfs_exit(struct wl1271 *wl)
{
kfree
(
wl
->
stats
.
fw_stats
);
wl
->
stats
.
fw_stats
=
NULL
;
debugfs_remove_recursive
(
wl
->
rootdir
);
wl
->
rootdir
=
NULL
;
}
drivers/net/wireless/wl12xx/event.c
浏览文件 @
cbdbc5eb
...
...
@@ -186,6 +186,7 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
int
ret
;
u32
vector
;
bool
beacon_loss
=
false
;
bool
is_ap
=
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
);
wl1271_event_mbox_dump
(
mbox
);
...
...
@@ -218,21 +219,21 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
* BSS_LOSE_EVENT, beacon loss has to be reported to the stack.
*
*/
if
(
vector
&
BSS_LOSE_EVENT_ID
)
{
if
(
(
vector
&
BSS_LOSE_EVENT_ID
)
&&
!
is_ap
)
{
wl1271_info
(
"Beacon loss detected."
);
/* indicate to the stack, that beacons have been lost */
beacon_loss
=
true
;
}
if
(
vector
&
PS_REPORT_EVENT_ID
)
{
if
(
(
vector
&
PS_REPORT_EVENT_ID
)
&&
!
is_ap
)
{
wl1271_debug
(
DEBUG_EVENT
,
"PS_REPORT_EVENT"
);
ret
=
wl1271_event_ps_report
(
wl
,
mbox
,
&
beacon_loss
);
if
(
ret
<
0
)
return
ret
;
}
if
(
vector
&
PSPOLL_DELIVERY_FAILURE_EVENT_ID
)
if
(
(
vector
&
PSPOLL_DELIVERY_FAILURE_EVENT_ID
)
&&
!
is_ap
)
wl1271_event_pspoll_delivery_fail
(
wl
);
if
(
vector
&
RSSI_SNR_TRIGGER_0_EVENT_ID
)
{
...
...
drivers/net/wireless/wl12xx/event.h
浏览文件 @
cbdbc5eb
...
...
@@ -59,6 +59,7 @@ enum {
BSS_LOSE_EVENT_ID
=
BIT
(
18
),
REGAINED_BSS_EVENT_ID
=
BIT
(
19
),
ROAMING_TRIGGER_MAX_TX_RETRY_EVENT_ID
=
BIT
(
20
),
STA_REMOVE_COMPLETE_EVENT_ID
=
BIT
(
21
),
/* AP */
SOFT_GEMINI_SENSE_EVENT_ID
=
BIT
(
22
),
SOFT_GEMINI_PREDICTION_EVENT_ID
=
BIT
(
23
),
SOFT_GEMINI_AVALANCHE_EVENT_ID
=
BIT
(
24
),
...
...
@@ -115,7 +116,12 @@ struct event_mailbox {
u8
scheduled_scan_status
;
u8
ps_status
;
u8
reserved_5
[
29
];
/* AP FW only */
u8
hlid_removed
;
__le16
sta_aging_status
;
__le16
sta_tx_retry_exceeded
;
u8
reserved_5
[
24
];
}
__packed
;
int
wl1271_event_unmask
(
struct
wl1271
*
wl
);
...
...
drivers/net/wireless/wl12xx/init.c
浏览文件 @
cbdbc5eb
...
...
@@ -30,27 +30,9 @@
#include "acx.h"
#include "cmd.h"
#include "reg.h"
#include "tx.h"
static
int
wl1271_init_hwenc_config
(
struct
wl1271
*
wl
)
{
int
ret
;
ret
=
wl1271_acx_feature_cfg
(
wl
);
if
(
ret
<
0
)
{
wl1271_warning
(
"couldn't set feature config"
);
return
ret
;
}
ret
=
wl1271_cmd_set_default_wep_key
(
wl
,
wl
->
default_key
);
if
(
ret
<
0
)
{
wl1271_warning
(
"couldn't set default key"
);
return
ret
;
}
return
0
;
}
int
wl1271_init_templates_config
(
struct
wl1271
*
wl
)
int
wl1271_sta_init_templates_config
(
struct
wl1271
*
wl
)
{
int
ret
,
i
;
...
...
@@ -118,6 +100,132 @@ int wl1271_init_templates_config(struct wl1271 *wl)
return
0
;
}
static
int
wl1271_ap_init_deauth_template
(
struct
wl1271
*
wl
)
{
struct
wl12xx_disconn_template
*
tmpl
;
int
ret
;
tmpl
=
kzalloc
(
sizeof
(
*
tmpl
),
GFP_KERNEL
);
if
(
!
tmpl
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
tmpl
->
header
.
frame_ctl
=
cpu_to_le16
(
IEEE80211_FTYPE_MGMT
|
IEEE80211_STYPE_DEAUTH
);
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_DEAUTH_AP
,
tmpl
,
sizeof
(
*
tmpl
),
0
,
wl1271_tx_min_rate_get
(
wl
));
out:
kfree
(
tmpl
);
return
ret
;
}
static
int
wl1271_ap_init_null_template
(
struct
wl1271
*
wl
)
{
struct
ieee80211_hdr_3addr
*
nullfunc
;
int
ret
;
nullfunc
=
kzalloc
(
sizeof
(
*
nullfunc
),
GFP_KERNEL
);
if
(
!
nullfunc
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
nullfunc
->
frame_control
=
cpu_to_le16
(
IEEE80211_FTYPE_DATA
|
IEEE80211_STYPE_NULLFUNC
|
IEEE80211_FCTL_FROMDS
);
/* nullfunc->addr1 is filled by FW */
memcpy
(
nullfunc
->
addr2
,
wl
->
mac_addr
,
ETH_ALEN
);
memcpy
(
nullfunc
->
addr3
,
wl
->
mac_addr
,
ETH_ALEN
);
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_NULL_DATA
,
nullfunc
,
sizeof
(
*
nullfunc
),
0
,
wl1271_tx_min_rate_get
(
wl
));
out:
kfree
(
nullfunc
);
return
ret
;
}
static
int
wl1271_ap_init_qos_null_template
(
struct
wl1271
*
wl
)
{
struct
ieee80211_qos_hdr
*
qosnull
;
int
ret
;
qosnull
=
kzalloc
(
sizeof
(
*
qosnull
),
GFP_KERNEL
);
if
(
!
qosnull
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
qosnull
->
frame_control
=
cpu_to_le16
(
IEEE80211_FTYPE_DATA
|
IEEE80211_STYPE_QOS_NULLFUNC
|
IEEE80211_FCTL_FROMDS
);
/* qosnull->addr1 is filled by FW */
memcpy
(
qosnull
->
addr2
,
wl
->
mac_addr
,
ETH_ALEN
);
memcpy
(
qosnull
->
addr3
,
wl
->
mac_addr
,
ETH_ALEN
);
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_QOS_NULL_DATA
,
qosnull
,
sizeof
(
*
qosnull
),
0
,
wl1271_tx_min_rate_get
(
wl
));
out:
kfree
(
qosnull
);
return
ret
;
}
static
int
wl1271_ap_init_templates_config
(
struct
wl1271
*
wl
)
{
int
ret
;
/*
* Put very large empty placeholders for all templates. These
* reserve memory for later.
*/
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_AP_PROBE_RESPONSE
,
NULL
,
sizeof
(
struct
wl12xx_probe_resp_template
),
0
,
WL1271_RATE_AUTOMATIC
);
if
(
ret
<
0
)
return
ret
;
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_AP_BEACON
,
NULL
,
sizeof
(
struct
wl12xx_beacon_template
),
0
,
WL1271_RATE_AUTOMATIC
);
if
(
ret
<
0
)
return
ret
;
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_DEAUTH_AP
,
NULL
,
sizeof
(
struct
wl12xx_disconn_template
),
0
,
WL1271_RATE_AUTOMATIC
);
if
(
ret
<
0
)
return
ret
;
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_NULL_DATA
,
NULL
,
sizeof
(
struct
wl12xx_null_data_template
),
0
,
WL1271_RATE_AUTOMATIC
);
if
(
ret
<
0
)
return
ret
;
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_QOS_NULL_DATA
,
NULL
,
sizeof
(
struct
wl12xx_qos_null_data_template
),
0
,
WL1271_RATE_AUTOMATIC
);
if
(
ret
<
0
)
return
ret
;
return
0
;
}
static
int
wl1271_init_rx_config
(
struct
wl1271
*
wl
,
u32
config
,
u32
filter
)
{
int
ret
;
...
...
@@ -145,10 +253,6 @@ int wl1271_init_phy_config(struct wl1271 *wl)
if
(
ret
<
0
)
return
ret
;
ret
=
wl1271_acx_group_address_tbl
(
wl
,
true
,
NULL
,
0
);
if
(
ret
<
0
)
return
ret
;
ret
=
wl1271_acx_service_period_timeout
(
wl
);
if
(
ret
<
0
)
return
ret
;
...
...
@@ -213,11 +317,186 @@ static int wl1271_init_beacon_broadcast(struct wl1271 *wl)
return
0
;
}
static
int
wl1271_sta_hw_init
(
struct
wl1271
*
wl
)
{
int
ret
;
ret
=
wl1271_cmd_ext_radio_parms
(
wl
);
if
(
ret
<
0
)
return
ret
;
ret
=
wl1271_sta_init_templates_config
(
wl
);
if
(
ret
<
0
)
return
ret
;
ret
=
wl1271_acx_group_address_tbl
(
wl
,
true
,
NULL
,
0
);
if
(
ret
<
0
)
return
ret
;
/* Initialize connection monitoring thresholds */
ret
=
wl1271_acx_conn_monit_params
(
wl
,
false
);
if
(
ret
<
0
)
return
ret
;
/* Beacon filtering */
ret
=
wl1271_init_beacon_filter
(
wl
);
if
(
ret
<
0
)
return
ret
;
/* Bluetooth WLAN coexistence */
ret
=
wl1271_init_pta
(
wl
);
if
(
ret
<
0
)
return
ret
;
/* Beacons and broadcast settings */
ret
=
wl1271_init_beacon_broadcast
(
wl
);
if
(
ret
<
0
)
return
ret
;
/* Configure for ELP power saving */
ret
=
wl1271_acx_sleep_auth
(
wl
,
WL1271_PSM_ELP
);
if
(
ret
<
0
)
return
ret
;
/* Configure rssi/snr averaging weights */
ret
=
wl1271_acx_rssi_snr_avg_weights
(
wl
);
if
(
ret
<
0
)
return
ret
;
ret
=
wl1271_acx_sta_rate_policies
(
wl
);
if
(
ret
<
0
)
return
ret
;
return
0
;
}
static
int
wl1271_sta_hw_init_post_mem
(
struct
wl1271
*
wl
)
{
int
ret
,
i
;
ret
=
wl1271_cmd_set_sta_default_wep_key
(
wl
,
wl
->
default_key
);
if
(
ret
<
0
)
{
wl1271_warning
(
"couldn't set default key"
);
return
ret
;
}
/* disable all keep-alive templates */
for
(
i
=
0
;
i
<
CMD_TEMPL_KLV_IDX_MAX
;
i
++
)
{
ret
=
wl1271_acx_keep_alive_config
(
wl
,
i
,
ACX_KEEP_ALIVE_TPL_INVALID
);
if
(
ret
<
0
)
return
ret
;
}
/* disable the keep-alive feature */
ret
=
wl1271_acx_keep_alive_mode
(
wl
,
false
);
if
(
ret
<
0
)
return
ret
;
return
0
;
}
static
int
wl1271_ap_hw_init
(
struct
wl1271
*
wl
)
{
int
ret
,
i
;
ret
=
wl1271_ap_init_templates_config
(
wl
);
if
(
ret
<
0
)
return
ret
;
/* Configure for power always on */
ret
=
wl1271_acx_sleep_auth
(
wl
,
WL1271_PSM_CAM
);
if
(
ret
<
0
)
return
ret
;
/* Configure initial TX rate classes */
for
(
i
=
0
;
i
<
wl
->
conf
.
tx
.
ac_conf_count
;
i
++
)
{
ret
=
wl1271_acx_ap_rate_policy
(
wl
,
&
wl
->
conf
.
tx
.
ap_rc_conf
[
i
],
i
);
if
(
ret
<
0
)
return
ret
;
}
ret
=
wl1271_acx_ap_rate_policy
(
wl
,
&
wl
->
conf
.
tx
.
ap_mgmt_conf
,
ACX_TX_AP_MODE_MGMT_RATE
);
if
(
ret
<
0
)
return
ret
;
ret
=
wl1271_acx_ap_rate_policy
(
wl
,
&
wl
->
conf
.
tx
.
ap_bcst_conf
,
ACX_TX_AP_MODE_BCST_RATE
);
if
(
ret
<
0
)
return
ret
;
ret
=
wl1271_acx_max_tx_retry
(
wl
);
if
(
ret
<
0
)
return
ret
;
return
0
;
}
static
int
wl1271_ap_hw_init_post_mem
(
struct
wl1271
*
wl
)
{
int
ret
;
ret
=
wl1271_ap_init_deauth_template
(
wl
);
if
(
ret
<
0
)
return
ret
;
ret
=
wl1271_ap_init_null_template
(
wl
);
if
(
ret
<
0
)
return
ret
;
ret
=
wl1271_ap_init_qos_null_template
(
wl
);
if
(
ret
<
0
)
return
ret
;
return
0
;
}
static
void
wl1271_check_ba_support
(
struct
wl1271
*
wl
)
{
/* validate FW cose ver x.x.x.50-60.x */
if
((
wl
->
chip
.
fw_ver
[
3
]
>=
WL12XX_BA_SUPPORT_FW_COST_VER2_START
)
&&
(
wl
->
chip
.
fw_ver
[
3
]
<
WL12XX_BA_SUPPORT_FW_COST_VER2_END
))
{
wl
->
ba_support
=
true
;
return
;
}
wl
->
ba_support
=
false
;
}
static
int
wl1271_set_ba_policies
(
struct
wl1271
*
wl
)
{
u8
tid_index
;
u8
ret
=
0
;
/* Reset the BA RX indicators */
wl
->
ba_rx_bitmap
=
0
;
/* validate that FW support BA */
wl1271_check_ba_support
(
wl
);
if
(
wl
->
ba_support
)
/* 802.11n initiator BA session setting */
for
(
tid_index
=
0
;
tid_index
<
CONF_TX_MAX_TID_COUNT
;
++
tid_index
)
{
ret
=
wl1271_acx_set_ba_session
(
wl
,
WLAN_BACK_INITIATOR
,
tid_index
,
true
);
if
(
ret
<
0
)
break
;
}
return
ret
;
}
int
wl1271_hw_init
(
struct
wl1271
*
wl
)
{
struct
conf_tx_ac_category
*
conf_ac
;
struct
conf_tx_tid
*
conf_tid
;
int
ret
,
i
;
bool
is_ap
=
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
);
ret
=
wl1271_cmd_general_parms
(
wl
);
if
(
ret
<
0
)
...
...
@@ -227,12 +506,12 @@ int wl1271_hw_init(struct wl1271 *wl)
if
(
ret
<
0
)
return
ret
;
ret
=
wl1271_cmd_ext_radio_parms
(
wl
);
if
(
ret
<
0
)
return
ret
;
/* Mode specific init */
if
(
is_ap
)
ret
=
wl1271_ap_hw_init
(
wl
);
else
ret
=
wl1271_sta_hw_init
(
wl
);
/* Template settings */
ret
=
wl1271_init_templates_config
(
wl
);
if
(
ret
<
0
)
return
ret
;
...
...
@@ -259,16 +538,6 @@ int wl1271_hw_init(struct wl1271 *wl)
if
(
ret
<
0
)
goto
out_free_memmap
;
/* Initialize connection monitoring thresholds */
ret
=
wl1271_acx_conn_monit_params
(
wl
,
false
);
if
(
ret
<
0
)
goto
out_free_memmap
;
/* Beacon filtering */
ret
=
wl1271_init_beacon_filter
(
wl
);
if
(
ret
<
0
)
goto
out_free_memmap
;
/* Configure TX patch complete interrupt behavior */
ret
=
wl1271_acx_tx_config_options
(
wl
);
if
(
ret
<
0
)
...
...
@@ -279,21 +548,11 @@ int wl1271_hw_init(struct wl1271 *wl)
if
(
ret
<
0
)
goto
out_free_memmap
;
/* Bluetooth WLAN coexistence */
ret
=
wl1271_init_pta
(
wl
);
if
(
ret
<
0
)
goto
out_free_memmap
;
/* Energy detection */
ret
=
wl1271_init_energy_detection
(
wl
);
if
(
ret
<
0
)
goto
out_free_memmap
;
/* Beacons and boradcast settings */
ret
=
wl1271_init_beacon_broadcast
(
wl
);
if
(
ret
<
0
)
goto
out_free_memmap
;
/* Default fragmentation threshold */
ret
=
wl1271_acx_frag_threshold
(
wl
,
wl
->
conf
.
tx
.
frag_threshold
);
if
(
ret
<
0
)
...
...
@@ -321,23 +580,13 @@ int wl1271_hw_init(struct wl1271 *wl)
goto
out_free_memmap
;
}
/* Configure TX rate classes */
ret
=
wl1271_acx_rate_policies
(
wl
);
if
(
ret
<
0
)
goto
out_free_memmap
;
/* Enable data path */
ret
=
wl1271_cmd_data_path
(
wl
,
1
);
if
(
ret
<
0
)
goto
out_free_memmap
;
/* Configure for ELP power saving */
ret
=
wl1271_acx_sleep_auth
(
wl
,
WL1271_PSM_ELP
);
if
(
ret
<
0
)
goto
out_free_memmap
;
/* Configure HW encryption */
ret
=
wl1271_
init_hwenc_confi
g
(
wl
);
ret
=
wl1271_
acx_feature_cf
g
(
wl
);
if
(
ret
<
0
)
goto
out_free_memmap
;
...
...
@@ -346,21 +595,17 @@ int wl1271_hw_init(struct wl1271 *wl)
if
(
ret
<
0
)
goto
out_free_memmap
;
/* disable all keep-alive templates */
for
(
i
=
0
;
i
<
CMD_TEMPL_KLV_IDX_MAX
;
i
++
)
{
ret
=
wl1271_acx_keep_alive_config
(
wl
,
i
,
ACX_KEEP_ALIVE_TPL_INVALID
);
if
(
ret
<
0
)
goto
out_free_memmap
;
}
/* Mode specific init - post mem init */
if
(
is_ap
)
ret
=
wl1271_ap_hw_init_post_mem
(
wl
);
else
ret
=
wl1271_sta_hw_init_post_mem
(
wl
);
/* disable the keep-alive feature */
ret
=
wl1271_acx_keep_alive_mode
(
wl
,
false
);
if
(
ret
<
0
)
goto
out_free_memmap
;
/* Configure
rssi/snr averaging weight
s */
ret
=
wl1271_
acx_rssi_snr_avg_weight
s
(
wl
);
/* Configure
initiator BA sessions policie
s */
ret
=
wl1271_
set_ba_policie
s
(
wl
);
if
(
ret
<
0
)
goto
out_free_memmap
;
...
...
drivers/net/wireless/wl12xx/init.h
浏览文件 @
cbdbc5eb
...
...
@@ -27,7 +27,7 @@
#include "wl12xx.h"
int
wl1271_hw_init_power_auth
(
struct
wl1271
*
wl
);
int
wl1271_init_templates_config
(
struct
wl1271
*
wl
);
int
wl1271_
sta_
init_templates_config
(
struct
wl1271
*
wl
);
int
wl1271_init_phy_config
(
struct
wl1271
*
wl
);
int
wl1271_init_pta
(
struct
wl1271
*
wl
);
int
wl1271_init_energy_detection
(
struct
wl1271
*
wl
);
...
...
drivers/net/wireless/wl12xx/main.c
浏览文件 @
cbdbc5eb
此差异已折叠。
点击以展开。
drivers/net/wireless/wl12xx/rx.c
浏览文件 @
cbdbc5eb
...
...
@@ -198,6 +198,16 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status)
pkt_offset
+=
pkt_length
;
}
}
wl1271_write32
(
wl
,
RX_DRIVER_COUNTER_ADDRESS
,
cpu_to_le32
(
wl
->
rx_counter
));
wl1271_write32
(
wl
,
RX_DRIVER_COUNTER_ADDRESS
,
wl
->
rx_counter
);
}
void
wl1271_set_default_filters
(
struct
wl1271
*
wl
)
{
if
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
)
{
wl
->
rx_config
=
WL1271_DEFAULT_AP_RX_CONFIG
;
wl
->
rx_filter
=
WL1271_DEFAULT_AP_RX_FILTER
;
}
else
{
wl
->
rx_config
=
WL1271_DEFAULT_STA_RX_CONFIG
;
wl
->
rx_filter
=
WL1271_DEFAULT_STA_RX_FILTER
;
}
}
drivers/net/wireless/wl12xx/rx.h
浏览文件 @
cbdbc5eb
...
...
@@ -86,8 +86,9 @@
/*
* RX Descriptor status
*
* Bits 0-2 - status
* Bits 3-7 - reserved
* Bits 0-2 - error code
* Bits 3-5 - process_id tag (AP mode FW)
* Bits 6-7 - reserved
*/
#define WL1271_RX_DESC_STATUS_MASK 0x07
...
...
@@ -110,12 +111,16 @@ struct wl1271_rx_descriptor {
u8
snr
;
__le32
timestamp
;
u8
packet_class
;
u8
process_id
;
union
{
u8
process_id
;
/* STA FW */
u8
hlid
;
/* AP FW */
}
__packed
;
u8
pad_len
;
u8
reserved
;
}
__packed
;
void
wl1271_rx
(
struct
wl1271
*
wl
,
struct
wl1271_fw_status
*
status
);
u8
wl1271_rate_to_idx
(
int
rate
,
enum
ieee80211_band
band
);
void
wl1271_set_default_filters
(
struct
wl1271
*
wl
);
#endif
drivers/net/wireless/wl12xx/sdio.c
浏览文件 @
cbdbc5eb
...
...
@@ -345,3 +345,4 @@ MODULE_LICENSE("GPL");
MODULE_AUTHOR
(
"Luciano Coelho <luciano.coelho@nokia.com>"
);
MODULE_AUTHOR
(
"Juuso Oikarinen <juuso.oikarinen@nokia.com>"
);
MODULE_FIRMWARE
(
WL1271_FW_NAME
);
MODULE_FIRMWARE
(
WL1271_AP_FW_NAME
);
drivers/net/wireless/wl12xx/spi.c
浏览文件 @
cbdbc5eb
...
...
@@ -110,9 +110,9 @@ static void wl1271_spi_reset(struct wl1271 *wl)
spi_message_add_tail
(
&
t
,
&
m
);
spi_sync
(
wl_to_spi
(
wl
),
&
m
);
kfree
(
cmd
);
wl1271_dump
(
DEBUG_SPI
,
"spi reset -> "
,
cmd
,
WSPI_INIT_CMD_LEN
);
kfree
(
cmd
);
}
static
void
wl1271_spi_init
(
struct
wl1271
*
wl
)
...
...
@@ -495,4 +495,5 @@ MODULE_LICENSE("GPL");
MODULE_AUTHOR
(
"Luciano Coelho <luciano.coelho@nokia.com>"
);
MODULE_AUTHOR
(
"Juuso Oikarinen <juuso.oikarinen@nokia.com>"
);
MODULE_FIRMWARE
(
WL1271_FW_NAME
);
MODULE_FIRMWARE
(
WL1271_AP_FW_NAME
);
MODULE_ALIAS
(
"spi:wl1271"
);
drivers/net/wireless/wl12xx/tx.c
浏览文件 @
cbdbc5eb
...
...
@@ -23,6 +23,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/etherdevice.h>
#include "wl12xx.h"
#include "io.h"
...
...
@@ -30,6 +31,23 @@
#include "ps.h"
#include "tx.h"
static
int
wl1271_set_default_wep_key
(
struct
wl1271
*
wl
,
u8
id
)
{
int
ret
;
bool
is_ap
=
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
);
if
(
is_ap
)
ret
=
wl1271_cmd_set_ap_default_wep_key
(
wl
,
id
);
else
ret
=
wl1271_cmd_set_sta_default_wep_key
(
wl
,
id
);
if
(
ret
<
0
)
return
ret
;
wl1271_debug
(
DEBUG_CRYPT
,
"default wep key idx: %d"
,
(
int
)
id
);
return
0
;
}
static
int
wl1271_alloc_tx_id
(
struct
wl1271
*
wl
,
struct
sk_buff
*
skb
)
{
int
id
;
...
...
@@ -99,7 +117,7 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
{
struct
timespec
ts
;
struct
wl1271_tx_hw_descr
*
desc
;
int
pad
,
ac
;
int
pad
,
ac
,
rate_idx
;
s64
hosttime
;
u16
tx_attr
;
...
...
@@ -117,7 +135,11 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
getnstimeofday
(
&
ts
);
hosttime
=
(
timespec_to_ns
(
&
ts
)
>>
10
);
desc
->
start_time
=
cpu_to_le32
(
hosttime
-
wl
->
time_offset
);
desc
->
life_time
=
cpu_to_le16
(
TX_HW_MGMT_PKT_LIFETIME_TU
);
if
(
wl
->
bss_type
!=
BSS_TYPE_AP_BSS
)
desc
->
life_time
=
cpu_to_le16
(
TX_HW_MGMT_PKT_LIFETIME_TU
);
else
desc
->
life_time
=
cpu_to_le16
(
TX_HW_AP_MODE_PKT_LIFETIME_TU
);
/* configure the tx attributes */
tx_attr
=
wl
->
session_counter
<<
TX_HW_ATTR_OFST_SESSION_COUNTER
;
...
...
@@ -125,7 +147,41 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
/* queue (we use same identifiers for tid's and ac's */
ac
=
wl1271_tx_get_queue
(
skb_get_queue_mapping
(
skb
));
desc
->
tid
=
ac
;
desc
->
aid
=
TX_HW_DEFAULT_AID
;
if
(
wl
->
bss_type
!=
BSS_TYPE_AP_BSS
)
{
desc
->
aid
=
TX_HW_DEFAULT_AID
;
/* if the packets are destined for AP (have a STA entry)
send them with AP rate policies, otherwise use default
basic rates */
if
(
control
->
control
.
sta
)
rate_idx
=
ACX_TX_AP_FULL_RATE
;
else
rate_idx
=
ACX_TX_BASIC_RATE
;
}
else
{
if
(
control
->
control
.
sta
)
{
struct
wl1271_station
*
wl_sta
;
wl_sta
=
(
struct
wl1271_station
*
)
control
->
control
.
sta
->
drv_priv
;
desc
->
hlid
=
wl_sta
->
hlid
;
rate_idx
=
ac
;
}
else
{
struct
ieee80211_hdr
*
hdr
;
hdr
=
(
struct
ieee80211_hdr
*
)
(
skb
->
data
+
sizeof
(
*
desc
));
if
(
ieee80211_is_mgmt
(
hdr
->
frame_control
))
{
desc
->
hlid
=
WL1271_AP_GLOBAL_HLID
;
rate_idx
=
ACX_TX_AP_MODE_MGMT_RATE
;
}
else
{
desc
->
hlid
=
WL1271_AP_BROADCAST_HLID
;
rate_idx
=
ACX_TX_AP_MODE_BCST_RATE
;
}
}
}
tx_attr
|=
rate_idx
<<
TX_HW_ATTR_OFST_RATE_POLICY
;
desc
->
reserved
=
0
;
/* align the length (and store in terms of words) */
...
...
@@ -136,14 +192,12 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
pad
=
pad
-
skb
->
len
;
tx_attr
|=
pad
<<
TX_HW_ATTR_OFST_LAST_WORD_PAD
;
/* if the packets are destined for AP (have a STA entry) send them
with AP rate policies, otherwise use default basic rates */
if
(
control
->
control
.
sta
)
tx_attr
|=
ACX_TX_AP_FULL_RATE
<<
TX_HW_ATTR_OFST_RATE_POLICY
;
desc
->
tx_attr
=
cpu_to_le16
(
tx_attr
);
wl1271_debug
(
DEBUG_TX
,
"tx_fill_hdr: pad: %d"
,
pad
);
wl1271_debug
(
DEBUG_TX
,
"tx_fill_hdr: pad: %d hlid: %d "
"tx_attr: 0x%x len: %d life: %d mem: %d"
,
pad
,
desc
->
hlid
,
le16_to_cpu
(
desc
->
tx_attr
),
le16_to_cpu
(
desc
->
length
),
le16_to_cpu
(
desc
->
life_time
),
desc
->
total_mem_blocks
);
}
/* caller must hold wl->mutex */
...
...
@@ -153,7 +207,6 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct sk_buff *skb,
struct
ieee80211_tx_info
*
info
;
u32
extra
=
0
;
int
ret
=
0
;
u8
idx
;
u32
total_len
;
if
(
!
skb
)
...
...
@@ -166,11 +219,15 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct sk_buff *skb,
extra
=
WL1271_TKIP_IV_SPACE
;
if
(
info
->
control
.
hw_key
)
{
idx
=
info
->
control
.
hw_key
->
hw_key_idx
;
bool
is_wep
;
u8
idx
=
info
->
control
.
hw_key
->
hw_key_idx
;
u32
cipher
=
info
->
control
.
hw_key
->
cipher
;
is_wep
=
(
cipher
==
WLAN_CIPHER_SUITE_WEP40
)
||
(
cipher
==
WLAN_CIPHER_SUITE_WEP104
);
/* FIXME: do we have to do this if we're not using WEP? */
if
(
unlikely
(
wl
->
default_key
!=
idx
))
{
ret
=
wl1271_cmd_set_default_wep_key
(
wl
,
idx
);
if
(
unlikely
(
is_wep
&&
wl
->
default_key
!=
idx
))
{
ret
=
wl1271_set_default_wep_key
(
wl
,
idx
);
if
(
ret
<
0
)
return
ret
;
wl
->
default_key
=
idx
;
...
...
@@ -303,7 +360,7 @@ void wl1271_tx_work_locked(struct wl1271 *wl)
woken_up
=
true
;
wl
->
rate_set
=
wl1271_tx_enabled_rates_get
(
wl
,
sta_rates
);
wl1271_acx_rate_policies
(
wl
);
wl1271_acx_
sta_
rate_policies
(
wl
);
}
while
((
skb
=
wl1271_skb_dequeue
(
wl
)))
{
...
...
@@ -521,3 +578,21 @@ void wl1271_tx_flush(struct wl1271 *wl)
wl1271_warning
(
"Unable to flush all TX buffers, timed out."
);
}
u32
wl1271_tx_min_rate_get
(
struct
wl1271
*
wl
)
{
int
i
;
u32
rate
=
0
;
if
(
!
wl
->
basic_rate_set
)
{
WARN_ON
(
1
);
wl
->
basic_rate_set
=
wl
->
conf
.
tx
.
basic_rate
;
}
for
(
i
=
0
;
!
rate
;
i
++
)
{
if
((
wl
->
basic_rate_set
>>
i
)
&
0x1
)
rate
=
1
<<
i
;
}
return
rate
;
}
drivers/net/wireless/wl12xx/tx.h
浏览文件 @
cbdbc5eb
...
...
@@ -29,6 +29,7 @@
#define TX_HW_BLOCK_SIZE 252
#define TX_HW_MGMT_PKT_LIFETIME_TU 2000
#define TX_HW_AP_MODE_PKT_LIFETIME_TU 8000
/* The chipset reference driver states, that the "aid" value 1
* is for infra-BSS, but is still always used */
#define TX_HW_DEFAULT_AID 1
...
...
@@ -77,8 +78,12 @@ struct wl1271_tx_hw_descr {
u8
id
;
/* The packet TID value (as User-Priority) */
u8
tid
;
/* Identifier of the remote STA in IBSS, 1 in infra-BSS */
u8
aid
;
union
{
/* STA - Identifier of the remote STA in IBSS, 1 in infra-BSS */
u8
aid
;
/* AP - host link ID (HLID) */
u8
hlid
;
}
__packed
;
u8
reserved
;
}
__packed
;
...
...
@@ -146,5 +151,6 @@ void wl1271_tx_reset(struct wl1271 *wl);
void
wl1271_tx_flush
(
struct
wl1271
*
wl
);
u8
wl1271_rate_to_idx
(
int
rate
,
enum
ieee80211_band
band
);
u32
wl1271_tx_enabled_rates_get
(
struct
wl1271
*
wl
,
u32
rate_set
);
u32
wl1271_tx_min_rate_get
(
struct
wl1271
*
wl
);
#endif
drivers/net/wireless/wl12xx/wl12xx.h
浏览文件 @
cbdbc5eb
...
...
@@ -38,6 +38,13 @@
#define DRIVER_NAME "wl1271"
#define DRIVER_PREFIX DRIVER_NAME ": "
/*
* FW versions support BA 11n
* versions marks x.x.x.50-60.x
*/
#define WL12XX_BA_SUPPORT_FW_COST_VER2_START 50
#define WL12XX_BA_SUPPORT_FW_COST_VER2_END 60
enum
{
DEBUG_NONE
=
0
,
DEBUG_IRQ
=
BIT
(
0
),
...
...
@@ -57,6 +64,8 @@ enum {
DEBUG_SDIO
=
BIT
(
14
),
DEBUG_FILTERS
=
BIT
(
15
),
DEBUG_ADHOC
=
BIT
(
16
),
DEBUG_AP
=
BIT
(
17
),
DEBUG_MASTER
=
(
DEBUG_ADHOC
|
DEBUG_AP
),
DEBUG_ALL
=
~
0
,
};
...
...
@@ -103,16 +112,27 @@ extern u32 wl12xx_debug_level;
true); \
} while (0)
#define WL1271_DEFAULT_RX_CONFIG (CFG_UNI_FILTER_EN | \
#define WL1271_DEFAULT_
STA_
RX_CONFIG (CFG_UNI_FILTER_EN | \
CFG_BSSID_FILTER_EN | \
CFG_MC_FILTER_EN)
#define WL1271_DEFAULT_RX_FILTER (CFG_RX_RCTS_ACK | CFG_RX_PRSP_EN | \
#define WL1271_DEFAULT_
STA_
RX_FILTER (CFG_RX_RCTS_ACK | CFG_RX_PRSP_EN | \
CFG_RX_MGMT_EN | CFG_RX_DATA_EN | \
CFG_RX_CTL_EN | CFG_RX_BCN_EN | \
CFG_RX_AUTH_EN | CFG_RX_ASSOC_EN)
#define WL1271_DEFAULT_AP_RX_CONFIG 0
#define WL1271_DEFAULT_AP_RX_FILTER (CFG_RX_RCTS_ACK | CFG_RX_PREQ_EN | \
CFG_RX_MGMT_EN | CFG_RX_DATA_EN | \
CFG_RX_CTL_EN | CFG_RX_AUTH_EN | \
CFG_RX_ASSOC_EN)
#define WL1271_FW_NAME "wl1271-fw.bin"
#define WL1271_AP_FW_NAME "wl1271-fw-ap.bin"
#define WL1271_NVS_NAME "wl1271-nvs.bin"
#define WL1271_TX_SECURITY_LO16(s) ((u16)((s) & 0xffff))
...
...
@@ -129,6 +149,14 @@ extern u32 wl12xx_debug_level;
#define WL1271_DEFAULT_BEACON_INT 100
#define WL1271_DEFAULT_DTIM_PERIOD 1
#define WL1271_AP_GLOBAL_HLID 0
#define WL1271_AP_BROADCAST_HLID 1
#define WL1271_AP_STA_HLID_START 2
#define WL1271_AP_BSS_INDEX 0
#define WL1271_AP_DEF_INACTIV_SEC 300
#define WL1271_AP_DEF_BEACON_EXP 20
#define ACX_TX_DESCRIPTORS 32
#define WL1271_AGGR_BUFFER_SIZE (4 * PAGE_SIZE)
...
...
@@ -161,10 +189,13 @@ struct wl1271_partition_set {
struct
wl1271
;
#define WL12XX_NUM_FW_VER 5
/* FIXME: I'm not sure about this structure name */
struct
wl1271_chip
{
u32
id
;
char
fw_ver
[
21
];
char
fw_ver_str
[
ETHTOOL_BUSINFO_LEN
];
unsigned
int
fw_ver
[
WL12XX_NUM_FW_VER
];
};
struct
wl1271_stats
{
...
...
@@ -178,6 +209,11 @@ struct wl1271_stats {
#define NUM_TX_QUEUES 4
#define NUM_RX_PKT_DESC 8
#define AP_MAX_STATIONS 5
/* Broadcast and Global links + links to stations */
#define AP_MAX_LINKS (AP_MAX_STATIONS + 2)
/* FW status registers */
struct
wl1271_fw_status
{
__le32
intr
;
...
...
@@ -188,7 +224,18 @@ struct wl1271_fw_status {
__le32
rx_pkt_descs
[
NUM_RX_PKT_DESC
];
__le32
tx_released_blks
[
NUM_TX_QUEUES
];
__le32
fw_localtime
;
__le32
padding
[
2
];
/* Next fields valid only in AP FW */
/*
* A bitmap (where each bit represents a single HLID)
* to indicate if the station is in PS mode.
*/
__le32
link_ps_bitmap
;
/* Number of freed MBs per HLID */
u8
tx_lnk_free_blks
[
AP_MAX_LINKS
];
u8
padding_1
[
1
];
}
__packed
;
struct
wl1271_rx_mem_pool_addr
{
...
...
@@ -218,6 +265,19 @@ struct wl1271_if_operations {
void
(
*
disable_irq
)(
struct
wl1271
*
wl
);
};
#define MAX_NUM_KEYS 14
#define MAX_KEY_SIZE 32
struct
wl1271_ap_key
{
u8
id
;
u8
key_type
;
u8
key_size
;
u8
key
[
MAX_KEY_SIZE
];
u8
hlid
;
u32
tx_seq_32
;
u16
tx_seq_16
;
};
struct
wl1271
{
struct
platform_device
*
plat_dev
;
struct
ieee80211_hw
*
hw
;
...
...
@@ -251,6 +311,7 @@ struct wl1271 {
#define WL1271_FLAG_PSPOLL_FAILURE (12)
#define WL1271_FLAG_STA_STATE_SENT (13)
#define WL1271_FLAG_FW_TX_BUSY (14)
#define WL1271_FLAG_AP_STARTED (15)
unsigned
long
flags
;
struct
wl1271_partition_set
part
;
...
...
@@ -262,6 +323,7 @@ struct wl1271 {
u8
*
fw
;
size_t
fw_len
;
u8
fw_bss_type
;
struct
wl1271_nvs_file
*
nvs
;
size_t
nvs_len
;
...
...
@@ -378,7 +440,6 @@ struct wl1271 {
int
last_rssi_event
;
struct
wl1271_stats
stats
;
struct
dentry
*
rootdir
;
__le32
buffer_32
;
u32
buffer_cmd
;
...
...
@@ -400,6 +461,23 @@ struct wl1271 {
/* Most recently reported noise in dBm */
s8
noise
;
/* map for HLIDs of associated stations - when operating in AP mode */
unsigned
long
ap_hlid_map
[
BITS_TO_LONGS
(
AP_MAX_STATIONS
)];
/* recoreded keys for AP-mode - set here before AP startup */
struct
wl1271_ap_key
*
recorded_ap_keys
[
MAX_NUM_KEYS
];
/* bands supported by this instance of wl12xx */
struct
ieee80211_supported_band
bands
[
IEEE80211_NUM_BANDS
];
/* RX BA constraint value */
bool
ba_support
;
u8
ba_rx_bitmap
;
};
struct
wl1271_station
{
u8
hlid
;
};
int
wl1271_plt_start
(
struct
wl1271
*
wl
);
...
...
drivers/net/wireless/wl12xx/wl12xx_80211.h
浏览文件 @
cbdbc5eb
...
...
@@ -138,13 +138,13 @@ struct wl12xx_arp_rsp_template {
struct
ieee80211_hdr_3addr
hdr
;
u8
llc_hdr
[
sizeof
(
rfc1042_header
)];
u
16
llc_type
;
__be
16
llc_type
;
struct
arphdr
arp_hdr
;
u8
sender_hw
[
ETH_ALEN
];
u
32
sender_ip
;
__be
32
sender_ip
;
u8
target_hw
[
ETH_ALEN
];
u
32
target_ip
;
__be
32
target_ip
;
}
__packed
;
...
...
@@ -160,4 +160,9 @@ struct wl12xx_probe_resp_template {
struct
wl12xx_ie_country
country
;
}
__packed
;
struct
wl12xx_disconn_template
{
struct
ieee80211_header
header
;
__le16
disconn_reason
;
}
__packed
;
#endif
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录