Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
54dceb00
K
Kernel
项目概览
openeuler
/
Kernel
接近 2 年 前同步成功
通知
8
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看板
提交
54dceb00
编写于
7月 08, 2008
作者:
D
David S. Miller
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/linville/wireless-next-2.6
上级
11a100f8
b4637271
变更
49
展开全部
隐藏空白更改
内联
并排
Showing
49 changed file
with
1449 addition
and
678 deletion
+1449
-678
drivers/net/wireless/Kconfig
drivers/net/wireless/Kconfig
+9
-3
drivers/net/wireless/b43legacy/dma.c
drivers/net/wireless/b43legacy/dma.c
+51
-15
drivers/net/wireless/hostap/hostap_hw.c
drivers/net/wireless/hostap/hostap_hw.c
+2
-2
drivers/net/wireless/iwlwifi/Kconfig
drivers/net/wireless/iwlwifi/Kconfig
+5
-0
drivers/net/wireless/iwlwifi/iwl-3945.h
drivers/net/wireless/iwlwifi/iwl-3945.h
+3
-8
drivers/net/wireless/iwlwifi/iwl-4965.c
drivers/net/wireless/iwlwifi/iwl-4965.c
+3
-3
drivers/net/wireless/iwlwifi/iwl-5000.c
drivers/net/wireless/iwlwifi/iwl-5000.c
+3
-3
drivers/net/wireless/iwlwifi/iwl-core.h
drivers/net/wireless/iwlwifi/iwl-core.h
+11
-2
drivers/net/wireless/iwlwifi/iwl-dev.h
drivers/net/wireless/iwlwifi/iwl-dev.h
+2
-2
drivers/net/wireless/iwlwifi/iwl-rfkill.c
drivers/net/wireless/iwlwifi/iwl-rfkill.c
+33
-32
drivers/net/wireless/iwlwifi/iwl-rfkill.h
drivers/net/wireless/iwlwifi/iwl-rfkill.h
+0
-3
drivers/net/wireless/iwlwifi/iwl-tx.c
drivers/net/wireless/iwlwifi/iwl-tx.c
+1
-1
drivers/net/wireless/iwlwifi/iwl3945-base.c
drivers/net/wireless/iwlwifi/iwl3945-base.c
+50
-67
drivers/net/wireless/iwlwifi/iwl4965-base.c
drivers/net/wireless/iwlwifi/iwl4965-base.c
+4
-4
drivers/net/wireless/rt2x00/Kconfig
drivers/net/wireless/rt2x00/Kconfig
+3
-5
drivers/net/wireless/rt2x00/rt2400pci.c
drivers/net/wireless/rt2x00/rt2400pci.c
+23
-0
drivers/net/wireless/rt2x00/rt2500pci.h
drivers/net/wireless/rt2x00/rt2500pci.h
+2
-2
drivers/net/wireless/rt2x00/rt2500usb.h
drivers/net/wireless/rt2x00/rt2500usb.h
+34
-6
drivers/net/wireless/rt2x00/rt2x00.h
drivers/net/wireless/rt2x00/rt2x00.h
+4
-2
drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/net/wireless/rt2x00/rt2x00dev.c
+4
-16
drivers/net/wireless/rt2x00/rt2x00lib.h
drivers/net/wireless/rt2x00/rt2x00lib.h
+1
-11
drivers/net/wireless/rt2x00/rt2x00mac.c
drivers/net/wireless/rt2x00/rt2x00mac.c
+2
-2
drivers/net/wireless/rt2x00/rt2x00queue.c
drivers/net/wireless/rt2x00/rt2x00queue.c
+4
-3
drivers/net/wireless/rt2x00/rt2x00queue.h
drivers/net/wireless/rt2x00/rt2x00queue.h
+2
-0
drivers/net/wireless/rt2x00/rt2x00rfkill.c
drivers/net/wireless/rt2x00/rt2x00rfkill.c
+33
-74
drivers/net/wireless/rtl8187.h
drivers/net/wireless/rtl8187.h
+97
-16
drivers/net/wireless/rtl8187_dev.c
drivers/net/wireless/rtl8187_dev.c
+417
-73
drivers/net/wireless/rtl8187_rtl8225.c
drivers/net/wireless/rtl8187_rtl8225.c
+215
-14
drivers/net/wireless/rtl818x.h
drivers/net/wireless/rtl818x.h
+27
-9
drivers/net/wireless/zd1211rw/zd_mac.c
drivers/net/wireless/zd1211rw/zd_mac.c
+45
-17
include/linux/ieee80211.h
include/linux/ieee80211.h
+6
-0
include/net/mac80211.h
include/net/mac80211.h
+28
-15
net/mac80211/Kconfig
net/mac80211/Kconfig
+1
-2
net/mac80211/aes_ccm.c
net/mac80211/aes_ccm.c
+25
-26
net/mac80211/aes_ccm.h
net/mac80211/aes_ccm.h
+2
-2
net/mac80211/ieee80211_i.h
net/mac80211/ieee80211_i.h
+2
-1
net/mac80211/main.c
net/mac80211/main.c
+25
-8
net/mac80211/michael.c
net/mac80211/michael.c
+15
-5
net/mac80211/michael.h
net/mac80211/michael.h
+1
-1
net/mac80211/mlme.c
net/mac80211/mlme.c
+33
-1
net/mac80211/rx.c
net/mac80211/rx.c
+65
-70
net/mac80211/sta_info.c
net/mac80211/sta_info.c
+1
-0
net/mac80211/sta_info.h
net/mac80211/sta_info.h
+60
-21
net/mac80211/wext.c
net/mac80211/wext.c
+2
-0
net/mac80211/wme.c
net/mac80211/wme.c
+2
-3
net/mac80211/wme.h
net/mac80211/wme.h
+0
-8
net/mac80211/wpa.c
net/mac80211/wpa.c
+76
-107
net/rfkill/rfkill.c
net/rfkill/rfkill.c
+11
-11
net/wireless/nl80211.c
net/wireless/nl80211.c
+4
-2
未找到文件。
drivers/net/wireless/Kconfig
浏览文件 @
54dceb00
...
...
@@ -611,14 +611,20 @@ config RTL8180
Thanks to Realtek for their support!
config RTL8187
tristate "Realtek 8187 USB support"
tristate "Realtek 8187
and 8187B
USB support"
depends on MAC80211 && USB && WLAN_80211 && EXPERIMENTAL
select EEPROM_93CX6
---help---
This is a driver for RTL8187 based cards.
These are USB based chips found in
card
s such as:
This is a driver for RTL8187
and RTL8187B
based cards.
These are USB based chips found in
device
s such as:
Netgear WG111v2
Level 1 WNC-0301USB
Micronet SP907GK V5
Encore ENUWI-G2
Trendnet TEW-424UB
ASUS P5B Deluxe
Toshiba Satellite Pro series of laptops
Thanks to Realtek for their support!
...
...
drivers/net/wireless/b43legacy/dma.c
浏览文件 @
54dceb00
...
...
@@ -859,6 +859,18 @@ static u64 supported_dma_mask(struct b43legacy_wldev *dev)
return
DMA_30BIT_MASK
;
}
static
enum
b43legacy_dmatype
dma_mask_to_engine_type
(
u64
dmamask
)
{
if
(
dmamask
==
DMA_30BIT_MASK
)
return
B43legacy_DMA_30BIT
;
if
(
dmamask
==
DMA_32BIT_MASK
)
return
B43legacy_DMA_32BIT
;
if
(
dmamask
==
DMA_64BIT_MASK
)
return
B43legacy_DMA_64BIT
;
B43legacy_WARN_ON
(
1
);
return
B43legacy_DMA_30BIT
;
}
/* Main initialization function. */
static
struct
b43legacy_dmaring
*
b43legacy_setup_dmaring
(
struct
b43legacy_wldev
*
dev
,
...
...
@@ -1018,6 +1030,43 @@ void b43legacy_dma_free(struct b43legacy_wldev *dev)
dma
->
tx_ring0
=
NULL
;
}
static
int
b43legacy_dma_set_mask
(
struct
b43legacy_wldev
*
dev
,
u64
mask
)
{
u64
orig_mask
=
mask
;
bool
fallback
=
0
;
int
err
;
/* Try to set the DMA mask. If it fails, try falling back to a
* lower mask, as we can always also support a lower one. */
while
(
1
)
{
err
=
ssb_dma_set_mask
(
dev
->
dev
,
mask
);
if
(
!
err
)
break
;
if
(
mask
==
DMA_64BIT_MASK
)
{
mask
=
DMA_32BIT_MASK
;
fallback
=
1
;
continue
;
}
if
(
mask
==
DMA_32BIT_MASK
)
{
mask
=
DMA_30BIT_MASK
;
fallback
=
1
;
continue
;
}
b43legacyerr
(
dev
->
wl
,
"The machine/kernel does not support "
"the required %u-bit DMA mask
\n
"
,
(
unsigned
int
)
dma_mask_to_engine_type
(
orig_mask
));
return
-
EOPNOTSUPP
;
}
if
(
fallback
)
{
b43legacyinfo
(
dev
->
wl
,
"DMA mask fallback from %u-bit to %u-"
"bit
\n
"
,
(
unsigned
int
)
dma_mask_to_engine_type
(
orig_mask
),
(
unsigned
int
)
dma_mask_to_engine_type
(
mask
));
}
return
0
;
}
int
b43legacy_dma_init
(
struct
b43legacy_wldev
*
dev
)
{
struct
b43legacy_dma
*
dma
=
&
dev
->
dma
;
...
...
@@ -1027,21 +1076,8 @@ int b43legacy_dma_init(struct b43legacy_wldev *dev)
enum
b43legacy_dmatype
type
;
dmamask
=
supported_dma_mask
(
dev
);
switch
(
dmamask
)
{
default:
B43legacy_WARN_ON
(
1
);
case
DMA_30BIT_MASK
:
type
=
B43legacy_DMA_30BIT
;
break
;
case
DMA_32BIT_MASK
:
type
=
B43legacy_DMA_32BIT
;
break
;
case
DMA_64BIT_MASK
:
type
=
B43legacy_DMA_64BIT
;
break
;
}
err
=
ssb_dma_set_mask
(
dev
->
dev
,
dmamask
);
type
=
dma_mask_to_engine_type
(
dmamask
);
err
=
b43legacy_dma_set_mask
(
dev
,
dmamask
);
if
(
err
)
{
#ifdef CONFIG_B43LEGACY_PIO
b43legacywarn
(
dev
->
wl
,
"DMA for this device not supported. "
...
...
drivers/net/wireless/hostap/hostap_hw.c
浏览文件 @
54dceb00
...
...
@@ -3417,7 +3417,7 @@ static void prism2_free_local_data(struct net_device *dev)
}
#if
ndef PRISM2_PLX
#if
(defined(PRISM2_PCI) && defined(CONFIG_PM)) || defined(PRISM2_PCCARD)
static
void
prism2_suspend
(
struct
net_device
*
dev
)
{
struct
hostap_interface
*
iface
;
...
...
@@ -3436,7 +3436,7 @@ static void prism2_suspend(struct net_device *dev)
/* Disable hardware and firmware */
prism2_hw_shutdown
(
dev
,
0
);
}
#endif
/*
PRISM2_PLX
*/
#endif
/*
(PRISM2_PCI && CONFIG_PM) || PRISM2_PCCARD
*/
/* These might at some point be compiled separately and used as separate
...
...
drivers/net/wireless/iwlwifi/Kconfig
浏览文件 @
54dceb00
...
...
@@ -104,6 +104,7 @@ config IWL3945
select IWLWIFI
select MAC80211_LEDS if IWL3945_LEDS
select LEDS_CLASS if IWL3945_LEDS
select RFKILL if IWL3945_RFKILL
---help---
Select to build the driver supporting the:
...
...
@@ -126,6 +127,10 @@ config IWL3945
say M here and read <file:Documentation/kbuild/modules.txt>. The
module will be called iwl3945.ko.
config IWL3945_RFKILL
bool "Enable RF kill support in iwl3945 drivers"
depends on IWL3945
config IWL3945_SPECTRUM_MEASUREMENT
bool "Enable Spectrum Measurement in iwl3945 drivers"
depends on IWL3945
...
...
drivers/net/wireless/iwlwifi/iwl-3945.h
浏览文件 @
54dceb00
...
...
@@ -690,14 +690,9 @@ enum {
#endif
#ifdef CONFIG_IWL
WIFI
_RFKILL
#ifdef CONFIG_IWL
3945
_RFKILL
struct
iwl3945_priv
;
struct
iwl3945_rfkill_mngr
{
struct
rfkill
*
rfkill
;
struct
input_dev
*
input_dev
;
};
void
iwl3945_rfkill_set_hw_state
(
struct
iwl3945_priv
*
priv
);
void
iwl3945_rfkill_unregister
(
struct
iwl3945_priv
*
priv
);
int
iwl3945_rfkill_init
(
struct
iwl3945_priv
*
priv
);
...
...
@@ -800,8 +795,8 @@ struct iwl3945_priv {
struct
iwl3945_init_alive_resp
card_alive_init
;
struct
iwl3945_alive_resp
card_alive
;
#ifdef CONFIG_IWL
WIFI
_RFKILL
struct
iwl3945_rfkill_mngr
rfkill_mngr
;
#ifdef CONFIG_IWL
3945
_RFKILL
struct
rfkill
*
rfkill
;
#endif
#ifdef CONFIG_IWL3945_LEDS
...
...
drivers/net/wireless/iwlwifi/iwl-4965.c
浏览文件 @
54dceb00
...
...
@@ -2285,9 +2285,9 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
iwl4965_tx_status_reply_tx
(
priv
,
agg
,
tx_resp
,
txq_id
,
index
);
if
((
tx_resp
->
frame_count
==
1
)
&&
!
iwl_is_tx_success
(
status
))
{
/* TODO: send BAR */
}
/* check if BAR is needed */
if
((
tx_resp
->
frame_count
==
1
)
&&
!
iwl_is_tx_success
(
status
))
info
->
flags
|=
IEEE80211_TX_STAT_AMPDU_NO_BACK
;
if
(
txq
->
q
.
read_ptr
!=
(
scd_ssn
&
0xff
))
{
int
freed
,
ampdu_q
;
...
...
drivers/net/wireless/iwlwifi/iwl-5000.c
浏览文件 @
54dceb00
...
...
@@ -1278,9 +1278,9 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
iwl5000_tx_status_reply_tx
(
priv
,
agg
,
tx_resp
,
txq_id
,
index
);
if
((
tx_resp
->
frame_count
==
1
)
&&
!
iwl_is_tx_success
(
status
))
{
/* TODO: send BAR */
}
/* check if BAR is needed */
if
((
tx_resp
->
frame_count
==
1
)
&&
!
iwl_is_tx_success
(
status
))
info
->
flags
|=
IEEE80211_TX_STAT_AMPDU_NO_BACK
;
if
(
txq
->
q
.
read_ptr
!=
(
scd_ssn
&
0xff
))
{
int
freed
,
ampdu_q
;
...
...
drivers/net/wireless/iwlwifi/iwl-core.h
浏览文件 @
54dceb00
...
...
@@ -356,10 +356,19 @@ static inline int iwl_is_init(struct iwl_priv *priv)
return
test_bit
(
STATUS_INIT
,
&
priv
->
status
);
}
static
inline
int
iwl_is_rfkill_sw
(
struct
iwl_priv
*
priv
)
{
return
test_bit
(
STATUS_RF_KILL_SW
,
&
priv
->
status
);
}
static
inline
int
iwl_is_rfkill_hw
(
struct
iwl_priv
*
priv
)
{
return
test_bit
(
STATUS_RF_KILL_HW
,
&
priv
->
status
);
}
static
inline
int
iwl_is_rfkill
(
struct
iwl_priv
*
priv
)
{
return
test_bit
(
STATUS_RF_KILL_HW
,
&
priv
->
status
)
||
test_bit
(
STATUS_RF_KILL_SW
,
&
priv
->
status
);
return
iwl_is_rfkill_hw
(
priv
)
||
iwl_is_rfkill_sw
(
priv
);
}
static
inline
int
iwl_is_ready_rf
(
struct
iwl_priv
*
priv
)
...
...
drivers/net/wireless/iwlwifi/iwl-dev.h
浏览文件 @
54dceb00
...
...
@@ -929,7 +929,7 @@ struct iwl_priv {
struct
iwl_init_alive_resp
card_alive_init
;
struct
iwl_alive_resp
card_alive
;
#ifdef CONFIG_IWLWIFI_RFKILL
struct
iwl_rfkill_mngr
rfkill_mngr
;
struct
rfkill
*
rfkill
;
#endif
#ifdef CONFIG_IWLWIFI_LEDS
...
...
@@ -1103,7 +1103,7 @@ static inline void iwl_txq_ctx_deactivate(struct iwl_priv *priv, int txq_id)
clear_bit
(
txq_id
,
&
priv
->
txq_ctx_active_msk
);
}
#ifdef CONFIG_IWLWIF_DEBUG
#ifdef CONFIG_IWLWIF
I
_DEBUG
const
char
*
iwl_get_tx_fail_reason
(
u32
status
);
#else
static
inline
const
char
*
iwl_get_tx_fail_reason
(
u32
status
)
{
return
""
;
}
...
...
drivers/net/wireless/iwlwifi/iwl-rfkill.c
浏览文件 @
54dceb00
...
...
@@ -44,7 +44,7 @@ static int iwl_rfkill_soft_rf_kill(void *data, enum rfkill_state state)
struct
iwl_priv
*
priv
=
data
;
int
err
=
0
;
if
(
!
priv
->
rfkill
_mngr
.
rfkill
)
if
(
!
priv
->
rfkill
)
return
0
;
if
(
test_bit
(
STATUS_EXIT_PENDING
,
&
priv
->
status
))
...
...
@@ -55,20 +55,20 @@ static int iwl_rfkill_soft_rf_kill(void *data, enum rfkill_state state)
switch
(
state
)
{
case
RFKILL_STATE_UNBLOCKED
:
iwl_radio_kill_sw_enable_radio
(
priv
);
/* if HW rf-kill is set dont allow ON state */
if
(
iwl_is_rfkill
(
priv
))
if
(
iwl_is_rfkill_hw
(
priv
))
{
err
=
-
EBUSY
;
goto
out_unlock
;
}
iwl_radio_kill_sw_enable_radio
(
priv
);
break
;
case
RFKILL_STATE_SOFT_BLOCKED
:
iwl_radio_kill_sw_disable_radio
(
priv
);
if
(
!
iwl_is_rfkill
(
priv
))
err
=
-
EBUSY
;
break
;
default:
IWL_WARNING
(
"we recieved unexpected RFKILL state %d
\n
"
,
state
);
break
;
}
out_unlock:
mutex_unlock
(
&
priv
->
mutex
);
return
err
;
...
...
@@ -82,39 +82,35 @@ int iwl_rfkill_init(struct iwl_priv *priv)
BUG_ON
(
device
==
NULL
);
IWL_DEBUG_RF_KILL
(
"Initializing RFKILL.
\n
"
);
priv
->
rfkill
_mngr
.
rfkill
=
rfkill_allocate
(
device
,
RFKILL_TYPE_WLAN
);
if
(
!
priv
->
rfkill
_mngr
.
rfkill
)
{
priv
->
rfkill
=
rfkill_allocate
(
device
,
RFKILL_TYPE_WLAN
);
if
(
!
priv
->
rfkill
)
{
IWL_ERROR
(
"Unable to allocate rfkill device.
\n
"
);
ret
=
-
ENOMEM
;
goto
error
;
}
priv
->
rfkill
_mngr
.
rfkill
->
name
=
priv
->
cfg
->
name
;
priv
->
rfkill
_mngr
.
rfkill
->
data
=
priv
;
priv
->
rfkill
_mngr
.
rfkill
->
state
=
RFKILL_STATE_ON
;
priv
->
rfkill
_mngr
.
rfkill
->
toggle_radio
=
iwl_rfkill_soft_rf_kill
;
priv
->
rfkill
_mngr
.
rfkill
->
user_claim_unsupported
=
1
;
priv
->
rfkill
->
name
=
priv
->
cfg
->
name
;
priv
->
rfkill
->
data
=
priv
;
priv
->
rfkill
->
state
=
RFKILL_STATE_UNBLOCKED
;
priv
->
rfkill
->
toggle_radio
=
iwl_rfkill_soft_rf_kill
;
priv
->
rfkill
->
user_claim_unsupported
=
1
;
priv
->
rfkill
_mngr
.
rfkill
->
dev
.
class
->
suspend
=
NULL
;
priv
->
rfkill
_mngr
.
rfkill
->
dev
.
class
->
resume
=
NULL
;
priv
->
rfkill
->
dev
.
class
->
suspend
=
NULL
;
priv
->
rfkill
->
dev
.
class
->
resume
=
NULL
;
ret
=
rfkill_register
(
priv
->
rfkill
_mngr
.
rfkill
);
ret
=
rfkill_register
(
priv
->
rfkill
);
if
(
ret
)
{
IWL_ERROR
(
"Unable to register rfkill: %d
\n
"
,
ret
);
goto
unregister
_rfkill
;
goto
free
_rfkill
;
}
IWL_DEBUG_RF_KILL
(
"RFKILL initialization complete.
\n
"
);
return
ret
;
unregister_rfkill:
rfkill_unregister
(
priv
->
rfkill_mngr
.
rfkill
);
priv
->
rfkill_mngr
.
rfkill
=
NULL
;
freed_rfkill:
if
(
priv
->
rfkill_mngr
.
rfkill
!=
NULL
)
rfkill_free
(
priv
->
rfkill_mngr
.
rfkill
);
priv
->
rfkill_mngr
.
rfkill
=
NULL
;
free_rfkill:
if
(
priv
->
rfkill
!=
NULL
)
rfkill_free
(
priv
->
rfkill
);
priv
->
rfkill
=
NULL
;
error:
IWL_DEBUG_RF_KILL
(
"RFKILL initialization complete.
\n
"
);
...
...
@@ -125,22 +121,27 @@ EXPORT_SYMBOL(iwl_rfkill_init);
void
iwl_rfkill_unregister
(
struct
iwl_priv
*
priv
)
{
if
(
priv
->
rfkill
_mngr
.
rfkill
)
rfkill_unregister
(
priv
->
rfkill
_mngr
.
rfkill
);
if
(
priv
->
rfkill
)
rfkill_unregister
(
priv
->
rfkill
);
priv
->
rfkill
_mngr
.
rfkill
=
NULL
;
priv
->
rfkill
=
NULL
;
}
EXPORT_SYMBOL
(
iwl_rfkill_unregister
);
/* set rf-kill to the right state. */
void
iwl_rfkill_set_hw_state
(
struct
iwl_priv
*
priv
)
{
if
(
!
priv
->
rfkill
_mngr
.
rfkill
)
if
(
!
priv
->
rfkill
)
return
;
if
(
!
iwl_is_rfkill
(
priv
))
priv
->
rfkill_mngr
.
rfkill
->
state
=
RFKILL_STATE_ON
;
if
(
iwl_is_rfkill_hw
(
priv
))
{
rfkill_force_state
(
priv
->
rfkill
,
RFKILL_STATE_HARD_BLOCKED
);
return
;
}
if
(
!
iwl_is_rfkill_sw
(
priv
))
rfkill_force_state
(
priv
->
rfkill
,
RFKILL_STATE_UNBLOCKED
);
else
priv
->
rfkill_mngr
.
rfkill
->
state
=
RFKILL_STATE_OFF
;
rfkill_force_state
(
priv
->
rfkill
,
RFKILL_STATE_SOFT_BLOCKED
)
;
}
EXPORT_SYMBOL
(
iwl_rfkill_set_hw_state
);
drivers/net/wireless/iwlwifi/iwl-rfkill.h
浏览文件 @
54dceb00
...
...
@@ -33,9 +33,6 @@ struct iwl_priv;
#include <linux/rfkill.h>
#ifdef CONFIG_IWLWIFI_RFKILL
struct
iwl_rfkill_mngr
{
struct
rfkill
*
rfkill
;
};
void
iwl_rfkill_set_hw_state
(
struct
iwl_priv
*
priv
);
void
iwl_rfkill_unregister
(
struct
iwl_priv
*
priv
);
...
...
drivers/net/wireless/iwlwifi/iwl-tx.c
浏览文件 @
54dceb00
...
...
@@ -1493,7 +1493,7 @@ void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
}
EXPORT_SYMBOL
(
iwl_rx_reply_compressed_ba
);
#ifdef CONFIG_IWLWIF_DEBUG
#ifdef CONFIG_IWLWIF
I
_DEBUG
#define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x
const
char
*
iwl_get_tx_fail_reason
(
u32
status
)
...
...
drivers/net/wireless/iwlwifi/iwl3945-base.c
浏览文件 @
54dceb00
...
...
@@ -537,10 +537,20 @@ static inline int iwl3945_is_init(struct iwl3945_priv *priv)
return
test_bit
(
STATUS_INIT
,
&
priv
->
status
);
}
static
inline
int
iwl3945_is_rfkill_sw
(
struct
iwl3945_priv
*
priv
)
{
return
test_bit
(
STATUS_RF_KILL_SW
,
&
priv
->
status
);
}
static
inline
int
iwl3945_is_rfkill_hw
(
struct
iwl3945_priv
*
priv
)
{
return
test_bit
(
STATUS_RF_KILL_HW
,
&
priv
->
status
);
}
static
inline
int
iwl3945_is_rfkill
(
struct
iwl3945_priv
*
priv
)
{
return
test_bit
(
STATUS_RF_KILL_HW
,
&
priv
->
status
)
||
test_bit
(
STATUS_RF_KILL_SW
,
&
priv
->
status
);
return
iwl3945_is_rfkill_hw
(
priv
)
||
iwl3945_is_rfkill_sw
(
priv
);
}
static
inline
int
iwl3945_is_ready_rf
(
struct
iwl3945_priv
*
priv
)
...
...
@@ -6013,12 +6023,11 @@ static int __iwl3945_up(struct iwl3945_priv *priv)
else
{
set_bit
(
STATUS_RF_KILL_HW
,
&
priv
->
status
);
if
(
!
test_bit
(
STATUS_IN_SUSPEND
,
&
priv
->
status
))
{
iwl3945_rfkill_set_hw_state
(
priv
);
IWL_WARNING
(
"Radio disabled by HW RF Kill switch
\n
"
);
return
-
ENODEV
;
}
}
iwl3945_rfkill_set_hw_state
(
priv
);
iwl3945_write32
(
priv
,
CSR_INT
,
0xFFFFFFFF
);
rc
=
iwl3945_hw_nic_init
(
priv
);
...
...
@@ -6143,8 +6152,8 @@ static void iwl3945_bg_rf_kill(struct work_struct *work)
"wireless networking to work.
\n
"
);
}
iwl3945_rfkill_set_hw_state
(
priv
);
mutex_unlock
(
&
priv
->
mutex
);
iwl3945_rfkill_set_hw_state
(
priv
);
}
static
void
iwl3945_bg_set_monitor
(
struct
work_struct
*
work
)
...
...
@@ -6398,6 +6407,7 @@ static void iwl3945_bg_up(struct work_struct *data)
mutex_lock
(
&
priv
->
mutex
);
__iwl3945_up
(
priv
);
mutex_unlock
(
&
priv
->
mutex
);
iwl3945_rfkill_set_hw_state
(
priv
);
}
static
void
iwl3945_bg_restart
(
struct
work_struct
*
data
)
...
...
@@ -6618,6 +6628,8 @@ static int iwl3945_mac_start(struct ieee80211_hw *hw)
mutex_unlock
(
&
priv
->
mutex
);
iwl3945_rfkill_set_hw_state
(
priv
);
if
(
ret
)
goto
out_release_irq
;
...
...
@@ -8276,14 +8288,14 @@ static int iwl3945_pci_resume(struct pci_dev *pdev)
#endif
/* CONFIG_PM */
/*************** RFKILL FUNCTIONS **********/
#ifdef CONFIG_IWL
WIFI
_RFKILL
#ifdef CONFIG_IWL
3945
_RFKILL
/* software rf-kill from user */
static
int
iwl3945_rfkill_soft_rf_kill
(
void
*
data
,
enum
rfkill_state
state
)
{
struct
iwl3945_priv
*
priv
=
data
;
int
err
=
0
;
if
(
!
priv
->
rfkill
_mngr
.
rfkill
)
if
(
!
priv
->
rfkill
)
return
0
;
if
(
test_bit
(
STATUS_EXIT_PENDING
,
&
priv
->
status
))
...
...
@@ -8294,20 +8306,20 @@ static int iwl3945_rfkill_soft_rf_kill(void *data, enum rfkill_state state)
switch
(
state
)
{
case
RFKILL_STATE_UNBLOCKED
:
iwl3945_radio_kill_sw
(
priv
,
0
);
/* if HW rf-kill is set dont allow ON state */
if
(
iwl3945_is_rfkill
(
priv
))
if
(
iwl3945_is_rfkill_hw
(
priv
))
{
err
=
-
EBUSY
;
goto
out_unlock
;
}
iwl3945_radio_kill_sw
(
priv
,
0
);
break
;
case
RFKILL_STATE_SOFT_BLOCKED
:
iwl3945_radio_kill_sw
(
priv
,
1
);
if
(
!
iwl3945_is_rfkill
(
priv
))
err
=
-
EBUSY
;
break
;
default:
IWL_WARNING
(
"we recieved unexpected RFKILL state %d
\n
"
,
state
);
break
;
}
out_unlock:
mutex_unlock
(
&
priv
->
mutex
);
return
err
;
...
...
@@ -8321,64 +8333,35 @@ int iwl3945_rfkill_init(struct iwl3945_priv *priv)
BUG_ON
(
device
==
NULL
);
IWL_DEBUG_RF_KILL
(
"Initializing RFKILL.
\n
"
);
priv
->
rfkill
_mngr
.
rfkill
=
rfkill_allocate
(
device
,
RFKILL_TYPE_WLAN
);
if
(
!
priv
->
rfkill
_mngr
.
rfkill
)
{
priv
->
rfkill
=
rfkill_allocate
(
device
,
RFKILL_TYPE_WLAN
);
if
(
!
priv
->
rfkill
)
{
IWL_ERROR
(
"Unable to allocate rfkill device.
\n
"
);
ret
=
-
ENOMEM
;
goto
error
;
}
priv
->
rfkill_mngr
.
rfkill
->
name
=
priv
->
cfg
->
name
;
priv
->
rfkill_mngr
.
rfkill
->
data
=
priv
;
priv
->
rfkill_mngr
.
rfkill
->
state
=
RFKILL_STATE_ON
;
priv
->
rfkill_mngr
.
rfkill
->
toggle_radio
=
iwl3945_rfkill_soft_rf_kill
;
priv
->
rfkill_mngr
.
rfkill
->
user_claim_unsupported
=
1
;
priv
->
rfkill_mngr
.
rfkill
->
dev
.
class
->
suspend
=
NULL
;
priv
->
rfkill_mngr
.
rfkill
->
dev
.
class
->
resume
=
NULL
;
priv
->
rfkill
->
name
=
priv
->
cfg
->
name
;
priv
->
rfkill
->
data
=
priv
;
priv
->
rfkill
->
state
=
RFKILL_STATE_UNBLOCKED
;
priv
->
rfkill
->
toggle_radio
=
iwl3945_rfkill_soft_rf_kill
;
priv
->
rfkill
->
user_claim_unsupported
=
1
;
priv
->
rfkill_mngr
.
input_dev
=
input_allocate_device
();
if
(
!
priv
->
rfkill_mngr
.
input_dev
)
{
IWL_ERROR
(
"Unable to allocate rfkill input device.
\n
"
);
ret
=
-
ENOMEM
;
goto
freed_rfkill
;
}
priv
->
rfkill
->
dev
.
class
->
suspend
=
NULL
;
priv
->
rfkill
->
dev
.
class
->
resume
=
NULL
;
priv
->
rfkill_mngr
.
input_dev
->
name
=
priv
->
cfg
->
name
;
priv
->
rfkill_mngr
.
input_dev
->
phys
=
wiphy_name
(
priv
->
hw
->
wiphy
);
priv
->
rfkill_mngr
.
input_dev
->
id
.
bustype
=
BUS_HOST
;
priv
->
rfkill_mngr
.
input_dev
->
id
.
vendor
=
priv
->
pci_dev
->
vendor
;
priv
->
rfkill_mngr
.
input_dev
->
dev
.
parent
=
device
;
priv
->
rfkill_mngr
.
input_dev
->
evbit
[
0
]
=
BIT
(
EV_KEY
);
set_bit
(
KEY_WLAN
,
priv
->
rfkill_mngr
.
input_dev
->
keybit
);
ret
=
rfkill_register
(
priv
->
rfkill_mngr
.
rfkill
);
ret
=
rfkill_register
(
priv
->
rfkill
);
if
(
ret
)
{
IWL_ERROR
(
"Unable to register rfkill: %d
\n
"
,
ret
);
goto
free_input_dev
;
}
ret
=
input_register_device
(
priv
->
rfkill_mngr
.
input_dev
);
if
(
ret
)
{
IWL_ERROR
(
"Unable to register rfkill input device: %d
\n
"
,
ret
);
goto
unregister_rfkill
;
goto
freed_rfkill
;
}
IWL_DEBUG_RF_KILL
(
"RFKILL initialization complete.
\n
"
);
return
ret
;
unregister_rfkill:
rfkill_unregister
(
priv
->
rfkill_mngr
.
rfkill
);
priv
->
rfkill_mngr
.
rfkill
=
NULL
;
free_input_dev:
input_free_device
(
priv
->
rfkill_mngr
.
input_dev
);
priv
->
rfkill_mngr
.
input_dev
=
NULL
;
freed_rfkill:
if
(
priv
->
rfkill
_mngr
.
rfkill
!=
NULL
)
rfkill_free
(
priv
->
rfkill
_mngr
.
rfkill
);
priv
->
rfkill
_mngr
.
rfkill
=
NULL
;
if
(
priv
->
rfkill
!=
NULL
)
rfkill_free
(
priv
->
rfkill
);
priv
->
rfkill
=
NULL
;
error:
IWL_DEBUG_RF_KILL
(
"RFKILL initialization complete.
\n
"
);
...
...
@@ -8387,28 +8370,28 @@ int iwl3945_rfkill_init(struct iwl3945_priv *priv)
void
iwl3945_rfkill_unregister
(
struct
iwl3945_priv
*
priv
)
{
if
(
priv
->
rfkill
)
rfkill_unregister
(
priv
->
rfkill
);
if
(
priv
->
rfkill_mngr
.
input_dev
)
input_unregister_device
(
priv
->
rfkill_mngr
.
input_dev
);
if
(
priv
->
rfkill_mngr
.
rfkill
)
rfkill_unregister
(
priv
->
rfkill_mngr
.
rfkill
);
priv
->
rfkill_mngr
.
input_dev
=
NULL
;
priv
->
rfkill_mngr
.
rfkill
=
NULL
;
priv
->
rfkill
=
NULL
;
}
/* set rf-kill to the right state. */
void
iwl3945_rfkill_set_hw_state
(
struct
iwl3945_priv
*
priv
)
{
if
(
!
priv
->
rfkill_mngr
.
rfkill
)
if
(
!
priv
->
rfkill
)
return
;
if
(
iwl3945_is_rfkill_hw
(
priv
))
{
rfkill_force_state
(
priv
->
rfkill
,
RFKILL_STATE_HARD_BLOCKED
);
return
;
}
if
(
!
iwl3945_is_rfkill
(
priv
))
priv
->
rfkill_mngr
.
rfkill
->
state
=
RFKILL_STATE_ON
;
if
(
!
iwl3945_is_rfkill
_sw
(
priv
))
rfkill_force_state
(
priv
->
rfkill
,
RFKILL_STATE_UNBLOCKED
)
;
else
priv
->
rfkill_mngr
.
rfkill
->
state
=
RFKILL_STATE_OFF
;
rfkill_force_state
(
priv
->
rfkill
,
RFKILL_STATE_SOFT_BLOCKED
)
;
}
#endif
...
...
drivers/net/wireless/iwlwifi/iwl4965-base.c
浏览文件 @
54dceb00
...
...
@@ -2187,13 +2187,11 @@ static int __iwl4965_up(struct iwl_priv *priv)
if
(
!
test_bit
(
STATUS_IN_SUSPEND
,
&
priv
->
status
)
&&
iwl_is_rfkill
(
priv
))
{
iwl_rfkill_set_hw_state
(
priv
);
IWL_WARNING
(
"Radio disabled by %s RF Kill switch
\n
"
,
test_bit
(
STATUS_RF_KILL_HW
,
&
priv
->
status
)
?
"HW"
:
"SW"
);
return
-
ENODEV
;
}
iwl_rfkill_set_hw_state
(
priv
);
iwl_write32
(
priv
,
CSR_INT
,
0xFFFFFFFF
);
ret
=
priv
->
cfg
->
ops
->
lib
->
alloc_shared_mem
(
priv
);
...
...
@@ -2330,9 +2328,8 @@ static void iwl4965_bg_rf_kill(struct work_struct *work)
"Kill switch must be turned off for "
"wireless networking to work.
\n
"
);
}
iwl_rfkill_set_hw_state
(
priv
);
mutex_unlock
(
&
priv
->
mutex
);
iwl_rfkill_set_hw_state
(
priv
);
}
static
void
iwl4965_bg_set_monitor
(
struct
work_struct
*
work
)
...
...
@@ -2390,6 +2387,7 @@ static void iwl4965_bg_up(struct work_struct *data)
mutex_lock
(
&
priv
->
mutex
);
__iwl4965_up
(
priv
);
mutex_unlock
(
&
priv
->
mutex
);
iwl_rfkill_set_hw_state
(
priv
);
}
static
void
iwl4965_bg_restart
(
struct
work_struct
*
data
)
...
...
@@ -2604,6 +2602,8 @@ static int iwl4965_mac_start(struct ieee80211_hw *hw)
mutex_unlock
(
&
priv
->
mutex
);
iwl_rfkill_set_hw_state
(
priv
);
if
(
ret
)
goto
out_release_irq
;
...
...
drivers/net/wireless/rt2x00/Kconfig
浏览文件 @
54dceb00
...
...
@@ -36,9 +36,7 @@ config RT2X00_LIB_FIRMWARE
config RT2X00_LIB_RFKILL
boolean
depends on RT2X00_LIB
depends on INPUT
select RFKILL
select INPUT_POLLDEV
config RT2X00_LIB_LEDS
boolean
...
...
@@ -57,7 +55,7 @@ config RT2400PCI
config RT2400PCI_RFKILL
bool "Ralink rt2400 rfkill support"
depends on RT2400PCI
&& INPUT
depends on RT2400PCI
select RT2X00_LIB_RFKILL
---help---
This adds support for integrated rt2400 hardware that features a
...
...
@@ -85,7 +83,7 @@ config RT2500PCI
config RT2500PCI_RFKILL
bool "Ralink rt2500 rfkill support"
depends on RT2500PCI
&& INPUT
depends on RT2500PCI
select RT2X00_LIB_RFKILL
---help---
This adds support for integrated rt2500 hardware that features a
...
...
@@ -115,7 +113,7 @@ config RT61PCI
config RT61PCI_RFKILL
bool "Ralink rt2501/rt61 rfkill support"
depends on RT61PCI
&& INPUT
depends on RT61PCI
select RT2X00_LIB_RFKILL
---help---
This adds support for integrated rt61 hardware that features a
...
...
drivers/net/wireless/rt2x00/rt2400pci.c
浏览文件 @
54dceb00
...
...
@@ -1087,25 +1087,48 @@ static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
static
void
rt2400pci_fill_rxdone
(
struct
queue_entry
*
entry
,
struct
rxdone_entry_desc
*
rxdesc
)
{
struct
rt2x00_dev
*
rt2x00dev
=
entry
->
queue
->
rt2x00dev
;
struct
queue_entry_priv_pci
*
entry_priv
=
entry
->
priv_data
;
u32
word0
;
u32
word2
;
u32
word3
;
u32
word4
;
u64
tsf
;
u32
rx_low
;
u32
rx_high
;
rt2x00_desc_read
(
entry_priv
->
desc
,
0
,
&
word0
);
rt2x00_desc_read
(
entry_priv
->
desc
,
2
,
&
word2
);
rt2x00_desc_read
(
entry_priv
->
desc
,
3
,
&
word3
);
rt2x00_desc_read
(
entry_priv
->
desc
,
4
,
&
word4
);
if
(
rt2x00_get_field32
(
word0
,
RXD_W0_CRC_ERROR
))
rxdesc
->
flags
|=
RX_FLAG_FAILED_FCS_CRC
;
if
(
rt2x00_get_field32
(
word0
,
RXD_W0_PHYSICAL_ERROR
))
rxdesc
->
flags
|=
RX_FLAG_FAILED_PLCP_CRC
;
/*
* We only get the lower 32bits from the timestamp,
* to get the full 64bits we must complement it with
* the timestamp from get_tsf().
* Note that when a wraparound of the lower 32bits
* has occurred between the frame arrival and the get_tsf()
* call, we must decrease the higher 32bits with 1 to get
* to correct value.
*/
tsf
=
rt2x00dev
->
ops
->
hw
->
get_tsf
(
rt2x00dev
->
hw
);
rx_low
=
rt2x00_get_field32
(
word4
,
RXD_W4_RX_END_TIME
);
rx_high
=
upper_32_bits
(
tsf
);
if
((
u32
)
tsf
<=
rx_low
)
rx_high
--
;
/*
* Obtain the status about this packet.
* The signal is the PLCP value, and needs to be stripped
* of the preamble bit (0x08).
*/
rxdesc
->
timestamp
=
((
u64
)
rx_high
<<
32
)
|
rx_low
;
rxdesc
->
signal
=
rt2x00_get_field32
(
word2
,
RXD_W2_SIGNAL
)
&
~
0x08
;
rxdesc
->
rssi
=
rt2x00_get_field32
(
word2
,
RXD_W3_RSSI
)
-
entry
->
queue
->
rt2x00dev
->
rssi_offset
;
...
...
drivers/net/wireless/rt2x00/rt2500pci.h
浏览文件 @
54dceb00
...
...
@@ -751,7 +751,7 @@
#define LEDCSR_LED_DEFAULT FIELD32(0x00100000)
/*
* AES control register.
*
SECCSR3:
AES control register.
*/
#define SECCSR3 0x00fc
...
...
@@ -895,7 +895,7 @@
#define ARTCSR2_ACK_CTS_54MBS FIELD32(0xff000000)
/*
* SECCSR1
_RT2509
: WEP control register.
* SECCSR1: WEP control register.
* KICK_ENCRYPT: Kick encryption engine, self-clear.
* ONE_SHOT: 0: ring mode, 1: One shot only mode.
* DESC_ADDRESS: Descriptor physical address of frame.
...
...
drivers/net/wireless/rt2x00/rt2500usb.h
浏览文件 @
54dceb00
...
...
@@ -209,7 +209,7 @@
#define MAC_CSR21_OFF_PERIOD FIELD16(0xff00)
/*
* Collision window control register.
*
MAC_CSR22:
Collision window control register.
*/
#define MAC_CSR22 0x042c
...
...
@@ -296,7 +296,7 @@
#define TXRX_CSR7_BBP_ID1_VALID FIELD16(0x8000)
/*
* TXRX_CSR
5
: OFDM TX BBP ID1.
* TXRX_CSR
8
: OFDM TX BBP ID1.
*/
#define TXRX_CSR8 0x0450
#define TXRX_CSR8_BBP_ID0 FIELD16(0x007f)
...
...
@@ -370,7 +370,14 @@
*/
/*
* SEC_CSR0-SEC_CSR7: Shared key 0, word 0-7
* SEC_CSR0: Shared key 0, word 0
* SEC_CSR1: Shared key 0, word 1
* SEC_CSR2: Shared key 0, word 2
* SEC_CSR3: Shared key 0, word 3
* SEC_CSR4: Shared key 0, word 4
* SEC_CSR5: Shared key 0, word 5
* SEC_CSR6: Shared key 0, word 6
* SEC_CSR7: Shared key 0, word 7
*/
#define SEC_CSR0 0x0480
#define SEC_CSR1 0x0482
...
...
@@ -382,7 +389,14 @@
#define SEC_CSR7 0x048e
/*
* SEC_CSR8-SEC_CSR15: Shared key 1, word 0-7
* SEC_CSR8: Shared key 1, word 0
* SEC_CSR9: Shared key 1, word 1
* SEC_CSR10: Shared key 1, word 2
* SEC_CSR11: Shared key 1, word 3
* SEC_CSR12: Shared key 1, word 4
* SEC_CSR13: Shared key 1, word 5
* SEC_CSR14: Shared key 1, word 6
* SEC_CSR15: Shared key 1, word 7
*/
#define SEC_CSR8 0x0490
#define SEC_CSR9 0x0492
...
...
@@ -394,7 +408,14 @@
#define SEC_CSR15 0x049e
/*
* SEC_CSR16-SEC_CSR23: Shared key 2, word 0-7
* SEC_CSR16: Shared key 2, word 0
* SEC_CSR17: Shared key 2, word 1
* SEC_CSR18: Shared key 2, word 2
* SEC_CSR19: Shared key 2, word 3
* SEC_CSR20: Shared key 2, word 4
* SEC_CSR21: Shared key 2, word 5
* SEC_CSR22: Shared key 2, word 6
* SEC_CSR23: Shared key 2, word 7
*/
#define SEC_CSR16 0x04a0
#define SEC_CSR17 0x04a2
...
...
@@ -406,7 +427,14 @@
#define SEC_CSR23 0x04ae
/*
* SEC_CSR24-SEC_CSR31: Shared key 3, word 0-7
* SEC_CSR24: Shared key 3, word 0
* SEC_CSR25: Shared key 3, word 1
* SEC_CSR26: Shared key 3, word 2
* SEC_CSR27: Shared key 3, word 3
* SEC_CSR28: Shared key 3, word 4
* SEC_CSR29: Shared key 3, word 5
* SEC_CSR30: Shared key 3, word 6
* SEC_CSR31: Shared key 3, word 7
*/
#define SEC_CSR24 0x04b0
#define SEC_CSR25 0x04b2
...
...
drivers/net/wireless/rt2x00/rt2x00.h
浏览文件 @
54dceb00
...
...
@@ -649,7 +649,7 @@ struct rt2x00_dev {
#define RFKILL_STATE_ALLOCATED 1
#define RFKILL_STATE_REGISTERED 2
struct
rfkill
*
rfkill
;
struct
input_polled_dev
*
poll_dev
;
struct
delayed_work
rfkill_work
;
#endif
/* CONFIG_RT2X00_LIB_RFKILL */
/*
...
...
@@ -787,8 +787,10 @@ struct rt2x00_dev {
/*
* Scheduled work.
* NOTE: intf_work will use ieee80211_iterate_active_interfaces()
* which means it cannot be placed on the hw->workqueue
* due to RTNL locking requirements.
*/
struct
workqueue_struct
*
workqueue
;
struct
work_struct
intf_work
;
struct
work_struct
filter_work
;
...
...
drivers/net/wireless/rt2x00/rt2x00dev.c
浏览文件 @
54dceb00
...
...
@@ -74,7 +74,7 @@ static void rt2x00lib_start_link_tuner(struct rt2x00_dev *rt2x00dev)
rt2x00lib_reset_link_tuner
(
rt2x00dev
);
queue_delayed_work
(
rt2x00dev
->
workqueue
,
queue_delayed_work
(
rt2x00dev
->
hw
->
workqueue
,
&
rt2x00dev
->
link
.
work
,
LINK_TUNE_INTERVAL
);
}
...
...
@@ -392,7 +392,7 @@ static void rt2x00lib_link_tuner(struct work_struct *work)
* Increase tuner counter, and reschedule the next link tuner run.
*/
rt2x00dev
->
link
.
count
++
;
queue_delayed_work
(
rt2x00dev
->
workqueue
,
queue_delayed_work
(
rt2x00dev
->
hw
->
workqueue
,
&
rt2x00dev
->
link
.
work
,
LINK_TUNE_INTERVAL
);
}
...
...
@@ -496,7 +496,7 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev)
rt2x00lib_beacondone_iter
,
rt2x00dev
);
queue_work
(
rt2x00dev
->
workqueue
,
&
rt2x00dev
->
intf_work
);
schedule_work
(
&
rt2x00dev
->
intf_work
);
}
EXPORT_SYMBOL_GPL
(
rt2x00lib_beacondone
);
...
...
@@ -664,6 +664,7 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
rt2x00dev
->
link
.
qual
.
rx_success
++
;
rx_status
->
mactime
=
rxdesc
.
timestamp
;
rx_status
->
rate_idx
=
idx
;
rx_status
->
qual
=
rt2x00lib_calculate_link_signal
(
rt2x00dev
,
rxdesc
.
rssi
);
...
...
@@ -1064,10 +1065,6 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
/*
* Initialize configuration work.
*/
rt2x00dev
->
workqueue
=
create_singlethread_workqueue
(
"rt2x00lib"
);
if
(
!
rt2x00dev
->
workqueue
)
goto
exit
;
INIT_WORK
(
&
rt2x00dev
->
intf_work
,
rt2x00lib_intf_scheduled
);
INIT_WORK
(
&
rt2x00dev
->
filter_work
,
rt2x00lib_packetfilter_scheduled
);
INIT_DELAYED_WORK
(
&
rt2x00dev
->
link
.
work
,
rt2x00lib_link_tuner
);
...
...
@@ -1127,13 +1124,6 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
rt2x00rfkill_free
(
rt2x00dev
);
rt2x00leds_unregister
(
rt2x00dev
);
/*
* Stop all queued work. Note that most tasks will already be halted
* during rt2x00lib_disable_radio() and rt2x00lib_uninitialize().
*/
flush_workqueue
(
rt2x00dev
->
workqueue
);
destroy_workqueue
(
rt2x00dev
->
workqueue
);
/*
* Free ieee80211_hw memory.
*/
...
...
@@ -1179,7 +1169,6 @@ int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state)
* Suspend/disable extra components.
*/
rt2x00leds_suspend
(
rt2x00dev
);
rt2x00rfkill_suspend
(
rt2x00dev
);
rt2x00debug_deregister
(
rt2x00dev
);
exit:
...
...
@@ -1235,7 +1224,6 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev)
* Restore/enable extra components.
*/
rt2x00debug_register
(
rt2x00dev
);
rt2x00rfkill_resume
(
rt2x00dev
);
rt2x00leds_resume
(
rt2x00dev
);
/*
...
...
drivers/net/wireless/rt2x00/rt2x00lib.h
浏览文件 @
54dceb00
...
...
@@ -33,7 +33,7 @@
* Both the link tuner as the rfkill will be called once per second.
*/
#define LINK_TUNE_INTERVAL ( round_jiffies_relative(HZ) )
#define RFKILL_POLL_INTERVAL (
1000
)
#define RFKILL_POLL_INTERVAL (
round_jiffies_relative(HZ)
)
/*
* rt2x00_rate: Per rate device information
...
...
@@ -204,8 +204,6 @@ void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev);
void
rt2x00rfkill_unregister
(
struct
rt2x00_dev
*
rt2x00dev
);
void
rt2x00rfkill_allocate
(
struct
rt2x00_dev
*
rt2x00dev
);
void
rt2x00rfkill_free
(
struct
rt2x00_dev
*
rt2x00dev
);
void
rt2x00rfkill_suspend
(
struct
rt2x00_dev
*
rt2x00dev
);
void
rt2x00rfkill_resume
(
struct
rt2x00_dev
*
rt2x00dev
);
#else
static
inline
void
rt2x00rfkill_register
(
struct
rt2x00_dev
*
rt2x00dev
)
{
...
...
@@ -222,14 +220,6 @@ static inline void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev)
static
inline
void
rt2x00rfkill_free
(
struct
rt2x00_dev
*
rt2x00dev
)
{
}
static
inline
void
rt2x00rfkill_suspend
(
struct
rt2x00_dev
*
rt2x00dev
)
{
}
static
inline
void
rt2x00rfkill_resume
(
struct
rt2x00_dev
*
rt2x00dev
)
{
}
#endif
/* CONFIG_RT2X00_LIB_RFKILL */
/*
...
...
drivers/net/wireless/rt2x00/rt2x00mac.c
浏览文件 @
54dceb00
...
...
@@ -431,7 +431,7 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
if
(
!
test_bit
(
DRIVER_REQUIRE_SCHEDULED
,
&
rt2x00dev
->
flags
))
rt2x00dev
->
ops
->
lib
->
config_filter
(
rt2x00dev
,
*
total_flags
);
else
queue_work
(
rt2x00dev
->
workqueue
,
&
rt2x00dev
->
filter_work
);
queue_work
(
rt2x00dev
->
hw
->
workqueue
,
&
rt2x00dev
->
filter_work
);
}
EXPORT_SYMBOL_GPL
(
rt2x00mac_configure_filter
);
...
...
@@ -512,7 +512,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
memcpy
(
&
intf
->
conf
,
bss_conf
,
sizeof
(
*
bss_conf
));
if
(
delayed
)
{
intf
->
delayed_flags
|=
delayed
;
queue_work
(
rt2x00dev
->
workqueue
,
&
rt2x00dev
->
intf_work
);
schedule_work
(
&
rt2x00dev
->
intf_work
);
}
spin_unlock
(
&
intf
->
lock
);
}
...
...
drivers/net/wireless/rt2x00/rt2x00queue.c
浏览文件 @
54dceb00
...
...
@@ -45,10 +45,11 @@ struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev,
frame_size
=
entry
->
queue
->
data_size
+
entry
->
queue
->
desc_size
;
/*
* Reserve a few bytes extra headroom to allow drivers some moving
* space (e.g. for alignment), while keeping the skb aligned.
* The payload should be aligned to a 4-byte boundary,
* this means we need at least 3 bytes for moving the frame
* into the correct offset.
*/
reserved_size
=
8
;
reserved_size
=
4
;
/*
* Allocate skbuffer.
...
...
drivers/net/wireless/rt2x00/rt2x00queue.h
浏览文件 @
54dceb00
...
...
@@ -146,6 +146,7 @@ enum rxdone_entry_desc_flags {
*
* Summary of information that has been read from the RX frame descriptor.
*
* @timestamp: RX Timestamp
* @signal: Signal of the received frame.
* @rssi: RSSI of the received frame.
* @size: Data size of the received frame.
...
...
@@ -154,6 +155,7 @@ enum rxdone_entry_desc_flags {
*/
struct
rxdone_entry_desc
{
u64
timestamp
;
int
signal
;
int
rssi
;
int
size
;
...
...
drivers/net/wireless/rt2x00/rt2x00rfkill.c
浏览文件 @
54dceb00
...
...
@@ -23,7 +23,6 @@
Abstract: rt2x00 rfkill routines.
*/
#include <linux/input-polldev.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/rfkill.h>
...
...
@@ -61,15 +60,35 @@ static int rt2x00rfkill_toggle_radio(void *data, enum rfkill_state state)
return
retval
;
}
static
void
rt2x00rfkill_poll
(
struct
input_polled_dev
*
poll_dev
)
static
int
rt2x00rfkill_get_state
(
void
*
data
,
enum
rfkill_state
*
state
)
{
struct
rt2x00_dev
*
rt2x00dev
=
poll_dev
->
private
;
int
state
=
rt2x00dev
->
ops
->
lib
->
rfkill_poll
(
rt2x00dev
);
struct
rt2x00_dev
*
rt2x00dev
=
data
;
if
(
rt2x00dev
->
rfkill
->
state
!=
state
)
{
input_report_key
(
poll_dev
->
input
,
KEY_WLAN
,
1
);
input_report_key
(
poll_dev
->
input
,
KEY_WLAN
,
0
);
}
*
state
=
rt2x00dev
->
rfkill
->
state
;
return
0
;
}
static
void
rt2x00rfkill_poll
(
struct
work_struct
*
work
)
{
struct
rt2x00_dev
*
rt2x00dev
=
container_of
(
work
,
struct
rt2x00_dev
,
rfkill_work
.
work
);
int
state
;
if
(
!
test_bit
(
RFKILL_STATE_REGISTERED
,
&
rt2x00dev
->
rfkill_state
))
return
;
/*
* rfkill_poll reports 1 when the key has been pressed and the
* radio should be blocked.
*/
state
=
!
rt2x00dev
->
ops
->
lib
->
rfkill_poll
(
rt2x00dev
)
?
RFKILL_STATE_UNBLOCKED
:
RFKILL_STATE_SOFT_BLOCKED
;
rfkill_force_state
(
rt2x00dev
->
rfkill
,
state
);
queue_delayed_work
(
rt2x00dev
->
hw
->
workqueue
,
&
rt2x00dev
->
rfkill_work
,
RFKILL_POLL_INTERVAL
);
}
void
rt2x00rfkill_register
(
struct
rt2x00_dev
*
rt2x00dev
)
...
...
@@ -83,12 +102,6 @@ void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
return
;
}
if
(
input_register_polled_device
(
rt2x00dev
->
poll_dev
))
{
ERROR
(
rt2x00dev
,
"Failed to register polled device.
\n
"
);
rfkill_unregister
(
rt2x00dev
->
rfkill
);
return
;
}
__set_bit
(
RFKILL_STATE_REGISTERED
,
&
rt2x00dev
->
rfkill_state
);
/*
...
...
@@ -96,7 +109,7 @@ void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
* and correctly sends the signal to the rfkill layer about this
* state.
*/
rt2x00rfkill_poll
(
rt2x00dev
->
poll_dev
);
rt2x00rfkill_poll
(
&
rt2x00dev
->
rfkill_work
.
work
);
}
void
rt2x00rfkill_unregister
(
struct
rt2x00_dev
*
rt2x00dev
)
...
...
@@ -105,38 +118,13 @@ void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev)
!
test_bit
(
RFKILL_STATE_REGISTERED
,
&
rt2x00dev
->
rfkill_state
))
return
;
input_unregister_polled_device
(
rt2x00dev
->
poll_dev
);
cancel_delayed_work_sync
(
&
rt2x00dev
->
rfkill_work
);
rfkill_unregister
(
rt2x00dev
->
rfkill
);
__clear_bit
(
RFKILL_STATE_REGISTERED
,
&
rt2x00dev
->
rfkill_state
);
}
static
struct
input_polled_dev
*
rt2x00rfkill_allocate_polldev
(
struct
rt2x00_dev
*
rt2x00dev
)
{
struct
input_polled_dev
*
poll_dev
;
poll_dev
=
input_allocate_polled_device
();
if
(
!
poll_dev
)
return
NULL
;
poll_dev
->
private
=
rt2x00dev
;
poll_dev
->
poll
=
rt2x00rfkill_poll
;
poll_dev
->
poll_interval
=
RFKILL_POLL_INTERVAL
;
poll_dev
->
input
->
name
=
rt2x00dev
->
ops
->
name
;
poll_dev
->
input
->
phys
=
wiphy_name
(
rt2x00dev
->
hw
->
wiphy
);
poll_dev
->
input
->
id
.
bustype
=
BUS_HOST
;
poll_dev
->
input
->
id
.
vendor
=
0x1814
;
poll_dev
->
input
->
id
.
product
=
rt2x00dev
->
chip
.
rt
;
poll_dev
->
input
->
id
.
version
=
rt2x00dev
->
chip
.
rev
;
poll_dev
->
input
->
dev
.
parent
=
wiphy_dev
(
rt2x00dev
->
hw
->
wiphy
);
poll_dev
->
input
->
evbit
[
0
]
=
BIT
(
EV_KEY
);
set_bit
(
KEY_WLAN
,
poll_dev
->
input
->
keybit
);
return
poll_dev
;
}
void
rt2x00rfkill_allocate
(
struct
rt2x00_dev
*
rt2x00dev
)
{
if
(
!
test_bit
(
CONFIG_SUPPORT_HW_BUTTON
,
&
rt2x00dev
->
flags
))
...
...
@@ -153,14 +141,9 @@ void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev)
rt2x00dev
->
rfkill
->
data
=
rt2x00dev
;
rt2x00dev
->
rfkill
->
state
=
-
1
;
rt2x00dev
->
rfkill
->
toggle_radio
=
rt2x00rfkill_toggle_radio
;
rt2x00dev
->
rfkill
->
get_state
=
rt2x00rfkill_get_state
;
rt2x00dev
->
poll_dev
=
rt2x00rfkill_allocate_polldev
(
rt2x00dev
);
if
(
!
rt2x00dev
->
poll_dev
)
{
ERROR
(
rt2x00dev
,
"Failed to allocate polled device.
\n
"
);
rfkill_free
(
rt2x00dev
->
rfkill
);
rt2x00dev
->
rfkill
=
NULL
;
return
;
}
INIT_DELAYED_WORK
(
&
rt2x00dev
->
rfkill_work
,
rt2x00rfkill_poll
);
return
;
}
...
...
@@ -171,32 +154,8 @@ void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev)
!
test_bit
(
RFKILL_STATE_ALLOCATED
,
&
rt2x00dev
->
rfkill_state
))
return
;
input_free_polled_device
(
rt2x00dev
->
poll_dev
);
rt2x00dev
->
poll_dev
=
NULL
;
cancel_delayed_work_sync
(
&
rt2x00dev
->
rfkill_work
);
rfkill_free
(
rt2x00dev
->
rfkill
);
rt2x00dev
->
rfkill
=
NULL
;
}
void
rt2x00rfkill_suspend
(
struct
rt2x00_dev
*
rt2x00dev
)
{
if
(
!
test_bit
(
CONFIG_SUPPORT_HW_BUTTON
,
&
rt2x00dev
->
flags
)
||
!
test_bit
(
RFKILL_STATE_ALLOCATED
,
&
rt2x00dev
->
rfkill_state
))
return
;
input_free_polled_device
(
rt2x00dev
->
poll_dev
);
rt2x00dev
->
poll_dev
=
NULL
;
}
void
rt2x00rfkill_resume
(
struct
rt2x00_dev
*
rt2x00dev
)
{
if
(
!
test_bit
(
CONFIG_SUPPORT_HW_BUTTON
,
&
rt2x00dev
->
flags
)
||
!
test_bit
(
RFKILL_STATE_ALLOCATED
,
&
rt2x00dev
->
rfkill_state
))
return
;
rt2x00dev
->
poll_dev
=
rt2x00rfkill_allocate_polldev
(
rt2x00dev
);
if
(
!
rt2x00dev
->
poll_dev
)
{
ERROR
(
rt2x00dev
,
"Failed to allocate polled device.
\n
"
);
return
;
}
}
drivers/net/wireless/rtl8187.h
浏览文件 @
54dceb00
...
...
@@ -44,17 +44,48 @@ struct rtl8187_rx_hdr {
__le64
mac_time
;
}
__attribute__
((
packed
));
struct
rtl8187
_t
x_hdr
{
struct
rtl8187
b_r
x_hdr
{
__le32
flags
;
__le64
mac_time
;
u8
noise
;
u8
signal
;
u8
agc
;
u8
reserved
;
__le32
unused
;
}
__attribute__
((
packed
));
/* {rtl8187,rtl8187b}_tx_info is in skb */
/* Tx flags are common between rtl8187 and rtl8187b */
#define RTL8187_TX_FLAG_NO_ENCRYPT (1 << 15)
#define RTL8187_TX_FLAG_MORE_FRAG (1 << 17)
#define RTL8187_TX_FLAG_CTS (1 << 18)
#define RTL8187_TX_FLAG_RTS (1 << 23)
struct
rtl8187_tx_hdr
{
__le32
flags
;
__le16
rts_duration
;
__le16
len
;
__le32
retry
;
}
__attribute__
((
packed
));
struct
rtl8187b_tx_hdr
{
__le32
flags
;
__le16
rts_duration
;
__le16
len
;
__le32
unused_1
;
__le16
unused_2
;
__le16
tx_duration
;
__le32
unused_3
;
__le32
retry
;
__le32
unused_4
[
2
];
}
__attribute__
((
packed
));
enum
{
DEVICE_RTL8187
,
DEVICE_RTL8187B
};
struct
rtl8187_priv
{
/* common between rtl818x drivers */
struct
rtl818x_csr
*
map
;
...
...
@@ -70,70 +101,120 @@ struct rtl8187_priv {
u32
rx_conf
;
u16
txpwr_base
;
u8
asic_rev
;
u8
is_rtl8187b
;
enum
{
RTL8187BvB
,
RTL8187BvD
,
RTL8187BvE
}
hw_rev
;
struct
sk_buff_head
rx_queue
;
u8
signal
;
u8
quality
;
u8
noise
;
};
void
rtl8187_write_phy
(
struct
ieee80211_hw
*
dev
,
u8
addr
,
u32
data
);
static
inline
u8
rtl818x_ioread8
(
struct
rtl8187_priv
*
priv
,
u8
*
addr
)
static
inline
u8
rtl818x_ioread8_idx
(
struct
rtl8187_priv
*
priv
,
u8
*
addr
,
u8
idx
)
{
u8
val
;
usb_control_msg
(
priv
->
udev
,
usb_rcvctrlpipe
(
priv
->
udev
,
0
),
RTL8187_REQ_GET_REG
,
RTL8187_REQT_READ
,
(
unsigned
long
)
addr
,
0
,
&
val
,
sizeof
(
val
),
HZ
/
2
);
(
unsigned
long
)
addr
,
idx
&
0x03
,
&
val
,
sizeof
(
val
),
HZ
/
2
);
return
val
;
}
static
inline
u16
rtl818x_ioread16
(
struct
rtl8187_priv
*
priv
,
__le16
*
addr
)
static
inline
u8
rtl818x_ioread8
(
struct
rtl8187_priv
*
priv
,
u8
*
addr
)
{
return
rtl818x_ioread8_idx
(
priv
,
addr
,
0
);
}
static
inline
u16
rtl818x_ioread16_idx
(
struct
rtl8187_priv
*
priv
,
__le16
*
addr
,
u8
idx
)
{
__le16
val
;
usb_control_msg
(
priv
->
udev
,
usb_rcvctrlpipe
(
priv
->
udev
,
0
),
RTL8187_REQ_GET_REG
,
RTL8187_REQT_READ
,
(
unsigned
long
)
addr
,
0
,
&
val
,
sizeof
(
val
),
HZ
/
2
);
(
unsigned
long
)
addr
,
idx
&
0x03
,
&
val
,
sizeof
(
val
),
HZ
/
2
);
return
le16_to_cpu
(
val
);
}
static
inline
u32
rtl818x_ioread32
(
struct
rtl8187_priv
*
priv
,
__le32
*
addr
)
static
inline
u16
rtl818x_ioread16
(
struct
rtl8187_priv
*
priv
,
__le16
*
addr
)
{
return
rtl818x_ioread16_idx
(
priv
,
addr
,
0
);
}
static
inline
u32
rtl818x_ioread32_idx
(
struct
rtl8187_priv
*
priv
,
__le32
*
addr
,
u8
idx
)
{
__le32
val
;
usb_control_msg
(
priv
->
udev
,
usb_rcvctrlpipe
(
priv
->
udev
,
0
),
RTL8187_REQ_GET_REG
,
RTL8187_REQT_READ
,
(
unsigned
long
)
addr
,
0
,
&
val
,
sizeof
(
val
),
HZ
/
2
);
(
unsigned
long
)
addr
,
idx
&
0x03
,
&
val
,
sizeof
(
val
),
HZ
/
2
);
return
le32_to_cpu
(
val
);
}
static
inline
void
rtl818x_iowrite8
(
struct
rtl8187_priv
*
priv
,
u8
*
addr
,
u8
val
)
static
inline
u32
rtl818x_ioread32
(
struct
rtl8187_priv
*
priv
,
__le32
*
addr
)
{
return
rtl818x_ioread32_idx
(
priv
,
addr
,
0
);
}
static
inline
void
rtl818x_iowrite8_idx
(
struct
rtl8187_priv
*
priv
,
u8
*
addr
,
u8
val
,
u8
idx
)
{
usb_control_msg
(
priv
->
udev
,
usb_sndctrlpipe
(
priv
->
udev
,
0
),
RTL8187_REQ_SET_REG
,
RTL8187_REQT_WRITE
,
(
unsigned
long
)
addr
,
0
,
&
val
,
sizeof
(
val
),
HZ
/
2
);
(
unsigned
long
)
addr
,
idx
&
0x03
,
&
val
,
sizeof
(
val
),
HZ
/
2
);
}
static
inline
void
rtl818x_iowrite8
(
struct
rtl8187_priv
*
priv
,
u8
*
addr
,
u8
val
)
{
rtl818x_iowrite8_idx
(
priv
,
addr
,
val
,
0
);
}
static
inline
void
rtl818x_iowrite16
(
struct
rtl8187_priv
*
priv
,
__le16
*
addr
,
u16
val
)
static
inline
void
rtl818x_iowrite16
_idx
(
struct
rtl8187_priv
*
priv
,
__le16
*
addr
,
u16
val
,
u8
idx
)
{
__le16
buf
=
cpu_to_le16
(
val
);
usb_control_msg
(
priv
->
udev
,
usb_sndctrlpipe
(
priv
->
udev
,
0
),
RTL8187_REQ_SET_REG
,
RTL8187_REQT_WRITE
,
(
unsigned
long
)
addr
,
0
,
&
buf
,
sizeof
(
buf
),
HZ
/
2
);
(
unsigned
long
)
addr
,
idx
&
0x03
,
&
buf
,
sizeof
(
buf
),
HZ
/
2
);
}
static
inline
void
rtl818x_iowrite32
(
struct
rtl8187_priv
*
priv
,
__le32
*
addr
,
u32
val
)
static
inline
void
rtl818x_iowrite16
(
struct
rtl8187_priv
*
priv
,
__le16
*
addr
,
u16
val
)
{
rtl818x_iowrite16_idx
(
priv
,
addr
,
val
,
0
);
}
static
inline
void
rtl818x_iowrite32_idx
(
struct
rtl8187_priv
*
priv
,
__le32
*
addr
,
u32
val
,
u8
idx
)
{
__le32
buf
=
cpu_to_le32
(
val
);
usb_control_msg
(
priv
->
udev
,
usb_sndctrlpipe
(
priv
->
udev
,
0
),
RTL8187_REQ_SET_REG
,
RTL8187_REQT_WRITE
,
(
unsigned
long
)
addr
,
0
,
&
buf
,
sizeof
(
buf
),
HZ
/
2
);
(
unsigned
long
)
addr
,
idx
&
0x03
,
&
buf
,
sizeof
(
buf
),
HZ
/
2
);
}
static
inline
void
rtl818x_iowrite32
(
struct
rtl8187_priv
*
priv
,
__le32
*
addr
,
u32
val
)
{
rtl818x_iowrite32_idx
(
priv
,
addr
,
val
,
0
);
}
#endif
/* RTL8187_H */
drivers/net/wireless/rtl8187_dev.c
浏览文件 @
54dceb00
此差异已折叠。
点击以展开。
drivers/net/wireless/rtl8187_rtl8225.c
浏览文件 @
54dceb00
...
...
@@ -305,9 +305,11 @@ static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
/* anaparam2 on */
rtl818x_iowrite8
(
priv
,
&
priv
->
map
->
EEPROM_CMD
,
RTL818X_EEPROM_CMD_CONFIG
);
reg
=
rtl818x_ioread8
(
priv
,
&
priv
->
map
->
CONFIG3
);
rtl818x_iowrite8
(
priv
,
&
priv
->
map
->
CONFIG3
,
reg
|
RTL818X_CONFIG3_ANAPARAM_WRITE
);
rtl818x_iowrite8
(
priv
,
&
priv
->
map
->
CONFIG3
,
reg
|
RTL818X_CONFIG3_ANAPARAM_WRITE
);
rtl818x_iowrite32
(
priv
,
&
priv
->
map
->
ANAPARAM2
,
RTL8225_ANAPARAM2_ON
);
rtl818x_iowrite8
(
priv
,
&
priv
->
map
->
CONFIG3
,
reg
&
~
RTL818X_CONFIG3_ANAPARAM_WRITE
);
rtl818x_iowrite8
(
priv
,
&
priv
->
map
->
CONFIG3
,
reg
&
~
RTL818X_CONFIG3_ANAPARAM_WRITE
);
rtl818x_iowrite8
(
priv
,
&
priv
->
map
->
EEPROM_CMD
,
RTL818X_EEPROM_CMD_NORMAL
);
rtl8225_write_phy_ofdm
(
dev
,
2
,
0x42
);
...
...
@@ -471,12 +473,42 @@ static void rtl8225_rf_init(struct ieee80211_hw *dev)
rtl8225_write_phy_cck
(
dev
,
0x41
,
rtl8225_threshold
[
2
]);
}
static
const
u8
rtl8225z2_agc
[]
=
{
0x5e
,
0x5e
,
0x5e
,
0x5e
,
0x5d
,
0x5b
,
0x59
,
0x57
,
0x55
,
0x53
,
0x51
,
0x4f
,
0x4d
,
0x4b
,
0x49
,
0x47
,
0x45
,
0x43
,
0x41
,
0x3f
,
0x3d
,
0x3b
,
0x39
,
0x37
,
0x35
,
0x33
,
0x31
,
0x2f
,
0x2d
,
0x2b
,
0x29
,
0x27
,
0x25
,
0x23
,
0x21
,
0x1f
,
0x1d
,
0x1b
,
0x19
,
0x17
,
0x15
,
0x13
,
0x11
,
0x0f
,
0x0d
,
0x0b
,
0x09
,
0x07
,
0x05
,
0x03
,
0x01
,
0x01
,
0x01
,
0x01
,
0x01
,
0x01
,
0x01
,
0x01
,
0x01
,
0x01
,
0x01
,
0x01
,
0x01
,
0x01
,
0x19
,
0x19
,
0x19
,
0x19
,
0x19
,
0x19
,
0x19
,
0x19
,
0x19
,
0x20
,
0x21
,
0x22
,
0x23
,
0x24
,
0x25
,
0x26
,
0x26
,
0x27
,
0x27
,
0x28
,
0x28
,
0x29
,
0x2a
,
0x2a
,
0x2a
,
0x2b
,
0x2b
,
0x2b
,
0x2c
,
0x2c
,
0x2c
,
0x2d
,
0x2d
,
0x2d
,
0x2d
,
0x2e
,
0x2e
,
0x2e
,
0x2e
,
0x2f
,
0x2f
,
0x2f
,
0x30
,
0x30
,
0x31
,
0x31
,
0x31
,
0x31
,
0x31
,
0x31
,
0x31
,
0x31
,
0x31
,
0x31
,
0x31
,
0x31
,
0x31
,
0x31
,
0x31
,
0x31
,
0x31
,
0x31
,
0x31
,
0x31
};
static
const
u8
rtl8225z2_ofdm
[]
=
{
0x10
,
0x0d
,
0x01
,
0x00
,
0x14
,
0xfb
,
0xfb
,
0x60
,
0x00
,
0x60
,
0x00
,
0x00
,
0x00
,
0x5c
,
0x00
,
0x00
,
0x40
,
0x00
,
0x40
,
0x00
,
0x00
,
0x00
,
0xa8
,
0x26
,
0x32
,
0x33
,
0x07
,
0xa5
,
0x6f
,
0x55
,
0xc8
,
0xb3
,
0x0a
,
0xe1
,
0x2C
,
0x8a
,
0x86
,
0x83
,
0x34
,
0x0f
,
0x4f
,
0x24
,
0x6f
,
0xc2
,
0x6b
,
0x40
,
0x80
,
0x00
,
0xc0
,
0xc1
,
0x58
,
0xf1
,
0x00
,
0xe4
,
0x90
,
0x3e
,
0x6d
,
0x3c
,
0xfb
,
0x07
};
static
const
u8
rtl8225z2_tx_power_cck_ch14
[]
=
{
0x36
,
0x35
,
0x2e
,
0x1b
,
0x00
,
0x00
,
0x00
,
0x00
0x36
,
0x35
,
0x2e
,
0x1b
,
0x00
,
0x00
,
0x00
,
0x00
,
0x30
,
0x2f
,
0x29
,
0x15
,
0x00
,
0x00
,
0x00
,
0x00
,
0x30
,
0x2f
,
0x29
,
0x15
,
0x00
,
0x00
,
0x00
,
0x00
,
0x30
,
0x2f
,
0x29
,
0x15
,
0x00
,
0x00
,
0x00
,
0x00
};
static
const
u8
rtl8225z2_tx_power_cck
[]
=
{
0x36
,
0x35
,
0x2e
,
0x25
,
0x1c
,
0x12
,
0x09
,
0x04
0x36
,
0x35
,
0x2e
,
0x25
,
0x1c
,
0x12
,
0x09
,
0x04
,
0x30
,
0x2f
,
0x29
,
0x21
,
0x19
,
0x10
,
0x08
,
0x03
,
0x2b
,
0x2a
,
0x25
,
0x1e
,
0x16
,
0x0e
,
0x07
,
0x03
,
0x26
,
0x25
,
0x21
,
0x1b
,
0x14
,
0x0d
,
0x06
,
0x03
};
static
const
u8
rtl8225z2_tx_power_ofdm
[]
=
{
...
...
@@ -526,9 +558,11 @@ static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
/* anaparam2 on */
rtl818x_iowrite8
(
priv
,
&
priv
->
map
->
EEPROM_CMD
,
RTL818X_EEPROM_CMD_CONFIG
);
reg
=
rtl818x_ioread8
(
priv
,
&
priv
->
map
->
CONFIG3
);
rtl818x_iowrite8
(
priv
,
&
priv
->
map
->
CONFIG3
,
reg
|
RTL818X_CONFIG3_ANAPARAM_WRITE
);
rtl818x_iowrite8
(
priv
,
&
priv
->
map
->
CONFIG3
,
reg
|
RTL818X_CONFIG3_ANAPARAM_WRITE
);
rtl818x_iowrite32
(
priv
,
&
priv
->
map
->
ANAPARAM2
,
RTL8225_ANAPARAM2_ON
);
rtl818x_iowrite8
(
priv
,
&
priv
->
map
->
CONFIG3
,
reg
&
~
RTL818X_CONFIG3_ANAPARAM_WRITE
);
rtl818x_iowrite8
(
priv
,
&
priv
->
map
->
CONFIG3
,
reg
&
~
RTL818X_CONFIG3_ANAPARAM_WRITE
);
rtl818x_iowrite8
(
priv
,
&
priv
->
map
->
EEPROM_CMD
,
RTL818X_EEPROM_CMD_NORMAL
);
rtl8225_write_phy_ofdm
(
dev
,
2
,
0x42
);
...
...
@@ -542,6 +576,85 @@ static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
msleep
(
1
);
}
static
void
rtl8225z2_b_rf_set_tx_power
(
struct
ieee80211_hw
*
dev
,
int
channel
)
{
struct
rtl8187_priv
*
priv
=
dev
->
priv
;
u8
cck_power
,
ofdm_power
;
const
u8
*
tmp
;
int
i
;
cck_power
=
priv
->
channels
[
channel
-
1
].
hw_value
&
0xF
;
ofdm_power
=
priv
->
channels
[
channel
-
1
].
hw_value
>>
4
;
if
(
cck_power
>
15
)
cck_power
=
(
priv
->
hw_rev
==
RTL8187BvB
)
?
15
:
22
;
else
cck_power
+=
(
priv
->
hw_rev
==
RTL8187BvB
)
?
0
:
7
;
cck_power
+=
priv
->
txpwr_base
&
0xF
;
cck_power
=
min
(
cck_power
,
(
u8
)
35
);
if
(
ofdm_power
>
15
)
ofdm_power
=
(
priv
->
hw_rev
==
RTL8187BvB
)
?
17
:
25
;
else
ofdm_power
+=
(
priv
->
hw_rev
==
RTL8187BvB
)
?
2
:
10
;
ofdm_power
+=
(
priv
->
txpwr_base
>>
4
)
&
0xF
;
ofdm_power
=
min
(
ofdm_power
,
(
u8
)
35
);
if
(
channel
==
14
)
tmp
=
rtl8225z2_tx_power_cck_ch14
;
else
tmp
=
rtl8225z2_tx_power_cck
;
if
(
priv
->
hw_rev
==
RTL8187BvB
)
{
if
(
cck_power
<=
6
)
;
/* do nothing */
else
if
(
cck_power
<=
11
)
tmp
+=
8
;
else
tmp
+=
16
;
}
else
{
if
(
cck_power
<=
5
)
;
/* do nothing */
else
if
(
cck_power
<=
11
)
tmp
+=
8
;
else
if
(
cck_power
<=
17
)
tmp
+=
16
;
else
tmp
+=
24
;
}
for
(
i
=
0
;
i
<
8
;
i
++
)
rtl8225_write_phy_cck
(
dev
,
0x44
+
i
,
*
tmp
++
);
rtl818x_iowrite8
(
priv
,
&
priv
->
map
->
TX_GAIN_CCK
,
rtl8225z2_tx_gain_cck_ofdm
[
cck_power
]);
msleep
(
1
);
rtl818x_iowrite8
(
priv
,
&
priv
->
map
->
TX_GAIN_OFDM
,
rtl8225z2_tx_gain_cck_ofdm
[
ofdm_power
]
<<
1
);
if
(
priv
->
hw_rev
==
RTL8187BvB
)
{
if
(
ofdm_power
<=
11
)
{
rtl8225_write_phy_ofdm
(
dev
,
0x87
,
0x60
);
rtl8225_write_phy_ofdm
(
dev
,
0x89
,
0x60
);
}
else
{
rtl8225_write_phy_ofdm
(
dev
,
0x87
,
0x5c
);
rtl8225_write_phy_ofdm
(
dev
,
0x89
,
0x5c
);
}
}
else
{
if
(
ofdm_power
<=
11
)
{
rtl8225_write_phy_ofdm
(
dev
,
0x87
,
0x5c
);
rtl8225_write_phy_ofdm
(
dev
,
0x89
,
0x5c
);
}
else
if
(
ofdm_power
<=
17
)
{
rtl8225_write_phy_ofdm
(
dev
,
0x87
,
0x54
);
rtl8225_write_phy_ofdm
(
dev
,
0x89
,
0x54
);
}
else
{
rtl8225_write_phy_ofdm
(
dev
,
0x87
,
0x50
);
rtl8225_write_phy_ofdm
(
dev
,
0x89
,
0x50
);
}
}
msleep
(
1
);
}
static
const
u16
rtl8225z2_rxgain
[]
=
{
0x0400
,
0x0401
,
0x0402
,
0x0403
,
0x0404
,
0x0405
,
0x0408
,
0x0409
,
0x040a
,
0x040b
,
0x0502
,
0x0503
,
0x0504
,
0x0505
,
0x0540
,
0x0541
,
...
...
@@ -715,6 +828,81 @@ static void rtl8225z2_rf_init(struct ieee80211_hw *dev)
rtl818x_iowrite32
(
priv
,
(
__le32
*
)
0xFF94
,
0x3dc00002
);
}
static
void
rtl8225z2_b_rf_init
(
struct
ieee80211_hw
*
dev
)
{
struct
rtl8187_priv
*
priv
=
dev
->
priv
;
int
i
;
rtl8225_write
(
dev
,
0x0
,
0x0B7
);
msleep
(
1
);
rtl8225_write
(
dev
,
0x1
,
0xEE0
);
msleep
(
1
);
rtl8225_write
(
dev
,
0x2
,
0x44D
);
msleep
(
1
);
rtl8225_write
(
dev
,
0x3
,
0x441
);
msleep
(
1
);
rtl8225_write
(
dev
,
0x4
,
0x8C3
);
msleep
(
1
);
rtl8225_write
(
dev
,
0x5
,
0xC72
);
msleep
(
1
);
rtl8225_write
(
dev
,
0x6
,
0x0E6
);
msleep
(
1
);
rtl8225_write
(
dev
,
0x7
,
0x82A
);
msleep
(
1
);
rtl8225_write
(
dev
,
0x8
,
0x03F
);
msleep
(
1
);
rtl8225_write
(
dev
,
0x9
,
0x335
);
msleep
(
1
);
rtl8225_write
(
dev
,
0xa
,
0x9D4
);
msleep
(
1
);
rtl8225_write
(
dev
,
0xb
,
0x7BB
);
msleep
(
1
);
rtl8225_write
(
dev
,
0xc
,
0x850
);
msleep
(
1
);
rtl8225_write
(
dev
,
0xd
,
0xCDF
);
msleep
(
1
);
rtl8225_write
(
dev
,
0xe
,
0x02B
);
msleep
(
1
);
rtl8225_write
(
dev
,
0xf
,
0x114
);
msleep
(
1
);
rtl8225_write
(
dev
,
0x0
,
0x1B7
);
msleep
(
1
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
rtl8225z2_rxgain
);
i
++
)
{
rtl8225_write
(
dev
,
0x1
,
i
+
1
);
msleep
(
1
);
rtl8225_write
(
dev
,
0x2
,
rtl8225z2_rxgain
[
i
]);
msleep
(
1
);
}
rtl8225_write
(
dev
,
0x3
,
0x080
);
msleep
(
1
);
rtl8225_write
(
dev
,
0x5
,
0x004
);
msleep
(
1
);
rtl8225_write
(
dev
,
0x0
,
0x0B7
);
msleep
(
1
);
msleep
(
3000
);
rtl8225_write
(
dev
,
0x2
,
0xC4D
);
msleep
(
1
);
msleep
(
2000
);
rtl8225_write
(
dev
,
0x2
,
0x44D
);
msleep
(
1
);
rtl8225_write
(
dev
,
0x0
,
0x2BF
);
msleep
(
1
);
rtl818x_iowrite8
(
priv
,
&
priv
->
map
->
TX_GAIN_CCK
,
0x03
);
rtl818x_iowrite8
(
priv
,
&
priv
->
map
->
TX_GAIN_OFDM
,
0x07
);
rtl818x_iowrite8
(
priv
,
&
priv
->
map
->
TX_ANTENNA
,
0x03
);
rtl8225_write_phy_ofdm
(
dev
,
0x80
,
0x12
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
rtl8225z2_agc
);
i
++
)
{
rtl8225_write_phy_ofdm
(
dev
,
0xF
,
rtl8225z2_agc
[
i
]);
rtl8225_write_phy_ofdm
(
dev
,
0xE
,
0x80
+
i
);
rtl8225_write_phy_ofdm
(
dev
,
0xE
,
0
);
}
rtl8225_write_phy_ofdm
(
dev
,
0x80
,
0x10
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
rtl8225z2_ofdm
);
i
++
)
rtl8225_write_phy_ofdm
(
dev
,
i
,
rtl8225z2_ofdm
[
i
]);
rtl818x_iowrite8
(
priv
,
&
priv
->
map
->
SIFS
,
0x22
);
rtl818x_iowrite8
(
priv
,
&
priv
->
map
->
SLOT
,
9
);
rtl818x_iowrite8
(
priv
,
(
u8
*
)
0xFFF0
,
28
);
rtl818x_iowrite8
(
priv
,
(
u8
*
)
0xFFF4
,
28
);
rtl818x_iowrite8
(
priv
,
(
u8
*
)
0xFFF8
,
28
);
rtl818x_iowrite8
(
priv
,
(
u8
*
)
0xFFFC
,
28
);
rtl818x_iowrite8
(
priv
,
(
u8
*
)
0xFF2D
,
0x5B
);
rtl818x_iowrite8
(
priv
,
(
u8
*
)
0xFF79
,
0x5B
);
rtl818x_iowrite32
(
priv
,
(
__le32
*
)
0xFFF0
,
(
7
<<
12
)
|
(
3
<<
8
)
|
28
);
rtl818x_iowrite32
(
priv
,
(
__le32
*
)
0xFFF4
,
(
7
<<
12
)
|
(
3
<<
8
)
|
28
);
rtl818x_iowrite32
(
priv
,
(
__le32
*
)
0xFFF8
,
(
7
<<
12
)
|
(
3
<<
8
)
|
28
);
rtl818x_iowrite32
(
priv
,
(
__le32
*
)
0xFFFC
,
(
7
<<
12
)
|
(
3
<<
8
)
|
28
);
rtl818x_iowrite8
(
priv
,
&
priv
->
map
->
ACM_CONTROL
,
0
);
rtl8225_write_phy_ofdm
(
dev
,
0x97
,
0x46
);
msleep
(
1
);
rtl8225_write_phy_ofdm
(
dev
,
0xa4
,
0xb6
);
msleep
(
1
);
rtl8225_write_phy_ofdm
(
dev
,
0x85
,
0xfc
);
msleep
(
1
);
rtl8225_write_phy_cck
(
dev
,
0xc1
,
0x88
);
msleep
(
1
);
}
static
void
rtl8225_rf_stop
(
struct
ieee80211_hw
*
dev
)
{
u8
reg
;
...
...
@@ -739,8 +927,10 @@ static void rtl8225_rf_set_channel(struct ieee80211_hw *dev,
if
(
priv
->
rf
->
init
==
rtl8225_rf_init
)
rtl8225_rf_set_tx_power
(
dev
,
chan
);
else
else
if
(
priv
->
rf
->
init
==
rtl8225z2_rf_init
)
rtl8225z2_rf_set_tx_power
(
dev
,
chan
);
else
rtl8225z2_b_rf_set_tx_power
(
dev
,
chan
);
rtl8225_write
(
dev
,
0x7
,
rtl8225_chan
[
chan
-
1
]);
msleep
(
10
);
...
...
@@ -760,19 +950,30 @@ static const struct rtl818x_rf_ops rtl8225z2_ops = {
.
set_chan
=
rtl8225_rf_set_channel
};
static
const
struct
rtl818x_rf_ops
rtl8225z2_b_ops
=
{
.
name
=
"rtl8225z2"
,
.
init
=
rtl8225z2_b_rf_init
,
.
stop
=
rtl8225_rf_stop
,
.
set_chan
=
rtl8225_rf_set_channel
};
const
struct
rtl818x_rf_ops
*
rtl8187_detect_rf
(
struct
ieee80211_hw
*
dev
)
{
u16
reg8
,
reg9
;
struct
rtl8187_priv
*
priv
=
dev
->
priv
;
rtl8225_write
(
dev
,
0
,
0x1B7
);
if
(
!
priv
->
is_rtl8187b
)
{
rtl8225_write
(
dev
,
0
,
0x1B7
);
reg8
=
rtl8225_read
(
dev
,
8
);
reg9
=
rtl8225_read
(
dev
,
9
);
reg8
=
rtl8225_read
(
dev
,
8
);
reg9
=
rtl8225_read
(
dev
,
9
);
rtl8225_write
(
dev
,
0
,
0x0B7
);
rtl8225_write
(
dev
,
0
,
0x0B7
);
if
(
reg8
!=
0x588
||
reg9
!=
0x700
)
return
&
rtl8225_ops
;
if
(
reg8
!=
0x588
||
reg9
!=
0x700
)
return
&
rtl8225_ops
;
return
&
rtl8225z2_ops
;
return
&
rtl8225z2_ops
;
}
else
return
&
rtl8225z2_b_ops
;
}
drivers/net/wireless/rtl818x.h
浏览文件 @
54dceb00
...
...
@@ -66,7 +66,10 @@ struct rtl818x_csr {
#define RTL818X_TX_CONF_R8180_F (3 << 25)
#define RTL818X_TX_CONF_R8185_ABC (4 << 25)
#define RTL818X_TX_CONF_R8185_D (5 << 25)
#define RTL818X_TX_CONF_R8187vD (5 << 25)
#define RTL818X_TX_CONF_R8187vD_B (6 << 25)
#define RTL818X_TX_CONF_HWVER_MASK (7 << 25)
#define RTL818X_TX_CONF_DISREQQSIZE (1 << 28)
#define RTL818X_TX_CONF_PROBE_DTS (1 << 29)
#define RTL818X_TX_CONF_HW_SEQNUM (1 << 30)
#define RTL818X_TX_CONF_CW_MIN (1 << 31)
...
...
@@ -106,8 +109,11 @@ struct rtl818x_csr {
#define RTL818X_MSR_NO_LINK (0 << 2)
#define RTL818X_MSR_ADHOC (1 << 2)
#define RTL818X_MSR_INFRA (2 << 2)
#define RTL818X_MSR_MASTER (3 << 2)
#define RTL818X_MSR_ENEDCA (4 << 2)
u8
CONFIG3
;
#define RTL818X_CONFIG3_ANAPARAM_WRITE (1 << 6)
#define RTL818X_CONFIG3_GNT_SELECT (1 << 7)
u8
CONFIG4
;
#define RTL818X_CONFIG4_POWEROFF (1 << 6)
#define RTL818X_CONFIG4_VCOOFF (1 << 7)
...
...
@@ -133,7 +139,9 @@ struct rtl818x_csr {
__le32
RF_TIMING
;
u8
GP_ENABLE
;
u8
GPIO
;
u8
reserved_12
[
10
];
u8
reserved_12
[
2
];
__le32
HSSI_PARA
;
u8
reserved_13
[
4
];
u8
TX_AGC_CTL
;
#define RTL818X_TX_AGC_CTL_PERPACKET_GAIN_SHIFT (1 << 0)
#define RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT (1 << 1)
...
...
@@ -141,29 +149,39 @@ struct rtl818x_csr {
u8
TX_GAIN_CCK
;
u8
TX_GAIN_OFDM
;
u8
TX_ANTENNA
;
u8
reserved_1
3
[
16
];
u8
reserved_1
4
[
16
];
u8
WPA_CONF
;
u8
reserved_1
4
[
3
];
u8
reserved_1
5
[
3
];
u8
SIFS
;
u8
DIFS
;
u8
SLOT
;
u8
reserved_1
5
[
5
];
u8
reserved_1
6
[
5
];
u8
CW_CONF
;
#define RTL818X_CW_CONF_PERPACKET_CW_SHIFT (1 << 0)
#define RTL818X_CW_CONF_PERPACKET_RETRY_SHIFT (1 << 1)
u8
CW_VAL
;
u8
RATE_FALLBACK
;
u8
reserved_16
[
25
];
#define RTL818X_RATE_FALLBACK_ENABLE (1 << 7)
u8
ACM_CONTROL
;
u8
reserved_17
[
24
];
u8
CONFIG5
;
u8
TX_DMA_POLLING
;
u8
reserved_1
7
[
2
];
u8
reserved_1
8
[
2
];
__le16
CWR
;
u8
RETRY_CTR
;
u8
reserved_18
[
5
];
u8
reserved_19
[
3
];
__le16
INT_MIG
;
/* RTL818X_R8187B_*: magic numbers from ioregisters */
#define RTL818X_R8187B_B 0
#define RTL818X_R8187B_D 1
#define RTL818X_R8187B_E 2
__le32
RDSAR
;
u8
reserved_19
[
12
];
__le16
FEMR
;
__le16
TID_AC_MAP
;
u8
reserved_20
[
4
];
u8
ANAPARAM3
;
u8
reserved_21
[
5
];
__le16
FEMR
;
u8
reserved_22
[
4
];
__le16
TALLY_CNT
;
u8
TALLY_SEL
;
}
__attribute__
((
packed
));
...
...
drivers/net/wireless/zd1211rw/zd_mac.c
浏览文件 @
54dceb00
...
...
@@ -405,43 +405,66 @@ static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs,
/* FIXME: Management frame? */
}
void
zd_mac_config_beacon
(
struct
ieee80211_hw
*
hw
,
struct
sk_buff
*
beacon
)
static
int
zd_mac_config_beacon
(
struct
ieee80211_hw
*
hw
,
struct
sk_buff
*
beacon
)
{
struct
zd_mac
*
mac
=
zd_hw_mac
(
hw
);
int
r
;
u32
tmp
,
j
=
0
;
/* 4 more bytes for tail CRC */
u32
full_len
=
beacon
->
len
+
4
;
zd_iowrite32
(
&
mac
->
chip
,
CR_BCN_FIFO_SEMAPHORE
,
0
);
zd_ioread32
(
&
mac
->
chip
,
CR_BCN_FIFO_SEMAPHORE
,
&
tmp
);
r
=
zd_iowrite32
(
&
mac
->
chip
,
CR_BCN_FIFO_SEMAPHORE
,
0
);
if
(
r
<
0
)
return
r
;
r
=
zd_ioread32
(
&
mac
->
chip
,
CR_BCN_FIFO_SEMAPHORE
,
&
tmp
);
if
(
r
<
0
)
return
r
;
while
(
tmp
&
0x2
)
{
zd_ioread32
(
&
mac
->
chip
,
CR_BCN_FIFO_SEMAPHORE
,
&
tmp
);
r
=
zd_ioread32
(
&
mac
->
chip
,
CR_BCN_FIFO_SEMAPHORE
,
&
tmp
);
if
(
r
<
0
)
return
r
;
if
((
++
j
%
100
)
==
0
)
{
printk
(
KERN_ERR
"CR_BCN_FIFO_SEMAPHORE not ready
\n
"
);
if
(
j
>=
500
)
{
printk
(
KERN_ERR
"Giving up beacon config.
\n
"
);
return
;
return
-
ETIMEDOUT
;
}
}
msleep
(
1
);
}
zd_iowrite32
(
&
mac
->
chip
,
CR_BCN_FIFO
,
full_len
-
1
);
if
(
zd_chip_is_zd1211b
(
&
mac
->
chip
))
zd_iowrite32
(
&
mac
->
chip
,
CR_BCN_LENGTH
,
full_len
-
1
);
r
=
zd_iowrite32
(
&
mac
->
chip
,
CR_BCN_FIFO
,
full_len
-
1
);
if
(
r
<
0
)
return
r
;
if
(
zd_chip_is_zd1211b
(
&
mac
->
chip
))
{
r
=
zd_iowrite32
(
&
mac
->
chip
,
CR_BCN_LENGTH
,
full_len
-
1
);
if
(
r
<
0
)
return
r
;
}
for
(
j
=
0
;
j
<
beacon
->
len
;
j
++
)
zd_iowrite32
(
&
mac
->
chip
,
CR_BCN_FIFO
,
for
(
j
=
0
;
j
<
beacon
->
len
;
j
++
)
{
r
=
zd_iowrite32
(
&
mac
->
chip
,
CR_BCN_FIFO
,
*
((
u8
*
)(
beacon
->
data
+
j
)));
if
(
r
<
0
)
return
r
;
}
for
(
j
=
0
;
j
<
4
;
j
++
)
zd_iowrite32
(
&
mac
->
chip
,
CR_BCN_FIFO
,
0x0
);
for
(
j
=
0
;
j
<
4
;
j
++
)
{
r
=
zd_iowrite32
(
&
mac
->
chip
,
CR_BCN_FIFO
,
0x0
);
if
(
r
<
0
)
return
r
;
}
r
=
zd_iowrite32
(
&
mac
->
chip
,
CR_BCN_FIFO_SEMAPHORE
,
1
);
if
(
r
<
0
)
return
r
;
zd_iowrite32
(
&
mac
->
chip
,
CR_BCN_FIFO_SEMAPHORE
,
1
);
/* 802.11b/g 2.4G CCK 1Mb
* 802.11a, not yet implemented, uses different values (see GPL vendor
* driver)
*/
zd_iowrite32
(
&
mac
->
chip
,
CR_BCN_PLCP_CFG
,
0x00000400
|
return
zd_iowrite32
(
&
mac
->
chip
,
CR_BCN_PLCP_CFG
,
0x00000400
|
(
full_len
<<
19
));
}
...
...
@@ -699,15 +722,20 @@ static int zd_op_config_interface(struct ieee80211_hw *hw,
{
struct
zd_mac
*
mac
=
zd_hw_mac
(
hw
);
int
associated
;
int
r
;
if
(
mac
->
type
==
IEEE80211_IF_TYPE_MESH_POINT
||
mac
->
type
==
IEEE80211_IF_TYPE_IBSS
)
{
associated
=
true
;
if
(
conf
->
beacon
)
{
zd_mac_config_beacon
(
hw
,
conf
->
beacon
);
kfree_skb
(
conf
->
beacon
);
zd_set_beacon_interval
(
&
mac
->
chip
,
BCN_MODE_IBSS
|
r
=
zd_mac_config_beacon
(
hw
,
conf
->
beacon
);
if
(
r
<
0
)
return
r
;
r
=
zd_set_beacon_interval
(
&
mac
->
chip
,
BCN_MODE_IBSS
|
hw
->
conf
.
beacon_int
);
if
(
r
<
0
)
return
r
;
kfree_skb
(
conf
->
beacon
);
}
}
else
associated
=
is_valid_ether_addr
(
conf
->
bssid
);
...
...
include/linux/ieee80211.h
浏览文件 @
54dceb00
...
...
@@ -99,6 +99,8 @@
#define IEEE80211_MAX_SSID_LEN 32
#define IEEE80211_MAX_MESH_ID_LEN 32
#define IEEE80211_QOS_CTL_LEN 2
#define IEEE80211_QOS_CTL_TID_MASK 0x000F
#define IEEE80211_QOS_CTL_TAG1D_MASK 0x0007
struct
ieee80211_hdr
{
__le16
frame_control
;
...
...
@@ -658,6 +660,10 @@ struct ieee80211_bar {
__le16
start_seq_num
;
}
__attribute__
((
packed
));
/* 802.11 BAR control masks */
#define IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL 0x0000
#define IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA 0x0004
/**
* struct ieee80211_ht_cap - HT capabilities
*
...
...
include/net/mac80211.h
浏览文件 @
54dceb00
...
...
@@ -42,7 +42,7 @@
* tasklet function.
*
* NOTE: If the driver opts to use the _irqsafe() functions, it may not also
* use the non-
irq
safe functions!
* use the non-
IRQ-
safe functions!
*/
/**
...
...
@@ -85,7 +85,7 @@ enum ieee80211_notification_types {
* struct ieee80211_ht_bss_info - describing BSS's HT characteristics
*
* This structure describes most essential parameters needed
* to describe 802.11n HT characteristics in a BSS
* to describe 802.11n HT characteristics in a BSS
.
*
* @primary_channel: channel number of primery channel
* @bss_cap: 802.11n's general BSS capabilities (e.g. channel width)
...
...
@@ -201,9 +201,9 @@ struct ieee80211_bss_conf {
};
/**
* enum mac80211_tx_
flags - flags to
transmission information/status
* enum mac80211_tx_
control_flags - flags to describe
transmission information/status
*
* These flags are used with the @flags member of &ieee80211_tx_info
* These flags are used with the @flags member of &ieee80211_tx_info
.
*
* @IEEE80211_TX_CTL_REQ_TX_STATUS: request TX status callback for this frame.
* @IEEE80211_TX_CTL_DO_NOT_ENCRYPT: send this frame without encryption;
...
...
@@ -212,11 +212,12 @@ struct ieee80211_bss_conf {
* @IEEE80211_TX_CTL_USE_CTS_PROTECT: use CTS protection for the frame (e.g.,
* for combined 802.11g / 802.11b networks)
* @IEEE80211_TX_CTL_NO_ACK: tell the low level not to wait for an ack
* @IEEE80211_TX_CTL_RATE_CTRL_PROBE
* @IEEE80211_TX_CTL_RATE_CTRL_PROBE
: TBD
* @IEEE80211_TX_CTL_CLEAR_PS_FILT: clear powersave filter for destination
* station
* @IEEE80211_TX_CTL_REQUEUE:
* @IEEE80211_TX_CTL_REQUEUE:
TBD
* @IEEE80211_TX_CTL_FIRST_FRAGMENT: this is a first fragment of the frame
* @IEEE80211_TX_CTL_SHORT_PREAMBLE: TBD
* @IEEE80211_TX_CTL_LONG_RETRY_LIMIT: this frame should be send using the
* through set_retry_limit configured long retry value
* @IEEE80211_TX_CTL_EAPOL_FRAME: internal to mac80211
...
...
@@ -230,11 +231,14 @@ struct ieee80211_bss_conf {
* @IEEE80211_TX_CTL_40_MHZ_WIDTH: send this frame using 40 Mhz channel width
* @IEEE80211_TX_CTL_DUP_DATA: duplicate data frame on both 20 Mhz channels
* @IEEE80211_TX_CTL_SHORT_GI: send this frame using short guard interval
* @IEEE80211_TX_CTL_INJECTED: TBD
* @IEEE80211_TX_STAT_TX_FILTERED: The frame was not transmitted
* because the destination STA was in powersave mode.
* @IEEE80211_TX_STAT_ACK: Frame was acknowledged
* @IEEE80211_TX_STAT_AMPDU: The frame was aggregated, so status
* is for the whole aggregation.
* @IEEE80211_TX_STAT_AMPDU_NO_BACK: no block ack was returned,
* so consider using block ack request (BAR).
*/
enum
mac80211_tx_control_flags
{
IEEE80211_TX_CTL_REQ_TX_STATUS
=
BIT
(
0
),
...
...
@@ -260,6 +264,7 @@ enum mac80211_tx_control_flags {
IEEE80211_TX_STAT_TX_FILTERED
=
BIT
(
20
),
IEEE80211_TX_STAT_ACK
=
BIT
(
21
),
IEEE80211_TX_STAT_AMPDU
=
BIT
(
22
),
IEEE80211_TX_STAT_AMPDU_NO_BACK
=
BIT
(
23
),
};
...
...
@@ -277,6 +282,12 @@ enum mac80211_tx_control_flags {
* (3) TX status information - driver tells mac80211 what happened
*
* @flags: transmit info flags, defined above
* @band: TBD
* @tx_rate_idx: TBD
* @antenna_sel_tx: TBD
* @control: union for control data
* @status: union for status data
* @driver_data: array of driver_data pointers
* @retry_count: number of retries
* @excessive_retries: set to 1 if the frame was retried many times
* but not acknowledged
...
...
@@ -559,8 +570,8 @@ enum ieee80211_key_alg {
/**
* enum ieee80211_key_len - key length
* @
WEP40: WEP 5
byte long key
* @
WEP104: WEP 13
byte long key
* @
LEN_WEP40: WEP 5-
byte long key
* @
LEN_WEP104: WEP 13-
byte long key
*/
enum
ieee80211_key_len
{
LEN_WEP40
=
5
,
...
...
@@ -637,7 +648,7 @@ enum set_key_cmd {
* enum sta_notify_cmd - sta notify command
*
* Used with the sta_notify() callback in &struct ieee80211_ops, this
* indicates addition and removal of a station to station table
* indicates addition and removal of a station to station table
.
*
* @STA_NOTIFY_ADD: a station was added to the station table
* @STA_NOTIFY_REMOVE: a station being removed from the station table
...
...
@@ -1337,7 +1348,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw);
*
* This function frees everything that was allocated, including the
* private data for the driver. You must call ieee80211_unregister_hw()
* before calling this function
* before calling this function
.
*
* @hw: the hardware to free
*/
...
...
@@ -1408,7 +1419,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw,
struct
sk_buff
*
skb
);
/**
* ieee80211_tx_status_irqsafe -
irq
-safe transmit status callback
* ieee80211_tx_status_irqsafe -
IRQ
-safe transmit status callback
*
* Like ieee80211_tx_status() but can be called in IRQ context
* (internally defers to a tasklet.)
...
...
@@ -1586,6 +1597,8 @@ unsigned int ieee80211_hdrlen(__le16 fc);
* @keyconf: the parameter passed with the set key
* @skb: the skb for which the key is needed
* @rc4key: a buffer to which the key will be written
* @type: TBD
* @key: TBD
*/
void
ieee80211_get_tkip_key
(
struct
ieee80211_key_conf
*
keyconf
,
struct
sk_buff
*
skb
,
...
...
@@ -1636,7 +1649,7 @@ void ieee80211_wake_queues(struct ieee80211_hw *hw);
void
ieee80211_scan_completed
(
struct
ieee80211_hw
*
hw
);
/**
* ieee80211_iterate_active_interfaces- iterate active interfaces
* ieee80211_iterate_active_interfaces
- iterate active interfaces
*
* This function iterates over the interfaces associated with a given
* hardware that are currently active and calls the callback for them.
...
...
@@ -1703,7 +1716,7 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid);
*
* This function must be called by low level driver once it has
* finished with preparations for the BA session.
* This version of the function is
irq
safe.
* This version of the function is
IRQ-
safe.
*/
void
ieee80211_start_tx_ba_cb_irqsafe
(
struct
ieee80211_hw
*
hw
,
const
u8
*
ra
,
u16
tid
);
...
...
@@ -1743,7 +1756,7 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid);
*
* This function must be called by low level driver once it has
* finished with preparations for the BA session tear down.
* This version of the function is
irq
safe.
* This version of the function is
IRQ-
safe.
*/
void
ieee80211_stop_tx_ba_cb_irqsafe
(
struct
ieee80211_hw
*
hw
,
const
u8
*
ra
,
u16
tid
);
...
...
@@ -1751,7 +1764,7 @@ void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, const u8 *ra,
/**
* ieee80211_notify_mac - low level driver notification
* @hw: pointer as obtained from ieee80211_alloc_hw().
* @notif
ication_types
: enum ieee80211_notification_types
* @notif
_type
: enum ieee80211_notification_types
*
* This function must be called by low level driver to inform mac80211 of
* low level driver status change or force mac80211 to re-assoc for low
...
...
net/mac80211/Kconfig
浏览文件 @
54dceb00
...
...
@@ -207,7 +207,6 @@ config MAC80211_LOWTX_FRAME_DUMP
config MAC80211_DEBUG_COUNTERS
bool "Extra statistics for TX/RX debugging"
depends on MAC80211_DEBUG
depends on MAC80211_DEBUG_MENU
depends on MAC80211_DEBUGFS
---help---
...
...
@@ -219,7 +218,7 @@ config MAC80211_DEBUG_COUNTERS
config MAC80211_VERBOSE_SPECT_MGMT_DEBUG
bool "Verbose Spectrum Management (IEEE 802.11h)debugging"
depends on MAC80211_DEBUG
depends on MAC80211_DEBUG
_MENU
---help---
Say Y here to print out verbose Spectrum Management (IEEE 802.11h)
debug messages.
net/mac80211/aes_ccm.c
浏览文件 @
54dceb00
...
...
@@ -16,31 +16,28 @@
#include "key.h"
#include "aes_ccm.h"
static
void
ieee80211_aes_encrypt
(
struct
crypto_cipher
*
tfm
,
const
u8
pt
[
16
],
u8
ct
[
16
])
{
crypto_cipher_encrypt_one
(
tfm
,
ct
,
pt
);
}
static
inline
void
aes_ccm_prepare
(
struct
crypto_cipher
*
tfm
,
u8
*
b_0
,
u8
*
aad
,
u8
*
b
,
u8
*
s_0
,
u8
*
a
)
static
void
aes_ccm_prepare
(
struct
crypto_cipher
*
tfm
,
u8
*
scratch
,
u8
*
a
)
{
int
i
;
u8
*
b_0
,
*
aad
,
*
b
,
*
s_0
;
ieee80211_aes_encrypt
(
tfm
,
b_0
,
b
);
b_0
=
scratch
+
3
*
AES_BLOCK_LEN
;
aad
=
scratch
+
4
*
AES_BLOCK_LEN
;
b
=
scratch
;
s_0
=
scratch
+
AES_BLOCK_LEN
;
crypto_cipher_encrypt_one
(
tfm
,
b
,
b_0
);
/* Extra Authenticate-only data (always two AES blocks) */
for
(
i
=
0
;
i
<
AES_BLOCK_LEN
;
i
++
)
aad
[
i
]
^=
b
[
i
];
ieee80211_aes_encrypt
(
tfm
,
aad
,
b
);
crypto_cipher_encrypt_one
(
tfm
,
b
,
aad
);
aad
+=
AES_BLOCK_LEN
;
for
(
i
=
0
;
i
<
AES_BLOCK_LEN
;
i
++
)
aad
[
i
]
^=
b
[
i
];
ieee80211_aes_encrypt
(
tfm
,
aad
,
a
);
crypto_cipher_encrypt_one
(
tfm
,
a
,
aad
);
/* Mask out bits from auth-only-b_0 */
b_0
[
0
]
&=
0x07
;
...
...
@@ -48,24 +45,26 @@ static inline void aes_ccm_prepare(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
/* S_0 is used to encrypt T (= MIC) */
b_0
[
14
]
=
0
;
b_0
[
15
]
=
0
;
ieee80211_aes_encrypt
(
tfm
,
b_0
,
s
_0
);
crypto_cipher_encrypt_one
(
tfm
,
s_0
,
b
_0
);
}
void
ieee80211_aes_ccm_encrypt
(
struct
crypto_cipher
*
tfm
,
u8
*
scratch
,
u8
*
b_0
,
u8
*
aad
,
u8
*
data
,
size_t
data_len
,
u8
*
data
,
size_t
data_len
,
u8
*
cdata
,
u8
*
mic
)
{
int
i
,
j
,
last_len
,
num_blocks
;
u8
*
pos
,
*
cpos
,
*
b
,
*
s_0
,
*
e
;
u8
*
pos
,
*
cpos
,
*
b
,
*
s_0
,
*
e
,
*
b_0
,
*
aad
;
b
=
scratch
;
s_0
=
scratch
+
AES_BLOCK_LEN
;
e
=
scratch
+
2
*
AES_BLOCK_LEN
;
b_0
=
scratch
+
3
*
AES_BLOCK_LEN
;
aad
=
scratch
+
4
*
AES_BLOCK_LEN
;
num_blocks
=
DIV_ROUND_UP
(
data_len
,
AES_BLOCK_LEN
);
last_len
=
data_len
%
AES_BLOCK_LEN
;
aes_ccm_prepare
(
tfm
,
b_0
,
aad
,
b
,
s_0
,
b
);
aes_ccm_prepare
(
tfm
,
scratch
,
b
);
/* Process payload blocks */
pos
=
data
;
...
...
@@ -77,11 +76,11 @@ void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch,
/* Authentication followed by encryption */
for
(
i
=
0
;
i
<
blen
;
i
++
)
b
[
i
]
^=
pos
[
i
];
ieee80211_aes_encrypt
(
tfm
,
b
,
b
);
crypto_cipher_encrypt_one
(
tfm
,
b
,
b
);
b_0
[
14
]
=
(
j
>>
8
)
&
0xff
;
b_0
[
15
]
=
j
&
0xff
;
ieee80211_aes_encrypt
(
tfm
,
b_0
,
e
);
crypto_cipher_encrypt_one
(
tfm
,
e
,
b_0
);
for
(
i
=
0
;
i
<
blen
;
i
++
)
*
cpos
++
=
*
pos
++
^
e
[
i
];
}
...
...
@@ -92,19 +91,20 @@ void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch,
int
ieee80211_aes_ccm_decrypt
(
struct
crypto_cipher
*
tfm
,
u8
*
scratch
,
u8
*
b_0
,
u8
*
aad
,
u8
*
cdata
,
size_t
data_len
,
u8
*
mic
,
u8
*
data
)
u8
*
cdata
,
size_t
data_len
,
u8
*
mic
,
u8
*
data
)
{
int
i
,
j
,
last_len
,
num_blocks
;
u8
*
pos
,
*
cpos
,
*
b
,
*
s_0
,
*
a
;
u8
*
pos
,
*
cpos
,
*
b
,
*
s_0
,
*
a
,
*
b_0
,
*
aad
;
b
=
scratch
;
s_0
=
scratch
+
AES_BLOCK_LEN
;
a
=
scratch
+
2
*
AES_BLOCK_LEN
;
b_0
=
scratch
+
3
*
AES_BLOCK_LEN
;
aad
=
scratch
+
4
*
AES_BLOCK_LEN
;
num_blocks
=
DIV_ROUND_UP
(
data_len
,
AES_BLOCK_LEN
);
last_len
=
data_len
%
AES_BLOCK_LEN
;
aes_ccm_prepare
(
tfm
,
b_0
,
aad
,
b
,
s_0
,
a
);
aes_ccm_prepare
(
tfm
,
scratch
,
a
);
/* Process payload blocks */
cpos
=
cdata
;
...
...
@@ -116,13 +116,12 @@ int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch,
/* Decryption followed by authentication */
b_0
[
14
]
=
(
j
>>
8
)
&
0xff
;
b_0
[
15
]
=
j
&
0xff
;
ieee80211_aes_encrypt
(
tfm
,
b_0
,
b
);
crypto_cipher_encrypt_one
(
tfm
,
b
,
b_0
);
for
(
i
=
0
;
i
<
blen
;
i
++
)
{
*
pos
=
*
cpos
++
^
b
[
i
];
a
[
i
]
^=
*
pos
++
;
}
ieee80211_aes_encrypt
(
tfm
,
a
,
a
);
crypto_cipher_encrypt_one
(
tfm
,
a
,
a
);
}
for
(
i
=
0
;
i
<
CCMP_MIC_LEN
;
i
++
)
{
...
...
net/mac80211/aes_ccm.h
浏览文件 @
54dceb00
...
...
@@ -16,10 +16,10 @@
struct
crypto_cipher
*
ieee80211_aes_key_setup_encrypt
(
const
u8
key
[]);
void
ieee80211_aes_ccm_encrypt
(
struct
crypto_cipher
*
tfm
,
u8
*
scratch
,
u8
*
b_0
,
u8
*
aad
,
u8
*
data
,
size_t
data_len
,
u8
*
data
,
size_t
data_len
,
u8
*
cdata
,
u8
*
mic
);
int
ieee80211_aes_ccm_decrypt
(
struct
crypto_cipher
*
tfm
,
u8
*
scratch
,
u8
*
b_0
,
u8
*
aad
,
u8
*
cdata
,
size_t
data_len
,
u8
*
cdata
,
size_t
data_len
,
u8
*
mic
,
u8
*
data
);
void
ieee80211_aes_key_free
(
struct
crypto_cipher
*
tfm
);
...
...
net/mac80211/ieee80211_i.h
浏览文件 @
54dceb00
...
...
@@ -893,7 +893,7 @@ int ieee80211_sta_deauthenticate(struct net_device *dev, u16 reason);
int
ieee80211_sta_disassociate
(
struct
net_device
*
dev
,
u16
reason
);
void
ieee80211_bss_info_change_notify
(
struct
ieee80211_sub_if_data
*
sdata
,
u32
changed
);
void
ieee80211_reset_erp_info
(
struct
net_device
*
dev
);
u32
ieee80211_reset_erp_info
(
struct
net_device
*
dev
);
int
ieee80211_ht_cap_ie_to_ht_info
(
struct
ieee80211_ht_cap
*
ht_cap_ie
,
struct
ieee80211_ht_info
*
ht_info
);
int
ieee80211_ht_addt_info_ie_to_ht_bss_info
(
...
...
@@ -904,6 +904,7 @@ void ieee80211_send_addba_request(struct net_device *dev, const u8 *da,
u16
agg_size
,
u16
timeout
);
void
ieee80211_send_delba
(
struct
net_device
*
dev
,
const
u8
*
da
,
u16
tid
,
u16
initiator
,
u16
reason_code
);
void
ieee80211_send_bar
(
struct
net_device
*
dev
,
u8
*
ra
,
u16
tid
,
u16
ssn
);
void
ieee80211_sta_stop_rx_ba_session
(
struct
net_device
*
dev
,
u8
*
da
,
u16
tid
,
u16
initiator
,
u16
reason
);
...
...
net/mac80211/main.c
浏览文件 @
54dceb00
...
...
@@ -182,10 +182,11 @@ static int ieee80211_open(struct net_device *dev)
{
struct
ieee80211_sub_if_data
*
sdata
,
*
nsdata
;
struct
ieee80211_local
*
local
=
wdev_priv
(
dev
->
ieee80211_ptr
);
struct
sta_info
*
sta
;
struct
ieee80211_if_init_conf
conf
;
u32
changed
=
0
;
int
res
;
bool
need_hw_reconfig
=
0
;
struct
sta_info
*
sta
;
sdata
=
IEEE80211_DEV_TO_SUB_IF
(
dev
);
...
...
@@ -329,7 +330,8 @@ static int ieee80211_open(struct net_device *dev)
goto
err_stop
;
ieee80211_if_config
(
dev
);
ieee80211_reset_erp_info
(
dev
);
changed
|=
ieee80211_reset_erp_info
(
dev
);
ieee80211_bss_info_change_notify
(
sdata
,
changed
);
ieee80211_enable_keys
(
sdata
);
if
(
sdata
->
vif
.
type
==
IEEE80211_IF_TYPE_STA
&&
...
...
@@ -1190,15 +1192,13 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
changed
);
}
void
ieee80211_reset_erp_info
(
struct
net_device
*
dev
)
u32
ieee80211_reset_erp_info
(
struct
net_device
*
dev
)
{
struct
ieee80211_sub_if_data
*
sdata
=
IEEE80211_DEV_TO_SUB_IF
(
dev
);
sdata
->
bss_conf
.
use_cts_prot
=
0
;
sdata
->
bss_conf
.
use_short_preamble
=
0
;
ieee80211_bss_info_change_notify
(
sdata
,
BSS_CHANGED_ERP_CTS_PROT
|
BSS_CHANGED_ERP_PREAMBLE
);
return
BSS_CHANGED_ERP_CTS_PROT
|
BSS_CHANGED_ERP_PREAMBLE
;
}
void
ieee80211_tx_status_irqsafe
(
struct
ieee80211_hw
*
hw
,
...
...
@@ -1404,14 +1404,15 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
struct
ieee80211_local
*
local
=
hw_to_local
(
hw
);
struct
ieee80211_tx_info
*
info
=
IEEE80211_SKB_CB
(
skb
);
u16
frag
,
type
;
__le16
fc
;
struct
ieee80211_tx_status_rtap_hdr
*
rthdr
;
struct
ieee80211_sub_if_data
*
sdata
;
struct
net_device
*
prev_dev
=
NULL
;
struct
sta_info
*
sta
;
rcu_read_lock
();
if
(
info
->
status
.
excessive_retries
)
{
struct
sta_info
*
sta
;
sta
=
sta_info_get
(
local
,
hdr
->
addr1
);
if
(
sta
)
{
if
(
test_sta_flags
(
sta
,
WLAN_STA_PS
))
{
...
...
@@ -1426,8 +1427,24 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
}
}
fc
=
hdr
->
frame_control
;
if
((
info
->
flags
&
IEEE80211_TX_STAT_AMPDU_NO_BACK
)
&&
(
ieee80211_is_data_qos
(
fc
)))
{
u16
tid
,
ssn
;
u8
*
qc
;
sta
=
sta_info_get
(
local
,
hdr
->
addr1
);
if
(
sta
)
{
qc
=
ieee80211_get_qos_ctl
(
hdr
);
tid
=
qc
[
0
]
&
0xf
;
ssn
=
((
le16_to_cpu
(
hdr
->
seq_ctrl
)
+
0x10
)
&
IEEE80211_SCTL_SEQ
);
ieee80211_send_bar
(
sta
->
sdata
->
dev
,
hdr
->
addr1
,
tid
,
ssn
);
}
}
if
(
info
->
flags
&
IEEE80211_TX_STAT_TX_FILTERED
)
{
struct
sta_info
*
sta
;
sta
=
sta_info_get
(
local
,
hdr
->
addr1
);
if
(
sta
)
{
ieee80211_handle_filtered_frame
(
local
,
sta
,
skb
);
...
...
net/mac80211/michael.c
浏览文件 @
54dceb00
...
...
@@ -8,6 +8,7 @@
*/
#include <linux/types.h>
#include <linux/bitops.h>
#include <linux/ieee80211.h>
#include <asm/unaligned.h>
#include "michael.h"
...
...
@@ -26,9 +27,18 @@ static void michael_block(struct michael_mic_ctx *mctx, u32 val)
mctx
->
l
+=
mctx
->
r
;
}
static
void
michael_mic_hdr
(
struct
michael_mic_ctx
*
mctx
,
const
u8
*
key
,
const
u8
*
da
,
const
u8
*
sa
,
u8
priority
)
static
void
michael_mic_hdr
(
struct
michael_mic_ctx
*
mctx
,
const
u8
*
key
,
struct
ieee80211_hdr
*
hdr
)
{
u8
*
da
,
*
sa
,
tid
;
da
=
ieee80211_get_DA
(
hdr
);
sa
=
ieee80211_get_SA
(
hdr
);
if
(
ieee80211_is_data_qos
(
hdr
->
frame_control
))
tid
=
*
ieee80211_get_qos_ctl
(
hdr
)
&
IEEE80211_QOS_CTL_TID_MASK
;
else
tid
=
0
;
mctx
->
l
=
get_unaligned_le32
(
key
);
mctx
->
r
=
get_unaligned_le32
(
key
+
4
);
...
...
@@ -40,17 +50,17 @@ static void michael_mic_hdr(struct michael_mic_ctx *mctx,
michael_block
(
mctx
,
get_unaligned_le16
(
&
da
[
4
])
|
(
get_unaligned_le16
(
sa
)
<<
16
));
michael_block
(
mctx
,
get_unaligned_le32
(
&
sa
[
2
]));
michael_block
(
mctx
,
priority
);
michael_block
(
mctx
,
tid
);
}
void
michael_mic
(
const
u8
*
key
,
const
u8
*
da
,
const
u8
*
sa
,
u8
priority
,
void
michael_mic
(
const
u8
*
key
,
struct
ieee80211_hdr
*
hdr
,
const
u8
*
data
,
size_t
data_len
,
u8
*
mic
)
{
u32
val
;
size_t
block
,
blocks
,
left
;
struct
michael_mic_ctx
mctx
;
michael_mic_hdr
(
&
mctx
,
key
,
da
,
sa
,
priority
);
michael_mic_hdr
(
&
mctx
,
key
,
hdr
);
/* Real data */
blocks
=
data_len
/
4
;
...
...
net/mac80211/michael.h
浏览文件 @
54dceb00
...
...
@@ -18,7 +18,7 @@ struct michael_mic_ctx {
u32
l
,
r
;
};
void
michael_mic
(
const
u8
*
key
,
const
u8
*
da
,
const
u8
*
sa
,
u8
priority
,
void
michael_mic
(
const
u8
*
key
,
struct
ieee80211_hdr
*
hdr
,
const
u8
*
data
,
size_t
data_len
,
u8
*
mic
);
#endif
/* MICHAEL_H */
net/mac80211/mlme.c
浏览文件 @
54dceb00
...
...
@@ -366,8 +366,10 @@ static u32 ieee80211_handle_protect_preamb(struct ieee80211_sub_if_data *sdata,
bool
use_short_preamble
)
{
struct
ieee80211_bss_conf
*
bss_conf
=
&
sdata
->
bss_conf
;
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
struct
ieee80211_if_sta
*
ifsta
=
&
sdata
->
u
.
sta
;
DECLARE_MAC_BUF
(
mac
);
#endif
u32
changed
=
0
;
if
(
use_protection
!=
bss_conf
->
use_cts_prot
)
{
...
...
@@ -571,7 +573,7 @@ static void ieee80211_set_associated(struct net_device *dev,
ieee80211_sta_tear_down_BA_sessions
(
dev
,
ifsta
->
bssid
);
ifsta
->
flags
&=
~
IEEE80211_STA_ASSOCIATED
;
netif_carrier_off
(
dev
);
ieee80211_reset_erp_info
(
dev
);
changed
|=
ieee80211_reset_erp_info
(
dev
);
sdata
->
bss_conf
.
assoc_ht
=
0
;
sdata
->
bss_conf
.
ht_conf
=
NULL
;
...
...
@@ -1536,6 +1538,35 @@ void ieee80211_send_delba(struct net_device *dev, const u8 *da, u16 tid,
ieee80211_sta_tx
(
dev
,
skb
,
0
);
}
void
ieee80211_send_bar
(
struct
net_device
*
dev
,
u8
*
ra
,
u16
tid
,
u16
ssn
)
{
struct
ieee80211_local
*
local
=
wdev_priv
(
dev
->
ieee80211_ptr
);
struct
sk_buff
*
skb
;
struct
ieee80211_bar
*
bar
;
u16
bar_control
=
0
;
skb
=
dev_alloc_skb
(
sizeof
(
*
bar
)
+
local
->
hw
.
extra_tx_headroom
);
if
(
!
skb
)
{
printk
(
KERN_ERR
"%s: failed to allocate buffer for "
"bar frame
\n
"
,
dev
->
name
);
return
;
}
skb_reserve
(
skb
,
local
->
hw
.
extra_tx_headroom
);
bar
=
(
struct
ieee80211_bar
*
)
skb_put
(
skb
,
sizeof
(
*
bar
));
memset
(
bar
,
0
,
sizeof
(
*
bar
));
bar
->
frame_control
=
IEEE80211_FC
(
IEEE80211_FTYPE_CTL
,
IEEE80211_STYPE_BACK_REQ
);
memcpy
(
bar
->
ra
,
ra
,
ETH_ALEN
);
memcpy
(
bar
->
ta
,
dev
->
dev_addr
,
ETH_ALEN
);
bar_control
|=
(
u16
)
IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL
;
bar_control
|=
(
u16
)
IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA
;
bar_control
|=
(
u16
)(
tid
<<
12
);
bar
->
control
=
cpu_to_le16
(
bar_control
);
bar
->
start_seq_num
=
cpu_to_le16
(
ssn
);
ieee80211_sta_tx
(
dev
,
skb
,
0
);
}
void
ieee80211_sta_stop_rx_ba_session
(
struct
net_device
*
dev
,
u8
*
ra
,
u16
tid
,
u16
initiator
,
u16
reason
)
{
...
...
@@ -2481,6 +2512,7 @@ static int ieee80211_sta_join_ibss(struct net_device *dev,
control
->
flags
|=
IEEE80211_TX_CTL_SHORT_PREAMBLE
;
control
->
antenna_sel_tx
=
local
->
hw
.
conf
.
antenna_sel_tx
;
control
->
flags
|=
IEEE80211_TX_CTL_NO_ACK
;
control
->
flags
|=
IEEE80211_TX_CTL_DO_NOT_ENCRYPT
;
control
->
control
.
retry_limit
=
1
;
ifsta
->
probe_resp
=
skb_copy
(
skb
,
GFP_ATOMIC
);
...
...
net/mac80211/rx.c
浏览文件 @
54dceb00
...
...
@@ -321,20 +321,20 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
static
void
ieee80211_parse_qos
(
struct
ieee80211_rx_data
*
rx
)
{
u8
*
data
=
rx
->
skb
->
data
;
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
rx
->
skb
->
data
;
int
tid
;
/* does the frame have a qos control field? */
if
(
WLAN_FC_IS_QOS_DATA
(
rx
->
fc
))
{
u8
*
qc
=
data
+
ieee80211_get_hdrlen
(
rx
->
fc
)
-
QOS_CONTROL_LEN
;
if
(
ieee80211_is_data_qos
(
hdr
->
frame_control
))
{
u8
*
qc
=
ieee80211_get_qos_ctl
(
hdr
)
;
/* frame has qos control */
tid
=
qc
[
0
]
&
QOS_CONTRO
L_TID_MASK
;
if
(
qc
[
0
]
&
IEEE80211_QOS_CONTROL_A_MSDU_PRESENT
)
tid
=
*
qc
&
IEEE80211_QOS_CT
L_TID_MASK
;
if
(
*
qc
&
IEEE80211_QOS_CONTROL_A_MSDU_PRESENT
)
rx
->
flags
|=
IEEE80211_RX_AMSDU
;
else
rx
->
flags
&=
~
IEEE80211_RX_AMSDU
;
}
else
{
if
(
unlikely
(
(
rx
->
fc
&
IEEE80211_FCTL_FTYPE
)
==
IEEE80211_FTYPE_MGMT
))
{
if
(
unlikely
(
ieee80211_is_mgmt
(
hdr
->
frame_control
)
))
{
/* Separate TID for management frames */
tid
=
NUM_RX_DATA_QUEUES
-
1
;
}
else
{
...
...
@@ -352,9 +352,10 @@ static void ieee80211_parse_qos(struct ieee80211_rx_data *rx)
static
void
ieee80211_verify_ip_alignment
(
struct
ieee80211_rx_data
*
rx
)
{
#ifdef CONFIG_MAC80211_DEBUG_PACKET_ALIGNMENT
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
rx
->
skb
->
data
;
int
hdrlen
;
if
(
!
WLAN_FC_DATA_PRESENT
(
rx
->
fc
))
if
(
!
ieee80211_is_data_present
(
hdr
->
frame_control
))
return
;
/*
...
...
@@ -376,7 +377,7 @@ static void ieee80211_verify_ip_alignment(struct ieee80211_rx_data *rx)
* header and the payload is not supported, the driver is required
* to move the 802.11 header further back in that case.
*/
hdrlen
=
ieee80211_
get_hdrlen
(
rx
->
fc
);
hdrlen
=
ieee80211_
hdrlen
(
hdr
->
frame_control
);
if
(
rx
->
flags
&
IEEE80211_RX_AMSDU
)
hdrlen
+=
ETH_HLEN
;
WARN_ON_ONCE
(((
unsigned
long
)(
rx
->
skb
->
data
+
hdrlen
))
&
3
);
...
...
@@ -415,14 +416,11 @@ ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx)
static
ieee80211_rx_result
ieee80211_rx_mesh_check
(
struct
ieee80211_rx_data
*
rx
)
{
int
hdrlen
=
ieee80211_get_hdrlen
(
rx
->
fc
)
;
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
rx
->
skb
->
data
;
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
rx
->
skb
->
data
;
unsigned
int
hdrlen
=
ieee80211_hdrlen
(
hdr
->
frame_control
)
;
#define msh_h_get(h, l) ((struct ieee80211s_hdr *) ((u8 *)h + l))
if
((
rx
->
fc
&
IEEE80211_FCTL_FTYPE
)
==
IEEE80211_FTYPE_DATA
)
{
if
(
!
((
rx
->
fc
&
IEEE80211_FCTL_FROMDS
)
&&
(
rx
->
fc
&
IEEE80211_FCTL_TODS
)))
if
(
ieee80211_is_data
(
hdr
->
frame_control
))
{
if
(
!
ieee80211_has_a4
(
hdr
->
frame_control
))
return
RX_DROP_MONITOR
;
if
(
memcmp
(
hdr
->
addr4
,
rx
->
dev
->
dev_addr
,
ETH_ALEN
)
==
0
)
return
RX_DROP_MONITOR
;
...
...
@@ -435,27 +433,30 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
if
(
!
rx
->
sta
||
sta_plink_state
(
rx
->
sta
)
!=
PLINK_ESTAB
)
{
struct
ieee80211_mgmt
*
mgmt
;
if
(
(
rx
->
fc
&
IEEE80211_FCTL_FTYPE
)
!=
IEEE80211_FTYPE_MGMT
)
if
(
!
ieee80211_is_mgmt
(
hdr
->
frame_control
)
)
return
RX_DROP_MONITOR
;
switch
(
rx
->
fc
&
IEEE80211_FCTL_STYPE
)
{
case
IEEE80211_STYPE_ACTION
:
if
(
ieee80211_is_action
(
hdr
->
frame_control
))
{
mgmt
=
(
struct
ieee80211_mgmt
*
)
hdr
;
if
(
mgmt
->
u
.
action
.
category
!=
PLINK_CATEGORY
)
return
RX_DROP_MONITOR
;
/* fall through on else */
case
IEEE80211_STYPE_PROBE_REQ
:
case
IEEE80211_STYPE_PROBE_RESP
:
case
IEEE80211_STYPE_BEACON
:
return
RX_CONTINUE
;
break
;
default:
return
RX_DROP_MONITOR
;
}
}
else
if
((
rx
->
fc
&
IEEE80211_FCTL_FTYPE
)
==
IEEE80211_FTYPE_DATA
&&
is_multicast_ether_addr
(
hdr
->
addr1
)
&&
mesh_rmc_check
(
hdr
->
addr4
,
msh_h_get
(
hdr
,
hdrlen
),
rx
->
dev
))
if
(
ieee80211_is_probe_req
(
hdr
->
frame_control
)
||
ieee80211_is_probe_resp
(
hdr
->
frame_control
)
||
ieee80211_is_beacon
(
hdr
->
frame_control
))
return
RX_CONTINUE
;
return
RX_DROP_MONITOR
;
}
#define msh_h_get(h, l) ((struct ieee80211s_hdr *) ((u8 *)h + l))
if
(
ieee80211_is_data
(
hdr
->
frame_control
)
&&
is_multicast_ether_addr
(
hdr
->
addr1
)
&&
mesh_rmc_check
(
hdr
->
addr4
,
msh_h_get
(
hdr
,
hdrlen
),
rx
->
dev
))
return
RX_DROP_MONITOR
;
#undef msh_h_get
...
...
@@ -466,13 +467,11 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
static
ieee80211_rx_result
debug_noinline
ieee80211_rx_h_check
(
struct
ieee80211_rx_data
*
rx
)
{
struct
ieee80211_hdr
*
hdr
;
hdr
=
(
struct
ieee80211_hdr
*
)
rx
->
skb
->
data
;
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
rx
->
skb
->
data
;
/* Drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.2.9) */
if
(
rx
->
sta
&&
!
is_multicast_ether_addr
(
hdr
->
addr1
))
{
if
(
unlikely
(
rx
->
fc
&
IEEE80211_FCTL_RETRY
&&
if
(
unlikely
(
ieee80211_has_retry
(
hdr
->
frame_control
)
&&
rx
->
sta
->
last_seq_ctrl
[
rx
->
queue
]
==
hdr
->
seq_ctrl
))
{
if
(
rx
->
flags
&
IEEE80211_RX_RA_MATCH
)
{
...
...
@@ -501,15 +500,14 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
if
(
ieee80211_vif_is_mesh
(
&
rx
->
sdata
->
vif
))
return
ieee80211_rx_mesh_check
(
rx
);
if
(
unlikely
(((
rx
->
fc
&
IEEE80211_FCTL_FTYPE
)
==
IEEE80211_FTYPE_DATA
||
((
rx
->
fc
&
IEEE80211_FCTL_FTYPE
)
==
IEEE80211_FTYPE_CTL
&&
(
rx
->
fc
&
IEEE80211_FCTL_STYPE
)
==
IEEE80211_STYPE_PSPOLL
))
&&
if
(
unlikely
((
ieee80211_is_data
(
hdr
->
frame_control
)
||
ieee80211_is_pspoll
(
hdr
->
frame_control
))
&&
rx
->
sdata
->
vif
.
type
!=
IEEE80211_IF_TYPE_IBSS
&&
(
!
rx
->
sta
||
!
test_sta_flags
(
rx
->
sta
,
WLAN_STA_ASSOC
))))
{
if
((
!
(
rx
->
fc
&
IEEE80211_FCTL_FROMDS
)
&&
!
(
rx
->
fc
&
IEEE80211_FCTL_TODS
)
&&
(
rx
->
fc
&
IEEE80211_FCTL_FTYPE
)
==
IEEE80211_FTYPE_DATA
)
||
!
(
rx
->
flags
&
IEEE80211_RX_RA_MATCH
))
{
if
((
!
ieee80211_has_fromds
(
hdr
->
frame_control
)
&&
!
ieee80211_has_tods
(
hdr
->
frame_control
)
&&
ieee80211_is_data
(
hdr
->
frame_control
))
||
!
(
rx
->
flags
&
IEEE80211_RX_RA_MATCH
))
{
/* Drop IBSS frames and frames for other hosts
* silently. */
return
RX_DROP_MONITOR
;
...
...
@@ -525,7 +523,7 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
static
ieee80211_rx_result
debug_noinline
ieee80211_rx_h_decrypt
(
struct
ieee80211_rx_data
*
rx
)
{
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
rx
->
skb
->
data
;
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
rx
->
skb
->
data
;
int
keyidx
;
int
hdrlen
;
ieee80211_rx_result
result
=
RX_DROP_UNUSABLE
;
...
...
@@ -557,7 +555,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
* possible.
*/
if
(
!
(
rx
->
fc
&
IEEE80211_FCTL_PROTECTED
))
if
(
!
ieee80211_has_protected
(
hdr
->
frame_control
))
return
RX_CONTINUE
;
/*
...
...
@@ -586,7 +584,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
(
rx
->
status
->
flag
&
RX_FLAG_IV_STRIPPED
))
return
RX_CONTINUE
;
hdrlen
=
ieee80211_
get_hdrlen
(
rx
->
fc
);
hdrlen
=
ieee80211_
hdrlen
(
hdr
->
frame_control
);
if
(
rx
->
skb
->
len
<
8
+
hdrlen
)
return
RX_DROP_UNUSABLE
;
/* TODO: count this? */
...
...
@@ -618,7 +616,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
/* Check for weak IVs if possible */
if
(
rx
->
sta
&&
rx
->
key
->
conf
.
alg
==
ALG_WEP
&&
((
rx
->
fc
&
IEEE80211_FCTL_FTYPE
)
==
IEEE80211_FTYPE_DATA
)
&&
ieee80211_is_data
(
hdr
->
frame_control
)
&&
(
!
(
rx
->
status
->
flag
&
RX_FLAG_IV_STRIPPED
)
||
!
(
rx
->
status
->
flag
&
RX_FLAG_DECRYPTED
))
&&
ieee80211_wep_is_weak_iv
(
rx
->
skb
,
rx
->
key
))
...
...
@@ -710,7 +708,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
{
struct
sta_info
*
sta
=
rx
->
sta
;
struct
net_device
*
dev
=
rx
->
dev
;
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
rx
->
skb
->
data
;
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
rx
->
skb
->
data
;
if
(
!
sta
)
return
RX_CONTINUE
;
...
...
@@ -744,21 +742,20 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
sta
->
last_qual
=
rx
->
status
->
qual
;
sta
->
last_noise
=
rx
->
status
->
noise
;
if
(
!
(
rx
->
fc
&
IEEE80211_FCTL_MOREFRAGS
))
{
if
(
!
ieee80211_has_morefrags
(
hdr
->
frame_control
))
{
/* Change STA power saving mode only in the end of a frame
* exchange sequence */
if
(
test_sta_flags
(
sta
,
WLAN_STA_PS
)
&&
!
(
rx
->
fc
&
IEEE80211_FCTL_PM
))
!
ieee80211_has_pm
(
hdr
->
frame_control
))
rx
->
sent_ps_buffered
+=
ap_sta_ps_end
(
dev
,
sta
);
else
if
(
!
test_sta_flags
(
sta
,
WLAN_STA_PS
)
&&
(
rx
->
fc
&
IEEE80211_FCTL_PM
))
ieee80211_has_pm
(
hdr
->
frame_control
))
ap_sta_ps_start
(
dev
,
sta
);
}
/* Drop data::nullfunc frames silently, since they are used only to
* control station power saving mode. */
if
((
rx
->
fc
&
IEEE80211_FCTL_FTYPE
)
==
IEEE80211_FTYPE_DATA
&&
(
rx
->
fc
&
IEEE80211_FCTL_STYPE
)
==
IEEE80211_STYPE_NULLFUNC
)
{
if
(
ieee80211_is_nullfunc
(
hdr
->
frame_control
))
{
I802_DEBUG_INC
(
rx
->
local
->
rx_handlers_drop_nullfunc
);
/* Update counter and free packet here to avoid counting this
* as a dropped packed. */
...
...
@@ -1037,19 +1034,19 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx)
static
ieee80211_rx_result
debug_noinline
ieee80211_rx_h_remove_qos_control
(
struct
ieee80211_rx_data
*
rx
)
{
u16
fc
=
rx
->
fc
;
u8
*
data
=
rx
->
skb
->
data
;
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
data
;
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
data
;
if
(
!
WLAN_FC_IS_QOS_DATA
(
fc
))
if
(
!
ieee80211_is_data_qos
(
hdr
->
frame_control
))
return
RX_CONTINUE
;
/* remove the qos control field, update frame type and meta-data */
memmove
(
data
+
2
,
data
,
ieee80211_get_hdrlen
(
fc
)
-
2
);
hdr
=
(
struct
ieee80211_hdr
*
)
skb_pull
(
rx
->
skb
,
2
);
memmove
(
data
+
IEEE80211_QOS_CTL_LEN
,
data
,
ieee80211_hdrlen
(
hdr
->
frame_control
)
-
IEEE80211_QOS_CTL_LEN
);
hdr
=
(
struct
ieee80211_hdr
*
)
skb_pull
(
rx
->
skb
,
IEEE80211_QOS_CTL_LEN
);
/* change frame type to non QOS */
rx
->
fc
=
fc
&=
~
IEEE80211_STYPE_QOS_DATA
;
hdr
->
frame_control
=
cpu_to_le16
(
fc
);
rx
->
fc
&=
~
IEEE80211_STYPE_QOS_DATA
;
hdr
->
frame_control
&=
~
cpu_to_le16
(
IEEE80211_STYPE_QOS_DATA
);
return
RX_CONTINUE
;
}
...
...
@@ -1465,15 +1462,15 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx)
struct
ieee80211_local
*
local
=
rx
->
local
;
struct
ieee80211_hw
*
hw
=
&
local
->
hw
;
struct
sk_buff
*
skb
=
rx
->
skb
;
struct
ieee80211_bar
*
bar
=
(
struct
ieee80211_bar
*
)
skb
->
data
;
struct
ieee80211_bar
*
bar
=
(
struct
ieee80211_bar
*
)
skb
->
data
;
struct
tid_ampdu_rx
*
tid_agg_rx
;
u16
start_seq_num
;
u16
tid
;
if
(
likely
(
(
rx
->
fc
&
IEEE80211_FCTL_FTYPE
)
!=
IEEE80211_FTYPE_CTL
))
if
(
likely
(
!
ieee80211_is_ctl
(
bar
->
frame_control
)
))
return
RX_CONTINUE
;
if
(
(
rx
->
fc
&
IEEE80211_FCTL_STYPE
)
==
IEEE80211_STYPE_BACK_REQ
)
{
if
(
ieee80211_is_back_req
(
bar
->
frame_control
)
)
{
if
(
!
rx
->
sta
)
return
RX_CONTINUE
;
tid
=
le16_to_cpu
(
bar
->
control
)
>>
12
;
...
...
@@ -1527,11 +1524,12 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev,
struct
ieee80211_hdr
*
hdr
,
struct
ieee80211_rx_data
*
rx
)
{
int
keyidx
,
hdrlen
;
int
keyidx
;
unsigned
int
hdrlen
;
DECLARE_MAC_BUF
(
mac
);
DECLARE_MAC_BUF
(
mac2
);
hdrlen
=
ieee80211_
get_hdrlen_from_skb
(
rx
->
skb
);
hdrlen
=
ieee80211_
hdrlen
(
hdr
->
frame_control
);
if
(
rx
->
skb
->
len
>=
hdrlen
+
4
)
keyidx
=
rx
->
skb
->
data
[
hdrlen
+
3
]
>>
6
;
else
...
...
@@ -1545,7 +1543,7 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev,
goto
ignore
;
}
if
(
!
(
rx
->
fc
&
IEEE80211_FCTL_PROTECTED
))
if
(
!
ieee80211_has_protected
(
hdr
->
frame_control
))
goto
ignore
;
if
(
rx
->
sdata
->
vif
.
type
==
IEEE80211_IF_TYPE_AP
&&
keyidx
)
{
...
...
@@ -1558,9 +1556,8 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev,
goto
ignore
;
}
if
((
rx
->
fc
&
IEEE80211_FCTL_FTYPE
)
!=
IEEE80211_FTYPE_DATA
&&
((
rx
->
fc
&
IEEE80211_FCTL_FTYPE
)
!=
IEEE80211_FTYPE_MGMT
||
(
rx
->
fc
&
IEEE80211_FCTL_STYPE
)
!=
IEEE80211_STYPE_AUTH
))
if
(
!
ieee80211_is_data
(
hdr
->
frame_control
)
&&
!
ieee80211_is_auth
(
hdr
->
frame_control
))
goto
ignore
;
mac80211_ev_michael_mic_failure
(
rx
->
dev
,
keyidx
,
hdr
);
...
...
@@ -1731,8 +1728,7 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
case
IEEE80211_IF_TYPE_IBSS
:
if
(
!
bssid
)
return
0
;
if
((
rx
->
fc
&
IEEE80211_FCTL_FTYPE
)
==
IEEE80211_FTYPE_MGMT
&&
(
rx
->
fc
&
IEEE80211_FCTL_STYPE
)
==
IEEE80211_STYPE_BEACON
)
{
if
(
ieee80211_is_beacon
(
hdr
->
frame_control
))
{
if
(
!
rx
->
sta
)
rx
->
sta
=
ieee80211_ibss_add_sta
(
sdata
->
dev
,
rx
->
skb
,
bssid
,
hdr
->
addr2
,
...
...
@@ -1783,8 +1779,7 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
return
0
;
break
;
case
IEEE80211_IF_TYPE_WDS
:
if
(
bssid
||
(
rx
->
fc
&
IEEE80211_FCTL_FTYPE
)
!=
IEEE80211_FTYPE_DATA
)
if
(
bssid
||
!
ieee80211_is_data
(
hdr
->
frame_control
))
return
0
;
if
(
compare_ether_addr
(
sdata
->
u
.
wds
.
remote_addr
,
hdr
->
addr2
))
return
0
;
...
...
@@ -2044,7 +2039,7 @@ static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local,
if
(
!
ieee80211_is_data_qos
(
hdr
->
frame_control
))
goto
end_reorder
;
tid
=
*
ieee80211_get_qos_ctl
(
hdr
)
&
QOS_CONTRO
L_TID_MASK
;
tid
=
*
ieee80211_get_qos_ctl
(
hdr
)
&
IEEE80211_QOS_CT
L_TID_MASK
;
if
(
sta
->
ampdu_mlme
.
tid_state_rx
[
tid
]
!=
HT_AGG_STATE_OPERATIONAL
)
goto
end_reorder
;
...
...
net/mac80211/sta_info.c
浏览文件 @
54dceb00
...
...
@@ -135,6 +135,7 @@ struct sta_info *sta_info_get_by_idx(struct ieee80211_local *local, int idx,
/**
* __sta_info_free - internal STA free helper
*
* @local: pointer to the global information
* @sta: STA info to free
*
* This function must undo everything done by sta_info_alloc()
...
...
net/mac80211/sta_info.h
浏览文件 @
54dceb00
...
...
@@ -160,11 +160,21 @@ struct sta_ampdu_mlme {
* @list: global linked list entry
* @hnext: hash table linked list pointer
* @local: pointer to the global information
* @sdata: TBD
* @key: TBD
* @rate_ctrl: TBD
* @rate_ctrl_priv: TBD
* @lock: used for locking all fields that require locking, see comments
* in the header file.
* @flaglock: spinlock for flags accesses
* @ht_info: HT capabilities of this STA
* @supp_rates: Bitmap of supported rates (per band)
* @addr: MAC address of this STA
* @aid: STA's unique AID (1..2007, 0 = not assigned yet),
* only used in AP (and IBSS?) mode
* @listen_interval: TBD
* @pin_status: TBD
* @flags: STA flags, see &enum ieee80211_sta_info_flags
* @flaglock: spinlock for flags accesses
* @ps_tx_buf: buffer of frames to transmit to this station
* when it leaves power saving state
* @tx_filtered: buffer of frames we already tried to transmit
...
...
@@ -172,10 +182,41 @@ struct sta_ampdu_mlme {
* power saving state
* @rx_packets: Number of MSDUs received from this STA
* @rx_bytes: Number of bytes received from this STA
* @supp_rates: Bitmap of supported rates (per band)
* @ht_info: HT capabilities of this STA
* @lock: used for locking all fields that require locking, see comments
* in the header file.
* @wep_weak_iv_count: TBD
* @last_rx: TBD
* @num_duplicates: number of duplicate frames received from this STA
* @rx_fragments: number of received MPDUs
* @rx_dropped: number of dropped MPDUs from this STA
* @last_signal: signal of last received frame from this STA
* @last_qual: qual of last received frame from this STA
* @last_noise: noise of last received frame from this STA
* @last_seq_ctrl: last received seq/frag number from this STA (per RX queue)
* @wme_rx_queue: TBD
* @tx_filtered_count: TBD
* @tx_retry_failed: TBD
* @tx_retry_count: TBD
* @tx_num_consecutive_failures: TBD
* @tx_num_mpdu_ok: TBD
* @tx_num_mpdu_fail: TBD
* @fail_avg: moving percentage of failed MSDUs
* @tx_packets: number of RX/TX MSDUs
* @tx_bytes: TBD
* @tx_fragments: number of transmitted MPDUs
* @txrate_idx: TBD
* @last_txrate_idx: TBD
* @wme_tx_queue: TBD
* @ampdu_mlme: TBD
* @timer_to_tid: identity mapping to ID timers
* @tid_to_tx_q: map tid to tx queue
* @llid: Local link ID
* @plid: Peer link ID
* @reason: Cancel reason on PLINK_HOLDING state
* @plink_retries: Retries in establishment
* @ignore_plink_timer: TBD
* @plink_state plink_state: TBD
* @plink_timeout: TBD
* @plink_timer: TBD
* @debugfs: debug filesystem info
*/
struct
sta_info
{
/* General information, mostly static */
...
...
@@ -217,14 +258,12 @@ struct sta_info {
unsigned
long
rx_packets
,
rx_bytes
;
unsigned
long
wep_weak_iv_count
;
unsigned
long
last_rx
;
unsigned
long
num_duplicates
;
/* number of duplicate frames received
* from this STA */
unsigned
long
rx_fragments
;
/* number of received MPDUs */
unsigned
long
rx_dropped
;
/* number of dropped MPDUs from this STA */
int
last_signal
;
/* signal of last received frame from this STA */
int
last_qual
;
/* qual of last received frame from this STA */
int
last_noise
;
/* noise of last received frame from this STA */
/* last received seq/frag number from this STA (per RX queue) */
unsigned
long
num_duplicates
;
unsigned
long
rx_fragments
;
unsigned
long
rx_dropped
;
int
last_signal
;
int
last_qual
;
int
last_noise
;
__le16
last_seq_ctrl
[
NUM_RX_DATA_QUEUES
];
#ifdef CONFIG_MAC80211_DEBUG_COUNTERS
unsigned
int
wme_rx_queue
[
NUM_RX_DATA_QUEUES
];
...
...
@@ -241,9 +280,9 @@ struct sta_info {
unsigned
int
fail_avg
;
/* Updated from TX path only, no locking requirements */
unsigned
long
tx_packets
;
/* number of RX/TX MSDUs */
unsigned
long
tx_packets
;
unsigned
long
tx_bytes
;
unsigned
long
tx_fragments
;
/* number of transmitted MPDUs */
unsigned
long
tx_fragments
;
int
txrate_idx
;
int
last_txrate_idx
;
#ifdef CONFIG_MAC80211_DEBUG_COUNTERS
...
...
@@ -254,18 +293,18 @@ struct sta_info {
* Aggregation information, locked with lock.
*/
struct
sta_ampdu_mlme
ampdu_mlme
;
u8
timer_to_tid
[
STA_TID_NUM
];
/* identity mapping to ID timers */
u8
tid_to_tx_q
[
STA_TID_NUM
];
/* map tid to tx queue */
u8
timer_to_tid
[
STA_TID_NUM
];
u8
tid_to_tx_q
[
STA_TID_NUM
];
#ifdef CONFIG_MAC80211_MESH
/*
* Mesh peer link attributes
* TODO: move to a sub-structure that is referenced with pointer?
*/
__le16
llid
;
/* Local link ID */
__le16
plid
;
/* Peer link ID */
__le16
reason
;
/* Cancel reason on PLINK_HOLDING state */
u8
plink_retries
;
/* Retries in establishment */
__le16
llid
;
__le16
plid
;
__le16
reason
;
u8
plink_retries
;
bool
ignore_plink_timer
;
enum
plink_state
plink_state
;
u32
plink_timeout
;
...
...
net/mac80211/wext.c
浏览文件 @
54dceb00
...
...
@@ -800,6 +800,8 @@ static int ieee80211_ioctl_siwfrag(struct net_device *dev,
if
(
frag
->
disabled
)
local
->
fragmentation_threshold
=
IEEE80211_MAX_FRAG_THRESHOLD
;
else
if
(
!
frag
->
fixed
)
local
->
fragmentation_threshold
=
IEEE80211_MAX_FRAG_THRESHOLD
;
else
if
(
frag
->
value
<
256
||
frag
->
value
>
IEEE80211_MAX_FRAG_THRESHOLD
)
return
-
EINVAL
;
...
...
net/mac80211/wme.c
浏览文件 @
54dceb00
...
...
@@ -154,7 +154,7 @@ static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd)
queue
=
skb_get_queue_mapping
(
skb
);
rcu_read_lock
();
sta
=
sta_info_get
(
local
,
hdr
->
addr1
);
tid
=
skb
->
priority
&
QOS_CONTRO
L_TAG1D_MASK
;
tid
=
skb
->
priority
&
IEEE80211_QOS_CT
L_TAG1D_MASK
;
if
(
sta
)
{
int
ampdu_queue
=
sta
->
tid_to_tx_q
[
tid
];
if
((
ampdu_queue
<
QD_NUM
(
hw
))
&&
...
...
@@ -181,7 +181,7 @@ static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd)
if
(
ieee80211_is_data_qos
(
hdr
->
frame_control
))
{
u8
*
p
=
ieee80211_get_qos_ctl
(
hdr
);
u8
ack_policy
=
0
;
tid
=
skb
->
priority
&
QOS_CONTRO
L_TAG1D_MASK
;
tid
=
skb
->
priority
&
IEEE80211_QOS_CT
L_TAG1D_MASK
;
if
(
local
->
wifi_wme_noack_test
)
ack_policy
|=
QOS_CONTROL_ACK_POLICY_NOACK
<<
QOS_CONTROL_ACK_POLICY_SHIFT
;
...
...
@@ -210,7 +210,6 @@ static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd)
kfree_skb
(
skb
);
err
=
NET_XMIT_DROP
;
}
else
{
tid
=
skb
->
priority
&
QOS_CONTROL_TAG1D_MASK
;
skb_set_queue_mapping
(
skb
,
queue
);
qdisc
=
q
->
queues
[
queue
];
err
=
qdisc
->
enqueue
(
skb
,
qdisc
);
...
...
net/mac80211/wme.h
浏览文件 @
54dceb00
...
...
@@ -19,18 +19,10 @@
#define QOS_CONTROL_ACK_POLICY_NORMAL 0
#define QOS_CONTROL_ACK_POLICY_NOACK 1
#define QOS_CONTROL_TID_MASK 0x0f
#define QOS_CONTROL_ACK_POLICY_SHIFT 5
#define QOS_CONTROL_TAG1D_MASK 0x07
extern
const
int
ieee802_1d_to_ac
[
8
];
static
inline
int
WLAN_FC_IS_QOS_DATA
(
u16
fc
)
{
return
(
fc
&
0x8C
)
==
0x88
;
}
#ifdef CONFIG_MAC80211_QOS
void
ieee80211_install_qdisc
(
struct
net_device
*
dev
);
int
ieee80211_qdisc_installed
(
struct
net_device
*
dev
);
...
...
net/mac80211/wpa.c
浏览文件 @
54dceb00
...
...
@@ -11,6 +11,8 @@
#include <linux/slab.h>
#include <linux/skbuff.h>
#include <linux/compiler.h>
#include <linux/ieee80211.h>
#include <asm/unaligned.h>
#include <net/mac80211.h>
#include "ieee80211_i.h"
...
...
@@ -19,53 +21,30 @@
#include "aes_ccm.h"
#include "wpa.h"
static
int
ieee80211_get_hdr_info
(
const
struct
sk_buff
*
skb
,
u8
**
sa
,
u8
**
da
,
u8
*
qos_tid
,
u8
**
data
,
size_t
*
data_len
)
{
struct
ieee80211_hdr
*
hdr
;
size_t
hdrlen
;
__le16
fc
;
hdr
=
(
struct
ieee80211_hdr
*
)
skb
->
data
;
fc
=
hdr
->
frame_control
;
hdrlen
=
ieee80211_hdrlen
(
fc
);
*
sa
=
ieee80211_get_SA
(
hdr
);
*
da
=
ieee80211_get_DA
(
hdr
);
*
data
=
skb
->
data
+
hdrlen
;
*
data_len
=
skb
->
len
-
hdrlen
;
if
(
ieee80211_is_data_qos
(
fc
))
*
qos_tid
=
(
*
ieee80211_get_qos_ctl
(
hdr
)
&
0x0f
)
|
0x80
;
else
*
qos_tid
=
0
;
return
skb
->
len
<
hdrlen
?
-
1
:
0
;
}
ieee80211_tx_result
ieee80211_tx_h_michael_mic_add
(
struct
ieee80211_tx_data
*
tx
)
{
u8
*
data
,
*
sa
,
*
da
,
*
key
,
*
mic
,
qos_tid
,
key_offset
;
u8
*
data
,
*
key
,
*
mic
,
key_offset
;
size_t
data_len
;
u16
fc
;
unsigned
int
hdrlen
;
struct
ieee80211_hdr
*
hdr
;
struct
sk_buff
*
skb
=
tx
->
skb
;
int
authenticator
;
int
wpa_test
=
0
;
int
tail
;
fc
=
tx
->
fc
;
hdr
=
(
struct
ieee80211_hdr
*
)
skb
->
data
;
if
(
!
tx
->
key
||
tx
->
key
->
conf
.
alg
!=
ALG_TKIP
||
skb
->
len
<
24
||
!
WLAN_FC_DATA_PRESENT
(
fc
))
!
ieee80211_is_data_present
(
hdr
->
frame_control
))
return
TX_CONTINUE
;
if
(
ieee80211_get_hdr_info
(
skb
,
&
sa
,
&
da
,
&
qos_tid
,
&
data
,
&
data_len
))
hdrlen
=
ieee80211_hdrlen
(
hdr
->
frame_control
);
if
(
skb
->
len
<
hdrlen
)
return
TX_DROP
;
data
=
skb
->
data
+
hdrlen
;
data_len
=
skb
->
len
-
hdrlen
;
if
((
tx
->
key
->
flags
&
KEY_FLAG_UPLOADED_TO_HARDWARE
)
&&
!
(
tx
->
flags
&
IEEE80211_TX_FRAGMENTED
)
&&
!
(
tx
->
key
->
conf
.
flags
&
IEEE80211_KEY_FLAG_GENERATE_MMIC
)
&&
...
...
@@ -95,7 +74,7 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx)
NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY
;
key
=
&
tx
->
key
->
conf
.
key
[
key_offset
];
mic
=
skb_put
(
skb
,
MICHAEL_MIC_LEN
);
michael_mic
(
key
,
da
,
sa
,
qos_tid
&
0x0f
,
data
,
data_len
,
mic
);
michael_mic
(
key
,
hdr
,
data
,
data_len
,
mic
);
return
TX_CONTINUE
;
}
...
...
@@ -104,31 +83,33 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx)
ieee80211_rx_result
ieee80211_rx_h_michael_mic_verify
(
struct
ieee80211_rx_data
*
rx
)
{
u8
*
data
,
*
sa
,
*
da
,
*
key
=
NULL
,
qos_tid
,
key_offset
;
u8
*
data
,
*
key
=
NULL
,
key_offset
;
size_t
data_len
;
u16
fc
;
unsigned
int
hdrlen
;
struct
ieee80211_hdr
*
hdr
;
u8
mic
[
MICHAEL_MIC_LEN
];
struct
sk_buff
*
skb
=
rx
->
skb
;
int
authenticator
=
1
,
wpa_test
=
0
;
DECLARE_MAC_BUF
(
mac
);
fc
=
rx
->
fc
;
/*
* No way to verify the MIC if the hardware stripped it
*/
if
(
rx
->
status
->
flag
&
RX_FLAG_MMIC_STRIPPED
)
return
RX_CONTINUE
;
hdr
=
(
struct
ieee80211_hdr
*
)
skb
->
data
;
if
(
!
rx
->
key
||
rx
->
key
->
conf
.
alg
!=
ALG_TKIP
||
!
(
rx
->
fc
&
IEEE80211_FCTL_PROTECTED
)
||
!
WLAN_FC_DATA_PRESENT
(
fc
))
!
ieee80211_has_protected
(
hdr
->
frame_control
)
||
!
ieee80211_is_data_present
(
hdr
->
frame_control
))
return
RX_CONTINUE
;
if
(
ieee80211_get_hdr_info
(
skb
,
&
sa
,
&
da
,
&
qos_tid
,
&
data
,
&
data_len
)
||
data_len
<
MICHAEL_MIC_LEN
)
hdrlen
=
ieee80211_hdrlen
(
hdr
->
frame_control
);
if
(
skb
->
len
<
hdrlen
+
MICHAEL_MIC_LEN
)
return
RX_DROP_UNUSABLE
;
data_len
-=
MICHAEL_MIC_LEN
;
data
=
skb
->
data
+
hdrlen
;
data_len
=
skb
->
len
-
hdrlen
-
MICHAEL_MIC_LEN
;
#if 0
authenticator = fc & IEEE80211_FCTL_TODS; /* FIX */
...
...
@@ -141,7 +122,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx)
NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY
:
NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY
;
key
=
&
rx
->
key
->
conf
.
key
[
key_offset
];
michael_mic
(
key
,
da
,
sa
,
qos_tid
&
0x0f
,
data
,
data_len
,
mic
);
michael_mic
(
key
,
hdr
,
data
,
data_len
,
mic
);
if
(
memcmp
(
mic
,
data
+
data_len
,
MICHAEL_MIC_LEN
)
!=
0
||
wpa_test
)
{
if
(
!
(
rx
->
flags
&
IEEE80211_RX_RA_MATCH
))
return
RX_DROP_UNUSABLE
;
...
...
@@ -253,7 +234,7 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx)
hdrlen
=
ieee80211_hdrlen
(
hdr
->
frame_control
);
if
(
(
rx
->
fc
&
IEEE80211_FCTL_FTYPE
)
!=
IEEE80211_FTYPE_DATA
)
if
(
!
ieee80211_is_data
(
hdr
->
frame_control
)
)
return
RX_CONTINUE
;
if
(
!
rx
->
sta
||
skb
->
len
-
hdrlen
<
12
)
...
...
@@ -293,70 +274,68 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx)
}
static
void
ccmp_special_blocks
(
struct
sk_buff
*
skb
,
u8
*
pn
,
u8
*
b_0
,
u8
*
aad
,
static
void
ccmp_special_blocks
(
struct
sk_buff
*
skb
,
u8
*
pn
,
u8
*
scratch
,
int
encrypted
)
{
u16
fc
;
int
a4_included
,
qos_included
;
u8
qos_tid
,
*
fc_pos
,
*
data
,
*
sa
,
*
da
;
int
len_a
;
size_t
data_len
;
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
skb
->
data
;
__le16
mask_fc
;
int
a4_included
;
u8
qos_tid
;
u8
*
b_0
,
*
aad
;
u16
data_len
,
len_a
;
unsigned
int
hdrlen
;
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
skb
->
data
;
fc_pos
=
(
u8
*
)
&
hdr
->
frame_control
;
fc
=
fc_pos
[
0
]
^
(
fc_pos
[
1
]
<<
8
);
a4_included
=
(
fc
&
(
IEEE80211_FCTL_TODS
|
IEEE80211_FCTL_FROMDS
))
==
(
IEEE80211_FCTL_TODS
|
IEEE80211_FCTL_FROMDS
);
ieee80211_get_hdr_info
(
skb
,
&
sa
,
&
da
,
&
qos_tid
,
&
data
,
&
data_len
);
data_len
-=
CCMP_HDR_LEN
+
(
encrypted
?
CCMP_MIC_LEN
:
0
);
if
(
qos_tid
&
0x80
)
{
qos_included
=
1
;
qos_tid
&=
0x0f
;
}
else
qos_included
=
0
;
/* First block, b_0 */
b_0
=
scratch
+
3
*
AES_BLOCK_LEN
;
aad
=
scratch
+
4
*
AES_BLOCK_LEN
;
/*
* Mask FC: zero subtype b4 b5 b6
* Retry, PwrMgt, MoreData; set Protected
*/
mask_fc
=
hdr
->
frame_control
;
mask_fc
&=
~
cpu_to_le16
(
0x0070
|
IEEE80211_FCTL_RETRY
|
IEEE80211_FCTL_PM
|
IEEE80211_FCTL_MOREDATA
);
mask_fc
|=
cpu_to_le16
(
IEEE80211_FCTL_PROTECTED
);
hdrlen
=
ieee80211_hdrlen
(
hdr
->
frame_control
);
len_a
=
hdrlen
-
2
;
a4_included
=
ieee80211_has_a4
(
hdr
->
frame_control
);
if
(
ieee80211_is_data_qos
(
hdr
->
frame_control
))
qos_tid
=
*
ieee80211_get_qos_ctl
(
hdr
)
&
IEEE80211_QOS_CTL_TID_MASK
;
else
qos_tid
=
0
;
data_len
=
skb
->
len
-
hdrlen
-
CCMP_HDR_LEN
;
if
(
encrypted
)
data_len
-=
CCMP_MIC_LEN
;
/* First block, b_0 */
b_0
[
0
]
=
0x59
;
/* flags: Adata: 1, M: 011, L: 001 */
/* Nonce: QoS Priority | A2 | PN */
b_0
[
1
]
=
qos_tid
;
memcpy
(
&
b_0
[
2
],
hdr
->
addr2
,
6
);
memcpy
(
&
b_0
[
2
],
hdr
->
addr2
,
ETH_ALEN
);
memcpy
(
&
b_0
[
8
],
pn
,
CCMP_PN_LEN
);
/* l(m) */
b_0
[
14
]
=
(
data_len
>>
8
)
&
0xff
;
b_0
[
15
]
=
data_len
&
0xff
;
put_unaligned_be16
(
data_len
,
&
b_0
[
14
]);
/* AAD (extra authenticate-only data) / masked 802.11 header
* FC | A1 | A2 | A3 | SC | [A4] | [QC] */
len_a
=
a4_included
?
28
:
22
;
if
(
qos_included
)
len_a
+=
2
;
aad
[
0
]
=
0
;
/* (len_a >> 8) & 0xff; */
aad
[
1
]
=
len_a
&
0xff
;
/* Mask FC: zero subtype b4 b5 b6 */
aad
[
2
]
=
fc_pos
[
0
]
&
~
(
BIT
(
4
)
|
BIT
(
5
)
|
BIT
(
6
));
/* Retry, PwrMgt, MoreData; set Protected */
aad
[
3
]
=
(
fc_pos
[
1
]
&
~
(
BIT
(
3
)
|
BIT
(
4
)
|
BIT
(
5
)))
|
BIT
(
6
);
memcpy
(
&
aad
[
4
],
&
hdr
->
addr1
,
18
);
put_unaligned_be16
(
len_a
,
&
aad
[
0
]);
put_unaligned
(
mask_fc
,
(
__le16
*
)
&
aad
[
2
]);
memcpy
(
&
aad
[
4
],
&
hdr
->
addr1
,
3
*
ETH_ALEN
);
/* Mask Seq#, leave Frag# */
aad
[
22
]
=
*
((
u8
*
)
&
hdr
->
seq_ctrl
)
&
0x0f
;
aad
[
23
]
=
0
;
if
(
a4_included
)
{
memcpy
(
&
aad
[
24
],
hdr
->
addr4
,
6
);
aad
[
30
]
=
0
;
memcpy
(
&
aad
[
24
],
hdr
->
addr4
,
ETH_ALEN
);
aad
[
30
]
=
qos_tid
;
aad
[
31
]
=
0
;
}
else
memset
(
&
aad
[
24
],
0
,
8
);
if
(
qos_included
)
{
u8
*
dpos
=
&
aad
[
a4_included
?
30
:
24
];
/* Mask QoS Control field */
dpos
[
0
]
=
qos_tid
;
dpos
[
1
]
=
0
;
}
else
{
memset
(
&
aad
[
24
],
0
,
ETH_ALEN
+
IEEE80211_QOS_CTL_LEN
);
aad
[
24
]
=
qos_tid
;
}
}
...
...
@@ -392,7 +371,7 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
struct
ieee80211_key
*
key
=
tx
->
key
;
struct
ieee80211_tx_info
*
info
=
IEEE80211_SKB_CB
(
skb
);
int
hdrlen
,
len
,
tail
;
u8
*
pos
,
*
pn
,
*
b_0
,
*
aad
,
*
scratch
;
u8
*
pos
,
*
pn
;
int
i
;
info
->
control
.
icv_len
=
CCMP_MIC_LEN
;
...
...
@@ -406,10 +385,6 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
return
0
;
}
scratch
=
key
->
u
.
ccmp
.
tx_crypto_buf
;
b_0
=
scratch
+
3
*
AES_BLOCK_LEN
;
aad
=
scratch
+
4
*
AES_BLOCK_LEN
;
hdrlen
=
ieee80211_hdrlen
(
hdr
->
frame_control
);
len
=
skb
->
len
-
hdrlen
;
...
...
@@ -445,8 +420,8 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
}
pos
+=
CCMP_HDR_LEN
;
ccmp_special_blocks
(
skb
,
pn
,
b_0
,
aad
,
0
);
ieee80211_aes_ccm_encrypt
(
key
->
u
.
ccmp
.
tfm
,
scratch
,
b_0
,
aad
,
pos
,
len
,
ccmp_special_blocks
(
skb
,
pn
,
key
->
u
.
ccmp
.
tx_crypto_buf
,
0
);
ieee80211_aes_ccm_encrypt
(
key
->
u
.
ccmp
.
tfm
,
key
->
u
.
ccmp
.
tx_crypto_buf
,
pos
,
len
,
pos
,
skb_put
(
skb
,
CCMP_MIC_LEN
));
return
0
;
...
...
@@ -478,7 +453,7 @@ ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx)
ieee80211_rx_result
ieee80211_crypto_ccmp_decrypt
(
struct
ieee80211_rx_data
*
rx
)
{
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
rx
->
skb
->
data
;
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
rx
->
skb
->
data
;
int
hdrlen
;
struct
ieee80211_key
*
key
=
rx
->
key
;
struct
sk_buff
*
skb
=
rx
->
skb
;
...
...
@@ -488,7 +463,7 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
hdrlen
=
ieee80211_hdrlen
(
hdr
->
frame_control
);
if
(
(
rx
->
fc
&
IEEE80211_FCTL_FTYPE
)
!=
IEEE80211_FTYPE_DATA
)
if
(
!
ieee80211_is_data
(
hdr
->
frame_control
)
)
return
RX_CONTINUE
;
data_len
=
skb
->
len
-
hdrlen
-
CCMP_HDR_LEN
-
CCMP_MIC_LEN
;
...
...
@@ -508,16 +483,10 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
if
(
!
(
rx
->
status
->
flag
&
RX_FLAG_DECRYPTED
))
{
/* hardware didn't decrypt/verify MIC */
u8
*
scratch
,
*
b_0
,
*
aad
;
scratch
=
key
->
u
.
ccmp
.
rx_crypto_buf
;
b_0
=
scratch
+
3
*
AES_BLOCK_LEN
;
aad
=
scratch
+
4
*
AES_BLOCK_LEN
;
ccmp_special_blocks
(
skb
,
pn
,
b_0
,
aad
,
1
);
ccmp_special_blocks
(
skb
,
pn
,
key
->
u
.
ccmp
.
rx_crypto_buf
,
1
);
if
(
ieee80211_aes_ccm_decrypt
(
key
->
u
.
ccmp
.
tfm
,
scratch
,
b_0
,
aad
,
key
->
u
.
ccmp
.
tfm
,
key
->
u
.
ccmp
.
rx_crypto_buf
,
skb
->
data
+
hdrlen
+
CCMP_HDR_LEN
,
data_len
,
skb
->
data
+
skb
->
len
-
CCMP_MIC_LEN
,
skb
->
data
+
hdrlen
+
CCMP_HDR_LEN
))
{
...
...
net/rfkill/rfkill.c
浏览文件 @
54dceb00
...
...
@@ -130,17 +130,19 @@ static void update_rfkill_state(struct rfkill *rfkill)
/**
* rfkill_toggle_radio - wrapper for toggle_radio hook
* calls toggle_radio taking into account a lot of "small"
* details.
*
* @rfkill: the rfkill struct to use
* @force: calls toggle_radio even if cache says it is not needed,
* and also makes sure notifications of the state will be
* sent even if it didn't change
* @state: the new state to call toggle_radio() with
*
* This wrappen protects and enforces the API for toggle_radio
* calls. Note that @force cannot override a (possibly cached)
* state of RFKILL_STATE_HARD_BLOCKED. Any device making use of
* Calls rfkill->toggle_radio, enforcing the API for toggle_radio
* calls and handling all the red tape such as issuing notifications
* if the call is successful.
*
* Note that @force cannot override a (possibly cached) state of
* RFKILL_STATE_HARD_BLOCKED. Any device making use of
* RFKILL_STATE_HARD_BLOCKED implements either get_state() or
* rfkill_force_state(), so the cache either is bypassed or valid.
*
...
...
@@ -499,17 +501,15 @@ static struct class rfkill_class = {
static
int
rfkill_add_switch
(
struct
rfkill
*
rfkill
)
{
int
error
;
mutex_lock
(
&
rfkill_mutex
);
error
=
rfkill_toggle_radio
(
rfkill
,
rfkill_states
[
rfkill
->
type
],
0
);
if
(
!
error
)
list_add_tail
(
&
rfkill
->
node
,
&
rfkill_list
);
rfkill_toggle_radio
(
rfkill
,
rfkill_states
[
rfkill
->
type
],
0
);
list_add_tail
(
&
rfkill
->
node
,
&
rfkill_list
);
mutex_unlock
(
&
rfkill_mutex
);
return
error
;
return
0
;
}
static
void
rfkill_remove_switch
(
struct
rfkill
*
rfkill
)
...
...
net/wireless/nl80211.c
浏览文件 @
54dceb00
...
...
@@ -199,12 +199,14 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
mutex_lock
(
&
cfg80211_drv_mutex
);
list_for_each_entry
(
dev
,
&
cfg80211_drv_list
,
list
)
{
if
(
++
idx
<
start
)
if
(
++
idx
<
=
start
)
continue
;
if
(
nl80211_send_wiphy
(
skb
,
NETLINK_CB
(
cb
->
skb
).
pid
,
cb
->
nlh
->
nlmsg_seq
,
NLM_F_MULTI
,
dev
)
<
0
)
dev
)
<
0
)
{
idx
--
;
break
;
}
}
mutex_unlock
(
&
cfg80211_drv_mutex
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录