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