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
nexedi
linux
Commits
890641b2
Commit
890641b2
authored
May 05, 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
eaef6a93
25eaea30
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
852 additions
and
280 deletions
+852
-280
drivers/net/wireless/wl12xx/acx.c
drivers/net/wireless/wl12xx/acx.c
+142
-48
drivers/net/wireless/wl12xx/acx.h
drivers/net/wireless/wl12xx/acx.h
+87
-16
drivers/net/wireless/wl12xx/boot.c
drivers/net/wireless/wl12xx/boot.c
+2
-4
drivers/net/wireless/wl12xx/cmd.c
drivers/net/wireless/wl12xx/cmd.c
+14
-4
drivers/net/wireless/wl12xx/conf.h
drivers/net/wireless/wl12xx/conf.h
+62
-28
drivers/net/wireless/wl12xx/debugfs.c
drivers/net/wireless/wl12xx/debugfs.c
+239
-0
drivers/net/wireless/wl12xx/event.c
drivers/net/wireless/wl12xx/event.c
+0
-47
drivers/net/wireless/wl12xx/event.h
drivers/net/wireless/wl12xx/event.h
+1
-11
drivers/net/wireless/wl12xx/init.c
drivers/net/wireless/wl12xx/init.c
+81
-29
drivers/net/wireless/wl12xx/init.h
drivers/net/wireless/wl12xx/init.h
+2
-0
drivers/net/wireless/wl12xx/main.c
drivers/net/wireless/wl12xx/main.c
+158
-74
drivers/net/wireless/wl12xx/ps.c
drivers/net/wireless/wl12xx/ps.c
+24
-6
drivers/net/wireless/wl12xx/rx.c
drivers/net/wireless/wl12xx/rx.c
+28
-8
drivers/net/wireless/wl12xx/tx.c
drivers/net/wireless/wl12xx/tx.c
+9
-4
drivers/net/wireless/wl12xx/tx.h
drivers/net/wireless/wl12xx/tx.h
+1
-1
drivers/net/wireless/wl12xx/wl12xx.h
drivers/net/wireless/wl12xx/wl12xx.h
+2
-0
No files found.
drivers/net/wireless/wl12xx/acx.c
View file @
890641b2
...
...
@@ -325,12 +325,19 @@ int wl1271_acx_service_period_timeout(struct wl1271 *wl)
return
ret
;
}
int
wl1271_acx_rts_threshold
(
struct
wl1271
*
wl
,
u
16
rts_threshold
)
int
wl1271_acx_rts_threshold
(
struct
wl1271
*
wl
,
u
32
rts_threshold
)
{
struct
acx_rts_threshold
*
rts
;
int
ret
;
wl1271_debug
(
DEBUG_ACX
,
"acx rts threshold"
);
/*
* If the RTS threshold is not configured or out of range, use the
* default value.
*/
if
(
rts_threshold
>
IEEE80211_MAX_RTS_THRESHOLD
)
rts_threshold
=
wl
->
conf
.
rx
.
rts_threshold
;
wl1271_debug
(
DEBUG_ACX
,
"acx rts threshold: %d"
,
rts_threshold
);
rts
=
kzalloc
(
sizeof
(
*
rts
),
GFP_KERNEL
);
if
(
!
rts
)
{
...
...
@@ -338,7 +345,7 @@ int wl1271_acx_rts_threshold(struct wl1271 *wl, u16 rts_threshold)
goto
out
;
}
rts
->
threshold
=
cpu_to_le16
(
rts_threshold
);
rts
->
threshold
=
cpu_to_le16
(
(
u16
)
rts_threshold
);
ret
=
wl1271_cmd_configure
(
wl
,
DOT11_RTS_THRESHOLD
,
rts
,
sizeof
(
*
rts
));
if
(
ret
<
0
)
{
...
...
@@ -540,13 +547,13 @@ int wl1271_acx_sg_enable(struct wl1271 *wl, bool enable)
return
ret
;
}
int
wl1271_acx_sg_cfg
(
struct
wl1271
*
wl
)
int
wl1271_acx_s
ta_s
g_cfg
(
struct
wl1271
*
wl
)
{
struct
acx_bt_wlan_coex_param
*
param
;
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 cfg"
);
wl1271_debug
(
DEBUG_ACX
,
"acx sg
sta
cfg"
);
param
=
kzalloc
(
sizeof
(
*
param
),
GFP_KERNEL
);
if
(
!
param
)
{
...
...
@@ -555,8 +562,38 @@ int wl1271_acx_sg_cfg(struct wl1271 *wl)
}
/* BT-WLAN coext parameters */
for
(
i
=
0
;
i
<
CONF_SG_PARAMS_MAX
;
i
++
)
param
->
params
[
i
]
=
cpu_to_le32
(
c
->
params
[
i
]);
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
)
{
struct
acx_ap_bt_wlan_coex_param
*
param
;
struct
conf_sg_settings
*
c
=
&
wl
->
conf
.
sg
;
int
i
,
ret
;
wl1271_debug
(
DEBUG_ACX
,
"acx sg ap cfg"
);
param
=
kzalloc
(
sizeof
(
*
param
),
GFP_KERNEL
);
if
(
!
param
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
/* BT-WLAN coext parameters */
for
(
i
=
0
;
i
<
CONF_SG_AP_PARAMS_MAX
;
i
++
)
param
->
params
[
i
]
=
cpu_to_le32
(
c
->
ap_params
[
i
]);
param
->
param_idx
=
CONF_SG_PARAMS_ALL
;
ret
=
wl1271_cmd_configure
(
wl
,
ACX_SG_CFG
,
param
,
sizeof
(
*
param
));
...
...
@@ -804,7 +841,8 @@ int wl1271_acx_ap_rate_policy(struct wl1271 *wl, struct conf_tx_rate_class *c,
struct
acx_ap_rate_policy
*
acx
;
int
ret
=
0
;
wl1271_debug
(
DEBUG_ACX
,
"acx ap rate policy"
);
wl1271_debug
(
DEBUG_ACX
,
"acx ap rate policy %d rates 0x%x"
,
idx
,
c
->
enabled_rates
);
acx
=
kzalloc
(
sizeof
(
*
acx
),
GFP_KERNEL
);
if
(
!
acx
)
{
...
...
@@ -898,12 +936,19 @@ int wl1271_acx_tid_cfg(struct wl1271 *wl, u8 queue_id, u8 channel_type,
return
ret
;
}
int
wl1271_acx_frag_threshold
(
struct
wl1271
*
wl
,
u
16
frag_threshold
)
int
wl1271_acx_frag_threshold
(
struct
wl1271
*
wl
,
u
32
frag_threshold
)
{
struct
acx_frag_threshold
*
acx
;
int
ret
=
0
;
wl1271_debug
(
DEBUG_ACX
,
"acx frag threshold"
);
/*
* If the fragmentation is not configured or out of range, use the
* default value.
*/
if
(
frag_threshold
>
IEEE80211_MAX_FRAG_THRESHOLD
)
frag_threshold
=
wl
->
conf
.
tx
.
frag_threshold
;
wl1271_debug
(
DEBUG_ACX
,
"acx frag threshold: %d"
,
frag_threshold
);
acx
=
kzalloc
(
sizeof
(
*
acx
),
GFP_KERNEL
);
...
...
@@ -912,7 +957,7 @@ int wl1271_acx_frag_threshold(struct wl1271 *wl, u16 frag_threshold)
goto
out
;
}
acx
->
frag_threshold
=
cpu_to_le16
(
frag_threshold
);
acx
->
frag_threshold
=
cpu_to_le16
(
(
u16
)
frag_threshold
);
ret
=
wl1271_cmd_configure
(
wl
,
ACX_FRAG_CFG
,
acx
,
sizeof
(
*
acx
));
if
(
ret
<
0
)
{
wl1271_warning
(
"Setting of frag threshold failed: %d"
,
ret
);
...
...
@@ -954,6 +999,7 @@ int wl1271_acx_tx_config_options(struct wl1271 *wl)
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"
);
...
...
@@ -964,14 +1010,21 @@ int wl1271_acx_ap_mem_cfg(struct wl1271 *wl)
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 */
/* FIXME: for now we always use mem_wl127x for AP, because it
* doesn't support dynamic memory and we don't have the
* optimal values for wl128x without dynamic memory yet */
mem_conf
->
num_stations
=
wl
->
conf
.
mem_wl127x
.
num_stations
;
mem_conf
->
rx_mem_block_num
=
wl
->
conf
.
mem_wl127x
.
rx_block_num
;
mem_conf
->
tx_min_mem_block_num
=
wl
->
conf
.
mem_wl127x
.
tx_min_block_num
;
mem_conf
->
num_ssid_profiles
=
wl
->
conf
.
mem_wl127x
.
ssid_profiles
;
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
,
...
...
@@ -1524,46 +1577,22 @@ int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime)
return
ret
;
}
int
wl1271_acx_
ap_
max_tx_retry
(
struct
wl1271
*
wl
)
int
wl1271_acx_max_tx_retry
(
struct
wl1271
*
wl
)
{
struct
wl1271_acx_
ap_
max_tx_retry
*
acx
=
NULL
;
struct
wl1271_acx_max_tx_retry
*
acx
=
NULL
;
int
ret
;
wl1271_debug
(
DEBUG_ACX
,
"acx
ap
max tx retry"
);
wl1271_debug
(
DEBUG_ACX
,
"acx max tx retry"
);
acx
=
kzalloc
(
sizeof
(
*
acx
),
GFP_KERNEL
);
if
(
!
acx
)
return
-
ENOMEM
;
acx
->
max_tx_retry
=
cpu_to_le16
(
wl
->
conf
.
tx
.
max_tx_retries
);
acx
->
max_tx_retry
=
cpu_to_le16
(
wl
->
conf
.
tx
.
ap_
max_tx_retries
);
ret
=
wl1271_cmd_configure
(
wl
,
ACX_MAX_TX_FAILURE
,
acx
,
sizeof
(
*
acx
));
if
(
ret
<
0
)
{
wl1271_warning
(
"acx ap max tx retry failed: %d"
,
ret
);
goto
out
;
}
out:
kfree
(
acx
);
return
ret
;
}
int
wl1271_acx_sta_max_tx_retry
(
struct
wl1271
*
wl
)
{
struct
wl1271_acx_sta_max_tx_retry
*
acx
=
NULL
;
int
ret
;
wl1271_debug
(
DEBUG_ACX
,
"acx sta max tx retry"
);
acx
=
kzalloc
(
sizeof
(
*
acx
),
GFP_KERNEL
);
if
(
!
acx
)
return
-
ENOMEM
;
acx
->
max_tx_retry
=
wl
->
conf
.
tx
.
max_tx_retries
;
ret
=
wl1271_cmd_configure
(
wl
,
ACX_CONS_TX_FAILURE
,
acx
,
sizeof
(
*
acx
));
if
(
ret
<
0
)
{
wl1271_warning
(
"acx sta max tx retry failed: %d"
,
ret
);
wl1271_warning
(
"acx max tx retry failed: %d"
,
ret
);
goto
out
;
}
...
...
@@ -1626,3 +1655,68 @@ int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr)
kfree
(
acx
);
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
;
int
ret
;
wl1271_debug
(
DEBUG_ACX
,
"acx fm coex setting"
);
acx
=
kzalloc
(
sizeof
(
*
acx
),
GFP_KERNEL
);
if
(
!
acx
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
acx
->
enable
=
wl
->
conf
.
fm_coex
.
enable
;
acx
->
swallow_period
=
wl
->
conf
.
fm_coex
.
swallow_period
;
acx
->
n_divider_fref_set_1
=
wl
->
conf
.
fm_coex
.
n_divider_fref_set_1
;
acx
->
n_divider_fref_set_2
=
wl
->
conf
.
fm_coex
.
n_divider_fref_set_2
;
acx
->
m_divider_fref_set_1
=
cpu_to_le16
(
wl
->
conf
.
fm_coex
.
m_divider_fref_set_1
);
acx
->
m_divider_fref_set_2
=
cpu_to_le16
(
wl
->
conf
.
fm_coex
.
m_divider_fref_set_2
);
acx
->
coex_pll_stabilization_time
=
cpu_to_le32
(
wl
->
conf
.
fm_coex
.
coex_pll_stabilization_time
);
acx
->
ldo_stabilization_time
=
cpu_to_le16
(
wl
->
conf
.
fm_coex
.
ldo_stabilization_time
);
acx
->
fm_disturbed_band_margin
=
wl
->
conf
.
fm_coex
.
fm_disturbed_band_margin
;
acx
->
swallow_clk_diff
=
wl
->
conf
.
fm_coex
.
swallow_clk_diff
;
ret
=
wl1271_cmd_configure
(
wl
,
ACX_FM_COEX_CFG
,
acx
,
sizeof
(
*
acx
));
if
(
ret
<
0
)
{
wl1271_warning
(
"acx fm coex setting failed: %d"
,
ret
);
goto
out
;
}
out:
kfree
(
acx
);
return
ret
;
}
drivers/net/wireless/wl12xx/acx.h
View file @
890641b2
...
...
@@ -303,7 +303,6 @@ struct acx_beacon_filter_option {
struct
acx_header
header
;
u8
enable
;
/*
* The number of beacons without the unicast TIM
* bit set that the firmware buffers before
...
...
@@ -370,14 +369,23 @@ struct acx_bt_wlan_coex {
u8
pad
[
3
];
}
__packed
;
struct
acx_bt_wlan_coex_param
{
struct
acx_
sta_
bt_wlan_coex_param
{
struct
acx_header
header
;
__le32
params
[
CONF_SG_PARAMS_MAX
];
__le32
params
[
CONF_SG_
STA_
PARAMS_MAX
];
u8
param_idx
;
u8
padding
[
3
];
}
__packed
;
struct
acx_ap_bt_wlan_coex_param
{
struct
acx_header
header
;
__le32
params
[
CONF_SG_AP_PARAMS_MAX
];
u8
param_idx
;
u8
padding
[
3
];
}
__packed
;
struct
acx_dco_itrim_params
{
struct
acx_header
header
;
...
...
@@ -1145,7 +1153,7 @@ struct wl1271_acx_fw_tsf_information {
u8
padding
[
3
];
}
__packed
;
struct
wl1271_acx_
ap_
max_tx_retry
{
struct
wl1271_acx_max_tx_retry
{
struct
acx_header
header
;
/*
...
...
@@ -1156,13 +1164,6 @@ struct wl1271_acx_ap_max_tx_retry {
u8
padding_1
[
2
];
}
__packed
;
struct
wl1271_acx_sta_max_tx_retry
{
struct
acx_header
header
;
u8
max_tx_retry
;
u8
padding_1
[
3
];
}
__packed
;
struct
wl1271_acx_config_ps
{
struct
acx_header
header
;
...
...
@@ -1179,6 +1180,72 @@ 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.
*/
struct
wl1271_acx_fm_coex
{
struct
acx_header
header
;
/* enable(1) / disable(0) the FM Coex feature */
u8
enable
;
/*
* Swallow period used in COEX PLL swallowing mechanism.
* 0xFF = use FW default
*/
u8
swallow_period
;
/*
* The N divider used in COEX PLL swallowing mechanism for Fref of
* 38.4/19.2 Mhz. 0xFF = use FW default
*/
u8
n_divider_fref_set_1
;
/*
* The N divider used in COEX PLL swallowing mechanism for Fref of
* 26/52 Mhz. 0xFF = use FW default
*/
u8
n_divider_fref_set_2
;
/*
* The M divider used in COEX PLL swallowing mechanism for Fref of
* 38.4/19.2 Mhz. 0xFFFF = use FW default
*/
__le16
m_divider_fref_set_1
;
/*
* The M divider used in COEX PLL swallowing mechanism for Fref of
* 26/52 Mhz. 0xFFFF = use FW default
*/
__le16
m_divider_fref_set_2
;
/*
* The time duration in uSec required for COEX PLL to stabilize.
* 0xFFFFFFFF = use FW default
*/
__le32
coex_pll_stabilization_time
;
/*
* The time duration in uSec required for LDO to stabilize.
* 0xFFFFFFFF = use FW default
*/
__le16
ldo_stabilization_time
;
/*
* The disturbed frequency band margin around the disturbed frequency
* center (single sided).
* For example, if 2 is configured, the following channels will be
* considered disturbed channel:
* 80 +- 0.1 MHz, 91 +- 0.1 MHz, 98 +- 0.1 MHz, 102 +- 0.1 MH
* 0xFF = use FW default
*/
u8
fm_disturbed_band_margin
;
/*
* The swallow clock difference of the swallowing mechanism.
* 0xFF = use FW default
*/
u8
swallow_clk_diff
;
}
__packed
;
enum
{
ACX_WAKE_UP_CONDITIONS
=
0x0002
,
ACX_MEM_CFG
=
0x0003
,
...
...
@@ -1197,6 +1264,7 @@ 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
,
...
...
@@ -1208,6 +1276,7 @@ enum {
ACX_BCN_DTIM_OPTIONS
=
0x0031
,
ACX_SG_ENABLE
=
0x0032
,
ACX_SG_CFG
=
0x0033
,
ACX_FM_COEX_CFG
=
0x0034
,
ACX_BEACON_FILTER_TABLE
=
0x0038
,
ACX_ARP_IP_FILTER
=
0x0039
,
ACX_ROAMING_STATISTICS_TBL
=
0x003B
,
...
...
@@ -1264,13 +1333,14 @@ int wl1271_acx_slot(struct wl1271 *wl, enum acx_slot_type slot_time);
int
wl1271_acx_group_address_tbl
(
struct
wl1271
*
wl
,
bool
enable
,
void
*
mc_list
,
u32
mc_list_len
);
int
wl1271_acx_service_period_timeout
(
struct
wl1271
*
wl
);
int
wl1271_acx_rts_threshold
(
struct
wl1271
*
wl
,
u
16
rts_threshold
);
int
wl1271_acx_rts_threshold
(
struct
wl1271
*
wl
,
u
32
rts_threshold
);
int
wl1271_acx_dco_itrim_params
(
struct
wl1271
*
wl
);
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_sg_cfg
(
struct
wl1271
*
wl
);
int
wl1271_acx_sta_sg_cfg
(
struct
wl1271
*
wl
);
int
wl1271_acx_ap_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
);
...
...
@@ -1287,7 +1357,7 @@ int wl1271_acx_ac_cfg(struct wl1271 *wl, u8 ac, u8 cw_min, u16 cw_max,
int
wl1271_acx_tid_cfg
(
struct
wl1271
*
wl
,
u8
queue_id
,
u8
channel_type
,
u8
tsid
,
u8
ps_scheme
,
u8
ack_policy
,
u32
apsd_conf0
,
u32
apsd_conf1
);
int
wl1271_acx_frag_threshold
(
struct
wl1271
*
wl
,
u
16
frag_threshold
);
int
wl1271_acx_frag_threshold
(
struct
wl1271
*
wl
,
u
32
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
);
...
...
@@ -1314,9 +1384,10 @@ int wl1271_acx_set_ba_session(struct wl1271 *wl,
int
wl1271_acx_set_ba_receiver_session
(
struct
wl1271
*
wl
,
u8
tid_index
,
u16
ssn
,
bool
enable
);
int
wl1271_acx_tsf_info
(
struct
wl1271
*
wl
,
u64
*
mactime
);
int
wl1271_acx_ap_max_tx_retry
(
struct
wl1271
*
wl
);
int
wl1271_acx_sta_max_tx_retry
(
struct
wl1271
*
wl
);
int
wl1271_acx_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
);
#endif
/* __WL1271_ACX_H__ */
drivers/net/wireless/wl12xx/boot.c
View file @
890641b2
...
...
@@ -478,12 +478,10 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl)
DISCONNECT_EVENT_COMPLETE_ID
|
RSSI_SNR_TRIGGER_0_EVENT_ID
|
PSPOLL_DELIVERY_FAILURE_EVENT_ID
|
SOFT_GEMINI_SENSE_EVENT_ID
|
MAX_TX_RETRY_EVENT_ID
;
SOFT_GEMINI_SENSE_EVENT_ID
;
if
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
)
wl
->
event_mask
|=
STA_REMOVE_COMPLETE_EVENT_ID
|
INACTIVE_STA_EVENT_ID
;
wl
->
event_mask
|=
STA_REMOVE_COMPLETE_EVENT_ID
;
else
wl
->
event_mask
|=
DUMMY_PACKET_EVENT_ID
;
...
...
drivers/net/wireless/wl12xx/cmd.c
View file @
890641b2
...
...
@@ -76,7 +76,7 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
if
(
time_after
(
jiffies
,
timeout
))
{
wl1271_error
(
"command complete timeout"
);
ret
=
-
ETIMEDOUT
;
goto
out
;
goto
fail
;
}
poll_count
++
;
...
...
@@ -96,14 +96,17 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
status
=
le16_to_cpu
(
cmd
->
status
);
if
(
status
!=
CMD_STATUS_SUCCESS
)
{
wl1271_error
(
"command execute failure %d"
,
status
);
ieee80211_queue_work
(
wl
->
hw
,
&
wl
->
recovery_work
);
ret
=
-
EIO
;
goto
fail
;
}
wl1271_write32
(
wl
,
ACX_REG_INTERRUPT_ACK
,
WL1271_ACX_INTR_CMD_COMPLETE
);
return
0
;
out:
fail:
WARN_ON
(
1
);
ieee80211_queue_work
(
wl
->
hw
,
&
wl
->
recovery_work
);
return
ret
;
}
...
...
@@ -129,6 +132,9 @@ int wl1271_cmd_general_parms(struct wl1271 *wl)
if
(
gp
->
tx_bip_fem_auto_detect
)
answer
=
true
;
/* Override the REF CLK from the NVS with the one from platform data */
gen_parms
->
general_params
.
ref_clock
=
wl
->
ref_clock
;
ret
=
wl1271_cmd_test
(
wl
,
gen_parms
,
sizeof
(
*
gen_parms
),
answer
);
if
(
ret
<
0
)
{
wl1271_warning
(
"CMD_INI_FILE_GENERAL_PARAM failed"
);
...
...
@@ -168,6 +174,10 @@ int wl128x_cmd_general_parms(struct wl1271 *wl)
if
(
gp
->
tx_bip_fem_auto_detect
)
answer
=
true
;
/* Replace REF and TCXO CLKs with the ones from platform data */
gen_parms
->
general_params
.
ref_clock
=
wl
->
ref_clock
;
gen_parms
->
general_params
.
tcxo_ref_clock
=
wl
->
tcxo_clock
;
ret
=
wl1271_cmd_test
(
wl
,
gen_parms
,
sizeof
(
*
gen_parms
),
answer
);
if
(
ret
<
0
)
{
wl1271_warning
(
"CMD_INI_FILE_GENERAL_PARAM failed"
);
...
...
@@ -1070,7 +1080,7 @@ int wl1271_cmd_start_bss(struct wl1271 *wl)
memcpy
(
cmd
->
bssid
,
bss_conf
->
bssid
,
ETH_ALEN
);
cmd
->
aging_period
=
cpu_to_le16
(
wl
->
conf
.
tx
.
ap_aging_period
);
cmd
->
aging_period
=
cpu_to_le16
(
WL1271_AP_DEF_INACTIV_SEC
);
cmd
->
bss_index
=
WL1271_AP_BSS_INDEX
;
cmd
->
global_hlid
=
WL1271_AP_GLOBAL_HLID
;
cmd
->
broadcast_hlid
=
WL1271_AP_BROADCAST_HLID
;
...
...
drivers/net/wireless/wl12xx/conf.h
View file @
890641b2
...
...
@@ -396,12 +396,43 @@ enum {
CONF_SG_TEMP_PARAM_3
,
CONF_SG_TEMP_PARAM_4
,
CONF_SG_TEMP_PARAM_5
,
CONF_SG_PARAMS_MAX
,
/*
* 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_ALL
=
0xff
};
struct
conf_sg_settings
{
u32
params
[
CONF_SG_PARAMS_MAX
];
u32
sta_params
[
CONF_SG_STA_PARAMS_MAX
];
u32
ap_params
[
CONF_SG_AP_PARAMS_MAX
];
u8
state
;
};
...
...
@@ -509,6 +540,12 @@ struct conf_rx_settings {
CONF_HW_BIT_RATE_36MBPS | CONF_HW_BIT_RATE_48MBPS | \
CONF_HW_BIT_RATE_54MBPS)
#define CONF_TX_OFDM_RATES (CONF_HW_BIT_RATE_6MBPS | \
CONF_HW_BIT_RATE_12MBPS | CONF_HW_BIT_RATE_24MBPS | \
CONF_HW_BIT_RATE_36MBPS | CONF_HW_BIT_RATE_48MBPS | \
CONF_HW_BIT_RATE_54MBPS)
/*
* Default rates for management traffic when operating in AP mode. This
* should be configured according to the basic rate set of the AP
...
...
@@ -516,6 +553,13 @@ struct conf_rx_settings {
#define CONF_TX_AP_DEFAULT_MGMT_RATES (CONF_HW_BIT_RATE_1MBPS | \
CONF_HW_BIT_RATE_2MBPS | CONF_HW_BIT_RATE_5_5MBPS)
/*
* Default rates for working as IBSS. use 11b rates
*/
#define CONF_TX_IBSS_DEFAULT_RATES (CONF_HW_BIT_RATE_1MBPS | \
CONF_HW_BIT_RATE_2MBPS | CONF_HW_BIT_RATE_5_5MBPS | \
CONF_HW_BIT_RATE_11MBPS);
struct
conf_tx_rate_class
{
/*
...
...
@@ -667,34 +711,10 @@ struct conf_tx_settings {
struct
conf_tx_ac_category
ac_conf
[
CONF_TX_MAX_AC_COUNT
];
/*
* Configuration for rate classes in AP-mode. These rate classes
* are for the AC TX queues
*/
struct
conf_tx_rate_class
ap_rc_conf
[
CONF_TX_MAX_AC_COUNT
];
/*
* Management TX rate class for AP-mode.
*/
struct
conf_tx_rate_class
ap_mgmt_conf
;
/*
* Broadcast TX rate class for AP-mode.
*/
struct
conf_tx_rate_class
ap_bcst_conf
;
/*
* Allow this number of TX retries to a connected station/AP before an
* AP-mode - allow this number of TX retries to a station before an
* event is triggered from FW.
* In AP-mode the hlids of unreachable stations are given in the
* "sta_tx_retry_exceeded" member in the event mailbox.
*/
u8
max_tx_retries
;
/*
* AP-mode - after this number of seconds a connected station is
* considered inactive.
*/
u16
ap_aging_period
;
u16
ap_max_tx_retries
;
/*
* Configuration for TID parameters.
...
...
@@ -1192,6 +1212,19 @@ struct conf_memory_settings {
u8
tx_min
;
};
struct
conf_fm_coex
{
u8
enable
;
u8
swallow_period
;
u8
n_divider_fref_set_1
;
u8
n_divider_fref_set_2
;
u16
m_divider_fref_set_1
;
u16
m_divider_fref_set_2
;
u32
coex_pll_stabilization_time
;
u16
ldo_stabilization_time
;
u8
fm_disturbed_band_margin
;
u8
swallow_clk_diff
;
};
struct
conf_drv_settings
{
struct
conf_sg_settings
sg
;
struct
conf_rx_settings
rx
;
...
...
@@ -1205,6 +1238,7 @@ struct conf_drv_settings {
struct
conf_ht_setting
ht
;
struct
conf_memory_settings
mem_wl127x
;
struct
conf_memory_settings
mem_wl128x
;
struct
conf_fm_coex
fm_coex
;
u8
hci_io_ds
;
};
...
...
drivers/net/wireless/wl12xx/debugfs.c
View file @
890641b2
...
...
@@ -291,6 +291,241 @@ static const struct file_operations gpio_power_ops = {
.
llseek
=
default_llseek
,
};
static
ssize_t
start_recovery_write
(
struct
file
*
file
,
const
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
wl1271
*
wl
=
file
->
private_data
;
mutex_lock
(
&
wl
->
mutex
);
ieee80211_queue_work
(
wl
->
hw
,
&
wl
->
recovery_work
);
mutex_unlock
(
&
wl
->
mutex
);
return
count
;
}
static
const
struct
file_operations
start_recovery_ops
=
{
.
write
=
start_recovery_write
,
.
open
=
wl1271_open_file_generic
,
.
llseek
=
default_llseek
,
};
static
ssize_t
driver_state_read
(
struct
file
*
file
,
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
wl1271
*
wl
=
file
->
private_data
;
int
res
=
0
;
char
buf
[
1024
];
mutex_lock
(
&
wl
->
mutex
);
#define DRIVER_STATE_PRINT(x, fmt) \
(res += scnprintf(buf + res, sizeof(buf) - res,\
#x " = " fmt "\n", wl->x))
#define DRIVER_STATE_PRINT_LONG(x) DRIVER_STATE_PRINT(x, "%ld")
#define DRIVER_STATE_PRINT_INT(x) DRIVER_STATE_PRINT(x, "%d")
#define DRIVER_STATE_PRINT_STR(x) DRIVER_STATE_PRINT(x, "%s")
#define DRIVER_STATE_PRINT_LHEX(x) DRIVER_STATE_PRINT(x, "0x%lx")
#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
);
DRIVER_STATE_PRINT_INT
(
tx_frames_cnt
);
DRIVER_STATE_PRINT_LHEX
(
tx_frames_map
[
0
]);
DRIVER_STATE_PRINT_INT
(
tx_queue_count
);
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_security_last_seq
);
DRIVER_STATE_PRINT_INT
(
rx_counter
);
DRIVER_STATE_PRINT_INT
(
session_counter
);
DRIVER_STATE_PRINT_INT
(
state
);
DRIVER_STATE_PRINT_INT
(
bss_type
);
DRIVER_STATE_PRINT_INT
(
channel
);
DRIVER_STATE_PRINT_HEX
(
rate_set
);
DRIVER_STATE_PRINT_HEX
(
basic_rate_set
);
DRIVER_STATE_PRINT_HEX
(
basic_rate
);
DRIVER_STATE_PRINT_INT
(
band
);
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
);
DRIVER_STATE_PRINT_INT
(
sg_enabled
);
DRIVER_STATE_PRINT_INT
(
enable_11a
);
DRIVER_STATE_PRINT_INT
(
noise
);
DRIVER_STATE_PRINT_LHEX
(
ap_hlid_map
[
0
]);
DRIVER_STATE_PRINT_INT
(
last_tx_hlid
);
DRIVER_STATE_PRINT_INT
(
ba_support
);
DRIVER_STATE_PRINT_HEX
(
ba_rx_bitmap
);
DRIVER_STATE_PRINT_HEX
(
ap_fw_ps_map
);
DRIVER_STATE_PRINT_LHEX
(
ap_ps_map
);
DRIVER_STATE_PRINT_HEX
(
quirks
);
DRIVER_STATE_PRINT_HEX
(
irq
);
DRIVER_STATE_PRINT_HEX
(
ref_clock
);
DRIVER_STATE_PRINT_HEX
(
tcxo_clock
);
DRIVER_STATE_PRINT_HEX
(
hw_pg_ver
);
DRIVER_STATE_PRINT_HEX
(
platform_quirks
);
DRIVER_STATE_PRINT_HEX
(
chip
.
id
);
DRIVER_STATE_PRINT_STR
(
chip
.
fw_ver_str
);
#undef DRIVER_STATE_PRINT_INT
#undef DRIVER_STATE_PRINT_LONG
#undef DRIVER_STATE_PRINT_HEX
#undef DRIVER_STATE_PRINT_LHEX
#undef DRIVER_STATE_PRINT_STR
#undef DRIVER_STATE_PRINT
mutex_unlock
(
&
wl
->
mutex
);
return
simple_read_from_buffer
(
user_buf
,
count
,
ppos
,
buf
,
res
);
}
static
const
struct
file_operations
driver_state_ops
=
{
.
read
=
driver_state_read
,
.
open
=
wl1271_open_file_generic
,
.
llseek
=
default_llseek
,
};
static
ssize_t
dtim_interval_read
(
struct
file
*
file
,
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
wl1271
*
wl
=
file
->
private_data
;
u8
value
;
if
(
wl
->
conf
.
conn
.
wake_up_event
==
CONF_WAKE_UP_EVENT_DTIM
||
wl
->
conf
.
conn
.
wake_up_event
==
CONF_WAKE_UP_EVENT_N_DTIM
)
value
=
wl
->
conf
.
conn
.
listen_interval
;
else
value
=
0
;
return
wl1271_format_buffer
(
user_buf
,
count
,
ppos
,
"%d
\n
"
,
value
);
}
static
ssize_t
dtim_interval_write
(
struct
file
*
file
,
const
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
wl1271
*
wl
=
file
->
private_data
;
char
buf
[
10
];
size_t
len
;
unsigned
long
value
;
int
ret
;
len
=
min
(
count
,
sizeof
(
buf
)
-
1
);
if
(
copy_from_user
(
buf
,
user_buf
,
len
))
return
-
EFAULT
;
buf
[
len
]
=
'\0'
;
ret
=
kstrtoul
(
buf
,
0
,
&
value
);
if
(
ret
<
0
)
{
wl1271_warning
(
"illegal value for dtim_interval"
);
return
-
EINVAL
;
}
if
(
value
<
1
||
value
>
10
)
{
wl1271_warning
(
"dtim value is not in valid range"
);
return
-
ERANGE
;
}
mutex_lock
(
&
wl
->
mutex
);
wl
->
conf
.
conn
.
listen_interval
=
value
;
/* for some reason there are different event types for 1 and >1 */
if
(
value
==
1
)
wl
->
conf
.
conn
.
wake_up_event
=
CONF_WAKE_UP_EVENT_DTIM
;
else
wl
->
conf
.
conn
.
wake_up_event
=
CONF_WAKE_UP_EVENT_N_DTIM
;
/*
* we don't reconfigure ACX_WAKE_UP_CONDITIONS now, so it will only
* take effect on the next time we enter psm.
*/
mutex_unlock
(
&
wl
->
mutex
);
return
count
;
}
static
const
struct
file_operations
dtim_interval_ops
=
{
.
read
=
dtim_interval_read
,
.
write
=
dtim_interval_write
,
.
open
=
wl1271_open_file_generic
,
.
llseek
=
default_llseek
,
};
static
ssize_t
beacon_interval_read
(
struct
file
*
file
,
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
wl1271
*
wl
=
file
->
private_data
;
u8
value
;
if
(
wl
->
conf
.
conn
.
wake_up_event
==
CONF_WAKE_UP_EVENT_BEACON
||
wl
->
conf
.
conn
.
wake_up_event
==
CONF_WAKE_UP_EVENT_N_BEACONS
)
value
=
wl
->
conf
.
conn
.
listen_interval
;
else
value
=
0
;
return
wl1271_format_buffer
(
user_buf
,
count
,
ppos
,
"%d
\n
"
,
value
);
}
static
ssize_t
beacon_interval_write
(
struct
file
*
file
,
const
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
wl1271
*
wl
=
file
->
private_data
;
char
buf
[
10
];
size_t
len
;
unsigned
long
value
;
int
ret
;
len
=
min
(
count
,
sizeof
(
buf
)
-
1
);
if
(
copy_from_user
(
buf
,
user_buf
,
len
))
return
-
EFAULT
;
buf
[
len
]
=
'\0'
;
ret
=
kstrtoul
(
buf
,
0
,
&
value
);
if
(
ret
<
0
)
{
wl1271_warning
(
"illegal value for beacon_interval"
);
return
-
EINVAL
;
}
if
(
value
<
1
||
value
>
255
)
{
wl1271_warning
(
"beacon interval value is not in valid range"
);
return
-
ERANGE
;
}
mutex_lock
(
&
wl
->
mutex
);
wl
->
conf
.
conn
.
listen_interval
=
value
;
/* for some reason there are different event types for 1 and >1 */
if
(
value
==
1
)
wl
->
conf
.
conn
.
wake_up_event
=
CONF_WAKE_UP_EVENT_BEACON
;
else
wl
->
conf
.
conn
.
wake_up_event
=
CONF_WAKE_UP_EVENT_N_BEACONS
;
/*
* we don't reconfigure ACX_WAKE_UP_CONDITIONS now, so it will only
* take effect on the next time we enter psm.
*/
mutex_unlock
(
&
wl
->
mutex
);
return
count
;
}
static
const
struct
file_operations
beacon_interval_ops
=
{
.
read
=
beacon_interval_read
,
.
write
=
beacon_interval_write
,
.
open
=
wl1271_open_file_generic
,
.
llseek
=
default_llseek
,
};
static
int
wl1271_debugfs_add_files
(
struct
wl1271
*
wl
,
struct
dentry
*
rootdir
)
{
...
...
@@ -399,6 +634,10 @@ static int wl1271_debugfs_add_files(struct wl1271 *wl,
DEBUGFS_ADD
(
excessive_retries
,
rootdir
);
DEBUGFS_ADD
(
gpio_power
,
rootdir
);
DEBUGFS_ADD
(
start_recovery
,
rootdir
);
DEBUGFS_ADD
(
driver_state
,
rootdir
);
DEBUGFS_ADD
(
dtim_interval
,
rootdir
);
DEBUGFS_ADD
(
beacon_interval
,
rootdir
);
return
0
;
...
...
drivers/net/wireless/wl12xx/event.c
View file @
890641b2
...
...
@@ -174,8 +174,6 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
u32
vector
;
bool
beacon_loss
=
false
;
bool
is_ap
=
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
);
bool
disconnect_sta
=
false
;
unsigned
long
sta_bitmap
=
0
;
wl1271_event_mbox_dump
(
mbox
);
...
...
@@ -237,54 +235,9 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
wl1271_tx_dummy_packet
(
wl
);
}
/*
* "TX retries exceeded" has a different meaning according to mode.
* In AP mode the offending station is disconnected. In STA mode we
* report connection loss.
*/
if
(
vector
&
MAX_TX_RETRY_EVENT_ID
)
{
wl1271_debug
(
DEBUG_EVENT
,
"MAX_TX_RETRY_EVENT_ID"
);
if
(
is_ap
)
{
sta_bitmap
|=
le16_to_cpu
(
mbox
->
sta_tx_retry_exceeded
);
disconnect_sta
=
true
;
}
else
{
beacon_loss
=
true
;
}
}
if
((
vector
&
INACTIVE_STA_EVENT_ID
)
&&
is_ap
)
{
wl1271_debug
(
DEBUG_EVENT
,
"INACTIVE_STA_EVENT_ID"
);
sta_bitmap
|=
le16_to_cpu
(
mbox
->
sta_aging_status
);
disconnect_sta
=
true
;
}
if
(
wl
->
vif
&&
beacon_loss
)
ieee80211_connection_loss
(
wl
->
vif
);
if
(
is_ap
&&
disconnect_sta
)
{
u32
num_packets
=
wl
->
conf
.
tx
.
max_tx_retries
;
struct
ieee80211_sta
*
sta
;
const
u8
*
addr
;
int
h
;
for
(
h
=
find_first_bit
(
&
sta_bitmap
,
AP_MAX_LINKS
);
h
<
AP_MAX_LINKS
;
h
=
find_next_bit
(
&
sta_bitmap
,
AP_MAX_LINKS
,
h
+
1
))
{
if
(
!
wl1271_is_active_sta
(
wl
,
h
))
continue
;
addr
=
wl
->
links
[
h
].
addr
;
rcu_read_lock
();
sta
=
ieee80211_find_sta
(
wl
->
vif
,
addr
);
if
(
sta
)
{
wl1271_debug
(
DEBUG_EVENT
,
"remove sta %d"
,
h
);
ieee80211_report_low_ack
(
sta
,
num_packets
);
}
rcu_read_unlock
();
}
}
return
0
;
}
...
...
drivers/net/wireless/wl12xx/event.h
View file @
890641b2
...
...
@@ -58,16 +58,13 @@ enum {
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
),
ROAMING_TRIGGER_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
),
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
),
SOFT_GEMINI_AVALANCHE_EVENT_ID
=
BIT
(
24
),
PLT_RX_CALIBRATION_COMPLETE_EVENT_ID
=
BIT
(
25
),
DBG_EVENT_ID
=
BIT
(
26
),
...
...
@@ -122,11 +119,7 @@ struct event_mailbox {
/* AP FW only */
u8
hlid_removed
;
/* a bitmap of hlids for stations that have been inactive too long */
__le16
sta_aging_status
;
/* a bitmap of hlids for stations which didn't respond to TX */
__le16
sta_tx_retry_exceeded
;
u8
reserved_5
[
24
];
...
...
@@ -137,7 +130,4 @@ void wl1271_event_mbox_config(struct wl1271 *wl);
int
wl1271_event_handle
(
struct
wl1271
*
wl
,
u8
mbox
);
void
wl1271_pspoll_work
(
struct
work_struct
*
work
);
/* Functions from main.c */
bool
wl1271_is_active_sta
(
struct
wl1271
*
wl
,
u8
hlid
);
#endif
drivers/net/wireless/wl12xx/init.c
View file @
890641b2
...
...
@@ -258,7 +258,7 @@ int wl1271_init_phy_config(struct wl1271 *wl)
if
(
ret
<
0
)
return
ret
;
ret
=
wl1271_acx_rts_threshold
(
wl
,
wl
->
conf
.
rx
.
rts_threshold
);
ret
=
wl1271_acx_rts_threshold
(
wl
,
wl
->
hw
->
wiphy
->
rts_threshold
);
if
(
ret
<
0
)
return
ret
;
...
...
@@ -285,7 +285,10 @@ int wl1271_init_pta(struct wl1271 *wl)
{
int
ret
;
ret
=
wl1271_acx_sg_cfg
(
wl
);
if
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
)
ret
=
wl1271_acx_ap_sg_cfg
(
wl
);
else
ret
=
wl1271_acx_sta_sg_cfg
(
wl
);
if
(
ret
<
0
)
return
ret
;
...
...
@@ -351,8 +354,8 @@ static int wl1271_sta_hw_init(struct wl1271 *wl)
if
(
ret
<
0
)
return
ret
;
/*
Bluetooth
WLAN coexistence */
ret
=
wl1271_
init_pta
(
wl
);
/*
FM
WLAN coexistence */
ret
=
wl1271_
acx_fm_coex
(
wl
);
if
(
ret
<
0
)
return
ret
;
...
...
@@ -375,10 +378,6 @@ static int wl1271_sta_hw_init(struct wl1271 *wl)
if
(
ret
<
0
)
return
ret
;
ret
=
wl1271_acx_sta_max_tx_retry
(
wl
);
if
(
ret
<
0
)
return
ret
;
ret
=
wl1271_acx_sta_mem_cfg
(
wl
);
if
(
ret
<
0
)
return
ret
;
...
...
@@ -414,7 +413,7 @@ static int wl1271_sta_hw_init_post_mem(struct wl1271 *wl)
static
int
wl1271_ap_hw_init
(
struct
wl1271
*
wl
)
{
int
ret
,
i
;
int
ret
;
ret
=
wl1271_ap_init_templates_config
(
wl
);
if
(
ret
<
0
)
...
...
@@ -425,27 +424,11 @@ static int wl1271_ap_hw_init(struct wl1271 *wl)
if
(
ret
<
0
)
return
ret
;
/* Configure initial TX rate classes */
for
(
i
=
0
;
i
<
wl
->
conf
.
tx
.
ac_conf_count
;
i
++
)
{
ret
=
wl1271_acx_ap_rate_policy
(
wl
,
&
wl
->
conf
.
tx
.
ap_rc_conf
[
i
],
i
);
if
(
ret
<
0
)
return
ret
;
}
ret
=
wl1271_acx_ap_rate_policy
(
wl
,
&
wl
->
conf
.
tx
.
ap_mgmt_conf
,
ACX_TX_AP_MODE_MGMT_RATE
);
ret
=
wl1271_init_ap_rates
(
wl
);
if
(
ret
<
0
)
return
ret
;
ret
=
wl1271_acx_ap_rate_policy
(
wl
,
&
wl
->
conf
.
tx
.
ap_bcst_conf
,
ACX_TX_AP_MODE_BCST_RATE
);
if
(
ret
<
0
)
return
ret
;
ret
=
wl1271_acx_ap_max_tx_retry
(
wl
);
ret
=
wl1271_acx_max_tx_retry
(
wl
);
if
(
ret
<
0
)
return
ret
;
...
...
@@ -456,7 +439,7 @@ static int wl1271_ap_hw_init(struct wl1271 *wl)
return
0
;
}
static
int
wl1271_ap_hw_init_post_mem
(
struct
wl1271
*
wl
)
int
wl1271_ap_init_templates
(
struct
wl1271
*
wl
)
{
int
ret
;
...
...
@@ -472,6 +455,70 @@ static int wl1271_ap_hw_init_post_mem(struct wl1271 *wl)
if
(
ret
<
0
)
return
ret
;
/*
* when operating as AP we want to receive external beacons for
* configuring ERP protection.
*/
ret
=
wl1271_acx_set_ap_beacon_filter
(
wl
,
false
);
if
(
ret
<
0
)
return
ret
;
return
0
;
}
static
int
wl1271_ap_hw_init_post_mem
(
struct
wl1271
*
wl
)
{
return
wl1271_ap_init_templates
(
wl
);
}
int
wl1271_init_ap_rates
(
struct
wl1271
*
wl
)
{
int
i
,
ret
;
struct
conf_tx_rate_class
rc
;
u32
supported_rates
;
wl1271_debug
(
DEBUG_AP
,
"AP basic rate set: 0x%x"
,
wl
->
basic_rate_set
);
if
(
wl
->
basic_rate_set
==
0
)
return
-
EINVAL
;
rc
.
enabled_rates
=
wl
->
basic_rate_set
;
rc
.
long_retry_limit
=
10
;
rc
.
short_retry_limit
=
10
;
rc
.
aflags
=
0
;
ret
=
wl1271_acx_ap_rate_policy
(
wl
,
&
rc
,
ACX_TX_AP_MODE_MGMT_RATE
);
if
(
ret
<
0
)
return
ret
;
/* use the min basic rate for AP broadcast/multicast */
rc
.
enabled_rates
=
wl1271_tx_min_rate_get
(
wl
);
rc
.
short_retry_limit
=
10
;
rc
.
long_retry_limit
=
10
;
rc
.
aflags
=
0
;
ret
=
wl1271_acx_ap_rate_policy
(
wl
,
&
rc
,
ACX_TX_AP_MODE_BCST_RATE
);
if
(
ret
<
0
)
return
ret
;
/*
* If the basic rates contain OFDM rates, use OFDM only
* rates for unicast TX as well. Else use all supported rates.
*/
if
((
wl
->
basic_rate_set
&
CONF_TX_OFDM_RATES
))
supported_rates
=
CONF_TX_OFDM_RATES
;
else
supported_rates
=
CONF_TX_AP_ENABLED_RATES
;
/* configure unicast TX rate classes */
for
(
i
=
0
;
i
<
wl
->
conf
.
tx
.
ac_conf_count
;
i
++
)
{
rc
.
enabled_rates
=
supported_rates
;
rc
.
short_retry_limit
=
10
;
rc
.
long_retry_limit
=
10
;
rc
.
aflags
=
0
;
ret
=
wl1271_acx_ap_rate_policy
(
wl
,
&
rc
,
i
);
if
(
ret
<
0
)
return
ret
;
}
return
0
;
}
...
...
@@ -567,6 +614,11 @@ int wl1271_hw_init(struct wl1271 *wl)
if
(
ret
<
0
)
return
ret
;
/* Bluetooth WLAN coexistence */
ret
=
wl1271_init_pta
(
wl
);
if
(
ret
<
0
)
return
ret
;
/* Default memory configuration */
ret
=
wl1271_acx_init_mem_config
(
wl
);
if
(
ret
<
0
)
...
...
@@ -606,7 +658,7 @@ int wl1271_hw_init(struct wl1271 *wl)
goto
out_free_memmap
;
/* Default fragmentation threshold */
ret
=
wl1271_acx_frag_threshold
(
wl
,
wl
->
conf
.
tx
.
frag_threshold
);
ret
=
wl1271_acx_frag_threshold
(
wl
,
wl
->
hw
->
wiphy
->
frag_threshold
);
if
(
ret
<
0
)
goto
out_free_memmap
;
...
...
drivers/net/wireless/wl12xx/init.h
View file @
890641b2
...
...
@@ -33,5 +33,7 @@ int wl1271_init_pta(struct wl1271 *wl);
int
wl1271_init_energy_detection
(
struct
wl1271
*
wl
);
int
wl1271_chip_specific_init
(
struct
wl1271
*
wl
);
int
wl1271_hw_init
(
struct
wl1271
*
wl
);
int
wl1271_init_ap_rates
(
struct
wl1271
*
wl
);
int
wl1271_ap_init_templates
(
struct
wl1271
*
wl
);
#endif
drivers/net/wireless/wl12xx/main.c
View file @
890641b2
...
...
@@ -51,7 +51,7 @@
static
struct
conf_drv_settings
default_conf
=
{
.
sg
=
{
.
params
=
{
.
sta_
params
=
{
[
CONF_SG_BT_PER_THRESHOLD
]
=
7500
,
[
CONF_SG_HV3_MAX_OVERRIDE
]
=
0
,
[
CONF_SG_BT_NFS_SAMPLE_INTERVAL
]
=
400
,
...
...
@@ -101,6 +101,61 @@ static struct conf_drv_settings default_conf = {
[
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
,
},
.
state
=
CONF_SG_PROTECTIVE
,
},
.
rx
=
{
...
...
@@ -108,7 +163,7 @@ static struct conf_drv_settings default_conf = {
.
packet_detection_threshold
=
0
,
.
ps_poll_timeout
=
15
,
.
upsd_timeout
=
15
,
.
rts_threshold
=
2347
,
.
rts_threshold
=
IEEE80211_MAX_RTS_THRESHOLD
,
.
rx_cca_threshold
=
0
,
.
irq_blk_threshold
=
0xFFFF
,
.
irq_pkt_threshold
=
0
,
...
...
@@ -154,46 +209,7 @@ static struct conf_drv_settings default_conf = {
.
tx_op_limit
=
1504
,
},
},
.
ap_rc_conf
=
{
[
0
]
=
{
.
enabled_rates
=
CONF_TX_AP_ENABLED_RATES
,
.
short_retry_limit
=
10
,
.
long_retry_limit
=
10
,
.
aflags
=
0
,
},
[
1
]
=
{
.
enabled_rates
=
CONF_TX_AP_ENABLED_RATES
,
.
short_retry_limit
=
10
,
.
long_retry_limit
=
10
,
.
aflags
=
0
,
},
[
2
]
=
{
.
enabled_rates
=
CONF_TX_AP_ENABLED_RATES
,
.
short_retry_limit
=
10
,
.
long_retry_limit
=
10
,
.
aflags
=
0
,
},
[
3
]
=
{
.
enabled_rates
=
CONF_TX_AP_ENABLED_RATES
,
.
short_retry_limit
=
10
,
.
long_retry_limit
=
10
,
.
aflags
=
0
,
},
},
.
ap_mgmt_conf
=
{
.
enabled_rates
=
CONF_TX_AP_DEFAULT_MGMT_RATES
,
.
short_retry_limit
=
10
,
.
long_retry_limit
=
10
,
.
aflags
=
0
,
},
.
ap_bcst_conf
=
{
.
enabled_rates
=
CONF_HW_BIT_RATE_1MBPS
,
.
short_retry_limit
=
10
,
.
long_retry_limit
=
10
,
.
aflags
=
0
,
},
.
max_tx_retries
=
100
,
.
ap_aging_period
=
300
,
.
ap_max_tx_retries
=
100
,
.
tid_conf_count
=
4
,
.
tid_conf
=
{
[
CONF_TX_AC_BE
]
=
{
...
...
@@ -258,7 +274,7 @@ static struct conf_drv_settings default_conf = {
.
bet_enable
=
CONF_BET_MODE_ENABLE
,
.
bet_max_consecutive
=
50
,
.
psm_entry_retries
=
5
,
.
psm_exit_retries
=
255
,
.
psm_exit_retries
=
16
,
.
psm_entry_nullfunc_retries
=
3
,
.
psm_entry_hangover_period
=
1
,
.
keep_alive_interval
=
55000
,
...
...
@@ -305,7 +321,7 @@ static struct conf_drv_settings default_conf = {
.
ssid_profiles
=
1
,
.
rx_block_num
=
70
,
.
tx_min_block_num
=
40
,
.
dynamic_memory
=
0
,
.
dynamic_memory
=
1
,
.
min_req_tx_blocks
=
100
,
.
min_req_rx_blocks
=
22
,
.
tx_min
=
27
,
...
...
@@ -320,10 +336,23 @@ static struct conf_drv_settings default_conf = {
.
min_req_rx_blocks
=
22
,
.
tx_min
=
27
,
},
.
fm_coex
=
{
.
enable
=
true
,
.
swallow_period
=
5
,
.
n_divider_fref_set_1
=
0xff
,
/* default */
.
n_divider_fref_set_2
=
12
,
.
m_divider_fref_set_1
=
148
,
.
m_divider_fref_set_2
=
0xffff
,
/* default */
.
coex_pll_stabilization_time
=
0xffffffff
,
/* default */
.
ldo_stabilization_time
=
0xffff
,
/* default */
.
fm_disturbed_band_margin
=
0xff
,
/* default */
.
swallow_clk_diff
=
0xff
,
/* default */
},
.
hci_io_ds
=
HCI_IO_DS_6MA
,
};
static
void
__wl1271_op_remove_interface
(
struct
wl1271
*
wl
);
static
void
__wl1271_op_remove_interface
(
struct
wl1271
*
wl
,
bool
reset_tx_queues
);
static
void
wl1271_free_ap_keys
(
struct
wl1271
*
wl
);
...
...
@@ -508,6 +537,11 @@ static int wl1271_plt_init(struct wl1271 *wl)
if
(
ret
<
0
)
goto
out_free_memmap
;
/* FM WLAN coexistence */
ret
=
wl1271_acx_fm_coex
(
wl
);
if
(
ret
<
0
)
goto
out_free_memmap
;
/* Energy detection */
ret
=
wl1271_init_energy_detection
(
wl
);
if
(
ret
<
0
)
...
...
@@ -932,15 +966,25 @@ static void wl1271_recovery_work(struct work_struct *work)
if
(
wl
->
state
!=
WL1271_STATE_ON
)
goto
out
;
wl1271_info
(
"Hardware recovery in progress."
);
wl1271_info
(
"Hardware recovery in progress. FW ver: %s pc: 0x%x"
,
wl
->
chip
.
fw_ver_str
,
wl1271_read32
(
wl
,
SCR_PAD4
));
if
(
test_bit
(
WL1271_FLAG_STA_ASSOCIATED
,
&
wl
->
flags
))
ieee80211_connection_loss
(
wl
->
vif
);
/* Prevent spurious TX during FW restart */
ieee80211_stop_queues
(
wl
->
hw
);
/* reboot the chipset */
__wl1271_op_remove_interface
(
wl
);
__wl1271_op_remove_interface
(
wl
,
false
);
ieee80211_restart_hw
(
wl
->
hw
);
/*
* Its safe to enable TX now - the queues are stopped after a request
* to restart the HW.
*/
ieee80211_wake_queues
(
wl
->
hw
);
out:
mutex_unlock
(
&
wl
->
mutex
);
}
...
...
@@ -1011,6 +1055,10 @@ static int wl1271_chip_wakeup(struct wl1271 *wl)
wl1271_debug
(
DEBUG_BOOT
,
"chip id 0x%x (1271 PG20)"
,
wl
->
chip
.
id
);
/* end-of-transaction flag should be set in wl127x AP mode */
if
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
)
wl
->
quirks
|=
WL12XX_QUIRK_END_OF_TRANSACTION
;
ret
=
wl1271_setup
(
wl
);
if
(
ret
<
0
)
goto
out
;
...
...
@@ -1273,7 +1321,7 @@ static struct sk_buff *wl12xx_alloc_dummy_packet(struct wl1271 *wl)
skb
->
priority
=
WL1271_TID_MGMT
;
/* Initialize all fields that might be used */
skb
->
queue_mapping
=
0
;
skb
_set_queue_mapping
(
skb
,
0
)
;
memset
(
IEEE80211_SKB_CB
(
skb
),
0
,
sizeof
(
struct
ieee80211_tx_info
));
return
skb
;
...
...
@@ -1440,7 +1488,8 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
return
ret
;
}
static
void
__wl1271_op_remove_interface
(
struct
wl1271
*
wl
)
static
void
__wl1271_op_remove_interface
(
struct
wl1271
*
wl
,
bool
reset_tx_queues
)
{
int
i
;
...
...
@@ -1486,7 +1535,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl)
mutex_lock
(
&
wl
->
mutex
);
/* let's notify MAC80211 about the remaining pending TX frames */
wl1271_tx_reset
(
wl
);
wl1271_tx_reset
(
wl
,
reset_tx_queues
);
wl1271_power_off
(
wl
);
memset
(
wl
->
bssid
,
0
,
ETH_ALEN
);
...
...
@@ -1547,7 +1596,7 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
*/
if
(
wl
->
vif
)
{
WARN_ON
(
wl
->
vif
!=
vif
);
__wl1271_op_remove_interface
(
wl
);
__wl1271_op_remove_interface
(
wl
,
true
);
}
mutex_unlock
(
&
wl
->
mutex
);
...
...
@@ -2284,7 +2333,7 @@ static int wl1271_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
if
(
ret
<
0
)
goto
out
;
ret
=
wl1271_acx_frag_threshold
(
wl
,
(
u16
)
value
);
ret
=
wl1271_acx_frag_threshold
(
wl
,
value
);
if
(
ret
<
0
)
wl1271_warning
(
"wl1271_op_set_frag_threshold failed: %d"
,
ret
);
...
...
@@ -2312,7 +2361,7 @@ static int wl1271_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
if
(
ret
<
0
)
goto
out
;
ret
=
wl1271_acx_rts_threshold
(
wl
,
(
u16
)
value
);
ret
=
wl1271_acx_rts_threshold
(
wl
,
value
);
if
(
ret
<
0
)
wl1271_warning
(
"wl1271_op_set_rts_threshold failed: %d"
,
ret
);
...
...
@@ -2455,24 +2504,19 @@ static void wl1271_bss_info_changed_ap(struct wl1271 *wl,
if
((
changed
&
BSS_CHANGED_BASIC_RATES
))
{
u32
rates
=
bss_conf
->
basic_rates
;
struct
conf_tx_rate_class
mgmt_rc
;
wl
->
basic_rate_set
=
wl1271_tx_enabled_rates_get
(
wl
,
rates
);
wl
->
basic_rate
=
wl1271_tx_min_rate_get
(
wl
);
wl1271_debug
(
DEBUG_AP
,
"basic rates: 0x%x"
,
wl
->
basic_rate_set
);
/* update the AP management rate policy with the new rates */
mgmt_rc
.
enabled_rates
=
wl
->
basic_rate_set
;
mgmt_rc
.
long_retry_limit
=
10
;
mgmt_rc
.
short_retry_limit
=
10
;
mgmt_rc
.
aflags
=
0
;
ret
=
wl1271_acx_ap_rate_policy
(
wl
,
&
mgmt_rc
,
ACX_TX_AP_MODE_MGMT_RATE
);
ret
=
wl1271_init_ap_rates
(
wl
);
if
(
ret
<
0
)
{
wl1271_error
(
"AP
mgmt
policy change failed %d"
,
ret
);
wl1271_error
(
"AP
rate
policy change failed %d"
,
ret
);
goto
out
;
}
ret
=
wl1271_ap_init_templates
(
wl
);
if
(
ret
<
0
)
goto
out
;
}
ret
=
wl1271_bss_beacon_info_changed
(
wl
,
vif
,
bss_conf
,
changed
);
...
...
@@ -2505,6 +2549,24 @@ static void wl1271_bss_info_changed_ap(struct wl1271 *wl,
}
}
if
(
changed
&
BSS_CHANGED_IBSS
)
{
wl1271_debug
(
DEBUG_ADHOC
,
"ibss_joined: %d"
,
bss_conf
->
ibss_joined
);
if
(
bss_conf
->
ibss_joined
)
{
u32
rates
=
bss_conf
->
basic_rates
;
wl
->
basic_rate_set
=
wl1271_tx_enabled_rates_get
(
wl
,
rates
);
wl
->
basic_rate
=
wl1271_tx_min_rate_get
(
wl
);
/* by default, use 11b rates */
wl
->
rate_set
=
CONF_TX_IBSS_DEFAULT_RATES
;
ret
=
wl1271_acx_sta_rate_policies
(
wl
);
if
(
ret
<
0
)
goto
out
;
}
}
ret
=
wl1271_bss_erp_info_changed
(
wl
,
bss_conf
,
changed
);
if
(
ret
<
0
)
goto
out
;
...
...
@@ -2694,8 +2756,10 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
}
}
else
{
/* use defaults when not associated */
bool
was_assoc
=
!!
test_and_clear_bit
(
WL1271_FLAG_STA_ASSOCIATED
,
&
wl
->
flags
);
clear_bit
(
WL1271_FLAG_STA_STATE_SENT
,
&
wl
->
flags
);
clear_bit
(
WL1271_FLAG_STA_ASSOCIATED
,
&
wl
->
flags
);
wl
->
aid
=
0
;
/* free probe-request template */
...
...
@@ -2721,8 +2785,10 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
goto
out
;
/* restore the bssid filter and go to dummy bssid */
wl1271_unjoin
(
wl
);
wl1271_dummy_join
(
wl
);
if
(
was_assoc
)
{
wl1271_unjoin
(
wl
);
wl1271_dummy_join
(
wl
);
}
}
}
...
...
@@ -2954,12 +3020,6 @@ static void wl1271_free_sta(struct wl1271 *wl, u8 hlid)
__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
)
...
...
@@ -3104,6 +3164,28 @@ static int wl1271_op_ampdu_action(struct ieee80211_hw *hw,
return
ret
;
}
static
bool
wl1271_tx_frames_pending
(
struct
ieee80211_hw
*
hw
)
{
struct
wl1271
*
wl
=
hw
->
priv
;
bool
ret
=
false
;
mutex_lock
(
&
wl
->
mutex
);
if
(
unlikely
(
wl
->
state
==
WL1271_STATE_OFF
))
goto
out
;
/* packets are considered pending if in the TX queue or the FW */
ret
=
(
wl
->
tx_queue_count
>
0
)
||
(
wl
->
tx_frames_cnt
>
0
);
/* the above is appropriate for STA mode for PS purposes */
WARN_ON
(
wl
->
bss_type
!=
BSS_TYPE_STA_BSS
);
out:
mutex_unlock
(
&
wl
->
mutex
);
return
ret
;
}
/* can't be const, mac80211 writes to this */
static
struct
ieee80211_rate
wl1271_rates
[]
=
{
{
.
bitrate
=
10
,
...
...
@@ -3355,6 +3437,7 @@ static const struct ieee80211_ops wl1271_ops = {
.
sta_add
=
wl1271_op_sta_add
,
.
sta_remove
=
wl1271_op_sta_remove
,
.
ampdu_action
=
wl1271_op_ampdu_action
,
.
tx_frames_pending
=
wl1271_tx_frames_pending
,
CFG80211_TESTMODE_CMD
(
wl1271_tm_cmd
)
};
...
...
@@ -3542,6 +3625,7 @@ int wl1271_init_ieee80211(struct wl1271 *wl)
IEEE80211_HW_HAS_RATE_CONTROL
|
IEEE80211_HW_CONNECTION_MONITOR
|
IEEE80211_HW_SUPPORTS_CQM_RSSI
|
IEEE80211_HW_REPORTS_TX_ACK_STATUS
|
IEEE80211_HW_AP_LINK_PS
;
wl
->
hw
->
wiphy
->
cipher_suites
=
cipher_suites
;
...
...
drivers/net/wireless/wl12xx/ps.c
View file @
890641b2
...
...
@@ -43,6 +43,10 @@ void wl1271_elp_work(struct work_struct *work)
if
(
unlikely
(
wl
->
state
==
WL1271_STATE_OFF
))
goto
out
;
/* our work might have been already cancelled */
if
(
unlikely
(
!
test_bit
(
WL1271_FLAG_ELP_REQUESTED
,
&
wl
->
flags
)))
goto
out
;
if
(
test_bit
(
WL1271_FLAG_IN_ELP
,
&
wl
->
flags
)
||
(
!
test_bit
(
WL1271_FLAG_PSM
,
&
wl
->
flags
)
&&
!
test_bit
(
WL1271_FLAG_IDLE
,
&
wl
->
flags
)))
...
...
@@ -61,12 +65,16 @@ void wl1271_elp_work(struct work_struct *work)
/* Routines to toggle sleep mode while in ELP */
void
wl1271_ps_elp_sleep
(
struct
wl1271
*
wl
)
{
if
(
test_bit
(
WL1271_FLAG_PSM
,
&
wl
->
flags
)
||
test_bit
(
WL1271_FLAG_IDLE
,
&
wl
->
flags
))
{
cancel_delayed_work
(
&
wl
->
elp_work
);
ieee80211_queue_delayed_work
(
wl
->
hw
,
&
wl
->
elp_work
,
msecs_to_jiffies
(
ELP_ENTRY_DELAY
));
}
/* we shouldn't get consecutive sleep requests */
if
(
WARN_ON
(
test_and_set_bit
(
WL1271_FLAG_ELP_REQUESTED
,
&
wl
->
flags
)))
return
;
if
(
!
test_bit
(
WL1271_FLAG_PSM
,
&
wl
->
flags
)
&&
!
test_bit
(
WL1271_FLAG_IDLE
,
&
wl
->
flags
))
return
;
ieee80211_queue_delayed_work
(
wl
->
hw
,
&
wl
->
elp_work
,
msecs_to_jiffies
(
ELP_ENTRY_DELAY
));
}
int
wl1271_ps_elp_wakeup
(
struct
wl1271
*
wl
)
...
...
@@ -77,6 +85,16 @@ int wl1271_ps_elp_wakeup(struct wl1271 *wl)
u32
start_time
=
jiffies
;
bool
pending
=
false
;
/*
* we might try to wake up even if we didn't go to sleep
* before (e.g. on boot)
*/
if
(
!
test_and_clear_bit
(
WL1271_FLAG_ELP_REQUESTED
,
&
wl
->
flags
))
return
0
;
/* don't cancel_sync as it might contend for a mutex and deadlock */
cancel_delayed_work
(
&
wl
->
elp_work
);
if
(
!
test_bit
(
WL1271_FLAG_IN_ELP
,
&
wl
->
flags
))
return
0
;
...
...
drivers/net/wireless/wl12xx/rx.c
View file @
890641b2
...
...
@@ -76,12 +76,15 @@ static void wl1271_rx_status(struct wl1271 *wl,
status
->
band
);
if
(
desc
->
flags
&
WL1271_RX_DESC_ENCRYPT_MASK
)
{
status
->
flag
|=
RX_FLAG_IV_STRIPPED
|
RX_FLAG_MMIC_STRIPPED
;
u8
desc_err_code
=
desc
->
status
&
WL1271_RX_DESC_STATUS_MASK
;
if
(
likely
(
!
(
desc
->
status
&
WL1271_RX_DESC_DECRYPT_FAIL
)))
status
->
flag
|=
RX_FLAG_DECRYPTED
;
if
(
unlikely
(
desc
->
status
&
WL1271_RX_DESC_MIC_FAIL
))
status
->
flag
|=
RX_FLAG_IV_STRIPPED
|
RX_FLAG_MMIC_STRIPPED
|
RX_FLAG_DECRYPTED
;
if
(
unlikely
(
desc_err_code
==
WL1271_RX_DESC_MIC_FAIL
))
{
status
->
flag
|=
RX_FLAG_MMIC_ERROR
;
wl1271_warning
(
"Michael MIC error"
);
}
}
}
...
...
@@ -100,6 +103,25 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length)
if
(
unlikely
(
wl
->
state
==
WL1271_STATE_PLT
))
return
-
EINVAL
;
/* the data read starts with the descriptor */
desc
=
(
struct
wl1271_rx_descriptor
*
)
data
;
switch
(
desc
->
status
&
WL1271_RX_DESC_STATUS_MASK
)
{
/* discard corrupted packets */
case
WL1271_RX_DESC_DRIVER_RX_Q_FAIL
:
case
WL1271_RX_DESC_DECRYPT_FAIL
:
wl1271_warning
(
"corrupted packet in RX with status: 0x%x"
,
desc
->
status
&
WL1271_RX_DESC_STATUS_MASK
);
return
-
EINVAL
;
case
WL1271_RX_DESC_SUCCESS
:
case
WL1271_RX_DESC_MIC_FAIL
:
break
;
default:
wl1271_error
(
"invalid RX descriptor status: 0x%x"
,
desc
->
status
&
WL1271_RX_DESC_STATUS_MASK
);
return
-
EINVAL
;
}
skb
=
__dev_alloc_skb
(
length
,
GFP_KERNEL
);
if
(
!
skb
)
{
wl1271_error
(
"Couldn't allocate RX frame"
);
...
...
@@ -109,9 +131,6 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length)
buf
=
skb_put
(
skb
,
length
);
memcpy
(
buf
,
data
,
length
);
/* the data read starts with the descriptor */
desc
=
(
struct
wl1271_rx_descriptor
*
)
buf
;
/* now we pull the descriptor out of the buffer */
skb_pull
(
skb
,
sizeof
(
*
desc
));
...
...
@@ -121,7 +140,8 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length)
wl1271_rx_status
(
wl
,
desc
,
IEEE80211_SKB_RXCB
(
skb
),
beacon
);
wl1271_debug
(
DEBUG_RX
,
"rx skb 0x%p: %d B %s"
,
skb
,
skb
->
len
,
wl1271_debug
(
DEBUG_RX
,
"rx skb 0x%p: %d B %s"
,
skb
,
skb
->
len
-
desc
->
pad_len
,
beacon
?
"beacon"
:
""
);
skb_trim
(
skb
,
skb
->
len
-
desc
->
pad_len
);
...
...
drivers/net/wireless/wl12xx/tx.c
View file @
890641b2
...
...
@@ -65,6 +65,9 @@ static int wl1271_alloc_tx_id(struct wl1271 *wl, struct sk_buff *skb)
static
void
wl1271_free_tx_id
(
struct
wl1271
*
wl
,
int
id
)
{
if
(
__test_and_clear_bit
(
id
,
wl
->
tx_frames_map
))
{
if
(
unlikely
(
wl
->
tx_frames_cnt
==
ACX_TX_DESCRIPTORS
))
clear_bit
(
WL1271_FLAG_FW_TX_BUSY
,
&
wl
->
flags
);
wl
->
tx_frames
[
id
]
=
NULL
;
wl
->
tx_frames_cnt
--
;
}
...
...
@@ -630,7 +633,7 @@ void wl1271_tx_work(struct work_struct *work)
wl1271_tx_work_locked
(
wl
);
wl1271_ps_elp_
wakeu
p
(
wl
);
wl1271_ps_elp_
slee
p
(
wl
);
out:
mutex_unlock
(
&
wl
->
mutex
);
}
...
...
@@ -766,8 +769,8 @@ void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid)
wl1271_handle_tx_low_watermark
(
wl
);
}
/* caller must hold wl->mutex */
void
wl1271_tx_reset
(
struct
wl1271
*
wl
)
/* caller must hold wl->mutex
and TX must be stopped
*/
void
wl1271_tx_reset
(
struct
wl1271
*
wl
,
bool
reset_tx_queues
)
{
int
i
;
struct
sk_buff
*
skb
;
...
...
@@ -803,8 +806,10 @@ void wl1271_tx_reset(struct wl1271 *wl)
/*
* Make sure the driver is at a consistent state, in case this
* function is called from a context other than interface removal.
* This call will always wake the TX queues.
*/
wl1271_handle_tx_low_watermark
(
wl
);
if
(
reset_tx_queues
)
wl1271_handle_tx_low_watermark
(
wl
);
for
(
i
=
0
;
i
<
ACX_TX_DESCRIPTORS
;
i
++
)
{
if
(
wl
->
tx_frames
[
i
]
==
NULL
)
...
...
drivers/net/wireless/wl12xx/tx.h
View file @
890641b2
...
...
@@ -185,7 +185,7 @@ static inline int wl1271_tx_get_queue(int queue)
void
wl1271_tx_work
(
struct
work_struct
*
work
);
void
wl1271_tx_work_locked
(
struct
wl1271
*
wl
);
void
wl1271_tx_complete
(
struct
wl1271
*
wl
);
void
wl1271_tx_reset
(
struct
wl1271
*
wl
);
void
wl1271_tx_reset
(
struct
wl1271
*
wl
,
bool
reset_tx_queues
);
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
);
...
...
drivers/net/wireless/wl12xx/wl12xx.h
View file @
890641b2
...
...
@@ -172,6 +172,7 @@ extern u32 wl12xx_debug_level;
#define WL1271_PS_STA_MAX_BLOCKS (2 * 9)
#define WL1271_AP_BSS_INDEX 0
#define WL1271_AP_DEF_INACTIV_SEC 300
#define WL1271_AP_DEF_BEACON_EXP 20
#define ACX_TX_DESCRIPTORS 32
...
...
@@ -345,6 +346,7 @@ enum wl12xx_flags {
WL1271_FLAG_TX_QUEUE_STOPPED
,
WL1271_FLAG_TX_PENDING
,
WL1271_FLAG_IN_ELP
,
WL1271_FLAG_ELP_REQUESTED
,
WL1271_FLAG_PSM
,
WL1271_FLAG_PSM_REQUESTED
,
WL1271_FLAG_IRQ_RUNNING
,
...
...
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