Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
e0a8c583
Commit
e0a8c583
authored
Aug 29, 2011
by
John W. Linville
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'for-linville' of
git://git.kernel.org/pub/scm/linux/kernel/git/luca/wl12xx
parents
a508a6ea
04b4d69c
Changes
25
Hide whitespace changes
Inline
Side-by-side
Showing
25 changed files
with
2090 additions
and
1860 deletions
+2090
-1860
drivers/net/wireless/wl12xx/acx.c
drivers/net/wireless/wl12xx/acx.c
+123
-199
drivers/net/wireless/wl12xx/acx.h
drivers/net/wireless/wl12xx/acx.h
+135
-259
drivers/net/wireless/wl12xx/boot.c
drivers/net/wireless/wl12xx/boot.c
+15
-28
drivers/net/wireless/wl12xx/boot.h
drivers/net/wireless/wl12xx/boot.h
+2
-1
drivers/net/wireless/wl12xx/cmd.c
drivers/net/wireless/wl12xx/cmd.c
+587
-206
drivers/net/wireless/wl12xx/cmd.h
drivers/net/wireless/wl12xx/cmd.h
+181
-148
drivers/net/wireless/wl12xx/conf.h
drivers/net/wireless/wl12xx/conf.h
+140
-212
drivers/net/wireless/wl12xx/debugfs.c
drivers/net/wireless/wl12xx/debugfs.c
+6
-11
drivers/net/wireless/wl12xx/event.c
drivers/net/wireless/wl12xx/event.c
+3
-3
drivers/net/wireless/wl12xx/event.h
drivers/net/wireless/wl12xx/event.h
+31
-49
drivers/net/wireless/wl12xx/init.c
drivers/net/wireless/wl12xx/init.c
+30
-61
drivers/net/wireless/wl12xx/io.h
drivers/net/wireless/wl12xx/io.h
+0
-1
drivers/net/wireless/wl12xx/main.c
drivers/net/wireless/wl12xx/main.c
+582
-379
drivers/net/wireless/wl12xx/ps.c
drivers/net/wireless/wl12xx/ps.c
+2
-2
drivers/net/wireless/wl12xx/reg.h
drivers/net/wireless/wl12xx/reg.h
+0
-75
drivers/net/wireless/wl12xx/rx.c
drivers/net/wireless/wl12xx/rx.c
+36
-24
drivers/net/wireless/wl12xx/rx.h
drivers/net/wireless/wl12xx/rx.h
+8
-10
drivers/net/wireless/wl12xx/scan.c
drivers/net/wireless/wl12xx/scan.c
+28
-10
drivers/net/wireless/wl12xx/scan.h
drivers/net/wireless/wl12xx/scan.h
+16
-9
drivers/net/wireless/wl12xx/sdio.c
drivers/net/wireless/wl12xx/sdio.c
+1
-3
drivers/net/wireless/wl12xx/spi.c
drivers/net/wireless/wl12xx/spi.c
+1
-3
drivers/net/wireless/wl12xx/tx.c
drivers/net/wireless/wl12xx/tx.c
+84
-52
drivers/net/wireless/wl12xx/tx.h
drivers/net/wireless/wl12xx/tx.h
+5
-11
drivers/net/wireless/wl12xx/wl12xx.h
drivers/net/wireless/wl12xx/wl12xx.h
+74
-79
drivers/net/wireless/wl12xx/wl12xx_80211.h
drivers/net/wireless/wl12xx/wl12xx_80211.h
+0
-25
No files found.
drivers/net/wireless/wl12xx/acx.c
View file @
e0a8c583
...
...
@@ -46,6 +46,7 @@ int wl1271_acx_wake_up_conditions(struct wl1271 *wl)
goto
out
;
}
wake_up
->
role_id
=
wl
->
role_id
;
wake_up
->
wake_up_event
=
wl
->
conf
.
conn
.
wake_up_event
;
wake_up
->
listen_interval
=
wl
->
conf
.
conn
.
listen_interval
;
...
...
@@ -101,6 +102,7 @@ int wl1271_acx_tx_power(struct wl1271 *wl, int power)
goto
out
;
}
acx
->
role_id
=
wl
->
role_id
;
acx
->
current_tx_power
=
power
*
10
;
ret
=
wl1271_cmd_configure
(
wl
,
DOT11_CUR_TX_PWR
,
acx
,
sizeof
(
*
acx
));
...
...
@@ -128,6 +130,7 @@ int wl1271_acx_feature_cfg(struct wl1271 *wl)
}
/* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE are disabled */
feature
->
role_id
=
wl
->
role_id
;
feature
->
data_flow_options
=
0
;
feature
->
options
=
0
;
...
...
@@ -183,34 +186,6 @@ int wl1271_acx_rx_msdu_life_time(struct wl1271 *wl)
return
ret
;
}
int
wl1271_acx_rx_config
(
struct
wl1271
*
wl
,
u32
config
,
u32
filter
)
{
struct
acx_rx_config
*
rx_config
;
int
ret
;
wl1271_debug
(
DEBUG_ACX
,
"acx rx config"
);
rx_config
=
kzalloc
(
sizeof
(
*
rx_config
),
GFP_KERNEL
);
if
(
!
rx_config
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
rx_config
->
config_options
=
cpu_to_le32
(
config
);
rx_config
->
filter_options
=
cpu_to_le32
(
filter
);
ret
=
wl1271_cmd_configure
(
wl
,
ACX_RX_CFG
,
rx_config
,
sizeof
(
*
rx_config
));
if
(
ret
<
0
)
{
wl1271_warning
(
"failed to set rx config: %d"
,
ret
);
goto
out
;
}
out:
kfree
(
rx_config
);
return
ret
;
}
int
wl1271_acx_pd_threshold
(
struct
wl1271
*
wl
)
{
struct
acx_packet_detection
*
pd
;
...
...
@@ -250,6 +225,7 @@ int wl1271_acx_slot(struct wl1271 *wl, enum acx_slot_type slot_time)
goto
out
;
}
slot
->
role_id
=
wl
->
role_id
;
slot
->
wone_index
=
STATION_WONE_INDEX
;
slot
->
slot_time
=
slot_time
;
...
...
@@ -279,6 +255,7 @@ int wl1271_acx_group_address_tbl(struct wl1271 *wl, bool enable,
}
/* MAC filtering */
acx
->
role_id
=
wl
->
role_id
;
acx
->
enabled
=
enable
;
acx
->
num_groups
=
mc_list_len
;
memcpy
(
acx
->
mac_table
,
mc_list
,
mc_list_len
*
ETH_ALEN
);
...
...
@@ -308,6 +285,7 @@ int wl1271_acx_service_period_timeout(struct wl1271 *wl)
wl1271_debug
(
DEBUG_ACX
,
"acx service period timeout"
);
rx_timeout
->
role_id
=
wl
->
role_id
;
rx_timeout
->
ps_poll_timeout
=
cpu_to_le16
(
wl
->
conf
.
rx
.
ps_poll_timeout
);
rx_timeout
->
upsd_timeout
=
cpu_to_le16
(
wl
->
conf
.
rx
.
upsd_timeout
);
...
...
@@ -344,6 +322,7 @@ int wl1271_acx_rts_threshold(struct wl1271 *wl, u32 rts_threshold)
goto
out
;
}
rts
->
role_id
=
wl
->
role_id
;
rts
->
threshold
=
cpu_to_le16
((
u16
)
rts_threshold
);
ret
=
wl1271_cmd_configure
(
wl
,
DOT11_RTS_THRESHOLD
,
rts
,
sizeof
(
*
rts
));
...
...
@@ -403,6 +382,7 @@ int wl1271_acx_beacon_filter_opt(struct wl1271 *wl, bool enable_filter)
goto
out
;
}
beacon_filter
->
role_id
=
wl
->
role_id
;
beacon_filter
->
enable
=
enable_filter
;
/*
...
...
@@ -439,6 +419,7 @@ int wl1271_acx_beacon_filter_table(struct wl1271 *wl)
}
/* configure default beacon pass-through rules */
ie_table
->
role_id
=
wl
->
role_id
;
ie_table
->
num_ie
=
0
;
for
(
i
=
0
;
i
<
wl
->
conf
.
conn
.
bcn_filt_ie_count
;
i
++
)
{
struct
conf_bcn_filt_rule
*
r
=
&
(
wl
->
conf
.
conn
.
bcn_filt_ie
[
i
]);
...
...
@@ -500,6 +481,7 @@ int wl1271_acx_conn_monit_params(struct wl1271 *wl, bool enable)
timeout
=
wl
->
conf
.
conn
.
bss_lose_timeout
;
}
acx
->
role_id
=
wl
->
role_id
;
acx
->
synch_fail_thold
=
cpu_to_le32
(
threshold
);
acx
->
bss_lose_timeout
=
cpu_to_le32
(
timeout
);
...
...
@@ -546,43 +528,13 @@ int wl1271_acx_sg_enable(struct wl1271 *wl, bool enable)
return
ret
;
}
int
wl1271_acx_sta_sg_cfg
(
struct
wl1271
*
wl
)
{
struct
acx_sta_bt_wlan_coex_param
*
param
;
struct
conf_sg_settings
*
c
=
&
wl
->
conf
.
sg
;
int
i
,
ret
;
wl1271_debug
(
DEBUG_ACX
,
"acx sg sta cfg"
);
param
=
kzalloc
(
sizeof
(
*
param
),
GFP_KERNEL
);
if
(
!
param
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
/* BT-WLAN coext parameters */
for
(
i
=
0
;
i
<
CONF_SG_STA_PARAMS_MAX
;
i
++
)
param
->
params
[
i
]
=
cpu_to_le32
(
c
->
sta_params
[
i
]);
param
->
param_idx
=
CONF_SG_PARAMS_ALL
;
ret
=
wl1271_cmd_configure
(
wl
,
ACX_SG_CFG
,
param
,
sizeof
(
*
param
));
if
(
ret
<
0
)
{
wl1271_warning
(
"failed to set sg config: %d"
,
ret
);
goto
out
;
}
out:
kfree
(
param
);
return
ret
;
}
int
wl1271_acx_ap_sg_cfg
(
struct
wl1271
*
wl
)
int
wl12xx_acx_sg_cfg
(
struct
wl1271
*
wl
)
{
struct
acx_
ap_
bt_wlan_coex_param
*
param
;
struct
acx_bt_wlan_coex_param
*
param
;
struct
conf_sg_settings
*
c
=
&
wl
->
conf
.
sg
;
int
i
,
ret
;
wl1271_debug
(
DEBUG_ACX
,
"acx sg
ap
cfg"
);
wl1271_debug
(
DEBUG_ACX
,
"acx sg cfg"
);
param
=
kzalloc
(
sizeof
(
*
param
),
GFP_KERNEL
);
if
(
!
param
)
{
...
...
@@ -591,8 +543,8 @@ int wl1271_acx_ap_sg_cfg(struct wl1271 *wl)
}
/* BT-WLAN coext parameters */
for
(
i
=
0
;
i
<
CONF_SG_
AP_
PARAMS_MAX
;
i
++
)
param
->
params
[
i
]
=
cpu_to_le32
(
c
->
ap_
params
[
i
]);
for
(
i
=
0
;
i
<
CONF_SG_PARAMS_MAX
;
i
++
)
param
->
params
[
i
]
=
cpu_to_le32
(
c
->
params
[
i
]);
param
->
param_idx
=
CONF_SG_PARAMS_ALL
;
ret
=
wl1271_cmd_configure
(
wl
,
ACX_SG_CFG
,
param
,
sizeof
(
*
param
));
...
...
@@ -647,6 +599,7 @@ int wl1271_acx_bcn_dtim_options(struct wl1271 *wl)
goto
out
;
}
bb
->
role_id
=
wl
->
role_id
;
bb
->
beacon_rx_timeout
=
cpu_to_le16
(
wl
->
conf
.
conn
.
beacon_rx_timeout
);
bb
->
broadcast_timeout
=
cpu_to_le16
(
wl
->
conf
.
conn
.
broadcast_timeout
);
bb
->
rx_broadcast_in_ps
=
wl
->
conf
.
conn
.
rx_broadcast_in_ps
;
...
...
@@ -676,6 +629,7 @@ int wl1271_acx_aid(struct wl1271 *wl, u16 aid)
goto
out
;
}
acx_aid
->
role_id
=
wl
->
role_id
;
acx_aid
->
aid
=
cpu_to_le16
(
aid
);
ret
=
wl1271_cmd_configure
(
wl
,
ACX_AID
,
acx_aid
,
sizeof
(
*
acx_aid
));
...
...
@@ -731,6 +685,7 @@ int wl1271_acx_set_preamble(struct wl1271 *wl, enum acx_preamble_type preamble)
goto
out
;
}
acx
->
role_id
=
wl
->
role_id
;
acx
->
preamble
=
preamble
;
ret
=
wl1271_cmd_configure
(
wl
,
ACX_PREAMBLE_TYPE
,
acx
,
sizeof
(
*
acx
));
...
...
@@ -758,6 +713,7 @@ int wl1271_acx_cts_protect(struct wl1271 *wl,
goto
out
;
}
acx
->
role_id
=
wl
->
role_id
;
acx
->
ctsprotect
=
ctsprotect
;
ret
=
wl1271_cmd_configure
(
wl
,
ACX_CTS_PROTECTION
,
acx
,
sizeof
(
*
acx
));
...
...
@@ -789,9 +745,8 @@ int wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats)
int
wl1271_acx_sta_rate_policies
(
struct
wl1271
*
wl
)
{
struct
acx_
sta_
rate_policy
*
acx
;
struct
acx_rate_policy
*
acx
;
struct
conf_tx_rate_class
*
c
=
&
wl
->
conf
.
tx
.
sta_rc_conf
;
int
idx
=
0
;
int
ret
=
0
;
wl1271_debug
(
DEBUG_ACX
,
"acx rate policies"
);
...
...
@@ -803,25 +758,30 @@ int wl1271_acx_sta_rate_policies(struct wl1271 *wl)
goto
out
;
}
wl1271_debug
(
DEBUG_ACX
,
"basic_rate: 0x%x, full_rate: 0x%x"
,
wl
->
basic_rate
,
wl
->
rate_set
);
/* configure one basic rate class */
idx
=
ACX_TX_BASIC_RATE
;
acx
->
rate_class
[
idx
].
enabled_rates
=
cpu_to_le32
(
wl
->
basic_rate
);
acx
->
rate_class
[
idx
].
short_retry_limit
=
c
->
short_retry_limit
;
acx
->
rate_class
[
idx
].
long_retry_limit
=
c
->
long_retry_limit
;
acx
->
rate_class
[
idx
].
aflags
=
c
->
aflags
;
acx
->
rate_policy_idx
=
cpu_to_le32
(
ACX_TX_BASIC_RATE
);
acx
->
rate_policy
.
enabled_rates
=
cpu_to_le32
(
wl
->
basic_rate
);
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
;
ret
=
wl1271_cmd_configure
(
wl
,
ACX_RATE_POLICY
,
acx
,
sizeof
(
*
acx
));
if
(
ret
<
0
)
{
wl1271_warning
(
"Setting of rate policies failed: %d"
,
ret
);
goto
out
;
}
/* configure one AP supported rate class */
idx
=
ACX_TX_AP_FULL_RATE
;
acx
->
rate_
class
[
idx
]
.
enabled_rates
=
cpu_to_le32
(
wl
->
rate_set
);
acx
->
rate_
class
[
idx
]
.
short_retry_limit
=
c
->
short_retry_limit
;
acx
->
rate_
class
[
idx
]
.
long_retry_limit
=
c
->
long_retry_limit
;
acx
->
rate_
class
[
idx
]
.
aflags
=
c
->
aflags
;
acx
->
rate_policy_idx
=
cpu_to_le32
(
ACX_TX_AP_FULL_RATE
)
;
acx
->
rate_
policy
.
enabled_rates
=
cpu_to_le32
(
wl
->
rate_set
);
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_class_cnt
=
cpu_to_le32
(
ACX_TX_RATE_POLICY_CNT
);
wl1271_debug
(
DEBUG_ACX
,
"basic_rate: 0x%x, full_rate: 0x%x"
,
acx
->
rate_class
[
ACX_TX_BASIC_RATE
].
enabled_rates
,
acx
->
rate_class
[
ACX_TX_AP_FULL_RATE
].
enabled_rates
);
ret
=
wl1271_cmd_configure
(
wl
,
ACX_RATE_POLICY
,
acx
,
sizeof
(
*
acx
));
if
(
ret
<
0
)
{
...
...
@@ -837,7 +797,7 @@ 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
)
{
struct
acx_
ap_
rate_policy
*
acx
;
struct
acx_rate_policy
*
acx
;
int
ret
=
0
;
wl1271_debug
(
DEBUG_ACX
,
"acx ap rate policy %d rates 0x%x"
,
...
...
@@ -883,6 +843,7 @@ int wl1271_acx_ac_cfg(struct wl1271 *wl, u8 ac, u8 cw_min, u16 cw_max,
goto
out
;
}
acx
->
role_id
=
wl
->
role_id
;
acx
->
ac
=
ac
;
acx
->
cw_min
=
cw_min
;
acx
->
cw_max
=
cpu_to_le16
(
cw_max
);
...
...
@@ -916,6 +877,7 @@ int wl1271_acx_tid_cfg(struct wl1271 *wl, u8 queue_id, u8 channel_type,
goto
out
;
}
acx
->
role_id
=
wl
->
role_id
;
acx
->
queue_id
=
queue_id
;
acx
->
channel_type
=
channel_type
;
acx
->
tsid
=
tsid
;
...
...
@@ -995,52 +957,9 @@ int wl1271_acx_tx_config_options(struct wl1271 *wl)
return
ret
;
}
int
wl1271_acx_ap_mem_cfg
(
struct
wl1271
*
wl
)
{
struct
wl1271_acx_ap_config_memory
*
mem_conf
;
struct
conf_memory_settings
*
mem
;
int
ret
;
wl1271_debug
(
DEBUG_ACX
,
"wl1271 mem cfg"
);
mem_conf
=
kzalloc
(
sizeof
(
*
mem_conf
),
GFP_KERNEL
);
if
(
!
mem_conf
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
if
(
wl
->
chip
.
id
==
CHIP_ID_1283_PG20
)
/*
* FIXME: The 128x AP FW does not yet support dynamic memory.
* Use the base memory configuration for 128x for now. This
* should be fine tuned in the future.
*/
mem
=
&
wl
->
conf
.
mem_wl128x
;
else
mem
=
&
wl
->
conf
.
mem_wl127x
;
/* memory config */
mem_conf
->
num_stations
=
mem
->
num_stations
;
mem_conf
->
rx_mem_block_num
=
mem
->
rx_block_num
;
mem_conf
->
tx_min_mem_block_num
=
mem
->
tx_min_block_num
;
mem_conf
->
num_ssid_profiles
=
mem
->
ssid_profiles
;
mem_conf
->
total_tx_descriptors
=
cpu_to_le32
(
ACX_TX_DESCRIPTORS
);
ret
=
wl1271_cmd_configure
(
wl
,
ACX_MEM_CFG
,
mem_conf
,
sizeof
(
*
mem_conf
));
if
(
ret
<
0
)
{
wl1271_warning
(
"wl1271 mem config failed: %d"
,
ret
);
goto
out
;
}
out:
kfree
(
mem_conf
);
return
ret
;
}
int
wl1271_acx_sta_mem_cfg
(
struct
wl1271
*
wl
)
int
wl12xx_acx_mem_cfg
(
struct
wl1271
*
wl
)
{
struct
wl12
71_acx_sta
_config_memory
*
mem_conf
;
struct
wl12
xx_acx
_config_memory
*
mem_conf
;
struct
conf_memory_settings
*
mem
;
int
ret
;
...
...
@@ -1183,6 +1102,7 @@ int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable)
goto
out
;
}
acx
->
role_id
=
wl
->
role_id
;
acx
->
enable
=
enable
?
CONF_BET_MODE_ENABLE
:
CONF_BET_MODE_DISABLE
;
acx
->
max_consecutive
=
wl
->
conf
.
conn
.
bet_max_consecutive
;
...
...
@@ -1210,6 +1130,7 @@ int wl1271_acx_arp_ip_filter(struct wl1271 *wl, u8 enable, __be32 address)
goto
out
;
}
acx
->
role_id
=
wl
->
role_id
;
acx
->
version
=
ACX_IPV4_VERSION
;
acx
->
enable
=
enable
;
...
...
@@ -1269,6 +1190,7 @@ int wl1271_acx_keep_alive_mode(struct wl1271 *wl, bool enable)
goto
out
;
}
acx
->
role_id
=
wl
->
role_id
;
acx
->
enabled
=
enable
;
ret
=
wl1271_cmd_configure
(
wl
,
ACX_KEEP_ALIVE_MODE
,
acx
,
sizeof
(
*
acx
));
...
...
@@ -1295,6 +1217,7 @@ int wl1271_acx_keep_alive_config(struct wl1271 *wl, u8 index, u8 tpl_valid)
goto
out
;
}
acx
->
role_id
=
wl
->
role_id
;
acx
->
period
=
cpu_to_le32
(
wl
->
conf
.
conn
.
keep_alive_interval
);
acx
->
index
=
index
;
acx
->
tpl_validation
=
tpl_valid
;
...
...
@@ -1328,6 +1251,7 @@ int wl1271_acx_rssi_snr_trigger(struct wl1271 *wl, bool enable,
wl
->
last_rssi_event
=
-
1
;
acx
->
role_id
=
wl
->
role_id
;
acx
->
pacing
=
cpu_to_le16
(
wl
->
conf
.
roam_trigger
.
trigger_pacing
);
acx
->
metric
=
WL1271_ACX_TRIG_METRIC_RSSI_BEACON
;
acx
->
type
=
WL1271_ACX_TRIG_TYPE_EDGE
;
...
...
@@ -1366,6 +1290,7 @@ int wl1271_acx_rssi_snr_avg_weights(struct wl1271 *wl)
goto
out
;
}
acx
->
role_id
=
wl
->
role_id
;
acx
->
rssi_beacon
=
c
->
avg_weight_rssi_beacon
;
acx
->
rssi_data
=
c
->
avg_weight_rssi_data
;
acx
->
snr_beacon
=
c
->
avg_weight_snr_beacon
;
...
...
@@ -1384,14 +1309,15 @@ int wl1271_acx_rssi_snr_avg_weights(struct wl1271 *wl)
int
wl1271_acx_set_ht_capabilities
(
struct
wl1271
*
wl
,
struct
ieee80211_sta_ht_cap
*
ht_cap
,
bool
allow_ht_operation
)
bool
allow_ht_operation
,
u8
hlid
)
{
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"
);
wl1271_debug
(
DEBUG_ACX
,
"acx ht capabilities setting "
"sta supp: %d sta cap: %d"
,
ht_cap
->
ht_supported
,
ht_cap
->
cap
);
acx
=
kzalloc
(
sizeof
(
*
acx
),
GFP_KERNEL
);
if
(
!
acx
)
{
...
...
@@ -1399,26 +1325,22 @@ int wl1271_acx_set_ht_capabilities(struct wl1271 *wl,
goto
out
;
}
/* Allow HT Operation ? */
if
(
allow_ht_operation
)
{
ht_capabilites
=
WL1271_ACX_FW_CAP_HT_OPERATION
;
if
(
ht_cap
->
cap
&
IEEE80211_HT_CAP_GRN_FLD
)
ht_capabilites
|=
WL1271_ACX_FW_CAP_GREENFIELD_FRAME_FORMAT
;
if
(
ht_cap
->
cap
&
IEEE80211_HT_CAP_SGI_20
)
ht_capabilites
|=
WL1271_ACX_FW_CAP_SHORT_GI_FOR_20MHZ_PACKETS
;
if
(
ht_cap
->
cap
&
IEEE80211_HT_CAP_LSIG_TXOP_PROT
)
ht_capabilites
|=
WL1271_ACX_FW_CAP_LSIG_TXOP_PROTECTION
;
if
(
allow_ht_operation
&&
ht_cap
->
ht_supported
)
{
/* no need to translate capabilities - use the spec values */
ht_capabilites
=
ht_cap
->
cap
;
/*
* this bit is not employed by the spec but only by FW to
* indicate peer HT support
*/
ht_capabilites
|=
WL12XX_HT_CAP_HT_OPERATION
;
/* get data from A-MPDU parameters field */
acx
->
ampdu_max_length
=
ht_cap
->
ampdu_factor
;
acx
->
ampdu_min_spacing
=
ht_cap
->
ampdu_density
;
}
memcpy
(
acx
->
mac_address
,
mac_address
,
ETH_ALEN
)
;
acx
->
hlid
=
hlid
;
acx
->
ht_capabilites
=
cpu_to_le32
(
ht_capabilites
);
ret
=
wl1271_cmd_configure
(
wl
,
ACX_PEER_HT_CAP
,
acx
,
sizeof
(
*
acx
));
...
...
@@ -1446,6 +1368,7 @@ int wl1271_acx_set_ht_information(struct wl1271 *wl,
goto
out
;
}
acx
->
role_id
=
wl
->
role_id
;
acx
->
ht_protection
=
(
u8
)(
ht_operation_mode
&
IEEE80211_HT_OP_MODE_PROTECTION
);
acx
->
rifs_mode
=
0
;
...
...
@@ -1467,14 +1390,12 @@ int wl1271_acx_set_ht_information(struct wl1271 *wl,
}
/* 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
)
int
wl12xx_acx_set_ba_initiator_policy
(
struct
wl1271
*
wl
)
{
struct
wl1271_acx_ba_
session
_policy
*
acx
;
struct
wl1271_acx_ba_
initiator
_policy
*
acx
;
int
ret
;
wl1271_debug
(
DEBUG_ACX
,
"acx ba
session setting
"
);
wl1271_debug
(
DEBUG_ACX
,
"acx ba
initiator policy
"
);
acx
=
kzalloc
(
sizeof
(
*
acx
),
GFP_KERNEL
);
if
(
!
acx
)
{
...
...
@@ -1482,33 +1403,18 @@ int wl1271_acx_set_ba_session(struct wl1271 *wl,
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
;
}
/* set for the current role */
acx
->
role_id
=
wl
->
role_id
;
acx
->
tid_bitmap
=
wl
->
conf
.
ht
.
tx_ba_tid_bitmap
;
acx
->
win_size
=
wl
->
conf
.
ht
.
tx_ba_win_size
;
acx
->
inactivity_timeout
=
wl
->
conf
.
ht
.
inactivity_timeout
;
ret
=
wl1271_cmd_configure
(
wl
,
ACX_BA_SESSION_
POLICY_CFG
,
ACX_BA_SESSION_
INIT_POLICY
,
acx
,
sizeof
(
*
acx
));
if
(
ret
<
0
)
{
wl1271_warning
(
"acx ba
session setting
failed: %d"
,
ret
);
wl1271_warning
(
"acx ba
initiator policy
failed: %d"
,
ret
);
goto
out
;
}
...
...
@@ -1518,8 +1424,8 @@ int wl1271_acx_set_ba_session(struct wl1271 *wl,
}
/* setup BA session receiver setting in the FW. */
int
wl12
71_acx_set_ba_receiver_session
(
struct
wl1271
*
wl
,
u8
tid_index
,
u16
ssn
,
bool
enable
)
int
wl12
xx_acx_set_ba_receiver_session
(
struct
wl1271
*
wl
,
u8
tid_index
,
u16
ssn
,
bool
enable
,
u8
peer_hlid
)
{
struct
wl1271_acx_ba_receiver_setup
*
acx
;
int
ret
;
...
...
@@ -1532,11 +1438,10 @@ int wl1271_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index, u16 ssn,
goto
out
;
}
/* Single link for now */
acx
->
link_id
=
1
;
acx
->
hlid
=
peer_hlid
;
acx
->
tid
=
tid_index
;
acx
->
enable
=
enable
;
acx
->
win_size
=
0
;
acx
->
win_size
=
wl
->
conf
.
ht
.
rx_ba_win_size
;
acx
->
ssn
=
ssn
;
ret
=
wl1271_cmd_configure
(
wl
,
ACX_BA_SESSION_RX_SETUP
,
acx
,
...
...
@@ -1606,6 +1511,7 @@ int wl1271_acx_ps_rx_streaming(struct wl1271 *wl, bool enable)
if
(
!
(
conf_queues
&
BIT
(
i
)))
continue
;
rx_streaming
->
role_id
=
wl
->
role_id
;
rx_streaming
->
tid
=
i
;
rx_streaming
->
enable
=
enable_queues
&
BIT
(
i
);
rx_streaming
->
period
=
wl
->
conf
.
rx_streaming
.
interval
;
...
...
@@ -1635,6 +1541,7 @@ int wl1271_acx_ap_max_tx_retry(struct wl1271 *wl)
if
(
!
acx
)
return
-
ENOMEM
;
acx
->
role_id
=
wl
->
role_id
;
acx
->
max_tx_retry
=
cpu_to_le16
(
wl
->
conf
.
tx
.
max_tx_retries
);
ret
=
wl1271_cmd_configure
(
wl
,
ACX_MAX_TX_FAILURE
,
acx
,
sizeof
(
*
acx
));
...
...
@@ -1703,31 +1610,6 @@ int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr)
return
ret
;
}
int
wl1271_acx_set_ap_beacon_filter
(
struct
wl1271
*
wl
,
bool
enable
)
{
struct
acx_ap_beacon_filter
*
acx
=
NULL
;
int
ret
;
wl1271_debug
(
DEBUG_ACX
,
"acx set ap beacon filter: %d"
,
enable
);
acx
=
kzalloc
(
sizeof
(
*
acx
),
GFP_KERNEL
);
if
(
!
acx
)
return
-
ENOMEM
;
acx
->
enable
=
enable
?
1
:
0
;
ret
=
wl1271_cmd_configure
(
wl
,
ACX_AP_BEACON_FILTER_OPT
,
acx
,
sizeof
(
*
acx
));
if
(
ret
<
0
)
{
wl1271_warning
(
"acx set ap beacon filter failed: %d"
,
ret
);
goto
out
;
}
out:
kfree
(
acx
);
return
ret
;
}
int
wl1271_acx_fm_coex
(
struct
wl1271
*
wl
)
{
struct
wl1271_acx_fm_coex
*
acx
;
...
...
@@ -1767,3 +1649,45 @@ int wl1271_acx_fm_coex(struct wl1271 *wl)
kfree
(
acx
);
return
ret
;
}
int
wl12xx_acx_set_rate_mgmt_params
(
struct
wl1271
*
wl
)
{
struct
wl12xx_acx_set_rate_mgmt_params
*
acx
=
NULL
;
struct
conf_rate_policy_settings
*
conf
=
&
wl
->
conf
.
rate
;
int
ret
;
wl1271_debug
(
DEBUG_ACX
,
"acx set rate mgmt params"
);
acx
=
kzalloc
(
sizeof
(
*
acx
),
GFP_KERNEL
);
if
(
!
acx
)
return
-
ENOMEM
;
acx
->
index
=
ACX_RATE_MGMT_ALL_PARAMS
;
acx
->
rate_retry_score
=
cpu_to_le16
(
conf
->
rate_retry_score
);
acx
->
per_add
=
cpu_to_le16
(
conf
->
per_add
);
acx
->
per_th1
=
cpu_to_le16
(
conf
->
per_th1
);
acx
->
per_th2
=
cpu_to_le16
(
conf
->
per_th2
);
acx
->
max_per
=
cpu_to_le16
(
conf
->
max_per
);
acx
->
inverse_curiosity_factor
=
conf
->
inverse_curiosity_factor
;
acx
->
tx_fail_low_th
=
conf
->
tx_fail_low_th
;
acx
->
tx_fail_high_th
=
conf
->
tx_fail_high_th
;
acx
->
per_alpha_shift
=
conf
->
per_alpha_shift
;
acx
->
per_add_shift
=
conf
->
per_add_shift
;
acx
->
per_beta1_shift
=
conf
->
per_beta1_shift
;
acx
->
per_beta2_shift
=
conf
->
per_beta2_shift
;
acx
->
rate_check_up
=
conf
->
rate_check_up
;
acx
->
rate_check_down
=
conf
->
rate_check_down
;
memcpy
(
acx
->
rate_retry_policy
,
conf
->
rate_retry_policy
,
sizeof
(
acx
->
rate_retry_policy
));
ret
=
wl1271_cmd_configure
(
wl
,
ACX_SET_RATE_MGMT_PARAMS
,
acx
,
sizeof
(
*
acx
));
if
(
ret
<
0
)
{
wl1271_warning
(
"acx set rate mgmt params failed: %d"
,
ret
);
goto
out
;
}
out:
kfree
(
acx
);
return
ret
;
}
drivers/net/wireless/wl12xx/acx.h
View file @
e0a8c583
...
...
@@ -101,6 +101,17 @@ struct acx_error_counter {
__le32
seq_num_miss
;
}
__packed
;
enum
wl12xx_role
{
WL1271_ROLE_STA
=
0
,
WL1271_ROLE_IBSS
,
WL1271_ROLE_AP
,
WL1271_ROLE_DEVICE
,
WL1271_ROLE_P2P_CL
,
WL1271_ROLE_P2P_GO
,
WL12XX_INVALID_ROLE_TYPE
=
0xff
};
enum
wl1271_psm_mode
{
/* Active mode */
WL1271_PSM_CAM
=
0
,
...
...
@@ -160,94 +171,6 @@ struct acx_rx_msdu_lifetime {
__le32
lifetime
;
}
__packed
;
/*
* RX Config Options Table
* Bit Definition
* === ==========
* 31:14 Reserved
* 13 Copy RX Status - when set, write three receive status words
* to top of rx'd MPDUs.
* When cleared, do not write three status words (added rev 1.5)
* 12 Reserved
* 11 RX Complete upon FCS error - when set, give rx complete
* interrupt for FCS errors, after the rx filtering, e.g. unicast
* frames not to us with FCS error will not generate an interrupt.
* 10 SSID Filter Enable - When set, the WiLink discards all beacon,
* probe request, and probe response frames with an SSID that does
* not match the SSID specified by the host in the START/JOIN
* command.
* When clear, the WiLink receives frames with any SSID.
* 9 Broadcast Filter Enable - When set, the WiLink discards all
* broadcast frames. When clear, the WiLink receives all received
* broadcast frames.
* 8:6 Reserved
* 5 BSSID Filter Enable - When set, the WiLink discards any frames
* with a BSSID that does not match the BSSID specified by the
* host.
* When clear, the WiLink receives frames from any BSSID.
* 4 MAC Addr Filter - When set, the WiLink discards any frames
* with a destination address that does not match the MAC address
* of the adaptor.
* When clear, the WiLink receives frames destined to any MAC
* address.
* 3 Promiscuous - When set, the WiLink receives all valid frames
* (i.e., all frames that pass the FCS check).
* When clear, only frames that pass the other filters specified
* are received.
* 2 FCS - When set, the WiLink includes the FCS with the received
* frame.
* When cleared, the FCS is discarded.
* 1 PLCP header - When set, write all data from baseband to frame
* buffer including PHY header.
* 0 Reserved - Always equal to 0.
*
* RX Filter Options Table
* Bit Definition
* === ==========
* 31:12 Reserved - Always equal to 0.
* 11 Association - When set, the WiLink receives all association
* related frames (association request/response, reassocation
* request/response, and disassociation). When clear, these frames
* are discarded.
* 10 Auth/De auth - When set, the WiLink receives all authentication
* and de-authentication frames. When clear, these frames are
* discarded.
* 9 Beacon - When set, the WiLink receives all beacon frames.
* When clear, these frames are discarded.
* 8 Contention Free - When set, the WiLink receives all contention
* free frames.
* When clear, these frames are discarded.
* 7 Control - When set, the WiLink receives all control frames.
* When clear, these frames are discarded.
* 6 Data - When set, the WiLink receives all data frames.
* When clear, these frames are discarded.
* 5 FCS Error - When set, the WiLink receives frames that have FCS
* errors.
* When clear, these frames are discarded.
* 4 Management - When set, the WiLink receives all management
* frames.
* When clear, these frames are discarded.
* 3 Probe Request - When set, the WiLink receives all probe request
* frames.
* When clear, these frames are discarded.
* 2 Probe Response - When set, the WiLink receives all probe
* response frames.
* When clear, these frames are discarded.
* 1 RTS/CTS/ACK - When set, the WiLink receives all RTS, CTS and ACK
* frames.
* When clear, these frames are discarded.
* 0 Rsvd Type/Sub Type - When set, the WiLink receives all frames
* that have reserved frame types and sub types as defined by the
* 802.11 specification.
* When clear, these frames are discarded.
*/
struct
acx_rx_config
{
struct
acx_header
header
;
__le32
config_options
;
__le32
filter_options
;
}
__packed
;
struct
acx_packet_detection
{
struct
acx_header
header
;
...
...
@@ -267,9 +190,10 @@ enum acx_slot_type {
struct
acx_slot
{
struct
acx_header
header
;
u8
role_id
;
u8
wone_index
;
/* Reserved */
u8
slot_time
;
u8
reserved
[
6
];
u8
reserved
[
5
];
}
__packed
;
...
...
@@ -279,29 +203,35 @@ struct acx_slot {
struct
acx_dot11_grp_addr_tbl
{
struct
acx_header
header
;
u8
role_id
;
u8
enabled
;
u8
num_groups
;
u8
pad
[
2
];
u8
pad
[
1
];
u8
mac_table
[
ADDRESS_GROUP_MAX_LEN
];
}
__packed
;
struct
acx_rx_timeout
{
struct
acx_header
header
;
u8
role_id
;
u8
reserved
;
__le16
ps_poll_timeout
;
__le16
upsd_timeout
;
u8
padding
[
2
];
}
__packed
;
struct
acx_rts_threshold
{
struct
acx_header
header
;
u8
role_id
;
u8
reserved
;
__le16
threshold
;
u8
pad
[
2
];
}
__packed
;
struct
acx_beacon_filter_option
{
struct
acx_header
header
;
u8
role_id
;
u8
enable
;
/*
* The number of beacons without the unicast TIM
...
...
@@ -311,7 +241,7 @@ struct acx_beacon_filter_option {
* without the unicast TIM bit set are dropped.
*/
u8
max_num_beacons
;
u8
pad
[
2
];
u8
pad
[
1
];
}
__packed
;
/*
...
...
@@ -350,14 +280,17 @@ struct acx_beacon_filter_option {
struct
acx_beacon_filter_ie_table
{
struct
acx_header
header
;
u8
role_id
;
u8
num_ie
;
u8
pad
[
3
];
u8
pad
[
2
];
u8
table
[
BEACON_FILTER_TABLE_MAX_SIZE
];
}
__packed
;
struct
acx_conn_monit_params
{
struct
acx_header
header
;
u8
role_id
;
u8
padding
[
3
];
__le32
synch_fail_thold
;
/* number of beacons missed */
__le32
bss_lose_timeout
;
/* number of TU's from synch fail */
}
__packed
;
...
...
@@ -369,23 +302,14 @@ struct acx_bt_wlan_coex {
u8
pad
[
3
];
}
__packed
;
struct
acx_sta_bt_wlan_coex_param
{
struct
acx_header
header
;
__le32
params
[
CONF_SG_STA_PARAMS_MAX
];
u8
param_idx
;
u8
padding
[
3
];
}
__packed
;
struct
acx_ap_bt_wlan_coex_param
{
struct
acx_bt_wlan_coex_param
{
struct
acx_header
header
;
__le32
params
[
CONF_SG_
AP_
PARAMS_MAX
];
__le32
params
[
CONF_SG_PARAMS_MAX
];
u8
param_idx
;
u8
padding
[
3
];
}
__packed
;
struct
acx_dco_itrim_params
{
struct
acx_header
header
;
...
...
@@ -406,15 +330,16 @@ struct acx_energy_detection {
struct
acx_beacon_broadcast
{
struct
acx_header
header
;
__le16
beacon_rx_timeout
;
__le16
broadcast_timeout
;
u8
role_id
;
/* Enables receiving of broadcast packets in PS mode */
u8
rx_broadcast_in_ps
;
__le16
beacon_rx_timeout
;
__le16
broadcast_timeout
;
/* Consecutive PS Poll failures before updating the host */
u8
ps_poll_threshold
;
u8
pad
[
2
];
u8
pad
[
1
];
}
__packed
;
struct
acx_event_mask
{
...
...
@@ -424,35 +349,6 @@ struct acx_event_mask {
__le32
high_event_mask
;
/* Unused */
}
__packed
;
#define CFG_RX_FCS BIT(2)
#define CFG_RX_ALL_GOOD BIT(3)
#define CFG_UNI_FILTER_EN BIT(4)
#define CFG_BSSID_FILTER_EN BIT(5)
#define CFG_MC_FILTER_EN BIT(6)
#define CFG_MC_ADDR0_EN BIT(7)
#define CFG_MC_ADDR1_EN BIT(8)
#define CFG_BC_REJECT_EN BIT(9)
#define CFG_SSID_FILTER_EN BIT(10)
#define CFG_RX_INT_FCS_ERROR BIT(11)
#define CFG_RX_INT_ENCRYPTED BIT(12)
#define CFG_RX_WR_RX_STATUS BIT(13)
#define CFG_RX_FILTER_NULTI BIT(14)
#define CFG_RX_RESERVE BIT(15)
#define CFG_RX_TIMESTAMP_TSF BIT(16)
#define CFG_RX_RSV_EN BIT(0)
#define CFG_RX_RCTS_ACK BIT(1)
#define CFG_RX_PRSP_EN BIT(2)
#define CFG_RX_PREQ_EN BIT(3)
#define CFG_RX_MGMT_EN BIT(4)
#define CFG_RX_FCS_ERROR BIT(5)
#define CFG_RX_DATA_EN BIT(6)
#define CFG_RX_CTL_EN BIT(7)
#define CFG_RX_CF_EN BIT(8)
#define CFG_RX_BCN_EN BIT(9)
#define CFG_RX_AUTH_EN BIT(10)
#define CFG_RX_ASSOC_EN BIT(11)
#define SCAN_PASSIVE BIT(0)
#define SCAN_5GHZ_BAND BIT(1)
#define SCAN_TRIGGERED BIT(2)
...
...
@@ -465,6 +361,8 @@ struct acx_event_mask {
struct
acx_feature_config
{
struct
acx_header
header
;
u8
role_id
;
u8
padding
[
3
];
__le32
options
;
__le32
data_flow_options
;
}
__packed
;
...
...
@@ -472,16 +370,18 @@ struct acx_feature_config {
struct
acx_current_tx_power
{
struct
acx_header
header
;
u8
role_id
;
u8
current_tx_power
;
u8
padding
[
3
];
u8
padding
[
2
];
}
__packed
;
struct
acx_wake_up_condition
{
struct
acx_header
header
;
u8
role_id
;
u8
wake_up_event
;
/* Only one bit can be set */
u8
listen_interval
;
u8
pad
[
2
];
u8
pad
[
1
];
}
__packed
;
struct
acx_aid
{
...
...
@@ -490,8 +390,9 @@ struct acx_aid {
/*
* To be set when associated with an AP.
*/
u8
role_id
;
u8
reserved
;
__le16
aid
;
u8
pad
[
2
];
}
__packed
;
enum
acx_preamble_type
{
...
...
@@ -506,8 +407,9 @@ struct acx_preamble {
* When set, the WiLink transmits the frames with a short preamble and
* when cleared, the WiLink transmits the frames with a long preamble.
*/
u8
role_id
;
u8
preamble
;
u8
padding
[
3
];
u8
padding
[
2
];
}
__packed
;
enum
acx_ctsprotect_type
{
...
...
@@ -517,8 +419,9 @@ enum acx_ctsprotect_type {
struct
acx_ctsprotect
{
struct
acx_header
header
;
u8
role_id
;
u8
ctsprotect
;
u8
padding
[
3
];
u8
padding
[
2
];
}
__packed
;
struct
acx_tx_statistics
{
...
...
@@ -753,18 +656,9 @@ 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_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_rate_policy
{
struct
acx_header
header
;
__le32
rate_policy_idx
;
...
...
@@ -773,22 +667,23 @@ struct acx_ap_rate_policy {
struct
acx_ac_cfg
{
struct
acx_header
header
;
u8
role_id
;
u8
ac
;
u8
aifsn
;
u8
cw_min
;
__le16
cw_max
;
u8
aifsn
;
u8
reserved
;
__le16
tx_op_limit
;
}
__packed
;
struct
acx_tid_config
{
struct
acx_header
header
;
u8
role_id
;
u8
queue_id
;
u8
channel_type
;
u8
tsid
;
u8
ps_scheme
;
u8
ack_policy
;
u8
padding
[
3
];
u8
padding
[
2
];
__le32
apsd_conf
[
2
];
}
__packed
;
...
...
@@ -804,19 +699,7 @@ struct acx_tx_config_options {
__le16
tx_compl_threshold
;
/* number of packets */
}
__packed
;
#define ACX_TX_DESCRIPTORS 32
struct
wl1271_acx_ap_config_memory
{
struct
acx_header
header
;
u8
rx_mem_block_num
;
u8
tx_min_mem_block_num
;
u8
num_stations
;
u8
num_ssid_profiles
;
__le32
total_tx_descriptors
;
}
__packed
;
struct
wl1271_acx_sta_config_memory
{
struct
wl12xx_acx_config_memory
{
struct
acx_header
header
;
u8
rx_mem_block_num
;
...
...
@@ -890,9 +773,10 @@ struct wl1271_acx_rx_config_opt {
struct
wl1271_acx_bet_enable
{
struct
acx_header
header
;
u8
role_id
;
u8
enable
;
u8
max_consecutive
;
u8
padding
[
2
];
u8
padding
[
1
];
}
__packed
;
#define ACX_IPV4_VERSION 4
...
...
@@ -905,9 +789,10 @@ struct wl1271_acx_bet_enable {
struct
wl1271_acx_arp_filter
{
struct
acx_header
header
;
u8
role_id
;
u8
version
;
/* ACX_IPV4_VERSION, ACX_IPV6_VERSION */
u8
enable
;
/* bitmap of enabled ARP filtering features */
u8
padding
[
2
];
u8
padding
[
1
];
u8
address
[
16
];
/* The configured device IP address - all ARP
requests directed to this IP address will pass
through. For IPv4, the first four bytes are
...
...
@@ -925,8 +810,9 @@ struct wl1271_acx_pm_config {
struct
wl1271_acx_keep_alive_mode
{
struct
acx_header
header
;
u8
role_id
;
u8
enabled
;
u8
padding
[
3
];
u8
padding
[
2
];
}
__packed
;
enum
{
...
...
@@ -942,11 +828,11 @@ enum {
struct
wl1271_acx_keep_alive_config
{
struct
acx_header
header
;
__le32
perio
d
;
u8
role_i
d
;
u8
index
;
u8
tpl_validation
;
u8
trigger
;
u8
padding
;
__le32
period
;
}
__packed
;
#define HOST_IF_CFG_RX_FIFO_ENABLE BIT(0)
...
...
@@ -990,26 +876,33 @@ enum {
struct
wl1271_acx_rssi_snr_trigger
{
struct
acx_header
header
;
__le16
threshold
;
__le16
pacing
;
/* 0 - 60000 ms */
u8
role_id
;
u8
metric
;
u8
type
;
u8
dir
;
__le16
threshold
;
__le16
pacing
;
/* 0 - 60000 ms */
u8
hysteresis
;
u8
index
;
u8
enable
;
u8
padding
[
2
];
u8
padding
[
1
];
};
struct
wl1271_acx_rssi_snr_avg_weights
{
struct
acx_header
header
;
u8
role_id
;
u8
padding
[
3
];
u8
rssi_beacon
;
u8
rssi_data
;
u8
snr_beacon
;
u8
snr_data
;
};
/* special capability bit (not employed by the 802.11n spec) */
#define WL12XX_HT_CAP_HT_OPERATION BIT(16)
/*
* ACX_PEER_HT_CAP
* Configure HT capabilities - declare the capabilities of the peer
...
...
@@ -1018,28 +911,11 @@ struct wl1271_acx_rssi_snr_avg_weights {
struct
wl1271_acx_ht_capabilities
{
struct
acx_header
header
;
/*
* bit 0 - Allow HT Operation
* bit 1 - Allow Greenfield format in TX
* bit 2 - Allow Short GI in TX
* bit 3 - Allow L-SIG TXOP Protection in TX
* bit 4 - Allow HT Control fields in TX.
* Note, driver will still leave space for HT control in packets
* regardless of the value of this field. FW will be responsible
* to drop the HT field from any frame when this Bit set to 0.
* bit 5 - Allow RD initiation in TXOP. FW is allowed to initate RD.
* Exact policy setting for this feature is TBD.
* Note, this bit can only be set to 1 if bit 3 is set to 1.
*/
/* bitmask of capability bits supported by the peer */
__le32
ht_capabilites
;
/*
* Indicates to which peer these capabilities apply.
* For infrastructure use ff:ff:ff:ff:ff:ff that indicates relevance
* for all peers.
* Only valid for IBSS/DLS operation.
*/
u8
mac_address
[
ETH_ALEN
];
/* Indicates to which link these capabilities apply. */
u8
hlid
;
/*
* This the maximum A-MPDU length supported by the AP. The FW may not
...
...
@@ -1049,16 +925,9 @@ struct wl1271_acx_ht_capabilities {
/* This is the minimal spacing required when sending A-MPDUs to the AP*/
u8
ampdu_min_spacing
;
}
__packed
;
/* HT Capabilites Fw Bit Mask Mapping */
#define WL1271_ACX_FW_CAP_HT_OPERATION BIT(0)
#define WL1271_ACX_FW_CAP_GREENFIELD_FRAME_FORMAT BIT(1)
#define WL1271_ACX_FW_CAP_SHORT_GI_FOR_20MHZ_PACKETS BIT(2)
#define WL1271_ACX_FW_CAP_LSIG_TXOP_PROTECTION BIT(3)
#define WL1271_ACX_FW_CAP_HT_CONTROL_FIELDS BIT(4)
#define WL1271_ACX_FW_CAP_RD_INITIATION BIT(5)
u8
padding
;
}
__packed
;
/*
* ACX_HT_BSS_OPERATION
...
...
@@ -1067,6 +936,8 @@ struct wl1271_acx_ht_capabilities {
struct
wl1271_acx_ht_information
{
struct
acx_header
header
;
u8
role_id
;
/* Values: 0 - RIFS not allowed, 1 - RIFS allowed */
u8
rifs_mode
;
...
...
@@ -1088,60 +959,51 @@ struct wl1271_acx_ht_information {
*/
u8
dual_cts_protection
;
u8
padding
[
3
];
u8
padding
[
2
];
}
__packed
;
#define RX_BA_
WIN_SIZE 8
#define RX_BA_
MAX_SESSIONS 2
struct
wl1271_acx_ba_
session
_policy
{
struct
wl1271_acx_ba_
initiator
_policy
{
struct
acx_header
header
;
/*
* Specifies role Id, Range 0-7, 0xFF means ANY role.
* Future use. For now this field is irrelevant
*/
/* Specifies role Id, Range 0-7, 0xFF means ANY role. */
u8
role_id
;
/*
*
Specifies Link Id, Range 0-31, 0xFF means ANY Link Id.
*
Not applicable if Role Id is set to ANY
.
*
Per TID setting for allowing TX BA. Set a bit to 1 to allow
*
TX BA sessions for the corresponding TID
.
*/
u8
link_id
;
u8
tid
;
u8
enable
;
u8
tid_bitmap
;
/* Windows size in number of packets */
u
16
win_size
;
u
8
win_size
;
/*
* As initiator inactivity timeout in time units(TU) of 1024us.
* As receiver reserved
*/
u16
inactivity_timeout
;
u8
padding1
[
1
];
/*
Initiator = 1/Receiver = 0
*/
u
8
ba_direction
;
/*
As initiator inactivity timeout in time units(TU) of 1024us
*/
u
16
inactivity_timeout
;
u8
padding
[
3
];
u8
padding
[
2
];
}
__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
;
/* Specifies
link id, range 0-31
*/
u8
hl
id
;
u8
tid
;
u8
enable
;
u8
padding
[
1
];
/* Windows size in number of packets */
u
16
win_size
;
u
8
win_size
;
/* BA session starting sequence number. RANGE 0-FFF */
u16
ssn
;
u8
padding
[
2
];
}
__packed
;
struct
wl1271_acx_fw_tsf_information
{
...
...
@@ -1158,6 +1020,7 @@ struct wl1271_acx_fw_tsf_information {
struct
wl1271_acx_ps_rx_streaming
{
struct
acx_header
header
;
u8
role_id
;
u8
tid
;
u8
enable
;
...
...
@@ -1166,17 +1029,20 @@ struct wl1271_acx_ps_rx_streaming {
/* timeout before first trigger (0-200 msec) */
u8
timeout
;
u8
padding
[
3
];
}
__packed
;
struct
wl1271_acx_ap_max_tx_retry
{
struct
acx_header
header
;
u8
role_id
;
u8
padding_1
;
/*
* the number of frames transmission failures before
* issuing the aging event.
*/
__le16
max_tx_retry
;
u8
padding_1
[
2
];
}
__packed
;
struct
wl1271_acx_config_ps
{
...
...
@@ -1195,13 +1061,6 @@ struct wl1271_acx_inconnection_sta {
u8
padding1
[
2
];
}
__packed
;
struct
acx_ap_beacon_filter
{
struct
acx_header
header
;
u8
enable
;
u8
pad
[
3
];
}
__packed
;
/*
* ACX_FM_COEX_CFG
* set the FM co-existence parameters.
...
...
@@ -1261,6 +1120,30 @@ struct wl1271_acx_fm_coex {
u8
swallow_clk_diff
;
}
__packed
;
#define ACX_RATE_MGMT_ALL_PARAMS 0xff
struct
wl12xx_acx_set_rate_mgmt_params
{
struct
acx_header
header
;
u8
index
;
/* 0xff to configure all params */
u8
padding1
;
__le16
rate_retry_score
;
__le16
per_add
;
__le16
per_th1
;
__le16
per_th2
;
__le16
max_per
;
u8
inverse_curiosity_factor
;
u8
tx_fail_low_th
;
u8
tx_fail_high_th
;
u8
per_alpha_shift
;
u8
per_add_shift
;
u8
per_beta1_shift
;
u8
per_beta2_shift
;
u8
rate_check_up
;
u8
rate_check_down
;
u8
rate_retry_policy
[
ACX_RATE_MGMT_NUM_OF_RATES
];
u8
padding2
[
2
];
}
__packed
;
enum
{
ACX_WAKE_UP_CONDITIONS
=
0x0002
,
ACX_MEM_CFG
=
0x0003
,
...
...
@@ -1268,10 +1151,7 @@ enum {
ACX_AC_CFG
=
0x0007
,
ACX_MEM_MAP
=
0x0008
,
ACX_AID
=
0x000A
,
/* ACX_FW_REV is missing in the ref driver, but seems to work */
ACX_FW_REV
=
0x000D
,
ACX_MEDIUM_USAGE
=
0x000F
,
ACX_RX_CFG
=
0x0010
,
ACX_TX_QUEUE_CFG
=
0x0011
,
/* FIXME: only used by wl1251 */
ACX_STATISTICS
=
0x0013
,
/* Debug API */
ACX_PWR_CONSUMPTION_STATISTICS
=
0x0014
,
...
...
@@ -1279,7 +1159,6 @@ enum {
ACX_TID_CFG
=
0x001A
,
ACX_PS_RX_STREAMING
=
0x001B
,
ACX_BEACON_FILTER_OPT
=
0x001F
,
ACX_AP_BEACON_FILTER_OPT
=
0x0020
,
ACX_NOISE_HIST
=
0x0021
,
ACX_HDK_VERSION
=
0x0022
,
/* ??? */
ACX_PD_THRESHOLD
=
0x0023
,
...
...
@@ -1287,7 +1166,6 @@ enum {
ACX_CCA_THRESHOLD
=
0x0025
,
ACX_EVENT_MBOX_MASK
=
0x0026
,
ACX_CONN_MONIT_PARAMS
=
0x002D
,
ACX_CONS_TX_FAILURE
=
0x002F
,
ACX_BCN_DTIM_OPTIONS
=
0x0031
,
ACX_SG_ENABLE
=
0x0032
,
ACX_SG_CFG
=
0x0033
,
...
...
@@ -1314,11 +1192,14 @@ enum {
ACX_RSSI_SNR_WEIGHTS
=
0x0052
,
ACX_KEEP_ALIVE_MODE
=
0x0053
,
ACX_SET_KEEP_ALIVE_CONFIG
=
0x0054
,
ACX_BA_SESSION_
POLICY_CFG
=
0x0055
,
ACX_BA_SESSION_
INIT_POLICY
=
0x0055
,
ACX_BA_SESSION_RX_SETUP
=
0x0056
,
ACX_PEER_HT_CAP
=
0x0057
,
ACX_HT_BSS_OPERATION
=
0x0058
,
ACX_COEX_ACTIVITY
=
0x0059
,
ACX_BURST_MODE
=
0x005C
,
ACX_SET_RATE_MGMT_PARAMS
=
0x005D
,
ACX_SET_RATE_ADAPT_PARAMS
=
0x0060
,
ACX_SET_DCO_ITRIM_PARAMS
=
0x0061
,
ACX_GEN_FW_CMD
=
0x0070
,
ACX_HOST_IF_CFG_BITMAP
=
0x0071
,
...
...
@@ -1342,7 +1223,6 @@ int wl1271_acx_feature_cfg(struct wl1271 *wl);
int
wl1271_acx_mem_map
(
struct
wl1271
*
wl
,
struct
acx_header
*
mem_map
,
size_t
len
);
int
wl1271_acx_rx_msdu_life_time
(
struct
wl1271
*
wl
);
int
wl1271_acx_rx_config
(
struct
wl1271
*
wl
,
u32
config
,
u32
filter
);
int
wl1271_acx_pd_threshold
(
struct
wl1271
*
wl
);
int
wl1271_acx_slot
(
struct
wl1271
*
wl
,
enum
acx_slot_type
slot_time
);
int
wl1271_acx_group_address_tbl
(
struct
wl1271
*
wl
,
bool
enable
,
...
...
@@ -1354,8 +1234,7 @@ int wl1271_acx_beacon_filter_opt(struct wl1271 *wl, bool enable_filter);
int
wl1271_acx_beacon_filter_table
(
struct
wl1271
*
wl
);
int
wl1271_acx_conn_monit_params
(
struct
wl1271
*
wl
,
bool
enable
);
int
wl1271_acx_sg_enable
(
struct
wl1271
*
wl
,
bool
enable
);
int
wl1271_acx_sta_sg_cfg
(
struct
wl1271
*
wl
);
int
wl1271_acx_ap_sg_cfg
(
struct
wl1271
*
wl
);
int
wl12xx_acx_sg_cfg
(
struct
wl1271
*
wl
);
int
wl1271_acx_cca_threshold
(
struct
wl1271
*
wl
);
int
wl1271_acx_bcn_dtim_options
(
struct
wl1271
*
wl
);
int
wl1271_acx_aid
(
struct
wl1271
*
wl
,
u16
aid
);
...
...
@@ -1374,8 +1253,7 @@ int wl1271_acx_tid_cfg(struct wl1271 *wl, u8 queue_id, u8 channel_type,
u32
apsd_conf0
,
u32
apsd_conf1
);
int
wl1271_acx_frag_threshold
(
struct
wl1271
*
wl
,
u32
frag_threshold
);
int
wl1271_acx_tx_config_options
(
struct
wl1271
*
wl
);
int
wl1271_acx_ap_mem_cfg
(
struct
wl1271
*
wl
);
int
wl1271_acx_sta_mem_cfg
(
struct
wl1271
*
wl
);
int
wl12xx_acx_mem_cfg
(
struct
wl1271
*
wl
);
int
wl1271_acx_init_mem_config
(
struct
wl1271
*
wl
);
int
wl1271_acx_host_if_cfg_bitmap
(
struct
wl1271
*
wl
,
u32
host_cfg_bitmap
);
int
wl1271_acx_init_rx_interrupt
(
struct
wl1271
*
wl
);
...
...
@@ -1390,20 +1268,18 @@ int wl1271_acx_rssi_snr_trigger(struct wl1271 *wl, bool enable,
int
wl1271_acx_rssi_snr_avg_weights
(
struct
wl1271
*
wl
);
int
wl1271_acx_set_ht_capabilities
(
struct
wl1271
*
wl
,
struct
ieee80211_sta_ht_cap
*
ht_cap
,
bool
allow_ht_operation
);
bool
allow_ht_operation
,
u8
hlid
);
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
wl12xx_acx_set_ba_initiator_policy
(
struct
wl1271
*
wl
);
int
wl12xx_acx_set_ba_receiver_session
(
struct
wl1271
*
wl
,
u8
tid_index
,
u16
ssn
,
bool
enable
,
u8
peer_hlid
);
int
wl1271_acx_tsf_info
(
struct
wl1271
*
wl
,
u64
*
mactime
);
int
wl1271_acx_ps_rx_streaming
(
struct
wl1271
*
wl
,
bool
enable
);
int
wl1271_acx_ap_max_tx_retry
(
struct
wl1271
*
wl
);
int
wl1271_acx_config_ps
(
struct
wl1271
*
wl
);
int
wl1271_acx_set_inconnection_sta
(
struct
wl1271
*
wl
,
u8
*
addr
);
int
wl1271_acx_set_ap_beacon_filter
(
struct
wl1271
*
wl
,
bool
enable
);
int
wl1271_acx_fm_coex
(
struct
wl1271
*
wl
);
int
wl12xx_acx_set_rate_mgmt_params
(
struct
wl1271
*
wl
);
#endif
/* __WL1271_ACX_H__ */
drivers/net/wireless/wl12xx/boot.c
View file @
e0a8c583
...
...
@@ -107,16 +107,6 @@ static unsigned int wl12xx_get_fw_ver_quirks(struct wl1271 *wl)
unsigned
int
quirks
=
0
;
unsigned
int
*
fw_ver
=
wl
->
chip
.
fw_ver
;
/* Only for wl127x */
if
((
fw_ver
[
FW_VER_CHIP
]
==
FW_VER_CHIP_WL127X
)
&&
/* Check STA version */
(((
fw_ver
[
FW_VER_IF_TYPE
]
==
FW_VER_IF_TYPE_STA
)
&&
(
fw_ver
[
FW_VER_MINOR
]
<
FW_VER_MINOR_1_SPARE_STA_MIN
))
||
/* Check AP version */
((
fw_ver
[
FW_VER_IF_TYPE
]
==
FW_VER_IF_TYPE_AP
)
&&
(
fw_ver
[
FW_VER_MINOR
]
<
FW_VER_MINOR_1_SPARE_AP_MIN
))))
quirks
|=
WL12XX_QUIRK_USE_2_SPARE_BLOCKS
;
/* Only new station firmwares support routing fw logs to the host */
if
((
fw_ver
[
FW_VER_IF_TYPE
]
==
FW_VER_IF_TYPE_STA
)
&&
(
fw_ver
[
FW_VER_MINOR
]
<
FW_VER_MINOR_FWLOG_STA_MIN
))
...
...
@@ -504,21 +494,18 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl)
wl
->
event_mask
=
BSS_LOSE_EVENT_ID
|
SCAN_COMPLETE_EVENT_ID
|
PS_REPORT_EVENT_ID
|
JOIN_EVENT_COMPLETE_ID
|
DISCONNECT_EVENT_COMPLETE_ID
|
RSSI_SNR_TRIGGER_0_EVENT_ID
|
PSPOLL_DELIVERY_FAILURE_EVENT_ID
|
SOFT_GEMINI_SENSE_EVENT_ID
|
PERIODIC_SCAN_REPORT_EVENT_ID
|
PERIODIC_SCAN_COMPLETE_EVENT_ID
;
if
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
)
wl
->
event_mask
|=
STA_REMOVE_COMPLETE_EVENT_ID
|
INACTIVE_STA_EVENT_ID
|
MAX_TX_RETRY_EVENT_ID
;
else
wl
->
event_mask
|=
DUMMY_PACKET_EVENT_ID
|
BA_SESSION_RX_CONSTRAINT_EVENT_ID
;
PERIODIC_SCAN_COMPLETE_EVENT_ID
|
DUMMY_PACKET_EVENT_ID
|
PEER_REMOVE_COMPLETE_EVENT_ID
|
BA_SESSION_RX_CONSTRAINT_EVENT_ID
|
REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID
|
INACTIVE_STA_EVENT_ID
|
MAX_TX_RETRY_EVENT_ID
;
ret
=
wl1271_event_unmask
(
wl
);
if
(
ret
<
0
)
{
...
...
@@ -549,13 +536,13 @@ static void wl1271_boot_hw_version(struct wl1271 *wl)
{
u32
fuse
;
fuse
=
wl1271_top_reg_read
(
wl
,
REG_FUSE_DATA_2_1
);
if
(
wl
->
chip
.
id
==
CHIP_ID_1283_PG20
)
fuse
=
wl1271_top_reg_read
(
wl
,
WL128X_REG_FUSE_DATA_2_1
);
else
fuse
=
wl1271_top_reg_read
(
wl
,
WL127X_REG_FUSE_DATA_2_1
);
fuse
=
(
fuse
&
PG_VER_MASK
)
>>
PG_VER_OFFSET
;
wl
->
hw_pg_ver
=
(
s8
)
fuse
;
if
(((
wl
->
hw_pg_ver
&
PG_MAJOR_VER_MASK
)
>>
PG_MAJOR_VER_OFFSET
)
<
3
)
wl
->
quirks
|=
WL12XX_QUIRK_END_OF_TRANSACTION
;
}
static
int
wl128x_switch_tcxo_to_fref
(
struct
wl1271
*
wl
)
...
...
@@ -696,7 +683,8 @@ static int wl127x_boot_clk(struct wl1271 *wl)
u32
pause
;
u32
clk
;
wl1271_boot_hw_version
(
wl
);
if
(((
wl
->
hw_pg_ver
&
PG_MAJOR_VER_MASK
)
>>
PG_MAJOR_VER_OFFSET
)
<
3
)
wl
->
quirks
|=
WL12XX_QUIRK_END_OF_TRANSACTION
;
if
(
wl
->
ref_clock
==
CONF_REF_CLK_19_2_E
||
wl
->
ref_clock
==
CONF_REF_CLK_38_4_E
||
...
...
@@ -750,6 +738,8 @@ int wl1271_load_firmware(struct wl1271 *wl)
u32
tmp
,
clk
;
int
selected_clock
=
-
1
;
wl1271_boot_hw_version
(
wl
);
if
(
wl
->
chip
.
id
==
CHIP_ID_1283_PG20
)
{
ret
=
wl128x_boot_clk
(
wl
,
&
selected_clock
);
if
(
ret
<
0
)
...
...
@@ -852,9 +842,6 @@ int wl1271_boot(struct wl1271 *wl)
/* Enable firmware interrupts now */
wl1271_boot_enable_interrupts
(
wl
);
/* set the wl1271 default filters */
wl1271_set_default_filters
(
wl
);
wl1271_event_mbox_config
(
wl
);
out:
...
...
drivers/net/wireless/wl12xx/boot.h
View file @
e0a8c583
...
...
@@ -55,7 +55,8 @@ struct wl1271_static_data {
#define OCP_REG_CLK_POLARITY 0x0cb2
#define OCP_REG_CLK_PULL 0x0cb4
#define REG_FUSE_DATA_2_1 0x050a
#define WL127X_REG_FUSE_DATA_2_1 0x050a
#define WL128X_REG_FUSE_DATA_2_1 0x2152
#define PG_VER_MASK 0x3c
#define PG_VER_OFFSET 2
...
...
drivers/net/wireless/wl12xx/cmd.c
View file @
e0a8c583
...
...
@@ -363,63 +363,470 @@ static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask)
return
0
;
}
int
wl12
71_cmd_join
(
struct
wl1271
*
wl
,
u8
bss_type
)
int
wl12
xx_cmd_role_enable
(
struct
wl1271
*
wl
,
u8
role_type
,
u8
*
role_id
)
{
struct
wl1271_cmd_join
*
join
;
int
ret
,
i
;
u8
*
bssid
;
struct
wl12xx_cmd_role_enable
*
cmd
;
int
ret
;
wl1271_debug
(
DEBUG_CMD
,
"cmd role enable"
);
join
=
kzalloc
(
sizeof
(
*
join
),
GFP_KERNEL
);
if
(
!
join
)
{
if
(
WARN_ON
(
*
role_id
!=
WL12XX_INVALID_ROLE_ID
))
return
-
EBUSY
;
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
wl1271_debug
(
DEBUG_CMD
,
"cmd join"
);
/* get role id */
cmd
->
role_id
=
find_first_zero_bit
(
wl
->
roles_map
,
WL12XX_MAX_ROLES
);
if
(
cmd
->
role_id
>=
WL12XX_MAX_ROLES
)
{
ret
=
-
EBUSY
;
goto
out_free
;
}
memcpy
(
cmd
->
mac_address
,
wl
->
mac_addr
,
ETH_ALEN
);
cmd
->
role_type
=
role_type
;
ret
=
wl1271_cmd_send
(
wl
,
CMD_ROLE_ENABLE
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to initiate cmd role enable"
);
goto
out_free
;
}
__set_bit
(
cmd
->
role_id
,
wl
->
roles_map
);
*
role_id
=
cmd
->
role_id
;
out_free:
kfree
(
cmd
);
out:
return
ret
;
}
int
wl12xx_cmd_role_disable
(
struct
wl1271
*
wl
,
u8
*
role_id
)
{
struct
wl12xx_cmd_role_disable
*
cmd
;
int
ret
;
wl1271_debug
(
DEBUG_CMD
,
"cmd role disable"
);
if
(
WARN_ON
(
*
role_id
==
WL12XX_INVALID_ROLE_ID
))
return
-
ENOENT
;
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
cmd
->
role_id
=
*
role_id
;
ret
=
wl1271_cmd_send
(
wl
,
CMD_ROLE_DISABLE
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to initiate cmd role disable"
);
goto
out_free
;
}
__clear_bit
(
*
role_id
,
wl
->
roles_map
);
*
role_id
=
WL12XX_INVALID_ROLE_ID
;
out_free:
kfree
(
cmd
);
out:
return
ret
;
}
static
int
wl12xx_allocate_link
(
struct
wl1271
*
wl
,
u8
*
hlid
)
{
u8
link
=
find_first_zero_bit
(
wl
->
links_map
,
WL12XX_MAX_LINKS
);
if
(
link
>=
WL12XX_MAX_LINKS
)
return
-
EBUSY
;
__set_bit
(
link
,
wl
->
links_map
);
*
hlid
=
link
;
return
0
;
}
static
void
wl12xx_free_link
(
struct
wl1271
*
wl
,
u8
*
hlid
)
{
if
(
*
hlid
==
WL12XX_INVALID_LINK_ID
)
return
;
__clear_bit
(
*
hlid
,
wl
->
links_map
);
*
hlid
=
WL12XX_INVALID_LINK_ID
;
}
static
int
wl12xx_get_new_session_id
(
struct
wl1271
*
wl
)
{
if
(
wl
->
session_counter
>=
SESSION_COUNTER_MAX
)
wl
->
session_counter
=
0
;
wl
->
session_counter
++
;
/* Reverse order BSSID */
bssid
=
(
u8
*
)
&
join
->
bssid_lsb
;
for
(
i
=
0
;
i
<
ETH_ALEN
;
i
++
)
bssid
[
i
]
=
wl
->
bssid
[
ETH_ALEN
-
i
-
1
];
return
wl
->
session_counter
;
}
int
wl12xx_cmd_role_start_dev
(
struct
wl1271
*
wl
)
{
struct
wl12xx_cmd_role_start
*
cmd
;
int
ret
;
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
join
->
rx_config_options
=
cpu_to_le32
(
wl
->
rx_config
);
join
->
rx_filter_options
=
cpu_to_le32
(
wl
->
rx_filter
);
join
->
bss_type
=
bss_type
;
join
->
basic_rate_set
=
cpu_to_le32
(
wl
->
basic_rate_set
);
join
->
supported_rate_set
=
cpu_to_le32
(
wl
->
rate_set
);
wl1271_debug
(
DEBUG_CMD
,
"cmd role start dev %d"
,
wl
->
dev_role_id
);
cmd
->
role_id
=
wl
->
dev_role_id
;
if
(
wl
->
band
==
IEEE80211_BAND_5GHZ
)
join
->
bss_type
|=
WL1271_JOIN_CMD_BSS_TYPE_5GHZ
;
cmd
->
band
=
WL12XX_BAND_5GHZ
;
cmd
->
channel
=
wl
->
channel
;
if
(
wl
->
dev_hlid
==
WL12XX_INVALID_LINK_ID
)
{
ret
=
wl12xx_allocate_link
(
wl
,
&
wl
->
dev_hlid
);
if
(
ret
)
goto
out_free
;
}
cmd
->
device
.
hlid
=
wl
->
dev_hlid
;
cmd
->
device
.
session
=
wl
->
session_counter
;
wl1271_debug
(
DEBUG_CMD
,
"role start: roleid=%d, hlid=%d, session=%d"
,
cmd
->
role_id
,
cmd
->
device
.
hlid
,
cmd
->
device
.
session
);
join
->
beacon_interval
=
cpu_to_le16
(
wl
->
beacon_int
);
join
->
dtim_interval
=
WL1271_DEFAULT_DTIM_PERIOD
;
ret
=
wl1271_cmd_send
(
wl
,
CMD_ROLE_START
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to initiate cmd role enable"
);
goto
err_hlid
;
}
goto
out_free
;
err_hlid:
/* clear links on error */
__clear_bit
(
wl
->
dev_hlid
,
wl
->
links_map
);
wl
->
dev_hlid
=
WL12XX_INVALID_LINK_ID
;
out_free:
kfree
(
cmd
);
join
->
channel
=
wl
->
channel
;
join
->
ssid_len
=
wl
->
ssid_len
;
memcpy
(
join
->
ssid
,
wl
->
ssid
,
wl
->
ssid_len
);
out:
return
ret
;
}
join
->
ctrl
|=
wl
->
session_counter
<<
WL1271_JOIN_CMD_TX_SESSION_OFFSET
;
int
wl12xx_cmd_role_stop_dev
(
struct
wl1271
*
wl
)
{
struct
wl12xx_cmd_role_stop
*
cmd
;
int
ret
;
wl1271_debug
(
DEBUG_CMD
,
"cmd join: basic_rate_set=0x%x, rate_set=0x%x"
,
join
->
basic_rate_set
,
join
->
supported_rate_set
)
;
if
(
WARN_ON
(
wl
->
dev_hlid
==
WL12XX_INVALID_LINK_ID
))
return
-
EINVAL
;
ret
=
wl1271_cmd_send
(
wl
,
CMD_START_JOIN
,
join
,
sizeof
(
*
join
),
0
);
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
wl1271_debug
(
DEBUG_CMD
,
"cmd role stop dev"
);
cmd
->
role_id
=
wl
->
dev_role_id
;
cmd
->
disc_type
=
DISCONNECT_IMMEDIATE
;
cmd
->
reason
=
cpu_to_le16
(
WLAN_REASON_UNSPECIFIED
);
ret
=
wl1271_cmd_send
(
wl
,
CMD_ROLE_STOP
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to initiate cmd
join
"
);
wl1271_error
(
"failed to initiate cmd
role stop
"
);
goto
out_free
;
}
ret
=
wl1271_cmd_wait_for_event
(
wl
,
JOIN_EVENT_COMPLETE_ID
);
ret
=
wl1271_cmd_wait_for_event
(
wl
,
DISCONNECT_EVENT_COMPLETE_ID
);
if
(
ret
<
0
)
{
wl1271_error
(
"cmd role stop dev event completion error"
);
goto
out_free
;
}
wl12xx_free_link
(
wl
,
&
wl
->
dev_hlid
);
out_free:
kfree
(
cmd
);
out:
return
ret
;
}
int
wl12xx_cmd_role_start_sta
(
struct
wl1271
*
wl
)
{
struct
wl12xx_cmd_role_start
*
cmd
;
int
ret
;
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
wl1271_debug
(
DEBUG_CMD
,
"cmd role start sta %d"
,
wl
->
role_id
);
cmd
->
role_id
=
wl
->
role_id
;
if
(
wl
->
band
==
IEEE80211_BAND_5GHZ
)
cmd
->
band
=
WL12XX_BAND_5GHZ
;
cmd
->
channel
=
wl
->
channel
;
cmd
->
sta
.
basic_rate_set
=
cpu_to_le32
(
wl
->
basic_rate_set
);
cmd
->
sta
.
beacon_interval
=
cpu_to_le16
(
wl
->
beacon_int
);
cmd
->
sta
.
ssid_type
=
WL12XX_SSID_TYPE_ANY
;
cmd
->
sta
.
ssid_len
=
wl
->
ssid_len
;
memcpy
(
cmd
->
sta
.
ssid
,
wl
->
ssid
,
wl
->
ssid_len
);
memcpy
(
cmd
->
sta
.
bssid
,
wl
->
bssid
,
ETH_ALEN
);
cmd
->
sta
.
local_rates
=
cpu_to_le32
(
wl
->
rate_set
);
if
(
wl
->
sta_hlid
==
WL12XX_INVALID_LINK_ID
)
{
ret
=
wl12xx_allocate_link
(
wl
,
&
wl
->
sta_hlid
);
if
(
ret
)
goto
out_free
;
}
cmd
->
sta
.
hlid
=
wl
->
sta_hlid
;
cmd
->
sta
.
session
=
wl12xx_get_new_session_id
(
wl
);
cmd
->
sta
.
remote_rates
=
cpu_to_le32
(
wl
->
rate_set
);
wl1271_debug
(
DEBUG_CMD
,
"role start: roleid=%d, hlid=%d, session=%d "
"basic_rate_set: 0x%x, remote_rates: 0x%x"
,
wl
->
role_id
,
cmd
->
sta
.
hlid
,
cmd
->
sta
.
session
,
wl
->
basic_rate_set
,
wl
->
rate_set
);
ret
=
wl1271_cmd_send
(
wl
,
CMD_ROLE_START
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to initiate cmd role start sta"
);
goto
err_hlid
;
}
goto
out_free
;
err_hlid:
/* clear links on error. */
wl12xx_free_link
(
wl
,
&
wl
->
sta_hlid
);
out_free:
kfree
(
cmd
);
out:
return
ret
;
}
/* use this function to stop ibss as well */
int
wl12xx_cmd_role_stop_sta
(
struct
wl1271
*
wl
)
{
struct
wl12xx_cmd_role_stop
*
cmd
;
int
ret
;
if
(
WARN_ON
(
wl
->
sta_hlid
==
WL12XX_INVALID_LINK_ID
))
return
-
EINVAL
;
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
wl1271_debug
(
DEBUG_CMD
,
"cmd role stop sta %d"
,
wl
->
role_id
);
cmd
->
role_id
=
wl
->
role_id
;
cmd
->
disc_type
=
DISCONNECT_IMMEDIATE
;
cmd
->
reason
=
cpu_to_le16
(
WLAN_REASON_UNSPECIFIED
);
ret
=
wl1271_cmd_send
(
wl
,
CMD_ROLE_STOP
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to initiate cmd role stop sta"
);
goto
out_free
;
}
wl12xx_free_link
(
wl
,
&
wl
->
sta_hlid
);
out_free:
kfree
(
cmd
);
out:
return
ret
;
}
int
wl12xx_cmd_role_start_ap
(
struct
wl1271
*
wl
)
{
struct
wl12xx_cmd_role_start
*
cmd
;
struct
ieee80211_bss_conf
*
bss_conf
=
&
wl
->
vif
->
bss_conf
;
int
ret
;
wl1271_debug
(
DEBUG_CMD
,
"cmd role start ap %d"
,
wl
->
role_id
);
/*
* 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
;
}
ret
=
wl12xx_allocate_link
(
wl
,
&
wl
->
ap_global_hlid
);
if
(
ret
<
0
)
wl1271_error
(
"cmd join event completion error"
);
goto
out_free
;
ret
=
wl12xx_allocate_link
(
wl
,
&
wl
->
ap_bcast_hlid
);
if
(
ret
<
0
)
goto
out_free_global
;
cmd
->
role_id
=
wl
->
role_id
;
cmd
->
ap
.
aging_period
=
cpu_to_le16
(
wl
->
conf
.
tx
.
ap_aging_period
);
cmd
->
ap
.
bss_index
=
WL1271_AP_BSS_INDEX
;
cmd
->
ap
.
global_hlid
=
wl
->
ap_global_hlid
;
cmd
->
ap
.
broadcast_hlid
=
wl
->
ap_bcast_hlid
;
cmd
->
ap
.
basic_rate_set
=
cpu_to_le32
(
wl
->
basic_rate_set
);
cmd
->
ap
.
beacon_interval
=
cpu_to_le16
(
wl
->
beacon_int
);
cmd
->
ap
.
dtim_interval
=
bss_conf
->
dtim_period
;
cmd
->
ap
.
beacon_expiry
=
WL1271_AP_DEF_BEACON_EXP
;
cmd
->
channel
=
wl
->
channel
;
cmd
->
ap
.
ssid_len
=
wl
->
ssid_len
;
cmd
->
ap
.
ssid_type
=
WL12XX_SSID_TYPE_PUBLIC
;
memcpy
(
cmd
->
ap
.
ssid
,
wl
->
ssid
,
wl
->
ssid_len
);
cmd
->
ap
.
local_rates
=
cpu_to_le32
(
0xffffffff
);
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
(
"ap start - unknown band: %d"
,
(
int
)
wl
->
band
);
cmd
->
band
=
RADIO_BAND_2_4GHZ
;
break
;
}
ret
=
wl1271_cmd_send
(
wl
,
CMD_ROLE_START
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to initiate cmd role start ap"
);
goto
out_free_bcast
;
}
goto
out_free
;
out_free_bcast:
wl12xx_free_link
(
wl
,
&
wl
->
ap_bcast_hlid
);
out_free_global:
wl12xx_free_link
(
wl
,
&
wl
->
ap_global_hlid
);
out_free:
kfree
(
cmd
);
out:
return
ret
;
}
int
wl12xx_cmd_role_stop_ap
(
struct
wl1271
*
wl
)
{
struct
wl12xx_cmd_role_stop
*
cmd
;
int
ret
;
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
wl1271_debug
(
DEBUG_CMD
,
"cmd role stop ap %d"
,
wl
->
role_id
);
cmd
->
role_id
=
wl
->
role_id
;
ret
=
wl1271_cmd_send
(
wl
,
CMD_ROLE_STOP
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to initiate cmd role stop ap"
);
goto
out_free
;
}
wl12xx_free_link
(
wl
,
&
wl
->
ap_bcast_hlid
);
wl12xx_free_link
(
wl
,
&
wl
->
ap_global_hlid
);
out_free:
kfree
(
join
);
kfree
(
cmd
);
out:
return
ret
;
}
int
wl12xx_cmd_role_start_ibss
(
struct
wl1271
*
wl
)
{
struct
wl12xx_cmd_role_start
*
cmd
;
struct
ieee80211_bss_conf
*
bss_conf
=
&
wl
->
vif
->
bss_conf
;
int
ret
;
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
wl1271_debug
(
DEBUG_CMD
,
"cmd role start ibss %d"
,
wl
->
role_id
);
cmd
->
role_id
=
wl
->
role_id
;
if
(
wl
->
band
==
IEEE80211_BAND_5GHZ
)
cmd
->
band
=
WL12XX_BAND_5GHZ
;
cmd
->
channel
=
wl
->
channel
;
cmd
->
ibss
.
basic_rate_set
=
cpu_to_le32
(
wl
->
basic_rate_set
);
cmd
->
ibss
.
beacon_interval
=
cpu_to_le16
(
wl
->
beacon_int
);
cmd
->
ibss
.
dtim_interval
=
bss_conf
->
dtim_period
;
cmd
->
ibss
.
ssid_type
=
WL12XX_SSID_TYPE_ANY
;
cmd
->
ibss
.
ssid_len
=
wl
->
ssid_len
;
memcpy
(
cmd
->
ibss
.
ssid
,
wl
->
ssid
,
wl
->
ssid_len
);
memcpy
(
cmd
->
ibss
.
bssid
,
wl
->
bssid
,
ETH_ALEN
);
cmd
->
sta
.
local_rates
=
cpu_to_le32
(
wl
->
rate_set
);
if
(
wl
->
sta_hlid
==
WL12XX_INVALID_LINK_ID
)
{
ret
=
wl12xx_allocate_link
(
wl
,
&
wl
->
sta_hlid
);
if
(
ret
)
goto
out_free
;
}
cmd
->
ibss
.
hlid
=
wl
->
sta_hlid
;
cmd
->
ibss
.
remote_rates
=
cpu_to_le32
(
wl
->
rate_set
);
wl1271_debug
(
DEBUG_CMD
,
"role start: roleid=%d, hlid=%d, session=%d "
"basic_rate_set: 0x%x, remote_rates: 0x%x"
,
wl
->
role_id
,
cmd
->
sta
.
hlid
,
cmd
->
sta
.
session
,
wl
->
basic_rate_set
,
wl
->
rate_set
);
wl1271_debug
(
DEBUG_CMD
,
"wl->bssid = %pM"
,
wl
->
bssid
);
ret
=
wl1271_cmd_send
(
wl
,
CMD_ROLE_START
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to initiate cmd role enable"
);
goto
err_hlid
;
}
goto
out_free
;
err_hlid:
/* clear links on error. */
wl12xx_free_link
(
wl
,
&
wl
->
sta_hlid
);
out_free:
kfree
(
cmd
);
out:
return
ret
;
}
/**
* send test command to firmware
*
...
...
@@ -567,6 +974,7 @@ int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode)
goto
out
;
}
ps_params
->
role_id
=
wl
->
role_id
;
ps_params
->
ps_mode
=
ps_mode
;
ret
=
wl1271_cmd_send
(
wl
,
CMD_SET_PS_MODE
,
ps_params
,
...
...
@@ -813,9 +1221,9 @@ int wl1271_build_qos_null_data(struct wl1271 *wl)
wl
->
basic_rate
);
}
int
wl12
71_cmd_set_sta_default_wep_key
(
struct
wl1271
*
wl
,
u8
id
)
int
wl12
xx_cmd_set_default_wep_key
(
struct
wl1271
*
wl
,
u8
id
,
u8
hl
id
)
{
struct
wl1271_cmd_set_
sta_
keys
*
cmd
;
struct
wl1271_cmd_set_keys
*
cmd
;
int
ret
=
0
;
wl1271_debug
(
DEBUG_CMD
,
"cmd set_default_wep_key %d"
,
id
);
...
...
@@ -826,36 +1234,7 @@ int wl1271_cmd_set_sta_default_wep_key(struct wl1271 *wl, u8 id)
goto
out
;
}
cmd
->
id
=
id
;
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_default_wep_key failed: %d"
,
ret
);
goto
out
;
}
out:
kfree
(
cmd
);
return
ret
;
}
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
->
hlid
=
hlid
;
cmd
->
key_id
=
id
;
cmd
->
lid_key_type
=
WEP_DEFAULT_LID_TYPE
;
cmd
->
key_action
=
cpu_to_le16
(
KEY_SET_ID
);
...
...
@@ -863,7 +1242,7 @@ int wl1271_cmd_set_ap_default_wep_key(struct wl1271 *wl, u8 id)
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
);
wl1271_warning
(
"cmd set_default_wep_key failed: %d"
,
ret
);
goto
out
;
}
...
...
@@ -877,17 +1256,27 @@ 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_
sta_
keys
*
cmd
;
struct
wl1271_cmd_set_keys
*
cmd
;
int
ret
=
0
;
/* hlid might have already been deleted */
if
(
wl
->
sta_hlid
==
WL12XX_INVALID_LINK_ID
)
return
0
;
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
if
(
key_type
!=
KEY_WEP
)
memcpy
(
cmd
->
addr
,
addr
,
ETH_ALEN
);
cmd
->
hlid
=
wl
->
sta_hlid
;
if
(
key_type
==
KEY_WEP
)
cmd
->
lid_key_type
=
WEP_DEFAULT_LID_TYPE
;
else
if
(
is_broadcast_ether_addr
(
addr
))
cmd
->
lid_key_type
=
BROADCAST_LID_TYPE
;
else
cmd
->
lid_key_type
=
UNICAST_LID_TYPE
;
cmd
->
key_action
=
cpu_to_le16
(
action
);
cmd
->
key_size
=
key_size
;
...
...
@@ -896,10 +1285,7 @@ int wl1271_cmd_set_sta_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
cmd
->
ac_seq_num16
[
0
]
=
cpu_to_le16
(
tx_seq_16
);
cmd
->
ac_seq_num32
[
0
]
=
cpu_to_le32
(
tx_seq_32
);
/* we have only one SSID profile */
cmd
->
ssid_profile
=
0
;
cmd
->
id
=
id
;
cmd
->
key_id
=
id
;
if
(
key_type
==
KEY_TKIP
)
{
/*
...
...
@@ -930,11 +1316,15 @@ int wl1271_cmd_set_sta_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
return
ret
;
}
/*
* TODO: merge with sta/ibss into 1 set_key function.
* note there are slight diffs
*/
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
;
struct
wl1271_cmd_set_keys
*
cmd
;
int
ret
=
0
;
u8
lid_type
;
...
...
@@ -942,7 +1332,7 @@ int wl1271_cmd_set_ap_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
if
(
!
cmd
)
return
-
ENOMEM
;
if
(
hlid
==
WL1271_AP_BROADCAST_HLID
)
{
if
(
hlid
==
wl
->
ap_bcast_hlid
)
{
if
(
key_type
==
KEY_WEP
)
lid_type
=
WEP_DEFAULT_LID_TYPE
;
else
...
...
@@ -991,12 +1381,12 @@ int wl1271_cmd_set_ap_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
return
ret
;
}
int
wl12
71_cmd_disconnect
(
struct
wl1271
*
wl
)
int
wl12
xx_cmd_set_peer_state
(
struct
wl1271
*
wl
,
u8
hlid
)
{
struct
wl12
71_cmd_disconnect
*
cmd
;
struct
wl12
xx_cmd_set_peer_state
*
cmd
;
int
ret
=
0
;
wl1271_debug
(
DEBUG_CMD
,
"cmd
disconnect"
);
wl1271_debug
(
DEBUG_CMD
,
"cmd
set peer state (hlid=%d)"
,
hlid
);
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
...
...
@@ -1004,21 +1394,15 @@ int wl1271_cmd_disconnect(struct wl1271 *wl)
goto
out
;
}
cmd
->
rx_config_options
=
cpu_to_le32
(
wl
->
rx_config
);
cmd
->
rx_filter_options
=
cpu_to_le32
(
wl
->
rx_filter
);
/* disconnect reason is not used in immediate disconnections */
cmd
->
type
=
DISCONNECT_IMMEDIATE
;
cmd
->
hlid
=
hlid
;
cmd
->
state
=
WL1271_CMD_STA_STATE_CONNECTED
;
ret
=
wl1271_cmd_send
(
wl
,
CMD_
DISCONNECT
,
cmd
,
sizeof
(
*
cmd
),
0
);
ret
=
wl1271_cmd_send
(
wl
,
CMD_
SET_PEER_STATE
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to send
disconnect
command"
);
wl1271_error
(
"failed to send
set peer state
command"
);
goto
out_free
;
}
ret
=
wl1271_cmd_wait_for_event
(
wl
,
DISCONNECT_EVENT_COMPLETE_ID
);
if
(
ret
<
0
)
wl1271_error
(
"cmd disconnect event completion error"
);
out_free:
kfree
(
cmd
);
...
...
@@ -1026,12 +1410,13 @@ int wl1271_cmd_disconnect(struct wl1271 *wl)
return
ret
;
}
int
wl12
71_cmd_set_sta_state
(
struct
wl1271
*
wl
)
int
wl12
xx_cmd_add_peer
(
struct
wl1271
*
wl
,
struct
ieee80211_sta
*
sta
,
u8
hlid
)
{
struct
wl1271_cmd_set_sta_state
*
cmd
;
int
ret
=
0
;
struct
wl12xx_cmd_add_peer
*
cmd
;
int
ret
;
u32
sta_rates
;
wl1271_debug
(
DEBUG_CMD
,
"cmd
set sta state"
);
wl1271_debug
(
DEBUG_CMD
,
"cmd
add peer %d"
,
(
int
)
hlid
);
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
...
...
@@ -1039,11 +1424,27 @@ int wl1271_cmd_set_sta_state(struct wl1271 *wl)
goto
out
;
}
cmd
->
state
=
WL1271_CMD_STA_STATE_CONNECTED
;
/* 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
;
cmd
->
wmm
=
sta
->
wme
?
1
:
0
;
sta_rates
=
sta
->
supp_rates
[
wl
->
band
];
if
(
sta
->
ht_cap
.
ht_supported
)
sta_rates
|=
sta
->
ht_cap
.
mcs
.
rx_mask
[
0
]
<<
HW_HT_RATES_OFFSET
;
cmd
->
supported_rates
=
cpu_to_le32
(
wl1271_tx_enabled_rates_get
(
wl
,
sta_rates
));
ret
=
wl1271_cmd_send
(
wl
,
CMD_SET_STA_STATE
,
cmd
,
sizeof
(
*
cmd
),
0
);
wl1271_debug
(
DEBUG_CMD
,
"new peer rates: 0x%x"
,
cmd
->
supported_rates
);
ret
=
wl1271_cmd_send
(
wl
,
CMD_ADD_PEER
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to
send set STA state command
"
);
wl1271_error
(
"failed to
initiate cmd add peer
"
);
goto
out_free
;
}
...
...
@@ -1054,23 +1455,12 @@ int wl1271_cmd_set_sta_state(struct wl1271 *wl)
return
ret
;
}
int
wl12
71_cmd_start_bss
(
struct
wl1271
*
wl
)
int
wl12
xx_cmd_remove_peer
(
struct
wl1271
*
wl
,
u8
hlid
)
{
struct
wl1271_cmd_bss_start
*
cmd
;
struct
ieee80211_bss_conf
*
bss_conf
=
&
wl
->
vif
->
bss_conf
;
struct
wl12xx_cmd_remove_peer
*
cmd
;
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
;
}
wl1271_debug
(
DEBUG_CMD
,
"cmd remove peer %d"
,
(
int
)
hlid
);
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
...
...
@@ -1078,40 +1468,24 @@ int wl1271_cmd_start_bss(struct wl1271 *wl)
goto
out
;
}
memcpy
(
cmd
->
bssid
,
bss_conf
->
bssid
,
ETH_ALEN
);
cmd
->
aging_period
=
cpu_to_le16
(
wl
->
conf
.
tx
.
ap_aging_period
);
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
;
}
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_
BSS_START
,
cmd
,
sizeof
(
*
cmd
),
0
);
ret
=
wl1271_cmd_send
(
wl
,
CMD_
REMOVE_PEER
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to initiate cmd
start bss
"
);
wl1271_error
(
"failed to initiate cmd
remove peer
"
);
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
,
PEER_REMOVE_COMPLETE_EVENT_ID
);
out_free:
kfree
(
cmd
);
...
...
@@ -1119,12 +1493,12 @@ int wl1271_cmd_start_bss(struct wl1271 *wl)
return
ret
;
}
int
wl12
71_cmd_stop_bss
(
struct
wl1271
*
wl
)
int
wl12
xx_cmd_config_fwlog
(
struct
wl1271
*
wl
)
{
struct
wl12
71_cmd_bss_start
*
cmd
;
int
ret
;
struct
wl12
xx_cmd_config_fwlog
*
cmd
;
int
ret
=
0
;
wl1271_debug
(
DEBUG_CMD
,
"cmd
stop bss
"
);
wl1271_debug
(
DEBUG_CMD
,
"cmd
config firmware logger
"
);
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
...
...
@@ -1132,11 +1506,15 @@ int wl1271_cmd_stop_bss(struct wl1271 *wl)
goto
out
;
}
cmd
->
bss_index
=
WL1271_AP_BSS_INDEX
;
cmd
->
logger_mode
=
wl
->
conf
.
fwlog
.
mode
;
cmd
->
log_severity
=
wl
->
conf
.
fwlog
.
severity
;
cmd
->
timestamp
=
wl
->
conf
.
fwlog
.
timestamp
;
cmd
->
output
=
wl
->
conf
.
fwlog
.
output
;
cmd
->
threshold
=
wl
->
conf
.
fwlog
.
threshold
;
ret
=
wl1271_cmd_send
(
wl
,
CMD_
BSS_STOP
,
cmd
,
sizeof
(
*
cmd
),
0
);
ret
=
wl1271_cmd_send
(
wl
,
CMD_
CONFIG_FWLOGGER
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to
initiate cmd stop bss
"
);
wl1271_error
(
"failed to
send config firmware logger command
"
);
goto
out_free
;
}
...
...
@@ -1147,12 +1525,12 @@ int wl1271_cmd_stop_bss(struct wl1271 *wl)
return
ret
;
}
int
wl12
71_cmd_add_sta
(
struct
wl1271
*
wl
,
struct
ieee80211_sta
*
sta
,
u8
hlid
)
int
wl12
xx_cmd_start_fwlog
(
struct
wl1271
*
wl
)
{
struct
wl12
71_cmd_add_sta
*
cmd
;
int
ret
;
struct
wl12
xx_cmd_start_fwlog
*
cmd
;
int
ret
=
0
;
wl1271_debug
(
DEBUG_CMD
,
"cmd
add sta %d"
,
(
int
)
hlid
);
wl1271_debug
(
DEBUG_CMD
,
"cmd
start firmware logger"
);
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
...
...
@@ -1160,23 +1538,9 @@ int wl1271_cmd_add_sta(struct wl1271 *wl, struct ieee80211_sta *sta, u8 hlid)
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
;
cmd
->
wmm
=
sta
->
wme
?
1
:
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
);
ret
=
wl1271_cmd_send
(
wl
,
CMD_START_FWLOGGER
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to
initiate cmd add sta
"
);
wl1271_error
(
"failed to
send start firmware logger command
"
);
goto
out_free
;
}
...
...
@@ -1187,12 +1551,12 @@ int wl1271_cmd_add_sta(struct wl1271 *wl, struct ieee80211_sta *sta, u8 hlid)
return
ret
;
}
int
wl12
71_cmd_remove_sta
(
struct
wl1271
*
wl
,
u8
hlid
)
int
wl12
xx_cmd_stop_fwlog
(
struct
wl1271
*
wl
)
{
struct
wl12
71_cmd_remove_sta
*
cmd
;
int
ret
;
struct
wl12
xx_cmd_stop_fwlog
*
cmd
;
int
ret
=
0
;
wl1271_debug
(
DEBUG_CMD
,
"cmd
remove sta %d"
,
(
int
)
hlid
);
wl1271_debug
(
DEBUG_CMD
,
"cmd
stop firmware logger"
);
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
...
...
@@ -1200,23 +1564,12 @@ int wl1271_cmd_remove_sta(struct wl1271 *wl, u8 hlid)
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
);
ret
=
wl1271_cmd_send
(
wl
,
CMD_STOP_FWLOGGER
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to
initiate cmd remove sta
"
);
wl1271_error
(
"failed to
send stop firmware logger command
"
);
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
);
...
...
@@ -1224,12 +1577,15 @@ int wl1271_cmd_remove_sta(struct wl1271 *wl, u8 hlid)
return
ret
;
}
int
wl12xx_cmd_config_fwlog
(
struct
wl1271
*
wl
)
static
int
wl12xx_cmd_roc
(
struct
wl1271
*
wl
,
u8
role_id
)
{
struct
wl12xx_cmd_
config_fwlog
*
cmd
;
struct
wl12xx_cmd_
roc
*
cmd
;
int
ret
=
0
;
wl1271_debug
(
DEBUG_CMD
,
"cmd config firmware logger"
);
wl1271_debug
(
DEBUG_CMD
,
"cmd roc %d (%d)"
,
wl
->
channel
,
role_id
);
if
(
WARN_ON
(
role_id
==
WL12XX_INVALID_ROLE_ID
))
return
-
EINVAL
;
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
...
...
@@ -1237,15 +1593,25 @@ int wl12xx_cmd_config_fwlog(struct wl1271 *wl)
goto
out
;
}
cmd
->
logger_mode
=
wl
->
conf
.
fwlog
.
mode
;
cmd
->
log_severity
=
wl
->
conf
.
fwlog
.
severity
;
cmd
->
timestamp
=
wl
->
conf
.
fwlog
.
timestamp
;
cmd
->
output
=
wl
->
conf
.
fwlog
.
output
;
cmd
->
threshold
=
wl
->
conf
.
fwlog
.
threshold
;
cmd
->
role_id
=
role_id
;
cmd
->
channel
=
wl
->
channel
;
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_error
(
"roc - unknown band: %d"
,
(
int
)
wl
->
band
);
ret
=
-
EINVAL
;
goto
out_free
;
}
ret
=
wl1271_cmd_send
(
wl
,
CMD_CONFIG_FWLOGGER
,
cmd
,
sizeof
(
*
cmd
),
0
);
ret
=
wl1271_cmd_send
(
wl
,
CMD_REMAIN_ON_CHANNEL
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to send
config firmware logger
command"
);
wl1271_error
(
"failed to send
ROC
command"
);
goto
out_free
;
}
...
...
@@ -1256,22 +1622,24 @@ int wl12xx_cmd_config_fwlog(struct wl1271 *wl)
return
ret
;
}
int
wl12xx_cmd_start_fwlog
(
struct
wl1271
*
wl
)
static
int
wl12xx_cmd_croc
(
struct
wl1271
*
wl
,
u8
role_id
)
{
struct
wl12xx_cmd_
start_fwlog
*
cmd
;
struct
wl12xx_cmd_
croc
*
cmd
;
int
ret
=
0
;
wl1271_debug
(
DEBUG_CMD
,
"cmd
start firmware logger"
);
wl1271_debug
(
DEBUG_CMD
,
"cmd
croc (%d)"
,
role_id
);
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
cmd
->
role_id
=
role_id
;
ret
=
wl1271_cmd_send
(
wl
,
CMD_START_FWLOGGER
,
cmd
,
sizeof
(
*
cmd
),
0
);
ret
=
wl1271_cmd_send
(
wl
,
CMD_CANCEL_REMAIN_ON_CHANNEL
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to send
start firmware logger
command"
);
wl1271_error
(
"failed to send
ROC
command"
);
goto
out_free
;
}
...
...
@@ -1282,28 +1650,41 @@ int wl12xx_cmd_start_fwlog(struct wl1271 *wl)
return
ret
;
}
int
wl12xx_
cmd_stop_fwlog
(
struct
wl1271
*
wl
)
int
wl12xx_
roc
(
struct
wl1271
*
wl
,
u8
role_id
)
{
struct
wl12xx_cmd_stop_fwlog
*
cmd
;
int
ret
=
0
;
wl1271_debug
(
DEBUG_CMD
,
"cmd stop firmware logger"
);
if
(
WARN_ON
(
test_bit
(
role_id
,
wl
->
roc_map
)))
return
0
;
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
ret
=
-
ENOMEM
;
ret
=
wl12xx_cmd_roc
(
wl
,
role_id
);
if
(
ret
<
0
)
goto
out
;
}
ret
=
wl1271_cmd_send
(
wl
,
CMD_STOP_FWLOGGER
,
cmd
,
sizeof
(
*
cmd
),
0
);
ret
=
wl1271_cmd_wait_for_event
(
wl
,
REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID
);
if
(
ret
<
0
)
{
wl1271_error
(
"
failed to send stop firmware logger command
"
);
goto
out
_free
;
wl1271_error
(
"
cmd roc event completion error
"
);
goto
out
;
}
out_free:
kfree
(
cmd
);
__set_bit
(
role_id
,
wl
->
roc_map
);
out:
return
ret
;
}
int
wl12xx_croc
(
struct
wl1271
*
wl
,
u8
role_id
)
{
int
ret
=
0
;
if
(
WARN_ON
(
!
test_bit
(
role_id
,
wl
->
roc_map
)))
return
0
;
ret
=
wl12xx_cmd_croc
(
wl
,
role_id
);
if
(
ret
<
0
)
goto
out
;
__clear_bit
(
role_id
,
wl
->
roc_map
);
out:
return
ret
;
}
drivers/net/wireless/wl12xx/cmd.h
View file @
e0a8c583
...
...
@@ -36,7 +36,15 @@ int wl128x_cmd_general_parms(struct wl1271 *wl);
int
wl1271_cmd_radio_parms
(
struct
wl1271
*
wl
);
int
wl128x_cmd_radio_parms
(
struct
wl1271
*
wl
);
int
wl1271_cmd_ext_radio_parms
(
struct
wl1271
*
wl
);
int
wl1271_cmd_join
(
struct
wl1271
*
wl
,
u8
bss_type
);
int
wl12xx_cmd_role_enable
(
struct
wl1271
*
wl
,
u8
role_type
,
u8
*
role_id
);
int
wl12xx_cmd_role_disable
(
struct
wl1271
*
wl
,
u8
*
role_id
);
int
wl12xx_cmd_role_start_dev
(
struct
wl1271
*
wl
);
int
wl12xx_cmd_role_stop_dev
(
struct
wl1271
*
wl
);
int
wl12xx_cmd_role_start_sta
(
struct
wl1271
*
wl
);
int
wl12xx_cmd_role_stop_sta
(
struct
wl1271
*
wl
);
int
wl12xx_cmd_role_start_ap
(
struct
wl1271
*
wl
);
int
wl12xx_cmd_role_stop_ap
(
struct
wl1271
*
wl
);
int
wl12xx_cmd_role_start_ibss
(
struct
wl1271
*
wl
);
int
wl1271_cmd_test
(
struct
wl1271
*
wl
,
void
*
buf
,
size_t
buf_len
,
u8
answer
);
int
wl1271_cmd_interrogate
(
struct
wl1271
*
wl
,
u16
id
,
void
*
buf
,
size_t
len
);
int
wl1271_cmd_configure
(
struct
wl1271
*
wl
,
u16
id
,
void
*
buf
,
size_t
len
);
...
...
@@ -56,20 +64,18 @@ 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_sta_default_wep_key
(
struct
wl1271
*
wl
,
u8
id
);
int
wl1271_cmd_set_ap_default_wep_key
(
struct
wl1271
*
wl
,
u8
id
);
int
wl12xx_cmd_set_default_wep_key
(
struct
wl1271
*
wl
,
u8
id
,
u8
hlid
);
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
);
int
wl12xx_cmd_set_peer_state
(
struct
wl1271
*
wl
,
u8
hlid
);
int
wl12xx_roc
(
struct
wl1271
*
wl
,
u8
role_id
);
int
wl12xx_croc
(
struct
wl1271
*
wl
,
u8
role_id
);
int
wl12xx_cmd_add_peer
(
struct
wl1271
*
wl
,
struct
ieee80211_sta
*
sta
,
u8
hlid
);
int
wl12xx_cmd_remove_peer
(
struct
wl1271
*
wl
,
u8
hlid
);
int
wl12xx_cmd_config_fwlog
(
struct
wl1271
*
wl
);
int
wl12xx_cmd_start_fwlog
(
struct
wl1271
*
wl
);
int
wl12xx_cmd_stop_fwlog
(
struct
wl1271
*
wl
);
...
...
@@ -83,25 +89,21 @@ enum wl1271_commands {
CMD_DISABLE_TX
=
6
,
CMD_SCAN
=
8
,
CMD_STOP_SCAN
=
9
,
CMD_START_JOIN
=
11
,
CMD_SET_KEYS
=
12
,
CMD_READ_MEMORY
=
13
,
CMD_WRITE_MEMORY
=
14
,
CMD_SET_TEMPLATE
=
19
,
CMD_TEST
=
23
,
CMD_NOISE_HIST
=
28
,
CMD_
LNA_CONTROL
=
32
,
CMD_
QUIET_ELEMENT_SET_STATE
=
29
,
CMD_SET_BCN_MODE
=
33
,
CMD_MEASUREMENT
=
34
,
CMD_STOP_MEASUREMENT
=
35
,
CMD_DISCONNECT
=
36
,
CMD_SET_PS_MODE
=
37
,
CMD_CHANNEL_SWITCH
=
38
,
CMD_STOP_CHANNEL_SWICTH
=
39
,
CMD_AP_DISCOVERY
=
40
,
CMD_STOP_AP_DISCOVERY
=
41
,
CMD_SPS_SCAN
=
42
,
CMD_STOP_SPS_SCAN
=
43
,
CMD_HEALTH_CHECK
=
45
,
CMD_DEBUG
=
46
,
CMD_TRIGGER_SCAN_TO
=
47
,
...
...
@@ -109,16 +111,30 @@ enum wl1271_commands {
CMD_CONNECTION_SCAN_SSID_CFG
=
49
,
CMD_START_PERIODIC_SCAN
=
50
,
CMD_STOP_PERIODIC_SCAN
=
51
,
CMD_SET_STA_STATE
=
52
,
CMD_CONFIG_FWLOGGER
=
53
,
CMD_START_FWLOGGER
=
54
,
CMD_STOP_FWLOGGER
=
55
,
CMD_SET_PEER_STATE
=
52
,
CMD_REMAIN_ON_CHANNEL
=
53
,
CMD_CANCEL_REMAIN_ON_CHANNEL
=
54
,
/* AP mode commands */
CMD_BSS_START
=
60
,
CMD_BSS_STOP
=
61
,
CMD_ADD_STA
=
62
,
CMD_REMOVE_STA
=
63
,
CMD_CONFIG_FWLOGGER
=
55
,
CMD_START_FWLOGGER
=
56
,
CMD_STOP_FWLOGGER
=
57
,
/* AP commands */
CMD_ADD_PEER
=
62
,
CMD_REMOVE_PEER
=
63
,
/* Role API */
CMD_ROLE_ENABLE
=
70
,
CMD_ROLE_DISABLE
=
71
,
CMD_ROLE_START
=
72
,
CMD_ROLE_STOP
=
73
,
/* WIFI Direct */
CMD_WFD_START_DISCOVERY
=
80
,
CMD_WFD_STOP_DISCOVERY
=
81
,
CMD_WFD_ATTRIBUTE_CONFIG
=
82
,
CMD_NOP
=
100
,
NUM_COMMANDS
,
MAX_COMMAND_ID
=
0xFFFF
,
...
...
@@ -147,21 +163,20 @@ enum cmd_templ {
CMD_TEMPL_CTS
,
/*
* For CTS-to-self (FastCTS) mechanism
* for BT/WLAN coexistence (SoftGemini). */
CMD_TEMPL_ARP_RSP
,
CMD_TEMPL_LINK_MEASUREMENT_REPORT
,
/* AP-mode specific */
CMD_TEMPL_AP_BEACON
=
13
,
CMD_TEMPL_AP_BEACON
,
CMD_TEMPL_AP_PROBE_RESPONSE
,
CMD_TEMPL_A
P_A
RP_RSP
,
CMD_TEMPL_ARP_RSP
,
CMD_TEMPL_DEAUTH_AP
,
CMD_TEMPL_TEMPORARY
,
CMD_TEMPL_LINK_MEASUREMENT_REPORT
,
CMD_TEMPL_MAX
=
0xff
};
/* unit ms */
#define WL1271_COMMAND_TIMEOUT 2000
#define WL1271_CMD_TEMPL_MAX_SIZE 252
#define WL1271_CMD_TEMPL_DFLT_SIZE 252
#define WL1271_CMD_TEMPL_MAX_SIZE 548
#define WL1271_EVENT_TIMEOUT 750
struct
wl1271_cmd_header
{
...
...
@@ -193,6 +208,8 @@ enum {
CMD_STATUS_WRONG_NESTING
=
19
,
CMD_STATUS_TIMEOUT
=
21
,
/* Driver internal use.*/
CMD_STATUS_FW_RESET
=
22
,
/* Driver internal use.*/
CMD_STATUS_TEMPLATE_OOM
=
23
,
CMD_STATUS_NO_RX_BA_SESSION
=
24
,
MAX_COMMAND_STATUS
=
0xff
};
...
...
@@ -210,38 +227,114 @@ enum {
#define WL1271_JOIN_CMD_TX_SESSION_OFFSET 1
#define WL1271_JOIN_CMD_BSS_TYPE_5GHZ 0x10
struct
wl12
71_cmd_join
{
struct
wl12
xx_cmd_role_enable
{
struct
wl1271_cmd_header
header
;
__le32
bssid_lsb
;
__le16
bssid_msb
;
__le16
beacon_interval
;
/* in TBTTs */
__le32
rx_config_options
;
__le32
rx_filter_options
;
u8
role_id
;
u8
role_type
;
u8
mac_address
[
ETH_ALEN
];
}
__packed
;
/*
* The target uses this field to determine the rate at
* which to transmit control frame responses (such as
* ACK or CTS frames).
*/
__le32
basic_rate_set
;
__le32
supported_rate_set
;
u8
dtim_interval
;
/*
* bits 0-2: This bitwise field specifies the type
* of BSS to start or join (BSS_TYPE_*).
* bit 4: Band - The radio band in which to join
* or start.
* 0 - 2.4GHz band
* 1 - 5GHz band
* bits 3, 5-7: Reserved
*/
u8
bss_type
;
struct
wl12xx_cmd_role_disable
{
struct
wl1271_cmd_header
header
;
u8
role_id
;
u8
padding
[
3
];
}
__packed
;
enum
wl12xx_band
{
WL12XX_BAND_2_4GHZ
=
0
,
WL12XX_BAND_5GHZ
=
1
,
WL12XX_BAND_JAPAN_4_9_GHZ
=
2
,
WL12XX_BAND_DEFAULT
=
WL12XX_BAND_2_4GHZ
,
WL12XX_BAND_INVALID
=
0x7E
,
WL12XX_BAND_MAX_RADIO
=
0x7F
,
};
struct
wl12xx_cmd_role_start
{
struct
wl1271_cmd_header
header
;
u8
role_id
;
u8
band
;
u8
channel
;
u8
ssid_len
;
u8
ssid
[
IEEE80211_MAX_SSID_LEN
];
u8
ctrl
;
/* JOIN_CMD_CTRL_* */
u8
reserved
[
3
];
u8
padding
;
union
{
struct
{
u8
hlid
;
u8
session
;
u8
padding_1
[
54
];
}
__packed
device
;
/* sta & p2p_cli use the same struct */
struct
{
u8
bssid
[
ETH_ALEN
];
u8
hlid
;
/* data hlid */
u8
session
;
__le32
remote_rates
;
/* remote supported rates */
/*
* The target uses this field to determine the rate at
* which to transmit control frame responses (such as
* ACK or CTS frames).
*/
__le32
basic_rate_set
;
__le32
local_rates
;
/* local supported rates */
u8
ssid_type
;
u8
ssid_len
;
u8
ssid
[
IEEE80211_MAX_SSID_LEN
];
__le16
beacon_interval
;
/* in TBTTs */
}
__packed
sta
;
struct
{
u8
bssid
[
ETH_ALEN
];
u8
hlid
;
/* data hlid */
u8
dtim_interval
;
__le32
remote_rates
;
/* remote supported rates */
__le32
basic_rate_set
;
__le32
local_rates
;
/* local supported rates */
u8
ssid_type
;
u8
ssid_len
;
u8
ssid
[
IEEE80211_MAX_SSID_LEN
];
__le16
beacon_interval
;
/* in TBTTs */
u8
padding_1
[
4
];
}
__packed
ibss
;
/* ap & p2p_go use the same struct */
struct
{
__le16
aging_period
;
/* in secs */
u8
beacon_expiry
;
/* in ms */
u8
bss_index
;
/* 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
;
__le16
beacon_interval
;
/* in TBTTs */
__le32
basic_rate_set
;
__le32
local_rates
;
/* local supported rates */
u8
dtim_interval
;
u8
ssid_type
;
u8
ssid_len
;
u8
ssid
[
IEEE80211_MAX_SSID_LEN
];
u8
padding_1
[
5
];
}
__packed
ap
;
};
}
__packed
;
struct
wl12xx_cmd_role_stop
{
struct
wl1271_cmd_header
header
;
u8
role_id
;
u8
disc_type
;
/* only STA and P2P_CLI */
__le16
reason
;
/* only STA and P2P_CLI */
}
__packed
;
struct
cmd_enabledisable_path
{
...
...
@@ -287,8 +380,9 @@ enum wl1271_cmd_ps_mode {
struct
wl1271_cmd_ps_params
{
struct
wl1271_cmd_header
header
;
u8
role_id
;
u8
ps_mode
;
/* STATION_* */
u8
padding
[
3
];
u8
padding
[
2
];
}
__packed
;
/* HW encryption keys */
...
...
@@ -301,6 +395,12 @@ enum wl1271_cmd_key_action {
MAX_KEY_ACTION
=
0xffff
,
};
enum
wl1271_cmd_lid_key_type
{
UNICAST_LID_TYPE
=
0
,
BROADCAST_LID_TYPE
=
1
,
WEP_DEFAULT_LID_TYPE
=
2
};
enum
wl1271_cmd_key_type
{
KEY_NONE
=
0
,
KEY_WEP
=
1
,
...
...
@@ -309,44 +409,7 @@ enum wl1271_cmd_key_type {
KEY_GEM
=
4
,
};
/* FIXME: Add description for key-types */
struct
wl1271_cmd_set_sta_keys
{
struct
wl1271_cmd_header
header
;
/* Ignored for default WEP key */
u8
addr
[
ETH_ALEN
];
/* key_action_e */
__le16
key_action
;
__le16
reserved_1
;
/* key size in bytes */
u8
key_size
;
/* key_type_e */
u8
key_type
;
u8
ssid_profile
;
/*
* TKIP, AES: frame's key id field.
* For WEP default key: key id;
*/
u8
id
;
u8
reserved_2
[
6
];
u8
key
[
MAX_KEY_SIZE
];
__le16
ac_seq_num16
[
NUM_ACCESS_CATEGORIES_COPY
];
__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_set_keys
{
struct
wl1271_cmd_header
header
;
/*
...
...
@@ -496,69 +559,39 @@ enum wl1271_disconnect_type {
DISCONNECT_DISASSOC
};
struct
wl1271_cmd_disconnect
{
struct
wl1271_cmd_header
header
;
__le32
rx_config_options
;
__le32
rx_filter_options
;
__le16
reason
;
u8
type
;
u8
padding
;
}
__packed
;
#define WL1271_CMD_STA_STATE_CONNECTED 1
struct
wl12
71_cmd_set_sta
_state
{
struct
wl12
xx_cmd_set_peer
_state
{
struct
wl1271_cmd_header
header
;
u8
hlid
;
u8
state
;
u8
padding
[
3
];
u8
padding
[
2
];
}
__packed
;
enum
wl1271_ssid_type
{
SSID_TYPE_PUBLIC
=
0
,
SSID_TYPE_HIDDEN
=
1
struct
wl12xx_cmd_roc
{
struct
wl1271_cmd_header
header
;
u8
role_id
;
u8
channel
;
u8
band
;
u8
padding
;
};
struct
wl12
71_cmd_bss_start
{
struct
wl12
xx_cmd_croc
{
struct
wl1271_cmd_header
header
;
/* wl1271_ssid_type */
u8
ssid_type
;
u8
ssid_len
;
u8
ssid
[
IEEE80211_MAX_SSID_LEN
];
u8
padding_1
[
2
];
/* Basic rate set */
__le32
basic_rate_set
;
/* Aging period in seconds*/
__le16
aging_period
;
u8
role_id
;
u8
padding
[
3
];
};
/*
* 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
;
enum
wl12xx_ssid_type
{
WL12XX_SSID_TYPE_PUBLIC
=
0
,
WL12XX_SSID_TYPE_HIDDEN
=
1
,
WL12XX_SSID_TYPE_ANY
=
2
,
};
struct
wl12
71_cmd_add_sta
{
struct
wl12
xx_cmd_add_peer
{
struct
wl1271_cmd_header
header
;
u8
addr
[
ETH_ALEN
];
...
...
@@ -572,7 +605,7 @@ struct wl1271_cmd_add_sta {
u8
padding1
;
}
__packed
;
struct
wl12
71_cmd_remove_sta
{
struct
wl12
xx_cmd_remove_peer
{
struct
wl1271_cmd_header
header
;
u8
hlid
;
...
...
drivers/net/wireless/wl12xx/conf.h
View file @
e0a8c583
...
...
@@ -99,40 +99,75 @@ enum {
enum
{
/*
* PER threshold in PPM of the BT voice
* Configure the min and max time BT gains the antenna
* in WLAN / BT master basic rate
*
* Range: 0 -
10000000
* Range: 0 -
255 (ms)
*/
CONF_SG_BT_PER_THRESHOLD
=
0
,
CONF_SG_ACL_BT_MASTER_MIN_BR
=
0
,
CONF_SG_ACL_BT_MASTER_MAX_BR
,
/*
*
Number of consequent RX_ACTIVE activities to override BT voice
*
frames to ensure WLAN connection
*
Configure the min and max time BT gains the antenna
*
in WLAN / BT slave basic rate
*
* Range: 0 -
100
* Range: 0 -
255 (ms)
*/
CONF_SG_HV3_MAX_OVERRIDE
,
CONF_SG_ACL_BT_SLAVE_MIN_BR
,
CONF_SG_ACL_BT_SLAVE_MAX_BR
,
/*
* Defines the PER threshold of the BT voice
* Configure the min and max time BT gains the antenna
* in WLAN / BT master EDR
*
* Range: 0 -
65000
* Range: 0 -
255 (ms)
*/
CONF_SG_BT_NFS_SAMPLE_INTERVAL
,
CONF_SG_ACL_BT_MASTER_MIN_EDR
,
CONF_SG_ACL_BT_MASTER_MAX_EDR
,
/*
* Defines the load ratio of BT
* Configure the min and max time BT gains the antenna
* in WLAN / BT slave EDR
*
* Range: 0 -
100 (%
)
* Range: 0 -
255 (ms
)
*/
CONF_SG_BT_LOAD_RATIO
,
CONF_SG_ACL_BT_SLAVE_MIN_EDR
,
CONF_SG_ACL_BT_SLAVE_MAX_EDR
,
/*
* Defines whether the SG will force WLAN host to enter/exit PSM
* The maximum time WLAN can gain the antenna
* in WLAN PSM / BT master/slave BR
*
* Range:
1 - SG can force, 0 - host handles PSM
* Range:
0 - 255 (ms)
*/
CONF_SG_AUTO_PS_MODE
,
CONF_SG_ACL_WLAN_PS_MASTER_BR
,
CONF_SG_ACL_WLAN_PS_SLAVE_BR
,
/*
* The maximum time WLAN can gain the antenna
* in WLAN PSM / BT master/slave EDR
*
* Range: 0 - 255 (ms)
*/
CONF_SG_ACL_WLAN_PS_MASTER_EDR
,
CONF_SG_ACL_WLAN_PS_SLAVE_EDR
,
/* TODO: explain these values */
CONF_SG_ACL_WLAN_ACTIVE_MASTER_MIN_BR
,
CONF_SG_ACL_WLAN_ACTIVE_MASTER_MAX_BR
,
CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MIN_BR
,
CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MAX_BR
,
CONF_SG_ACL_WLAN_ACTIVE_MASTER_MIN_EDR
,
CONF_SG_ACL_WLAN_ACTIVE_MASTER_MAX_EDR
,
CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MIN_EDR
,
CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MAX_EDR
,
CONF_SG_ACL_ACTIVE_SCAN_WLAN_BR
,
CONF_SG_ACL_ACTIVE_SCAN_WLAN_EDR
,
CONF_SG_ACL_PASSIVE_SCAN_BT_BR
,
CONF_SG_ACL_PASSIVE_SCAN_WLAN_BR
,
CONF_SG_ACL_PASSIVE_SCAN_BT_EDR
,
CONF_SG_ACL_PASSIVE_SCAN_WLAN_EDR
,
/*
* Compensation percentage of probe requests when scan initiated
...
...
@@ -151,102 +186,70 @@ enum {
CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3
,
/*
* Defines antenna configuration (single/dual antenna)
*
* Range: 0 - single antenna, 1 - dual antenna
*/
CONF_SG_ANTENNA_CONFIGURATION
,
/*
* The threshold (percent) of max consequtive beacon misses before
* increasing priority of beacon reception.
*
* Range: 0 - 100 (%)
*/
CONF_SG_BEACON_MISS_PERCENT
,
/*
* The rate threshold below which receiving a data frame from the AP
* will increase the priority of the data frame above BT traffic.
*
* Range: 0,2, 5(=5.5), 6, 9, 11, 12, 18, 24, 36, 48, 54
*/
CONF_SG_RATE_ADAPT_THRESH
,
/*
* Not used currently.
* Compensation percentage of WLAN active scan window if initiated
* during BT A2DP
*
* Range: 0
* Range: 0
- 1000 (%)
*/
CONF_SG_
RATE_ADAPT_SNR
,
CONF_SG_
ACTIVE_SCAN_DURATION_FACTOR_A2DP
,
/*
* Co
nfigure the min and max time BT gains the antenna
*
in WLAN PSM / BT master basic rate
* Co
mpensation percentage of WLAN passive scan window if initiated
*
during BT A2DP BR
*
* Range: 0 -
255 (ms
)
* Range: 0 -
1000 (%
)
*/
CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_BR
,
CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_BR
,
CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP_BR
,
/*
*
The time after it expires no new WLAN trigger frame is trasmit
ted
*
in WLAN PSM / BT master basic rate
*
Compensation percentage of WLAN passive scan window if initia
ted
*
during BT A2DP EDR
*
* Range: 0 -
255 (ms
)
* Range: 0 -
1000 (%
)
*/
CONF_SG_
WLAN_PS_MAX_BT_ACL_MASTER_B
R
,
CONF_SG_
PASSIVE_SCAN_DURATION_FACTOR_A2DP_ED
R
,
/*
* Co
nfigure the min and max time BT gains the antenna
*
in WLAN PSM / BT slave basic rat
e
* Co
mpensation percentage of WLAN passive scan window if initiated
*
during BT voic
e
*
* Range: 0 -
255 (ms
)
* Range: 0 -
1000 (%
)
*/
CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_BR
,
CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_BR
,
CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3
,
/*
* The time after it expires no new WLAN trigger frame is trasmitted
* in WLAN PSM / BT slave basic rate
*
* Range: 0 - 255 (ms)
*/
CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_BR
,
/* TODO: explain these values */
CONF_SG_CONSECUTIVE_HV3_IN_PASSIVE_SCAN
,
CONF_SG_BCN_HV3_COLLISION_THRESH_IN_PASSIVE_SCAN
,
CONF_SG_TX_RX_PROTECTION_BWIDTH_IN_PASSIVE_SCAN
,
/*
* Configure the min and max time BT gains the antenna
* in WLAN PSM / BT master EDR
* Defines whether the SG will force WLAN host to enter/exit PSM
*
* Range:
0 - 255 (ms)
* Range:
1 - SG can force, 0 - host handles PSM
*/
CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_EDR
,
CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_EDR
,
CONF_SG_STA_FORCE_PS_IN_BT_SCO
,
/*
* The time after it expires no new WLAN trigger frame is trasmitted
* in WLAN PSM / BT master EDR
* Defines antenna configuration (single/dual antenna)
*
* Range: 0 -
255 (ms)
* Range: 0 -
single antenna, 1 - dual antenna
*/
CONF_SG_
WLAN_PS_MAX_BT_ACL_MASTER_EDR
,
CONF_SG_
ANTENNA_CONFIGURATION
,
/*
*
Configure the min and max time BT gains the antenna
* in
WLAN PSM / BT slave EDR
*
The threshold (percent) of max consecutive beacon misses before
* in
creasing priority of beacon reception.
*
* Range: 0 -
255 (ms
)
* Range: 0 -
100 (%
)
*/
CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_EDR
,
CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_EDR
,
CONF_SG_BEACON_MISS_PERCENT
,
/*
* The time after it expires no new WLAN trigger frame is trasmitted
* in WLAN PSM / BT slave EDR
* Protection time of the DHCP procedure.
*
* Range: 0 -
255
(ms)
* Range: 0 -
100000
(ms)
*/
CONF_SG_
WLAN_PS_MAX_BT_ACL_SLAVE_EDR
,
CONF_SG_
DHCP_TIME
,
/*
* RX guard time before the beginning of a new BT voice frame during
...
...
@@ -273,166 +276,59 @@ enum {
*/
CONF_SG_ADAPTIVE_RXT_TXT
,
/*
* The used WLAN legacy service period during active BT ACL link
*
* Range: 0 - 255 (ms)
*/
CONF_SG_PS_POLL_TIMEOUT
,
/*
* The used WLAN UPSD service period during active BT ACL link
*
* Range: 0 - 255 (ms)
*/
CONF_SG_UPSD_TIMEOUT
,
/*
* Configure the min and max time BT gains the antenna
* in WLAN Active / BT master EDR
*
* Range: 0 - 255 (ms)
*/
CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MIN_EDR
,
CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MAX_EDR
,
/*
* The maximum time WLAN can gain the antenna for
* in WLAN Active / BT master EDR
*
* Range: 0 - 255 (ms)
*/
CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_MASTER_EDR
,
/*
* Configure the min and max time BT gains the antenna
* in WLAN Active / BT slave EDR
*
* Range: 0 - 255 (ms)
*/
CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MIN_EDR
,
CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MAX_EDR
,
/* TODO: explain this value */
CONF_SG_GENERAL_USAGE_BIT_MAP
,
/*
* The maximum time WLAN can gain the antenna for
* in WLAN Active / BT slave EDR
* Number of consecutive BT voice frames not interrupted by WLAN
*
* Range: 0 -
255 (ms)
* Range: 0 -
100
*/
CONF_SG_
WLAN_ACTIVE_MAX_BT_ACL_SLAVE_EDR
,
CONF_SG_
HV3_MAX_SERVED
,
/*
* Configure the min and max time BT gains the antenna
* in WLAN Active / BT basic rate
* The used WLAN legacy service period during active BT ACL link
*
* Range: 0 - 255 (ms)
*/
CONF_SG_WLAN_ACTIVE_BT_ACL_MIN_BR
,
CONF_SG_WLAN_ACTIVE_BT_ACL_MAX_BR
,
CONF_SG_PS_POLL_TIMEOUT
,
/*
* The maximum time WLAN can gain the antenna for
* in WLAN Active / BT basic rate
* The used WLAN UPSD service period during active BT ACL link
*
* Range: 0 - 255 (ms)
*/
CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_BR
,
/*
* Compensation percentage of WLAN passive scan window if initiated
* during BT voice
*
* Range: 0 - 1000 (%)
*/
CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3
,
/*
* Compensation percentage of WLAN passive scan window if initiated
* during BT A2DP
*
* Range: 0 - 1000 (%)
*/
CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP
,
/*
* Fixed time ensured for BT traffic to gain the antenna during WLAN
* passive scan.
*
* Range: 0 - 1000 ms
*/
CONF_SG_PASSIVE_SCAN_A2DP_BT_TIME
,
/*
* Fixed time ensured for WLAN traffic to gain the antenna during WLAN
* passive scan.
*
* Range: 0 - 1000 ms
*/
CONF_SG_PASSIVE_SCAN_A2DP_WLAN_TIME
,
CONF_SG_UPSD_TIMEOUT
,
/*
* Number of consequent BT voice frames not interrupted by WLAN
*
* Range: 0 - 100
*/
CONF_SG_HV3_MAX_SERVED
,
CONF_SG_CONSECUTIVE_CTS_THRESHOLD
,
CONF_SG_STA_RX_WINDOW_AFTER_DTIM
,
CONF_SG_STA_CONNECTION_PROTECTION_TIME
,
/*
* Protection time of the DHCP procedure.
*
* Range: 0 - 100000 (ms)
*/
CONF_SG_DHCP_TIME
,
/* AP params */
CONF_AP_BEACON_MISS_TX
,
CONF_AP_RX_WINDOW_AFTER_BEACON
,
CONF_AP_BEACON_WINDOW_INTERVAL
,
CONF_AP_CONNECTION_PROTECTION_TIME
,
CONF_AP_BT_ACL_VAL_BT_SERVE_TIME
,
CONF_AP_BT_ACL_VAL_WL_SERVE_TIME
,
/*
* Compensation percentage of WLAN active scan window if initiated
* during BT A2DP
*
* Range: 0 - 1000 (%)
*/
CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP
,
CONF_SG_TEMP_PARAM_1
,
CONF_SG_TEMP_PARAM_2
,
CONF_SG_TEMP_PARAM_3
,
CONF_SG_TEMP_PARAM_4
,
CONF_SG_TEMP_PARAM_5
,
/*
* AP beacon miss
*
* Range: 0 - 255
*/
CONF_SG_AP_BEACON_MISS_TX
,
/*
* AP RX window length
*
* Range: 0 - 50
*/
CONF_SG_RX_WINDOW_LENGTH
,
/*
* AP connection protection time
*
* Range: 0 - 5000
*/
CONF_SG_AP_CONNECTION_PROTECTION_TIME
,
CONF_SG_TEMP_PARAM_6
,
CONF_SG_TEMP_PARAM_7
,
CONF_SG_TEMP_PARAM_8
,
CONF_SG_TEMP_PARAM_9
,
CONF_SG_TEMP_PARAM_10
,
CONF_SG_STA_PARAMS_MAX
=
CONF_SG_TEMP_PARAM_5
+
1
,
CONF_SG_AP_PARAMS_MAX
=
CONF_SG_TEMP_PARAM_10
+
1
,
CONF_SG_PARAMS_MAX
,
CONF_SG_PARAMS_ALL
=
0xff
};
struct
conf_sg_settings
{
u32
sta_params
[
CONF_SG_STA_PARAMS_MAX
];
u32
ap_params
[
CONF_SG_AP_PARAMS_MAX
];
u32
params
[
CONF_SG_PARAMS_MAX
];
u8
state
;
};
...
...
@@ -545,6 +441,11 @@ struct conf_rx_settings {
CONF_HW_BIT_RATE_36MBPS | CONF_HW_BIT_RATE_48MBPS | \
CONF_HW_BIT_RATE_54MBPS)
#define CONF_TX_MCS_RATES (CONF_HW_BIT_RATE_MCS_0 | \
CONF_HW_BIT_RATE_MCS_1 | CONF_HW_BIT_RATE_MCS_2 | \
CONF_HW_BIT_RATE_MCS_3 | CONF_HW_BIT_RATE_MCS_4 | \
CONF_HW_BIT_RATE_MCS_5 | CONF_HW_BIT_RATE_MCS_6 | \
CONF_HW_BIT_RATE_MCS_7)
/*
* Default rates for management traffic when operating in AP mode. This
...
...
@@ -661,6 +562,9 @@ struct conf_tx_ac_category {
#define CONF_TX_MAX_TID_COUNT 8
/* Allow TX BA on all TIDs but 6,7. These are currently reserved in the FW */
#define CONF_TX_BA_ENABLED_TID_BITMAP 0x3F
enum
{
CONF_CHANNEL_TYPE_DCF
=
0
,
/* DC/LEGACY*/
CONF_CHANNEL_TYPE_EDCF
=
1
,
/* EDCA*/
...
...
@@ -913,7 +817,7 @@ struct conf_conn_settings {
struct
conf_bcn_filt_rule
bcn_filt_ie
[
CONF_MAX_BCN_FILT_IE_COUNT
];
/*
* The number of conse
q
utive beacons to lose, before the firmware
* The number of conse
c
utive beacons to lose, before the firmware
* becomes out of synch.
*
* Range: u32
...
...
@@ -951,7 +855,7 @@ struct conf_conn_settings {
u8
rx_broadcast_in_ps
;
/*
* Conse
q
utive PS Poll failures before sending event to driver
* Conse
c
utive PS Poll failures before sending event to driver
*
* Range: u8
*/
...
...
@@ -1199,8 +1103,12 @@ struct conf_rf_settings {
};
struct
conf_ht_setting
{
u16
tx_ba_win_size
;
u8
rx_ba_win_size
;
u8
tx_ba_win_size
;
u16
inactivity_timeout
;
/* bitmap of enabled TIDs for TX BA sessions */
u8
tx_ba_tid_bitmap
;
};
struct
conf_memory_settings
{
...
...
@@ -1309,6 +1217,25 @@ struct conf_fwlog {
u8
threshold
;
};
#define ACX_RATE_MGMT_NUM_OF_RATES 13
struct
conf_rate_policy_settings
{
u16
rate_retry_score
;
u16
per_add
;
u16
per_th1
;
u16
per_th2
;
u16
max_per
;
u8
inverse_curiosity_factor
;
u8
tx_fail_low_th
;
u8
tx_fail_high_th
;
u8
per_alpha_shift
;
u8
per_add_shift
;
u8
per_beta1_shift
;
u8
per_beta2_shift
;
u8
rate_check_up
;
u8
rate_check_down
;
u8
rate_retry_policy
[
ACX_RATE_MGMT_NUM_OF_RATES
];
};
struct
conf_drv_settings
{
struct
conf_sg_settings
sg
;
struct
conf_rx_settings
rx
;
...
...
@@ -1326,6 +1253,7 @@ struct conf_drv_settings {
struct
conf_fm_coex
fm_coex
;
struct
conf_rx_streaming_settings
rx_streaming
;
struct
conf_fwlog
fwlog
;
struct
conf_rate_policy_settings
rate
;
u8
hci_io_ds
;
};
...
...
drivers/net/wireless/wl12xx/debugfs.c
View file @
e0a8c583
...
...
@@ -339,10 +339,11 @@ static ssize_t driver_state_read(struct file *file, char __user *user_buf,
#define DRIVER_STATE_PRINT_HEX(x) DRIVER_STATE_PRINT(x, "0x%x")
DRIVER_STATE_PRINT_INT
(
tx_blocks_available
);
DRIVER_STATE_PRINT_INT
(
tx_allocated_blocks
[
0
]);
DRIVER_STATE_PRINT_INT
(
tx_allocated_blocks
[
1
]);
DRIVER_STATE_PRINT_INT
(
tx_allocated_blocks
[
2
]);
DRIVER_STATE_PRINT_INT
(
tx_allocated_blocks
[
3
]);
DRIVER_STATE_PRINT_INT
(
tx_allocated_blocks
);
DRIVER_STATE_PRINT_INT
(
tx_allocated_pkts
[
0
]);
DRIVER_STATE_PRINT_INT
(
tx_allocated_pkts
[
1
]);
DRIVER_STATE_PRINT_INT
(
tx_allocated_pkts
[
2
]);
DRIVER_STATE_PRINT_INT
(
tx_allocated_pkts
[
3
]);
DRIVER_STATE_PRINT_INT
(
tx_frames_cnt
);
DRIVER_STATE_PRINT_LHEX
(
tx_frames_map
[
0
]);
DRIVER_STATE_PRINT_INT
(
tx_queue_count
[
0
]);
...
...
@@ -352,10 +353,7 @@ static ssize_t driver_state_read(struct file *file, char __user *user_buf,
DRIVER_STATE_PRINT_INT
(
tx_packets_count
);
DRIVER_STATE_PRINT_INT
(
tx_results_count
);
DRIVER_STATE_PRINT_LHEX
(
flags
);
DRIVER_STATE_PRINT_INT
(
tx_blocks_freed
[
0
]);
DRIVER_STATE_PRINT_INT
(
tx_blocks_freed
[
1
]);
DRIVER_STATE_PRINT_INT
(
tx_blocks_freed
[
2
]);
DRIVER_STATE_PRINT_INT
(
tx_blocks_freed
[
3
]);
DRIVER_STATE_PRINT_INT
(
tx_blocks_freed
);
DRIVER_STATE_PRINT_INT
(
tx_security_last_seq_lsb
);
DRIVER_STATE_PRINT_INT
(
rx_counter
);
DRIVER_STATE_PRINT_INT
(
session_counter
);
...
...
@@ -369,9 +367,6 @@ static ssize_t driver_state_read(struct file *file, char __user *user_buf,
DRIVER_STATE_PRINT_INT
(
beacon_int
);
DRIVER_STATE_PRINT_INT
(
psm_entry_retry
);
DRIVER_STATE_PRINT_INT
(
ps_poll_failures
);
DRIVER_STATE_PRINT_HEX
(
filters
);
DRIVER_STATE_PRINT_HEX
(
rx_config
);
DRIVER_STATE_PRINT_HEX
(
rx_filter
);
DRIVER_STATE_PRINT_INT
(
power_level
);
DRIVER_STATE_PRINT_INT
(
rssi_thold
);
DRIVER_STATE_PRINT_INT
(
last_rssi_event
);
...
...
drivers/net/wireless/wl12xx/event.c
View file @
e0a8c583
...
...
@@ -285,13 +285,13 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
if
((
vector
&
BA_SESSION_RX_CONSTRAINT_EVENT_ID
)
&&
!
is_ap
)
{
wl1271_debug
(
DEBUG_EVENT
,
"BA_SESSION_RX_CONSTRAINT_EVENT_ID. "
"ba_allowed = 0x%x"
,
mbox
->
ba_allowed
);
"ba_allowed = 0x%x"
,
mbox
->
rx_
ba_allowed
);
if
(
wl
->
vif
)
wl1271_stop_ba_event
(
wl
,
mbox
->
ba_allowed
);
wl1271_stop_ba_event
(
wl
,
mbox
->
rx_
ba_allowed
);
}
if
((
vector
&
DUMMY_PACKET_EVENT_ID
)
&&
!
is_ap
)
{
if
((
vector
&
DUMMY_PACKET_EVENT_ID
))
{
wl1271_debug
(
DEBUG_EVENT
,
"DUMMY_PACKET_ID_EVENT_ID"
);
if
(
wl
->
vif
)
wl1271_tx_dummy_packet
(
wl
);
...
...
drivers/net/wireless/wl12xx/event.h
View file @
e0a8c583
...
...
@@ -49,32 +49,27 @@ enum {
MEASUREMENT_START_EVENT_ID
=
BIT
(
8
),
MEASUREMENT_COMPLETE_EVENT_ID
=
BIT
(
9
),
SCAN_COMPLETE_EVENT_ID
=
BIT
(
10
),
SCHEDULED_SCAN_COMPLETE_EVENT_ID
=
BIT
(
11
),
WFD_DISCOVERY_COMPLETE_EVENT_ID
=
BIT
(
11
),
AP_DISCOVERY_COMPLETE_EVENT_ID
=
BIT
(
12
),
PS_REPORT_EVENT_ID
=
BIT
(
13
),
PSPOLL_DELIVERY_FAILURE_EVENT_ID
=
BIT
(
14
),
DISCONNECT_EVENT_COMPLETE_ID
=
BIT
(
15
),
JOIN_EVENT_COMPLETE_ID
=
BIT
(
16
),
/* BIT(16) is reserved */
CHANNEL_SWITCH_COMPLETE_EVENT_ID
=
BIT
(
17
),
BSS_LOSE_EVENT_ID
=
BIT
(
18
),
REGAINED_BSS_EVENT_ID
=
BIT
(
19
),
MAX_TX_RETRY_EVENT_ID
=
BIT
(
20
),
/* STA: dummy paket for dynamic mem blocks */
DUMMY_PACKET_EVENT_ID
=
BIT
(
21
),
/* AP: STA remove complete */
STA_REMOVE_COMPLETE_EVENT_ID
=
BIT
(
21
),
DUMMY_PACKET_EVENT_ID
=
BIT
(
21
),
SOFT_GEMINI_SENSE_EVENT_ID
=
BIT
(
22
),
/* STA: SG prediction */
SOFT_GEMINI_PREDICTION_EVENT_ID
=
BIT
(
23
),
/* AP: Inactive STA */
INACTIVE_STA_EVENT_ID
=
BIT
(
23
),
CHANGE_AUTO_MODE_TIMEOUT_EVENT_ID
=
BIT
(
23
),
SOFT_GEMINI_AVALANCHE_EVENT_ID
=
BIT
(
24
),
PLT_RX_CALIBRATION_COMPLETE_EVENT_ID
=
BIT
(
25
),
DBG_EVENT_ID
=
BIT
(
26
),
HEALTH_CHECK_REPLY
_EVENT_ID
=
BIT
(
27
),
INACTIVE_STA_EVENT_ID
=
BIT
(
26
),
PEER_REMOVE_COMPLETE
_EVENT_ID
=
BIT
(
27
),
PERIODIC_SCAN_COMPLETE_EVENT_ID
=
BIT
(
28
),
PERIODIC_SCAN_REPORT_EVENT_ID
=
BIT
(
29
),
BA_SESSION_RX_CONSTRAINT_EVENT_ID
=
BIT
(
30
),
REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID
=
BIT
(
31
),
EVENT_MBOX_ALL_EVENT_ID
=
0x7fffffff
,
};
...
...
@@ -83,15 +78,6 @@ enum {
EVENT_ENTER_POWER_SAVE_SUCCESS
,
};
struct
event_debug_report
{
u8
debug_event_id
;
u8
num_params
;
__le16
pad
;
__le32
report_1
;
__le32
report_2
;
__le32
report_3
;
}
__packed
;
#define NUM_OF_RSSI_SNR_TRIGGERS 8
struct
event_mailbox
{
...
...
@@ -100,49 +86,45 @@ struct event_mailbox {
__le32
reserved_1
;
__le32
reserved_2
;
u8
dbg_event_id
;
u8
num_relevant_params
;
__le16
reserved_3
;
__le32
event_report_p1
;
__le32
event_report_p2
;
__le32
event_report_p3
;
u8
number_of_scan_results
;
u8
scan_tag
;
u8
reserved_4
[
2
]
;
__le32
compl_scheduled_scan_status
;
u8
completed_scan_status
;
u8
reserved_3
;
__le16
scheduled_scan_attended_channels
;
u8
soft_gemini_sense_info
;
u8
soft_gemini_protective_info
;
s8
rssi_snr_trigger_metric
[
NUM_OF_RSSI_SNR_TRIGGERS
];
u8
channel_switch_status
;
u8
scheduled_scan_status
;
u8
ps_status
;
/* tuned channel (roc) */
u8
roc_channel
;
/* AP FW only */
u8
hlid_removed
;
__le16
hlid_removed_bitmap
;
/*
a bitmap of hlids for stations that have been inactive too long
*/
/*
bitmap of aged stations (by HLID)
*/
__le16
sta_aging_status
;
/*
a bitmap of hlids for stations which didn't respond to TX
*/
/*
bitmap of stations (by HLID) which exceeded max tx retries
*/
__le16
sta_tx_retry_exceeded
;
/*
* Bitmap, Each bit set represents the Role ID for which this constraint
* is set. Range: 0 - FF, FF means ANY role
*/
u8
ba_role_id
;
/*
* Bitmap, Each bit set represents the Link ID for which this constraint
* is set. Not applicable if ba_role_id is set to ANY role (FF).
* Range: 0 - FFFF, FFFF means ANY link in that role
*/
u8
ba_link_id
;
u8
ba_allowed
;
u8
reserved_5
[
21
];
/* discovery completed results */
u8
discovery_tag
;
u8
number_of_preq_results
;
u8
number_of_prsp_results
;
u8
reserved_5
;
/* rx ba constraint */
u8
role_id
;
/* 0xFF means any role. */
u8
rx_ba_allowed
;
u8
reserved_6
[
2
];
u8
ps_poll_delivery_failure_role_ids
;
u8
stopped_role_ids
;
u8
started_role_ids
;
u8
change_auto_mode_timeout
;
u8
reserved_7
[
12
];
}
__packed
;
int
wl1271_event_unmask
(
struct
wl1271
*
wl
);
...
...
drivers/net/wireless/wl12xx/init.c
View file @
e0a8c583
...
...
@@ -39,13 +39,13 @@ int wl1271_sta_init_templates_config(struct wl1271 *wl)
/* send empty templates for fw memory reservation */
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_CFG_PROBE_REQ_2_4
,
NULL
,
WL1271_CMD_TEMPL_
MAX
_SIZE
,
WL1271_CMD_TEMPL_
DFLT
_SIZE
,
0
,
WL1271_RATE_AUTOMATIC
);
if
(
ret
<
0
)
return
ret
;
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_CFG_PROBE_REQ_5
,
NULL
,
WL1271_CMD_TEMPL_
MAX
_SIZE
,
0
,
NULL
,
WL1271_CMD_TEMPL_
DFLT
_SIZE
,
0
,
WL1271_RATE_AUTOMATIC
);
if
(
ret
<
0
)
return
ret
;
...
...
@@ -70,15 +70,13 @@ int wl1271_sta_init_templates_config(struct wl1271 *wl)
return
ret
;
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_PROBE_RESPONSE
,
NULL
,
sizeof
(
struct
wl12xx_probe_resp_template
),
WL1271_CMD_TEMPL_DFLT_SIZE
,
0
,
WL1271_RATE_AUTOMATIC
);
if
(
ret
<
0
)
return
ret
;
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_BEACON
,
NULL
,
sizeof
(
struct
wl12xx_beacon_template
),
WL1271_CMD_TEMPL_DFLT_SIZE
,
0
,
WL1271_RATE_AUTOMATIC
);
if
(
ret
<
0
)
return
ret
;
...
...
@@ -92,7 +90,7 @@ int wl1271_sta_init_templates_config(struct wl1271 *wl)
for
(
i
=
0
;
i
<
CMD_TEMPL_KLV_IDX_MAX
;
i
++
)
{
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_KLV
,
NULL
,
WL1271_CMD_TEMPL_
MAX
_SIZE
,
i
,
WL1271_CMD_TEMPL_
DFLT
_SIZE
,
i
,
WL1271_RATE_AUTOMATIC
);
if
(
ret
<
0
)
return
ret
;
...
...
@@ -191,15 +189,13 @@ static int wl1271_ap_init_templates_config(struct wl1271 *wl)
* reserve memory for later.
*/
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_AP_PROBE_RESPONSE
,
NULL
,
sizeof
(
struct
wl12xx_probe_resp_template
),
WL1271_CMD_TEMPL_MAX_SIZE
,
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
),
WL1271_CMD_TEMPL_MAX_SIZE
,
0
,
WL1271_RATE_AUTOMATIC
);
if
(
ret
<
0
)
return
ret
;
...
...
@@ -227,7 +223,7 @@ static int wl1271_ap_init_templates_config(struct wl1271 *wl)
return
0
;
}
static
int
wl12
71_init_rx_config
(
struct
wl1271
*
wl
,
u32
config
,
u32
filter
)
static
int
wl12
xx_init_rx_config
(
struct
wl1271
*
wl
)
{
int
ret
;
...
...
@@ -235,10 +231,6 @@ static int wl1271_init_rx_config(struct wl1271 *wl, u32 config, u32 filter)
if
(
ret
<
0
)
return
ret
;
ret
=
wl1271_acx_rx_config
(
wl
,
config
,
filter
);
if
(
ret
<
0
)
return
ret
;
return
0
;
}
...
...
@@ -285,10 +277,7 @@ int wl1271_init_pta(struct wl1271 *wl)
{
int
ret
;
if
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
)
ret
=
wl1271_acx_ap_sg_cfg
(
wl
);
else
ret
=
wl1271_acx_sta_sg_cfg
(
wl
);
ret
=
wl12xx_acx_sg_cfg
(
wl
);
if
(
ret
<
0
)
return
ret
;
...
...
@@ -392,7 +381,7 @@ static int wl1271_sta_hw_init(struct wl1271 *wl)
if
(
ret
<
0
)
return
ret
;
ret
=
wl12
71_acx_sta
_mem_cfg
(
wl
);
ret
=
wl12
xx_acx
_mem_cfg
(
wl
);
if
(
ret
<
0
)
return
ret
;
...
...
@@ -408,12 +397,6 @@ 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
,
...
...
@@ -451,7 +434,7 @@ static int wl1271_ap_hw_init(struct wl1271 *wl)
if
(
ret
<
0
)
return
ret
;
ret
=
wl12
71_acx_ap
_mem_cfg
(
wl
);
ret
=
wl12
xx_acx
_mem_cfg
(
wl
);
if
(
ret
<
0
)
return
ret
;
...
...
@@ -483,7 +466,7 @@ int wl1271_ap_init_templates(struct wl1271 *wl)
* when operating as AP we want to receive external beacons for
* configuring ERP protection.
*/
ret
=
wl1271_acx_
set_ap_beacon_filter
(
wl
,
false
);
ret
=
wl1271_acx_
beacon_filter_opt
(
wl
,
false
);
if
(
ret
<
0
)
return
ret
;
...
...
@@ -532,6 +515,9 @@ int wl1271_init_ap_rates(struct wl1271 *wl)
else
supported_rates
=
CONF_TX_AP_ENABLED_RATES
;
/* unconditionally enable HT rates */
supported_rates
|=
CONF_TX_MCS_RATES
;
/* configure unicast TX rate classes */
for
(
i
=
0
;
i
<
wl
->
conf
.
tx
.
ac_conf_count
;
i
++
)
{
rc
.
enabled_rates
=
supported_rates
;
...
...
@@ -546,41 +532,24 @@ int wl1271_init_ap_rates(struct wl1271 *wl)
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
;
int
ret
=
0
;
/* Reset the BA RX indicators */
wl
->
ba_rx_bitmap
=
0
;
wl
->
ba_allowed
=
true
;
wl
->
ba_rx_session_count
=
0
;
/* validate that FW support BA */
wl1271_check_ba_support
(
wl
);
/* BA is supported in STA/AP modes */
if
(
wl
->
bss_type
!=
BSS_TYPE_AP_BSS
&&
wl
->
bss_type
!=
BSS_TYPE_STA_BSS
)
{
wl
->
ba_support
=
false
;
return
0
;
}
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
;
}
wl
->
ba_support
=
true
;
return
ret
;
/* 802.11n initiator BA session setting */
return
wl12xx_acx_set_ba_initiator_policy
(
wl
);
}
int
wl1271_chip_specific_init
(
struct
wl1271
*
wl
)
...
...
@@ -650,11 +619,7 @@ int wl1271_hw_init(struct wl1271 *wl)
return
ret
;
/* RX config */
ret
=
wl1271_init_rx_config
(
wl
,
RX_CFG_PROMISCUOUS
|
RX_CFG_TSF
,
RX_FILTER_OPTION_DEF
);
/* RX_CONFIG_OPTION_ANY_DST_ANY_BSS,
RX_FILTER_OPTION_FILTER_ALL); */
ret
=
wl12xx_init_rx_config
(
wl
);
if
(
ret
<
0
)
goto
out_free_memmap
;
...
...
@@ -733,6 +698,10 @@ int wl1271_hw_init(struct wl1271 *wl)
if
(
ret
<
0
)
goto
out_free_memmap
;
ret
=
wl12xx_acx_set_rate_mgmt_params
(
wl
);
if
(
ret
<
0
)
goto
out_free_memmap
;
/* Configure initiator BA sessions policies */
ret
=
wl1271_set_ba_policies
(
wl
);
if
(
ret
<
0
)
...
...
drivers/net/wireless/wl12xx/io.h
View file @
e0a8c583
...
...
@@ -186,6 +186,5 @@ int wl1271_free_hw(struct wl1271 *wl);
irqreturn_t
wl1271_irq
(
int
irq
,
void
*
data
);
bool
wl1271_set_block_size
(
struct
wl1271
*
wl
);
int
wl1271_tx_dummy_packet
(
struct
wl1271
*
wl
);
void
wl1271_configure_filters
(
struct
wl1271
*
wl
,
unsigned
int
filters
);
#endif
drivers/net/wireless/wl12xx/main.c
View file @
e0a8c583
...
...
@@ -52,110 +52,67 @@
static
struct
conf_drv_settings
default_conf
=
{
.
sg
=
{
.
sta_params
=
{
[
CONF_SG_BT_PER_THRESHOLD
]
=
7500
,
[
CONF_SG_HV3_MAX_OVERRIDE
]
=
0
,
[
CONF_SG_BT_NFS_SAMPLE_INTERVAL
]
=
400
,
[
CONF_SG_BT_LOAD_RATIO
]
=
200
,
[
CONF_SG_AUTO_PS_MODE
]
=
1
,
[
CONF_SG_AUTO_SCAN_PROBE_REQ
]
=
170
,
[
CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3
]
=
50
,
[
CONF_SG_ANTENNA_CONFIGURATION
]
=
0
,
[
CONF_SG_BEACON_MISS_PERCENT
]
=
60
,
[
CONF_SG_RATE_ADAPT_THRESH
]
=
12
,
[
CONF_SG_RATE_ADAPT_SNR
]
=
0
,
[
CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_BR
]
=
10
,
[
CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_BR
]
=
30
,
[
CONF_SG_WLAN_PS_MAX_BT_ACL_MASTER_BR
]
=
8
,
[
CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_BR
]
=
20
,
[
CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_BR
]
=
50
,
/* Note: with UPSD, this should be 4 */
[
CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_BR
]
=
8
,
[
CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_EDR
]
=
7
,
[
CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_EDR
]
=
25
,
[
CONF_SG_WLAN_PS_MAX_BT_ACL_MASTER_EDR
]
=
20
,
/* Note: with UPDS, this should be 15 */
[
CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_EDR
]
=
8
,
/* Note: with UPDS, this should be 50 */
[
CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_EDR
]
=
40
,
/* Note: with UPDS, this should be 10 */
[
CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_EDR
]
=
20
,
[
CONF_SG_RXT
]
=
1200
,
[
CONF_SG_TXT
]
=
1000
,
[
CONF_SG_ADAPTIVE_RXT_TXT
]
=
1
,
[
CONF_SG_PS_POLL_TIMEOUT
]
=
10
,
[
CONF_SG_UPSD_TIMEOUT
]
=
10
,
[
CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MIN_EDR
]
=
7
,
[
CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MAX_EDR
]
=
15
,
[
CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_MASTER_EDR
]
=
15
,
[
CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MIN_EDR
]
=
8
,
[
CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MAX_EDR
]
=
20
,
[
CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_SLAVE_EDR
]
=
15
,
[
CONF_SG_WLAN_ACTIVE_BT_ACL_MIN_BR
]
=
20
,
[
CONF_SG_WLAN_ACTIVE_BT_ACL_MAX_BR
]
=
50
,
[
CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_BR
]
=
10
,
[
CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3
]
=
200
,
[
CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP
]
=
800
,
[
CONF_SG_PASSIVE_SCAN_A2DP_BT_TIME
]
=
75
,
[
CONF_SG_PASSIVE_SCAN_A2DP_WLAN_TIME
]
=
15
,
[
CONF_SG_HV3_MAX_SERVED
]
=
6
,
[
CONF_SG_DHCP_TIME
]
=
5000
,
[
CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP
]
=
100
,
},
.
ap_params
=
{
[
CONF_SG_BT_PER_THRESHOLD
]
=
7500
,
[
CONF_SG_HV3_MAX_OVERRIDE
]
=
0
,
[
CONF_SG_BT_NFS_SAMPLE_INTERVAL
]
=
400
,
[
CONF_SG_BT_LOAD_RATIO
]
=
50
,
[
CONF_SG_AUTO_PS_MODE
]
=
1
,
[
CONF_SG_AUTO_SCAN_PROBE_REQ
]
=
170
,
[
CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3
]
=
50
,
[
CONF_SG_ANTENNA_CONFIGURATION
]
=
0
,
[
CONF_SG_BEACON_MISS_PERCENT
]
=
60
,
[
CONF_SG_RATE_ADAPT_THRESH
]
=
64
,
[
CONF_SG_RATE_ADAPT_SNR
]
=
1
,
[
CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_BR
]
=
10
,
[
CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_BR
]
=
25
,
[
CONF_SG_WLAN_PS_MAX_BT_ACL_MASTER_BR
]
=
25
,
[
CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_BR
]
=
20
,
[
CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_BR
]
=
25
,
[
CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_BR
]
=
25
,
[
CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_EDR
]
=
7
,
[
CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_EDR
]
=
25
,
[
CONF_SG_WLAN_PS_MAX_BT_ACL_MASTER_EDR
]
=
25
,
[
CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_EDR
]
=
8
,
[
CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_EDR
]
=
25
,
[
CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_EDR
]
=
25
,
[
CONF_SG_RXT
]
=
1200
,
[
CONF_SG_TXT
]
=
1000
,
[
CONF_SG_ADAPTIVE_RXT_TXT
]
=
1
,
[
CONF_SG_PS_POLL_TIMEOUT
]
=
10
,
[
CONF_SG_UPSD_TIMEOUT
]
=
10
,
[
CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MIN_EDR
]
=
7
,
[
CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MAX_EDR
]
=
15
,
[
CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_MASTER_EDR
]
=
15
,
[
CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MIN_EDR
]
=
8
,
[
CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MAX_EDR
]
=
20
,
[
CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_SLAVE_EDR
]
=
15
,
[
CONF_SG_WLAN_ACTIVE_BT_ACL_MIN_BR
]
=
20
,
[
CONF_SG_WLAN_ACTIVE_BT_ACL_MAX_BR
]
=
50
,
[
CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_BR
]
=
10
,
[
CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3
]
=
200
,
[
CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP
]
=
800
,
[
CONF_SG_PASSIVE_SCAN_A2DP_BT_TIME
]
=
75
,
[
CONF_SG_PASSIVE_SCAN_A2DP_WLAN_TIME
]
=
15
,
[
CONF_SG_HV3_MAX_SERVED
]
=
6
,
[
CONF_SG_DHCP_TIME
]
=
5000
,
[
CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP
]
=
100
,
[
CONF_SG_TEMP_PARAM_1
]
=
0
,
[
CONF_SG_TEMP_PARAM_2
]
=
0
,
[
CONF_SG_TEMP_PARAM_3
]
=
0
,
[
CONF_SG_TEMP_PARAM_4
]
=
0
,
[
CONF_SG_TEMP_PARAM_5
]
=
0
,
[
CONF_SG_AP_BEACON_MISS_TX
]
=
3
,
[
CONF_SG_RX_WINDOW_LENGTH
]
=
6
,
[
CONF_SG_AP_CONNECTION_PROTECTION_TIME
]
=
50
,
[
CONF_SG_TEMP_PARAM_6
]
=
1
,
.
params
=
{
[
CONF_SG_ACL_BT_MASTER_MIN_BR
]
=
10
,
[
CONF_SG_ACL_BT_MASTER_MAX_BR
]
=
180
,
[
CONF_SG_ACL_BT_SLAVE_MIN_BR
]
=
10
,
[
CONF_SG_ACL_BT_SLAVE_MAX_BR
]
=
180
,
[
CONF_SG_ACL_BT_MASTER_MIN_EDR
]
=
10
,
[
CONF_SG_ACL_BT_MASTER_MAX_EDR
]
=
80
,
[
CONF_SG_ACL_BT_SLAVE_MIN_EDR
]
=
10
,
[
CONF_SG_ACL_BT_SLAVE_MAX_EDR
]
=
80
,
[
CONF_SG_ACL_WLAN_PS_MASTER_BR
]
=
8
,
[
CONF_SG_ACL_WLAN_PS_SLAVE_BR
]
=
8
,
[
CONF_SG_ACL_WLAN_PS_MASTER_EDR
]
=
20
,
[
CONF_SG_ACL_WLAN_PS_SLAVE_EDR
]
=
20
,
[
CONF_SG_ACL_WLAN_ACTIVE_MASTER_MIN_BR
]
=
20
,
[
CONF_SG_ACL_WLAN_ACTIVE_MASTER_MAX_BR
]
=
35
,
[
CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MIN_BR
]
=
16
,
[
CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MAX_BR
]
=
35
,
[
CONF_SG_ACL_WLAN_ACTIVE_MASTER_MIN_EDR
]
=
32
,
[
CONF_SG_ACL_WLAN_ACTIVE_MASTER_MAX_EDR
]
=
50
,
[
CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MIN_EDR
]
=
28
,
[
CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MAX_EDR
]
=
50
,
[
CONF_SG_ACL_ACTIVE_SCAN_WLAN_BR
]
=
10
,
[
CONF_SG_ACL_ACTIVE_SCAN_WLAN_EDR
]
=
20
,
[
CONF_SG_ACL_PASSIVE_SCAN_BT_BR
]
=
75
,
[
CONF_SG_ACL_PASSIVE_SCAN_WLAN_BR
]
=
15
,
[
CONF_SG_ACL_PASSIVE_SCAN_BT_EDR
]
=
27
,
[
CONF_SG_ACL_PASSIVE_SCAN_WLAN_EDR
]
=
17
,
/* active scan params */
[
CONF_SG_AUTO_SCAN_PROBE_REQ
]
=
170
,
[
CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3
]
=
50
,
[
CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP
]
=
100
,
/* passive scan params */
[
CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP_BR
]
=
800
,
[
CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP_EDR
]
=
200
,
[
CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3
]
=
200
,
/* passive scan in dual antenna params */
[
CONF_SG_CONSECUTIVE_HV3_IN_PASSIVE_SCAN
]
=
0
,
[
CONF_SG_BCN_HV3_COLLISION_THRESH_IN_PASSIVE_SCAN
]
=
0
,
[
CONF_SG_TX_RX_PROTECTION_BWIDTH_IN_PASSIVE_SCAN
]
=
0
,
/* general params */
[
CONF_SG_STA_FORCE_PS_IN_BT_SCO
]
=
1
,
[
CONF_SG_ANTENNA_CONFIGURATION
]
=
0
,
[
CONF_SG_BEACON_MISS_PERCENT
]
=
60
,
[
CONF_SG_DHCP_TIME
]
=
5000
,
[
CONF_SG_RXT
]
=
1200
,
[
CONF_SG_TXT
]
=
1000
,
[
CONF_SG_ADAPTIVE_RXT_TXT
]
=
1
,
[
CONF_SG_GENERAL_USAGE_BIT_MAP
]
=
3
,
[
CONF_SG_HV3_MAX_SERVED
]
=
6
,
[
CONF_SG_PS_POLL_TIMEOUT
]
=
10
,
[
CONF_SG_UPSD_TIMEOUT
]
=
10
,
[
CONF_SG_CONSECUTIVE_CTS_THRESHOLD
]
=
2
,
[
CONF_SG_STA_RX_WINDOW_AFTER_DTIM
]
=
5
,
[
CONF_SG_STA_CONNECTION_PROTECTION_TIME
]
=
30
,
/* AP params */
[
CONF_AP_BEACON_MISS_TX
]
=
3
,
[
CONF_AP_RX_WINDOW_AFTER_BEACON
]
=
10
,
[
CONF_AP_BEACON_WINDOW_INTERVAL
]
=
2
,
[
CONF_AP_CONNECTION_PROTECTION_TIME
]
=
0
,
[
CONF_AP_BT_ACL_VAL_BT_SERVE_TIME
]
=
25
,
[
CONF_AP_BT_ACL_VAL_WL_SERVE_TIME
]
=
25
,
},
.
state
=
CONF_SG_PROTECTIVE
,
},
...
...
@@ -329,8 +286,10 @@ static struct conf_drv_settings default_conf = {
},
},
.
ht
=
{
.
rx_ba_win_size
=
8
,
.
tx_ba_win_size
=
64
,
.
inactivity_timeout
=
10000
,
.
tx_ba_tid_bitmap
=
CONF_TX_BA_ENABLED_TID_BITMAP
,
},
.
mem_wl127x
=
{
.
num_stations
=
1
,
...
...
@@ -379,6 +338,27 @@ static struct conf_drv_settings default_conf = {
.
threshold
=
0
,
},
.
hci_io_ds
=
HCI_IO_DS_6MA
,
.
rate
=
{
.
rate_retry_score
=
32000
,
.
per_add
=
8192
,
.
per_th1
=
2048
,
.
per_th2
=
4096
,
.
max_per
=
8100
,
.
inverse_curiosity_factor
=
5
,
.
tx_fail_low_th
=
4
,
.
tx_fail_high_th
=
10
,
.
per_alpha_shift
=
4
,
.
per_add_shift
=
13
,
.
per_beta1_shift
=
10
,
.
per_beta2_shift
=
8
,
.
rate_check_up
=
2
,
.
rate_check_down
=
12
,
.
rate_retry_policy
=
{
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
},
},
};
static
char
*
fwlog_param
;
...
...
@@ -415,10 +395,12 @@ static int wl1271_check_operstate(struct wl1271 *wl, unsigned char operstate)
if
(
test_and_set_bit
(
WL1271_FLAG_STA_STATE_SENT
,
&
wl
->
flags
))
return
0
;
ret
=
wl12
71_cmd_set_sta_state
(
wl
);
ret
=
wl12
xx_cmd_set_peer_state
(
wl
,
wl
->
sta_hlid
);
if
(
ret
<
0
)
return
ret
;
wl12xx_croc
(
wl
,
wl
->
role_id
);
wl1271_info
(
"Association completed."
);
return
0
;
}
...
...
@@ -718,7 +700,7 @@ static int wl1271_plt_init(struct wl1271 *wl)
if
(
ret
<
0
)
goto
out_free_memmap
;
ret
=
wl12
71_acx_sta
_mem_cfg
(
wl
);
ret
=
wl12
xx_acx
_mem_cfg
(
wl
);
if
(
ret
<
0
)
goto
out_free_memmap
;
...
...
@@ -773,7 +755,7 @@ static int wl1271_plt_init(struct wl1271 *wl)
return
ret
;
}
static
void
wl12
71_irq_ps_regulate_link
(
struct
wl1271
*
wl
,
u8
hlid
,
u8
tx_blk
s
)
static
void
wl12
xx_irq_ps_regulate_link
(
struct
wl1271
*
wl
,
u8
hlid
,
u8
tx_pkt
s
)
{
bool
fw_ps
;
...
...
@@ -785,21 +767,35 @@ static void wl1271_irq_ps_regulate_link(struct wl1271 *wl, u8 hlid, u8 tx_blks)
/*
* Wake up from high level PS if the STA is asleep with too little
*
block
s in FW or if the STA is awake.
*
packet
s in FW or if the STA is awake.
*/
if
(
!
fw_ps
||
tx_
blks
<
WL1271_PS_STA_MAX_BLOCK
S
)
if
(
!
fw_ps
||
tx_
pkts
<
WL1271_PS_STA_MAX_PACKET
S
)
wl1271_ps_link_end
(
wl
,
hlid
);
/* Start high-level PS if the STA is asleep with enough blocks in FW */
else
if
(
fw_ps
&&
tx_
blks
>=
WL1271_PS_STA_MAX_BLOCK
S
)
else
if
(
fw_ps
&&
tx_
pkts
>=
WL1271_PS_STA_MAX_PACKET
S
)
wl1271_ps_link_start
(
wl
,
hlid
,
true
);
}
static
void
wl1271_irq_update_links_status
(
struct
wl1271
*
wl
,
struct
wl1271_fw_ap_status
*
status
)
bool
wl1271_is_active_sta
(
struct
wl1271
*
wl
,
u8
hlid
)
{
int
id
;
/* global/broadcast "stations" are always active */
if
(
hlid
<
WL1271_AP_STA_HLID_START
)
return
true
;
id
=
hlid
-
WL1271_AP_STA_HLID_START
;
return
test_bit
(
id
,
wl
->
ap_hlid_map
);
}
static
void
wl12xx_irq_update_links_status
(
struct
wl1271
*
wl
,
struct
wl12xx_fw_status
*
status
)
{
u32
cur_fw_ps_map
;
u8
hlid
;
u8
hlid
,
cnt
;
/* TODO: also use link_fast_bitmap here */
cur_fw_ps_map
=
le32_to_cpu
(
status
->
link_ps_bitmap
);
if
(
wl
->
ap_fw_ps_map
!=
cur_fw_ps_map
)
{
...
...
@@ -812,45 +808,30 @@ static void wl1271_irq_update_links_status(struct wl1271 *wl,
}
for
(
hlid
=
WL1271_AP_STA_HLID_START
;
hlid
<
AP_MAX_LINKS
;
hlid
++
)
{
u8
cnt
=
status
->
tx_lnk_free_blks
[
hlid
]
-
wl
->
links
[
hlid
].
prev_freed_blks
;
if
(
!
wl1271_is_active_sta
(
wl
,
hlid
))
continue
;
wl
->
links
[
hlid
].
prev_freed_blks
=
status
->
tx_lnk_free_blks
[
hlid
];
wl
->
links
[
hlid
].
allocated_blks
-=
cnt
;
cnt
=
status
->
tx_lnk_free_pkts
[
hlid
]
-
wl
->
links
[
hlid
].
prev_freed_pkts
;
wl1271_irq_ps_regulate_link
(
wl
,
hlid
,
wl
->
links
[
hlid
].
allocated_blks
);
}
}
wl
->
links
[
hlid
].
prev_freed_pkts
=
status
->
tx_lnk_free_pkts
[
hlid
];
wl
->
links
[
hlid
].
allocated_pkts
-=
cnt
;
static
u32
wl1271_tx_allocated_blocks
(
struct
wl1271
*
wl
)
{
int
i
;
u32
total_alloc_blocks
=
0
;
for
(
i
=
0
;
i
<
NUM_TX_QUEUES
;
i
++
)
total_alloc_blocks
+=
wl
->
tx_allocated_blocks
[
i
];
return
total_alloc_blocks
;
wl12xx_irq_ps_regulate_link
(
wl
,
hlid
,
wl
->
links
[
hlid
].
allocated_pkts
);
}
}
static
void
wl12
71
_fw_status
(
struct
wl1271
*
wl
,
struct
wl12
71_fw_full_status
*
full_
status
)
static
void
wl12
xx
_fw_status
(
struct
wl1271
*
wl
,
struct
wl12
xx_fw_status
*
status
)
{
struct
wl1271_fw_common_status
*
status
=
&
full_status
->
common
;
struct
timespec
ts
;
u32
old_tx_blk_count
=
wl
->
tx_blocks_available
;
u32
freed_blocks
=
0
,
ac_
freed_blocks
;
int
avail
,
freed_blocks
;
int
i
;
if
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
)
{
wl1271_raw_read
(
wl
,
FW_STATUS_ADDR
,
status
,
sizeof
(
struct
wl1271_fw_ap_status
),
false
);
}
else
{
wl1271_raw_read
(
wl
,
FW_STATUS_ADDR
,
status
,
sizeof
(
struct
wl1271_fw_sta_status
),
false
);
}
wl1271_raw_read
(
wl
,
FW_STATUS_ADDR
,
status
,
sizeof
(
*
status
),
false
);
wl1271_debug
(
DEBUG_IRQ
,
"intr: 0x%x (fw_rx_counter = %d, "
"drv_rx_counter = %d, tx_results_counter = %d)"
,
...
...
@@ -859,42 +840,49 @@ static void wl1271_fw_status(struct wl1271 *wl,
status
->
drv_rx_counter
,
status
->
tx_results_counter
);
/* update number of available TX blocks */
for
(
i
=
0
;
i
<
NUM_TX_QUEUES
;
i
++
)
{
ac_freed_blocks
=
le32_to_cpu
(
status
->
tx_released_blks
[
i
])
-
wl
->
tx_blocks_freed
[
i
];
freed_blocks
+=
ac_freed_blocks
;
wl
->
tx_allocated_blocks
[
i
]
-=
ac_freed_blocks
;
/* prevent wrap-around in freed-packets counter */
wl
->
tx_allocated_pkts
[
i
]
-=
(
status
->
tx_released_pkts
[
i
]
-
wl
->
tx_pkts_freed
[
i
])
&
0xff
;
wl
->
tx_blocks_freed
[
i
]
=
le32_to_cpu
(
status
->
tx_released_blks
[
i
]);
wl
->
tx_pkts_freed
[
i
]
=
status
->
tx_released_pkts
[
i
];
}
if
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
)
{
/* Update num of allocated TX blocks per link and ps status */
wl1271_irq_update_links_status
(
wl
,
&
full_status
->
ap
);
wl
->
tx_blocks_available
+=
freed_blocks
;
}
else
{
int
avail
=
full_status
->
sta
.
tx_total
-
wl1271_tx_allocated_blocks
(
wl
);
/* prevent wrap-around in total blocks counter */
if
(
likely
(
wl
->
tx_blocks_freed
<=
le32_to_cpu
(
status
->
total_released_blks
)))
freed_blocks
=
le32_to_cpu
(
status
->
total_released_blks
)
-
wl
->
tx_blocks_freed
;
else
freed_blocks
=
0x100000000LL
-
wl
->
tx_blocks_freed
+
le32_to_cpu
(
status
->
total_released_blks
);
/*
* The FW might change the total number of TX memblocks before
* we get a notification about blocks being released. Thus, the
* available blocks calculation might yield a temporary result
* which is lower than the actual available blocks. Keeping in
* mind that only blocks that were allocated can be moved from
* TX to RX, tx_blocks_available should never decrease here.
*/
wl
->
tx_blocks_available
=
max
((
int
)
wl
->
tx_blocks_available
,
avail
);
}
wl
->
tx_blocks_freed
=
le32_to_cpu
(
status
->
total_released_blks
);
wl
->
tx_allocated_blocks
-=
freed_blocks
;
avail
=
le32_to_cpu
(
status
->
tx_total
)
-
wl
->
tx_allocated_blocks
;
/*
* The FW might change the total number of TX memblocks before
* we get a notification about blocks being released. Thus, the
* available blocks calculation might yield a temporary result
* which is lower than the actual available blocks. Keeping in
* mind that only blocks that were allocated can be moved from
* TX to RX, tx_blocks_available should never decrease here.
*/
wl
->
tx_blocks_available
=
max
((
int
)
wl
->
tx_blocks_available
,
avail
);
/* if more blocks are available now, tx work can be scheduled */
if
(
wl
->
tx_blocks_available
>
old_tx_blk_count
)
clear_bit
(
WL1271_FLAG_FW_TX_BUSY
,
&
wl
->
flags
);
/* for AP update num of allocated TX blocks per link and ps status */
if
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
)
wl12xx_irq_update_links_status
(
wl
,
status
);
/* update the host-chipset time offset */
getnstimeofday
(
&
ts
);
wl
->
time_offset
=
(
timespec_to_ns
(
&
ts
)
>>
10
)
-
...
...
@@ -967,8 +955,8 @@ irqreturn_t wl1271_irq(int irq, void *cookie)
clear_bit
(
WL1271_FLAG_IRQ_RUNNING
,
&
wl
->
flags
);
smp_mb__after_clear_bit
();
wl12
71
_fw_status
(
wl
,
wl
->
fw_status
);
intr
=
le32_to_cpu
(
wl
->
fw_status
->
common
.
intr
);
wl12
xx
_fw_status
(
wl
,
wl
->
fw_status
);
intr
=
le32_to_cpu
(
wl
->
fw_status
->
intr
);
intr
&=
WL1271_INTR_MASK
;
if
(
!
intr
)
{
done
=
true
;
...
...
@@ -987,7 +975,7 @@ irqreturn_t wl1271_irq(int irq, void *cookie)
if
(
likely
(
intr
&
WL1271_ACX_INTR_DATA
))
{
wl1271_debug
(
DEBUG_IRQ
,
"WL1271_ACX_INTR_DATA"
);
wl12
71_rx
(
wl
,
&
wl
->
fw_status
->
common
);
wl12
xx_rx
(
wl
,
wl
->
fw_status
);
/* Check if any tx blocks were freed */
spin_lock_irqsave
(
&
wl
->
wl_lock
,
flags
);
...
...
@@ -1004,7 +992,7 @@ irqreturn_t wl1271_irq(int irq, void *cookie)
}
/* check for tx results */
if
(
wl
->
fw_status
->
common
.
tx_results_counter
!=
if
(
wl
->
fw_status
->
tx_results_counter
!=
(
wl
->
tx_results_count
&
0xff
))
wl1271_tx_complete
(
wl
);
...
...
@@ -1056,25 +1044,10 @@ static int wl1271_fetch_firmware(struct wl1271 *wl)
const
char
*
fw_name
;
int
ret
;
switch
(
wl
->
bss_type
)
{
case
BSS_TYPE_AP_BSS
:
if
(
wl
->
chip
.
id
==
CHIP_ID_1283_PG20
)
fw_name
=
WL128X_AP_FW_NAME
;
else
fw_name
=
WL127X_AP_FW_NAME
;
break
;
case
BSS_TYPE_IBSS
:
case
BSS_TYPE_STA_BSS
:
if
(
wl
->
chip
.
id
==
CHIP_ID_1283_PG20
)
fw_name
=
WL128X_FW_NAME
;
else
fw_name
=
WL1271_FW_NAME
;
break
;
default:
wl1271_error
(
"no compatible firmware for bss_type %d"
,
wl
->
bss_type
);
return
-
EINVAL
;
}
if
(
wl
->
chip
.
id
==
CHIP_ID_1283_PG20
)
fw_name
=
WL128X_FW_NAME
;
else
fw_name
=
WL127X_FW_NAME
;
wl1271_debug
(
DEBUG_BOOT
,
"booting firmware %s"
,
fw_name
);
...
...
@@ -1103,7 +1076,6 @@ static int wl1271_fetch_firmware(struct wl1271 *wl)
}
memcpy
(
wl
->
fw
,
fw
->
data
,
wl
->
fw_len
);
wl
->
fw_bss_type
=
wl
->
bss_type
;
ret
=
0
;
out:
...
...
@@ -1194,8 +1166,8 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl)
wl12xx_cmd_stop_fwlog
(
wl
);
/* Read the first memory block address */
wl12
71
_fw_status
(
wl
,
wl
->
fw_status
);
first_addr
=
__le32_to_cpu
(
wl
->
fw_status
->
sta
.
log_start_addr
);
wl12
xx
_fw_status
(
wl
,
wl
->
fw_status
);
first_addr
=
le32_to_cpu
(
wl
->
fw_status
->
log_start_addr
);
if
(
!
first_addr
)
goto
out
;
...
...
@@ -1211,7 +1183,7 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl)
* of each memory block hold the hardware address of the next
* one. The last memory block points to the first one.
*/
addr
=
__
le32_to_cpup
((
__le32
*
)
block
);
addr
=
le32_to_cpup
((
__le32
*
)
block
);
if
(
!
wl12xx_copy_fwlog
(
wl
,
block
+
sizeof
(
addr
),
WL12XX_HW_BLOCK_SIZE
-
sizeof
(
addr
)))
break
;
...
...
@@ -1374,8 +1346,7 @@ static int wl1271_chip_wakeup(struct wl1271 *wl)
goto
out
;
}
/* Make sure the firmware type matches the BSS type */
if
(
wl
->
fw
==
NULL
||
wl
->
fw_bss_type
!=
wl
->
bss_type
)
{
if
(
wl
->
fw
==
NULL
)
{
ret
=
wl1271_fetch_firmware
(
wl
);
if
(
ret
<
0
)
goto
out
;
...
...
@@ -1395,6 +1366,7 @@ static int wl1271_chip_wakeup(struct wl1271 *wl)
int
wl1271_plt_start
(
struct
wl1271
*
wl
)
{
int
retries
=
WL1271_BOOT_RETRIES
;
struct
wiphy
*
wiphy
=
wl
->
hw
->
wiphy
;
int
ret
;
mutex_lock
(
&
wl
->
mutex
);
...
...
@@ -1428,6 +1400,11 @@ int wl1271_plt_start(struct wl1271 *wl)
wl1271_notice
(
"firmware booted in PLT mode (%s)"
,
wl
->
chip
.
fw_ver_str
);
/* update hw/fw version info in wiphy struct */
wiphy
->
hw_version
=
wl
->
chip
.
id
;
strncpy
(
wiphy
->
fw_version
,
wl
->
chip
.
fw_ver_str
,
sizeof
(
wiphy
->
fw_version
));
goto
out
;
irq_disable:
...
...
@@ -1504,10 +1481,25 @@ static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
q
=
wl1271_tx_get_queue
(
mapping
);
if
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
)
hlid
=
wl12
71_tx_get_hlid
(
skb
);
hlid
=
wl12
xx_tx_get_hlid_ap
(
wl
,
skb
);
spin_lock_irqsave
(
&
wl
->
wl_lock
,
flags
);
/* queue the packet */
if
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
)
{
if
(
!
wl1271_is_active_sta
(
wl
,
hlid
))
{
wl1271_debug
(
DEBUG_TX
,
"DROP skb hlid %d q %d"
,
hlid
,
q
);
dev_kfree_skb
(
skb
);
goto
out
;
}
wl1271_debug
(
DEBUG_TX
,
"queue skb hlid %d q %d"
,
hlid
,
q
);
skb_queue_tail
(
&
wl
->
links
[
hlid
].
tx_queue
[
q
],
skb
);
}
else
{
skb_queue_tail
(
&
wl
->
tx_queue
[
q
],
skb
);
}
wl
->
tx_queue_count
[
q
]
++
;
/*
...
...
@@ -1520,14 +1512,6 @@ static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
set_bit
(
q
,
&
wl
->
stopped_queues_map
);
}
/* queue the packet */
if
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
)
{
wl1271_debug
(
DEBUG_TX
,
"queue skb hlid %d q %d"
,
hlid
,
q
);
skb_queue_tail
(
&
wl
->
links
[
hlid
].
tx_queue
[
q
],
skb
);
}
else
{
skb_queue_tail
(
&
wl
->
tx_queue
[
q
],
skb
);
}
/*
* The chip specific setup must run before the first TX packet -
* before that, the tx_work will not be initialized!
...
...
@@ -1537,6 +1521,7 @@ static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
!
test_bit
(
WL1271_FLAG_TX_PENDING
,
&
wl
->
flags
))
ieee80211_queue_work
(
wl
->
hw
,
&
wl
->
tx_work
);
out:
spin_unlock_irqrestore
(
&
wl
->
wl_lock
,
flags
);
}
...
...
@@ -1673,7 +1658,7 @@ static int wl1271_configure_suspend_ap(struct wl1271 *wl)
if
(
ret
<
0
)
goto
out_unlock
;
ret
=
wl1271_acx_
set_ap_beacon_filter
(
wl
,
true
);
ret
=
wl1271_acx_
beacon_filter_opt
(
wl
,
true
);
wl1271_ps_elp_sleep
(
wl
);
out_unlock:
...
...
@@ -1711,7 +1696,7 @@ static void wl1271_configure_resume(struct wl1271 *wl)
wl1271_ps_set_mode
(
wl
,
STATION_ACTIVE_MODE
,
wl
->
basic_rate
,
true
);
}
else
if
(
is_ap
)
{
wl1271_acx_
set_ap_beacon_filter
(
wl
,
false
);
wl1271_acx_
beacon_filter_opt
(
wl
,
false
);
}
wl1271_ps_elp_sleep
(
wl
);
...
...
@@ -1803,9 +1788,6 @@ static int wl1271_op_start(struct ieee80211_hw *hw)
*
* The MAC address is first known when the corresponding interface
* is added. That is where we will initialize the hardware.
*
* In addition, we currently have different firmwares for AP and managed
* operation. We will know which to boot according to interface type.
*/
return
0
;
...
...
@@ -1816,6 +1798,24 @@ static void wl1271_op_stop(struct ieee80211_hw *hw)
wl1271_debug
(
DEBUG_MAC80211
,
"mac80211 stop"
);
}
static
u8
wl12xx_get_role_type
(
struct
wl1271
*
wl
)
{
switch
(
wl
->
bss_type
)
{
case
BSS_TYPE_AP_BSS
:
return
WL1271_ROLE_AP
;
case
BSS_TYPE_STA_BSS
:
return
WL1271_ROLE_STA
;
case
BSS_TYPE_IBSS
:
return
WL1271_ROLE_IBSS
;
default:
wl1271_error
(
"invalid bss_type: %d"
,
wl
->
bss_type
);
}
return
WL12XX_INVALID_ROLE_TYPE
;
}
static
int
wl1271_op_add_interface
(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
)
{
...
...
@@ -1823,6 +1823,7 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
struct
wiphy
*
wiphy
=
hw
->
wiphy
;
int
retries
=
WL1271_BOOT_RETRIES
;
int
ret
=
0
;
u8
role_type
;
bool
booted
=
false
;
wl1271_debug
(
DEBUG_MAC80211
,
"mac80211 add interface type %d mac %pM"
,
...
...
@@ -1863,6 +1864,11 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
goto
out
;
}
role_type
=
wl12xx_get_role_type
(
wl
);
if
(
role_type
==
WL12XX_INVALID_ROLE_TYPE
)
{
ret
=
-
EINVAL
;
goto
out
;
}
memcpy
(
wl
->
mac_addr
,
vif
->
addr
,
ETH_ALEN
);
if
(
wl
->
state
!=
WL1271_STATE_OFF
)
{
...
...
@@ -1882,6 +1888,25 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
if
(
ret
<
0
)
goto
power_off
;
if
(
wl
->
bss_type
==
BSS_TYPE_STA_BSS
||
wl
->
bss_type
==
BSS_TYPE_IBSS
)
{
/*
* The device role is a special role used for
* rx and tx frames prior to association (as
* the STA role can get packets only from
* its associated bssid)
*/
ret
=
wl12xx_cmd_role_enable
(
wl
,
WL1271_ROLE_DEVICE
,
&
wl
->
dev_role_id
);
if
(
ret
<
0
)
goto
irq_disable
;
}
ret
=
wl12xx_cmd_role_enable
(
wl
,
role_type
,
&
wl
->
role_id
);
if
(
ret
<
0
)
goto
irq_disable
;
ret
=
wl1271_hw_init
(
wl
);
if
(
ret
<
0
)
goto
irq_disable
;
...
...
@@ -1946,7 +1971,7 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
static
void
__wl1271_op_remove_interface
(
struct
wl1271
*
wl
,
bool
reset_tx_queues
)
{
int
i
;
int
ret
,
i
;
wl1271_debug
(
DEBUG_MAC80211
,
"mac80211 remove interface"
);
...
...
@@ -1971,6 +1996,31 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
ieee80211_scan_completed
(
wl
->
hw
,
true
);
}
if
(
!
test_bit
(
WL1271_FLAG_RECOVERY_IN_PROGRESS
,
&
wl
->
flags
))
{
/* disable active roles */
ret
=
wl1271_ps_elp_wakeup
(
wl
);
if
(
ret
<
0
)
goto
deinit
;
if
(
wl
->
bss_type
==
BSS_TYPE_STA_BSS
)
{
ret
=
wl12xx_cmd_role_disable
(
wl
,
&
wl
->
dev_role_id
);
if
(
ret
<
0
)
goto
deinit
;
}
ret
=
wl12xx_cmd_role_disable
(
wl
,
&
wl
->
role_id
);
if
(
ret
<
0
)
goto
deinit
;
wl1271_ps_elp_sleep
(
wl
);
}
deinit:
/* clear all hlids (except system_hlid) */
wl
->
sta_hlid
=
WL12XX_INVALID_LINK_ID
;
wl
->
dev_hlid
=
WL12XX_INVALID_LINK_ID
;
wl
->
ap_bcast_hlid
=
WL12XX_INVALID_LINK_ID
;
wl
->
ap_global_hlid
=
WL12XX_INVALID_LINK_ID
;
/*
* this must be before the cancel_work calls below, so that the work
* functions don't perform further work.
...
...
@@ -2007,18 +2057,26 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
wl
->
psm_entry_retry
=
0
;
wl
->
power_level
=
WL1271_DEFAULT_POWER_LEVEL
;
wl
->
tx_blocks_available
=
0
;
wl
->
tx_allocated_blocks
=
0
;
wl
->
tx_results_count
=
0
;
wl
->
tx_packets_count
=
0
;
wl
->
time_offset
=
0
;
wl
->
session_counter
=
0
;
wl
->
rate_set
=
CONF_TX_RATE_MASK_BASIC
;
wl
->
vif
=
NULL
;
wl
->
filters
=
0
;
wl1271_free_ap_keys
(
wl
);
memset
(
wl
->
ap_hlid_map
,
0
,
sizeof
(
wl
->
ap_hlid_map
));
wl
->
ap_fw_ps_map
=
0
;
wl
->
ap_ps_map
=
0
;
wl
->
sched_scanning
=
false
;
wl
->
role_id
=
WL12XX_INVALID_ROLE_ID
;
wl
->
dev_role_id
=
WL12XX_INVALID_ROLE_ID
;
memset
(
wl
->
roles_map
,
0
,
sizeof
(
wl
->
roles_map
));
memset
(
wl
->
links_map
,
0
,
sizeof
(
wl
->
links_map
));
memset
(
wl
->
roc_map
,
0
,
sizeof
(
wl
->
roc_map
));
/* The system link is always allocated */
__set_bit
(
WL12XX_SYSTEM_HLID
,
wl
->
links_map
);
/*
* this is performed after the cancel_work calls and the associated
...
...
@@ -2027,9 +2085,11 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
*/
wl
->
flags
=
0
;
wl
->
tx_blocks_freed
=
0
;
for
(
i
=
0
;
i
<
NUM_TX_QUEUES
;
i
++
)
{
wl
->
tx_
block
s_freed
[
i
]
=
0
;
wl
->
tx_allocated_
block
s
[
i
]
=
0
;
wl
->
tx_
pkt
s_freed
[
i
]
=
0
;
wl
->
tx_allocated_
pkt
s
[
i
]
=
0
;
}
wl1271_debugfs_reset
(
wl
);
...
...
@@ -2061,64 +2121,10 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
cancel_work_sync
(
&
wl
->
recovery_work
);
}
void
wl1271_configure_filters
(
struct
wl1271
*
wl
,
unsigned
int
filters
)
{
wl1271_set_default_filters
(
wl
);
/* combine requested filters with current filter config */
filters
=
wl
->
filters
|
filters
;
wl1271_debug
(
DEBUG_FILTERS
,
"RX filters set: "
);
if
(
filters
&
FIF_PROMISC_IN_BSS
)
{
wl1271_debug
(
DEBUG_FILTERS
,
" - FIF_PROMISC_IN_BSS"
);
wl
->
rx_config
&=
~
CFG_UNI_FILTER_EN
;
wl
->
rx_config
|=
CFG_BSSID_FILTER_EN
;
}
if
(
filters
&
FIF_BCN_PRBRESP_PROMISC
)
{
wl1271_debug
(
DEBUG_FILTERS
,
" - FIF_BCN_PRBRESP_PROMISC"
);
wl
->
rx_config
&=
~
CFG_BSSID_FILTER_EN
;
wl
->
rx_config
&=
~
CFG_SSID_FILTER_EN
;
}
if
(
filters
&
FIF_OTHER_BSS
)
{
wl1271_debug
(
DEBUG_FILTERS
,
" - FIF_OTHER_BSS"
);
wl
->
rx_config
&=
~
CFG_BSSID_FILTER_EN
;
}
if
(
filters
&
FIF_CONTROL
)
{
wl1271_debug
(
DEBUG_FILTERS
,
" - FIF_CONTROL"
);
wl
->
rx_filter
|=
CFG_RX_CTL_EN
;
}
if
(
filters
&
FIF_FCSFAIL
)
{
wl1271_debug
(
DEBUG_FILTERS
,
" - FIF_FCSFAIL"
);
wl
->
rx_filter
|=
CFG_RX_FCS_ERROR
;
}
}
static
int
wl1271_dummy_join
(
struct
wl1271
*
wl
)
{
int
ret
=
0
;
/* we need to use a dummy BSSID for now */
static
const
u8
dummy_bssid
[
ETH_ALEN
]
=
{
0x0b
,
0xad
,
0xde
,
0xad
,
0xbe
,
0xef
};
memcpy
(
wl
->
bssid
,
dummy_bssid
,
ETH_ALEN
);
/* pass through frames from all BSS */
wl1271_configure_filters
(
wl
,
FIF_OTHER_BSS
);
ret
=
wl1271_cmd_join
(
wl
,
wl
->
set_bss_type
);
if
(
ret
<
0
)
goto
out
;
set_bit
(
WL1271_FLAG_JOINED
,
&
wl
->
flags
);
out:
return
ret
;
}
static
int
wl1271_join
(
struct
wl1271
*
wl
,
bool
set_assoc
)
{
int
ret
;
bool
is_ibss
=
(
wl
->
bss_type
==
BSS_TYPE_IBSS
);
/*
* One of the side effects of the JOIN command is that is clears
...
...
@@ -2135,12 +2141,13 @@ static int wl1271_join(struct wl1271 *wl, bool set_assoc)
if
(
set_assoc
)
set_bit
(
WL1271_FLAG_STA_ASSOCIATED
,
&
wl
->
flags
);
ret
=
wl1271_cmd_join
(
wl
,
wl
->
set_bss_type
);
if
(
is_ibss
)
ret
=
wl12xx_cmd_role_start_ibss
(
wl
);
else
ret
=
wl12xx_cmd_role_start_sta
(
wl
);
if
(
ret
<
0
)
goto
out
;
set_bit
(
WL1271_FLAG_JOINED
,
&
wl
->
flags
);
if
(
!
test_bit
(
WL1271_FLAG_STA_ASSOCIATED
,
&
wl
->
flags
))
goto
out
;
...
...
@@ -2176,20 +2183,16 @@ static int wl1271_unjoin(struct wl1271 *wl)
int
ret
;
/* to stop listening to a channel, we disconnect */
ret
=
wl12
71_cmd_disconnect
(
wl
);
ret
=
wl12
xx_cmd_role_stop_sta
(
wl
);
if
(
ret
<
0
)
goto
out
;
clear_bit
(
WL1271_FLAG_JOINED
,
&
wl
->
flags
);
memset
(
wl
->
bssid
,
0
,
ETH_ALEN
);
/* reset TX security counters on a clean disconnect */
wl
->
tx_security_last_seq_lsb
=
0
;
wl
->
tx_security_seq
=
0
;
/* stop filtering packets based on bssid */
wl1271_configure_filters
(
wl
,
FIF_OTHER_BSS
);
out:
return
ret
;
}
...
...
@@ -2202,13 +2205,29 @@ static void wl1271_set_band_rate(struct wl1271 *wl)
wl
->
basic_rate_set
=
wl
->
conf
.
tx
.
basic_rate_5
;
}
static
bool
wl12xx_is_roc
(
struct
wl1271
*
wl
)
{
u8
role_id
;
role_id
=
find_first_bit
(
wl
->
roc_map
,
WL12XX_MAX_ROLES
);
if
(
role_id
>=
WL12XX_MAX_ROLES
)
return
false
;
return
true
;
}
static
int
wl1271_sta_handle_idle
(
struct
wl1271
*
wl
,
bool
idle
)
{
int
ret
;
if
(
idle
)
{
if
(
test_bit
(
WL1271_FLAG_JOINED
,
&
wl
->
flags
))
{
ret
=
wl1271_unjoin
(
wl
);
/* no need to croc if we weren't busy (e.g. during boot) */
if
(
wl12xx_is_roc
(
wl
))
{
ret
=
wl12xx_croc
(
wl
,
wl
->
dev_role_id
);
if
(
ret
<
0
)
goto
out
;
ret
=
wl12xx_cmd_role_stop_dev
(
wl
);
if
(
ret
<
0
)
goto
out
;
}
...
...
@@ -2223,18 +2242,17 @@ static int wl1271_sta_handle_idle(struct wl1271 *wl, bool idle)
goto
out
;
set_bit
(
WL1271_FLAG_IDLE
,
&
wl
->
flags
);
}
else
{
/* increment the session counter */
wl
->
session_counter
++
;
if
(
wl
->
session_counter
>=
SESSION_COUNTER_MAX
)
wl
->
session_counter
=
0
;
/* The current firmware only supports sched_scan in idle */
if
(
wl
->
sched_scanning
)
{
wl1271_scan_sched_scan_stop
(
wl
);
ieee80211_sched_scan_stopped
(
wl
->
hw
);
}
ret
=
wl1271_dummy_join
(
wl
);
ret
=
wl12xx_cmd_role_start_dev
(
wl
);
if
(
ret
<
0
)
goto
out
;
ret
=
wl12xx_roc
(
wl
,
wl
->
dev_role_id
);
if
(
ret
<
0
)
goto
out
;
clear_bit
(
WL1271_FLAG_IDLE
,
&
wl
->
flags
);
...
...
@@ -2314,11 +2332,34 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
wl1271_warning
(
"rate policy for channel "
"failed %d"
,
ret
);
if
(
test_bit
(
WL1271_FLAG_JOINED
,
&
wl
->
flags
))
{
if
(
test_bit
(
WL1271_FLAG_STA_ASSOCIATED
,
&
wl
->
flags
))
{
if
(
wl12xx_is_roc
(
wl
))
{
/* roaming */
ret
=
wl12xx_croc
(
wl
,
wl
->
dev_role_id
);
if
(
ret
<
0
)
goto
out_sleep
;
}
ret
=
wl1271_join
(
wl
,
false
);
if
(
ret
<
0
)
wl1271_warning
(
"cmd join on channel "
"failed %d"
,
ret
);
}
else
{
/*
* change the ROC channel. do it only if we are
* not idle. otherwise, CROC will be called
* anyway.
*/
if
(
wl12xx_is_roc
(
wl
)
&&
!
(
conf
->
flags
&
IEEE80211_CONF_IDLE
))
{
ret
=
wl12xx_croc
(
wl
,
wl
->
dev_role_id
);
if
(
ret
<
0
)
goto
out_sleep
;
ret
=
wl12xx_roc
(
wl
,
wl
->
dev_role_id
);
if
(
ret
<
0
)
wl1271_warning
(
"roc failed %d"
,
ret
);
}
}
}
}
...
...
@@ -2458,18 +2499,11 @@ static void wl1271_op_configure_filter(struct ieee80211_hw *hw,
goto
out_sleep
;
}
/* determine, whether supported filter values have changed */
if
(
changed
==
0
)
goto
out_sleep
;
/* configure filters */
wl
->
filters
=
*
total
;
wl1271_configure_filters
(
wl
,
0
);
/* apply configured filters */
ret
=
wl1271_acx_rx_config
(
wl
,
wl
->
rx_config
,
wl
->
rx_filter
);
if
(
ret
<
0
)
goto
out_sleep
;
/*
* the fw doesn't provide an api to configure the filters. instead,
* the filters configuration is based on the active roles / ROC
* state.
*/
out_sleep:
wl1271_ps_elp_sleep
(
wl
);
...
...
@@ -2541,14 +2575,19 @@ static int wl1271_ap_init_hwenc(struct wl1271 *wl)
bool
wep_key_added
=
false
;
for
(
i
=
0
;
i
<
MAX_NUM_KEYS
;
i
++
)
{
u8
hlid
;
if
(
wl
->
recorded_ap_keys
[
i
]
==
NULL
)
break
;
key
=
wl
->
recorded_ap_keys
[
i
];
hlid
=
key
->
hlid
;
if
(
hlid
==
WL12XX_INVALID_LINK_ID
)
hlid
=
wl
->
ap_bcast_hlid
;
ret
=
wl1271_cmd_set_ap_key
(
wl
,
KEY_ADD_OR_REPLACE
,
key
->
id
,
key
->
key_type
,
key
->
key_size
,
key
->
key
,
key
->
hlid
,
key
->
tx_seq_32
,
hlid
,
key
->
tx_seq_32
,
key
->
tx_seq_16
);
if
(
ret
<
0
)
goto
out
;
...
...
@@ -2558,7 +2597,8 @@ static int wl1271_ap_init_hwenc(struct wl1271 *wl)
}
if
(
wep_key_added
)
{
ret
=
wl1271_cmd_set_ap_default_wep_key
(
wl
,
wl
->
default_key
);
ret
=
wl12xx_cmd_set_default_wep_key
(
wl
,
wl
->
default_key
,
wl
->
ap_bcast_hlid
);
if
(
ret
<
0
)
goto
out
;
}
...
...
@@ -2583,7 +2623,7 @@ static int wl1271_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
wl_sta
=
(
struct
wl1271_station
*
)
sta
->
drv_priv
;
hlid
=
wl_sta
->
hlid
;
}
else
{
hlid
=
WL1271_AP_BROADCAST_HLID
;
hlid
=
wl
->
ap_bcast_hlid
;
}
if
(
!
test_bit
(
WL1271_FLAG_AP_STARTED
,
&
wl
->
flags
))
{
...
...
@@ -2627,6 +2667,11 @@ static int wl1271_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
if
(
action
==
KEY_REMOVE
&&
!
is_broadcast_ether_addr
(
addr
))
return
0
;
/* don't remove key if hlid was already deleted */
if
(
action
==
KEY_REMOVE
&&
wl
->
sta_hlid
==
WL12XX_INVALID_LINK_ID
)
return
0
;
ret
=
wl1271_cmd_set_sta_key
(
wl
,
action
,
id
,
key_type
,
key_size
,
key
,
addr
,
tx_seq_32
,
...
...
@@ -2636,8 +2681,9 @@ static int wl1271_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
/* the default WEP key needs to be configured at least once */
if
(
key_type
==
KEY_WEP
)
{
ret
=
wl1271_cmd_set_sta_default_wep_key
(
wl
,
wl
->
default_key
);
ret
=
wl12xx_cmd_set_default_wep_key
(
wl
,
wl
->
default_key
,
wl
->
sta_hlid
);
if
(
ret
<
0
)
return
ret
;
}
...
...
@@ -2779,10 +2825,20 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw,
if
(
ret
<
0
)
goto
out
;
ret
=
wl1271_scan
(
hw
->
priv
,
ssid
,
len
,
req
);
/* cancel ROC before scanning */
if
(
wl12xx_is_roc
(
wl
))
{
if
(
test_bit
(
WL1271_FLAG_STA_ASSOCIATED
,
&
wl
->
flags
))
{
/* don't allow scanning right now */
ret
=
-
EBUSY
;
goto
out_sleep
;
}
wl12xx_croc
(
wl
,
wl
->
dev_role_id
);
wl12xx_cmd_role_stop_dev
(
wl
);
}
ret
=
wl1271_scan
(
hw
->
priv
,
ssid
,
len
,
req
);
out_sleep:
wl1271_ps_elp_sleep
(
wl
);
out:
mutex_unlock
(
&
wl
->
mutex
);
...
...
@@ -3094,20 +3150,20 @@ static void wl1271_bss_info_changed_ap(struct wl1271 *wl,
if
((
changed
&
BSS_CHANGED_BEACON_ENABLED
))
{
if
(
bss_conf
->
enable_beacon
)
{
if
(
!
test_bit
(
WL1271_FLAG_AP_STARTED
,
&
wl
->
flags
))
{
ret
=
wl12
71_cmd_start_bss
(
wl
);
ret
=
wl12
xx_cmd_role_start_ap
(
wl
);
if
(
ret
<
0
)
goto
out
;
set_bit
(
WL1271_FLAG_AP_STARTED
,
&
wl
->
flags
);
wl1271_debug
(
DEBUG_AP
,
"started AP"
);
ret
=
wl1271_ap_init_hwenc
(
wl
);
if
(
ret
<
0
)
goto
out
;
set_bit
(
WL1271_FLAG_AP_STARTED
,
&
wl
->
flags
);
wl1271_debug
(
DEBUG_AP
,
"started AP"
);
}
}
else
{
if
(
test_bit
(
WL1271_FLAG_AP_STARTED
,
&
wl
->
flags
))
{
ret
=
wl12
71_cmd_stop_bss
(
wl
);
ret
=
wl12
xx_cmd_role_stop_ap
(
wl
);
if
(
ret
<
0
)
goto
out
;
...
...
@@ -3120,6 +3176,18 @@ static void wl1271_bss_info_changed_ap(struct wl1271 *wl,
ret
=
wl1271_bss_erp_info_changed
(
wl
,
bss_conf
,
changed
);
if
(
ret
<
0
)
goto
out
;
/* Handle HT information change */
if
((
changed
&
BSS_CHANGED_HT
)
&&
(
bss_conf
->
channel_type
!=
NL80211_CHAN_NO_HT
))
{
ret
=
wl1271_acx_set_ht_information
(
wl
,
bss_conf
->
ht_operation_mode
);
if
(
ret
<
0
)
{
wl1271_warning
(
"Set ht information failed %d"
,
ret
);
goto
out
;
}
}
out:
return
;
}
...
...
@@ -3132,6 +3200,7 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
{
bool
do_join
=
false
,
set_assoc
=
false
;
bool
is_ibss
=
(
wl
->
bss_type
==
BSS_TYPE_IBSS
);
bool
ibss_joined
=
false
;
u32
sta_rate_set
=
0
;
int
ret
;
struct
ieee80211_sta
*
sta
;
...
...
@@ -3145,14 +3214,28 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
goto
out
;
}
if
((
changed
&
BSS_CHANGED_BEACON_INT
)
&&
is_ibss
)
if
(
changed
&
BSS_CHANGED_IBSS
)
{
if
(
bss_conf
->
ibss_joined
)
{
set_bit
(
WL1271_FLAG_IBSS_JOINED
,
&
wl
->
flags
);
ibss_joined
=
true
;
}
else
{
if
(
test_and_clear_bit
(
WL1271_FLAG_IBSS_JOINED
,
&
wl
->
flags
))
{
wl1271_unjoin
(
wl
);
wl12xx_cmd_role_start_dev
(
wl
);
wl12xx_roc
(
wl
,
wl
->
dev_role_id
);
}
}
}
if
((
changed
&
BSS_CHANGED_BEACON_INT
)
&&
ibss_joined
)
do_join
=
true
;
/* Need to update the SSID (for filtering etc) */
if
((
changed
&
BSS_CHANGED_BEACON
)
&&
i
s_ibss
)
if
((
changed
&
BSS_CHANGED_BEACON
)
&&
i
bss_joined
)
do_join
=
true
;
if
((
changed
&
BSS_CHANGED_BEACON_ENABLED
)
&&
i
s_ibss
)
{
if
((
changed
&
BSS_CHANGED_BEACON_ENABLED
)
&&
i
bss_joined
)
{
wl1271_debug
(
DEBUG_ADHOC
,
"ad-hoc beaconing: %s"
,
bss_conf
->
enable_beacon
?
"enabled"
:
"disabled"
);
...
...
@@ -3192,17 +3275,17 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
if
(
ret
<
0
)
goto
out
;
/* filter out all packets not from this BSSID */
wl1271_configure_filters
(
wl
,
0
);
/* Need to update the BSSID (for filtering etc) */
do_join
=
true
;
}
}
rcu_read_lock
();
sta
=
ieee80211_find_sta
(
vif
,
bss_conf
->
bssid
);
if
(
sta
)
{
if
(
changed
&
(
BSS_CHANGED_ASSOC
|
BSS_CHANGED_HT
))
{
rcu_read_lock
();
sta
=
ieee80211_find_sta
(
vif
,
bss_conf
->
bssid
);
if
(
!
sta
)
goto
sta_not_found
;
/* save the supp_rates of the ap */
sta_rate_set
=
sta
->
supp_rates
[
wl
->
hw
->
conf
.
channel
->
band
];
if
(
sta
->
ht_cap
.
ht_supported
)
...
...
@@ -3210,38 +3293,9 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
(
sta
->
ht_cap
.
mcs
.
rx_mask
[
0
]
<<
HW_HT_RATES_OFFSET
);
sta_ht_cap
=
sta
->
ht_cap
;
sta_exists
=
true
;
}
rcu_read_unlock
();
if
(
sta_exists
)
{
/* handle new association with HT and HT information change */
if
((
changed
&
BSS_CHANGED_HT
)
&&
(
bss_conf
->
channel_type
!=
NL80211_CHAN_NO_HT
))
{
ret
=
wl1271_acx_set_ht_capabilities
(
wl
,
&
sta_ht_cap
,
true
);
if
(
ret
<
0
)
{
wl1271_warning
(
"Set ht cap true failed %d"
,
ret
);
goto
out
;
}
ret
=
wl1271_acx_set_ht_information
(
wl
,
bss_conf
->
ht_operation_mode
);
if
(
ret
<
0
)
{
wl1271_warning
(
"Set ht information failed %d"
,
ret
);
goto
out
;
}
}
/* handle new association without HT and disassociation */
else
if
(
changed
&
BSS_CHANGED_ASSOC
)
{
ret
=
wl1271_acx_set_ht_capabilities
(
wl
,
&
sta_ht_cap
,
false
);
if
(
ret
<
0
)
{
wl1271_warning
(
"Set ht cap false failed %d"
,
ret
);
goto
out
;
}
}
sta_not_found:
rcu_read_unlock
();
}
if
((
changed
&
BSS_CHANGED_ASSOC
))
{
...
...
@@ -3309,7 +3363,9 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
bool
was_assoc
=
!!
test_and_clear_bit
(
WL1271_FLAG_STA_ASSOCIATED
,
&
wl
->
flags
);
clear_bit
(
WL1271_FLAG_STA_STATE_SENT
,
&
wl
->
flags
);
bool
was_ifup
=
!!
test_and_clear_bit
(
WL1271_FLAG_STA_STATE_SENT
,
&
wl
->
flags
);
wl
->
aid
=
0
;
/* free probe-request template */
...
...
@@ -3336,8 +3392,32 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
/* restore the bssid filter and go to dummy bssid */
if
(
was_assoc
)
{
u32
conf_flags
=
wl
->
hw
->
conf
.
flags
;
/*
* we might have to disable roc, if there was
* no IF_OPER_UP notification.
*/
if
(
!
was_ifup
)
{
ret
=
wl12xx_croc
(
wl
,
wl
->
role_id
);
if
(
ret
<
0
)
goto
out
;
}
/*
* (we also need to disable roc in case of
* roaming on the same channel. until we will
* have a better flow...)
*/
if
(
test_bit
(
wl
->
dev_role_id
,
wl
->
roc_map
))
{
ret
=
wl12xx_croc
(
wl
,
wl
->
dev_role_id
);
if
(
ret
<
0
)
goto
out
;
}
wl1271_unjoin
(
wl
);
wl1271_dummy_join
(
wl
);
if
(
!
(
conf_flags
&
IEEE80211_CONF_IDLE
))
{
wl12xx_cmd_role_start_dev
(
wl
);
wl12xx_roc
(
wl
,
wl
->
dev_role_id
);
}
}
}
}
...
...
@@ -3398,7 +3478,68 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
wl1271_warning
(
"cmd join failed %d"
,
ret
);
goto
out
;
}
wl1271_check_operstate
(
wl
,
ieee80211_get_operstate
(
vif
));
/* ROC until connected (after EAPOL exchange) */
if
(
!
is_ibss
)
{
ret
=
wl12xx_roc
(
wl
,
wl
->
role_id
);
if
(
ret
<
0
)
goto
out
;
wl1271_check_operstate
(
wl
,
ieee80211_get_operstate
(
vif
));
}
/*
* stop device role if started (we might already be in
* STA role). TODO: make it better.
*/
if
(
wl
->
dev_role_id
!=
WL12XX_INVALID_ROLE_ID
)
{
ret
=
wl12xx_croc
(
wl
,
wl
->
dev_role_id
);
if
(
ret
<
0
)
goto
out
;
ret
=
wl12xx_cmd_role_stop_dev
(
wl
);
if
(
ret
<
0
)
goto
out
;
}
}
/* Handle new association with HT. Do this after join. */
if
(
sta_exists
)
{
if
((
changed
&
BSS_CHANGED_HT
)
&&
(
bss_conf
->
channel_type
!=
NL80211_CHAN_NO_HT
))
{
ret
=
wl1271_acx_set_ht_capabilities
(
wl
,
&
sta_ht_cap
,
true
,
wl
->
sta_hlid
);
if
(
ret
<
0
)
{
wl1271_warning
(
"Set ht cap true failed %d"
,
ret
);
goto
out
;
}
}
/* handle new association without HT and disassociation */
else
if
(
changed
&
BSS_CHANGED_ASSOC
)
{
ret
=
wl1271_acx_set_ht_capabilities
(
wl
,
&
sta_ht_cap
,
false
,
wl
->
sta_hlid
);
if
(
ret
<
0
)
{
wl1271_warning
(
"Set ht cap false failed %d"
,
ret
);
goto
out
;
}
}
}
/* Handle HT information change. Done after join. */
if
((
changed
&
BSS_CHANGED_HT
)
&&
(
bss_conf
->
channel_type
!=
NL80211_CHAN_NO_HT
))
{
ret
=
wl1271_acx_set_ht_information
(
wl
,
bss_conf
->
ht_operation_mode
);
if
(
ret
<
0
)
{
wl1271_warning
(
"Set ht information failed %d"
,
ret
);
goto
out
;
}
}
out:
...
...
@@ -3568,7 +3709,7 @@ static int wl1271_allocate_sta(struct wl1271 *wl,
}
wl_sta
=
(
struct
wl1271_station
*
)
sta
->
drv_priv
;
__
set_bit
(
id
,
wl
->
ap_hlid_map
);
set_bit
(
id
,
wl
->
ap_hlid_map
);
wl_sta
->
hlid
=
WL1271_AP_STA_HLID_START
+
id
;
*
hlid
=
wl_sta
->
hlid
;
memcpy
(
wl
->
links
[
wl_sta
->
hlid
].
addr
,
sta
->
addr
,
ETH_ALEN
);
...
...
@@ -3582,19 +3723,14 @@ static void wl1271_free_sta(struct wl1271 *wl, u8 hlid)
if
(
WARN_ON
(
!
test_bit
(
id
,
wl
->
ap_hlid_map
)))
return
;
__
clear_bit
(
id
,
wl
->
ap_hlid_map
);
clear_bit
(
id
,
wl
->
ap_hlid_map
);
memset
(
wl
->
links
[
hlid
].
addr
,
0
,
ETH_ALEN
);
wl
->
links
[
hlid
].
ba_bitmap
=
0
;
wl1271_tx_reset_link_queues
(
wl
,
hlid
);
__clear_bit
(
hlid
,
&
wl
->
ap_ps_map
);
__clear_bit
(
hlid
,
(
unsigned
long
*
)
&
wl
->
ap_fw_ps_map
);
}
bool
wl1271_is_active_sta
(
struct
wl1271
*
wl
,
u8
hlid
)
{
int
id
=
hlid
-
WL1271_AP_STA_HLID_START
;
return
test_bit
(
id
,
wl
->
ap_hlid_map
);
}
static
int
wl1271_op_sta_add
(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
,
struct
ieee80211_sta
*
sta
)
...
...
@@ -3621,7 +3757,15 @@ static int wl1271_op_sta_add(struct ieee80211_hw *hw,
if
(
ret
<
0
)
goto
out_free_sta
;
ret
=
wl1271_cmd_add_sta
(
wl
,
sta
,
hlid
);
ret
=
wl12xx_cmd_add_peer
(
wl
,
sta
,
hlid
);
if
(
ret
<
0
)
goto
out_sleep
;
ret
=
wl12xx_cmd_set_peer_state
(
wl
,
hlid
);
if
(
ret
<
0
)
goto
out_sleep
;
ret
=
wl1271_acx_set_ht_capabilities
(
wl
,
&
sta
->
ht_cap
,
true
,
hlid
);
if
(
ret
<
0
)
goto
out_sleep
;
...
...
@@ -3664,7 +3808,7 @@ static int wl1271_op_sta_remove(struct ieee80211_hw *hw,
if
(
ret
<
0
)
goto
out
;
ret
=
wl12
71_cmd_remove_sta
(
wl
,
wl_sta
->
hlid
);
ret
=
wl12
xx_cmd_remove_peer
(
wl
,
wl_sta
->
hlid
);
if
(
ret
<
0
)
goto
out_sleep
;
...
...
@@ -3686,6 +3830,14 @@ static int wl1271_op_ampdu_action(struct ieee80211_hw *hw,
{
struct
wl1271
*
wl
=
hw
->
priv
;
int
ret
;
u8
hlid
,
*
ba_bitmap
;
wl1271_debug
(
DEBUG_MAC80211
,
"mac80211 ampdu action %d tid %d"
,
action
,
tid
);
/* sanity check - the fields in FW are only 8bits wide */
if
(
WARN_ON
(
tid
>
0xFF
))
return
-
ENOTSUPP
;
mutex_lock
(
&
wl
->
mutex
);
...
...
@@ -3694,6 +3846,20 @@ static int wl1271_op_ampdu_action(struct ieee80211_hw *hw,
goto
out
;
}
if
(
wl
->
bss_type
==
BSS_TYPE_STA_BSS
)
{
hlid
=
wl
->
sta_hlid
;
ba_bitmap
=
&
wl
->
ba_rx_bitmap
;
}
else
if
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
)
{
struct
wl1271_station
*
wl_sta
;
wl_sta
=
(
struct
wl1271_station
*
)
sta
->
drv_priv
;
hlid
=
wl_sta
->
hlid
;
ba_bitmap
=
&
wl
->
links
[
hlid
].
ba_bitmap
;
}
else
{
ret
=
-
EINVAL
;
goto
out
;
}
ret
=
wl1271_ps_elp_wakeup
(
wl
);
if
(
ret
<
0
)
goto
out
;
...
...
@@ -3703,20 +3869,46 @@ static int wl1271_op_ampdu_action(struct ieee80211_hw *hw,
switch
(
action
)
{
case
IEEE80211_AMPDU_RX_START
:
if
((
wl
->
ba_support
)
&&
(
wl
->
ba_allowed
))
{
ret
=
wl1271_acx_set_ba_receiver_session
(
wl
,
tid
,
*
ssn
,
true
);
if
(
!
ret
)
wl
->
ba_rx_bitmap
|=
BIT
(
tid
);
}
else
{
if
(
!
wl
->
ba_support
||
!
wl
->
ba_allowed
)
{
ret
=
-
ENOTSUPP
;
break
;
}
if
(
wl
->
ba_rx_session_count
>=
RX_BA_MAX_SESSIONS
)
{
ret
=
-
EBUSY
;
wl1271_error
(
"exceeded max RX BA sessions"
);
break
;
}
if
(
*
ba_bitmap
&
BIT
(
tid
))
{
ret
=
-
EINVAL
;
wl1271_error
(
"cannot enable RX BA session on active "
"tid: %d"
,
tid
);
break
;
}
ret
=
wl12xx_acx_set_ba_receiver_session
(
wl
,
tid
,
*
ssn
,
true
,
hlid
);
if
(
!
ret
)
{
*
ba_bitmap
|=
BIT
(
tid
);
wl
->
ba_rx_session_count
++
;
}
break
;
case
IEEE80211_AMPDU_RX_STOP
:
ret
=
wl1271_acx_set_ba_receiver_session
(
wl
,
tid
,
0
,
false
);
if
(
!
ret
)
wl
->
ba_rx_bitmap
&=
~
BIT
(
tid
);
if
(
!
(
*
ba_bitmap
&
BIT
(
tid
)))
{
ret
=
-
EINVAL
;
wl1271_error
(
"no active RX BA session on tid: %d"
,
tid
);
break
;
}
ret
=
wl12xx_acx_set_ba_receiver_session
(
wl
,
tid
,
0
,
false
,
hlid
);
if
(
!
ret
)
{
*
ba_bitmap
&=
~
BIT
(
tid
);
wl
->
ba_rx_session_count
--
;
}
break
;
/*
...
...
@@ -4126,7 +4318,7 @@ static ssize_t wl1271_sysfs_show_hw_pg_ver(struct device *dev,
return
len
;
}
static
DEVICE_ATTR
(
hw_pg_ver
,
S_IRUGO
|
S_IWUSR
,
static
DEVICE_ATTR
(
hw_pg_ver
,
S_IRUGO
,
wl1271_sysfs_show_hw_pg_ver
,
NULL
);
static
ssize_t
wl1271_sysfs_read_fwlog
(
struct
file
*
filp
,
struct
kobject
*
kobj
,
...
...
@@ -4288,7 +4480,7 @@ int wl1271_init_ieee80211(struct wl1271 *wl)
* should be the maximum length possible for a template, without
* the IEEE80211 header of the template
*/
wl
->
hw
->
wiphy
->
max_scan_ie_len
=
WL1271_CMD_TEMPL_
MAX
_SIZE
-
wl
->
hw
->
wiphy
->
max_scan_ie_len
=
WL1271_CMD_TEMPL_
DFLT
_SIZE
-
sizeof
(
struct
ieee80211_header
);
/* make sure all our channels fit in the scanned_ch bitmask */
...
...
@@ -4387,8 +4579,6 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
wl
->
beacon_int
=
WL1271_DEFAULT_BEACON_INT
;
wl
->
default_key
=
0
;
wl
->
rx_counter
=
0
;
wl
->
rx_config
=
WL1271_DEFAULT_STA_RX_CONFIG
;
wl
->
rx_filter
=
WL1271_DEFAULT_STA_RX_FILTER
;
wl
->
psm_entry_retry
=
0
;
wl
->
power_level
=
WL1271_DEFAULT_POWER_LEVEL
;
wl
->
basic_rate_set
=
CONF_TX_RATE_MASK_BASIC
;
...
...
@@ -4401,7 +4591,6 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
wl
->
hw_pg_ver
=
-
1
;
wl
->
bss_type
=
MAX_BSS_TYPE
;
wl
->
set_bss_type
=
MAX_BSS_TYPE
;
wl
->
fw_bss_type
=
MAX_BSS_TYPE
;
wl
->
last_tx_hlid
=
0
;
wl
->
ap_ps_map
=
0
;
wl
->
ap_fw_ps_map
=
0
;
...
...
@@ -4410,12 +4599,22 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
wl
->
sched_scanning
=
false
;
wl
->
tx_security_seq
=
0
;
wl
->
tx_security_last_seq_lsb
=
0
;
wl
->
role_id
=
WL12XX_INVALID_ROLE_ID
;
wl
->
system_hlid
=
WL12XX_SYSTEM_HLID
;
wl
->
sta_hlid
=
WL12XX_INVALID_LINK_ID
;
wl
->
dev_role_id
=
WL12XX_INVALID_ROLE_ID
;
wl
->
dev_hlid
=
WL12XX_INVALID_LINK_ID
;
wl
->
session_counter
=
0
;
wl
->
ap_bcast_hlid
=
WL12XX_INVALID_LINK_ID
;
wl
->
ap_global_hlid
=
WL12XX_INVALID_LINK_ID
;
setup_timer
(
&
wl
->
rx_streaming_timer
,
wl1271_rx_streaming_timer
,
(
unsigned
long
)
wl
);
wl
->
fwlog_size
=
0
;
init_waitqueue_head
(
&
wl
->
fwlog_waitq
);
/* The system link is always allocated */
__set_bit
(
WL12XX_SYSTEM_HLID
,
wl
->
links_map
);
memset
(
wl
->
tx_frames_map
,
0
,
sizeof
(
wl
->
tx_frames_map
));
for
(
i
=
0
;
i
<
ACX_TX_DESCRIPTORS
;
i
++
)
wl
->
tx_frames
[
i
]
=
NULL
;
...
...
@@ -4522,6 +4721,10 @@ int wl1271_free_hw(struct wl1271 *wl)
mutex_unlock
(
&
wl
->
mutex
);
device_remove_bin_file
(
&
wl
->
plat_dev
->
dev
,
&
fwlog_attr
);
device_remove_file
(
&
wl
->
plat_dev
->
dev
,
&
dev_attr_hw_pg_ver
);
device_remove_file
(
&
wl
->
plat_dev
->
dev
,
&
dev_attr_bt_coex_state
);
platform_device_unregister
(
wl
->
plat_dev
);
free_page
((
unsigned
long
)
wl
->
fwlog
);
dev_kfree_skb
(
wl
->
dummy_packet
);
...
...
drivers/net/wireless/wl12xx/ps.c
View file @
e0a8c583
...
...
@@ -226,8 +226,8 @@ void wl1271_ps_link_start(struct wl1271 *wl, u8 hlid, bool clean_queues)
if
(
test_bit
(
hlid
,
&
wl
->
ap_ps_map
))
return
;
wl1271_debug
(
DEBUG_PSM
,
"start mac80211 PSM on hlid %d
blk
s %d "
"clean_queues %d"
,
hlid
,
wl
->
links
[
hlid
].
allocated_
blk
s
,
wl1271_debug
(
DEBUG_PSM
,
"start mac80211 PSM on hlid %d
pkt
s %d "
"clean_queues %d"
,
hlid
,
wl
->
links
[
hlid
].
allocated_
pkt
s
,
clean_queues
);
rcu_read_lock
();
...
...
drivers/net/wireless/wl12xx/reg.h
View file @
e0a8c583
...
...
@@ -296,81 +296,6 @@
===============================================*/
#define REG_EVENT_MAILBOX_PTR (SCR_PAD1)
/* Misc */
#define REG_ENABLE_TX_RX (ENABLE)
/*
* Rx configuration (filter) information element
* ---------------------------------------------
*/
#define REG_RX_CONFIG (RX_CFG)
#define REG_RX_FILTER (RX_FILTER_CFG)
#define RX_CFG_ENABLE_PHY_HEADER_PLCP 0x0002
/* promiscuous - receives all valid frames */
#define RX_CFG_PROMISCUOUS 0x0008
/* receives frames from any BSSID */
#define RX_CFG_BSSID 0x0020
/* receives frames destined to any MAC address */
#define RX_CFG_MAC 0x0010
#define RX_CFG_ENABLE_ONLY_MY_DEST_MAC 0x0010
#define RX_CFG_ENABLE_ANY_DEST_MAC 0x0000
#define RX_CFG_ENABLE_ONLY_MY_BSSID 0x0020
#define RX_CFG_ENABLE_ANY_BSSID 0x0000
/* discards all broadcast frames */
#define RX_CFG_DISABLE_BCAST 0x0200
#define RX_CFG_ENABLE_ONLY_MY_SSID 0x0400
#define RX_CFG_ENABLE_RX_CMPLT_FCS_ERROR 0x0800
#define RX_CFG_COPY_RX_STATUS 0x2000
#define RX_CFG_TSF 0x10000
#define RX_CONFIG_OPTION_ANY_DST_MY_BSS (RX_CFG_ENABLE_ANY_DEST_MAC | \
RX_CFG_ENABLE_ONLY_MY_BSSID)
#define RX_CONFIG_OPTION_MY_DST_ANY_BSS (RX_CFG_ENABLE_ONLY_MY_DEST_MAC\
| RX_CFG_ENABLE_ANY_BSSID)
#define RX_CONFIG_OPTION_ANY_DST_ANY_BSS (RX_CFG_ENABLE_ANY_DEST_MAC | \
RX_CFG_ENABLE_ANY_BSSID)
#define RX_CONFIG_OPTION_MY_DST_MY_BSS (RX_CFG_ENABLE_ONLY_MY_DEST_MAC\
| RX_CFG_ENABLE_ONLY_MY_BSSID)
#define RX_CONFIG_OPTION_FOR_SCAN (RX_CFG_ENABLE_PHY_HEADER_PLCP \
| RX_CFG_ENABLE_RX_CMPLT_FCS_ERROR \
| RX_CFG_COPY_RX_STATUS | RX_CFG_TSF)
#define RX_CONFIG_OPTION_FOR_MEASUREMENT (RX_CFG_ENABLE_ANY_DEST_MAC)
#define RX_CONFIG_OPTION_FOR_JOIN (RX_CFG_ENABLE_ONLY_MY_BSSID | \
RX_CFG_ENABLE_ONLY_MY_DEST_MAC)
#define RX_CONFIG_OPTION_FOR_IBSS_JOIN (RX_CFG_ENABLE_ONLY_MY_SSID | \
RX_CFG_ENABLE_ONLY_MY_DEST_MAC)
#define RX_FILTER_OPTION_DEF (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 RX_FILTER_OPTION_FILTER_ALL 0
#define RX_FILTER_OPTION_DEF_PRSP_BCN (CFG_RX_PRSP_EN | CFG_RX_MGMT_EN\
| CFG_RX_RCTS_ACK | CFG_RX_BCN_EN)
#define RX_FILTER_OPTION_JOIN (CFG_RX_MGMT_EN | CFG_RX_DATA_EN\
| CFG_RX_BCN_EN | CFG_RX_AUTH_EN\
| CFG_RX_ASSOC_EN | CFG_RX_RCTS_ACK\
| CFG_RX_PRSP_EN)
/*===============================================
EEPROM Read/Write Request 32bit RW
------------------------------------------
...
...
drivers/net/wireless/wl12xx/rx.c
View file @
e0a8c583
...
...
@@ -30,20 +30,28 @@
#include "rx.h"
#include "io.h"
static
u8
wl12
71_rx_get_mem_block
(
struct
wl1271_fw_common
_status
*
status
,
static
u8
wl12
xx_rx_get_mem_block
(
struct
wl12xx_fw
_status
*
status
,
u32
drv_rx_counter
)
{
return
le32_to_cpu
(
status
->
rx_pkt_descs
[
drv_rx_counter
])
&
RX_MEM_BLOCK_MASK
;
}
static
u32
wl12
71_rx_get_buf_size
(
struct
wl1271_fw_common
_status
*
status
,
static
u32
wl12
xx_rx_get_buf_size
(
struct
wl12xx_fw
_status
*
status
,
u32
drv_rx_counter
)
{
return
(
le32_to_cpu
(
status
->
rx_pkt_descs
[
drv_rx_counter
])
&
RX_BUF_SIZE_MASK
)
>>
RX_BUF_SIZE_SHIFT_DIV
;
}
static
bool
wl12xx_rx_get_unaligned
(
struct
wl12xx_fw_status
*
status
,
u32
drv_rx_counter
)
{
/* Convert the value to bool */
return
!!
(
le32_to_cpu
(
status
->
rx_pkt_descs
[
drv_rx_counter
])
&
RX_BUF_UNALIGNED_PAYLOAD
);
}
static
void
wl1271_rx_status
(
struct
wl1271
*
wl
,
struct
wl1271_rx_descriptor
*
desc
,
struct
ieee80211_rx_status
*
status
,
...
...
@@ -89,7 +97,8 @@ static void wl1271_rx_status(struct wl1271 *wl,
}
}
static
int
wl1271_rx_handle_data
(
struct
wl1271
*
wl
,
u8
*
data
,
u32
length
)
static
int
wl1271_rx_handle_data
(
struct
wl1271
*
wl
,
u8
*
data
,
u32
length
,
bool
unaligned
)
{
struct
wl1271_rx_descriptor
*
desc
;
struct
sk_buff
*
skb
;
...
...
@@ -97,6 +106,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length)
u8
*
buf
;
u8
beacon
=
0
;
u8
is_data
=
0
;
u8
reserved
=
unaligned
?
NET_IP_ALIGN
:
0
;
/*
* In PLT mode we seem to get frames and mac80211 warns about them,
...
...
@@ -131,17 +141,25 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length)
return
-
EINVAL
;
}
skb
=
__dev_alloc_skb
(
length
,
GFP_KERNEL
);
/* skb length not included rx descriptor */
skb
=
__dev_alloc_skb
(
length
+
reserved
-
sizeof
(
*
desc
),
GFP_KERNEL
);
if
(
!
skb
)
{
wl1271_error
(
"Couldn't allocate RX frame"
);
return
-
ENOMEM
;
}
buf
=
skb_put
(
skb
,
length
);
memcpy
(
buf
,
data
,
length
);
/* reserve the unaligned payload(if any) */
skb_reserve
(
skb
,
reserved
);
/* now we pull the descriptor out of the buffer */
skb_pull
(
skb
,
sizeof
(
*
desc
));
buf
=
skb_put
(
skb
,
length
-
sizeof
(
*
desc
));
/*
* Copy packets from aggregation buffer to the skbs without rx
* descriptor and with packet payload aligned care. In case of unaligned
* packets copy the packets in offset of 2 bytes guarantee IP header
* payload aligned to 4 bytes.
*/
memcpy
(
buf
,
data
+
sizeof
(
*
desc
),
length
-
sizeof
(
*
desc
));
hdr
=
(
struct
ieee80211_hdr
*
)
skb
->
data
;
if
(
ieee80211_is_beacon
(
hdr
->
frame_control
))
...
...
@@ -163,7 +181,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length)
return
is_data
;
}
void
wl12
71_rx
(
struct
wl1271
*
wl
,
struct
wl1271_fw_common
_status
*
status
)
void
wl12
xx_rx
(
struct
wl1271
*
wl
,
struct
wl12xx_fw
_status
*
status
)
{
struct
wl1271_acx_mem_map
*
wl_mem_map
=
wl
->
target_mem_map
;
u32
buf_size
;
...
...
@@ -175,12 +193,13 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status)
u32
pkt_offset
;
bool
is_ap
=
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
);
bool
had_data
=
false
;
bool
unaligned
=
false
;
while
(
drv_rx_counter
!=
fw_rx_counter
)
{
buf_size
=
0
;
rx_counter
=
drv_rx_counter
;
while
(
rx_counter
!=
fw_rx_counter
)
{
pkt_length
=
wl12
71
_rx_get_buf_size
(
status
,
rx_counter
);
pkt_length
=
wl12
xx
_rx_get_buf_size
(
status
,
rx_counter
);
if
(
buf_size
+
pkt_length
>
WL1271_AGGR_BUFFER_SIZE
)
break
;
buf_size
+=
pkt_length
;
...
...
@@ -199,7 +218,7 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status)
* For aggregated packets, only the first memory block
* should be retrieved. The FW takes care of the rest.
*/
mem_block
=
wl12
71
_rx_get_mem_block
(
status
,
mem_block
=
wl12
xx
_rx_get_mem_block
(
status
,
drv_rx_counter
);
wl
->
rx_mem_pool_addr
.
addr
=
(
mem_block
<<
8
)
+
...
...
@@ -220,8 +239,12 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status)
/* Split data into separate packets */
pkt_offset
=
0
;
while
(
pkt_offset
<
buf_size
)
{
pkt_length
=
wl12
71
_rx_get_buf_size
(
status
,
pkt_length
=
wl12
xx
_rx_get_buf_size
(
status
,
drv_rx_counter
);
unaligned
=
wl12xx_rx_get_unaligned
(
status
,
drv_rx_counter
);
/*
* the handle data call can only fail in memory-outage
* conditions, in that case the received frame will just
...
...
@@ -229,7 +252,7 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status)
*/
if
(
wl1271_rx_handle_data
(
wl
,
wl
->
aggr_buf
+
pkt_offset
,
pkt_length
)
==
1
)
pkt_length
,
unaligned
)
==
1
)
had_data
=
true
;
wl
->
rx_counter
++
;
...
...
@@ -260,14 +283,3 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status)
jiffies
+
msecs_to_jiffies
(
timeout
));
}
}
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
View file @
e0a8c583
...
...
@@ -86,16 +86,18 @@
* Bits 3-5 - process_id tag (AP mode FW)
* Bits 6-7 - reserved
*/
#define WL1271_RX_DESC_STATUS_MASK 0x0
7
#define WL1271_RX_DESC_STATUS_MASK 0x0
3
#define WL1271_RX_DESC_SUCCESS 0x00
#define WL1271_RX_DESC_DECRYPT_FAIL 0x01
#define WL1271_RX_DESC_MIC_FAIL 0x02
#define WL1271_RX_DESC_DRIVER_RX_Q_FAIL 0x03
#define RX_MEM_BLOCK_MASK 0xFF
#define RX_BUF_SIZE_MASK 0xFFF00
#define RX_BUF_SIZE_SHIFT_DIV 6
#define RX_MEM_BLOCK_MASK 0xFF
#define RX_BUF_SIZE_MASK 0xFFF00
#define RX_BUF_SIZE_SHIFT_DIV 6
/* If set, the start of IP payload is not 4 bytes aligned */
#define RX_BUF_UNALIGNED_PAYLOAD BIT(20)
enum
{
WL12XX_RX_CLASS_UNKNOWN
,
...
...
@@ -119,16 +121,12 @@ struct wl1271_rx_descriptor {
u8
snr
;
__le32
timestamp
;
u8
packet_class
;
union
{
u8
process_id
;
/* STA FW */
u8
hlid
;
/* AP FW */
}
__packed
;
u8
hlid
;
u8
pad_len
;
u8
reserved
;
}
__packed
;
void
wl12
71_rx
(
struct
wl1271
*
wl
,
struct
wl1271_fw_common
_status
*
status
);
void
wl12
xx_rx
(
struct
wl1271
*
wl
,
struct
wl12xx_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/scan.c
View file @
e0a8c583
...
...
@@ -33,6 +33,8 @@ void wl1271_scan_complete_work(struct work_struct *work)
{
struct
delayed_work
*
dwork
;
struct
wl1271
*
wl
;
int
ret
;
bool
is_sta
,
is_ibss
;
dwork
=
container_of
(
work
,
struct
delayed_work
,
work
);
wl
=
container_of
(
dwork
,
struct
wl1271
,
scan_complete_work
);
...
...
@@ -50,21 +52,34 @@ void wl1271_scan_complete_work(struct work_struct *work)
wl
->
scan
.
state
=
WL1271_SCAN_STATE_IDLE
;
memset
(
wl
->
scan
.
scanned_ch
,
0
,
sizeof
(
wl
->
scan
.
scanned_ch
));
wl
->
scan
.
req
=
NULL
;
ieee80211_scan_completed
(
wl
->
hw
,
false
);
/* restore hardware connection monitoring template */
ret
=
wl1271_ps_elp_wakeup
(
wl
);
if
(
ret
<
0
)
goto
out
;
if
(
test_bit
(
WL1271_FLAG_STA_ASSOCIATED
,
&
wl
->
flags
))
{
if
(
wl1271_ps_elp_wakeup
(
wl
)
==
0
)
{
wl1271_cmd_build_ap_probe_req
(
wl
,
wl
->
probereq
);
wl1271_ps_elp_sleep
(
wl
);
}
/* restore hardware connection monitoring template */
wl1271_cmd_build_ap_probe_req
(
wl
,
wl
->
probereq
);
}
/* return to ROC if needed */
is_sta
=
(
wl
->
bss_type
==
BSS_TYPE_STA_BSS
);
is_ibss
=
(
wl
->
bss_type
==
BSS_TYPE_IBSS
);
if
((
is_sta
&&
!
test_bit
(
WL1271_FLAG_STA_ASSOCIATED
,
&
wl
->
flags
))
||
(
is_ibss
&&
!
test_bit
(
WL1271_FLAG_IBSS_JOINED
,
&
wl
->
flags
)))
{
/* restore remain on channel */
wl12xx_cmd_role_start_dev
(
wl
);
wl12xx_roc
(
wl
,
wl
->
dev_role_id
);
}
wl1271_ps_elp_sleep
(
wl
);
if
(
wl
->
scan
.
failed
)
{
wl1271_info
(
"Scan completed due to error."
);
wl12xx_queue_recovery_work
(
wl
);
}
ieee80211_scan_completed
(
wl
->
hw
,
false
);
out:
mutex_unlock
(
&
wl
->
mutex
);
...
...
@@ -156,6 +171,11 @@ static int wl1271_scan_send(struct wl1271 *wl, enum ieee80211_band band,
if
(
passive
||
wl
->
scan
.
req
->
n_ssids
==
0
)
scan_options
|=
WL1271_SCAN_OPT_PASSIVE
;
if
(
WARN_ON
(
wl
->
role_id
==
WL12XX_INVALID_ROLE_ID
))
{
ret
=
-
EINVAL
;
goto
out
;
}
cmd
->
params
.
role_id
=
wl
->
role_id
;
cmd
->
params
.
scan_options
=
cpu_to_le16
(
scan_options
);
cmd
->
params
.
n_ch
=
wl1271_get_scan_channels
(
wl
,
wl
->
scan
.
req
,
...
...
@@ -167,10 +187,6 @@ static int wl1271_scan_send(struct wl1271 *wl, enum ieee80211_band band,
}
cmd
->
params
.
tx_rate
=
cpu_to_le32
(
basic_rate
);
cmd
->
params
.
rx_config_options
=
cpu_to_le32
(
CFG_RX_ALL_GOOD
);
cmd
->
params
.
rx_filter_options
=
cpu_to_le32
(
CFG_RX_PRSP_EN
|
CFG_RX_MGMT_EN
|
CFG_RX_BCN_EN
);
cmd
->
params
.
n_probe_reqs
=
wl
->
conf
.
scan
.
num_probe_reqs
;
cmd
->
params
.
tx_rate
=
cpu_to_le32
(
basic_rate
);
cmd
->
params
.
tid_trigger
=
0
;
...
...
@@ -186,6 +202,8 @@ static int wl1271_scan_send(struct wl1271 *wl, enum ieee80211_band band,
memcpy
(
cmd
->
params
.
ssid
,
wl
->
scan
.
ssid
,
wl
->
scan
.
ssid_len
);
}
memcpy
(
cmd
->
addr
,
wl
->
mac_addr
,
ETH_ALEN
);
ret
=
wl1271_cmd_build_probe_req
(
wl
,
wl
->
scan
.
ssid
,
wl
->
scan
.
ssid_len
,
wl
->
scan
.
req
->
ie
,
wl
->
scan
.
req
->
ie_len
,
band
);
...
...
drivers/net/wireless/wl12xx/scan.h
View file @
e0a8c583
...
...
@@ -46,7 +46,10 @@ void wl1271_scan_sched_scan_results(struct wl1271 *wl);
#define WL1271_SCAN_CURRENT_TX_PWR 0
#define WL1271_SCAN_OPT_ACTIVE 0
#define WL1271_SCAN_OPT_PASSIVE 1
#define WL1271_SCAN_OPT_TRIGGERED_SCAN 2
#define WL1271_SCAN_OPT_PRIORITY_HIGH 4
/* scan even if we fail to enter psm */
#define WL1271_SCAN_OPT_FORCE 8
#define WL1271_SCAN_BAND_2_4_GHZ 0
#define WL1271_SCAN_BAND_5_GHZ 1
...
...
@@ -62,27 +65,27 @@ enum {
};
struct
basic_scan_params
{
__le32
rx_config_options
;
__le32
rx_filter_options
;
/* Scan option flags (WL1271_SCAN_OPT_*) */
__le16
scan_options
;
u8
role_id
;
/* Number of scan channels in the list (maximum 30) */
u8
n_ch
;
/* This field indicates the number of probe requests to send
per channel for an active scan */
u8
n_probe_reqs
;
/* Rate bit field for sending the probes */
__le32
tx_rate
;
u8
tid_trigger
;
u8
ssid_len
;
/* in order to align */
u8
padding1
[
2
];
u8
use_ssid_list
;
/* Rate bit field for sending the probes */
__le32
tx_rate
;
u8
ssid
[
IEEE80211_MAX_SSID_LEN
];
/* Band to scan */
u8
band
;
u8
use_ssid_list
;
u8
scan_tag
;
u8
padding2
;
u8
padding2
[
2
]
;
}
__packed
;
struct
basic_scan_channel_params
{
...
...
@@ -105,6 +108,10 @@ struct wl1271_cmd_scan {
struct
basic_scan_params
params
;
struct
basic_scan_channel_params
channels
[
WL1271_SCAN_MAX_CHANNELS
];
/* src mac address */
u8
addr
[
ETH_ALEN
];
u8
padding
[
2
];
}
__packed
;
struct
wl1271_cmd_trigger_scan_to
{
...
...
@@ -184,7 +191,7 @@ struct wl1271_cmd_sched_scan_config {
}
__packed
;
#define SCHED_SCAN_MAX_SSIDS
8
#define SCHED_SCAN_MAX_SSIDS
16
enum
{
SCAN_SSID_TYPE_PUBLIC
=
0
,
...
...
drivers/net/wireless/wl12xx/sdio.c
View file @
e0a8c583
...
...
@@ -412,7 +412,5 @@ module_exit(wl1271_exit);
MODULE_LICENSE
(
"GPL"
);
MODULE_AUTHOR
(
"Luciano Coelho <coelho@ti.com>"
);
MODULE_AUTHOR
(
"Juuso Oikarinen <juuso.oikarinen@nokia.com>"
);
MODULE_FIRMWARE
(
WL127
1
_FW_NAME
);
MODULE_FIRMWARE
(
WL127
X
_FW_NAME
);
MODULE_FIRMWARE
(
WL128X_FW_NAME
);
MODULE_FIRMWARE
(
WL127X_AP_FW_NAME
);
MODULE_FIRMWARE
(
WL128X_AP_FW_NAME
);
drivers/net/wireless/wl12xx/spi.c
View file @
e0a8c583
...
...
@@ -486,8 +486,6 @@ module_exit(wl1271_exit);
MODULE_LICENSE
(
"GPL"
);
MODULE_AUTHOR
(
"Luciano Coelho <coelho@ti.com>"
);
MODULE_AUTHOR
(
"Juuso Oikarinen <juuso.oikarinen@nokia.com>"
);
MODULE_FIRMWARE
(
WL127
1
_FW_NAME
);
MODULE_FIRMWARE
(
WL127
X
_FW_NAME
);
MODULE_FIRMWARE
(
WL128X_FW_NAME
);
MODULE_FIRMWARE
(
WL127X_AP_FW_NAME
);
MODULE_FIRMWARE
(
WL128X_AP_FW_NAME
);
MODULE_ALIAS
(
"spi:wl1271"
);
drivers/net/wireless/wl12xx/tx.c
View file @
e0a8c583
...
...
@@ -37,9 +37,10 @@ static int wl1271_set_default_wep_key(struct wl1271 *wl, u8 id)
bool
is_ap
=
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
);
if
(
is_ap
)
ret
=
wl1271_cmd_set_ap_default_wep_key
(
wl
,
id
);
ret
=
wl12xx_cmd_set_default_wep_key
(
wl
,
id
,
wl
->
ap_bcast_hlid
);
else
ret
=
wl12
71_cmd_set_sta_default_wep_key
(
wl
,
id
);
ret
=
wl12
xx_cmd_set_default_wep_key
(
wl
,
id
,
wl
->
sta_hl
id
);
if
(
ret
<
0
)
return
ret
;
...
...
@@ -77,6 +78,7 @@ static int wl1271_tx_update_filters(struct wl1271 *wl,
struct
sk_buff
*
skb
)
{
struct
ieee80211_hdr
*
hdr
;
int
ret
;
hdr
=
(
struct
ieee80211_hdr
*
)(
skb
->
data
+
sizeof
(
struct
wl1271_tx_hw_descr
));
...
...
@@ -90,9 +92,19 @@ static int wl1271_tx_update_filters(struct wl1271 *wl,
if
(
!
ieee80211_is_auth
(
hdr
->
frame_control
))
return
0
;
wl1271_configure_filters
(
wl
,
FIF_OTHER_BSS
);
if
(
wl
->
dev_hlid
!=
WL12XX_INVALID_LINK_ID
)
goto
out
;
return
wl1271_acx_rx_config
(
wl
,
wl
->
rx_config
,
wl
->
rx_filter
);
wl1271_debug
(
DEBUG_CMD
,
"starting device role for roaming"
);
ret
=
wl12xx_cmd_role_start_dev
(
wl
);
if
(
ret
<
0
)
goto
out
;
ret
=
wl12xx_roc
(
wl
,
wl
->
dev_role_id
);
if
(
ret
<
0
)
goto
out
;
out:
return
0
;
}
static
void
wl1271_tx_ap_update_inconnection_sta
(
struct
wl1271
*
wl
,
...
...
@@ -114,24 +126,29 @@ static void wl1271_tx_ap_update_inconnection_sta(struct wl1271 *wl,
static
void
wl1271_tx_regulate_link
(
struct
wl1271
*
wl
,
u8
hlid
)
{
bool
fw_ps
;
u8
tx_
blk
s
;
u8
tx_
pkt
s
;
/* only regulate station links */
if
(
hlid
<
WL1271_AP_STA_HLID_START
)
return
;
fw_ps
=
test_bit
(
hlid
,
(
unsigned
long
*
)
&
wl
->
ap_fw_ps_map
);
tx_
blks
=
wl
->
links
[
hlid
].
allocated_blk
s
;
tx_
pkts
=
wl
->
links
[
hlid
].
allocated_pkt
s
;
/*
* if in FW PS and there is enough data in FW we can put the link
* into high-level PS and clean out its TX queues.
*/
if
(
fw_ps
&&
tx_
blks
>=
WL1271_PS_STA_MAX_BLOCK
S
)
if
(
fw_ps
&&
tx_
pkts
>=
WL1271_PS_STA_MAX_PACKET
S
)
wl1271_ps_link_start
(
wl
,
hlid
,
true
);
}
u8
wl1271_tx_get_hlid
(
struct
sk_buff
*
skb
)
static
bool
wl12xx_is_dummy_packet
(
struct
wl1271
*
wl
,
struct
sk_buff
*
skb
)
{
return
wl
->
dummy_packet
==
skb
;
}
u8
wl12xx_tx_get_hlid_ap
(
struct
wl1271
*
wl
,
struct
sk_buff
*
skb
)
{
struct
ieee80211_tx_info
*
control
=
IEEE80211_SKB_CB
(
skb
);
...
...
@@ -144,14 +161,32 @@ u8 wl1271_tx_get_hlid(struct sk_buff *skb)
}
else
{
struct
ieee80211_hdr
*
hdr
;
if
(
!
test_bit
(
WL1271_FLAG_AP_STARTED
,
&
wl
->
flags
))
return
wl
->
system_hlid
;
hdr
=
(
struct
ieee80211_hdr
*
)
skb
->
data
;
if
(
ieee80211_is_mgmt
(
hdr
->
frame_control
))
return
WL1271_AP_GLOBAL_HLID
;
return
wl
->
ap_global_hlid
;
else
return
WL1271_AP_BROADCAST_HLID
;
return
wl
->
ap_bcast_hlid
;
}
}
static
u8
wl1271_tx_get_hlid
(
struct
wl1271
*
wl
,
struct
sk_buff
*
skb
)
{
if
(
wl12xx_is_dummy_packet
(
wl
,
skb
))
return
wl
->
system_hlid
;
if
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
)
return
wl12xx_tx_get_hlid_ap
(
wl
,
skb
);
if
(
test_bit
(
WL1271_FLAG_STA_ASSOCIATED
,
&
wl
->
flags
)
||
test_bit
(
WL1271_FLAG_IBSS_JOINED
,
&
wl
->
flags
))
return
wl
->
sta_hlid
;
else
return
wl
->
dev_hlid
;
}
static
unsigned
int
wl12xx_calc_packet_alignment
(
struct
wl1271
*
wl
,
unsigned
int
packet_length
)
{
...
...
@@ -169,12 +204,9 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra,
u32
len
;
u32
total_blocks
;
int
id
,
ret
=
-
EBUSY
,
ac
;
u32
spare_blocks
;
if
(
unlikely
(
wl
->
quirks
&
WL12XX_QUIRK_USE_2_SPARE_BLOCKS
))
spare_blocks
=
2
;
else
spare_blocks
=
1
;
/* we use 1 spare block */
u32
spare_blocks
=
1
;
if
(
buf_offset
+
total_len
>
WL1271_AGGR_BUFFER_SIZE
)
return
-
EAGAIN
;
...
...
@@ -206,12 +238,14 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra,
desc
->
id
=
id
;
wl
->
tx_blocks_available
-=
total_blocks
;
wl
->
tx_allocated_blocks
+=
total_blocks
;
ac
=
wl1271_tx_get_queue
(
skb_get_queue_mapping
(
skb
));
wl
->
tx_allocated_
blocks
[
ac
]
+=
total_blocks
;
wl
->
tx_allocated_
pkts
[
ac
]
++
;
if
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
)
wl
->
links
[
hlid
].
allocated_blks
+=
total_blocks
;
if
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
&&
hlid
>=
WL1271_AP_STA_HLID_START
)
wl
->
links
[
hlid
].
allocated_pkts
++
;
ret
=
0
;
...
...
@@ -225,11 +259,6 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra,
return
ret
;
}
static
bool
wl12xx_is_dummy_packet
(
struct
wl1271
*
wl
,
struct
sk_buff
*
skb
)
{
return
wl
->
dummy_packet
==
skb
;
}
static
void
wl1271_tx_fill_hdr
(
struct
wl1271
*
wl
,
struct
sk_buff
*
skb
,
u32
extra
,
struct
ieee80211_tx_info
*
control
,
u8
hlid
)
...
...
@@ -280,9 +309,9 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
wl
->
session_counter
<<
TX_HW_ATTR_OFST_SESSION_COUNTER
;
}
if
(
wl
->
bss_type
!=
BSS_TYPE_AP_BSS
)
{
desc
->
aid
=
hlid
;
desc
->
hlid
=
hlid
;
if
(
wl
->
bss_type
!=
BSS_TYPE_AP_BSS
)
{
/* if the packets are destined for AP (have a STA entry)
send them with AP rate policies, otherwise use default
basic rates */
...
...
@@ -291,18 +320,12 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
else
rate_idx
=
ACX_TX_BASIC_RATE
;
}
else
{
desc
->
hlid
=
hlid
;
switch
(
hlid
)
{
case
WL1271_AP_GLOBAL_HLID
:
if
(
hlid
==
wl
->
ap_global_hlid
)
rate_idx
=
ACX_TX_AP_MODE_MGMT_RATE
;
break
;
case
WL1271_AP_BROADCAST_HLID
:
else
if
(
hlid
==
wl
->
ap_bcast_hlid
)
rate_idx
=
ACX_TX_AP_MODE_BCST_RATE
;
break
;
default:
else
rate_idx
=
ac
;
break
;
}
}
tx_attr
|=
rate_idx
<<
TX_HW_ATTR_OFST_RATE_POLICY
;
...
...
@@ -376,10 +399,11 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct sk_buff *skb,
}
}
if
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
)
hlid
=
wl1271_tx_get_hlid
(
skb
);
else
hlid
=
TX_HW_DEFAULT_AID
;
hlid
=
wl1271_tx_get_hlid
(
wl
,
skb
);
if
(
hlid
==
WL12XX_INVALID_LINK_ID
)
{
wl1271_error
(
"invalid hlid. dropping skb 0x%p"
,
skb
);
return
-
EINVAL
;
}
ret
=
wl1271_tx_allocate
(
wl
,
skb
,
extra
,
buf_offset
,
hlid
);
if
(
ret
<
0
)
...
...
@@ -462,20 +486,24 @@ void wl1271_handle_tx_low_watermark(struct wl1271 *wl)
static
struct
sk_buff_head
*
wl1271_select_queue
(
struct
wl1271
*
wl
,
struct
sk_buff_head
*
queues
)
{
int
i
,
q
=
-
1
;
u32
min_
blk
s
=
0xffffffff
;
int
i
,
q
=
-
1
,
ac
;
u32
min_
pkt
s
=
0xffffffff
;
/*
* Find a non-empty ac where:
* 1. There are packets to transmit
* 2. The FW has the least allocated blocks
*
* We prioritize the ACs according to VO>VI>BE>BK
*/
for
(
i
=
0
;
i
<
NUM_TX_QUEUES
;
i
++
)
if
(
!
skb_queue_empty
(
&
queues
[
i
])
&&
(
wl
->
tx_allocated_blocks
[
i
]
<
min_blks
))
{
q
=
i
;
min_blks
=
wl
->
tx_allocated_blocks
[
q
];
for
(
i
=
0
;
i
<
NUM_TX_QUEUES
;
i
++
)
{
ac
=
wl1271_tx_get_queue
(
i
);
if
(
!
skb_queue_empty
(
&
queues
[
ac
])
&&
(
wl
->
tx_allocated_pkts
[
ac
]
<
min_pkts
))
{
q
=
ac
;
min_pkts
=
wl
->
tx_allocated_pkts
[
q
];
}
}
if
(
q
==
-
1
)
return
NULL
;
...
...
@@ -579,7 +607,7 @@ static void wl1271_skb_queue_head(struct wl1271 *wl, struct sk_buff *skb)
if
(
wl12xx_is_dummy_packet
(
wl
,
skb
))
{
set_bit
(
WL1271_FLAG_DUMMY_PACKET_PENDING
,
&
wl
->
flags
);
}
else
if
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
)
{
u8
hlid
=
wl1271_tx_get_hlid
(
skb
);
u8
hlid
=
wl1271_tx_get_hlid
(
wl
,
skb
);
skb_queue_head
(
&
wl
->
links
[
hlid
].
tx_queue
[
q
],
skb
);
/* make sure we dequeue the same packet next time */
...
...
@@ -826,10 +854,14 @@ void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid)
total
[
i
]
=
0
;
while
((
skb
=
skb_dequeue
(
&
wl
->
links
[
hlid
].
tx_queue
[
i
])))
{
wl1271_debug
(
DEBUG_TX
,
"link freeing skb 0x%p"
,
skb
);
info
=
IEEE80211_SKB_CB
(
skb
);
info
->
status
.
rates
[
0
].
idx
=
-
1
;
info
->
status
.
rates
[
0
].
count
=
0
;
ieee80211_tx_status_ni
(
wl
->
hw
,
skb
);
if
(
!
wl12xx_is_dummy_packet
(
wl
,
skb
))
{
info
=
IEEE80211_SKB_CB
(
skb
);
info
->
status
.
rates
[
0
].
idx
=
-
1
;
info
->
status
.
rates
[
0
].
count
=
0
;
ieee80211_tx_status_ni
(
wl
->
hw
,
skb
);
}
total
[
i
]
++
;
}
}
...
...
@@ -853,8 +885,8 @@ void wl1271_tx_reset(struct wl1271 *wl, bool reset_tx_queues)
if
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
)
{
for
(
i
=
0
;
i
<
AP_MAX_LINKS
;
i
++
)
{
wl1271_tx_reset_link_queues
(
wl
,
i
);
wl
->
links
[
i
].
allocated_
blk
s
=
0
;
wl
->
links
[
i
].
prev_freed_
blk
s
=
0
;
wl
->
links
[
i
].
allocated_
pkt
s
=
0
;
wl
->
links
[
i
].
prev_freed_
pkt
s
=
0
;
}
wl
->
last_tx_hlid
=
0
;
...
...
drivers/net/wireless/wl12xx/tx.h
View file @
e0a8c583
...
...
@@ -29,9 +29,6 @@
#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
#define TX_HW_ATTR_SAVE_RETRIES BIT(0)
#define TX_HW_ATTR_HEADER_PAD BIT(1)
...
...
@@ -116,12 +113,8 @@ struct wl1271_tx_hw_descr {
u8
id
;
/* The packet TID value (as User-Priority) */
u8
tid
;
union
{
/* STA - Identifier of the remote STA in IBSS, 1 in infra-BSS */
u8
aid
;
/* AP - host link ID (HLID) */
u8
hlid
;
}
__packed
;
/* host link ID (HLID) */
u8
hlid
;
u8
reserved
;
}
__packed
;
...
...
@@ -133,7 +126,8 @@ enum wl1271_tx_hw_res_status {
TX_TIMEOUT
=
4
,
TX_KEY_NOT_FOUND
=
5
,
TX_PEER_NOT_FOUND
=
6
,
TX_SESSION_MISMATCH
=
7
TX_SESSION_MISMATCH
=
7
,
TX_LINK_NOT_VALID
=
8
,
};
struct
wl1271_tx_hw_res_descr
{
...
...
@@ -216,7 +210,7 @@ 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
);
u8
wl12
71_tx_get_hlid
(
struct
sk_buff
*
skb
);
u8
wl12
xx_tx_get_hlid_ap
(
struct
wl1271
*
wl
,
struct
sk_buff
*
skb
);
void
wl1271_tx_reset_link_queues
(
struct
wl1271
*
wl
,
u8
hlid
);
void
wl1271_handle_tx_low_watermark
(
struct
wl1271
*
wl
);
...
...
drivers/net/wireless/wl12xx/wl12xx.h
View file @
e0a8c583
...
...
@@ -112,28 +112,8 @@ extern u32 wl12xx_debug_level;
true); \
} while (0)
#define WL1271_DEFAULT_STA_RX_CONFIG (CFG_UNI_FILTER_EN | \
CFG_BSSID_FILTER_EN | \
CFG_MC_FILTER_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 "ti-connectivity/wl1271-fw-2.bin"
#define WL128X_FW_NAME "ti-connectivity/wl128x-fw.bin"
#define WL127X_AP_FW_NAME "ti-connectivity/wl1271-fw-ap.bin"
#define WL128X_AP_FW_NAME "ti-connectivity/wl128x-fw-ap.bin"
#define WL127X_FW_NAME "ti-connectivity/wl127x-fw-3.bin"
#define WL128X_FW_NAME "ti-connectivity/wl128x-fw-3.bin"
/*
* wl127x and wl128x are using the same NVS file name. However, the
...
...
@@ -157,25 +137,34 @@ 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 WL12XX_MAX_ROLES 4
#define WL12XX_MAX_LINKS 8
#define WL12XX_INVALID_ROLE_ID 0xff
#define WL12XX_INVALID_LINK_ID 0xff
/* Defined by FW as 0. Will not be freed or allocated. */
#define WL12XX_SYSTEM_HLID 0
/*
* TODO: we currently don't support multirole. remove
* this constant from the code when we do.
*/
#define WL1271_AP_STA_HLID_START 3
/*
* When in AP-mode, we allow (at least) this number of
mem-block
s
* When in AP-mode, we allow (at least) this number of
packet
s
* to be transmitted to FW for a STA in PS-mode. Only when packets are
* present in the FW buffers it will wake the sleeping STA. We want to put
* enough packets for the driver to transmit all of its buffered data before
* the STA goes to sleep again. But we don't want to take too much mem
-blocks
* the STA goes to sleep again. But we don't want to take too much mem
ory
* as it might hurt the throughput of active STAs.
* The number of blocks (18) is enough for 2 large packets.
*/
#define WL1271_PS_STA_MAX_
BLOCKS (2 * 9)
#define WL1271_PS_STA_MAX_
PACKETS 2
#define WL1271_AP_BSS_INDEX 0
#define WL1271_AP_DEF_BEACON_EXP 20
#define ACX_TX_DESCRIPTORS
32
#define ACX_TX_DESCRIPTORS
16
#define WL1271_AGGR_BUFFER_SIZE (4 * PAGE_SIZE)
...
...
@@ -247,26 +236,22 @@ struct wl1271_stats {
#define AP_MAX_STATIONS 5
/* Broadcast and Global links + links to stations */
#define AP_MAX_LINKS (AP_MAX_STATIONS + 2)
/* Broadcast and Global links + system link + links to stations */
/*
* TODO: when WL1271_AP_STA_HLID_START is no longer constant, change all
* the places that use this.
*/
#define AP_MAX_LINKS (AP_MAX_STATIONS + 3)
/* FW status registers
common for AP/STA
*/
struct
wl12
71_fw_common
_status
{
/* FW status registers */
struct
wl12
xx_fw
_status
{
__le32
intr
;
u8
fw_rx_counter
;
u8
drv_rx_counter
;
u8
reserved
;
u8
tx_results_counter
;
__le32
rx_pkt_descs
[
NUM_RX_PKT_DESC
];
__le32
tx_released_blks
[
NUM_TX_QUEUES
];
__le32
fw_localtime
;
}
__packed
;
/* FW status registers for AP */
struct
wl1271_fw_ap_status
{
struct
wl1271_fw_common_status
common
;
/* Next fields valid only in AP FW */
/*
* A bitmap (where each bit represents a single HLID)
...
...
@@ -274,29 +259,29 @@ struct wl1271_fw_ap_status {
*/
__le32
link_ps_bitmap
;
/* Number of freed MBs per HLID */
u8
tx_lnk_free_blks
[
AP_MAX_LINKS
];
u8
padding_1
[
1
];
}
__packed
;
/*
* A bitmap (where each bit represents a single HLID) to indicate
* if the station is in Fast mode
*/
__le32
link_fast_bitmap
;
/* FW status registers for STA */
struct
wl1271_fw_sta_status
{
struct
wl1271_fw_common_status
common
;
/* Cumulative counter of total released mem blocks since FW-reset */
__le32
total_released_blks
;
u8
tx_total
;
u8
reserved1
;
__le16
reserved2
;
__le32
log_start_addr
;
}
__packed
;
/* Size (in Memory Blocks) of TX pool */
__le32
tx_total
;
struct
wl1271_fw_full_status
{
union
{
struct
wl1271_fw_common_status
common
;
struct
wl1271_fw_sta_status
sta
;
struct
wl1271_fw_ap_status
ap
;
};
}
__packed
;
/* Cumulative counter of released packets per AC */
u8
tx_released_pkts
[
NUM_TX_QUEUES
];
/* Cumulative counter of freed packets per HLID */
u8
tx_lnk_free_pkts
[
WL12XX_MAX_LINKS
];
/* Cumulative counter of released Voice memory blocks */
u8
tx_voice_released_blks
;
u8
padding_1
[
7
];
__le32
log_start_addr
;
}
__packed
;
struct
wl1271_rx_mem_pool_addr
{
u32
addr
;
...
...
@@ -342,7 +327,7 @@ struct wl1271_ap_key {
enum
wl12xx_flags
{
WL1271_FLAG_STA_ASSOCIATED
,
WL1271_FLAG_JOINED
,
WL1271_FLAG_
IBSS_
JOINED
,
WL1271_FLAG_GPIO_POWER
,
WL1271_FLAG_TX_QUEUE_STOPPED
,
WL1271_FLAG_TX_PENDING
,
...
...
@@ -369,11 +354,14 @@ struct wl1271_link {
/* AP-mode - TX queue per AC in link */
struct
sk_buff_head
tx_queue
[
NUM_TX_QUEUES
];
/* accounting for allocated /
available TX block
s in FW */
u8
allocated_
blk
s
;
u8
prev_freed_
blk
s
;
/* accounting for allocated /
freed packet
s in FW */
u8
allocated_
pkt
s
;
u8
prev_freed_
pkt
s
;
u8
addr
[
ETH_ALEN
];
/* bitmap of TIDs where RX BA sessions are active for this link */
u8
ba_bitmap
;
};
struct
wl1271
{
...
...
@@ -405,7 +393,6 @@ struct wl1271 {
u8
*
fw
;
size_t
fw_len
;
u8
fw_bss_type
;
void
*
nvs
;
size_t
nvs_len
;
...
...
@@ -418,15 +405,30 @@ struct wl1271 {
u8
ssid
[
IEEE80211_MAX_SSID_LEN
+
1
];
u8
ssid_len
;
int
channel
;
u8
role_id
;
u8
dev_role_id
;
u8
system_hlid
;
u8
sta_hlid
;
u8
dev_hlid
;
u8
ap_global_hlid
;
u8
ap_bcast_hlid
;
unsigned
long
links_map
[
BITS_TO_LONGS
(
WL12XX_MAX_LINKS
)];
unsigned
long
roles_map
[
BITS_TO_LONGS
(
WL12XX_MAX_ROLES
)];
unsigned
long
roc_map
[
BITS_TO_LONGS
(
WL12XX_MAX_ROLES
)];
struct
wl1271_acx_mem_map
*
target_mem_map
;
/* Accounting for allocated / available TX blocks on HW */
u32
tx_blocks_freed
[
NUM_TX_QUEUES
]
;
u32
tx_blocks_freed
;
u32
tx_blocks_available
;
u32
tx_allocated_blocks
[
NUM_TX_QUEUES
]
;
u32
tx_allocated_blocks
;
u32
tx_results_count
;
/* Accounting for allocated / available Tx packets in HW */
u32
tx_pkts_freed
[
NUM_TX_QUEUES
];
u32
tx_allocated_pkts
[
NUM_TX_QUEUES
];
/* Transmitted TX packets counter for chipset interface */
u32
tx_packets_count
;
...
...
@@ -535,10 +537,6 @@ struct wl1271 {
struct
work_struct
rx_streaming_disable_work
;
struct
timer_list
rx_streaming_timer
;
unsigned
int
filters
;
unsigned
int
rx_config
;
unsigned
int
rx_filter
;
struct
completion
*
elp_compl
;
struct
completion
*
ps_compl
;
struct
delayed_work
elp_work
;
...
...
@@ -562,7 +560,7 @@ struct wl1271 {
u32
buffer_cmd
;
u32
buffer_busyword
[
WL1271_BUSY_WORD_CNT
];
struct
wl12
71_fw_full
_status
*
fw_status
;
struct
wl12
xx_fw
_status
*
fw_status
;
struct
wl1271_tx_hw_res_if
*
tx_res_if
;
struct
ieee80211_vif
*
vif
;
...
...
@@ -622,6 +620,9 @@ struct wl1271 {
/* Platform limitations */
unsigned
int
platform_quirks
;
/* number of currently active RX BA sessions */
int
ba_rx_session_count
;
};
struct
wl1271_station
{
...
...
@@ -659,12 +660,6 @@ size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen);
/* Each RX/TX transaction requires an end-of-transaction transfer */
#define WL12XX_QUIRK_END_OF_TRANSACTION BIT(0)
/*
* Older firmwares use 2 spare TX blocks
* (for STA < 6.1.3.50.58 or for AP < 6.2.0.0.47)
*/
#define WL12XX_QUIRK_USE_2_SPARE_BLOCKS BIT(1)
/* WL128X requires aggregated packets to be aligned to the SDIO block size */
#define WL12XX_QUIRK_BLOCKSIZE_ALIGNMENT BIT(2)
...
...
drivers/net/wireless/wl12xx/wl12xx_80211.h
View file @
e0a8c583
...
...
@@ -105,18 +105,6 @@ struct wl12xx_ie_country {
/* Templates */
struct
wl12xx_beacon_template
{
struct
ieee80211_header
header
;
__le32
time_stamp
[
2
];
__le16
beacon_interval
;
__le16
capability
;
struct
wl12xx_ie_ssid
ssid
;
struct
wl12xx_ie_rates
rates
;
struct
wl12xx_ie_rates
ext_rates
;
struct
wl12xx_ie_ds_params
ds_params
;
struct
wl12xx_ie_country
country
;
}
__packed
;
struct
wl12xx_null_data_template
{
struct
ieee80211_header
header
;
}
__packed
;
...
...
@@ -146,19 +134,6 @@ struct wl12xx_arp_rsp_template {
__be32
target_ip
;
}
__packed
;
struct
wl12xx_probe_resp_template
{
struct
ieee80211_header
header
;
__le32
time_stamp
[
2
];
__le16
beacon_interval
;
__le16
capability
;
struct
wl12xx_ie_ssid
ssid
;
struct
wl12xx_ie_rates
rates
;
struct
wl12xx_ie_rates
ext_rates
;
struct
wl12xx_ie_ds_params
ds_params
;
struct
wl12xx_ie_country
country
;
}
__packed
;
struct
wl12xx_disconn_template
{
struct
ieee80211_header
header
;
__le16
disconn_reason
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment