Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
c2786e4a
K
Kernel
项目概览
openeuler
/
Kernel
大约 1 年 前同步成功
通知
5
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
c2786e4a
编写于
4月 12, 2012
作者:
J
John W. Linville
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'for-linville' of
git://github.com/kvalo/ath6kl
上级
80652480
d97c121b
变更
20
展开全部
隐藏空白更改
内联
并排
Showing
20 changed file
with
3370 addition
and
165 deletion
+3370
-165
drivers/net/wireless/ath/ath6kl/Makefile
drivers/net/wireless/ath/ath6kl/Makefile
+2
-1
drivers/net/wireless/ath/ath6kl/cfg80211.c
drivers/net/wireless/ath/ath6kl/cfg80211.c
+339
-78
drivers/net/wireless/ath/ath6kl/common.h
drivers/net/wireless/ath/ath6kl/common.h
+3
-1
drivers/net/wireless/ath/ath6kl/core.c
drivers/net/wireless/ath/ath6kl/core.c
+28
-2
drivers/net/wireless/ath/ath6kl/core.h
drivers/net/wireless/ath/ath6kl/core.h
+32
-2
drivers/net/wireless/ath/ath6kl/debug.c
drivers/net/wireless/ath/ath6kl/debug.c
+6
-0
drivers/net/wireless/ath/ath6kl/debug.h
drivers/net/wireless/ath/ath6kl/debug.h
+1
-0
drivers/net/wireless/ath/ath6kl/hif-ops.h
drivers/net/wireless/ath/ath6kl/hif-ops.h
+34
-0
drivers/net/wireless/ath/ath6kl/hif.h
drivers/net/wireless/ath/ath6kl/hif.h
+6
-0
drivers/net/wireless/ath/ath6kl/htc-ops.h
drivers/net/wireless/ath/ath6kl/htc-ops.h
+113
-0
drivers/net/wireless/ath/ath6kl/htc.h
drivers/net/wireless/ath/ath6kl/htc.h
+73
-25
drivers/net/wireless/ath/ath6kl/htc_mbox.c
drivers/net/wireless/ath/ath6kl/htc_mbox.c
+59
-26
drivers/net/wireless/ath/ath6kl/htc_pipe.c
drivers/net/wireless/ath/ath6kl/htc_pipe.c
+1713
-0
drivers/net/wireless/ath/ath6kl/init.c
drivers/net/wireless/ath/ath6kl/init.c
+36
-21
drivers/net/wireless/ath/ath6kl/main.c
drivers/net/wireless/ath/ath6kl/main.c
+4
-0
drivers/net/wireless/ath/ath6kl/sdio.c
drivers/net/wireless/ath/ath6kl/sdio.c
+1
-1
drivers/net/wireless/ath/ath6kl/txrx.c
drivers/net/wireless/ath/ath6kl/txrx.c
+19
-4
drivers/net/wireless/ath/ath6kl/usb.c
drivers/net/wireless/ath/ath6kl/usb.c
+781
-4
drivers/net/wireless/ath/ath6kl/wmi.c
drivers/net/wireless/ath/ath6kl/wmi.c
+80
-0
drivers/net/wireless/ath/ath6kl/wmi.h
drivers/net/wireless/ath/ath6kl/wmi.h
+40
-0
未找到文件。
drivers/net/wireless/ath/ath6kl/Makefile
浏览文件 @
c2786e4a
...
...
@@ -25,7 +25,8 @@
obj-$(CONFIG_ATH6KL)
+=
ath6kl_core.o
ath6kl_core-y
+=
debug.o
ath6kl_core-y
+=
hif.o
ath6kl_core-y
+=
htc.o
ath6kl_core-y
+=
htc_mbox.o
ath6kl_core-y
+=
htc_pipe.o
ath6kl_core-y
+=
bmi.o
ath6kl_core-y
+=
cfg80211.o
ath6kl_core-y
+=
init.o
...
...
drivers/net/wireless/ath/ath6kl/cfg80211.c
浏览文件 @
c2786e4a
...
...
@@ -51,6 +51,8 @@
.max_power = 30, \
}
#define DEFAULT_BG_SCAN_PERIOD 60
static
struct
ieee80211_rate
ath6kl_rates
[]
=
{
RATETAB_ENT
(
10
,
0x1
,
0
),
RATETAB_ENT
(
20
,
0x2
,
0
),
...
...
@@ -71,7 +73,8 @@ static struct ieee80211_rate ath6kl_rates[] = {
#define ath6kl_g_rates (ath6kl_rates + 0)
#define ath6kl_g_rates_size 12
#define ath6kl_g_htcap (IEEE80211_HT_CAP_SUP_WIDTH_20_40 | \
#define ath6kl_g_htcap IEEE80211_HT_CAP_SGI_20
#define ath6kl_a_htcap (IEEE80211_HT_CAP_SUP_WIDTH_20_40 | \
IEEE80211_HT_CAP_SGI_20 | \
IEEE80211_HT_CAP_SGI_40)
...
...
@@ -128,7 +131,7 @@ static struct ieee80211_supported_band ath6kl_band_5ghz = {
.
channels
=
ath6kl_5ghz_a_channels
,
.
n_bitrates
=
ath6kl_a_rates_size
,
.
bitrates
=
ath6kl_a_rates
,
.
ht_cap
.
cap
=
ath6kl_
g
_htcap
,
.
ht_cap
.
cap
=
ath6kl_
a
_htcap
,
.
ht_cap
.
ht_supported
=
true
,
};
...
...
@@ -609,6 +612,17 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
vif
->
req_bssid
,
vif
->
ch_hint
,
ar
->
connect_ctrl_flags
,
nw_subtype
);
/* disable background scan if period is 0 */
if
(
sme
->
bg_scan_period
==
0
)
sme
->
bg_scan_period
=
0xffff
;
/* configure default value if not specified */
if
(
sme
->
bg_scan_period
==
-
1
)
sme
->
bg_scan_period
=
DEFAULT_BG_SCAN_PERIOD
;
ath6kl_wmi_scanparams_cmd
(
ar
->
wmi
,
vif
->
fw_vif_idx
,
0
,
0
,
sme
->
bg_scan_period
,
0
,
0
,
0
,
3
,
0
,
0
,
0
);
up
(
&
ar
->
sem
);
if
(
status
==
-
EINVAL
)
{
...
...
@@ -943,6 +957,8 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
if
(
test_bit
(
CONNECTED
,
&
vif
->
flags
))
force_fg_scan
=
1
;
vif
->
scan_req
=
request
;
if
(
test_bit
(
ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX
,
ar
->
fw_capabilities
))
{
/*
...
...
@@ -965,10 +981,10 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
ATH6KL_FG_SCAN_INTERVAL
,
n_channels
,
channels
);
}
if
(
ret
)
if
(
ret
)
{
ath6kl_err
(
"wmi_startscan_cmd failed
\n
"
);
else
vif
->
scan_req
=
request
;
vif
->
scan_req
=
NULL
;
}
kfree
(
channels
);
...
...
@@ -1438,9 +1454,38 @@ static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy,
struct
vif_params
*
params
)
{
struct
ath6kl_vif
*
vif
=
netdev_priv
(
ndev
);
int
i
;
ath6kl_dbg
(
ATH6KL_DBG_WLAN_CFG
,
"%s: type %u
\n
"
,
__func__
,
type
);
/*
* Don't bring up p2p on an interface which is not initialized
* for p2p operation where fw does not have capability to switch
* dynamically between non-p2p and p2p type interface.
*/
if
(
!
test_bit
(
ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX
,
vif
->
ar
->
fw_capabilities
)
&&
(
type
==
NL80211_IFTYPE_P2P_CLIENT
||
type
==
NL80211_IFTYPE_P2P_GO
))
{
if
(
vif
->
ar
->
vif_max
==
1
)
{
if
(
vif
->
fw_vif_idx
!=
0
)
return
-
EINVAL
;
else
goto
set_iface_type
;
}
for
(
i
=
vif
->
ar
->
max_norm_iface
;
i
<
vif
->
ar
->
vif_max
;
i
++
)
{
if
(
i
==
vif
->
fw_vif_idx
)
break
;
}
if
(
i
==
vif
->
ar
->
vif_max
)
{
ath6kl_err
(
"Invalid interface to bring up P2P
\n
"
);
return
-
EINVAL
;
}
}
set_iface_type:
switch
(
type
)
{
case
NL80211_IFTYPE_STATION
:
vif
->
next_mode
=
INFRA_NETWORK
;
...
...
@@ -1926,12 +1971,61 @@ static int ath6kl_wow_sta(struct ath6kl *ar, struct ath6kl_vif *vif)
return
0
;
}
static
int
is_hsleep_mode_procsed
(
struct
ath6kl_vif
*
vif
)
{
return
test_bit
(
HOST_SLEEP_MODE_CMD_PROCESSED
,
&
vif
->
flags
);
}
static
bool
is_ctrl_ep_empty
(
struct
ath6kl
*
ar
)
{
return
!
ar
->
tx_pending
[
ar
->
ctrl_ep
];
}
static
int
ath6kl_cfg80211_host_sleep
(
struct
ath6kl
*
ar
,
struct
ath6kl_vif
*
vif
)
{
int
ret
,
left
;
clear_bit
(
HOST_SLEEP_MODE_CMD_PROCESSED
,
&
vif
->
flags
);
ret
=
ath6kl_wmi_set_host_sleep_mode_cmd
(
ar
->
wmi
,
vif
->
fw_vif_idx
,
ATH6KL_HOST_MODE_ASLEEP
);
if
(
ret
)
return
ret
;
left
=
wait_event_interruptible_timeout
(
ar
->
event_wq
,
is_hsleep_mode_procsed
(
vif
),
WMI_TIMEOUT
);
if
(
left
==
0
)
{
ath6kl_warn
(
"timeout, didn't get host sleep cmd processed event
\n
"
);
ret
=
-
ETIMEDOUT
;
}
else
if
(
left
<
0
)
{
ath6kl_warn
(
"error while waiting for host sleep cmd processed event %d
\n
"
,
left
);
ret
=
left
;
}
if
(
ar
->
tx_pending
[
ar
->
ctrl_ep
])
{
left
=
wait_event_interruptible_timeout
(
ar
->
event_wq
,
is_ctrl_ep_empty
(
ar
),
WMI_TIMEOUT
);
if
(
left
==
0
)
{
ath6kl_warn
(
"clear wmi ctrl data timeout
\n
"
);
ret
=
-
ETIMEDOUT
;
}
else
if
(
left
<
0
)
{
ath6kl_warn
(
"clear wmi ctrl data failed: %d
\n
"
,
left
);
ret
=
left
;
}
}
return
ret
;
}
static
int
ath6kl_wow_suspend
(
struct
ath6kl
*
ar
,
struct
cfg80211_wowlan
*
wow
)
{
struct
in_device
*
in_dev
;
struct
in_ifaddr
*
ifa
;
struct
ath6kl_vif
*
vif
;
int
ret
,
left
;
int
ret
;
u32
filter
=
0
;
u16
i
,
bmiss_time
;
u8
index
=
0
;
...
...
@@ -2032,39 +2126,11 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
if
(
ret
)
return
ret
;
clear_bit
(
HOST_SLEEP_MODE_CMD_PROCESSED
,
&
vif
->
flags
);
ret
=
ath6kl_wmi_set_host_sleep_mode_cmd
(
ar
->
wmi
,
vif
->
fw_vif_idx
,
ATH6KL_HOST_MODE_ASLEEP
);
ret
=
ath6kl_cfg80211_host_sleep
(
ar
,
vif
);
if
(
ret
)
return
ret
;
left
=
wait_event_interruptible_timeout
(
ar
->
event_wq
,
test_bit
(
HOST_SLEEP_MODE_CMD_PROCESSED
,
&
vif
->
flags
),
WMI_TIMEOUT
);
if
(
left
==
0
)
{
ath6kl_warn
(
"timeout, didn't get host sleep cmd "
"processed event
\n
"
);
ret
=
-
ETIMEDOUT
;
}
else
if
(
left
<
0
)
{
ath6kl_warn
(
"error while waiting for host sleep cmd "
"processed event %d
\n
"
,
left
);
ret
=
left
;
}
if
(
ar
->
tx_pending
[
ar
->
ctrl_ep
])
{
left
=
wait_event_interruptible_timeout
(
ar
->
event_wq
,
ar
->
tx_pending
[
ar
->
ctrl_ep
]
==
0
,
WMI_TIMEOUT
);
if
(
left
==
0
)
{
ath6kl_warn
(
"clear wmi ctrl data timeout
\n
"
);
ret
=
-
ETIMEDOUT
;
}
else
if
(
left
<
0
)
{
ath6kl_warn
(
"clear wmi ctrl data failed: %d
\n
"
,
left
);
ret
=
left
;
}
}
return
ret
;
return
0
;
}
static
int
ath6kl_wow_resume
(
struct
ath6kl
*
ar
)
...
...
@@ -2111,10 +2177,82 @@ static int ath6kl_wow_resume(struct ath6kl *ar)
return
0
;
}
static
int
ath6kl_cfg80211_deepsleep_suspend
(
struct
ath6kl
*
ar
)
{
struct
ath6kl_vif
*
vif
;
int
ret
;
vif
=
ath6kl_vif_first
(
ar
);
if
(
!
vif
)
return
-
EIO
;
if
(
!
ath6kl_cfg80211_ready
(
vif
))
return
-
EIO
;
ath6kl_cfg80211_stop_all
(
ar
);
/* Save the current power mode before enabling power save */
ar
->
wmi
->
saved_pwr_mode
=
ar
->
wmi
->
pwr_mode
;
ret
=
ath6kl_wmi_powermode_cmd
(
ar
->
wmi
,
0
,
REC_POWER
);
if
(
ret
)
return
ret
;
/* Disable WOW mode */
ret
=
ath6kl_wmi_set_wow_mode_cmd
(
ar
->
wmi
,
vif
->
fw_vif_idx
,
ATH6KL_WOW_MODE_DISABLE
,
0
,
0
);
if
(
ret
)
return
ret
;
/* Flush all non control pkts in TX path */
ath6kl_tx_data_cleanup
(
ar
);
ret
=
ath6kl_cfg80211_host_sleep
(
ar
,
vif
);
if
(
ret
)
return
ret
;
return
0
;
}
static
int
ath6kl_cfg80211_deepsleep_resume
(
struct
ath6kl
*
ar
)
{
struct
ath6kl_vif
*
vif
;
int
ret
;
vif
=
ath6kl_vif_first
(
ar
);
if
(
!
vif
)
return
-
EIO
;
if
(
ar
->
wmi
->
pwr_mode
!=
ar
->
wmi
->
saved_pwr_mode
)
{
ret
=
ath6kl_wmi_powermode_cmd
(
ar
->
wmi
,
0
,
ar
->
wmi
->
saved_pwr_mode
);
if
(
ret
)
return
ret
;
}
ret
=
ath6kl_wmi_set_host_sleep_mode_cmd
(
ar
->
wmi
,
vif
->
fw_vif_idx
,
ATH6KL_HOST_MODE_AWAKE
);
if
(
ret
)
return
ret
;
ar
->
state
=
ATH6KL_STATE_ON
;
/* Reset scan parameter to default values */
ret
=
ath6kl_wmi_scanparams_cmd
(
ar
->
wmi
,
vif
->
fw_vif_idx
,
0
,
0
,
0
,
0
,
0
,
0
,
3
,
0
,
0
,
0
);
if
(
ret
)
return
ret
;
return
0
;
}
int
ath6kl_cfg80211_suspend
(
struct
ath6kl
*
ar
,
enum
ath6kl_cfg_suspend_mode
mode
,
struct
cfg80211_wowlan
*
wow
)
{
struct
ath6kl_vif
*
vif
;
enum
ath6kl_state
prev_state
;
int
ret
;
...
...
@@ -2139,15 +2277,12 @@ int ath6kl_cfg80211_suspend(struct ath6kl *ar,
case
ATH6KL_CFG_SUSPEND_DEEPSLEEP
:
ath6kl_cfg80211_stop_all
(
ar
);
/* save the current power mode before enabling power save */
ar
->
wmi
->
saved_pwr_mode
=
ar
->
wmi
->
pwr_mode
;
ath6kl_dbg
(
ATH6KL_DBG_SUSPEND
,
"deep sleep suspend
\n
"
);
ret
=
ath6kl_
wmi_powermode_cmd
(
ar
->
wmi
,
0
,
REC_POWER
);
ret
=
ath6kl_
cfg80211_deepsleep_suspend
(
ar
);
if
(
ret
)
{
ath6kl_
warn
(
"wmi powermode command failed during suspend: %d
\n
"
,
ret
)
;
ath6kl_
err
(
"deepsleep suspend failed: %d
\n
"
,
ret
);
return
ret
;
}
ar
->
state
=
ATH6KL_STATE_DEEPSLEEP
;
...
...
@@ -2187,6 +2322,9 @@ int ath6kl_cfg80211_suspend(struct ath6kl *ar,
break
;
}
list_for_each_entry
(
vif
,
&
ar
->
vif_list
,
list
)
ath6kl_cfg80211_scan_complete_event
(
vif
,
true
);
return
0
;
}
EXPORT_SYMBOL
(
ath6kl_cfg80211_suspend
);
...
...
@@ -2208,17 +2346,13 @@ int ath6kl_cfg80211_resume(struct ath6kl *ar)
break
;
case
ATH6KL_STATE_DEEPSLEEP
:
if
(
ar
->
wmi
->
pwr_mode
!=
ar
->
wmi
->
saved_pwr_mode
)
{
ret
=
ath6kl_wmi_powermode_cmd
(
ar
->
wmi
,
0
,
ar
->
wmi
->
saved_pwr_mode
);
if
(
ret
)
{
ath6kl_warn
(
"wmi powermode command failed during resume: %d
\n
"
,
ret
);
}
}
ar
->
state
=
ATH6KL_STATE_ON
;
ath6kl_dbg
(
ATH6KL_DBG_SUSPEND
,
"deep sleep resume
\n
"
);
ret
=
ath6kl_cfg80211_deepsleep_resume
(
ar
);
if
(
ret
)
{
ath6kl_warn
(
"deep sleep resume failed: %d
\n
"
,
ret
);
return
ret
;
}
break
;
case
ATH6KL_STATE_CUTPOWER
:
...
...
@@ -2292,31 +2426,25 @@ void ath6kl_check_wow_status(struct ath6kl *ar)
}
#endif
static
int
ath6kl_set_channel
(
struct
wiphy
*
wiphy
,
struct
net_device
*
dev
,
struct
ieee80211_channel
*
chan
,
enum
nl80211_channel_type
channel_type
)
static
int
ath6kl_set_htcap
(
struct
ath6kl_vif
*
vif
,
enum
ieee80211_band
band
,
bool
ht_enable
)
{
struct
ath6kl_vif
*
vif
;
/*
* 'dev' could be NULL if a channel change is required for the hardware
* device itself, instead of a particular VIF.
*
* FIXME: To be handled properly when monitor mode is supported.
*/
if
(
!
dev
)
return
-
EBUSY
;
vif
=
netdev_priv
(
dev
);
struct
ath6kl_htcap
*
htcap
=
&
vif
->
htcap
;
if
(
!
ath6kl_cfg80211_ready
(
vif
)
)
return
-
EIO
;
if
(
htcap
->
ht_enable
==
ht_enable
)
return
0
;
ath6kl_dbg
(
ATH6KL_DBG_WLAN_CFG
,
"%s: center_freq=%u hw_value=%u
\n
"
,
__func__
,
chan
->
center_freq
,
chan
->
hw_value
);
vif
->
next_chan
=
chan
->
center_freq
;
if
(
ht_enable
)
{
/* Set default ht capabilities */
htcap
->
ht_enable
=
true
;
htcap
->
cap_info
=
(
band
==
IEEE80211_BAND_2GHZ
)
?
ath6kl_g_htcap
:
ath6kl_a_htcap
;
htcap
->
ampdu_factor
=
IEEE80211_HT_MAX_AMPDU_16K
;
}
else
/* Disable ht */
memset
(
htcap
,
0
,
sizeof
(
*
htcap
));
return
0
;
return
ath6kl_wmi_set_htcap_cmd
(
vif
->
ar
->
wmi
,
vif
->
fw_vif_idx
,
band
,
htcap
);
}
static
bool
ath6kl_is_p2p_ie
(
const
u8
*
pos
)
...
...
@@ -2393,6 +2521,81 @@ static int ath6kl_set_ies(struct ath6kl_vif *vif,
return
0
;
}
static
int
ath6kl_set_channel
(
struct
wiphy
*
wiphy
,
struct
net_device
*
dev
,
struct
ieee80211_channel
*
chan
,
enum
nl80211_channel_type
channel_type
)
{
struct
ath6kl_vif
*
vif
;
/*
* 'dev' could be NULL if a channel change is required for the hardware
* device itself, instead of a particular VIF.
*
* FIXME: To be handled properly when monitor mode is supported.
*/
if
(
!
dev
)
return
-
EBUSY
;
vif
=
netdev_priv
(
dev
);
if
(
!
ath6kl_cfg80211_ready
(
vif
))
return
-
EIO
;
ath6kl_dbg
(
ATH6KL_DBG_WLAN_CFG
,
"%s: center_freq=%u hw_value=%u
\n
"
,
__func__
,
chan
->
center_freq
,
chan
->
hw_value
);
vif
->
next_chan
=
chan
->
center_freq
;
vif
->
next_ch_type
=
channel_type
;
vif
->
next_ch_band
=
chan
->
band
;
return
0
;
}
static
int
ath6kl_get_rsn_capab
(
struct
cfg80211_beacon_data
*
beacon
,
u8
*
rsn_capab
)
{
const
u8
*
rsn_ie
;
size_t
rsn_ie_len
;
u16
cnt
;
if
(
!
beacon
->
tail
)
return
-
EINVAL
;
rsn_ie
=
cfg80211_find_ie
(
WLAN_EID_RSN
,
beacon
->
tail
,
beacon
->
tail_len
);
if
(
!
rsn_ie
)
return
-
EINVAL
;
rsn_ie_len
=
*
(
rsn_ie
+
1
);
/* skip element id and length */
rsn_ie
+=
2
;
/* skip version, group cipher */
if
(
rsn_ie_len
<
6
)
return
-
EINVAL
;
rsn_ie
+=
6
;
rsn_ie_len
-=
6
;
/* skip pairwise cipher suite */
if
(
rsn_ie_len
<
2
)
return
-
EINVAL
;
cnt
=
*
((
u16
*
)
rsn_ie
);
rsn_ie
+=
(
2
+
cnt
*
4
);
rsn_ie_len
-=
(
2
+
cnt
*
4
);
/* skip akm suite */
if
(
rsn_ie_len
<
2
)
return
-
EINVAL
;
cnt
=
*
((
u16
*
)
rsn_ie
);
rsn_ie
+=
(
2
+
cnt
*
4
);
rsn_ie_len
-=
(
2
+
cnt
*
4
);
if
(
rsn_ie_len
<
2
)
return
-
EINVAL
;
memcpy
(
rsn_capab
,
rsn_ie
,
2
);
return
0
;
}
static
int
ath6kl_start_ap
(
struct
wiphy
*
wiphy
,
struct
net_device
*
dev
,
struct
cfg80211_ap_settings
*
info
)
{
...
...
@@ -2405,6 +2608,7 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
struct
wmi_connect_cmd
p
;
int
res
;
int
i
,
ret
;
u16
rsn_capab
=
0
;
ath6kl_dbg
(
ATH6KL_DBG_WLAN_CFG
,
"%s:
\n
"
,
__func__
);
...
...
@@ -2534,6 +2738,34 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
p
.
nw_subtype
=
SUBTYPE_NONE
;
}
if
(
info
->
inactivity_timeout
)
{
res
=
ath6kl_wmi_set_inact_period
(
ar
->
wmi
,
vif
->
fw_vif_idx
,
info
->
inactivity_timeout
);
if
(
res
<
0
)
return
res
;
}
if
(
ath6kl_set_htcap
(
vif
,
vif
->
next_ch_band
,
vif
->
next_ch_type
!=
NL80211_CHAN_NO_HT
))
return
-
EIO
;
/*
* Get the PTKSA replay counter in the RSN IE. Supplicant
* will use the RSN IE in M3 message and firmware has to
* advertise the same in beacon/probe response. Send
* the complete RSN IE capability field to firmware
*/
if
(
!
ath6kl_get_rsn_capab
(
&
info
->
beacon
,
(
u8
*
)
&
rsn_capab
)
&&
test_bit
(
ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE
,
ar
->
fw_capabilities
))
{
res
=
ath6kl_wmi_set_ie_cmd
(
ar
->
wmi
,
vif
->
fw_vif_idx
,
WLAN_EID_RSN
,
WMI_RSN_IE_CAPB
,
(
const
u8
*
)
&
rsn_capab
,
sizeof
(
rsn_capab
));
if
(
res
<
0
)
return
res
;
}
res
=
ath6kl_wmi_ap_profile_commit
(
ar
->
wmi
,
vif
->
fw_vif_idx
,
&
p
);
if
(
res
<
0
)
return
res
;
...
...
@@ -2568,6 +2800,13 @@ static int ath6kl_stop_ap(struct wiphy *wiphy, struct net_device *dev)
ath6kl_wmi_disconnect_cmd
(
ar
->
wmi
,
vif
->
fw_vif_idx
);
clear_bit
(
CONNECTED
,
&
vif
->
flags
);
/* Restore ht setting in firmware */
if
(
ath6kl_set_htcap
(
vif
,
IEEE80211_BAND_2GHZ
,
true
))
return
-
EIO
;
if
(
ath6kl_set_htcap
(
vif
,
IEEE80211_BAND_5GHZ
,
true
))
return
-
EIO
;
return
0
;
}
...
...
@@ -2749,6 +2988,21 @@ static bool ath6kl_mgmt_powersave_ap(struct ath6kl_vif *vif,
return
false
;
}
/* Check if SSID length is greater than DIRECT- */
static
bool
ath6kl_is_p2p_go_ssid
(
const
u8
*
buf
,
size_t
len
)
{
const
struct
ieee80211_mgmt
*
mgmt
;
mgmt
=
(
const
struct
ieee80211_mgmt
*
)
buf
;
/* variable[1] contains the SSID tag length */
if
(
buf
+
len
>=
&
mgmt
->
u
.
probe_resp
.
variable
[
1
]
&&
(
mgmt
->
u
.
probe_resp
.
variable
[
1
]
>
P2P_WILDCARD_SSID_LEN
))
{
return
true
;
}
return
false
;
}
static
int
ath6kl_mgmt_tx
(
struct
wiphy
*
wiphy
,
struct
net_device
*
dev
,
struct
ieee80211_channel
*
chan
,
bool
offchan
,
enum
nl80211_channel_type
channel_type
,
...
...
@@ -2763,11 +3017,11 @@ static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
bool
more_data
,
queued
;
mgmt
=
(
const
struct
ieee80211_mgmt
*
)
buf
;
if
(
buf
+
len
>=
mgmt
->
u
.
probe_resp
.
variable
&&
vif
->
nw_type
==
AP_NETWORK
&&
test_bit
(
CONNECTED
,
&
vif
->
flags
)
&&
ieee80211_is_probe_resp
(
mgmt
->
frame_control
))
{
if
(
vif
->
nw_type
==
AP_NETWORK
&&
test_bit
(
CONNECTED
,
&
vif
->
flags
)
&&
ieee80211_is_probe_resp
(
mgmt
->
frame_control
)
&&
ath6kl_is_p2p_go_ssid
(
buf
,
len
))
{
/*
* Send Probe Response frame in
AP
mode using a separate WMI
* Send Probe Response frame in
GO
mode using a separate WMI
* command to allow the target to fill in the generic IEs.
*/
*
cookie
=
0
;
/* TX status not supported */
...
...
@@ -2835,6 +3089,8 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy,
if
(
vif
->
sme_state
!=
SME_DISCONNECTED
)
return
-
EBUSY
;
ath6kl_cfg80211_scan_complete_event
(
vif
,
true
);
for
(
i
=
0
;
i
<
ar
->
wiphy
->
max_sched_scan_ssids
;
i
++
)
{
ath6kl_wmi_probedssid_cmd
(
ar
->
wmi
,
vif
->
fw_vif_idx
,
i
,
DISABLE_SSID_FLAG
,
...
...
@@ -3096,6 +3352,7 @@ struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
vif
->
next_mode
=
nw_type
;
vif
->
listen_intvl_t
=
ATH6KL_DEFAULT_LISTEN_INTVAL
;
vif
->
bmiss_time_t
=
ATH6KL_DEFAULT_BMISS_TIME
;
vif
->
htcap
.
ht_enable
=
true
;
memcpy
(
ndev
->
dev_addr
,
ar
->
mac_addr
,
ETH_ALEN
);
if
(
fw_vif_idx
!=
0
)
...
...
@@ -3183,6 +3440,10 @@ int ath6kl_cfg80211_init(struct ath6kl *ar)
if
(
test_bit
(
ATH6KL_FW_CAPABILITY_SCHED_SCAN
,
ar
->
fw_capabilities
))
ar
->
wiphy
->
flags
|=
WIPHY_FLAG_SUPPORTS_SCHED_SCAN
;
if
(
test_bit
(
ATH6KL_FW_CAPABILITY_INACTIVITY_TIMEOUT
,
ar
->
fw_capabilities
))
ar
->
wiphy
->
features
=
NL80211_FEATURE_INACTIVITY_TIMER
;
ar
->
wiphy
->
probe_resp_offload
=
NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS
|
NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2
|
...
...
drivers/net/wireless/ath/ath6kl/common.h
浏览文件 @
c2786e4a
...
...
@@ -22,7 +22,8 @@
#define ATH6KL_MAX_IE 256
extern
int
ath6kl_printk
(
const
char
*
level
,
const
char
*
fmt
,
...);
extern
__printf
(
2
,
3
)
int
ath6kl_printk
(
const
char
*
level
,
const
char
*
fmt
,
...);
/*
* Reflects the version of binary interface exposed by ATH6KL target
...
...
@@ -77,6 +78,7 @@ enum crypto_type {
struct
htc_endpoint_credit_dist
;
struct
ath6kl
;
struct
ath6kl_htcap
;
enum
htc_credit_dist_reason
;
struct
ath6kl_htc_credit_info
;
...
...
drivers/net/wireless/ath/ath6kl/core.c
浏览文件 @
c2786e4a
...
...
@@ -20,9 +20,11 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/export.h>
#include <linux/vmalloc.h>
#include "debug.h"
#include "hif-ops.h"
#include "htc-ops.h"
#include "cfg80211.h"
unsigned
int
debug_mask
;
...
...
@@ -39,12 +41,36 @@ module_param(uart_debug, uint, 0644);
module_param
(
ath6kl_p2p
,
uint
,
0644
);
module_param
(
testmode
,
uint
,
0644
);
int
ath6kl_core_init
(
struct
ath6kl
*
ar
)
void
ath6kl_core_tx_complete
(
struct
ath6kl
*
ar
,
struct
sk_buff
*
skb
)
{
ath6kl_htc_tx_complete
(
ar
,
skb
);
}
EXPORT_SYMBOL
(
ath6kl_core_tx_complete
);
void
ath6kl_core_rx_complete
(
struct
ath6kl
*
ar
,
struct
sk_buff
*
skb
,
u8
pipe
)
{
ath6kl_htc_rx_complete
(
ar
,
skb
,
pipe
);
}
EXPORT_SYMBOL
(
ath6kl_core_rx_complete
);
int
ath6kl_core_init
(
struct
ath6kl
*
ar
,
enum
ath6kl_htc_type
htc_type
)
{
struct
ath6kl_bmi_target_info
targ_info
;
struct
net_device
*
ndev
;
int
ret
=
0
,
i
;
switch
(
htc_type
)
{
case
ATH6KL_HTC_TYPE_MBOX
:
ath6kl_htc_mbox_attach
(
ar
);
break
;
case
ATH6KL_HTC_TYPE_PIPE
:
ath6kl_htc_pipe_attach
(
ar
);
break
;
default:
WARN_ON
(
1
);
return
-
ENOMEM
;
}
ar
->
ath6kl_wq
=
create_singlethread_workqueue
(
"ath6kl"
);
if
(
!
ar
->
ath6kl_wq
)
return
-
ENOMEM
;
...
...
@@ -280,7 +306,7 @@ void ath6kl_core_cleanup(struct ath6kl *ar)
kfree
(
ar
->
fw_board
);
kfree
(
ar
->
fw_otp
);
k
free
(
ar
->
fw
);
v
free
(
ar
->
fw
);
kfree
(
ar
->
fw_patch
);
kfree
(
ar
->
fw_testscript
);
...
...
drivers/net/wireless/ath/ath6kl/core.h
浏览文件 @
c2786e4a
...
...
@@ -91,6 +91,15 @@ enum ath6kl_fw_capability {
*/
ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX
,
/*
* Firmware has support to cleanup inactive stations
* in AP mode.
*/
ATH6KL_FW_CAPABILITY_INACTIVITY_TIMEOUT
,
/* Firmware has support to override rsn cap of rsn ie */
ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE
,
/* this needs to be last */
ATH6KL_FW_CAPABILITY_MAX
,
};
...
...
@@ -205,6 +214,8 @@ struct ath6kl_fw_ie {
#define ATH6KL_CONF_ENABLE_TX_BURST BIT(3)
#define ATH6KL_CONF_UART_DEBUG BIT(4)
#define P2P_WILDCARD_SSID_LEN 7
/* DIRECT- */
enum
wlan_low_pwr_state
{
WLAN_POWER_STATE_ON
,
WLAN_POWER_STATE_CUT_PWR
,
...
...
@@ -454,6 +465,11 @@ enum ath6kl_hif_type {
ATH6KL_HIF_TYPE_USB
,
};
enum
ath6kl_htc_type
{
ATH6KL_HTC_TYPE_MBOX
,
ATH6KL_HTC_TYPE_PIPE
,
};
/* Max number of filters that hw supports */
#define ATH6K_MAX_MC_FILTERS_PER_LIST 7
struct
ath6kl_mc_filter
{
...
...
@@ -461,6 +477,12 @@ struct ath6kl_mc_filter {
char
hw_addr
[
ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE
];
};
struct
ath6kl_htcap
{
bool
ht_enable
;
u8
ampdu_factor
;
unsigned
short
cap_info
;
};
/*
* Driver's maximum limit, note that some firmwares support only one vif
* and the runtime (current) limit must be checked from ar->vif_max.
...
...
@@ -509,6 +531,7 @@ struct ath6kl_vif {
struct
ath6kl_wep_key
wep_key_list
[
WMI_MAX_KEY_INDEX
+
1
];
struct
ath6kl_key
keys
[
WMI_MAX_KEY_INDEX
+
1
];
struct
aggr_info
*
aggr_cntxt
;
struct
ath6kl_htcap
htcap
;
struct
timer_list
disconnect_timer
;
struct
timer_list
sched_scan_timer
;
...
...
@@ -521,6 +544,8 @@ struct ath6kl_vif {
u32
send_action_id
;
bool
probe_req_report
;
u16
next_chan
;
enum
nl80211_channel_type
next_ch_type
;
enum
ieee80211_band
next_ch_band
;
u16
assoc_bss_beacon_int
;
u16
listen_intvl_t
;
u16
bmiss_time_t
;
...
...
@@ -568,6 +593,7 @@ struct ath6kl {
struct
ath6kl_bmi
bmi
;
const
struct
ath6kl_hif_ops
*
hif_ops
;
const
struct
ath6kl_htc_ops
*
htc_ops
;
struct
wmi
*
wmi
;
int
tx_pending
[
ENDPOINT_MAX
];
int
total_tx_data_pend
;
...
...
@@ -746,7 +772,8 @@ void init_netdev(struct net_device *dev);
void
ath6kl_cookie_init
(
struct
ath6kl
*
ar
);
void
ath6kl_cookie_cleanup
(
struct
ath6kl
*
ar
);
void
ath6kl_rx
(
struct
htc_target
*
target
,
struct
htc_packet
*
packet
);
void
ath6kl_tx_complete
(
void
*
context
,
struct
list_head
*
packet_queue
);
void
ath6kl_tx_complete
(
struct
htc_target
*
context
,
struct
list_head
*
packet_queue
);
enum
htc_send_full_action
ath6kl_tx_queue_full
(
struct
htc_target
*
target
,
struct
htc_packet
*
packet
);
void
ath6kl_stop_txrx
(
struct
ath6kl
*
ar
);
...
...
@@ -821,8 +848,11 @@ int ath6kl_init_hw_params(struct ath6kl *ar);
void
ath6kl_check_wow_status
(
struct
ath6kl
*
ar
);
void
ath6kl_core_tx_complete
(
struct
ath6kl
*
ar
,
struct
sk_buff
*
skb
);
void
ath6kl_core_rx_complete
(
struct
ath6kl
*
ar
,
struct
sk_buff
*
skb
,
u8
pipe
);
struct
ath6kl
*
ath6kl_core_create
(
struct
device
*
dev
);
int
ath6kl_core_init
(
struct
ath6kl
*
ar
);
int
ath6kl_core_init
(
struct
ath6kl
*
ar
,
enum
ath6kl_htc_type
htc_type
);
void
ath6kl_core_cleanup
(
struct
ath6kl
*
ar
);
void
ath6kl_core_destroy
(
struct
ath6kl
*
ar
);
...
...
drivers/net/wireless/ath/ath6kl/debug.c
浏览文件 @
c2786e4a
...
...
@@ -616,6 +616,12 @@ static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf,
"Num disconnects"
,
tgt_stats
->
cs_discon_cnt
);
len
+=
scnprintf
(
buf
+
len
,
buf_len
-
len
,
"%20s %10d
\n
"
,
"Beacon avg rssi"
,
tgt_stats
->
cs_ave_beacon_rssi
);
len
+=
scnprintf
(
buf
+
len
,
buf_len
-
len
,
"%20s %10d
\n
"
,
"ARP pkt received"
,
tgt_stats
->
arp_received
);
len
+=
scnprintf
(
buf
+
len
,
buf_len
-
len
,
"%20s %10d
\n
"
,
"ARP pkt matched"
,
tgt_stats
->
arp_matched
);
len
+=
scnprintf
(
buf
+
len
,
buf_len
-
len
,
"%20s %10d
\n
"
,
"ARP pkt replied"
,
tgt_stats
->
arp_replied
);
if
(
len
>
buf_len
)
len
=
buf_len
;
...
...
drivers/net/wireless/ath/ath6kl/debug.h
浏览文件 @
c2786e4a
...
...
@@ -43,6 +43,7 @@ enum ATH6K_DEBUG_MASK {
ATH6KL_DBG_WMI_DUMP
=
BIT
(
19
),
ATH6KL_DBG_SUSPEND
=
BIT
(
20
),
ATH6KL_DBG_USB
=
BIT
(
21
),
ATH6KL_DBG_USB_BULK
=
BIT
(
22
),
ATH6KL_DBG_ANY
=
0xffffffff
/* enable all logs */
};
...
...
drivers/net/wireless/ath/ath6kl/hif-ops.h
浏览文件 @
c2786e4a
...
...
@@ -150,4 +150,38 @@ static inline void ath6kl_hif_stop(struct ath6kl *ar)
ar
->
hif_ops
->
stop
(
ar
);
}
static
inline
int
ath6kl_hif_pipe_send
(
struct
ath6kl
*
ar
,
u8
pipe
,
struct
sk_buff
*
hdr_buf
,
struct
sk_buff
*
buf
)
{
ath6kl_dbg
(
ATH6KL_DBG_HIF
,
"hif pipe send
\n
"
);
return
ar
->
hif_ops
->
pipe_send
(
ar
,
pipe
,
hdr_buf
,
buf
);
}
static
inline
void
ath6kl_hif_pipe_get_default
(
struct
ath6kl
*
ar
,
u8
*
ul_pipe
,
u8
*
dl_pipe
)
{
ath6kl_dbg
(
ATH6KL_DBG_HIF
,
"hif pipe get default
\n
"
);
ar
->
hif_ops
->
pipe_get_default
(
ar
,
ul_pipe
,
dl_pipe
);
}
static
inline
int
ath6kl_hif_pipe_map_service
(
struct
ath6kl
*
ar
,
u16
service_id
,
u8
*
ul_pipe
,
u8
*
dl_pipe
)
{
ath6kl_dbg
(
ATH6KL_DBG_HIF
,
"hif pipe get default
\n
"
);
return
ar
->
hif_ops
->
pipe_map_service
(
ar
,
service_id
,
ul_pipe
,
dl_pipe
);
}
static
inline
u16
ath6kl_hif_pipe_get_free_queue_number
(
struct
ath6kl
*
ar
,
u8
pipe
)
{
ath6kl_dbg
(
ATH6KL_DBG_HIF
,
"hif pipe get free queue number
\n
"
);
return
ar
->
hif_ops
->
pipe_get_free_queue_number
(
ar
,
pipe
);
}
#endif
drivers/net/wireless/ath/ath6kl/hif.h
浏览文件 @
c2786e4a
...
...
@@ -256,6 +256,12 @@ struct ath6kl_hif_ops {
int
(
*
power_on
)(
struct
ath6kl
*
ar
);
int
(
*
power_off
)(
struct
ath6kl
*
ar
);
void
(
*
stop
)(
struct
ath6kl
*
ar
);
int
(
*
pipe_send
)(
struct
ath6kl
*
ar
,
u8
pipe
,
struct
sk_buff
*
hdr_buf
,
struct
sk_buff
*
buf
);
void
(
*
pipe_get_default
)(
struct
ath6kl
*
ar
,
u8
*
pipe_ul
,
u8
*
pipe_dl
);
int
(
*
pipe_map_service
)(
struct
ath6kl
*
ar
,
u16
service_id
,
u8
*
pipe_ul
,
u8
*
pipe_dl
);
u16
(
*
pipe_get_free_queue_number
)(
struct
ath6kl
*
ar
,
u8
pipe
);
};
int
ath6kl_hif_setup
(
struct
ath6kl_device
*
dev
);
...
...
drivers/net/wireless/ath/ath6kl/htc-ops.h
0 → 100644
浏览文件 @
c2786e4a
/*
* Copyright (c) 2004-2011 Atheros Communications Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef HTC_OPS_H
#define HTC_OPS_H
#include "htc.h"
#include "debug.h"
static
inline
void
*
ath6kl_htc_create
(
struct
ath6kl
*
ar
)
{
return
ar
->
htc_ops
->
create
(
ar
);
}
static
inline
int
ath6kl_htc_wait_target
(
struct
htc_target
*
target
)
{
return
target
->
dev
->
ar
->
htc_ops
->
wait_target
(
target
);
}
static
inline
int
ath6kl_htc_start
(
struct
htc_target
*
target
)
{
return
target
->
dev
->
ar
->
htc_ops
->
start
(
target
);
}
static
inline
int
ath6kl_htc_conn_service
(
struct
htc_target
*
target
,
struct
htc_service_connect_req
*
req
,
struct
htc_service_connect_resp
*
resp
)
{
return
target
->
dev
->
ar
->
htc_ops
->
conn_service
(
target
,
req
,
resp
);
}
static
inline
int
ath6kl_htc_tx
(
struct
htc_target
*
target
,
struct
htc_packet
*
packet
)
{
return
target
->
dev
->
ar
->
htc_ops
->
tx
(
target
,
packet
);
}
static
inline
void
ath6kl_htc_stop
(
struct
htc_target
*
target
)
{
return
target
->
dev
->
ar
->
htc_ops
->
stop
(
target
);
}
static
inline
void
ath6kl_htc_cleanup
(
struct
htc_target
*
target
)
{
return
target
->
dev
->
ar
->
htc_ops
->
cleanup
(
target
);
}
static
inline
void
ath6kl_htc_flush_txep
(
struct
htc_target
*
target
,
enum
htc_endpoint_id
endpoint
,
u16
tag
)
{
return
target
->
dev
->
ar
->
htc_ops
->
flush_txep
(
target
,
endpoint
,
tag
);
}
static
inline
void
ath6kl_htc_flush_rx_buf
(
struct
htc_target
*
target
)
{
return
target
->
dev
->
ar
->
htc_ops
->
flush_rx_buf
(
target
);
}
static
inline
void
ath6kl_htc_activity_changed
(
struct
htc_target
*
target
,
enum
htc_endpoint_id
endpoint
,
bool
active
)
{
return
target
->
dev
->
ar
->
htc_ops
->
activity_changed
(
target
,
endpoint
,
active
);
}
static
inline
int
ath6kl_htc_get_rxbuf_num
(
struct
htc_target
*
target
,
enum
htc_endpoint_id
endpoint
)
{
return
target
->
dev
->
ar
->
htc_ops
->
get_rxbuf_num
(
target
,
endpoint
);
}
static
inline
int
ath6kl_htc_add_rxbuf_multiple
(
struct
htc_target
*
target
,
struct
list_head
*
pktq
)
{
return
target
->
dev
->
ar
->
htc_ops
->
add_rxbuf_multiple
(
target
,
pktq
);
}
static
inline
int
ath6kl_htc_credit_setup
(
struct
htc_target
*
target
,
struct
ath6kl_htc_credit_info
*
info
)
{
return
target
->
dev
->
ar
->
htc_ops
->
credit_setup
(
target
,
info
);
}
static
inline
void
ath6kl_htc_tx_complete
(
struct
ath6kl
*
ar
,
struct
sk_buff
*
skb
)
{
ar
->
htc_ops
->
tx_complete
(
ar
,
skb
);
}
static
inline
void
ath6kl_htc_rx_complete
(
struct
ath6kl
*
ar
,
struct
sk_buff
*
skb
,
u8
pipe
)
{
ar
->
htc_ops
->
rx_complete
(
ar
,
skb
,
pipe
);
}
#endif
drivers/net/wireless/ath/ath6kl/htc.h
浏览文件 @
c2786e4a
...
...
@@ -25,6 +25,7 @@
/* send direction */
#define HTC_FLAGS_NEED_CREDIT_UPDATE (1 << 0)
#define HTC_FLAGS_SEND_BUNDLE (1 << 1)
#define HTC_FLAGS_TX_FIXUP_NETBUF (1 << 2)
/* receive direction */
#define HTC_FLG_RX_UNUSED (1 << 0)
...
...
@@ -56,6 +57,10 @@
#define HTC_CONN_FLGS_THRESH_LVL_THREE_QUAT 0x2
#define HTC_CONN_FLGS_REDUCE_CRED_DRIB 0x4
#define HTC_CONN_FLGS_THRESH_MASK 0x3
/* disable credit flow control on a specific service */
#define HTC_CONN_FLGS_DISABLE_CRED_FLOW_CTRL (1 << 3)
#define HTC_CONN_FLGS_SET_RECV_ALLOC_SHIFT 8
#define HTC_CONN_FLGS_SET_RECV_ALLOC_MASK 0xFF00
/* connect response status codes */
#define HTC_SERVICE_SUCCESS 0
...
...
@@ -75,6 +80,7 @@
#define HTC_RECORD_LOOKAHEAD_BUNDLE 3
#define HTC_SETUP_COMP_FLG_RX_BNDL_EN (1 << 0)
#define HTC_SETUP_COMP_FLG_DISABLE_TX_CREDIT_FLOW (1 << 1)
#define MAKE_SERVICE_ID(group, index) \
(int)(((int)group << 8) | (int)(index))
...
...
@@ -109,6 +115,8 @@
/* HTC operational parameters */
#define HTC_TARGET_RESPONSE_TIMEOUT 2000
/* in ms */
#define HTC_TARGET_RESPONSE_POLL_WAIT 10
#define HTC_TARGET_RESPONSE_POLL_COUNT 200
#define HTC_TARGET_DEBUG_INTR_MASK 0x01
#define HTC_TARGET_CREDIT_INTR_MASK 0xF0
...
...
@@ -128,6 +136,7 @@
#define HTC_RECV_WAIT_BUFFERS (1 << 0)
#define HTC_OP_STATE_STOPPING (1 << 0)
#define HTC_OP_STATE_SETUP_COMPLETE (1 << 1)
/*
* The frame header length and message formats defined herein were selected
...
...
@@ -311,6 +320,14 @@ struct htc_packet {
void
(
*
completion
)
(
struct
htc_target
*
,
struct
htc_packet
*
);
struct
htc_target
*
context
;
/*
* optimization for network-oriented data, the HTC packet
* can pass the network buffer corresponding to the HTC packet
* lower layers may optimized the transfer knowing this is
* a network buffer
*/
struct
sk_buff
*
skb
;
};
enum
htc_send_full_action
{
...
...
@@ -319,12 +336,14 @@ enum htc_send_full_action {
};
struct
htc_ep_callbacks
{
void
(
*
tx_complete
)
(
struct
htc_target
*
,
struct
htc_packet
*
);
void
(
*
rx
)
(
struct
htc_target
*
,
struct
htc_packet
*
);
void
(
*
rx_refill
)
(
struct
htc_target
*
,
enum
htc_endpoint_id
endpoint
);
enum
htc_send_full_action
(
*
tx_full
)
(
struct
htc_target
*
,
struct
htc_packet
*
);
struct
htc_packet
*
(
*
rx_allocthresh
)
(
struct
htc_target
*
,
enum
htc_endpoint_id
,
int
);
void
(
*
tx_comp_multi
)
(
struct
htc_target
*
,
struct
list_head
*
);
int
rx_alloc_thresh
;
int
rx_refill_thresh
;
};
...
...
@@ -502,6 +521,13 @@ struct htc_endpoint {
u32
conn_flags
;
struct
htc_endpoint_stats
ep_st
;
u16
tx_drop_packet_threshold
;
struct
{
u8
pipeid_ul
;
u8
pipeid_dl
;
struct
list_head
tx_lookup_queue
;
bool
tx_credit_flow_enabled
;
}
pipe
;
};
struct
htc_control_buffer
{
...
...
@@ -509,6 +535,42 @@ struct htc_control_buffer {
u8
*
buf
;
};
struct
htc_pipe_txcredit_alloc
{
u16
service_id
;
u8
credit_alloc
;
};
enum
htc_send_queue_result
{
HTC_SEND_QUEUE_OK
=
0
,
/* packet was queued */
HTC_SEND_QUEUE_DROP
=
1
,
/* this packet should be dropped */
};
struct
ath6kl_htc_ops
{
void
*
(
*
create
)(
struct
ath6kl
*
ar
);
int
(
*
wait_target
)(
struct
htc_target
*
target
);
int
(
*
start
)(
struct
htc_target
*
target
);
int
(
*
conn_service
)(
struct
htc_target
*
target
,
struct
htc_service_connect_req
*
req
,
struct
htc_service_connect_resp
*
resp
);
int
(
*
tx
)(
struct
htc_target
*
target
,
struct
htc_packet
*
packet
);
void
(
*
stop
)(
struct
htc_target
*
target
);
void
(
*
cleanup
)(
struct
htc_target
*
target
);
void
(
*
flush_txep
)(
struct
htc_target
*
target
,
enum
htc_endpoint_id
endpoint
,
u16
tag
);
void
(
*
flush_rx_buf
)(
struct
htc_target
*
target
);
void
(
*
activity_changed
)(
struct
htc_target
*
target
,
enum
htc_endpoint_id
endpoint
,
bool
active
);
int
(
*
get_rxbuf_num
)(
struct
htc_target
*
target
,
enum
htc_endpoint_id
endpoint
);
int
(
*
add_rxbuf_multiple
)(
struct
htc_target
*
target
,
struct
list_head
*
pktq
);
int
(
*
credit_setup
)(
struct
htc_target
*
target
,
struct
ath6kl_htc_credit_info
*
cred_info
);
int
(
*
tx_complete
)(
struct
ath6kl
*
ar
,
struct
sk_buff
*
skb
);
int
(
*
rx_complete
)(
struct
ath6kl
*
ar
,
struct
sk_buff
*
skb
,
u8
pipe
);
};
struct
ath6kl_device
;
/* our HTC target state */
...
...
@@ -557,36 +619,19 @@ struct htc_target {
/* counts the number of Tx without bundling continously per AC */
u32
ac_tx_count
[
WMM_NUM_AC
];
struct
{
struct
htc_packet
*
htc_packet_pool
;
u8
ctrl_response_buf
[
HTC_MAX_CTRL_MSG_LEN
];
int
ctrl_response_len
;
bool
ctrl_response_valid
;
struct
htc_pipe_txcredit_alloc
txcredit_alloc
[
ENDPOINT_MAX
];
}
pipe
;
};
void
*
ath6kl_htc_create
(
struct
ath6kl
*
ar
);
void
ath6kl_htc_set_credit_dist
(
struct
htc_target
*
target
,
struct
ath6kl_htc_credit_info
*
cred_info
,
u16
svc_pri_order
[],
int
len
);
int
ath6kl_htc_wait_target
(
struct
htc_target
*
target
);
int
ath6kl_htc_start
(
struct
htc_target
*
target
);
int
ath6kl_htc_conn_service
(
struct
htc_target
*
target
,
struct
htc_service_connect_req
*
req
,
struct
htc_service_connect_resp
*
resp
);
int
ath6kl_htc_tx
(
struct
htc_target
*
target
,
struct
htc_packet
*
packet
);
void
ath6kl_htc_stop
(
struct
htc_target
*
target
);
void
ath6kl_htc_cleanup
(
struct
htc_target
*
target
);
void
ath6kl_htc_flush_txep
(
struct
htc_target
*
target
,
enum
htc_endpoint_id
endpoint
,
u16
tag
);
void
ath6kl_htc_flush_rx_buf
(
struct
htc_target
*
target
);
void
ath6kl_htc_indicate_activity_change
(
struct
htc_target
*
target
,
enum
htc_endpoint_id
endpoint
,
bool
active
);
int
ath6kl_htc_get_rxbuf_num
(
struct
htc_target
*
target
,
enum
htc_endpoint_id
endpoint
);
int
ath6kl_htc_add_rxbuf_multiple
(
struct
htc_target
*
target
,
struct
list_head
*
pktq
);
int
ath6kl_htc_rxmsg_pending_handler
(
struct
htc_target
*
target
,
u32
msg_look_ahead
,
int
*
n_pkts
);
int
ath6kl_credit_setup
(
void
*
htc_handle
,
struct
ath6kl_htc_credit_info
*
cred_info
);
static
inline
void
set_htc_pkt_info
(
struct
htc_packet
*
packet
,
void
*
context
,
u8
*
buf
,
unsigned
int
len
,
enum
htc_endpoint_id
eid
,
u16
tag
)
...
...
@@ -626,4 +671,7 @@ static inline int get_queue_depth(struct list_head *queue)
return
depth
;
}
void
ath6kl_htc_pipe_attach
(
struct
ath6kl
*
ar
);
void
ath6kl_htc_mbox_attach
(
struct
ath6kl
*
ar
);
#endif
drivers/net/wireless/ath/ath6kl/htc.c
→
drivers/net/wireless/ath/ath6kl/htc
_mbox
.c
浏览文件 @
c2786e4a
...
...
@@ -23,6 +23,14 @@
#define CALC_TXRX_PADDED_LEN(dev, len) (__ALIGN_MASK((len), (dev)->block_mask))
static
void
ath6kl_htc_mbox_cleanup
(
struct
htc_target
*
target
);
static
void
ath6kl_htc_mbox_stop
(
struct
htc_target
*
target
);
static
int
ath6kl_htc_mbox_add_rxbuf_multiple
(
struct
htc_target
*
target
,
struct
list_head
*
pkt_queue
);
static
void
ath6kl_htc_set_credit_dist
(
struct
htc_target
*
target
,
struct
ath6kl_htc_credit_info
*
cred_info
,
u16
svc_pri_order
[],
int
len
);
/* threshold to re-enable Tx bundling for an AC*/
#define TX_RESUME_BUNDLE_THRESHOLD 1500
...
...
@@ -130,8 +138,8 @@ static void ath6kl_credit_init(struct ath6kl_htc_credit_info *cred_info,
}
/* initialize and setup credit distribution */
int
ath6kl_credit_setup
(
void
*
htc_handle
,
struct
ath6kl_htc_credit_info
*
cred_info
)
static
int
ath6kl_htc_mbox_credit_setup
(
struct
htc_target
*
htc_target
,
struct
ath6kl_htc_credit_info
*
cred_info
)
{
u16
servicepriority
[
5
];
...
...
@@ -144,7 +152,7 @@ int ath6kl_credit_setup(void *htc_handle,
servicepriority
[
4
]
=
WMI_DATA_BK_SVC
;
/* lowest */
/* set priority list */
ath6kl_htc_set_credit_dist
(
htc_
handle
,
cred_info
,
servicepriority
,
5
);
ath6kl_htc_set_credit_dist
(
htc_
target
,
cred_info
,
servicepriority
,
5
);
return
0
;
}
...
...
@@ -432,7 +440,7 @@ static void htc_tx_complete(struct htc_endpoint *endpoint,
"htc tx complete ep %d pkts %d
\n
"
,
endpoint
->
eid
,
get_queue_depth
(
txq
));
ath6kl_tx_complete
(
endpoint
->
target
->
dev
->
ar
,
txq
);
ath6kl_tx_complete
(
endpoint
->
target
,
txq
);
}
static
void
htc_tx_comp_handler
(
struct
htc_target
*
target
,
...
...
@@ -1065,7 +1073,7 @@ static int htc_setup_tx_complete(struct htc_target *target)
return
status
;
}
void
ath6kl_htc_set_credit_dist
(
struct
htc_target
*
target
,
static
void
ath6kl_htc_set_credit_dist
(
struct
htc_target
*
target
,
struct
ath6kl_htc_credit_info
*
credit_info
,
u16
srvc_pri_order
[],
int
list_len
)
{
...
...
@@ -1093,7 +1101,8 @@ void ath6kl_htc_set_credit_dist(struct htc_target *target,
}
}
int
ath6kl_htc_tx
(
struct
htc_target
*
target
,
struct
htc_packet
*
packet
)
static
int
ath6kl_htc_mbox_tx
(
struct
htc_target
*
target
,
struct
htc_packet
*
packet
)
{
struct
htc_endpoint
*
endpoint
;
struct
list_head
queue
;
...
...
@@ -1121,7 +1130,7 @@ int ath6kl_htc_tx(struct htc_target *target, struct htc_packet *packet)
}
/* flush endpoint TX queue */
void
ath6kl_htc
_flush_txep
(
struct
htc_target
*
target
,
static
void
ath6kl_htc_mbox
_flush_txep
(
struct
htc_target
*
target
,
enum
htc_endpoint_id
eid
,
u16
tag
)
{
struct
htc_packet
*
packet
,
*
tmp_pkt
;
...
...
@@ -1173,12 +1182,13 @@ static void ath6kl_htc_flush_txep_all(struct htc_target *target)
if
(
endpoint
->
svc_id
==
0
)
/* not in use.. */
continue
;
ath6kl_htc_flush_txep
(
target
,
i
,
HTC_TX_PACKET_TAG_ALL
);
ath6kl_htc_
mbox_
flush_txep
(
target
,
i
,
HTC_TX_PACKET_TAG_ALL
);
}
}
void
ath6kl_htc_indicate_activity_change
(
struct
htc_target
*
target
,
enum
htc_endpoint_id
eid
,
bool
active
)
static
void
ath6kl_htc_mbox_activity_changed
(
struct
htc_target
*
target
,
enum
htc_endpoint_id
eid
,
bool
active
)
{
struct
htc_endpoint
*
endpoint
=
&
target
->
endpoint
[
eid
];
bool
dist
=
false
;
...
...
@@ -1246,7 +1256,7 @@ static int htc_add_rxbuf(struct htc_target *target, struct htc_packet *packet)
INIT_LIST_HEAD
(
&
queue
);
list_add_tail
(
&
packet
->
list
,
&
queue
);
return
ath6kl_htc_add_rxbuf_multiple
(
target
,
&
queue
);
return
ath6kl_htc_
mbox_
add_rxbuf_multiple
(
target
,
&
queue
);
}
static
void
htc_reclaim_rxbuf
(
struct
htc_target
*
target
,
...
...
@@ -1353,7 +1363,9 @@ static int ath6kl_htc_rx_setup(struct htc_target *target,
sizeof
(
*
htc_hdr
));
if
(
!
htc_valid_rx_frame_len
(
target
,
ep
->
eid
,
full_len
))
{
ath6kl_warn
(
"Rx buffer requested with invalid length
\n
"
);
ath6kl_warn
(
"Rx buffer requested with invalid length htc_hdr:eid %d, flags 0x%x, len %d
\n
"
,
htc_hdr
->
eid
,
htc_hdr
->
flags
,
le16_to_cpu
(
htc_hdr
->
payld_len
));
return
-
EINVAL
;
}
...
...
@@ -2288,7 +2300,7 @@ static struct htc_packet *htc_wait_for_ctrl_msg(struct htc_target *target)
return
NULL
;
}
int
ath6kl_htc
_add_rxbuf_multiple
(
struct
htc_target
*
target
,
static
int
ath6kl_htc_mbox
_add_rxbuf_multiple
(
struct
htc_target
*
target
,
struct
list_head
*
pkt_queue
)
{
struct
htc_endpoint
*
endpoint
;
...
...
@@ -2350,7 +2362,7 @@ int ath6kl_htc_add_rxbuf_multiple(struct htc_target *target,
return
status
;
}
void
ath6kl_htc
_flush_rx_buf
(
struct
htc_target
*
target
)
static
void
ath6kl_htc_mbox
_flush_rx_buf
(
struct
htc_target
*
target
)
{
struct
htc_endpoint
*
endpoint
;
struct
htc_packet
*
packet
,
*
tmp_pkt
;
...
...
@@ -2392,7 +2404,7 @@ void ath6kl_htc_flush_rx_buf(struct htc_target *target)
}
}
int
ath6kl_htc
_conn_service
(
struct
htc_target
*
target
,
static
int
ath6kl_htc_mbox
_conn_service
(
struct
htc_target
*
target
,
struct
htc_service_connect_req
*
conn_req
,
struct
htc_service_connect_resp
*
conn_resp
)
{
...
...
@@ -2564,7 +2576,7 @@ static void reset_ep_state(struct htc_target *target)
INIT_LIST_HEAD
(
&
target
->
cred_dist_list
);
}
int
ath6kl_htc
_get_rxbuf_num
(
struct
htc_target
*
target
,
static
int
ath6kl_htc_mbox
_get_rxbuf_num
(
struct
htc_target
*
target
,
enum
htc_endpoint_id
endpoint
)
{
int
num
;
...
...
@@ -2624,7 +2636,7 @@ static void htc_setup_msg_bndl(struct htc_target *target)
}
}
int
ath6kl_htc
_wait_target
(
struct
htc_target
*
target
)
static
int
ath6kl_htc_mbox
_wait_target
(
struct
htc_target
*
target
)
{
struct
htc_packet
*
packet
=
NULL
;
struct
htc_ready_ext_msg
*
rdy_msg
;
...
...
@@ -2693,12 +2705,12 @@ int ath6kl_htc_wait_target(struct htc_target *target)
connect
.
svc_id
=
HTC_CTRL_RSVD_SVC
;
/* connect fake service */
status
=
ath6kl_htc_conn_service
((
void
*
)
target
,
&
connect
,
&
resp
);
status
=
ath6kl_htc_
mbox_
conn_service
((
void
*
)
target
,
&
connect
,
&
resp
);
if
(
status
)
/*
* FIXME: this call doesn't make sense, the caller should
* call ath6kl_htc_cleanup() when it wants remove htc
* call ath6kl_htc_
mbox_
cleanup() when it wants remove htc
*/
ath6kl_hif_cleanup_scatter
(
target
->
dev
->
ar
);
...
...
@@ -2715,7 +2727,7 @@ int ath6kl_htc_wait_target(struct htc_target *target)
* Start HTC, enable interrupts and let the target know
* host has finished setup.
*/
int
ath6kl_htc
_start
(
struct
htc_target
*
target
)
static
int
ath6kl_htc_mbox
_start
(
struct
htc_target
*
target
)
{
struct
htc_packet
*
packet
;
int
status
;
...
...
@@ -2752,7 +2764,7 @@ int ath6kl_htc_start(struct htc_target *target)
status
=
ath6kl_hif_unmask_intrs
(
target
->
dev
);
if
(
status
)
ath6kl_htc_stop
(
target
);
ath6kl_htc_
mbox_
stop
(
target
);
return
status
;
}
...
...
@@ -2796,7 +2808,7 @@ static int ath6kl_htc_reset(struct htc_target *target)
}
/* htc_stop: stop interrupt reception, and flush all queued buffers */
void
ath6kl_htc
_stop
(
struct
htc_target
*
target
)
static
void
ath6kl_htc_mbox
_stop
(
struct
htc_target
*
target
)
{
spin_lock_bh
(
&
target
->
htc_lock
);
target
->
htc_flags
|=
HTC_OP_STATE_STOPPING
;
...
...
@@ -2811,12 +2823,12 @@ void ath6kl_htc_stop(struct htc_target *target)
ath6kl_htc_flush_txep_all
(
target
);
ath6kl_htc_flush_rx_buf
(
target
);
ath6kl_htc_
mbox_
flush_rx_buf
(
target
);
ath6kl_htc_reset
(
target
);
}
void
*
ath6kl_htc
_create
(
struct
ath6kl
*
ar
)
static
void
*
ath6kl_htc_mbox
_create
(
struct
ath6kl
*
ar
)
{
struct
htc_target
*
target
=
NULL
;
int
status
=
0
;
...
...
@@ -2857,13 +2869,13 @@ void *ath6kl_htc_create(struct ath6kl *ar)
return
target
;
err_htc_cleanup:
ath6kl_htc_cleanup
(
target
);
ath6kl_htc_
mbox_
cleanup
(
target
);
return
NULL
;
}
/* cleanup the HTC instance */
void
ath6kl_htc
_cleanup
(
struct
htc_target
*
target
)
static
void
ath6kl_htc_mbox
_cleanup
(
struct
htc_target
*
target
)
{
struct
htc_packet
*
packet
,
*
tmp_packet
;
...
...
@@ -2888,3 +2900,24 @@ void ath6kl_htc_cleanup(struct htc_target *target)
kfree
(
target
->
dev
);
kfree
(
target
);
}
static
const
struct
ath6kl_htc_ops
ath6kl_htc_mbox_ops
=
{
.
create
=
ath6kl_htc_mbox_create
,
.
wait_target
=
ath6kl_htc_mbox_wait_target
,
.
start
=
ath6kl_htc_mbox_start
,
.
conn_service
=
ath6kl_htc_mbox_conn_service
,
.
tx
=
ath6kl_htc_mbox_tx
,
.
stop
=
ath6kl_htc_mbox_stop
,
.
cleanup
=
ath6kl_htc_mbox_cleanup
,
.
flush_txep
=
ath6kl_htc_mbox_flush_txep
,
.
flush_rx_buf
=
ath6kl_htc_mbox_flush_rx_buf
,
.
activity_changed
=
ath6kl_htc_mbox_activity_changed
,
.
get_rxbuf_num
=
ath6kl_htc_mbox_get_rxbuf_num
,
.
add_rxbuf_multiple
=
ath6kl_htc_mbox_add_rxbuf_multiple
,
.
credit_setup
=
ath6kl_htc_mbox_credit_setup
,
};
void
ath6kl_htc_mbox_attach
(
struct
ath6kl
*
ar
)
{
ar
->
htc_ops
=
&
ath6kl_htc_mbox_ops
;
}
drivers/net/wireless/ath/ath6kl/htc_pipe.c
0 → 100644
浏览文件 @
c2786e4a
此差异已折叠。
点击以展开。
drivers/net/wireless/ath/ath6kl/init.c
浏览文件 @
c2786e4a
...
...
@@ -23,12 +23,14 @@
#include <linux/export.h>
#include <linux/of.h>
#include <linux/mmc/sdio_func.h>
#include <linux/vmalloc.h>
#include "core.h"
#include "cfg80211.h"
#include "target.h"
#include "debug.h"
#include "hif-ops.h"
#include "htc-ops.h"
static
const
struct
ath6kl_hw
hw_list
[]
=
{
{
...
...
@@ -258,6 +260,7 @@ static int ath6kl_init_service_ep(struct ath6kl *ar)
memset
(
&
connect
,
0
,
sizeof
(
connect
));
/* these fields are the same for all service endpoints */
connect
.
ep_cb
.
tx_comp_multi
=
ath6kl_tx_complete
;
connect
.
ep_cb
.
rx
=
ath6kl_rx
;
connect
.
ep_cb
.
rx_refill
=
ath6kl_rx_refill
;
connect
.
ep_cb
.
tx_full
=
ath6kl_tx_queue_full
;
...
...
@@ -487,22 +490,31 @@ int ath6kl_configure_target(struct ath6kl *ar)
fw_mode
|=
fw_iftype
<<
(
i
*
HI_OPTION_FW_MODE_BITS
);
/*
* By default, submodes :
* Submodes when fw does not support dynamic interface
* switching:
* vif[0] - AP/STA/IBSS
* vif[1] - "P2P dev"/"P2P GO"/"P2P Client"
* vif[2] - "P2P dev"/"P2P GO"/"P2P Client"
* Otherwise, All the interface are initialized to p2p dev.
*/
for
(
i
=
0
;
i
<
ar
->
max_norm_iface
;
i
++
)
fw_submode
|=
HI_OPTION_FW_SUBMODE_NONE
<<
(
i
*
HI_OPTION_FW_SUBMODE_BITS
);
if
(
test_bit
(
ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX
,
ar
->
fw_capabilities
))
{
for
(
i
=
0
;
i
<
ar
->
vif_max
;
i
++
)
fw_submode
|=
HI_OPTION_FW_SUBMODE_P2PDEV
<<
(
i
*
HI_OPTION_FW_SUBMODE_BITS
);
}
else
{
for
(
i
=
0
;
i
<
ar
->
max_norm_iface
;
i
++
)
fw_submode
|=
HI_OPTION_FW_SUBMODE_NONE
<<
(
i
*
HI_OPTION_FW_SUBMODE_BITS
);
for
(
i
=
ar
->
max_norm_iface
;
i
<
ar
->
vif_max
;
i
++
)
fw_submode
|=
HI_OPTION_FW_SUBMODE_P2PDEV
<<
(
i
*
HI_OPTION_FW_SUBMODE_BITS
);
for
(
i
=
ar
->
max_norm_iface
;
i
<
ar
->
vif_max
;
i
++
)
fw_submode
|=
HI_OPTION_FW_SUBMODE_P2PDEV
<<
(
i
*
HI_OPTION_FW_SUBMODE_BITS
);
if
(
ar
->
p2p
&&
ar
->
vif_max
==
1
)
fw_submode
=
HI_OPTION_FW_SUBMODE_P2PDEV
;
if
(
ar
->
p2p
&&
ar
->
vif_max
==
1
)
fw_submode
=
HI_OPTION_FW_SUBMODE_P2PDEV
;
}
if
(
ath6kl_bmi_write_hi32
(
ar
,
hi_app_host_interest
,
HTC_PROTOCOL_VERSION
)
!=
0
)
{
...
...
@@ -541,18 +553,20 @@ int ath6kl_configure_target(struct ath6kl *ar)
* but possible in theory.
*/
param
=
ar
->
hw
.
board_ext_data_addr
;
ram_reserved_size
=
ar
->
hw
.
reserved_ram_size
;
if
(
ar
->
target_type
==
TARGET_TYPE_AR6003
)
{
param
=
ar
->
hw
.
board_ext_data_addr
;
ram_reserved_size
=
ar
->
hw
.
reserved_ram_size
;
if
(
ath6kl_bmi_write_hi32
(
ar
,
hi_board_ext_data
,
param
)
!=
0
)
{
ath6kl_err
(
"bmi_write_memory for hi_board_ext_data failed
\n
"
);
return
-
EIO
;
}
if
(
ath6kl_bmi_write_hi32
(
ar
,
hi_board_ext_data
,
param
)
!=
0
)
{
ath6kl_err
(
"bmi_write_memory for hi_board_ext_data failed
\n
"
);
return
-
EIO
;
}
if
(
ath6kl_bmi_write_hi32
(
ar
,
hi_end_ram_reserve_sz
,
ram_reserved_size
)
!=
0
)
{
ath6kl_err
(
"bmi_write_memory for hi_end_ram_reserve_sz failed
\n
"
);
return
-
EIO
;
if
(
ath6kl_bmi_write_hi32
(
ar
,
hi_end_ram_reserve_sz
,
ram_reserved_size
)
!=
0
)
{
ath6kl_err
(
"bmi_write_memory for hi_end_ram_reserve_sz failed
\n
"
);
return
-
EIO
;
}
}
/* set the block size for the target */
...
...
@@ -926,13 +940,14 @@ static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name)
if
(
ar
->
fw
!=
NULL
)
break
;
ar
->
fw
=
kmemdup
(
data
,
ie_len
,
GFP_KERNEL
);
ar
->
fw
=
vmalloc
(
ie_len
);
if
(
ar
->
fw
==
NULL
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
memcpy
(
ar
->
fw
,
data
,
ie_len
);
ar
->
fw_len
=
ie_len
;
break
;
case
ATH6KL_FW_IE_PATCH_IMAGE
:
...
...
@@ -1509,7 +1524,7 @@ int ath6kl_init_hw_start(struct ath6kl *ar)
}
/* setup credit distribution */
ath6kl_credit_setup
(
ar
->
htc_target
,
&
ar
->
credit_state_info
);
ath6kl_
htc_
credit_setup
(
ar
->
htc_target
,
&
ar
->
credit_state_info
);
/* start HTC */
ret
=
ath6kl_htc_start
(
ar
->
htc_target
);
...
...
drivers/net/wireless/ath/ath6kl/main.c
浏览文件 @
c2786e4a
...
...
@@ -758,6 +758,10 @@ static void ath6kl_update_target_stats(struct ath6kl_vif *vif, u8 *ptr, u32 len)
stats
->
wow_evt_discarded
+=
le16_to_cpu
(
tgt_stats
->
wow_stats
.
wow_evt_discarded
);
stats
->
arp_received
=
le32_to_cpu
(
tgt_stats
->
arp_stats
.
arp_received
);
stats
->
arp_replied
=
le32_to_cpu
(
tgt_stats
->
arp_stats
.
arp_replied
);
stats
->
arp_matched
=
le32_to_cpu
(
tgt_stats
->
arp_stats
.
arp_matched
);
if
(
test_bit
(
STATS_UPDATE_PEND
,
&
vif
->
flags
))
{
clear_bit
(
STATS_UPDATE_PEND
,
&
vif
->
flags
);
wake_up
(
&
ar
->
event_wq
);
...
...
drivers/net/wireless/ath/ath6kl/sdio.c
浏览文件 @
c2786e4a
...
...
@@ -1362,7 +1362,7 @@ static int ath6kl_sdio_probe(struct sdio_func *func,
goto
err_core_alloc
;
}
ret
=
ath6kl_core_init
(
ar
);
ret
=
ath6kl_core_init
(
ar
,
ATH6KL_HTC_TYPE_MBOX
);
if
(
ret
)
{
ath6kl_err
(
"Failed to init ath6kl core
\n
"
);
goto
err_core_alloc
;
...
...
drivers/net/wireless/ath/ath6kl/txrx.c
浏览文件 @
c2786e4a
...
...
@@ -19,6 +19,7 @@
#include "core.h"
#include "debug.h"
#include "htc-ops.h"
/*
* tid - tid_mux0..tid_mux3
...
...
@@ -324,6 +325,7 @@ int ath6kl_control_tx(void *devt, struct sk_buff *skb,
cookie
->
map_no
=
0
;
set_htc_pkt_info
(
&
cookie
->
htc_pkt
,
cookie
,
skb
->
data
,
skb
->
len
,
eid
,
ATH6KL_CONTROL_PKT_TAG
);
cookie
->
htc_pkt
.
skb
=
skb
;
/*
* This interface is asynchronous, if there is an error, cleanup
...
...
@@ -492,6 +494,7 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
cookie
->
map_no
=
map_no
;
set_htc_pkt_info
(
&
cookie
->
htc_pkt
,
cookie
,
skb
->
data
,
skb
->
len
,
eid
,
htc_tag
);
cookie
->
htc_pkt
.
skb
=
skb
;
ath6kl_dbg_dump
(
ATH6KL_DBG_RAW_BYTES
,
__func__
,
"tx "
,
skb
->
data
,
skb
->
len
);
...
...
@@ -572,7 +575,7 @@ void ath6kl_indicate_tx_activity(void *devt, u8 traffic_class, bool active)
notify_htc:
/* notify HTC, this may cause credit distribution changes */
ath6kl_htc_
indicate_activity_change
(
ar
->
htc_target
,
eid
,
active
);
ath6kl_htc_
activity_changed
(
ar
->
htc_target
,
eid
,
active
);
}
enum
htc_send_full_action
ath6kl_tx_queue_full
(
struct
htc_target
*
target
,
...
...
@@ -668,9 +671,10 @@ static void ath6kl_tx_clear_node_map(struct ath6kl_vif *vif,
}
}
void
ath6kl_tx_complete
(
void
*
context
,
struct
list_head
*
packet_queue
)
void
ath6kl_tx_complete
(
struct
htc_target
*
target
,
struct
list_head
*
packet_queue
)
{
struct
ath6kl
*
ar
=
context
;
struct
ath6kl
*
ar
=
target
->
dev
->
ar
;
struct
sk_buff_head
skb_queue
;
struct
htc_packet
*
packet
;
struct
sk_buff
*
skb
;
...
...
@@ -889,6 +893,7 @@ void ath6kl_rx_refill(struct htc_target *target, enum htc_endpoint_id endpoint)
skb
->
data
=
PTR_ALIGN
(
skb
->
data
-
4
,
4
);
set_htc_rxpkt_info
(
packet
,
skb
,
skb
->
data
,
ATH6KL_BUFFER_SIZE
,
endpoint
);
packet
->
skb
=
skb
;
list_add_tail
(
&
packet
->
list
,
&
queue
);
}
...
...
@@ -911,6 +916,8 @@ void ath6kl_refill_amsdu_rxbufs(struct ath6kl *ar, int count)
skb
->
data
=
PTR_ALIGN
(
skb
->
data
-
4
,
4
);
set_htc_rxpkt_info
(
packet
,
skb
,
skb
->
data
,
ATH6KL_AMSDU_BUFFER_SIZE
,
0
);
packet
->
skb
=
skb
;
spin_lock_bh
(
&
ar
->
lock
);
list_add_tail
(
&
packet
->
list
,
&
ar
->
amsdu_rx_buffer_queue
);
spin_unlock_bh
(
&
ar
->
lock
);
...
...
@@ -1283,6 +1290,7 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
struct
wmi_data_hdr
*
dhdr
;
int
min_hdr_len
;
u8
meta_type
,
dot11_hdr
=
0
;
u8
pad_before_data_start
;
int
status
=
packet
->
status
;
enum
htc_endpoint_id
ept
=
packet
->
endpoint
;
bool
is_amsdu
,
prev_ps
,
ps_state
=
false
;
...
...
@@ -1494,6 +1502,10 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
seq_no
=
wmi_data_hdr_get_seqno
(
dhdr
);
meta_type
=
wmi_data_hdr_get_meta
(
dhdr
);
dot11_hdr
=
wmi_data_hdr_get_dot11
(
dhdr
);
pad_before_data_start
=
(
le16_to_cpu
(
dhdr
->
info3
)
>>
WMI_DATA_HDR_PAD_BEFORE_DATA_SHIFT
)
&
WMI_DATA_HDR_PAD_BEFORE_DATA_MASK
;
skb_pull
(
skb
,
sizeof
(
struct
wmi_data_hdr
));
switch
(
meta_type
)
{
...
...
@@ -1512,6 +1524,8 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
break
;
}
skb_pull
(
skb
,
pad_before_data_start
);
if
(
dot11_hdr
)
status
=
ath6kl_wmi_dot11_hdr_remove
(
ar
->
wmi
,
skb
);
else
if
(
!
is_amsdu
)
...
...
@@ -1581,7 +1595,8 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
/* aggregation code will handle the skb */
return
;
}
}
}
else
if
(
!
is_broadcast_ether_addr
(
datap
->
h_dest
))
vif
->
net_stats
.
multicast
++
;
ath6kl_deliver_frames_to_nw_stack
(
vif
->
ndev
,
skb
);
}
...
...
drivers/net/wireless/ath/ath6kl/usb.c
浏览文件 @
c2786e4a
此差异已折叠。
点击以展开。
drivers/net/wireless/ath/ath6kl/wmi.c
浏览文件 @
c2786e4a
...
...
@@ -2882,6 +2882,43 @@ int ath6kl_wmi_set_keepalive_cmd(struct wmi *wmi, u8 if_idx,
return
ret
;
}
int
ath6kl_wmi_set_htcap_cmd
(
struct
wmi
*
wmi
,
u8
if_idx
,
enum
ieee80211_band
band
,
struct
ath6kl_htcap
*
htcap
)
{
struct
sk_buff
*
skb
;
struct
wmi_set_htcap_cmd
*
cmd
;
skb
=
ath6kl_wmi_get_new_buf
(
sizeof
(
*
cmd
));
if
(
!
skb
)
return
-
ENOMEM
;
cmd
=
(
struct
wmi_set_htcap_cmd
*
)
skb
->
data
;
/*
* NOTE: Band in firmware matches enum ieee80211_band, it is unlikely
* this will be changed in firmware. If at all there is any change in
* band value, the host needs to be fixed.
*/
cmd
->
band
=
band
;
cmd
->
ht_enable
=
!!
htcap
->
ht_enable
;
cmd
->
ht20_sgi
=
!!
(
htcap
->
cap_info
&
IEEE80211_HT_CAP_SGI_20
);
cmd
->
ht40_supported
=
!!
(
htcap
->
cap_info
&
IEEE80211_HT_CAP_SUP_WIDTH_20_40
);
cmd
->
ht40_sgi
=
!!
(
htcap
->
cap_info
&
IEEE80211_HT_CAP_SGI_40
);
cmd
->
intolerant_40mhz
=
!!
(
htcap
->
cap_info
&
IEEE80211_HT_CAP_40MHZ_INTOLERANT
);
cmd
->
max_ampdu_len_exp
=
htcap
->
ampdu_factor
;
ath6kl_dbg
(
ATH6KL_DBG_WMI
,
"Set htcap: band:%d ht_enable:%d 40mhz:%d sgi_20mhz:%d sgi_40mhz:%d 40mhz_intolerant:%d ampdu_len_exp:%d
\n
"
,
cmd
->
band
,
cmd
->
ht_enable
,
cmd
->
ht40_supported
,
cmd
->
ht20_sgi
,
cmd
->
ht40_sgi
,
cmd
->
intolerant_40mhz
,
cmd
->
max_ampdu_len_exp
);
return
ath6kl_wmi_cmd_send
(
wmi
,
if_idx
,
skb
,
WMI_SET_HT_CAP_CMDID
,
NO_SYNC_WMIFLAG
);
}
int
ath6kl_wmi_test_cmd
(
struct
wmi
*
wmi
,
void
*
buf
,
size_t
len
)
{
struct
sk_buff
*
skb
;
...
...
@@ -3032,6 +3069,9 @@ int ath6kl_wmi_ap_set_mlme(struct wmi *wmip, u8 if_idx, u8 cmd, const u8 *mac,
cm
->
reason
=
cpu_to_le16
(
reason
);
cm
->
cmd
=
cmd
;
ath6kl_dbg
(
ATH6KL_DBG_WMI
,
"ap_set_mlme: cmd=%d reason=%d
\n
"
,
cm
->
cmd
,
cm
->
reason
);
return
ath6kl_wmi_cmd_send
(
wmip
,
if_idx
,
skb
,
WMI_AP_SET_MLME_CMDID
,
NO_SYNC_WMIFLAG
);
}
...
...
@@ -3181,6 +3221,29 @@ int ath6kl_wmi_set_appie_cmd(struct wmi *wmi, u8 if_idx, u8 mgmt_frm_type,
NO_SYNC_WMIFLAG
);
}
int
ath6kl_wmi_set_ie_cmd
(
struct
wmi
*
wmi
,
u8
if_idx
,
u8
ie_id
,
u8
ie_field
,
const
u8
*
ie_info
,
u8
ie_len
)
{
struct
sk_buff
*
skb
;
struct
wmi_set_ie_cmd
*
p
;
skb
=
ath6kl_wmi_get_new_buf
(
sizeof
(
*
p
)
+
ie_len
);
if
(
!
skb
)
return
-
ENOMEM
;
ath6kl_dbg
(
ATH6KL_DBG_WMI
,
"set_ie_cmd: ie_id=%u ie_ie_field=%u ie_len=%u
\n
"
,
ie_id
,
ie_field
,
ie_len
);
p
=
(
struct
wmi_set_ie_cmd
*
)
skb
->
data
;
p
->
ie_id
=
ie_id
;
p
->
ie_field
=
ie_field
;
p
->
ie_len
=
ie_len
;
if
(
ie_info
&&
ie_len
>
0
)
memcpy
(
p
->
ie_info
,
ie_info
,
ie_len
);
return
ath6kl_wmi_cmd_send
(
wmi
,
if_idx
,
skb
,
WMI_SET_IE_CMDID
,
NO_SYNC_WMIFLAG
);
}
int
ath6kl_wmi_disable_11b_rates_cmd
(
struct
wmi
*
wmi
,
bool
disable
)
{
struct
sk_buff
*
skb
;
...
...
@@ -3392,6 +3455,23 @@ int ath6kl_wmi_cancel_remain_on_chnl_cmd(struct wmi *wmi, u8 if_idx)
WMI_CANCEL_REMAIN_ON_CHNL_CMDID
);
}
int
ath6kl_wmi_set_inact_period
(
struct
wmi
*
wmi
,
u8
if_idx
,
int
inact_timeout
)
{
struct
sk_buff
*
skb
;
struct
wmi_set_inact_period_cmd
*
cmd
;
skb
=
ath6kl_wmi_get_new_buf
(
sizeof
(
*
cmd
));
if
(
!
skb
)
return
-
ENOMEM
;
cmd
=
(
struct
wmi_set_inact_period_cmd
*
)
skb
->
data
;
cmd
->
inact_period
=
cpu_to_le32
(
inact_timeout
);
cmd
->
num_null_func
=
0
;
return
ath6kl_wmi_cmd_send
(
wmi
,
if_idx
,
skb
,
WMI_AP_CONN_INACT_CMDID
,
NO_SYNC_WMIFLAG
);
}
static
int
ath6kl_wmi_control_rx_xtnd
(
struct
wmi
*
wmi
,
struct
sk_buff
*
skb
)
{
struct
wmix_cmd_hdr
*
cmd
;
...
...
drivers/net/wireless/ath/ath6kl/wmi.h
浏览文件 @
c2786e4a
...
...
@@ -182,6 +182,9 @@ enum wmi_data_hdr_flags {
#define WMI_DATA_HDR_META_MASK 0x7
#define WMI_DATA_HDR_META_SHIFT 13
#define WMI_DATA_HDR_PAD_BEFORE_DATA_MASK 0xFF
#define WMI_DATA_HDR_PAD_BEFORE_DATA_SHIFT 0x8
/* Macros for operating on WMI_DATA_HDR (info3) field */
#define WMI_DATA_HDR_IF_IDX_MASK 0xF
...
...
@@ -423,6 +426,7 @@ enum wmi_cmd_id {
WMI_SET_FRAMERATES_CMDID
,
WMI_SET_AP_PS_CMDID
,
WMI_SET_QOS_SUPP_CMDID
,
WMI_SET_IE_CMDID
,
/* WMI_THIN_RESERVED_... mark the start and end
* values for WMI_THIN_RESERVED command IDs. These
...
...
@@ -629,6 +633,11 @@ enum wmi_mgmt_frame_type {
WMI_NUM_MGMT_FRAME
};
enum
wmi_ie_field_type
{
WMI_RSN_IE_CAPB
=
0x1
,
WMI_IE_FULL
=
0xFF
,
/* indicats full IE */
};
/* WMI_CONNECT_CMDID */
enum
network_type
{
INFRA_NETWORK
=
0x01
,
...
...
@@ -1268,6 +1277,16 @@ struct wmi_mcast_filter_add_del_cmd {
u8
mcast_mac
[
ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE
];
}
__packed
;
struct
wmi_set_htcap_cmd
{
u8
band
;
u8
ht_enable
;
u8
ht40_supported
;
u8
ht20_sgi
;
u8
ht40_sgi
;
u8
intolerant_40mhz
;
u8
max_ampdu_len_exp
;
}
__packed
;
/* Command Replies */
/* WMI_GET_CHANNEL_LIST_CMDID reply */
...
...
@@ -1913,6 +1932,14 @@ struct wmi_set_appie_cmd {
u8
ie_info
[
0
];
}
__packed
;
struct
wmi_set_ie_cmd
{
u8
ie_id
;
u8
ie_field
;
/* enum wmi_ie_field_type */
u8
ie_len
;
u8
reserved
;
u8
ie_info
[
0
];
}
__packed
;
/* Notify the WSC registration status to the target */
#define WSC_REG_ACTIVE 1
#define WSC_REG_INACTIVE 0
...
...
@@ -2141,6 +2168,11 @@ struct wmi_ap_hidden_ssid_cmd {
u8
hidden_ssid
;
}
__packed
;
struct
wmi_set_inact_period_cmd
{
__le32
inact_period
;
u8
num_null_func
;
}
__packed
;
/* AP mode events */
struct
wmi_ap_set_apsd_cmd
{
u8
enable
;
...
...
@@ -2465,6 +2497,9 @@ int ath6kl_wmi_get_roam_tbl_cmd(struct wmi *wmi);
int
ath6kl_wmi_set_wmm_txop
(
struct
wmi
*
wmi
,
u8
if_idx
,
enum
wmi_txop_cfg
cfg
);
int
ath6kl_wmi_set_keepalive_cmd
(
struct
wmi
*
wmi
,
u8
if_idx
,
u8
keep_alive_intvl
);
int
ath6kl_wmi_set_htcap_cmd
(
struct
wmi
*
wmi
,
u8
if_idx
,
enum
ieee80211_band
band
,
struct
ath6kl_htcap
*
htcap
);
int
ath6kl_wmi_test_cmd
(
struct
wmi
*
wmi
,
void
*
buf
,
size_t
len
);
s32
ath6kl_wmi_get_rate
(
s8
rate_index
);
...
...
@@ -2515,6 +2550,9 @@ int ath6kl_wmi_set_rx_frame_format_cmd(struct wmi *wmi, u8 if_idx,
int
ath6kl_wmi_set_appie_cmd
(
struct
wmi
*
wmi
,
u8
if_idx
,
u8
mgmt_frm_type
,
const
u8
*
ie
,
u8
ie_len
);
int
ath6kl_wmi_set_ie_cmd
(
struct
wmi
*
wmi
,
u8
if_idx
,
u8
ie_id
,
u8
ie_field
,
const
u8
*
ie_info
,
u8
ie_len
);
/* P2P */
int
ath6kl_wmi_disable_11b_rates_cmd
(
struct
wmi
*
wmi
,
bool
disable
);
...
...
@@ -2538,6 +2576,8 @@ int ath6kl_wmi_cancel_remain_on_chnl_cmd(struct wmi *wmi, u8 if_idx);
int
ath6kl_wmi_set_appie_cmd
(
struct
wmi
*
wmi
,
u8
if_idx
,
u8
mgmt_frm_type
,
const
u8
*
ie
,
u8
ie_len
);
int
ath6kl_wmi_set_inact_period
(
struct
wmi
*
wmi
,
u8
if_idx
,
int
inact_timeout
);
void
ath6kl_wmi_sscan_timer
(
unsigned
long
ptr
);
struct
ath6kl_vif
*
ath6kl_get_vif_by_index
(
struct
ath6kl
*
ar
,
u8
if_idx
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录