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
c21a7d66
Commit
c21a7d66
authored
Oct 03, 2013
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
d819c6cf
f2cede49
Changes
11
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
342 additions
and
87 deletions
+342
-87
drivers/net/wireless/ti/wl18xx/main.c
drivers/net/wireless/ti/wl18xx/main.c
+89
-6
drivers/net/wireless/ti/wl18xx/reg.h
drivers/net/wireless/ti/wl18xx/reg.h
+23
-10
drivers/net/wireless/ti/wlcore/cmd.c
drivers/net/wireless/ti/wlcore/cmd.c
+34
-24
drivers/net/wireless/ti/wlcore/main.c
drivers/net/wireless/ti/wlcore/main.c
+131
-25
drivers/net/wireless/ti/wlcore/ps.c
drivers/net/wireless/ti/wlcore/ps.c
+4
-0
drivers/net/wireless/ti/wlcore/scan.c
drivers/net/wireless/ti/wlcore/scan.c
+13
-14
drivers/net/wireless/ti/wlcore/testmode.c
drivers/net/wireless/ti/wlcore/testmode.c
+11
-2
drivers/net/wireless/ti/wlcore/tx.c
drivers/net/wireless/ti/wlcore/tx.c
+21
-6
drivers/net/wireless/ti/wlcore/tx.h
drivers/net/wireless/ti/wlcore/tx.h
+3
-0
drivers/net/wireless/ti/wlcore/wlcore.h
drivers/net/wireless/ti/wlcore/wlcore.h
+2
-0
drivers/net/wireless/ti/wlcore/wlcore_i.h
drivers/net/wireless/ti/wlcore/wlcore_i.h
+11
-0
No files found.
drivers/net/wireless/ti/wl18xx/main.c
View file @
c21a7d66
...
...
@@ -623,6 +623,18 @@ static const int wl18xx_rtable[REG_TABLE_LEN] = {
[
REG_RAW_FW_STATUS_ADDR
]
=
WL18XX_FW_STATUS_ADDR
,
};
static
const
struct
wl18xx_clk_cfg
wl18xx_clk_table_coex
[
NUM_CLOCK_CONFIGS
]
=
{
[
CLOCK_CONFIG_16_2_M
]
=
{
8
,
121
,
0
,
0
,
false
},
[
CLOCK_CONFIG_16_368_M
]
=
{
8
,
120
,
0
,
0
,
false
},
[
CLOCK_CONFIG_16_8_M
]
=
{
8
,
117
,
0
,
0
,
false
},
[
CLOCK_CONFIG_19_2_M
]
=
{
10
,
128
,
0
,
0
,
false
},
[
CLOCK_CONFIG_26_M
]
=
{
11
,
104
,
0
,
0
,
false
},
[
CLOCK_CONFIG_32_736_M
]
=
{
8
,
120
,
0
,
0
,
false
},
[
CLOCK_CONFIG_33_6_M
]
=
{
8
,
117
,
0
,
0
,
false
},
[
CLOCK_CONFIG_38_468_M
]
=
{
10
,
128
,
0
,
0
,
false
},
[
CLOCK_CONFIG_52_M
]
=
{
11
,
104
,
0
,
0
,
false
},
};
static
const
struct
wl18xx_clk_cfg
wl18xx_clk_table
[
NUM_CLOCK_CONFIGS
]
=
{
[
CLOCK_CONFIG_16_2_M
]
=
{
7
,
104
,
801
,
4
,
true
},
[
CLOCK_CONFIG_16_368_M
]
=
{
9
,
132
,
3751
,
4
,
true
},
...
...
@@ -704,6 +716,23 @@ static int wl18xx_set_clk(struct wl1271 *wl)
wl18xx_clk_table
[
clk_freq
].
p
,
wl18xx_clk_table
[
clk_freq
].
q
,
wl18xx_clk_table
[
clk_freq
].
swallow
?
"swallow"
:
"spit"
);
/* coex PLL configuration */
ret
=
wl18xx_top_reg_write
(
wl
,
PLLSH_COEX_PLL_N
,
wl18xx_clk_table_coex
[
clk_freq
].
n
);
if
(
ret
<
0
)
goto
out
;
ret
=
wl18xx_top_reg_write
(
wl
,
PLLSH_COEX_PLL_M
,
wl18xx_clk_table_coex
[
clk_freq
].
m
);
if
(
ret
<
0
)
goto
out
;
/* bypass the swallowing logic */
ret
=
wl18xx_top_reg_write
(
wl
,
PLLSH_COEX_PLL_SWALLOW_EN
,
PLLSH_COEX_PLL_SWALLOW_EN_VAL1
);
if
(
ret
<
0
)
goto
out
;
ret
=
wl18xx_top_reg_write
(
wl
,
PLLSH_WCS_PLL_N
,
wl18xx_clk_table
[
clk_freq
].
n
);
if
(
ret
<
0
)
...
...
@@ -745,6 +774,30 @@ static int wl18xx_set_clk(struct wl1271 *wl)
PLLSH_WCS_PLL_SWALLOW_EN_VAL2
);
}
/* choose WCS PLL */
ret
=
wl18xx_top_reg_write
(
wl
,
PLLSH_WL_PLL_SEL
,
PLLSH_WL_PLL_SEL_WCS_PLL
);
if
(
ret
<
0
)
goto
out
;
/* enable both PLLs */
ret
=
wl18xx_top_reg_write
(
wl
,
PLLSH_WL_PLL_EN
,
PLLSH_WL_PLL_EN_VAL1
);
if
(
ret
<
0
)
goto
out
;
udelay
(
1000
);
/* disable coex PLL */
ret
=
wl18xx_top_reg_write
(
wl
,
PLLSH_WL_PLL_EN
,
PLLSH_WL_PLL_EN_VAL2
);
if
(
ret
<
0
)
goto
out
;
/* reset the swallowing logic */
ret
=
wl18xx_top_reg_write
(
wl
,
PLLSH_COEX_PLL_SWALLOW_EN
,
PLLSH_COEX_PLL_SWALLOW_EN_VAL2
);
if
(
ret
<
0
)
goto
out
;
out:
return
ret
;
}
...
...
@@ -1175,16 +1228,48 @@ static u32 wl18xx_ap_get_mimo_wide_rate_mask(struct wl1271 *wl,
}
}
static
const
char
*
wl18xx_rdl_name
(
enum
wl18xx_rdl_num
rdl_num
)
{
switch
(
rdl_num
)
{
case
RDL_1_HP
:
return
"183xH"
;
case
RDL_2_SP
:
return
"183x or 180x"
;
case
RDL_3_HP
:
return
"187xH"
;
case
RDL_4_SP
:
return
"187x"
;
case
RDL_5_SP
:
return
"RDL11 - Not Supported"
;
case
RDL_6_SP
:
return
"180xD"
;
case
RDL_7_SP
:
return
"RDL13 - Not Supported (1893Q)"
;
case
RDL_8_SP
:
return
"18xxQ"
;
case
RDL_NONE
:
return
"UNTRIMMED"
;
default:
return
"UNKNOWN"
;
}
}
static
int
wl18xx_get_pg_ver
(
struct
wl1271
*
wl
,
s8
*
ver
)
{
u32
fuse
;
s8
rom
=
0
,
metal
=
0
,
pg_ver
=
0
,
rdl_ver
=
0
;
s8
rom
=
0
,
metal
=
0
,
pg_ver
=
0
,
rdl_ver
=
0
,
package_type
=
0
;
int
ret
;
ret
=
wlcore_set_partition
(
wl
,
&
wl
->
ptable
[
PART_TOP_PRCM_ELP_SOC
]);
if
(
ret
<
0
)
goto
out
;
ret
=
wlcore_read32
(
wl
,
WL18XX_REG_FUSE_DATA_2_3
,
&
fuse
);
if
(
ret
<
0
)
goto
out
;
package_type
=
(
fuse
>>
WL18XX_PACKAGE_TYPE_OFFSET
)
&
1
;
ret
=
wlcore_read32
(
wl
,
WL18XX_REG_FUSE_DATA_1_3
,
&
fuse
);
if
(
ret
<
0
)
goto
out
;
...
...
@@ -1192,7 +1277,7 @@ static int wl18xx_get_pg_ver(struct wl1271 *wl, s8 *ver)
pg_ver
=
(
fuse
&
WL18XX_PG_VER_MASK
)
>>
WL18XX_PG_VER_OFFSET
;
rom
=
(
fuse
&
WL18XX_ROM_VER_MASK
)
>>
WL18XX_ROM_VER_OFFSET
;
if
(
rom
<=
0xE
)
if
(
(
rom
<=
0xE
)
&&
(
package_type
==
WL18XX_PACKAGE_TYPE_WSP
)
)
metal
=
(
fuse
&
WL18XX_METAL_VER_MASK
)
>>
WL18XX_METAL_VER_OFFSET
;
else
...
...
@@ -1204,11 +1289,9 @@ static int wl18xx_get_pg_ver(struct wl1271 *wl, s8 *ver)
goto
out
;
rdl_ver
=
(
fuse
&
WL18XX_RDL_VER_MASK
)
>>
WL18XX_RDL_VER_OFFSET
;
if
(
rdl_ver
>
RDL_MAX
)
rdl_ver
=
RDL_NONE
;
wl1271_info
(
"wl18xx HW:
RDL %d, %s, PG %x.%x (ROM
%x)"
,
rdl_ver
,
rdl_names
[
rdl_ver
]
,
pg_ver
,
metal
,
rom
);
wl1271_info
(
"wl18xx HW:
%s, PG %d.%d (ROM 0x
%x)"
,
wl18xx_rdl_name
(
rdl_ver
)
,
pg_ver
,
metal
,
rom
);
if
(
ver
)
*
ver
=
pg_ver
;
...
...
drivers/net/wireless/ti/wl18xx/reg.h
View file @
c21a7d66
...
...
@@ -114,6 +114,11 @@
#define PLATFORM_DETECTION 0xA0E3E0
#define OCS_EN 0xA02080
#define PRIMARY_CLK_DETECT 0xA020A6
#define PLLSH_COEX_PLL_N 0xA02384
#define PLLSH_COEX_PLL_M 0xA02382
#define PLLSH_COEX_PLL_SWALLOW_EN 0xA0238E
#define PLLSH_WL_PLL_SEL 0xA02398
#define PLLSH_WCS_PLL_N 0xA02362
#define PLLSH_WCS_PLL_M 0xA02360
#define PLLSH_WCS_PLL_Q_FACTOR_CFG_1 0xA02364
...
...
@@ -128,19 +133,30 @@
#define PLLSH_WCS_PLL_P_FACTOR_CFG_1_MASK 0xFFFF
#define PLLSH_WCS_PLL_P_FACTOR_CFG_2_MASK 0x000F
#define PLLSH_WL_PLL_EN_VAL1 0x7
#define PLLSH_WL_PLL_EN_VAL2 0x2
#define PLLSH_COEX_PLL_SWALLOW_EN_VAL1 0x2
#define PLLSH_COEX_PLL_SWALLOW_EN_VAL2 0x11
#define PLLSH_WCS_PLL_SWALLOW_EN_VAL1 0x1
#define PLLSH_WCS_PLL_SWALLOW_EN_VAL2 0x12
#define PLLSH_WL_PLL_SEL_WCS_PLL 0x0
#define PLLSH_WL_PLL_SEL_COEX_PLL 0x1
#define WL18XX_REG_FUSE_DATA_1_3 0xA0260C
#define WL18XX_PG_VER_MASK 0x70
#define WL18XX_PG_VER_OFFSET 4
#define WL18XX_ROM_VER_MASK 0x3
#define WL18XX_ROM_VER_OFFSET
0
#define WL18XX_ROM_VER_MASK 0x3
e00
#define WL18XX_ROM_VER_OFFSET
9
#define WL18XX_METAL_VER_MASK 0xC
#define WL18XX_METAL_VER_OFFSET 2
#define WL18XX_NEW_METAL_VER_MASK 0x180
#define WL18XX_NEW_METAL_VER_OFFSET 7
#define WL18XX_PACKAGE_TYPE_OFFSET 13
#define WL18XX_PACKAGE_TYPE_WSP 0
#define WL18XX_REG_FUSE_DATA_2_3 0xA02614
#define WL18XX_RDL_VER_MASK 0x1f00
#define WL18XX_RDL_VER_OFFSET 8
...
...
@@ -201,24 +217,21 @@ enum {
NUM_BOARD_TYPES
,
};
enum
{
enum
wl18xx_rdl_num
{
RDL_NONE
=
0
,
RDL_1_HP
=
1
,
RDL_2_SP
=
2
,
RDL_3_HP
=
3
,
RDL_4_SP
=
4
,
RDL_5_SP
=
0x11
,
RDL_6_SP
=
0x12
,
RDL_7_SP
=
0x13
,
RDL_8_SP
=
0x14
,
_RDL_LAST
,
RDL_MAX
=
_RDL_LAST
-
1
,
};
static
const
char
*
const
rdl_names
[]
=
{
[
RDL_NONE
]
=
""
,
[
RDL_1_HP
]
=
"1853 SISO"
,
[
RDL_2_SP
]
=
"1857 MIMO"
,
[
RDL_3_HP
]
=
"1893 SISO"
,
[
RDL_4_SP
]
=
"1897 MIMO"
,
};
/* FPGA_SPARE_1 register - used to change the PHY ATPG clock at boot time */
#define WL18XX_PHY_FPGA_SPARE_1 0x8093CA40
...
...
drivers/net/wireless/ti/wlcore/cmd.c
View file @
c21a7d66
...
...
@@ -1126,6 +1126,8 @@ int wl12xx_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif,
u16
template_id_2_4
=
wl
->
scan_templ_id_2_4
;
u16
template_id_5
=
wl
->
scan_templ_id_5
;
wl1271_debug
(
DEBUG_SCAN
,
"build probe request band %d"
,
band
);
skb
=
ieee80211_probereq_get
(
wl
->
hw
,
vif
,
ssid
,
ssid_len
,
ie_len
);
if
(
!
skb
)
{
...
...
@@ -1135,8 +1137,6 @@ int wl12xx_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif,
if
(
ie_len
)
memcpy
(
skb_put
(
skb
,
ie_len
),
ie
,
ie_len
);
wl1271_dump
(
DEBUG_SCAN
,
"PROBE REQ: "
,
skb
->
data
,
skb
->
len
);
if
(
sched_scan
&&
(
wl
->
quirks
&
WLCORE_QUIRK_DUAL_PROBE_TMPL
))
{
template_id_2_4
=
wl
->
sched_scan_templ_id_2_4
;
...
...
@@ -1172,7 +1172,7 @@ struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl,
if
(
!
skb
)
goto
out
;
wl1271_d
ump
(
DEBUG_SCAN
,
"AP PROBE REQ: "
,
skb
->
data
,
skb
->
len
);
wl1271_d
ebug
(
DEBUG_SCAN
,
"set ap probe request template"
);
rate
=
wl1271_tx_min_rate_get
(
wl
,
wlvif
->
bitrate_masks
[
wlvif
->
band
]);
if
(
wlvif
->
band
==
IEEE80211_BAND_2GHZ
)
...
...
@@ -1607,33 +1607,43 @@ int wl12xx_cmd_remove_peer(struct wl1271 *wl, u8 hlid)
static
int
wlcore_get_reg_conf_ch_idx
(
enum
ieee80211_band
band
,
u16
ch
)
{
int
idx
=
-
1
;
/*
* map the given band/channel to the respective predefined
* bit expected by the fw
*/
switch
(
band
)
{
case
IEEE80211_BAND_5GHZ
:
if
(
ch
>=
8
&&
ch
<=
16
)
idx
=
((
ch
-
8
)
/
4
+
18
);
else
if
(
ch
>=
34
&&
ch
<=
64
)
idx
=
((
ch
-
34
)
/
2
+
3
+
18
);
else
if
(
ch
>=
100
&&
ch
<=
140
)
idx
=
((
ch
-
100
)
/
4
+
15
+
18
);
else
if
(
ch
>=
149
&&
ch
<=
165
)
idx
=
((
ch
-
149
)
/
4
+
26
+
18
);
else
idx
=
-
1
;
break
;
case
IEEE80211_BAND_2GHZ
:
/* channels 1..14 are mapped to 0..13 */
if
(
ch
>=
1
&&
ch
<=
14
)
idx
=
ch
-
1
;
else
idx
=
-
1
;
return
ch
-
1
;
break
;
case
IEEE80211_BAND_5GHZ
:
switch
(
ch
)
{
case
8
...
16
:
/* channels 8,12,16 are mapped to 18,19,20 */
return
18
+
(
ch
-
8
)
/
4
;
case
34
...
48
:
/* channels 34,36..48 are mapped to 21..28 */
return
21
+
(
ch
-
34
)
/
2
;
case
52
...
64
:
/* channels 52,56..64 are mapped to 29..32 */
return
29
+
(
ch
-
52
)
/
4
;
case
100
...
140
:
/* channels 100,104..140 are mapped to 33..43 */
return
33
+
(
ch
-
100
)
/
4
;
case
149
...
165
:
/* channels 149,153..165 are mapped to 44..48 */
return
44
+
(
ch
-
149
)
/
4
;
default:
wl1271_error
(
"get reg conf ch idx - unknown band: %d"
,
(
int
)
band
);
break
;
}
break
;
default:
break
;
}
return
idx
;
wl1271_error
(
"%s: unknown band/channel: %d/%d"
,
__func__
,
band
,
ch
);
return
-
1
;
}
void
wlcore_set_pending_regdomain_ch
(
struct
wl1271
*
wl
,
u16
channel
,
...
...
@@ -1646,7 +1656,7 @@ void wlcore_set_pending_regdomain_ch(struct wl1271 *wl, u16 channel,
ch_bit_idx
=
wlcore_get_reg_conf_ch_idx
(
band
,
channel
);
if
(
ch_bit_idx
>
0
&&
ch_bit_idx
<=
WL1271_MAX_CHANNELS
)
if
(
ch_bit_idx
>
=
0
&&
ch_bit_idx
<=
WL1271_MAX_CHANNELS
)
set_bit
(
ch_bit_idx
,
(
long
*
)
wl
->
reg_ch_conf_pending
);
}
...
...
drivers/net/wireless/ti/wlcore/main.c
View file @
c21a7d66
...
...
@@ -1062,7 +1062,8 @@ int wl1271_plt_start(struct wl1271 *wl, const enum plt_mode plt_mode)
static
const
char
*
const
PLT_MODE
[]
=
{
"PLT_OFF"
,
"PLT_ON"
,
"PLT_FEM_DETECT"
"PLT_FEM_DETECT"
,
"PLT_CHIP_AWAKE"
};
int
ret
;
...
...
@@ -1088,9 +1089,11 @@ int wl1271_plt_start(struct wl1271 *wl, const enum plt_mode plt_mode)
if
(
ret
<
0
)
goto
power_off
;
if
(
plt_mode
!=
PLT_CHIP_AWAKE
)
{
ret
=
wl
->
ops
->
plt_init
(
wl
);
if
(
ret
<
0
)
goto
power_off
;
}
wl
->
state
=
WLCORE_STATE_ON
;
wl1271_notice
(
"firmware booted in PLT mode %s (%s)"
,
...
...
@@ -2008,6 +2011,47 @@ static void wlcore_connection_loss_work(struct work_struct *work)
mutex_unlock
(
&
wl
->
mutex
);
}
static
void
wlcore_pending_auth_complete_work
(
struct
work_struct
*
work
)
{
struct
delayed_work
*
dwork
;
struct
wl1271
*
wl
;
struct
wl12xx_vif
*
wlvif
;
unsigned
long
time_spare
;
int
ret
;
dwork
=
container_of
(
work
,
struct
delayed_work
,
work
);
wlvif
=
container_of
(
dwork
,
struct
wl12xx_vif
,
pending_auth_complete_work
);
wl
=
wlvif
->
wl
;
mutex_lock
(
&
wl
->
mutex
);
if
(
unlikely
(
wl
->
state
!=
WLCORE_STATE_ON
))
goto
out
;
/*
* Make sure a second really passed since the last auth reply. Maybe
* a second auth reply arrived while we were stuck on the mutex.
* Check for a little less than the timeout to protect from scheduler
* irregularities.
*/
time_spare
=
jiffies
+
msecs_to_jiffies
(
WLCORE_PEND_AUTH_ROC_TIMEOUT
-
50
);
if
(
!
time_after
(
time_spare
,
wlvif
->
pending_auth_reply_time
))
goto
out
;
ret
=
wl1271_ps_elp_wakeup
(
wl
);
if
(
ret
<
0
)
goto
out
;
/* cancel the ROC if active */
wlcore_update_inconn_sta
(
wl
,
wlvif
,
NULL
,
false
);
wl1271_ps_elp_sleep
(
wl
);
out:
mutex_unlock
(
&
wl
->
mutex
);
}
static
int
wl12xx_allocate_rate_policy
(
struct
wl1271
*
wl
,
u8
*
idx
)
{
u8
policy
=
find_first_zero_bit
(
wl
->
rate_policies_map
,
...
...
@@ -2159,6 +2203,8 @@ static int wl12xx_init_vif_data(struct wl1271 *wl, struct ieee80211_vif *vif)
wlcore_channel_switch_work
);
INIT_DELAYED_WORK
(
&
wlvif
->
connection_loss_work
,
wlcore_connection_loss_work
);
INIT_DELAYED_WORK
(
&
wlvif
->
pending_auth_complete_work
,
wlcore_pending_auth_complete_work
);
INIT_LIST_HEAD
(
&
wlvif
->
list
);
setup_timer
(
&
wlvif
->
rx_streaming_timer
,
wl1271_rx_streaming_timer
,
...
...
@@ -2376,6 +2422,11 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
int
ret
=
0
;
u8
role_type
;
if
(
wl
->
plt
)
{
wl1271_error
(
"Adding Interface not allowed while in PLT mode"
);
return
-
EBUSY
;
}
vif
->
driver_flags
|=
IEEE80211_VIF_BEACON_FILTER
|
IEEE80211_VIF_SUPPORTS_CQM_RSSI
;
...
...
@@ -2590,6 +2641,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
cancel_work_sync
(
&
wlvif
->
rx_streaming_disable_work
);
cancel_delayed_work_sync
(
&
wlvif
->
connection_loss_work
);
cancel_delayed_work_sync
(
&
wlvif
->
channel_switch_work
);
cancel_delayed_work_sync
(
&
wlvif
->
pending_auth_complete_work
);
mutex_lock
(
&
wl
->
mutex
);
}
...
...
@@ -2875,6 +2927,25 @@ static void wl1271_set_band_rate(struct wl1271 *wl, struct wl12xx_vif *wlvif)
wlvif
->
rate_set
=
wlvif
->
basic_rate_set
;
}
static
void
wl1271_sta_handle_idle
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
,
bool
idle
)
{
bool
cur_idle
=
!
test_bit
(
WLVIF_FLAG_ACTIVE
,
&
wlvif
->
flags
);
if
(
idle
==
cur_idle
)
return
;
if
(
idle
)
{
clear_bit
(
WLVIF_FLAG_ACTIVE
,
&
wlvif
->
flags
);
}
else
{
/* The current firmware only supports sched_scan in idle */
if
(
wl
->
sched_vif
==
wlvif
)
wl
->
ops
->
sched_scan_stop
(
wl
,
wlvif
);
set_bit
(
WLVIF_FLAG_ACTIVE
,
&
wlvif
->
flags
);
}
}
static
int
wl12xx_config_vif
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
,
struct
ieee80211_conf
*
conf
,
u32
changed
)
{
...
...
@@ -3969,6 +4040,13 @@ static void wl1271_bss_info_changed_ap(struct wl1271 *wl,
}
}
else
{
if
(
test_bit
(
WLVIF_FLAG_AP_STARTED
,
&
wlvif
->
flags
))
{
/*
* AP might be in ROC in case we have just
* sent auth reply. handle it.
*/
if
(
test_bit
(
wlvif
->
role_id
,
wl
->
roc_map
))
wl12xx_croc
(
wl
,
wlvif
->
role_id
);
ret
=
wl12xx_cmd_role_stop_ap
(
wl
,
wlvif
);
if
(
ret
<
0
)
goto
out
;
...
...
@@ -4120,6 +4198,9 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
do_join
=
true
;
}
if
(
changed
&
BSS_CHANGED_IDLE
&&
!
is_ibss
)
wl1271_sta_handle_idle
(
wl
,
wlvif
,
bss_conf
->
idle
);
if
(
changed
&
BSS_CHANGED_CQM
)
{
bool
enable
=
false
;
if
(
bss_conf
->
cqm_rssi_thold
)
...
...
@@ -4656,28 +4737,48 @@ static void wlcore_roc_if_possible(struct wl1271 *wl,
wl12xx_roc
(
wl
,
wlvif
,
wlvif
->
role_id
,
wlvif
->
band
,
wlvif
->
channel
);
}
static
void
wlcore_update_inconn_sta
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
,
struct
wl1271_station
*
wl_sta
,
bool
in_connection
)
/*
* when wl_sta is NULL, we treat this call as if coming from a
* pending auth reply.
* wl->mutex must be taken and the FW must be awake when the call
* takes place.
*/
void
wlcore_update_inconn_sta
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
,
struct
wl1271_station
*
wl_sta
,
bool
in_conn
)
{
if
(
in_conn
ection
)
{
if
(
WARN_ON
(
wl_sta
->
in_connection
))
if
(
in_conn
)
{
if
(
WARN_ON
(
wl_sta
&&
wl_sta
->
in_connection
))
return
;
wl_sta
->
in_connection
=
true
;
if
(
!
wlvif
->
inconn_count
++
)
if
(
!
wlvif
->
ap_pending_auth_reply
&&
!
wlvif
->
inconn_count
)
wlcore_roc_if_possible
(
wl
,
wlvif
);
if
(
wl_sta
)
{
wl_sta
->
in_connection
=
true
;
wlvif
->
inconn_count
++
;
}
else
{
wlvif
->
ap_pending_auth_reply
=
true
;
}
}
else
{
if
(
!
wl_sta
->
in_connection
)
if
(
wl_sta
&&
!
wl_sta
->
in_connection
)
return
;
if
(
WARN_ON
(
!
wl_sta
&&
!
wlvif
->
ap_pending_auth_reply
))
return
;
if
(
WARN_ON
(
wl_sta
&&
!
wlvif
->
inconn_count
))
return
;
if
(
wl_sta
)
{
wl_sta
->
in_connection
=
false
;
wlvif
->
inconn_count
--
;
if
(
WARN_ON
(
wlvif
->
inconn_count
<
0
))
return
;
}
else
{
wlvif
->
ap_pending_auth_reply
=
false
;
}
if
(
!
wlvif
->
inconn_count
)
if
(
test_bit
(
wlvif
->
role_id
,
wl
->
roc_map
))
if
(
!
wlvif
->
inconn_count
&&
!
wlvif
->
ap_pending_auth_reply
&&
test_bit
(
wlvif
->
role_id
,
wl
->
roc_map
))
wl12xx_croc
(
wl
,
wlvif
->
role_id
);
}
}
...
...
@@ -5313,10 +5414,7 @@ static struct ieee80211_rate wl1271_rates_5ghz[] = {
/* 5 GHz band channels for WL1273 */
static
struct
ieee80211_channel
wl1271_channels_5ghz
[]
=
{
{
.
hw_value
=
7
,
.
center_freq
=
5035
,
.
max_power
=
WLCORE_MAX_TXPWR
},
{
.
hw_value
=
8
,
.
center_freq
=
5040
,
.
max_power
=
WLCORE_MAX_TXPWR
},
{
.
hw_value
=
9
,
.
center_freq
=
5045
,
.
max_power
=
WLCORE_MAX_TXPWR
},
{
.
hw_value
=
11
,
.
center_freq
=
5055
,
.
max_power
=
WLCORE_MAX_TXPWR
},
{
.
hw_value
=
12
,
.
center_freq
=
5060
,
.
max_power
=
WLCORE_MAX_TXPWR
},
{
.
hw_value
=
16
,
.
center_freq
=
5080
,
.
max_power
=
WLCORE_MAX_TXPWR
},
{
.
hw_value
=
34
,
.
center_freq
=
5170
,
.
max_power
=
WLCORE_MAX_TXPWR
},
...
...
@@ -5896,6 +5994,11 @@ static const struct wiphy_wowlan_support wlcore_wowlan_support = {
};
#endif
static
irqreturn_t
wlcore_hardirq
(
int
irq
,
void
*
cookie
)
{
return
IRQ_WAKE_THREAD
;
}
static
void
wlcore_nvs_cb
(
const
struct
firmware
*
fw
,
void
*
context
)
{
struct
wl1271
*
wl
=
context
;
...
...
@@ -5904,6 +6007,7 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context)
struct
wl12xx_platform_data
*
pdata
=
pdev_data
->
pdata
;
unsigned
long
irqflags
;
int
ret
;
irq_handler_t
hardirq_fn
=
NULL
;
if
(
fw
)
{
wl
->
nvs
=
kmemdup
(
fw
->
data
,
fw
->
size
,
GFP_KERNEL
);
...
...
@@ -5932,12 +6036,14 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context)
wl
->
platform_quirks
=
pdata
->
platform_quirks
;
wl
->
if_ops
=
pdev_data
->
if_ops
;
if
(
wl
->
platform_quirks
&
WL12XX_PLATFORM_QUIRK_EDGE_IRQ
)
if
(
wl
->
platform_quirks
&
WL12XX_PLATFORM_QUIRK_EDGE_IRQ
)
{
irqflags
=
IRQF_TRIGGER_RISING
;
else
hardirq_fn
=
wlcore_hardirq
;
}
else
{
irqflags
=
IRQF_TRIGGER_HIGH
|
IRQF_ONESHOT
;
}
ret
=
request_threaded_irq
(
wl
->
irq
,
NULL
,
wlcore_irq
,
ret
=
request_threaded_irq
(
wl
->
irq
,
hardirq_fn
,
wlcore_irq
,
irqflags
,
pdev
->
name
,
wl
);
if
(
ret
<
0
)
{
wl1271_error
(
"request_irq() failed: %d"
,
ret
);
...
...
drivers/net/wireless/ti/wlcore/ps.c
View file @
c21a7d66
...
...
@@ -83,6 +83,10 @@ void wl1271_ps_elp_sleep(struct wl1271 *wl)
struct
wl12xx_vif
*
wlvif
;
u32
timeout
;
/* We do not enter elp sleep in PLT mode */
if
(
wl
->
plt
)
return
;
if
(
wl
->
sleep_auth
!=
WL1271_PSM_ELP
)
return
;
...
...
drivers/net/wireless/ti/wlcore/scan.c
View file @
c21a7d66
...
...
@@ -174,17 +174,7 @@ wlcore_scan_get_channels(struct wl1271 *wl,
/* if radar is set, we ignore the passive flag */
(
radar
||
!!
(
flags
&
IEEE80211_CHAN_PASSIVE_SCAN
)
==
passive
))
{
wl1271_debug
(
DEBUG_SCAN
,
"band %d, center_freq %d "
,
req_channels
[
i
]
->
band
,
req_channels
[
i
]
->
center_freq
);
wl1271_debug
(
DEBUG_SCAN
,
"hw_value %d, flags %X"
,
req_channels
[
i
]
->
hw_value
,
req_channels
[
i
]
->
flags
);
wl1271_debug
(
DEBUG_SCAN
,
"max_power %d"
,
req_channels
[
i
]
->
max_power
);
wl1271_debug
(
DEBUG_SCAN
,
"min_dwell_time %d max dwell time %d"
,
min_dwell_time_active
,
max_dwell_time_active
);
if
(
flags
&
IEEE80211_CHAN_RADAR
)
{
channels
[
j
].
flags
|=
SCAN_CHANNEL_FLAGS_DFS
;
...
...
@@ -222,6 +212,17 @@ wlcore_scan_get_channels(struct wl1271 *wl,
*
n_pactive_ch
);
}
wl1271_debug
(
DEBUG_SCAN
,
"freq %d, ch. %d, flags 0x%x, power %d, min/max_dwell %d/%d%s%s"
,
req_channels
[
i
]
->
center_freq
,
req_channels
[
i
]
->
hw_value
,
req_channels
[
i
]
->
flags
,
req_channels
[
i
]
->
max_power
,
min_dwell_time_active
,
max_dwell_time_active
,
flags
&
IEEE80211_CHAN_RADAR
?
", DFS"
:
""
,
flags
&
IEEE80211_CHAN_PASSIVE_SCAN
?
", PASSIVE"
:
""
);
j
++
;
}
}
...
...
@@ -364,7 +365,7 @@ wlcore_scan_sched_scan_ssid_list(struct wl1271 *wl,
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"
);
wl1271_debug
(
(
DEBUG_CMD
|
DEBUG_SCAN
)
,
"cmd sched scan ssid list"
);
/* count the match sets that contain SSIDs */
for
(
i
=
0
;
i
<
req
->
n_match_sets
;
i
++
)
...
...
@@ -442,8 +443,6 @@ wlcore_scan_sched_scan_ssid_list(struct wl1271 *wl,
}
}
wl1271_dump
(
DEBUG_SCAN
,
"SSID_LIST: "
,
cmd
,
sizeof
(
*
cmd
));
ret
=
wl1271_cmd_send
(
wl
,
CMD_CONNECTION_SCAN_SSID_CFG
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
...
...
drivers/net/wireless/ti/wlcore/testmode.c
View file @
c21a7d66
...
...
@@ -297,7 +297,8 @@ static int wl1271_tm_cmd_set_plt_mode(struct wl1271 *wl, struct nlattr *tb[])
ret
=
wl1271_plt_stop
(
wl
);
break
;
case
PLT_ON
:
ret
=
wl1271_plt_start
(
wl
,
PLT_ON
);
case
PLT_CHIP_AWAKE
:
ret
=
wl1271_plt_start
(
wl
,
val
);
break
;
case
PLT_FEM_DETECT
:
ret
=
wl1271_tm_detect_fem
(
wl
,
tb
);
...
...
@@ -361,6 +362,7 @@ int wl1271_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
{
struct
wl1271
*
wl
=
hw
->
priv
;
struct
nlattr
*
tb
[
WL1271_TM_ATTR_MAX
+
1
];
u32
nla_cmd
;
int
err
;
err
=
nla_parse
(
tb
,
WL1271_TM_ATTR_MAX
,
data
,
len
,
wl1271_tm_policy
);
...
...
@@ -370,7 +372,14 @@ int wl1271_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
if
(
!
tb
[
WL1271_TM_ATTR_CMD_ID
])
return
-
EINVAL
;
switch
(
nla_get_u32
(
tb
[
WL1271_TM_ATTR_CMD_ID
]))
{
nla_cmd
=
nla_get_u32
(
tb
[
WL1271_TM_ATTR_CMD_ID
]);
/* Only SET_PLT_MODE is allowed in case of mode PLT_CHIP_AWAKE */
if
(
wl
->
plt_mode
==
PLT_CHIP_AWAKE
&&
nla_cmd
!=
WL1271_TM_CMD_SET_PLT_MODE
)
return
-
EOPNOTSUPP
;
switch
(
nla_cmd
)
{
case
WL1271_TM_CMD_TEST
:
return
wl1271_tm_cmd_test
(
wl
,
tb
);
case
WL1271_TM_CMD_INTERROGATE
:
...
...
drivers/net/wireless/ti/wlcore/tx.c
View file @
c21a7d66
...
...
@@ -86,19 +86,34 @@ void wl1271_free_tx_id(struct wl1271 *wl, int id)
EXPORT_SYMBOL
(
wl1271_free_tx_id
);
static
void
wl1271_tx_ap_update_inconnection_sta
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
,
struct
sk_buff
*
skb
)
{
struct
ieee80211_hdr
*
hdr
;
hdr
=
(
struct
ieee80211_hdr
*
)(
skb
->
data
+
sizeof
(
struct
wl1271_tx_hw_descr
));
if
(
!
ieee80211_is_auth
(
hdr
->
frame_control
))
return
;
/*
* add the station to the known list before transmitting the
* authentication response. this way it won't get de-authed by FW
* when transmitting too soon.
*/
hdr
=
(
struct
ieee80211_hdr
*
)(
skb
->
data
+
sizeof
(
struct
wl1271_tx_hw_descr
));
if
(
ieee80211_is_auth
(
hdr
->
frame_control
))
wl1271_acx_set_inconnection_sta
(
wl
,
hdr
->
addr1
);
/*
* ROC for 1 second on the AP channel for completing the connection.
* Note the ROC will be continued by the update_sta_state callbacks
* once the station reaches the associated state.
*/
wlcore_update_inconn_sta
(
wl
,
wlvif
,
NULL
,
true
);
wlvif
->
pending_auth_reply_time
=
jiffies
;
cancel_delayed_work
(
&
wlvif
->
pending_auth_complete_work
);
ieee80211_queue_delayed_work
(
wl
->
hw
,
&
wlvif
->
pending_auth_complete_work
,
msecs_to_jiffies
(
WLCORE_PEND_AUTH_ROC_TIMEOUT
));
}
static
void
wl1271_tx_regulate_link
(
struct
wl1271
*
wl
,
...
...
@@ -386,7 +401,7 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct wl12xx_vif *wlvif,
is_wep
=
(
cipher
==
WLAN_CIPHER_SUITE_WEP40
)
||
(
cipher
==
WLAN_CIPHER_SUITE_WEP104
);
if
(
WARN_ON
(
is_wep
&&
wlvif
->
default_key
!=
idx
))
{
if
(
WARN_ON
(
is_wep
&&
wlvif
&&
wlvif
->
default_key
!=
idx
))
{
ret
=
wl1271_set_default_wep_key
(
wl
,
wlvif
,
idx
);
if
(
ret
<
0
)
return
ret
;
...
...
@@ -404,7 +419,7 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct wl12xx_vif *wlvif,
wl1271_tx_fill_hdr
(
wl
,
wlvif
,
skb
,
extra
,
info
,
hlid
);
if
(
!
is_dummy
&&
wlvif
&&
wlvif
->
bss_type
==
BSS_TYPE_AP_BSS
)
{
wl1271_tx_ap_update_inconnection_sta
(
wl
,
skb
);
wl1271_tx_ap_update_inconnection_sta
(
wl
,
wlvif
,
skb
);
wl1271_tx_regulate_link
(
wl
,
wlvif
,
hlid
);
}
...
...
drivers/net/wireless/ti/wlcore/tx.h
View file @
c21a7d66
...
...
@@ -56,6 +56,9 @@
/* Used for management frames and dummy packets */
#define WL1271_TID_MGMT 7
/* stop a ROC for pending authentication reply after this time (ms) */
#define WLCORE_PEND_AUTH_ROC_TIMEOUT 1000
struct
wl127x_tx_mem
{
/*
* Number of extra memory blocks to allocate for this packet
...
...
drivers/net/wireless/ti/wlcore/wlcore.h
View file @
c21a7d66
...
...
@@ -481,6 +481,8 @@ int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
struct
ieee80211_sta
*
sta
,
struct
ieee80211_key_conf
*
key_conf
);
void
wlcore_regdomain_config
(
struct
wl1271
*
wl
);
void
wlcore_update_inconn_sta
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
,
struct
wl1271_station
*
wl_sta
,
bool
in_conn
);
static
inline
void
wlcore_set_ht_cap
(
struct
wl1271
*
wl
,
enum
ieee80211_band
band
,
...
...
drivers/net/wireless/ti/wlcore/wlcore_i.h
View file @
c21a7d66
...
...
@@ -255,6 +255,7 @@ enum wl12xx_vif_flags {
WLVIF_FLAG_CS_PROGRESS
,
WLVIF_FLAG_AP_PROBE_RESP_SET
,
WLVIF_FLAG_IN_USE
,
WLVIF_FLAG_ACTIVE
,
};
struct
wl12xx_vif
;
...
...
@@ -307,6 +308,7 @@ enum plt_mode {
PLT_OFF
=
0
,
PLT_ON
=
1
,
PLT_FEM_DETECT
=
2
,
PLT_CHIP_AWAKE
=
3
};
struct
wl12xx_rx_filter_field
{
...
...
@@ -456,6 +458,15 @@ struct wl12xx_vif {
*/
int
hw_queue_base
;
/* do we have a pending auth reply? (and ROC) */
bool
ap_pending_auth_reply
;
/* time when we sent the pending auth reply */
unsigned
long
pending_auth_reply_time
;
/* work for canceling ROC after pending auth reply */
struct
delayed_work
pending_auth_complete_work
;
/*
* This struct must be last!
* data that has to be saved acrossed reconfigs (e.g. recovery)
...
...
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