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
376cf5d3
Commit
376cf5d3
authored
Sep 19, 2011
by
John W. Linville
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'for-linville' of
git://github.com/lucacoelho/wl12xx
parents
12e62d6f
045c745f
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
358 additions
and
158 deletions
+358
-158
drivers/net/wireless/wl12xx/Kconfig
drivers/net/wireless/wl12xx/Kconfig
+0
-10
drivers/net/wireless/wl12xx/acx.c
drivers/net/wireless/wl12xx/acx.c
+40
-0
drivers/net/wireless/wl12xx/acx.h
drivers/net/wireless/wl12xx/acx.h
+18
-0
drivers/net/wireless/wl12xx/cmd.c
drivers/net/wireless/wl12xx/cmd.c
+11
-6
drivers/net/wireless/wl12xx/cmd.h
drivers/net/wireless/wl12xx/cmd.h
+7
-0
drivers/net/wireless/wl12xx/conf.h
drivers/net/wireless/wl12xx/conf.h
+15
-8
drivers/net/wireless/wl12xx/debugfs.c
drivers/net/wireless/wl12xx/debugfs.c
+47
-41
drivers/net/wireless/wl12xx/event.c
drivers/net/wireless/wl12xx/event.c
+23
-14
drivers/net/wireless/wl12xx/init.c
drivers/net/wireless/wl12xx/init.c
+5
-0
drivers/net/wireless/wl12xx/main.c
drivers/net/wireless/wl12xx/main.c
+71
-25
drivers/net/wireless/wl12xx/ps.c
drivers/net/wireless/wl12xx/ps.c
+6
-2
drivers/net/wireless/wl12xx/rx.c
drivers/net/wireless/wl12xx/rx.c
+5
-4
drivers/net/wireless/wl12xx/scan.c
drivers/net/wireless/wl12xx/scan.c
+84
-40
drivers/net/wireless/wl12xx/tx.c
drivers/net/wireless/wl12xx/tx.c
+16
-6
drivers/net/wireless/wl12xx/tx.h
drivers/net/wireless/wl12xx/tx.h
+4
-0
drivers/net/wireless/wl12xx/wl12xx.h
drivers/net/wireless/wl12xx/wl12xx.h
+6
-2
No files found.
drivers/net/wireless/wl12xx/Kconfig
View file @
376cf5d3
...
...
@@ -19,16 +19,6 @@ config WL12XX
If you choose to build a module, it will be called wl12xx. Say N if
unsure.
config WL12XX_HT
bool "TI wl12xx 802.11 HT support (EXPERIMENTAL)"
depends on WL12XX && EXPERIMENTAL
default n
---help---
This will enable 802.11 HT support in the wl12xx module.
That configuration is temporary due to the code incomplete and
still in testing process.
config WL12XX_SPI
tristate "TI wl12xx SPI support"
depends on WL12XX && SPI_MASTER
...
...
drivers/net/wireless/wl12xx/acx.c
View file @
376cf5d3
...
...
@@ -1691,3 +1691,43 @@ int wl12xx_acx_set_rate_mgmt_params(struct wl1271 *wl)
kfree
(
acx
);
return
ret
;
}
int
wl12xx_acx_config_hangover
(
struct
wl1271
*
wl
)
{
struct
wl12xx_acx_config_hangover
*
acx
;
struct
conf_hangover_settings
*
conf
=
&
wl
->
conf
.
hangover
;
int
ret
;
wl1271_debug
(
DEBUG_ACX
,
"acx config hangover"
);
acx
=
kzalloc
(
sizeof
(
*
acx
),
GFP_KERNEL
);
if
(
!
acx
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
acx
->
recover_time
=
cpu_to_le32
(
conf
->
recover_time
);
acx
->
hangover_period
=
conf
->
hangover_period
;
acx
->
dynamic_mode
=
conf
->
dynamic_mode
;
acx
->
early_termination_mode
=
conf
->
early_termination_mode
;
acx
->
max_period
=
conf
->
max_period
;
acx
->
min_period
=
conf
->
min_period
;
acx
->
increase_delta
=
conf
->
increase_delta
;
acx
->
decrease_delta
=
conf
->
decrease_delta
;
acx
->
quiet_time
=
conf
->
quiet_time
;
acx
->
increase_time
=
conf
->
increase_time
;
acx
->
window_size
=
acx
->
window_size
;
ret
=
wl1271_cmd_configure
(
wl
,
ACX_CONFIG_HANGOVER
,
acx
,
sizeof
(
*
acx
));
if
(
ret
<
0
)
{
wl1271_warning
(
"acx config hangover failed: %d"
,
ret
);
goto
out
;
}
out:
kfree
(
acx
);
return
ret
;
}
drivers/net/wireless/wl12xx/acx.h
View file @
376cf5d3
...
...
@@ -1144,6 +1144,23 @@ struct wl12xx_acx_set_rate_mgmt_params {
u8
padding2
[
2
];
}
__packed
;
struct
wl12xx_acx_config_hangover
{
struct
acx_header
header
;
__le32
recover_time
;
u8
hangover_period
;
u8
dynamic_mode
;
u8
early_termination_mode
;
u8
max_period
;
u8
min_period
;
u8
increase_delta
;
u8
decrease_delta
;
u8
quiet_time
;
u8
increase_time
;
u8
window_size
;
u8
padding
[
2
];
}
__packed
;
enum
{
ACX_WAKE_UP_CONDITIONS
=
0x0002
,
ACX_MEM_CFG
=
0x0003
,
...
...
@@ -1281,5 +1298,6 @@ int wl1271_acx_config_ps(struct wl1271 *wl);
int
wl1271_acx_set_inconnection_sta
(
struct
wl1271
*
wl
,
u8
*
addr
);
int
wl1271_acx_fm_coex
(
struct
wl1271
*
wl
);
int
wl12xx_acx_set_rate_mgmt_params
(
struct
wl1271
*
wl
);
int
wl12xx_acx_config_hangover
(
struct
wl1271
*
wl
);
#endif
/* __WL1271_ACX_H__ */
drivers/net/wireless/wl12xx/cmd.c
View file @
376cf5d3
...
...
@@ -895,7 +895,7 @@ int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len)
struct
acx_header
*
acx
=
buf
;
int
ret
;
wl1271_debug
(
DEBUG_CMD
,
"cmd configure
"
);
wl1271_debug
(
DEBUG_CMD
,
"cmd configure
(%d)"
,
id
);
acx
->
id
=
cpu_to_le16
(
id
);
...
...
@@ -1413,7 +1413,7 @@ int wl12xx_cmd_set_peer_state(struct wl1271 *wl, u8 hlid)
int
wl12xx_cmd_add_peer
(
struct
wl1271
*
wl
,
struct
ieee80211_sta
*
sta
,
u8
hlid
)
{
struct
wl12xx_cmd_add_peer
*
cmd
;
int
ret
;
int
i
,
ret
;
u32
sta_rates
;
wl1271_debug
(
DEBUG_CMD
,
"cmd add peer %d"
,
(
int
)
hlid
);
...
...
@@ -1424,15 +1424,19 @@ int wl12xx_cmd_add_peer(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
->
sp_len
=
sta
->
max_sp
;
cmd
->
wmm
=
sta
->
wme
?
1
:
0
;
for
(
i
=
0
;
i
<
NUM_ACCESS_CATEGORIES_COPY
;
i
++
)
if
(
sta
->
wme
&&
(
sta
->
uapsd_queues
&
BIT
(
i
)))
cmd
->
psd_type
[
i
]
=
WL1271_PSD_UPSD_TRIGGER
;
else
cmd
->
psd_type
[
i
]
=
WL1271_PSD_LEGACY
;
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
;
...
...
@@ -1440,7 +1444,8 @@ int wl12xx_cmd_add_peer(struct wl1271 *wl, struct ieee80211_sta *sta, u8 hlid)
cmd
->
supported_rates
=
cpu_to_le32
(
wl1271_tx_enabled_rates_get
(
wl
,
sta_rates
));
wl1271_debug
(
DEBUG_CMD
,
"new peer rates: 0x%x"
,
cmd
->
supported_rates
);
wl1271_debug
(
DEBUG_CMD
,
"new peer rates=0x%x queues=0x%x"
,
cmd
->
supported_rates
,
sta
->
uapsd_queues
);
ret
=
wl1271_cmd_send
(
wl
,
CMD_ADD_PEER
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
...
...
drivers/net/wireless/wl12xx/cmd.h
View file @
376cf5d3
...
...
@@ -591,6 +591,13 @@ enum wl12xx_ssid_type {
WL12XX_SSID_TYPE_ANY
=
2
,
};
enum
wl1271_psd_type
{
WL1271_PSD_LEGACY
=
0
,
WL1271_PSD_UPSD_TRIGGER
=
1
,
WL1271_PSD_LEGACY_PSPOLL
=
2
,
WL1271_PSD_SAPSD
=
3
};
struct
wl12xx_cmd_add_peer
{
struct
wl1271_cmd_header
header
;
...
...
drivers/net/wireless/wl12xx/conf.h
View file @
376cf5d3
...
...
@@ -915,14 +915,6 @@ struct conf_conn_settings {
*/
u8
psm_entry_nullfunc_retries
;
/*
* Specifies the time to linger in active mode after successfully
* transmitting the PSM entry null-func frame.
*
* Range 0 - 255 TU's
*/
u8
psm_entry_hangover_period
;
/*
*
* Specifies the interval of the connection keep-alive null-func
...
...
@@ -1236,6 +1228,20 @@ struct conf_rate_policy_settings {
u8
rate_retry_policy
[
ACX_RATE_MGMT_NUM_OF_RATES
];
};
struct
conf_hangover_settings
{
u32
recover_time
;
u8
hangover_period
;
u8
dynamic_mode
;
u8
early_termination_mode
;
u8
max_period
;
u8
min_period
;
u8
increase_delta
;
u8
decrease_delta
;
u8
quiet_time
;
u8
increase_time
;
u8
window_size
;
};
struct
conf_drv_settings
{
struct
conf_sg_settings
sg
;
struct
conf_rx_settings
rx
;
...
...
@@ -1254,6 +1260,7 @@ struct conf_drv_settings {
struct
conf_rx_streaming_settings
rx_streaming
;
struct
conf_fwlog
fwlog
;
struct
conf_rate_policy_settings
rate
;
struct
conf_hangover_settings
hangover
;
u8
hci_io_ds
;
};
...
...
drivers/net/wireless/wl12xx/debugfs.c
View file @
376cf5d3
...
...
@@ -265,18 +265,10 @@ static ssize_t gpio_power_write(struct file *file,
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
);
ret
=
kstrtoul_from_user
(
user_buf
,
count
,
10
,
&
value
);
if
(
ret
<
0
)
{
wl1271_warning
(
"illegal value in gpio_power"
);
return
-
EINVAL
;
...
...
@@ -427,17 +419,10 @@ static ssize_t dtim_interval_write(struct file *file,
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
);
ret
=
kstrtoul_from_user
(
user_buf
,
count
,
10
,
&
value
);
if
(
ret
<
0
)
{
wl1271_warning
(
"illegal value for dtim_interval"
);
return
-
EINVAL
;
...
...
@@ -492,17 +477,10 @@ static ssize_t beacon_interval_write(struct file *file,
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
);
ret
=
kstrtoul_from_user
(
user_buf
,
count
,
10
,
&
value
);
if
(
ret
<
0
)
{
wl1271_warning
(
"illegal value for beacon_interval"
);
return
-
EINVAL
;
...
...
@@ -542,17 +520,10 @@ static ssize_t rx_streaming_interval_write(struct file *file,
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
);
ret
=
kstrtoul_from_user
(
user_buf
,
count
,
10
,
&
value
);
if
(
ret
<
0
)
{
wl1271_warning
(
"illegal value in rx_streaming_interval!"
);
return
-
EINVAL
;
...
...
@@ -601,17 +572,10 @@ static ssize_t rx_streaming_always_write(struct file *file,
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
);
ret
=
kstrtoul_from_user
(
user_buf
,
count
,
10
,
&
value
);
if
(
ret
<
0
)
{
wl1271_warning
(
"illegal value in rx_streaming_write!"
);
return
-
EINVAL
;
...
...
@@ -655,6 +619,47 @@ static const struct file_operations rx_streaming_always_ops = {
.
llseek
=
default_llseek
,
};
static
ssize_t
beacon_filtering_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_filtering!"
);
return
-
EINVAL
;
}
mutex_lock
(
&
wl
->
mutex
);
ret
=
wl1271_ps_elp_wakeup
(
wl
);
if
(
ret
<
0
)
goto
out
;
ret
=
wl1271_acx_beacon_filter_opt
(
wl
,
!!
value
);
wl1271_ps_elp_sleep
(
wl
);
out:
mutex_unlock
(
&
wl
->
mutex
);
return
count
;
}
static
const
struct
file_operations
beacon_filtering_ops
=
{
.
write
=
beacon_filtering_write
,
.
open
=
wl1271_open_file_generic
,
.
llseek
=
default_llseek
,
};
static
int
wl1271_debugfs_add_files
(
struct
wl1271
*
wl
,
struct
dentry
*
rootdir
)
{
...
...
@@ -767,6 +772,7 @@ static int wl1271_debugfs_add_files(struct wl1271 *wl,
DEBUGFS_ADD
(
driver_state
,
rootdir
);
DEBUGFS_ADD
(
dtim_interval
,
rootdir
);
DEBUGFS_ADD
(
beacon_interval
,
rootdir
);
DEBUGFS_ADD
(
beacon_filtering
,
rootdir
);
streaming
=
debugfs_create_dir
(
"rx_streaming"
,
rootdir
);
if
(
!
streaming
||
IS_ERR
(
streaming
))
...
...
drivers/net/wireless/wl12xx/event.c
View file @
376cf5d3
...
...
@@ -171,19 +171,26 @@ static void wl1271_event_rssi_trigger(struct wl1271 *wl,
wl
->
last_rssi_event
=
event
;
}
static
void
wl1271_stop_ba_event
(
struct
wl1271
*
wl
,
u8
ba_allowed
)
static
void
wl1271_stop_ba_event
(
struct
wl1271
*
wl
)
{
/* Convert the value to bool */
wl
->
ba_allowed
=
!!
ba_allowed
;
/*
* Return in case:
* there are not BA open or the event indication is to allowed BA
*/
if
((
!
wl
->
ba_rx_bitmap
)
||
(
wl
->
ba_allowed
))
return
;
if
(
wl
->
bss_type
!=
BSS_TYPE_AP_BSS
)
{
if
(
!
wl
->
ba_rx_bitmap
)
return
;
ieee80211_stop_rx_ba_session
(
wl
->
vif
,
wl
->
ba_rx_bitmap
,
wl
->
bssid
);
}
else
{
int
i
;
struct
wl1271_link
*
lnk
;
for
(
i
=
WL1271_AP_STA_HLID_START
;
i
<
WL12XX_MAX_LINKS
;
i
++
)
{
lnk
=
&
wl
->
links
[
i
];
if
(
!
wl1271_is_active_sta
(
wl
,
i
)
||
!
lnk
->
ba_bitmap
)
continue
;
ieee80211_stop_rx_ba_session
(
wl
->
vif
,
wl
->
ba_rx_bitmap
,
wl
->
bssid
);
ieee80211_stop_rx_ba_session
(
wl
->
vif
,
lnk
->
ba_bitmap
,
lnk
->
addr
);
}
}
}
static
void
wl12xx_event_soft_gemini_sense
(
struct
wl1271
*
wl
,
...
...
@@ -283,12 +290,14 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
wl1271_event_rssi_trigger
(
wl
,
mbox
);
}
if
((
vector
&
BA_SESSION_RX_CONSTRAINT_EVENT_ID
)
&&
!
is_ap
)
{
if
((
vector
&
BA_SESSION_RX_CONSTRAINT_EVENT_ID
))
{
wl1271_debug
(
DEBUG_EVENT
,
"BA_SESSION_RX_CONSTRAINT_EVENT_ID. "
"ba_allowed = 0x%x"
,
mbox
->
rx_ba_allowed
);
if
(
wl
->
vif
)
wl1271_stop_ba_event
(
wl
,
mbox
->
rx_ba_allowed
);
wl
->
ba_allowed
=
!!
mbox
->
rx_ba_allowed
;
if
(
wl
->
vif
&&
!
wl
->
ba_allowed
)
wl1271_stop_ba_event
(
wl
);
}
if
((
vector
&
DUMMY_PACKET_EVENT_ID
))
{
...
...
drivers/net/wireless/wl12xx/init.c
View file @
376cf5d3
...
...
@@ -707,6 +707,11 @@ int wl1271_hw_init(struct wl1271 *wl)
if
(
ret
<
0
)
goto
out_free_memmap
;
/* configure hangover */
ret
=
wl12xx_acx_config_hangover
(
wl
);
if
(
ret
<
0
)
goto
out_free_memmap
;
return
0
;
out_free_memmap:
...
...
drivers/net/wireless/wl12xx/main.c
View file @
376cf5d3
...
...
@@ -239,7 +239,6 @@ static struct conf_drv_settings default_conf = {
.
psm_entry_retries
=
8
,
.
psm_exit_retries
=
16
,
.
psm_entry_nullfunc_retries
=
3
,
.
psm_entry_hangover_period
=
1
,
.
keep_alive_interval
=
55000
,
.
max_listen_interval
=
20
,
},
...
...
@@ -267,8 +266,8 @@ static struct conf_drv_settings default_conf = {
},
.
sched_scan
=
{
/* sched_scan requires dwell times in TU instead of TU/1000 */
.
min_dwell_time_active
=
8
,
.
max_dwell_time_active
=
3
0
,
.
min_dwell_time_active
=
30
,
.
max_dwell_time_active
=
6
0
,
.
dwell_time_passive
=
100
,
.
dwell_time_dfs
=
150
,
.
num_probe_reqs
=
2
,
...
...
@@ -359,9 +358,23 @@ static struct conf_drv_settings default_conf = {
0x00
,
0x00
,
0x00
,
},
},
.
hangover
=
{
.
recover_time
=
0
,
.
hangover_period
=
20
,
.
dynamic_mode
=
1
,
.
early_termination_mode
=
1
,
.
max_period
=
20
,
.
min_period
=
1
,
.
increase_delta
=
1
,
.
decrease_delta
=
2
,
.
quiet_time
=
4
,
.
increase_time
=
1
,
.
window_size
=
16
,
},
};
static
char
*
fwlog_param
;
static
bool
bug_on_recovery
;
static
void
__wl1271_op_remove_interface
(
struct
wl1271
*
wl
,
bool
reset_tx_queues
);
...
...
@@ -757,13 +770,14 @@ static int wl1271_plt_init(struct wl1271 *wl)
static
void
wl12xx_irq_ps_regulate_link
(
struct
wl1271
*
wl
,
u8
hlid
,
u8
tx_pkts
)
{
bool
fw_ps
;
bool
fw_ps
,
single_sta
;
/* only regulate station links */
if
(
hlid
<
WL1271_AP_STA_HLID_START
)
return
;
fw_ps
=
test_bit
(
hlid
,
(
unsigned
long
*
)
&
wl
->
ap_fw_ps_map
);
single_sta
=
(
wl
->
active_sta_count
==
1
);
/*
* Wake up from high level PS if the STA is asleep with too little
...
...
@@ -772,8 +786,12 @@ static void wl12xx_irq_ps_regulate_link(struct wl1271 *wl, u8 hlid, u8 tx_pkts)
if
(
!
fw_ps
||
tx_pkts
<
WL1271_PS_STA_MAX_PACKETS
)
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_pkts
>=
WL1271_PS_STA_MAX_PACKETS
)
/*
* Start high-level PS if the STA is asleep with enough blocks in FW.
* Make an exception if this is the only connected station. In this
* case FW-memory congestion is not a problem.
*/
else
if
(
!
single_sta
&&
fw_ps
&&
tx_pkts
>=
WL1271_PS_STA_MAX_PACKETS
)
wl1271_ps_link_start
(
wl
,
hlid
,
true
);
}
...
...
@@ -1213,6 +1231,8 @@ static void wl1271_recovery_work(struct work_struct *work)
wl1271_info
(
"Hardware recovery in progress. FW ver: %s pc: 0x%x"
,
wl
->
chip
.
fw_ver_str
,
wl1271_read32
(
wl
,
SCR_PAD4
));
BUG_ON
(
bug_on_recovery
);
/*
* Advance security sequence number to overcome potential progress
* in the firmware during recovery. This doens't hurt if the network is
...
...
@@ -1222,9 +1242,6 @@ static void wl1271_recovery_work(struct work_struct *work)
test_bit
(
WL1271_FLAG_AP_STARTED
,
&
wl
->
flags
))
wl
->
tx_security_seq
+=
WL1271_TX_SQN_POST_RECOVERY_PADDING
;
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
);
...
...
@@ -1528,7 +1545,13 @@ static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
int
wl1271_tx_dummy_packet
(
struct
wl1271
*
wl
)
{
unsigned
long
flags
;
int
q
=
wl1271_tx_get_queue
(
skb_get_queue_mapping
(
wl
->
dummy_packet
));
int
q
;
/* no need to queue a new dummy packet if one is already pending */
if
(
test_bit
(
WL1271_FLAG_DUMMY_PACKET_PENDING
,
&
wl
->
flags
))
return
0
;
q
=
wl1271_tx_get_queue
(
skb_get_queue_mapping
(
wl
->
dummy_packet
));
spin_lock_irqsave
(
&
wl
->
wl_lock
,
flags
);
set_bit
(
WL1271_FLAG_DUMMY_PACKET_PENDING
,
&
wl
->
flags
);
...
...
@@ -1802,10 +1825,16 @@ static u8 wl12xx_get_role_type(struct wl1271 *wl)
{
switch
(
wl
->
bss_type
)
{
case
BSS_TYPE_AP_BSS
:
return
WL1271_ROLE_AP
;
if
(
wl
->
p2p
)
return
WL1271_ROLE_P2P_GO
;
else
return
WL1271_ROLE_AP
;
case
BSS_TYPE_STA_BSS
:
return
WL1271_ROLE_STA
;
if
(
wl
->
p2p
)
return
WL1271_ROLE_P2P_CL
;
else
return
WL1271_ROLE_STA
;
case
BSS_TYPE_IBSS
:
return
WL1271_ROLE_IBSS
;
...
...
@@ -1827,7 +1856,7 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
bool
booted
=
false
;
wl1271_debug
(
DEBUG_MAC80211
,
"mac80211 add interface type %d mac %pM"
,
vif
->
type
,
vif
->
addr
);
ieee80211_vif_type_p2p
(
vif
)
,
vif
->
addr
);
mutex_lock
(
&
wl
->
mutex
);
if
(
wl
->
vif
)
{
...
...
@@ -1847,7 +1876,10 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
goto
out
;
}
switch
(
vif
->
type
)
{
switch
(
ieee80211_vif_type_p2p
(
vif
))
{
case
NL80211_IFTYPE_P2P_CLIENT
:
wl
->
p2p
=
1
;
/* fall-through */
case
NL80211_IFTYPE_STATION
:
wl
->
bss_type
=
BSS_TYPE_STA_BSS
;
wl
->
set_bss_type
=
BSS_TYPE_STA_BSS
;
...
...
@@ -1856,6 +1888,9 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
wl
->
bss_type
=
BSS_TYPE_IBSS
;
wl
->
set_bss_type
=
BSS_TYPE_STA_BSS
;
break
;
case
NL80211_IFTYPE_P2P_GO
:
wl
->
p2p
=
1
;
/* fall-through */
case
NL80211_IFTYPE_AP
:
wl
->
bss_type
=
BSS_TYPE_AP_BSS
;
break
;
...
...
@@ -2051,6 +2086,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
wl
->
ssid_len
=
0
;
wl
->
bss_type
=
MAX_BSS_TYPE
;
wl
->
set_bss_type
=
MAX_BSS_TYPE
;
wl
->
p2p
=
0
;
wl
->
band
=
IEEE80211_BAND_2GHZ
;
wl
->
rx_counter
=
0
;
...
...
@@ -2075,6 +2111,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
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
));
wl
->
active_sta_count
=
0
;
/* The system link is always allocated */
__set_bit
(
WL12XX_SYSTEM_HLID
,
wl
->
links_map
);
...
...
@@ -3729,14 +3766,18 @@ static int wl1271_allocate_sta(struct wl1271 *wl,
wl_sta
->
hlid
=
WL1271_AP_STA_HLID_START
+
id
;
*
hlid
=
wl_sta
->
hlid
;
memcpy
(
wl
->
links
[
wl_sta
->
hlid
].
addr
,
sta
->
addr
,
ETH_ALEN
);
wl
->
active_sta_count
++
;
return
0
;
}
static
void
wl1271_free_sta
(
struct
wl1271
*
wl
,
u8
hlid
)
void
wl1271_free_sta
(
struct
wl1271
*
wl
,
u8
hlid
)
{
int
id
=
hlid
-
WL1271_AP_STA_HLID_START
;
if
(
WARN_ON
(
!
test_bit
(
id
,
wl
->
ap_hlid_map
)))
if
(
hlid
<
WL1271_AP_STA_HLID_START
)
return
;
if
(
!
test_bit
(
id
,
wl
->
ap_hlid_map
))
return
;
clear_bit
(
id
,
wl
->
ap_hlid_map
);
...
...
@@ -3745,6 +3786,7 @@ static void wl1271_free_sta(struct wl1271 *wl, u8 hlid)
wl1271_tx_reset_link_queues
(
wl
,
hlid
);
__clear_bit
(
hlid
,
&
wl
->
ap_ps_map
);
__clear_bit
(
hlid
,
(
unsigned
long
*
)
&
wl
->
ap_fw_ps_map
);
wl
->
active_sta_count
--
;
}
static
int
wl1271_op_sta_add
(
struct
ieee80211_hw
*
hw
,
...
...
@@ -4066,7 +4108,6 @@ static const u8 wl1271_rate_to_idx_2ghz[] = {
/* 11n STA capabilities */
#define HW_RX_HIGHEST_RATE 72
#ifdef CONFIG_WL12XX_HT
#define WL12XX_HT_CAP { \
.cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 | \
(1 << IEEE80211_HT_CAP_RX_STBC_SHIFT), \
...
...
@@ -4079,11 +4120,6 @@ static const u8 wl1271_rate_to_idx_2ghz[] = {
.tx_params = IEEE80211_HT_MCS_TX_DEFINED, \
}, \
}
#else
#define WL12XX_HT_CAP { \
.ht_supported = false, \
}
#endif
/* can't be const, mac80211 writes to this */
static
struct
ieee80211_supported_band
wl1271_band_2ghz
=
{
...
...
@@ -4483,15 +4519,19 @@ int wl1271_init_ieee80211(struct wl1271 *wl)
IEEE80211_HW_SUPPORTS_CQM_RSSI
|
IEEE80211_HW_REPORTS_TX_ACK_STATUS
|
IEEE80211_HW_SPECTRUM_MGMT
|
IEEE80211_HW_AP_LINK_PS
;
IEEE80211_HW_AP_LINK_PS
|
IEEE80211_HW_AMPDU_AGGREGATION
|
IEEE80211_HW_TX_AMPDU_SETUP_IN_HW
;
wl
->
hw
->
wiphy
->
cipher_suites
=
cipher_suites
;
wl
->
hw
->
wiphy
->
n_cipher_suites
=
ARRAY_SIZE
(
cipher_suites
);
wl
->
hw
->
wiphy
->
interface_modes
=
BIT
(
NL80211_IFTYPE_STATION
)
|
BIT
(
NL80211_IFTYPE_ADHOC
)
|
BIT
(
NL80211_IFTYPE_AP
);
BIT
(
NL80211_IFTYPE_ADHOC
)
|
BIT
(
NL80211_IFTYPE_AP
)
|
BIT
(
NL80211_IFTYPE_P2P_CLIENT
)
|
BIT
(
NL80211_IFTYPE_P2P_GO
);
wl
->
hw
->
wiphy
->
max_scan_ssids
=
1
;
wl
->
hw
->
wiphy
->
max_sched_scan_ssids
=
8
;
wl
->
hw
->
wiphy
->
max_sched_scan_ssids
=
16
;
wl
->
hw
->
wiphy
->
max_match_sets
=
16
;
/*
* Maximum length of elements in scanning probe request templates
* should be the maximum length possible for a template, without
...
...
@@ -4500,6 +4540,8 @@ int wl1271_init_ieee80211(struct wl1271 *wl)
wl
->
hw
->
wiphy
->
max_scan_ie_len
=
WL1271_CMD_TEMPL_DFLT_SIZE
-
sizeof
(
struct
ieee80211_header
);
wl
->
hw
->
wiphy
->
flags
|=
WIPHY_FLAG_AP_UAPSD
;
/* make sure all our channels fit in the scanned_ch bitmask */
BUILD_BUG_ON
(
ARRAY_SIZE
(
wl1271_channels
)
+
ARRAY_SIZE
(
wl1271_channels_5ghz
)
>
...
...
@@ -4625,6 +4667,7 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
wl
->
session_counter
=
0
;
wl
->
ap_bcast_hlid
=
WL12XX_INVALID_LINK_ID
;
wl
->
ap_global_hlid
=
WL12XX_INVALID_LINK_ID
;
wl
->
active_sta_count
=
0
;
setup_timer
(
&
wl
->
rx_streaming_timer
,
wl1271_rx_streaming_timer
,
(
unsigned
long
)
wl
);
wl
->
fwlog_size
=
0
;
...
...
@@ -4776,6 +4819,9 @@ module_param_named(fwlog, fwlog_param, charp, 0);
MODULE_PARM_DESC
(
keymap
,
"FW logger options: continuous, ondemand, dbgpins or disable"
);
module_param
(
bug_on_recovery
,
bool
,
S_IRUSR
|
S_IWUSR
);
MODULE_PARM_DESC
(
bug_on_recovery
,
"BUG() on fw recovery"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_AUTHOR
(
"Luciano Coelho <coelho@ti.com>"
);
MODULE_AUTHOR
(
"Juuso Oikarinen <juuso.oikarinen@nokia.com>"
);
drivers/net/wireless/wl12xx/ps.c
View file @
376cf5d3
...
...
@@ -199,15 +199,19 @@ static void wl1271_ps_filter_frames(struct wl1271 *wl, u8 hlid)
unsigned
long
flags
;
int
filtered
[
NUM_TX_QUEUES
];
/* filter all frames currently
the low level queu
s for this hlid */
/* filter all frames currently
in the low level queue
s for this hlid */
for
(
i
=
0
;
i
<
NUM_TX_QUEUES
;
i
++
)
{
filtered
[
i
]
=
0
;
while
((
skb
=
skb_dequeue
(
&
wl
->
links
[
hlid
].
tx_queue
[
i
])))
{
filtered
[
i
]
++
;
if
(
WARN_ON
(
wl12xx_is_dummy_packet
(
wl
,
skb
)))
continue
;
info
=
IEEE80211_SKB_CB
(
skb
);
info
->
flags
|=
IEEE80211_TX_STAT_TX_FILTERED
;
info
->
status
.
rates
[
0
].
idx
=
-
1
;
ieee80211_tx_status_ni
(
wl
->
hw
,
skb
);
filtered
[
i
]
++
;
}
}
...
...
drivers/net/wireless/wl12xx/rx.c
View file @
376cf5d3
...
...
@@ -66,11 +66,9 @@ static void wl1271_rx_status(struct wl1271 *wl,
status
->
rate_idx
=
wl1271_rate_to_idx
(
desc
->
rate
,
status
->
band
);
#ifdef CONFIG_WL12XX_HT
/* 11n support */
if
(
desc
->
rate
<=
CONF_HW_RXTX_RATE_MCS0
)
status
->
flag
|=
RX_FLAG_HT
;
#endif
status
->
signal
=
desc
->
rssi
;
...
...
@@ -107,6 +105,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
u8
beacon
=
0
;
u8
is_data
=
0
;
u8
reserved
=
unaligned
?
NET_IP_ALIGN
:
0
;
u16
seq_num
;
/*
* In PLT mode we seem to get frames and mac80211 warns about them,
...
...
@@ -169,9 +168,11 @@ 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
,
seq_num
=
(
le16_to_cpu
(
hdr
->
seq_ctrl
)
&
IEEE80211_SCTL_SEQ
)
>>
4
;
wl1271_debug
(
DEBUG_RX
,
"rx skb 0x%p: %d B %s seq %d"
,
skb
,
skb
->
len
-
desc
->
pad_len
,
beacon
?
"beacon"
:
""
);
beacon
?
"beacon"
:
""
,
seq_num
);
skb_trim
(
skb
,
skb
->
len
-
desc
->
pad_len
);
...
...
drivers/net/wireless/wl12xx/scan.c
View file @
376cf5d3
...
...
@@ -65,8 +65,9 @@ void wl1271_scan_complete_work(struct work_struct *work)
/* 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
)))
{
if
(((
is_sta
&&
!
test_bit
(
WL1271_FLAG_STA_ASSOCIATED
,
&
wl
->
flags
))
||
(
is_ibss
&&
!
test_bit
(
WL1271_FLAG_IBSS_JOINED
,
&
wl
->
flags
)))
&&
!
test_bit
(
wl
->
dev_role_id
,
wl
->
roc_map
))
{
/* restore remain on channel */
wl12xx_cmd_role_start_dev
(
wl
);
wl12xx_roc
(
wl
,
wl
->
dev_role_id
);
...
...
@@ -164,9 +165,6 @@ static int wl1271_scan_send(struct wl1271 *wl, enum ieee80211_band band,
goto
out
;
}
/* We always use high priority scans */
scan_options
=
WL1271_SCAN_OPT_PRIORITY_HIGH
;
/* No SSIDs means that we have a forced passive scan */
if
(
passive
||
wl
->
scan
.
req
->
n_ssids
==
0
)
scan_options
|=
WL1271_SCAN_OPT_PASSIVE
;
...
...
@@ -473,34 +471,86 @@ wl1271_scan_sched_scan_channels(struct wl1271 *wl,
cfg
->
passive
[
2
]
||
cfg
->
active
[
2
];
}
/* Returns 0 if no wildcard is used, 1 if wildcard is used or a
* negative value on error */
/* Returns the scan type to be used or a negative value on error */
static
int
wl12xx_scan_sched_scan_ssid_list
(
struct
wl1271
*
wl
,
struct
cfg80211_sched_scan_request
*
req
)
{
struct
wl1271_cmd_sched_scan_ssid_list
*
cmd
=
NULL
;
struct
cfg80211_ssid
*
ssid
=
req
->
ssids
;
int
ret
,
wildcard
=
0
;
struct
cfg80211_match_set
*
sets
=
req
->
match_sets
;
struct
cfg80211_ssid
*
ssids
=
req
->
ssids
;
int
ret
=
0
,
type
,
i
,
j
,
n_match_ssids
=
0
;
wl1271_debug
(
DEBUG_CMD
,
"cmd sched scan ssid list"
);
/* count the match sets that contain SSIDs */
for
(
i
=
0
;
i
<
req
->
n_match_sets
;
i
++
)
if
(
sets
[
i
].
ssid
.
ssid_len
>
0
)
n_match_ssids
++
;
/* No filter, no ssids or only bcast ssid */
if
(
!
n_match_ssids
&&
(
!
req
->
n_ssids
||
(
req
->
n_ssids
==
1
&&
req
->
ssids
[
0
].
ssid_len
==
0
)))
{
type
=
SCAN_SSID_FILTER_ANY
;
goto
out
;
}
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
return
-
ENOMEM
;
if
(
!
cmd
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
if
(
!
n_match_ssids
)
{
/* No filter, with ssids */
type
=
SCAN_SSID_FILTER_DISABLED
;
for
(
i
=
0
;
i
<
req
->
n_ssids
;
i
++
)
{
cmd
->
ssids
[
cmd
->
n_ssids
].
type
=
(
ssids
[
i
].
ssid_len
)
?
SCAN_SSID_TYPE_HIDDEN
:
SCAN_SSID_TYPE_PUBLIC
;
cmd
->
ssids
[
cmd
->
n_ssids
].
len
=
ssids
[
i
].
ssid_len
;
memcpy
(
cmd
->
ssids
[
cmd
->
n_ssids
].
ssid
,
ssids
[
i
].
ssid
,
ssids
[
i
].
ssid_len
);
cmd
->
n_ssids
++
;
}
}
else
{
type
=
SCAN_SSID_FILTER_LIST
;
/* Add all SSIDs from the filters */
for
(
i
=
0
;
i
<
req
->
n_match_sets
;
i
++
)
{
/* ignore sets without SSIDs */
if
(
!
sets
[
i
].
ssid
.
ssid_len
)
continue
;
while
((
cmd
->
n_ssids
<
req
->
n_ssids
)
&&
ssid
)
{
if
(
ssid
->
ssid_len
==
0
)
{
wildcard
=
1
;
cmd
->
ssids
[
cmd
->
n_ssids
].
type
=
SCAN_SSID_TYPE_PUBLIC
;
}
else
{
cmd
->
ssids
[
cmd
->
n_ssids
].
type
=
SCAN_SSID_TYPE_HIDDEN
;
cmd
->
ssids
[
cmd
->
n_ssids
].
len
=
sets
[
i
].
ssid
.
ssid_len
;
memcpy
(
cmd
->
ssids
[
cmd
->
n_ssids
].
ssid
,
sets
[
i
].
ssid
.
ssid
,
sets
[
i
].
ssid
.
ssid_len
);
cmd
->
n_ssids
++
;
}
if
((
req
->
n_ssids
>
1
)
||
(
req
->
n_ssids
==
1
&&
req
->
ssids
[
0
].
ssid_len
>
0
))
{
/*
* Mark all the SSIDs passed in the SSID list as HIDDEN,
* so they're used in probe requests.
*/
for
(
i
=
0
;
i
<
req
->
n_ssids
;
i
++
)
{
for
(
j
=
0
;
j
<
cmd
->
n_ssids
;
j
++
)
if
(
!
memcmp
(
req
->
ssids
[
i
].
ssid
,
cmd
->
ssids
[
j
].
ssid
,
req
->
ssids
[
i
].
ssid_len
))
{
cmd
->
ssids
[
j
].
type
=
SCAN_SSID_TYPE_HIDDEN
;
break
;
}
/* Fail if SSID isn't present in the filters */
if
(
j
==
req
->
n_ssids
)
{
ret
=
-
EINVAL
;
goto
out_free
;
}
}
}
cmd
->
ssids
[
cmd
->
n_ssids
].
len
=
ssid
->
ssid_len
;
memcpy
(
cmd
->
ssids
[
cmd
->
n_ssids
].
ssid
,
ssid
->
ssid
,
ssid
->
ssid_len
);
ssid
++
;
cmd
->
n_ssids
++
;
}
wl1271_dump
(
DEBUG_SCAN
,
"SSID_LIST: "
,
cmd
,
sizeof
(
*
cmd
));
...
...
@@ -509,13 +559,15 @@ wl12xx_scan_sched_scan_ssid_list(struct wl1271 *wl,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_error
(
"cmd sched scan ssid list failed"
);
goto
out
;
goto
out
_free
;
}
ret
=
wildcard
;
out:
out_free:
kfree
(
cmd
);
return
ret
;
out:
if
(
ret
<
0
)
return
ret
;
return
type
;
}
int
wl1271_scan_sched_scan_config
(
struct
wl1271
*
wl
,
...
...
@@ -550,21 +602,13 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl,
cfg
->
intervals
[
i
]
=
cpu_to_le32
(
req
->
interval
);
cfg
->
ssid_len
=
0
;
if
(
req
->
n_ssids
==
0
)
{
wl1271_debug
(
DEBUG_SCAN
,
"using SCAN_SSID_FILTER_ANY"
);
cfg
->
filter_type
=
SCAN_SSID_FILTER_ANY
;
}
else
{
ret
=
wl12xx_scan_sched_scan_ssid_list
(
wl
,
req
);
if
(
ret
<
0
)
goto
out
;
if
(
ret
)
{
wl1271_debug
(
DEBUG_SCAN
,
"using SCAN_SSID_FILTER_DISABLED"
);
cfg
->
filter_type
=
SCAN_SSID_FILTER_DISABLED
;
}
else
{
wl1271_debug
(
DEBUG_SCAN
,
"using SCAN_SSID_FILTER_LIST"
);
cfg
->
filter_type
=
SCAN_SSID_FILTER_LIST
;
}
}
ret
=
wl12xx_scan_sched_scan_ssid_list
(
wl
,
req
);
if
(
ret
<
0
)
goto
out
;
cfg
->
filter_type
=
ret
;
wl1271_debug
(
DEBUG_SCAN
,
"filter_type = %d"
,
cfg
->
filter_type
);
if
(
!
wl1271_scan_sched_scan_channels
(
wl
,
req
,
cfg
))
{
wl1271_error
(
"scan channel list is empty"
);
...
...
drivers/net/wireless/wl12xx/tx.c
View file @
376cf5d3
...
...
@@ -30,6 +30,7 @@
#include "reg.h"
#include "ps.h"
#include "tx.h"
#include "event.h"
static
int
wl1271_set_default_wep_key
(
struct
wl1271
*
wl
,
u8
id
)
{
...
...
@@ -125,25 +126,31 @@ 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
;
bool
fw_ps
,
single_sta
;
u8
tx_pkts
;
/* only regulate station links */
if
(
hlid
<
WL1271_AP_STA_HLID_START
)
return
;
if
(
WARN_ON
(
!
wl1271_is_active_sta
(
wl
,
hlid
)))
return
;
fw_ps
=
test_bit
(
hlid
,
(
unsigned
long
*
)
&
wl
->
ap_fw_ps_map
);
tx_pkts
=
wl
->
links
[
hlid
].
allocated_pkts
;
single_sta
=
(
wl
->
active_sta_count
==
1
);
/*
* 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.
* Make an exception if this is the only connected station. In this
* case FW-memory congestion is not a problem.
*/
if
(
fw_ps
&&
tx_pkts
>=
WL1271_PS_STA_MAX_PACKETS
)
if
(
!
single_sta
&&
fw_ps
&&
tx_pkts
>=
WL1271_PS_STA_MAX_PACKETS
)
wl1271_ps_link_start
(
wl
,
hlid
,
true
);
}
static
bool
wl12xx_is_dummy_packet
(
struct
wl1271
*
wl
,
struct
sk_buff
*
skb
)
bool
wl12xx_is_dummy_packet
(
struct
wl1271
*
wl
,
struct
sk_buff
*
skb
)
{
return
wl
->
dummy_packet
==
skb
;
}
...
...
@@ -453,7 +460,6 @@ u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set)
rate_set
>>=
1
;
}
#ifdef CONFIG_WL12XX_HT
/* MCS rates indication are on bits 16 - 23 */
rate_set
>>=
HW_HT_RATES_OFFSET
-
band
->
n_bitrates
;
...
...
@@ -462,7 +468,6 @@ u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set)
enabled_rates
|=
(
CONF_HW_BIT_RATE_MCS_0
<<
bit
);
rate_set
>>=
1
;
}
#endif
return
enabled_rates
;
}
...
...
@@ -886,6 +891,7 @@ void wl1271_tx_reset(struct wl1271 *wl, bool reset_tx_queues)
/* TX failure */
if
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
)
{
for
(
i
=
0
;
i
<
AP_MAX_LINKS
;
i
++
)
{
wl1271_free_sta
(
wl
,
i
);
wl1271_tx_reset_link_queues
(
wl
,
i
);
wl
->
links
[
i
].
allocated_pkts
=
0
;
wl
->
links
[
i
].
prev_freed_pkts
=
0
;
...
...
@@ -905,10 +911,14 @@ void wl1271_tx_reset(struct wl1271 *wl, bool reset_tx_queues)
ieee80211_tx_status_ni
(
wl
->
hw
,
skb
);
}
}
wl
->
tx_queue_count
[
i
]
=
0
;
}
wl
->
ba_rx_bitmap
=
0
;
}
for
(
i
=
0
;
i
<
NUM_TX_QUEUES
;
i
++
)
wl
->
tx_queue_count
[
i
]
=
0
;
wl
->
stopped_queues_map
=
0
;
/*
...
...
drivers/net/wireless/wl12xx/tx.h
View file @
376cf5d3
...
...
@@ -214,5 +214,9 @@ u32 wl1271_tx_min_rate_get(struct wl1271 *wl);
u8
wl12xx_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
);
bool
wl12xx_is_dummy_packet
(
struct
wl1271
*
wl
,
struct
sk_buff
*
skb
);
/* from main.c */
void
wl1271_free_sta
(
struct
wl1271
*
wl
,
u8
hlid
);
#endif
drivers/net/wireless/wl12xx/wl12xx.h
View file @
376cf5d3
...
...
@@ -234,14 +234,14 @@ struct wl1271_stats {
#define NUM_TX_QUEUES 4
#define NUM_RX_PKT_DESC 8
#define AP_MAX_STATIONS
5
#define AP_MAX_STATIONS
8
/* 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
)
#define AP_MAX_LINKS (AP_MAX_STATIONS +
WL1271_AP_STA_HLID_START
)
/* FW status registers */
struct
wl12xx_fw_status
{
...
...
@@ -402,6 +402,7 @@ struct wl1271 {
u8
mac_addr
[
ETH_ALEN
];
u8
bss_type
;
u8
set_bss_type
;
u8
p2p
;
/* we are using p2p role */
u8
ssid
[
IEEE80211_MAX_SSID_LEN
+
1
];
u8
ssid_len
;
int
channel
;
...
...
@@ -626,6 +627,9 @@ struct wl1271 {
/* number of currently active RX BA sessions */
int
ba_rx_session_count
;
/* AP-mode - number of currently connected stations */
int
active_sta_count
;
};
struct
wl1271_station
{
...
...
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