Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
db4148da
K
Kernel
项目概览
openeuler
/
Kernel
1 年多 前同步成功
通知
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看板
提交
db4148da
编写于
16年前
作者:
D
David S. Miller
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' of
git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
上级
ef40a685
8d09a5e1
变更
60
隐藏空白更改
内联
并排
Showing
60 changed file
with
1077 addition
and
1080 deletion
+1077
-1080
drivers/net/wireless/airo.c
drivers/net/wireless/airo.c
+1
-1
drivers/net/wireless/airo_cs.c
drivers/net/wireless/airo_cs.c
+1
-1
drivers/net/wireless/ath5k/phy.c
drivers/net/wireless/ath5k/phy.c
+1
-1
drivers/net/wireless/ath5k/reg.h
drivers/net/wireless/ath5k/reg.h
+0
-2
drivers/net/wireless/ath5k/reset.c
drivers/net/wireless/ath5k/reset.c
+13
-7
drivers/net/wireless/ath9k/beacon.c
drivers/net/wireless/ath9k/beacon.c
+66
-79
drivers/net/wireless/ath9k/core.c
drivers/net/wireless/ath9k/core.c
+2
-1
drivers/net/wireless/ath9k/core.h
drivers/net/wireless/ath9k/core.h
+1
-0
drivers/net/wireless/ath9k/hw.c
drivers/net/wireless/ath9k/hw.c
+16
-2
drivers/net/wireless/ath9k/rc.c
drivers/net/wireless/ath9k/rc.c
+42
-56
drivers/net/wireless/atmel.c
drivers/net/wireless/atmel.c
+1
-1
drivers/net/wireless/atmel_cs.c
drivers/net/wireless/atmel_cs.c
+1
-1
drivers/net/wireless/b43/rfkill.c
drivers/net/wireless/b43/rfkill.c
+5
-0
drivers/net/wireless/iwlwifi/iwl-3945-rs.c
drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+40
-142
drivers/net/wireless/iwlwifi/iwl-3945-rs.h
drivers/net/wireless/iwlwifi/iwl-3945-rs.h
+0
-9
drivers/net/wireless/iwlwifi/iwl-3945.h
drivers/net/wireless/iwlwifi/iwl-3945.h
+4
-0
drivers/net/wireless/iwlwifi/iwl-agn-rs.c
drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+59
-87
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-agn.c
+16
-8
drivers/net/wireless/iwlwifi/iwl-core.c
drivers/net/wireless/iwlwifi/iwl-core.c
+19
-8
drivers/net/wireless/iwlwifi/iwl-scan.c
drivers/net/wireless/iwlwifi/iwl-scan.c
+1
-7
drivers/net/wireless/iwlwifi/iwl-tx.c
drivers/net/wireless/iwlwifi/iwl-tx.c
+3
-4
drivers/net/wireless/iwlwifi/iwl3945-base.c
drivers/net/wireless/iwlwifi/iwl3945-base.c
+1
-10
drivers/net/wireless/libertas/dev.h
drivers/net/wireless/libertas/dev.h
+1
-0
drivers/net/wireless/libertas/wext.c
drivers/net/wireless/libertas/wext.c
+23
-3
drivers/net/wireless/netwave_cs.c
drivers/net/wireless/netwave_cs.c
+1
-1
drivers/net/wireless/orinoco.c
drivers/net/wireless/orinoco.c
+1
-1
drivers/net/wireless/orinoco_cs.c
drivers/net/wireless/orinoco_cs.c
+1
-1
drivers/net/wireless/ray_cs.c
drivers/net/wireless/ray_cs.c
+1
-1
drivers/net/wireless/rndis_wlan.c
drivers/net/wireless/rndis_wlan.c
+1
-2
drivers/net/wireless/rt2x00/rt2x00mac.c
drivers/net/wireless/rt2x00/rt2x00mac.c
+2
-1
drivers/net/wireless/rt2x00/rt61pci.c
drivers/net/wireless/rt2x00/rt61pci.c
+2
-2
drivers/net/wireless/rt2x00/rt73usb.c
drivers/net/wireless/rt2x00/rt73usb.c
+2
-2
drivers/net/wireless/spectrum_cs.c
drivers/net/wireless/spectrum_cs.c
+1
-1
drivers/net/wireless/wavelan_cs.c
drivers/net/wireless/wavelan_cs.c
+1
-1
drivers/net/wireless/wl3501_cs.c
drivers/net/wireless/wl3501_cs.c
+1
-1
include/linux/ieee80211.h
include/linux/ieee80211.h
+5
-0
include/net/cfg80211.h
include/net/cfg80211.h
+4
-2
include/net/mac80211.h
include/net/mac80211.h
+68
-0
include/net/wireless.h
include/net/wireless.h
+11
-9
net/mac80211/cfg.c
net/mac80211/cfg.c
+4
-60
net/mac80211/debugfs_sta.c
net/mac80211/debugfs_sta.c
+1
-2
net/mac80211/ieee80211_i.h
net/mac80211/ieee80211_i.h
+6
-0
net/mac80211/iface.c
net/mac80211/iface.c
+1
-0
net/mac80211/main.c
net/mac80211/main.c
+13
-10
net/mac80211/mesh.c
net/mac80211/mesh.c
+1
-1
net/mac80211/mesh.h
net/mac80211/mesh.h
+4
-0
net/mac80211/mesh_pathtbl.c
net/mac80211/mesh_pathtbl.c
+126
-1
net/mac80211/mlme.c
net/mac80211/mlme.c
+6
-4
net/mac80211/rate.c
net/mac80211/rate.c
+57
-14
net/mac80211/rate.h
net/mac80211/rate.h
+26
-76
net/mac80211/rc80211_pid.h
net/mac80211/rc80211_pid.h
+0
-2
net/mac80211/rc80211_pid_algo.c
net/mac80211/rc80211_pid_algo.c
+59
-99
net/mac80211/rx.c
net/mac80211/rx.c
+39
-20
net/mac80211/sta_info.c
net/mac80211/sta_info.c
+5
-12
net/mac80211/sta_info.h
net/mac80211/sta_info.h
+1
-1
net/mac80211/tx.c
net/mac80211/tx.c
+54
-21
net/wireless/core.c
net/wireless/core.c
+9
-153
net/wireless/nl80211.c
net/wireless/nl80211.c
+30
-15
net/wireless/reg.c
net/wireless/reg.c
+212
-99
net/wireless/reg.h
net/wireless/reg.h
+4
-35
未找到文件。
drivers/net/wireless/airo.c
浏览文件 @
db4148da
...
...
@@ -7107,7 +7107,7 @@ static int airo_get_aplist(struct net_device *dev,
*/
static
int
airo_set_scan
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
struct
iw_p
aram
*
v
wrq
,
struct
iw_p
oint
*
d
wrq
,
char
*
extra
)
{
struct
airo_info
*
ai
=
dev
->
priv
;
...
...
This diff is collapsed.
Click to expand it.
drivers/net/wireless/airo_cs.c
浏览文件 @
db4148da
...
...
@@ -147,7 +147,7 @@ static int airo_probe(struct pcmcia_device *p_dev)
DEBUG
(
0
,
"airo_attach()
\n
"
);
/* Interrupt setup */
p_dev
->
irq
.
Attributes
=
IRQ_TYPE_
EXCLUSIVE
;
p_dev
->
irq
.
Attributes
=
IRQ_TYPE_
DYNAMIC_SHARING
;
p_dev
->
irq
.
IRQInfo1
=
IRQ_LEVEL_ID
;
p_dev
->
irq
.
Handler
=
NULL
;
...
...
This diff is collapsed.
Click to expand it.
drivers/net/wireless/ath5k/phy.c
浏览文件 @
db4148da
...
...
@@ -2124,7 +2124,7 @@ static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah,
beacon
=
ath5k_hw_reg_read
(
ah
,
AR5K_BEACON_5210
);
ath5k_hw_reg_write
(
ah
,
beacon
&
~
AR5K_BEACON_ENABLE
,
AR5K_BEACON_5210
);
udelay
(
2300
);
mdelay
(
2
);
/*
* Set the channel (with AGC turned off)
...
...
This diff is collapsed.
Click to expand it.
drivers/net/wireless/ath5k/reg.h
浏览文件 @
db4148da
...
...
@@ -820,8 +820,6 @@
#define AR5K_RESET_CTL_MAC 0x00000004
/* MAC reset (PCU+Baseband ?) [5210] */
#define AR5K_RESET_CTL_PHY 0x00000008
/* PHY reset [5210] */
#define AR5K_RESET_CTL_PCI 0x00000010
/* PCI Core reset (interrupts etc) */
#define AR5K_RESET_CTL_CHIP (AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_DMA | \
AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_PHY)
/*
* Sleep control register
...
...
This diff is collapsed.
Click to expand it.
drivers/net/wireless/ath5k/reset.c
浏览文件 @
db4148da
...
...
@@ -173,8 +173,10 @@ static int ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val)
udelay
(
15
);
if
(
ah
->
ah_version
==
AR5K_AR5210
)
{
val
&=
AR5K_RESET_CTL_CHIP
;
mask
&=
AR5K_RESET_CTL_CHIP
;
val
&=
AR5K_RESET_CTL_PCU
|
AR5K_RESET_CTL_DMA
|
AR5K_RESET_CTL_MAC
|
AR5K_RESET_CTL_PHY
;
mask
&=
AR5K_RESET_CTL_PCU
|
AR5K_RESET_CTL_DMA
|
AR5K_RESET_CTL_MAC
|
AR5K_RESET_CTL_PHY
;
}
else
{
val
&=
AR5K_RESET_CTL_PCU
|
AR5K_RESET_CTL_BASEBAND
;
mask
&=
AR5K_RESET_CTL_PCU
|
AR5K_RESET_CTL_BASEBAND
;
...
...
@@ -361,16 +363,20 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
bus_flags
=
(
pdev
->
is_pcie
)
?
0
:
AR5K_RESET_CTL_PCI
;
/* Reset chipset */
ret
=
ath5k_hw_nic_reset
(
ah
,
AR5K_RESET_CTL_PCU
|
AR5K_RESET_CTL_BASEBAND
|
bus_flags
);
if
(
ah
->
ah_version
==
AR5K_AR5210
)
{
ret
=
ath5k_hw_nic_reset
(
ah
,
AR5K_RESET_CTL_PCU
|
AR5K_RESET_CTL_MAC
|
AR5K_RESET_CTL_DMA
|
AR5K_RESET_CTL_PHY
|
AR5K_RESET_CTL_PCI
);
mdelay
(
2
);
}
else
{
ret
=
ath5k_hw_nic_reset
(
ah
,
AR5K_RESET_CTL_PCU
|
AR5K_RESET_CTL_BASEBAND
|
bus_flags
);
}
if
(
ret
)
{
ATH5K_ERR
(
ah
->
ah_sc
,
"failed to reset the MAC Chip
\n
"
);
return
-
EIO
;
}
if
(
ah
->
ah_version
==
AR5K_AR5210
)
udelay
(
2300
);
/* ...wakeup again!*/
ret
=
ath5k_hw_set_power
(
ah
,
AR5K_PM_AWAKE
,
true
,
0
);
if
(
ret
)
{
...
...
This diff is collapsed.
Click to expand it.
drivers/net/wireless/ath9k/beacon.c
浏览文件 @
db4148da
...
...
@@ -16,7 +16,6 @@
/* Implementation of beacon processing. */
#include <asm/unaligned.h>
#include "core.h"
/*
...
...
@@ -26,7 +25,6 @@
* the operating mode of the station (AP or AdHoc). Parameters are AIFS
* settings and channel width min/max
*/
static
int
ath_beaconq_config
(
struct
ath_softc
*
sc
)
{
struct
ath_hal
*
ah
=
sc
->
sc_ah
;
...
...
@@ -63,19 +61,18 @@ static int ath_beaconq_config(struct ath_softc *sc)
* up all required antenna switch parameters, rate codes, and channel flags.
* Beacons are always sent out at the lowest rate, and are not retried.
*/
static
void
ath_beacon_setup
(
struct
ath_softc
*
sc
,
struct
ath_vap
*
avp
,
struct
ath_buf
*
bf
)
struct
ath_vap
*
avp
,
struct
ath_buf
*
bf
)
{
struct
sk_buff
*
skb
=
(
struct
sk_buff
*
)
bf
->
bf_mpdu
;
struct
ath_hal
*
ah
=
sc
->
sc_ah
;
struct
ath_desc
*
ds
;
int
flags
,
antenna
;
struct
ath9k_11n_rate_series
series
[
4
]
;
const
struct
ath9k_rate_table
*
rt
;
int
flags
,
antenna
;
u8
rix
,
rate
;
int
ctsrate
=
0
;
int
ctsduration
=
0
;
struct
ath9k_11n_rate_series
series
[
4
];
DPRINTF
(
sc
,
ATH_DBG_BEACON
,
"%s: m %p len %u
\n
"
,
__func__
,
skb
,
skb
->
len
);
...
...
@@ -115,20 +112,21 @@ static void ath_beacon_setup(struct ath_softc *sc,
rate
|=
rt
->
info
[
rix
].
shortPreamble
;
ath9k_hw_set11n_txdesc
(
ah
,
ds
,
skb
->
len
+
FCS_LEN
,
/* frame length */
ATH9K_PKT_TYPE_BEACON
,
/* Atheros packet type */
skb
->
len
+
FCS_LEN
,
/* frame length */
ATH9K_PKT_TYPE_BEACON
,
/* Atheros packet type */
avp
->
av_btxctl
.
txpower
,
/* txpower XXX */
ATH9K_TXKEYIX_INVALID
,
/* no encryption */
ATH9K_KEY_TYPE_CLEAR
,
/* no encryption */
flags
/* no ack, veol for beacons */
ATH9K_TXKEYIX_INVALID
,
/* no encryption */
ATH9K_KEY_TYPE_CLEAR
,
/* no encryption */
flags
/* no ack,
veol for beacons */
);
/* NB: beacon's BufLen must be a multiple of 4 bytes */
ath9k_hw_filltxdesc
(
ah
,
ds
,
roundup
(
skb
->
len
,
4
),
/* buffer length */
true
,
/* first segment */
true
,
/* last segment */
ds
/* first descriptor */
true
,
/* first segment */
true
,
/* last segment */
ds
/* first descriptor */
);
memzero
(
series
,
sizeof
(
struct
ath9k_11n_rate_series
)
*
4
);
...
...
@@ -153,22 +151,23 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
struct
ath_buf
*
bf
;
struct
ath_vap
*
avp
;
struct
sk_buff
*
skb
;
int
cabq_depth
;
struct
ath_txq
*
cabq
;
struct
ieee80211_tx_info
*
info
;
int
cabq_depth
;
avp
=
sc
->
sc_vaps
[
if_id
];
ASSERT
(
avp
);
cabq
=
sc
->
sc_cabq
;
ASSERT
(
avp
);
if
(
avp
->
av_bcbuf
==
NULL
)
{
DPRINTF
(
sc
,
ATH_DBG_BEACON
,
"%s: avp=%p av_bcbuf=%p
\n
"
,
__func__
,
avp
,
avp
->
av_bcbuf
);
return
NULL
;
}
bf
=
avp
->
av_bcbuf
;
skb
=
(
struct
sk_buff
*
)
bf
->
bf_mpdu
;
skb
=
(
struct
sk_buff
*
)
bf
->
bf_mpdu
;
if
(
skb
)
{
pci_unmap_single
(
sc
->
pdev
,
bf
->
bf_dmacontext
,
skb_end_pointer
(
skb
)
-
skb
->
head
,
...
...
@@ -179,17 +178,19 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
bf
->
bf_mpdu
=
skb
;
if
(
skb
==
NULL
)
return
NULL
;
info
=
IEEE80211_SKB_CB
(
skb
);
if
(
info
->
flags
&
IEEE80211_TX_CTL_ASSIGN_SEQ
)
{
/*
* TODO: make sure the seq# gets assigned properly (vs. other
* TX frames)
*/
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
skb
->
data
;
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
skb
->
data
;
sc
->
seq_no
+=
0x10
;
hdr
->
seq_ctrl
&=
cpu_to_le16
(
IEEE80211_SCTL_FRAG
);
hdr
->
seq_ctrl
|=
cpu_to_le16
(
sc
->
seq_no
);
}
bf
->
bf_buf_addr
=
bf
->
bf_dmacontext
=
pci_map_single
(
sc
->
pdev
,
skb
->
data
,
skb_end_pointer
(
skb
)
-
skb
->
head
,
...
...
@@ -241,7 +242,6 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
* Startup beacon transmission for adhoc mode when they are sent entirely
* by the hardware using the self-linked descriptor + veol trick.
*/
static
void
ath_beacon_start_adhoc
(
struct
ath_softc
*
sc
,
int
if_id
)
{
struct
ath_hal
*
ah
=
sc
->
sc_ah
;
...
...
@@ -278,7 +278,6 @@ static void ath_beacon_start_adhoc(struct ath_softc *sc, int if_id)
* min/max, and enable aifs). The info structure does not need to be
* persistant.
*/
int
ath_beaconq_setup
(
struct
ath_hal
*
ah
)
{
struct
ath9k_tx_queue_info
qi
;
...
...
@@ -299,26 +298,24 @@ int ath_beaconq_setup(struct ath_hal *ah)
* the ATH interface. This routine also calculates the beacon "slot" for
* staggared beacons in the mBSSID case.
*/
int
ath_beacon_alloc
(
struct
ath_softc
*
sc
,
int
if_id
)
{
struct
ath_vap
*
avp
;
struct
ieee80211_hdr
*
wh
;
struct
ieee80211_hdr
*
hdr
;
struct
ath_buf
*
bf
;
struct
sk_buff
*
skb
;
__le64
tstamp
;
avp
=
sc
->
sc_vaps
[
if_id
];
ASSERT
(
avp
);
/* Allocate a beacon descriptor if we haven't done so. */
if
(
!
avp
->
av_bcbuf
)
{
/*
* Allocate beacon state for hostap/ibss. We know
* a buffer is available.
*/
/* Allocate beacon state for hostap/ibss. We know
* a buffer is available. */
avp
->
av_bcbuf
=
list_first_entry
(
&
sc
->
sc_bbuf
,
struct
ath_buf
,
list
);
struct
ath_buf
,
list
);
list_del
(
&
avp
->
av_bcbuf
->
list
);
if
(
sc
->
sc_ah
->
ah_opmode
==
ATH9K_M_HOSTAP
||
...
...
@@ -362,9 +359,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
}
/*
* NB: the beacon data buffer must be 32-bit aligned;
* we assume the wbuf routines will return us something
* with this alignment (perhaps should assert).
* NB: the beacon data buffer must be 32-bit aligned.
* FIXME: Fill avp->av_btxctl.txpower and
* avp->av_btxctl.shortPreamble
*/
...
...
@@ -375,6 +370,9 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
return
-
ENOMEM
;
}
tstamp
=
((
struct
ieee80211_mgmt
*
)
skb
->
data
)
->
u
.
beacon
.
timestamp
;
sc
->
bc_tstamp
=
le64_to_cpu
(
tstamp
);
/*
* Calculate a TSF adjustment factor required for
* staggered beacons. Note that we assume the format
...
...
@@ -408,8 +406,8 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
__func__
,
"stagger"
,
avp
->
av_bslot
,
intval
,
(
unsigned
long
long
)
tsfadjust
);
wh
=
(
struct
ieee80211_hdr
*
)
skb
->
data
;
memcpy
(
&
wh
[
1
],
&
val
,
sizeof
(
val
));
hdr
=
(
struct
ieee80211_hdr
*
)
skb
->
data
;
memcpy
(
&
hdr
[
1
],
&
val
,
sizeof
(
val
));
}
bf
->
bf_buf_addr
=
bf
->
bf_dmacontext
=
...
...
@@ -425,9 +423,8 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
* Reclaim beacon resources and return buffer to the pool.
*
* Checks the VAP to put the beacon frame buffer back to the ATH object
* queue, and de-allocates any
wbuf frame
s that were sent as CAB traffic.
* queue, and de-allocates any
skb
s that were sent as CAB traffic.
*/
void
ath_beacon_return
(
struct
ath_softc
*
sc
,
struct
ath_vap
*
avp
)
{
if
(
avp
->
av_bcbuf
!=
NULL
)
{
...
...
@@ -459,10 +456,7 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp)
* Transmit one or more beacon frames at SWBA. Dynamic updates to the frame
* contents are done as needed and the slot time is also adjusted based on
* current state.
*
* This tasklet is not scheduled, it's called in ISR context.
*/
void
ath9k_beacon_tasklet
(
unsigned
long
data
)
{
struct
ath_softc
*
sc
=
(
struct
ath_softc
*
)
data
;
...
...
@@ -490,6 +484,8 @@ void ath9k_beacon_tasklet(unsigned long data)
* and wait for the next. Missed beacons indicate
* a problem and should not occur. If we miss too
* many consecutive beacons reset the device.
*
* FIXME: Clean up this mess !!
*/
if
(
ath9k_hw_numtxpending
(
ah
,
sc
->
sc_bhalq
)
!=
0
)
{
sc
->
sc_bmisscount
++
;
...
...
@@ -505,19 +501,16 @@ void ath9k_beacon_tasklet(unsigned long data)
__func__
,
sc
->
sc_bmisscount
);
if
(
show_cycles
)
{
/*
* Display cycle counter stats
* from HW to aide in debug of
* stickiness.
* Display cycle counter stats from HW
* to aide in debug of stickiness.
*/
DPRINTF
(
sc
,
ATH_DBG_BEACON
,
DPRINTF
(
sc
,
ATH_DBG_BEACON
,
"%s: busy times: rx_clear=%d, "
"rx_frame=%d, tx_frame=%d
\n
"
,
__func__
,
rx_clear
,
rx_frame
,
tx_frame
);
}
else
{
DPRINTF
(
sc
,
ATH_DBG_BEACON
,
DPRINTF
(
sc
,
ATH_DBG_BEACON
,
"%s: unable to obtain "
"busy times
\n
"
,
__func__
);
}
...
...
@@ -529,8 +522,7 @@ void ath9k_beacon_tasklet(unsigned long data)
}
else
if
(
sc
->
sc_bmisscount
>=
BSTUCK_THRESH
)
{
if
(
sc
->
sc_flags
&
SC_OP_NO_RESET
)
{
if
(
sc
->
sc_bmisscount
==
BSTUCK_THRESH
)
{
DPRINTF
(
sc
,
ATH_DBG_BEACON
,
DPRINTF
(
sc
,
ATH_DBG_BEACON
,
"%s: beacon is officially "
"stuck
\n
"
,
__func__
);
ath9k_hw_dmaRegDump
(
ah
);
...
...
@@ -542,13 +534,12 @@ void ath9k_beacon_tasklet(unsigned long data)
ath_bstuck_process
(
sc
);
}
}
return
;
}
if
(
sc
->
sc_bmisscount
!=
0
)
{
if
(
sc
->
sc_flags
&
SC_OP_NO_RESET
)
{
DPRINTF
(
sc
,
ATH_DBG_BEACON
,
DPRINTF
(
sc
,
ATH_DBG_BEACON
,
"%s: resume beacon xmit after %u misses
\n
"
,
__func__
,
sc
->
sc_bmisscount
);
}
else
{
...
...
@@ -572,10 +563,12 @@ void ath9k_beacon_tasklet(unsigned long data)
tsftu
=
TSF_TO_TU
(
tsf
>>
32
,
tsf
);
slot
=
((
tsftu
%
intval
)
*
ATH_BCBUF
)
/
intval
;
if_id
=
sc
->
sc_bslot
[(
slot
+
1
)
%
ATH_BCBUF
];
DPRINTF
(
sc
,
ATH_DBG_BEACON
,
"%s: slot %d [tsf %llu tsftu %u intval %u] if_id %d
\n
"
,
__func__
,
slot
,
(
unsigned
long
long
)
tsf
,
tsftu
,
intval
,
if_id
);
"%s: slot %d [tsf %llu tsftu %u intval %u] if_id %d
\n
"
,
__func__
,
slot
,
(
unsigned
long
long
)
tsf
,
tsftu
,
intval
,
if_id
);
bfaddr
=
0
;
if
(
if_id
!=
ATH_IF_ID_ANY
)
{
bf
=
ath_beacon_generate
(
sc
,
if_id
);
...
...
@@ -632,9 +625,8 @@ void ath9k_beacon_tasklet(unsigned long data)
* Tasklet for Beacon Stuck processing
*
* Processing for Beacon Stuck.
* Basically
calls the ath_internal_reset function to reset
the chip.
* Basically
resets
the chip.
*/
void
ath_bstuck_process
(
struct
ath_softc
*
sc
)
{
DPRINTF
(
sc
,
ATH_DBG_BEACON
,
...
...
@@ -658,13 +650,12 @@ void ath_bstuck_process(struct ath_softc *sc)
* interrupt when we stop seeing beacons from the AP
* we've associated with.
*/
void
ath_beacon_config
(
struct
ath_softc
*
sc
,
int
if_id
)
{
struct
ath_hal
*
ah
=
sc
->
sc_ah
;
u32
nexttbtt
,
intval
;
struct
ath_beacon_config
conf
;
enum
ath9k_opmode
av_opmode
;
u32
nexttbtt
,
intval
;
if
(
if_id
!=
ATH_IF_ID_ANY
)
av_opmode
=
sc
->
sc_vaps
[
if_id
]
->
av_opmode
;
...
...
@@ -673,12 +664,6 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
memzero
(
&
conf
,
sizeof
(
struct
ath_beacon_config
));
/* FIXME: Use default values for now - Sujith */
/* Query beacon configuration first */
/*
* Protocol stack doesn't support dynamic beacon configuration,
* use default configurations.
*/
conf
.
beacon_interval
=
sc
->
hw
->
conf
.
beacon_int
?
sc
->
hw
->
conf
.
beacon_int
:
ATH_DEFAULT_BINTVAL
;
conf
.
listen_interval
=
1
;
...
...
@@ -687,8 +672,8 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
conf
.
bmiss_timeout
=
ATH_DEFAULT_BMISS_LIMIT
*
conf
.
beacon_interval
;
/* extract tstamp from last beacon and convert to TU */
nexttbtt
=
TSF_TO_TU
(
get_unaligned_le32
(
conf
.
u
.
last_tstamp
+
4
),
get_unaligned_le32
(
conf
.
u
.
last_tstamp
));
nexttbtt
=
TSF_TO_TU
(
sc
->
bc_tstamp
>>
32
,
sc
->
bc_tstamp
);
/* XXX conditionalize multi-bss support? */
if
(
sc
->
sc_ah
->
ah_opmode
==
ATH9K_M_HOSTAP
)
{
/*
...
...
@@ -704,12 +689,14 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
intval
=
conf
.
beacon_interval
&
ATH9K_BEACON_PERIOD
;
}
if
(
nexttbtt
==
0
)
/* e.g. for ap mode */
if
(
nexttbtt
==
0
)
/* e.g. for ap mode */
nexttbtt
=
intval
;
else
if
(
intval
)
/* NB: can be 0 for monitor mode */
else
if
(
intval
)
/* NB: can be 0 for monitor mode */
nexttbtt
=
roundup
(
nexttbtt
,
intval
);
DPRINTF
(
sc
,
ATH_DBG_BEACON
,
"%s: nexttbtt %u intval %u (%u)
\n
"
,
__func__
,
nexttbtt
,
intval
,
conf
.
beacon_interval
);
/* Check for ATH9K_M_HOSTAP and sc_nostabeacons for WDS client */
if
(
sc
->
sc_ah
->
ah_opmode
==
ATH9K_M_STA
)
{
struct
ath9k_beacon_state
bs
;
...
...
@@ -723,19 +710,19 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
* last beacon we received (which may be none).
*/
dtimperiod
=
conf
.
dtim_period
;
if
(
dtimperiod
<=
0
)
/* NB: 0 if not known */
if
(
dtimperiod
<=
0
)
/* NB: 0 if not known */
dtimperiod
=
1
;
dtimcount
=
conf
.
dtim_count
;
if
(
dtimcount
>=
dtimperiod
)
/* NB: sanity check */
dtimcount
=
0
;
/* XXX? */
cfpperiod
=
1
;
/* NB: no PCF support yet */
if
(
dtimcount
>=
dtimperiod
)
/* NB: sanity check */
dtimcount
=
0
;
cfpperiod
=
1
;
/* NB: no PCF support yet */
cfpcount
=
0
;
sleepduration
=
conf
.
listen_interval
*
intval
;
if
(
sleepduration
<=
0
)
sleepduration
=
intval
;
#define FUDGE
2
#define FUDGE 2
/*
* Pull nexttbtt forward to reflect the current
* TSF and calculate dtim+cfp state for the result.
...
...
@@ -759,6 +746,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
bs
.
bs_cfpperiod
=
cfpperiod
*
bs
.
bs_dtimperiod
;
bs
.
bs_cfpnext
=
bs
.
bs_nextdtim
+
cfpcount
*
bs
.
bs_dtimperiod
;
bs
.
bs_cfpmaxduration
=
0
;
/*
* Calculate the number of consecutive beacons to miss
* before taking a BMISS interrupt. The configuration
...
...
@@ -767,9 +755,8 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
* result to at most 15 beacons.
*/
if
(
sleepduration
>
intval
)
{
bs
.
bs_bmissthreshold
=
conf
.
listen_interval
*
ATH_DEFAULT_BMISS_LIMIT
/
2
;
bs
.
bs_bmissthreshold
=
conf
.
listen_interval
*
ATH_DEFAULT_BMISS_LIMIT
/
2
;
}
else
{
bs
.
bs_bmissthreshold
=
DIV_ROUND_UP
(
conf
.
bmiss_timeout
,
intval
);
...
...
@@ -789,8 +776,8 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
* XXX fixed at 100ms
*/
bs
.
bs_sleepduration
=
roundup
(
IEEE80211_MS_TO_TU
(
100
),
sleepduration
);
bs
.
bs_sleepduration
=
roundup
(
IEEE80211_MS_TO_TU
(
100
),
sleepduration
);
if
(
bs
.
bs_sleepduration
>
bs
.
bs_dtimperiod
)
bs
.
bs_sleepduration
=
bs
.
bs_dtimperiod
;
...
...
@@ -834,9 +821,9 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
if
(
sc
->
sc_ah
->
ah_opmode
==
ATH9K_M_IBSS
)
{
/*
* Pull nexttbtt forward to reflect the current
* TSF
.
* TSF
*/
#define FUDGE
2
#define FUDGE 2
if
(
!
(
intval
&
ATH9K_BEACON_RESET_TSF
))
{
tsf
=
ath9k_hw_gettsf64
(
ah
);
tsftu
=
TSF_TO_TU
((
u32
)(
tsf
>>
32
),
...
...
This diff is collapsed.
Click to expand it.
drivers/net/wireless/ath9k/core.c
浏览文件 @
db4148da
...
...
@@ -534,7 +534,8 @@ int ath_vap_attach(struct ath_softc *sc,
avp
->
av_opmode
=
opmode
;
avp
->
av_bslot
=
-
1
;
ath9k_hw_set_tsfadjust
(
sc
->
sc_ah
,
1
);
if
(
opmode
==
ATH9K_M_HOSTAP
)
ath9k_hw_set_tsfadjust
(
sc
->
sc_ah
,
1
);
sc
->
sc_vaps
[
if_id
]
=
avp
;
sc
->
sc_nvaps
++
;
...
...
This diff is collapsed.
Click to expand it.
drivers/net/wireless/ath9k/core.h
浏览文件 @
db4148da
...
...
@@ -1001,6 +1001,7 @@ struct ath_softc {
u32
sc_bhalq
;
u32
sc_bmisscount
;
u32
ast_be_xmit
;
/* beacons transmitted */
u64
bc_tstamp
;
/* Rate */
struct
ieee80211_rate
rates
[
IEEE80211_NUM_BANDS
][
ATH_RATE_MAX
];
...
...
This diff is collapsed.
Click to expand it.
drivers/net/wireless/ath9k/hw.c
浏览文件 @
db4148da
...
...
@@ -2526,6 +2526,11 @@ static void ath9k_ani_reset(struct ath_hal *ah)
}
}
/*
* Process a MIB interrupt. We may potentially be invoked because
* any of the MIB counters overflow/trigger so don't assume we're
* here because a PHY error counter triggered.
*/
void
ath9k_hw_procmibevent
(
struct
ath_hal
*
ah
,
const
struct
ath9k_node_stats
*
stats
)
{
...
...
@@ -2533,18 +2538,20 @@ void ath9k_hw_procmibevent(struct ath_hal *ah,
u32
phyCnt1
,
phyCnt2
;
DPRINTF
(
ah
->
ah_sc
,
ATH_DBG_ANI
,
"Processing Mib Intr
\n
"
);
/* Reset these counters regardless */
REG_WRITE
(
ah
,
AR_FILT_OFDM
,
0
);
REG_WRITE
(
ah
,
AR_FILT_CCK
,
0
);
if
(
!
(
REG_READ
(
ah
,
AR_SLP_MIB_CTRL
)
&
AR_SLP_MIB_PENDING
))
REG_WRITE
(
ah
,
AR_SLP_MIB_CTRL
,
AR_SLP_MIB_CLEAR
);
/* Clear the mib counters and save them in the stats */
ath9k_hw_update_mibstats
(
ah
,
&
ahp
->
ah_mibStats
);
ahp
->
ah_stats
.
ast_nodestats
=
*
stats
;
if
(
!
DO_ANI
(
ah
))
return
;
/* NB: these are not reset-on-read */
phyCnt1
=
REG_READ
(
ah
,
AR_PHY_ERR_1
);
phyCnt2
=
REG_READ
(
ah
,
AR_PHY_ERR_2
);
if
(((
phyCnt1
&
AR_MIBCNT_INTRMASK
)
==
AR_MIBCNT_INTRMASK
)
||
...
...
@@ -2552,6 +2559,7 @@ void ath9k_hw_procmibevent(struct ath_hal *ah,
struct
ar5416AniState
*
aniState
=
ahp
->
ah_curani
;
u32
ofdmPhyErrCnt
,
cckPhyErrCnt
;
/* NB: only use ast_ani_*errs with AH_PRIVATE_DIAG */
ofdmPhyErrCnt
=
phyCnt1
-
aniState
->
ofdmPhyErrBase
;
ahp
->
ah_stats
.
ast_ani_ofdmerrs
+=
ofdmPhyErrCnt
-
aniState
->
ofdmPhyErrCount
;
...
...
@@ -2562,11 +2570,17 @@ void ath9k_hw_procmibevent(struct ath_hal *ah,
cckPhyErrCnt
-
aniState
->
cckPhyErrCount
;
aniState
->
cckPhyErrCount
=
cckPhyErrCnt
;
/*
* NB: figure out which counter triggered. If both
* trigger we'll only deal with one as the processing
* clobbers the error counter so the trigger threshold
* check will never be true.
*/
if
(
aniState
->
ofdmPhyErrCount
>
aniState
->
ofdmTrigHigh
)
ath9k_hw_ani_ofdm_err_trigger
(
ah
);
if
(
aniState
->
cckPhyErrCount
>
aniState
->
cckTrigHigh
)
ath9k_hw_ani_cck_err_trigger
(
ah
);
/* NB: always restart to insure the h/w counters are reset */
ath9k_ani_restart
(
ah
);
}
}
...
...
This diff is collapsed.
Click to expand it.
drivers/net/wireless/ath9k/rc.c
浏览文件 @
db4148da
...
...
@@ -20,6 +20,7 @@
*/
#include "core.h"
/* FIXME: remove this include! */
#include "../net/mac80211/rate.h"
static
u32
tx_triglevel_max
;
...
...
@@ -1812,20 +1813,18 @@ static void ath_rc_sib_init(struct ath_rate_node *ath_rc_priv)
}
static
void
ath_setup_rates
(
struct
ieee80211_local
*
local
,
struct
sta_info
*
sta
)
static
void
ath_setup_rates
(
struct
ath_softc
*
sc
,
struct
ieee80211_supported_band
*
sband
,
struct
ieee80211_sta
*
sta
,
struct
ath_rate_node
*
rc_priv
)
{
struct
ieee80211_supported_band
*
sband
;
struct
ieee80211_hw
*
hw
=
local_to_hw
(
local
);
struct
ath_softc
*
sc
=
hw
->
priv
;
struct
ath_rate_node
*
rc_priv
=
sta
->
rate_ctrl_priv
;
int
i
,
j
=
0
;
DPRINTF
(
sc
,
ATH_DBG_RATE
,
"%s
\n
"
,
__func__
);
sband
=
local
->
hw
.
wiphy
->
bands
[
local
->
hw
.
conf
.
channel
->
band
];
for
(
i
=
0
;
i
<
sband
->
n_bitrates
;
i
++
)
{
if
(
sta
->
s
ta
.
supp_rates
[
local
->
hw
.
conf
.
channel
->
band
]
&
BIT
(
i
))
{
if
(
sta
->
s
upp_rates
[
sband
->
band
]
&
BIT
(
i
))
{
rc_priv
->
neg_rates
.
rs_rates
[
j
]
=
(
sband
->
bitrates
[
i
].
bitrate
*
2
)
/
10
;
j
++
;
...
...
@@ -1852,19 +1851,17 @@ void ath_rc_node_update(struct ieee80211_hw *hw, struct ath_rate_node *rc_priv)
}
/* Rate Control callbacks */
static
void
ath_tx_status
(
void
*
priv
,
struct
net_device
*
dev
,
static
void
ath_tx_status
(
void
*
priv
,
struct
ieee80211_supported_band
*
sband
,
struct
ieee80211_sta
*
sta
,
void
*
priv_sta
,
struct
sk_buff
*
skb
)
{
struct
ath_softc
*
sc
=
priv
;
struct
ath_tx_info_priv
*
tx_info_priv
;
struct
ath_node
*
an
;
struct
sta_info
*
sta
;
struct
ieee80211_local
*
local
;
struct
ieee80211_tx_info
*
tx_info
=
IEEE80211_SKB_CB
(
skb
);
struct
ieee80211_hdr
*
hdr
;
__le16
fc
;
local
=
hw_to_local
(
sc
->
hw
);
hdr
=
(
struct
ieee80211_hdr
*
)
skb
->
data
;
fc
=
hdr
->
frame_control
;
tx_info_priv
=
(
struct
ath_tx_info_priv
*
)
tx_info
->
driver_data
[
0
];
...
...
@@ -1873,8 +1870,7 @@ static void ath_tx_status(void *priv, struct net_device *dev,
an
=
ath_node_find
(
sc
,
hdr
->
addr1
);
spin_unlock_bh
(
&
sc
->
node_lock
);
sta
=
sta_info_get
(
local
,
hdr
->
addr1
);
if
(
!
an
||
!
sta
||
!
ieee80211_is_data
(
fc
))
{
if
(
!
an
||
!
priv_sta
||
!
ieee80211_is_data
(
fc
))
{
if
(
tx_info
->
driver_data
[
0
]
!=
NULL
)
{
kfree
(
tx_info
->
driver_data
[
0
]);
tx_info
->
driver_data
[
0
]
=
NULL
;
...
...
@@ -1882,24 +1878,22 @@ static void ath_tx_status(void *priv, struct net_device *dev,
return
;
}
if
(
tx_info
->
driver_data
[
0
]
!=
NULL
)
{
ath_rate_tx_complete
(
sc
,
an
,
sta
->
rate_ctrl_priv
,
tx_info_priv
);
ath_rate_tx_complete
(
sc
,
an
,
priv_sta
,
tx_info_priv
);
kfree
(
tx_info
->
driver_data
[
0
]);
tx_info
->
driver_data
[
0
]
=
NULL
;
}
}
static
void
ath_tx_aggr_resp
(
struct
ath_softc
*
sc
,
struct
sta_info
*
sta
,
struct
ieee80211_supported_band
*
sband
,
struct
ieee80211_sta
*
sta
,
struct
ath_node
*
an
,
u8
tidno
)
{
struct
ieee80211_hw
*
hw
=
sc
->
hw
;
struct
ieee80211_local
*
local
;
struct
ath_atx_tid
*
txtid
;
struct
ieee80211_supported_band
*
sband
;
u16
buffersize
=
0
;
int
state
;
DECLARE_MAC_BUF
(
mac
)
;
struct
sta_info
*
si
;
if
(
!
(
sc
->
sc_flags
&
SC_OP_TXAGGR
))
return
;
...
...
@@ -1908,11 +1902,16 @@ static void ath_tx_aggr_resp(struct ath_softc *sc,
if
(
!
txtid
->
paused
)
return
;
local
=
hw_to_local
(
sc
->
hw
);
sband
=
hw
->
wiphy
->
bands
[
hw
->
conf
.
channel
->
band
];
/*
* XXX: This is entirely busted, we aren't supposed to
* access the sta from here because it's internal
* to mac80211, and looking at the state without
* locking is wrong too.
*/
si
=
container_of
(
sta
,
struct
sta_info
,
sta
);
buffersize
=
IEEE80211_MIN_AMPDU_BUF
<<
sband
->
ht_info
.
ampdu_factor
;
/* FIXME */
state
=
s
ta
->
ampdu_mlme
.
tid_state_tx
[
tidno
];
state
=
s
i
->
ampdu_mlme
.
tid_state_tx
[
tidno
];
if
(
state
&
HT_ADDBA_RECEIVED_MSK
)
{
txtid
->
addba_exchangecomplete
=
1
;
...
...
@@ -1928,18 +1927,15 @@ static void ath_tx_aggr_resp(struct ath_softc *sc,
}
}
static
void
ath_get_rate
(
void
*
priv
,
struct
net_device
*
dev
,
struct
ieee80211_supported_band
*
sband
,
struct
sk_buff
*
skb
,
struct
rate_selection
*
sel
)
static
void
ath_get_rate
(
void
*
priv
,
struct
ieee80211_supported_band
*
sband
,
struct
ieee80211_sta
*
sta
,
void
*
priv_sta
,
struct
sk_buff
*
skb
,
struct
rate_selection
*
sel
)
{
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
skb
->
data
;
struct
ieee80211_local
*
local
=
wdev_priv
(
dev
->
ieee80211_ptr
);
struct
sta_info
*
sta
;
struct
ath_softc
*
sc
=
(
struct
ath_softc
*
)
priv
;
struct
ath_softc
*
sc
=
priv
;
struct
ieee80211_hw
*
hw
=
sc
->
hw
;
struct
ath_tx_info_priv
*
tx_info_priv
;
struct
ath_rate_node
*
ath_rc_priv
;
struct
ath_rate_node
*
ath_rc_priv
=
priv_sta
;
struct
ath_node
*
an
;
struct
ieee80211_tx_info
*
tx_info
=
IEEE80211_SKB_CB
(
skb
);
int
is_probe
=
FALSE
,
chk
,
ret
;
...
...
@@ -1955,8 +1951,7 @@ static void ath_get_rate(void *priv, struct net_device *dev,
ASSERT
(
tx_info
->
driver_data
[
0
]
!=
NULL
);
tx_info_priv
=
(
struct
ath_tx_info_priv
*
)
tx_info
->
driver_data
[
0
];
sta
=
sta_info_get
(
local
,
hdr
->
addr1
);
lowest_idx
=
rate_lowest_index
(
local
,
sband
,
sta
);
lowest_idx
=
rate_lowest_index
(
sband
,
sta
);
tx_info_priv
->
min_rate
=
(
sband
->
bitrates
[
lowest_idx
].
bitrate
*
2
)
/
10
;
/* lowest rate for management and multicast/broadcast frames */
if
(
!
ieee80211_is_data
(
fc
)
||
...
...
@@ -1965,8 +1960,6 @@ static void ath_get_rate(void *priv, struct net_device *dev,
return
;
}
ath_rc_priv
=
sta
->
rate_ctrl_priv
;
/* Find tx rate for unicast frames */
ath_rate_findrate
(
sc
,
ath_rc_priv
,
ATH_11N_TXMAXTRY
,
4
,
...
...
@@ -1975,8 +1968,7 @@ static void ath_get_rate(void *priv, struct net_device *dev,
&
is_probe
,
false
);
if
(
is_probe
)
sel
->
probe_idx
=
((
struct
ath_tx_ratectrl
*
)
sta
->
rate_ctrl_priv
)
->
probe_rate
;
sel
->
probe_idx
=
ath_rc_priv
->
tx_ratectrl
.
probe_rate
;
/* Ratecontrol sometimes returns invalid rate index */
if
(
tx_info_priv
->
rcs
[
0
].
rix
!=
0xff
)
...
...
@@ -2020,37 +2012,31 @@ static void ath_get_rate(void *priv, struct net_device *dev,
__func__
,
print_mac
(
mac
,
hdr
->
addr1
));
}
else
if
(
chk
==
AGGR_EXCHANGE_PROGRESS
)
ath_tx_aggr_resp
(
sc
,
sta
,
an
,
tid
);
ath_tx_aggr_resp
(
sc
,
s
band
,
s
ta
,
an
,
tid
);
}
}
}
static
void
ath_rate_init
(
void
*
priv
,
void
*
priv_sta
,
struct
ieee80211_local
*
local
,
struct
sta_info
*
sta
)
static
void
ath_rate_init
(
void
*
priv
,
struct
ieee80211_supported_band
*
sband
,
struct
ieee80211_sta
*
sta
,
void
*
priv_sta
)
{
struct
ieee80211_supported_band
*
sband
;
struct
ieee80211_hw
*
hw
=
local_to_hw
(
local
);
struct
ieee80211_conf
*
conf
=
&
local
->
hw
.
conf
;
struct
ath_softc
*
sc
=
hw
->
priv
;
struct
ath_softc
*
sc
=
priv
;
struct
ath_rate_node
*
ath_rc_priv
=
priv_sta
;
int
i
,
j
=
0
;
DPRINTF
(
sc
,
ATH_DBG_RATE
,
"%s
\n
"
,
__func__
);
sband
=
local
->
hw
.
wiphy
->
bands
[
local
->
hw
.
conf
.
channel
->
band
];
ath_setup_rates
(
local
,
sta
);
if
(
conf
->
flags
&
IEEE80211_CONF_SUPPORT_HT_MODE
)
{
ath_setup_rates
(
sc
,
sband
,
sta
,
ath_rc_priv
);
if
(
sc
->
hw
->
conf
.
flags
&
IEEE80211_CONF_SUPPORT_HT_MODE
)
{
for
(
i
=
0
;
i
<
MCS_SET_SIZE
;
i
++
)
{
if
(
conf
->
ht_conf
.
supp_mcs_set
[
i
/
8
]
&
(
1
<<
(
i
%
8
)))
if
(
sc
->
hw
->
conf
.
ht_conf
.
supp_mcs_set
[
i
/
8
]
&
(
1
<<
(
i
%
8
)))
ath_rc_priv
->
neg_ht_rates
.
rs_rates
[
j
++
]
=
i
;
if
(
j
==
ATH_RATE_MAX
)
break
;
}
ath_rc_priv
->
neg_ht_rates
.
rs_nrates
=
j
;
}
ath_rc_node_update
(
hw
,
priv_sta
);
ath_rc_node_update
(
sc
->
hw
,
priv_sta
);
}
static
void
ath_rate_clear
(
void
*
priv
)
...
...
@@ -2058,13 +2044,12 @@ static void ath_rate_clear(void *priv)
return
;
}
static
void
*
ath_rate_alloc
(
struct
ieee80211_
local
*
local
)
static
void
*
ath_rate_alloc
(
struct
ieee80211_
hw
*
hw
,
struct
dentry
*
debugfsdir
)
{
struct
ieee80211_hw
*
hw
=
local_to_hw
(
local
);
struct
ath_softc
*
sc
=
hw
->
priv
;
DPRINTF
(
sc
,
ATH_DBG_RATE
,
"%s
\n
"
,
__func__
);
return
local
->
hw
.
priv
;
return
hw
->
priv
;
}
static
void
ath_rate_free
(
void
*
priv
)
...
...
@@ -2072,7 +2057,7 @@ static void ath_rate_free(void *priv)
return
;
}
static
void
*
ath_rate_alloc_sta
(
void
*
priv
,
gfp_t
gfp
)
static
void
*
ath_rate_alloc_sta
(
void
*
priv
,
struct
ieee80211_sta
*
sta
,
gfp_t
gfp
)
{
struct
ath_softc
*
sc
=
priv
;
struct
ath_vap
*
avp
=
sc
->
sc_vaps
[
0
];
...
...
@@ -2092,7 +2077,8 @@ static void *ath_rate_alloc_sta(void *priv, gfp_t gfp)
return
rate_priv
;
}
static
void
ath_rate_free_sta
(
void
*
priv
,
void
*
priv_sta
)
static
void
ath_rate_free_sta
(
void
*
priv
,
struct
ieee80211_sta
*
sta
,
void
*
priv_sta
)
{
struct
ath_rate_node
*
rate_priv
=
priv_sta
;
struct
ath_softc
*
sc
=
priv
;
...
...
@@ -2111,7 +2097,7 @@ static struct rate_control_ops ath_rate_ops = {
.
alloc
=
ath_rate_alloc
,
.
free
=
ath_rate_free
,
.
alloc_sta
=
ath_rate_alloc_sta
,
.
free_sta
=
ath_rate_free_sta
.
free_sta
=
ath_rate_free_sta
,
};
int
ath_rate_control_register
(
void
)
...
...
This diff is collapsed.
Click to expand it.
drivers/net/wireless/atmel.c
浏览文件 @
db4148da
...
...
@@ -2258,7 +2258,7 @@ static int atmel_get_freq(struct net_device *dev,
static
int
atmel_set_scan
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
struct
iw_p
aram
*
v
wrq
,
struct
iw_p
oint
*
d
wrq
,
char
*
extra
)
{
struct
atmel_private
*
priv
=
netdev_priv
(
dev
);
...
...
This diff is collapsed.
Click to expand it.
drivers/net/wireless/atmel_cs.c
浏览文件 @
db4148da
...
...
@@ -158,7 +158,7 @@ static int atmel_probe(struct pcmcia_device *p_dev)
DEBUG
(
0
,
"atmel_attach()
\n
"
);
/* Interrupt setup */
p_dev
->
irq
.
Attributes
=
IRQ_TYPE_
EXCLUSIVE
;
p_dev
->
irq
.
Attributes
=
IRQ_TYPE_
DYNAMIC_SHARING
;
p_dev
->
irq
.
IRQInfo1
=
IRQ_LEVEL_ID
;
p_dev
->
irq
.
Handler
=
NULL
;
...
...
This diff is collapsed.
Click to expand it.
drivers/net/wireless/b43/rfkill.c
浏览文件 @
db4148da
...
...
@@ -188,6 +188,11 @@ void b43_rfkill_init(struct b43_wldev *dev)
"The built-in radio LED will not work.
\n
"
);
#endif
/* CONFIG_RFKILL_INPUT */
#if !defined(CONFIG_RFKILL_INPUT) && !defined(CONFIG_RFKILL_INPUT_MODULE)
b43warn
(
wl
,
"The rfkill-input subsystem is not available. "
"The built-in radio LED will not work.
\n
"
);
#endif
err
=
input_register_polled_device
(
rfk
->
poll_dev
);
if
(
err
)
goto
err_unreg_rfk
;
...
...
This diff is collapsed.
Click to expand it.
drivers/net/wireless/iwlwifi/iwl-3945-rs.c
浏览文件 @
db4148da
...
...
@@ -36,8 +36,6 @@
#include <linux/workqueue.h>
#include "../net/mac80211/rate.h"
#include "iwl-3945.h"
#define RS_NAME "iwl-3945-rs"
...
...
@@ -319,10 +317,10 @@ static void iwl3945_collect_tx_data(struct iwl3945_rs_sta *rs_sta,
}
}
static
void
rs_rate_init
(
void
*
priv
_rate
,
void
*
priv_sta
,
struct
ieee80211_
local
*
local
,
struct
sta_info
*
sta
)
static
void
rs_rate_init
(
void
*
priv
,
struct
ieee80211_supported_band
*
sband
,
struct
ieee80211_
sta
*
sta
,
void
*
priv_
sta
)
{
struct
iwl3945_rs_sta
*
rs_sta
=
(
void
*
)
sta
->
rate_ctrl_priv
;
struct
iwl3945_rs_sta
*
rs_sta
=
priv_sta
;
int
i
;
IWL_DEBUG_RATE
(
"enter
\n
"
);
...
...
@@ -333,22 +331,22 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
* after assoc.. */
for
(
i
=
IWL_RATE_COUNT
-
1
;
i
>=
0
;
i
--
)
{
if
(
sta
->
s
ta
.
supp_rates
[
local
->
hw
.
conf
.
channel
->
band
]
&
(
1
<<
i
))
{
if
(
sta
->
s
upp_rates
[
sband
->
band
]
&
(
1
<<
i
))
{
rs_sta
->
last_txrate_idx
=
i
;
break
;
}
}
/* For 5 GHz band it start at IWL_FIRST_OFDM_RATE */
if
(
local
->
hw
.
conf
.
channel
->
band
==
IEEE80211_BAND_5GHZ
)
if
(
sband
->
band
==
IEEE80211_BAND_5GHZ
)
rs_sta
->
last_txrate_idx
+=
IWL_FIRST_OFDM_RATE
;
IWL_DEBUG_RATE
(
"leave
\n
"
);
}
static
void
*
rs_alloc
(
struct
ieee80211_
local
*
local
)
static
void
*
rs_alloc
(
struct
ieee80211_
hw
*
hw
,
struct
dentry
*
debugfsdir
)
{
return
local
->
hw
.
priv
;
return
hw
->
priv
;
}
/* rate scale requires free function to be implemented */
...
...
@@ -356,17 +354,24 @@ static void rs_free(void *priv)
{
return
;
}
static
void
rs_clear
(
void
*
priv
)
{
return
;
}
static
void
*
rs_alloc_sta
(
void
*
priv
,
gfp_t
gfp
)
static
void
*
rs_alloc_sta
(
void
*
priv
,
struct
ieee80211_sta
*
sta
,
gfp_t
gfp
)
{
struct
iwl3945_rs_sta
*
rs_sta
;
struct
iwl3945_sta_priv
*
psta
=
(
void
*
)
sta
->
drv_priv
;
int
i
;
/*
* XXX: If it's using sta->drv_priv anyway, it might
* as well just put all the information there.
*/
IWL_DEBUG_RATE
(
"enter
\n
"
);
rs_sta
=
kzalloc
(
sizeof
(
struct
iwl3945_rs_sta
),
gfp
);
...
...
@@ -375,6 +380,8 @@ static void *rs_alloc_sta(void *priv, gfp_t gfp)
return
NULL
;
}
psta
->
rs_sta
=
rs_sta
;
spin_lock_init
(
&
rs_sta
->
lock
);
rs_sta
->
start_rate
=
IWL_RATE_INVALID
;
...
...
@@ -400,10 +407,14 @@ static void *rs_alloc_sta(void *priv, gfp_t gfp)
return
rs_sta
;
}
static
void
rs_free_sta
(
void
*
priv
,
void
*
priv_sta
)
static
void
rs_free_sta
(
void
*
priv
,
struct
ieee80211_sta
*
sta
,
void
*
priv_sta
)
{
struct
iwl3945_sta_priv
*
psta
=
(
void
*
)
sta
->
drv_priv
;
struct
iwl3945_rs_sta
*
rs_sta
=
priv_sta
;
psta
->
rs_sta
=
NULL
;
IWL_DEBUG_RATE
(
"enter
\n
"
);
del_timer_sync
(
&
rs_sta
->
rate_scale_flush
);
kfree
(
rs_sta
);
...
...
@@ -445,26 +456,19 @@ static int rs_adjust_next_rate(struct iwl3945_priv *priv, int rate)
* NOTE: Uses iwl3945_priv->retry_rate for the # of retries attempted by
* the hardware for each rate.
*/
static
void
rs_tx_status
(
void
*
priv_rate
,
struct
net_device
*
dev
,
static
void
rs_tx_status
(
void
*
priv_rate
,
struct
ieee80211_supported_band
*
sband
,
struct
ieee80211_sta
*
sta
,
void
*
priv_sta
,
struct
sk_buff
*
skb
)
{
u8
retries
,
current_count
;
int
scale_rate_index
,
first_index
,
last_index
;
unsigned
long
flags
;
struct
sta_info
*
sta
;
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
skb
->
data
;
struct
iwl3945_priv
*
priv
=
(
struct
iwl3945_priv
*
)
priv_rate
;
struct
ieee80211_local
*
local
=
wdev_priv
(
dev
->
ieee80211_ptr
);
struct
iwl3945_rs_sta
*
rs_sta
;
struct
ieee80211_supported_band
*
sband
;
struct
iwl3945_rs_sta
*
rs_sta
=
priv_sta
;
struct
ieee80211_tx_info
*
info
=
IEEE80211_SKB_CB
(
skb
);
IWL_DEBUG_RATE
(
"enter
\n
"
);
sband
=
local
->
hw
.
wiphy
->
bands
[
local
->
hw
.
conf
.
channel
->
band
];
retries
=
info
->
status
.
retry_count
;
first_index
=
sband
->
bitrates
[
info
->
tx_rate_idx
].
hw_value
;
if
((
first_index
<
0
)
||
(
first_index
>=
IWL_RATE_COUNT
))
{
...
...
@@ -472,17 +476,11 @@ static void rs_tx_status(void *priv_rate,
return
;
}
rcu_read_lock
();
sta
=
sta_info_get
(
local
,
hdr
->
addr1
);
if
(
!
sta
||
!
sta
->
rate_ctrl_priv
)
{
rcu_read_unlock
();
if
(
!
priv_sta
)
{
IWL_DEBUG_RATE
(
"leave: No STA priv data to update!
\n
"
);
return
;
}
rs_sta
=
(
void
*
)
sta
->
rate_ctrl_priv
;
rs_sta
->
tx_packets
++
;
scale_rate_index
=
first_index
;
...
...
@@ -549,8 +547,6 @@ static void rs_tx_status(void *priv_rate,
spin_unlock_irqrestore
(
&
rs_sta
->
lock
,
flags
);
rcu_read_unlock
();
IWL_DEBUG_RATE
(
"leave
\n
"
);
return
;
...
...
@@ -634,16 +630,15 @@ static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta,
* rate table and must reference the driver allocated rate table
*
*/
static
void
rs_get_rate
(
void
*
priv_rate
,
struct
net_device
*
dev
,
struct
ieee80211_supported_band
*
sband
,
struct
sk_buff
*
skb
,
struct
rate_selection
*
sel
)
static
void
rs_get_rate
(
void
*
priv_r
,
struct
ieee80211_supported_band
*
sband
,
struct
ieee80211_sta
*
sta
,
void
*
priv_sta
,
struct
sk_buff
*
skb
,
struct
rate_selection
*
sel
)
{
u8
low
=
IWL_RATE_INVALID
;
u8
high
=
IWL_RATE_INVALID
;
u16
high_low
;
int
index
;
struct
iwl3945_rs_sta
*
rs_sta
;
struct
iwl3945_rs_sta
*
rs_sta
=
priv_sta
;
struct
iwl3945_rate_scale_data
*
window
=
NULL
;
int
current_tpt
=
IWL_INV_TPT
;
int
low_tpt
=
IWL_INV_TPT
;
...
...
@@ -651,34 +646,25 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
u32
fail_count
;
s8
scale_action
=
0
;
unsigned
long
flags
;
struct
ieee80211_local
*
local
=
wdev_priv
(
dev
->
ieee80211_ptr
);
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
skb
->
data
;
struct
sta_info
*
sta
;
u16
fc
,
rate_mask
;
struct
iwl3945_priv
*
priv
=
(
struct
iwl3945_priv
*
)
priv_r
ate
;
struct
iwl3945_priv
*
priv
=
(
struct
iwl3945_priv
*
)
priv_r
;
DECLARE_MAC_BUF
(
mac
);
IWL_DEBUG_RATE
(
"enter
\n
"
);
rcu_read_lock
();
sta
=
sta_info_get
(
local
,
hdr
->
addr1
);
/* Send management frames and broadcast/multicast data using lowest
* rate. */
fc
=
le16_to_cpu
(
hdr
->
frame_control
);
if
((
fc
&
IEEE80211_FCTL_FTYPE
)
!=
IEEE80211_FTYPE_DATA
||
is_multicast_ether_addr
(
hdr
->
addr1
)
||
!
sta
||
!
sta
->
rate_ctrl_priv
)
{
!
sta
||
!
priv_sta
)
{
IWL_DEBUG_RATE
(
"leave: No STA priv data to update!
\n
"
);
sel
->
rate_idx
=
rate_lowest_index
(
local
,
sband
,
sta
);
rcu_read_unlock
();
sel
->
rate_idx
=
rate_lowest_index
(
sband
,
sta
);
return
;
}
rs_sta
=
(
void
*
)
sta
->
rate_ctrl_priv
;
rate_mask
=
sta
->
sta
.
supp_rates
[
sband
->
band
];
rate_mask
=
sta
->
supp_rates
[
sband
->
band
];
index
=
min
(
rs_sta
->
last_txrate_idx
&
0xffff
,
IWL_RATE_COUNT
-
1
);
if
(
sband
->
band
==
IEEE80211_BAND_5GHZ
)
...
...
@@ -811,8 +797,6 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
else
sel
->
rate_idx
=
rs_sta
->
last_txrate_idx
;
rcu_read_unlock
();
IWL_DEBUG_RATE
(
"leave: %d
\n
"
,
index
);
}
...
...
@@ -829,114 +813,28 @@ static struct rate_control_ops rs_ops = {
.
free_sta
=
rs_free_sta
,
};
int
iwl3945_fill_rs_info
(
struct
ieee80211_hw
*
hw
,
char
*
buf
,
u8
sta_id
)
{
struct
ieee80211_local
*
local
=
hw_to_local
(
hw
);
struct
iwl3945_priv
*
priv
=
hw
->
priv
;
struct
iwl3945_rs_sta
*
rs_sta
;
struct
sta_info
*
sta
;
unsigned
long
flags
;
int
count
=
0
,
i
;
u32
samples
=
0
,
success
=
0
,
good
=
0
;
unsigned
long
now
=
jiffies
;
u32
max_time
=
0
;
rcu_read_lock
();
sta
=
sta_info_get
(
local
,
priv
->
stations
[
sta_id
].
sta
.
sta
.
addr
);
if
(
!
sta
||
!
sta
->
rate_ctrl_priv
)
{
if
(
sta
)
IWL_DEBUG_RATE
(
"leave - no private rate data!
\n
"
);
else
IWL_DEBUG_RATE
(
"leave - no station!
\n
"
);
rcu_read_unlock
();
return
sprintf
(
buf
,
"station %d not found
\n
"
,
sta_id
);
}
rs_sta
=
(
void
*
)
sta
->
rate_ctrl_priv
;
spin_lock_irqsave
(
&
rs_sta
->
lock
,
flags
);
i
=
IWL_RATE_54M_INDEX
;
while
(
1
)
{
u64
mask
;
int
j
;
count
+=
sprintf
(
&
buf
[
count
],
" %2dMbs: "
,
iwl3945_rates
[
i
].
ieee
/
2
);
mask
=
(
1ULL
<<
(
IWL_RATE_MAX_WINDOW
-
1
));
for
(
j
=
0
;
j
<
IWL_RATE_MAX_WINDOW
;
j
++
,
mask
>>=
1
)
buf
[
count
++
]
=
(
rs_sta
->
win
[
i
].
data
&
mask
)
?
'1'
:
'0'
;
samples
+=
rs_sta
->
win
[
i
].
counter
;
good
+=
rs_sta
->
win
[
i
].
success_counter
;
success
+=
rs_sta
->
win
[
i
].
success_counter
*
iwl3945_rates
[
i
].
ieee
;
if
(
rs_sta
->
win
[
i
].
stamp
)
{
int
delta
=
jiffies_to_msecs
(
now
-
rs_sta
->
win
[
i
].
stamp
);
if
(
delta
>
max_time
)
max_time
=
delta
;
count
+=
sprintf
(
&
buf
[
count
],
"%5dms
\n
"
,
delta
);
}
else
buf
[
count
++
]
=
'\n'
;
j
=
iwl3945_get_prev_ieee_rate
(
i
);
if
(
j
==
i
)
break
;
i
=
j
;
}
spin_unlock_irqrestore
(
&
rs_sta
->
lock
,
flags
);
rcu_read_unlock
();
/* Display the average rate of all samples taken.
*
* NOTE: We multiple # of samples by 2 since the IEEE measurement
* added from iwl3945_rates is actually 2X the rate */
if
(
samples
)
count
+=
sprintf
(
&
buf
[
count
],
"
\n
Average rate is %3d.%02dMbs over last %4dms
\n
"
"%3d%% success (%d good packets over %d tries)
\n
"
,
success
/
(
2
*
samples
),
(
success
*
5
/
samples
)
%
10
,
max_time
,
good
*
100
/
samples
,
good
,
samples
);
else
count
+=
sprintf
(
&
buf
[
count
],
"
\n
Average rate: 0Mbs
\n
"
);
return
count
;
}
void
iwl3945_rate_scale_init
(
struct
ieee80211_hw
*
hw
,
s32
sta_id
)
{
struct
iwl3945_priv
*
priv
=
hw
->
priv
;
s32
rssi
=
0
;
unsigned
long
flags
;
struct
ieee80211_local
*
local
=
hw_to_local
(
hw
);
struct
iwl3945_rs_sta
*
rs_sta
;
struct
sta_info
*
sta
;
struct
ieee80211_sta
*
sta
;
struct
iwl3945_sta_priv
*
psta
;
IWL_DEBUG_RATE
(
"enter
\n
"
);
if
(
!
local
->
rate_ctrl
->
ops
->
name
||
strcmp
(
local
->
rate_ctrl
->
ops
->
name
,
RS_NAME
))
{
IWL_WARNING
(
"iwl-3945-rs not selected as rate control algo!
\n
"
);
IWL_DEBUG_RATE
(
"leave - mac80211 picked the wrong RC algo.
\n
"
);
return
;
}
rcu_read_lock
();
sta
=
sta_info_get
(
local
,
priv
->
stations
[
sta_id
].
sta
.
sta
.
addr
);
if
(
!
sta
||
!
sta
->
rate_ctrl_priv
)
{
sta
=
ieee80211_find_sta
(
hw
,
priv
->
stations
[
sta_id
].
sta
.
sta
.
addr
);
psta
=
(
void
*
)
sta
->
drv_priv
;
if
(
!
sta
||
!
psta
)
{
IWL_DEBUG_RATE
(
"leave - no private rate data!
\n
"
);
rcu_read_unlock
();
return
;
}
rs_sta
=
(
void
*
)
sta
->
rate_ctrl_priv
;
rs_sta
=
psta
->
rs_sta
;
spin_lock_irqsave
(
&
rs_sta
->
lock
,
flags
);
...
...
This diff is collapsed.
Click to expand it.
drivers/net/wireless/iwlwifi/iwl-3945-rs.h
浏览文件 @
db4148da
...
...
@@ -175,15 +175,6 @@ static inline u8 iwl3945_get_prev_ieee_rate(u8 rate_index)
return
rate
;
}
/**
* iwl3945_fill_rs_info - Fill an output text buffer with the rate representation
*
* NOTE: This is provided as a quick mechanism for a user to visualize
* the performance of the rate control algorithm and is not meant to be
* parsed software.
*/
extern
int
iwl3945_fill_rs_info
(
struct
ieee80211_hw
*
,
char
*
buf
,
u8
sta_id
);
/**
* iwl3945_rate_scale_init - Initialize the rate scale table based on assoc info
*
...
...
This diff is collapsed.
Click to expand it.
drivers/net/wireless/iwlwifi/iwl-3945.h
浏览文件 @
db4148da
...
...
@@ -73,6 +73,10 @@ extern struct pci_device_id iwl3945_hw_card_ids[];
extern
int
iwl3945_param_hwcrypto
;
extern
int
iwl3945_param_queues_num
;
struct
iwl3945_sta_priv
{
struct
iwl3945_rs_sta
*
rs_sta
;
};
enum
iwl3945_antenna
{
IWL_ANTENNA_DIVERSITY
,
IWL_ANTENNA_MAIN
,
...
...
This diff is collapsed.
Click to expand it.
drivers/net/wireless/iwlwifi/iwl-agn-rs.c
浏览文件 @
db4148da
...
...
@@ -35,8 +35,6 @@
#include <linux/workqueue.h>
#include "../net/mac80211/rate.h"
#include "iwl-dev.h"
#include "iwl-sta.h"
#include "iwl-core.h"
...
...
@@ -169,9 +167,9 @@ struct iwl_lq_sta {
};
static
void
rs_rate_scale_perform
(
struct
iwl_priv
*
priv
,
struct
net_device
*
dev
,
struct
ieee80211_hdr
*
hdr
,
struct
sta_info
*
sta
);
struct
ieee80211_sta
*
sta
,
struct
iwl_lq_sta
*
lq_sta
);
static
void
rs_fill_link_cmd
(
const
struct
iwl_priv
*
priv
,
struct
iwl_lq_sta
*
lq_sta
,
u32
rate_n_flags
);
...
...
@@ -357,20 +355,20 @@ static u32 rs_tl_get_load(struct iwl_lq_sta *lq_data, u8 tid)
static
void
rs_tl_turn_on_agg_for_tid
(
struct
iwl_priv
*
priv
,
struct
iwl_lq_sta
*
lq_data
,
u8
tid
,
struct
sta_info
*
sta
)
struct
ieee80211_sta
*
sta
)
{
DECLARE_MAC_BUF
(
mac
);
if
(
rs_tl_get_load
(
lq_data
,
tid
)
>
IWL_AGG_LOAD_THRESHOLD
)
{
IWL_DEBUG_HT
(
"Starting Tx agg: STA: %s tid: %d
\n
"
,
print_mac
(
mac
,
sta
->
sta
.
addr
),
tid
);
ieee80211_start_tx_ba_session
(
priv
->
hw
,
sta
->
sta
.
addr
,
tid
);
print_mac
(
mac
,
sta
->
addr
),
tid
);
ieee80211_start_tx_ba_session
(
priv
->
hw
,
sta
->
addr
,
tid
);
}
}
static
void
rs_tl_turn_on_agg
(
struct
iwl_priv
*
priv
,
u8
tid
,
struct
iwl_lq_sta
*
lq_data
,
struct
sta_info
*
sta
)
struct
ieee80211_sta
*
sta
)
{
if
((
tid
<
TID_MAX_LOAD_COUNT
))
rs_tl_turn_on_agg_for_tid
(
priv
,
lq_data
,
tid
,
sta
);
...
...
@@ -770,7 +768,8 @@ static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta,
/*
* mac80211 sends us Tx status
*/
static
void
rs_tx_status
(
void
*
priv_rate
,
struct
net_device
*
dev
,
static
void
rs_tx_status
(
void
*
priv_r
,
struct
ieee80211_supported_band
*
sband
,
struct
ieee80211_sta
*
sta
,
void
*
priv_sta
,
struct
sk_buff
*
skb
)
{
int
status
;
...
...
@@ -778,11 +777,9 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
int
rs_index
,
index
=
0
;
struct
iwl_lq_sta
*
lq_sta
;
struct
iwl_link_quality_cmd
*
table
;
struct
sta_info
*
sta
;
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
skb
->
data
;
struct
iwl_priv
*
priv
=
(
struct
iwl_priv
*
)
priv_rate
;
struct
ieee80211_local
*
local
=
wdev_priv
(
dev
->
ieee80211_ptr
);
struct
ieee80211_hw
*
hw
=
local_to_hw
(
local
);
struct
iwl_priv
*
priv
=
(
struct
iwl_priv
*
)
priv_r
;
struct
ieee80211_hw
*
hw
=
priv
->
hw
;
struct
ieee80211_tx_info
*
info
=
IEEE80211_SKB_CB
(
skb
);
struct
iwl_rate_scale_data
*
window
=
NULL
;
struct
iwl_rate_scale_data
*
search_win
=
NULL
;
...
...
@@ -808,15 +805,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
if
(
retries
>
15
)
retries
=
15
;
rcu_read_lock
();
sta
=
sta_info_get
(
local
,
hdr
->
addr1
);
if
(
!
sta
||
!
sta
->
rate_ctrl_priv
)
goto
out
;
lq_sta
=
(
struct
iwl_lq_sta
*
)
sta
->
rate_ctrl_priv
;
lq_sta
=
(
struct
iwl_lq_sta
*
)
priv_sta
;
if
((
priv
->
iw_mode
==
NL80211_IFTYPE_ADHOC
)
&&
!
lq_sta
->
ibss_sta_added
)
...
...
@@ -962,9 +951,8 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
}
/* See if there's a better rate or modulation mode to try. */
rs_rate_scale_perform
(
priv
,
dev
,
hdr
,
sta
);
rs_rate_scale_perform
(
priv
,
hdr
,
sta
,
lq_
sta
);
out:
rcu_read_unlock
();
return
;
}
...
...
@@ -1140,7 +1128,7 @@ static s32 rs_get_best_rate(struct iwl_priv *priv,
static
int
rs_switch_to_mimo2
(
struct
iwl_priv
*
priv
,
struct
iwl_lq_sta
*
lq_sta
,
struct
ieee80211_conf
*
conf
,
struct
sta_info
*
sta
,
struct
ieee80211_sta
*
sta
,
struct
iwl_scale_tbl_info
*
tbl
,
int
index
)
{
u16
rate_mask
;
...
...
@@ -1148,10 +1136,10 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
s8
is_green
=
lq_sta
->
is_green
;
if
(
!
(
conf
->
flags
&
IEEE80211_CONF_SUPPORT_HT_MODE
)
||
!
sta
->
sta
.
ht_info
.
ht_supported
)
!
sta
->
ht_info
.
ht_supported
)
return
-
1
;
if
(((
sta
->
sta
.
ht_info
.
cap
&
IEEE80211_HT_CAP_SM_PS
)
>>
2
)
if
(((
sta
->
ht_info
.
cap
&
IEEE80211_HT_CAP_SM_PS
)
>>
2
)
==
WLAN_HT_CAP_SM_PS_STATIC
)
return
-
1
;
...
...
@@ -1208,7 +1196,7 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
static
int
rs_switch_to_siso
(
struct
iwl_priv
*
priv
,
struct
iwl_lq_sta
*
lq_sta
,
struct
ieee80211_conf
*
conf
,
struct
sta_info
*
sta
,
struct
ieee80211_sta
*
sta
,
struct
iwl_scale_tbl_info
*
tbl
,
int
index
)
{
u16
rate_mask
;
...
...
@@ -1216,7 +1204,7 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
s32
rate
;
if
(
!
(
conf
->
flags
&
IEEE80211_CONF_SUPPORT_HT_MODE
)
||
!
sta
->
sta
.
ht_info
.
ht_supported
)
!
sta
->
ht_info
.
ht_supported
)
return
-
1
;
IWL_DEBUG_RATE
(
"LQ: try to switch to SISO
\n
"
);
...
...
@@ -1268,7 +1256,7 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
static
int
rs_move_legacy_other
(
struct
iwl_priv
*
priv
,
struct
iwl_lq_sta
*
lq_sta
,
struct
ieee80211_conf
*
conf
,
struct
sta_info
*
sta
,
struct
ieee80211_sta
*
sta
,
int
index
)
{
struct
iwl_scale_tbl_info
*
tbl
=
&
(
lq_sta
->
lq_info
[
lq_sta
->
active_tbl
]);
...
...
@@ -1376,7 +1364,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
static
int
rs_move_siso_to_other
(
struct
iwl_priv
*
priv
,
struct
iwl_lq_sta
*
lq_sta
,
struct
ieee80211_conf
*
conf
,
struct
sta_info
*
sta
,
int
index
)
struct
ieee80211_sta
*
sta
,
int
index
)
{
u8
is_green
=
lq_sta
->
is_green
;
struct
iwl_scale_tbl_info
*
tbl
=
&
(
lq_sta
->
lq_info
[
lq_sta
->
active_tbl
]);
...
...
@@ -1487,7 +1475,7 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
static
int
rs_move_mimo_to_other
(
struct
iwl_priv
*
priv
,
struct
iwl_lq_sta
*
lq_sta
,
struct
ieee80211_conf
*
conf
,
struct
sta_info
*
sta
,
int
index
)
struct
ieee80211_sta
*
sta
,
int
index
)
{
s8
is_green
=
lq_sta
->
is_green
;
struct
iwl_scale_tbl_info
*
tbl
=
&
(
lq_sta
->
lq_info
[
lq_sta
->
active_tbl
]);
...
...
@@ -1680,12 +1668,11 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta)
* Do rate scaling and search for new modulation mode.
*/
static
void
rs_rate_scale_perform
(
struct
iwl_priv
*
priv
,
struct
net_device
*
dev
,
struct
ieee80211_hdr
*
hdr
,
struct
sta_info
*
sta
)
struct
ieee80211_sta
*
sta
,
struct
iwl_lq_sta
*
lq_sta
)
{
struct
ieee80211_local
*
local
=
wdev_priv
(
dev
->
ieee80211_ptr
);
struct
ieee80211_hw
*
hw
=
local_to_hw
(
local
);
struct
ieee80211_hw
*
hw
=
priv
->
hw
;
struct
ieee80211_conf
*
conf
=
&
hw
->
conf
;
int
low
=
IWL_RATE_INVALID
;
int
high
=
IWL_RATE_INVALID
;
...
...
@@ -1700,7 +1687,6 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
__le16
fc
;
u16
rate_mask
;
u8
update_lq
=
0
;
struct
iwl_lq_sta
*
lq_sta
;
struct
iwl_scale_tbl_info
*
tbl
,
*
tbl1
;
u16
rate_scale_index_msk
=
0
;
u32
rate
;
...
...
@@ -1721,11 +1707,10 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
return
;
}
if
(
!
sta
||
!
sta
->
rate_ctrl_priv
)
if
(
!
sta
||
!
lq_sta
)
return
;
lq_sta
=
(
struct
iwl_lq_sta
*
)
sta
->
rate_ctrl_priv
;
lq_sta
->
supp_rates
=
sta
->
sta
.
supp_rates
[
lq_sta
->
band
];
lq_sta
->
supp_rates
=
sta
->
supp_rates
[
lq_sta
->
band
];
tid
=
rs_tl_add_packet
(
lq_sta
,
hdr
);
...
...
@@ -2064,9 +2049,9 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
static
void
rs_initialize_lq
(
struct
iwl_priv
*
priv
,
struct
ieee80211_conf
*
conf
,
struct
sta_info
*
sta
)
struct
ieee80211_sta
*
sta
,
struct
iwl_lq_sta
*
lq_sta
)
{
struct
iwl_lq_sta
*
lq_sta
;
struct
iwl_scale_tbl_info
*
tbl
;
int
rate_idx
;
int
i
;
...
...
@@ -2075,10 +2060,9 @@ static void rs_initialize_lq(struct iwl_priv *priv,
u8
active_tbl
=
0
;
u8
valid_tx_ant
;
if
(
!
sta
||
!
sta
->
rate_ctrl_priv
)
if
(
!
sta
||
!
lq_sta
)
goto
out
;
lq_sta
=
(
struct
iwl_lq_sta
*
)
sta
->
rate_ctrl_priv
;
i
=
lq_sta
->
last_txrate_idx
;
if
((
lq_sta
->
lq
.
sta_id
==
0xff
)
&&
...
...
@@ -2119,37 +2103,30 @@ static void rs_initialize_lq(struct iwl_priv *priv,
return
;
}
static
void
rs_get_rate
(
void
*
priv_rate
,
struct
net_device
*
dev
,
struct
ieee80211_supported_band
*
sband
,
struct
sk_buff
*
skb
,
struct
rate_selection
*
sel
)
static
void
rs_get_rate
(
void
*
priv_r
,
struct
ieee80211_supported_band
*
sband
,
struct
ieee80211_sta
*
sta
,
void
*
priv_sta
,
struct
sk_buff
*
skb
,
struct
rate_selection
*
sel
)
{
int
i
;
struct
i
eee80211_local
*
local
=
wdev_priv
(
dev
->
ieee80211_ptr
)
;
struct
ieee80211_conf
*
conf
=
&
local
->
hw
.
conf
;
struct
i
wl_priv
*
priv
=
(
struct
iwl_priv
*
)
priv_r
;
struct
ieee80211_conf
*
conf
=
&
priv
->
hw
->
conf
;
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
skb
->
data
;
struct
sta_info
*
sta
;
__le16
fc
;
struct
iwl_priv
*
priv
=
(
struct
iwl_priv
*
)
priv_rate
;
struct
iwl_lq_sta
*
lq_sta
;
IWL_DEBUG_RATE_LIMIT
(
"rate scale calculate new rate for skb
\n
"
);
rcu_read_lock
();
sta
=
sta_info_get
(
local
,
hdr
->
addr1
);
/* Send management frames and broadcast/multicast data using lowest
* rate. */
fc
=
hdr
->
frame_control
;
if
(
!
ieee80211_is_data
(
fc
)
||
is_multicast_ether_addr
(
hdr
->
addr1
)
||
!
sta
||
!
sta
->
rate_ctrl_priv
)
{
sel
->
rate_idx
=
rate_lowest_index
(
local
,
sband
,
sta
);
goto
out
;
!
sta
||
!
priv_sta
)
{
sel
->
rate_idx
=
rate_lowest_index
(
sband
,
sta
);
return
;
}
lq_sta
=
(
struct
iwl_lq_sta
*
)
sta
->
rate_ctrl_priv
;
lq_sta
=
(
struct
iwl_lq_sta
*
)
priv_sta
;
i
=
lq_sta
->
last_txrate_idx
;
if
((
priv
->
iw_mode
==
NL80211_IFTYPE_ADHOC
)
&&
...
...
@@ -2167,23 +2144,22 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
lq_sta
->
lq
.
sta_id
=
sta_id
;
lq_sta
->
lq
.
rs_table
[
0
].
rate_n_flags
=
0
;
lq_sta
->
ibss_sta_added
=
1
;
rs_initialize_lq
(
priv
,
conf
,
sta
);
rs_initialize_lq
(
priv
,
conf
,
sta
,
lq_sta
);
}
}
if
((
i
<
0
)
||
(
i
>
IWL_RATE_COUNT
))
{
sel
->
rate_idx
=
rate_lowest_index
(
local
,
sband
,
sta
);
goto
out
;
sel
->
rate_idx
=
rate_lowest_index
(
sband
,
sta
);
return
;
}
if
(
sband
->
band
==
IEEE80211_BAND_5GHZ
)
i
-=
IWL_FIRST_OFDM_RATE
;
sel
->
rate_idx
=
i
;
out:
rcu_read_unlock
();
}
static
void
*
rs_alloc_sta
(
void
*
priv_rate
,
gfp_t
gfp
)
static
void
*
rs_alloc_sta
(
void
*
priv_rate
,
struct
ieee80211_sta
*
sta
,
gfp_t
gfp
)
{
struct
iwl_lq_sta
*
lq_sta
;
struct
iwl_priv
*
priv
;
...
...
@@ -2206,20 +2182,16 @@ static void *rs_alloc_sta(void *priv_rate, gfp_t gfp)
return
lq_sta
;
}
static
void
rs_rate_init
(
void
*
priv_rate
,
void
*
priv_sta
,
struct
ieee80211_local
*
local
,
struct
sta_info
*
sta
)
static
void
rs_rate_init
(
void
*
priv_r
,
struct
ieee80211_supported_band
*
sband
,
struct
ieee80211_sta
*
sta
,
void
*
priv_sta
)
{
int
i
,
j
;
struct
ieee80211_conf
*
conf
=
&
local
->
hw
.
conf
;
struct
ieee80211_supported_band
*
sband
;
struct
iwl_priv
*
priv
=
(
struct
iwl_priv
*
)
priv_rate
;
struct
iwl_priv
*
priv
=
(
struct
iwl_priv
*
)
priv_r
;
struct
ieee80211_conf
*
conf
=
&
priv
->
hw
->
conf
;
struct
iwl_lq_sta
*
lq_sta
=
priv_sta
;
sband
=
local
->
hw
.
wiphy
->
bands
[
local
->
hw
.
conf
.
channel
->
band
];
lq_sta
->
flush_timer
=
0
;
lq_sta
->
supp_rates
=
sta
->
s
ta
.
s
upp_rates
[
sband
->
band
];
lq_sta
->
supp_rates
=
sta
->
supp_rates
[
sband
->
band
];
for
(
j
=
0
;
j
<
LQ_SIZE
;
j
++
)
for
(
i
=
0
;
i
<
IWL_RATE_COUNT
;
i
++
)
rs_rate_scale_clear_window
(
&
lq_sta
->
lq_info
[
j
].
win
[
i
]);
...
...
@@ -2232,17 +2204,17 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
lq_sta
->
ibss_sta_added
=
0
;
if
(
priv
->
iw_mode
==
NL80211_IFTYPE_AP
)
{
u8
sta_id
=
iwl_find_station
(
priv
,
sta
->
sta
.
addr
);
u8
sta_id
=
iwl_find_station
(
priv
,
sta
->
addr
);
DECLARE_MAC_BUF
(
mac
);
/* for IBSS the call are from tasklet */
IWL_DEBUG_RATE
(
"LQ: ADD station %s
\n
"
,
print_mac
(
mac
,
sta
->
sta
.
addr
));
print_mac
(
mac
,
sta
->
addr
));
if
(
sta_id
==
IWL_INVALID_STATION
)
{
IWL_DEBUG_RATE
(
"LQ: ADD station %s
\n
"
,
print_mac
(
mac
,
sta
->
sta
.
addr
));
sta_id
=
iwl_add_station_flags
(
priv
,
sta
->
sta
.
addr
,
print_mac
(
mac
,
sta
->
addr
));
sta_id
=
iwl_add_station_flags
(
priv
,
sta
->
addr
,
0
,
CMD_ASYNC
,
NULL
);
}
if
((
sta_id
!=
IWL_INVALID_STATION
))
{
...
...
@@ -2256,11 +2228,11 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
/* Find highest tx rate supported by hardware and destination station */
lq_sta
->
last_txrate_idx
=
3
;
for
(
i
=
0
;
i
<
sband
->
n_bitrates
;
i
++
)
if
(
sta
->
s
ta
.
s
upp_rates
[
sband
->
band
]
&
BIT
(
i
))
if
(
sta
->
supp_rates
[
sband
->
band
]
&
BIT
(
i
))
lq_sta
->
last_txrate_idx
=
i
;
/* For MODE_IEEE80211A, skip over cck rates in global rate table */
if
(
local
->
hw
.
conf
.
channel
->
band
==
IEEE80211_BAND_5GHZ
)
if
(
sband
->
band
==
IEEE80211_BAND_5GHZ
)
lq_sta
->
last_txrate_idx
+=
IWL_FIRST_OFDM_RATE
;
lq_sta
->
is_dup
=
0
;
...
...
@@ -2301,7 +2273,7 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
lq_sta
->
tx_agg_tid_en
=
IWL_AGG_ALL_TID
;
lq_sta
->
drv
=
priv
;
rs_initialize_lq
(
priv
,
conf
,
sta
);
rs_initialize_lq
(
priv
,
conf
,
sta
,
lq_sta
);
}
static
void
rs_fill_link_cmd
(
const
struct
iwl_priv
*
priv
,
...
...
@@ -2423,9 +2395,9 @@ static void rs_fill_link_cmd(const struct iwl_priv *priv,
lq_cmd
->
agg_params
.
agg_time_limit
=
cpu_to_le16
(
4000
);
}
static
void
*
rs_alloc
(
struct
ieee80211_
local
*
local
)
static
void
*
rs_alloc
(
struct
ieee80211_
hw
*
hw
,
struct
dentry
*
debugfsdir
)
{
return
local
->
hw
.
priv
;
return
hw
->
priv
;
}
/* rate scale requires free function to be implemented */
static
void
rs_free
(
void
*
priv_rate
)
...
...
@@ -2446,12 +2418,12 @@ static void rs_clear(void *priv_rate)
#endif
/* CONFIG_IWLWIFI_DEBUG */
}
static
void
rs_free_sta
(
void
*
priv_rate
,
void
*
priv_sta
)
static
void
rs_free_sta
(
void
*
priv_r
,
struct
ieee80211_sta
*
sta
,
void
*
priv_sta
)
{
struct
iwl_lq_sta
*
lq_sta
=
priv_sta
;
struct
iwl_priv
*
priv
;
struct
iwl_priv
*
priv
=
priv_r
;
priv
=
(
struct
iwl_priv
*
)
priv_rate
;
IWL_DEBUG_RATE
(
"enter
\n
"
);
kfree
(
lq_sta
);
IWL_DEBUG_RATE
(
"leave
\n
"
);
...
...
This diff is collapsed.
Click to expand it.
drivers/net/wireless/iwlwifi/iwl-agn.c
浏览文件 @
db4148da
...
...
@@ -2504,8 +2504,7 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
priv
->
staging_rxon
.
filter_flags
|=
RXON_FILTER_ASSOC_MSK
;
if
(
priv
->
current_ht_config
.
is_ht
)
iwl_set_rxon_ht
(
priv
,
&
priv
->
current_ht_config
);
iwl_set_rxon_ht
(
priv
,
&
priv
->
current_ht_config
);
iwl_set_rxon_chain
(
priv
);
priv
->
staging_rxon
.
assoc_id
=
cpu_to_le16
(
priv
->
assoc_id
);
...
...
@@ -2568,8 +2567,6 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
iwl_chain_noise_reset
(
priv
);
priv
->
start_calib
=
1
;
/* we have just associated, don't start scan too early */
priv
->
next_scan_jiffies
=
jiffies
+
IWL_DELAY_NEXT_SCAN
;
}
static
int
iwl4965_mac_config
(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_conf
*
conf
);
...
...
@@ -3171,6 +3168,10 @@ static void iwl4965_bss_info_changed(struct ieee80211_hw *hw,
priv
->
power_data
.
dtim_period
=
bss_conf
->
dtim_period
;
priv
->
timestamp
=
bss_conf
->
timestamp
;
priv
->
assoc_capability
=
bss_conf
->
assoc_capability
;
/* we have just associated, don't start scan too early
* leave time for EAPOL exchange to complete
*/
priv
->
next_scan_jiffies
=
jiffies
+
IWL_DELAY_NEXT_SCAN_AFTER_ASSOC
;
mutex_lock
(
&
priv
->
mutex
);
...
...
@@ -3189,9 +3190,9 @@ static void iwl4965_bss_info_changed(struct ieee80211_hw *hw,
static
int
iwl_mac_hw_scan
(
struct
ieee80211_hw
*
hw
,
u8
*
ssid
,
size_t
ssid_len
)
{
int
ret
;
unsigned
long
flags
;
struct
iwl_priv
*
priv
=
hw
->
priv
;
int
ret
;
IWL_DEBUG_MAC80211
(
"enter
\n
"
);
...
...
@@ -3210,20 +3211,27 @@ static int iwl_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t ssid_len)
goto
out_unlock
;
}
/* we don't schedule scan within next_scan_jiffies period */
/* We don't schedule scan within next_scan_jiffies period.
* Avoid scanning during possible EAPOL exchange, return
* success immediately.
*/
if
(
priv
->
next_scan_jiffies
&&
time_after
(
priv
->
next_scan_jiffies
,
jiffies
))
{
IWL_DEBUG_SCAN
(
"scan rejected: within next scan period
\n
"
);
ret
=
-
EAGAIN
;
queue_work
(
priv
->
workqueue
,
&
priv
->
scan_completed
);
ret
=
0
;
goto
out_unlock
;
}
/* if we just finished scan ask for delay */
if
(
iwl_is_associated
(
priv
)
&&
priv
->
last_scan_jiffies
&&
time_after
(
priv
->
last_scan_jiffies
+
IWL_DELAY_NEXT_SCAN
,
jiffies
))
{
IWL_DEBUG_SCAN
(
"scan rejected: within previous scan period
\n
"
);
ret
=
-
EAGAIN
;
queue_work
(
priv
->
workqueue
,
&
priv
->
scan_completed
);
ret
=
0
;
goto
out_unlock
;
}
if
(
ssid_len
)
{
priv
->
one_direct_scan
=
1
;
priv
->
direct_ssid_len
=
min_t
(
u8
,
ssid_len
,
IW_ESSID_MAX_SIZE
);
...
...
This diff is collapsed.
Click to expand it.
drivers/net/wireless/iwlwifi/iwl-core.c
浏览文件 @
db4148da
...
...
@@ -646,8 +646,14 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info)
struct
iwl_rxon_cmd
*
rxon
=
&
priv
->
staging_rxon
;
u32
val
;
if
(
!
ht_info
->
is_ht
)
if
(
!
ht_info
->
is_ht
)
{
rxon
->
flags
&=
~
(
RXON_FLG_CHANNEL_MODE_MIXED_MSK
|
RXON_FLG_CHANNEL_MODE_PURE_40_MSK
|
RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK
|
RXON_FLG_FAT_PROT_MSK
|
RXON_FLG_HT_PROT_MSK
);
return
;
}
/* Set up channel bandwidth: 20 MHz only, or 20/40 mixed if fat ok */
if
(
iwl_is_fat_tx_allowed
(
priv
,
NULL
))
...
...
@@ -697,8 +703,12 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info)
}
EXPORT_SYMBOL
(
iwl_set_rxon_ht
);
/*
* Determine how many receiver/antenna chains to use.
#define IWL_NUM_RX_CHAINS_MULTIPLE 3
#define IWL_NUM_RX_CHAINS_SINGLE 2
#define IWL_NUM_IDLE_CHAINS_DUAL 2
#define IWL_NUM_IDLE_CHAINS_SINGLE 1
/* Determine how many receiver/antenna chains to use.
* More provides better reception via diversity. Fewer saves power.
* MIMO (dual stream) requires at least 2, but works better with 3.
* This does not determine *which* chains to use, just how many.
...
...
@@ -711,9 +721,9 @@ static int iwl_get_active_rx_chain_count(struct iwl_priv *priv)
/* # of Rx chains to use when expecting MIMO. */
if
(
is_single
||
(
!
is_cam
&&
(
priv
->
current_ht_config
.
sm_ps
==
WLAN_HT_CAP_SM_PS_STATIC
)))
return
2
;
return
IWL_NUM_RX_CHAINS_SINGLE
;
else
return
3
;
return
IWL_NUM_RX_CHAINS_MULTIPLE
;
}
static
int
iwl_get_idle_rx_chain_count
(
struct
iwl_priv
*
priv
,
int
active_cnt
)
...
...
@@ -724,10 +734,11 @@ static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt)
switch
(
priv
->
current_ht_config
.
sm_ps
)
{
case
WLAN_HT_CAP_SM_PS_STATIC
:
case
WLAN_HT_CAP_SM_PS_DYNAMIC
:
idle_cnt
=
(
is_cam
)
?
2
:
1
;
idle_cnt
=
(
is_cam
)
?
IWL_NUM_IDLE_CHAINS_DUAL
:
IWL_NUM_IDLE_CHAINS_SINGLE
;
break
;
case
WLAN_HT_CAP_SM_PS_DISABLED
:
idle_cnt
=
(
is_cam
)
?
active_cnt
:
1
;
idle_cnt
=
(
is_cam
)
?
active_cnt
:
IWL_NUM_IDLE_CHAINS_SINGLE
;
break
;
case
WLAN_HT_CAP_SM_PS_INVALID
:
default:
...
...
@@ -796,7 +807,7 @@ void iwl_set_rxon_chain(struct iwl_priv *priv)
priv
->
staging_rxon
.
rx_chain
=
cpu_to_le16
(
rx_chain
);
if
(
!
is_single
&&
(
active_rx_cnt
>=
2
)
&&
is_cam
)
if
(
!
is_single
&&
(
active_rx_cnt
>=
IWL_NUM_RX_CHAINS_SINGLE
)
&&
is_cam
)
priv
->
staging_rxon
.
rx_chain
|=
RXON_RX_CHAIN_MIMO_FORCE_MSK
;
else
priv
->
staging_rxon
.
rx_chain
&=
~
RXON_RX_CHAIN_MIMO_FORCE_MSK
;
...
...
This diff is collapsed.
Click to expand it.
drivers/net/wireless/iwlwifi/iwl-scan.c
浏览文件 @
db4148da
...
...
@@ -463,11 +463,6 @@ void iwl_init_scan_params(struct iwl_priv *priv)
int
iwl_scan_initiate
(
struct
iwl_priv
*
priv
)
{
if
(
priv
->
iw_mode
==
NL80211_IFTYPE_AP
)
{
IWL_ERROR
(
"APs don't scan.
\n
"
);
return
0
;
}
if
(
!
iwl_is_ready_rf
(
priv
))
{
IWL_DEBUG_SCAN
(
"Aborting scan due to not ready.
\n
"
);
return
-
EIO
;
...
...
@@ -479,8 +474,7 @@ int iwl_scan_initiate(struct iwl_priv *priv)
}
if
(
test_bit
(
STATUS_SCAN_ABORTING
,
&
priv
->
status
))
{
IWL_DEBUG_SCAN
(
"Scan request while abort pending. "
"Queuing.
\n
"
);
IWL_DEBUG_SCAN
(
"Scan request while abort pending
\n
"
);
return
-
EAGAIN
;
}
...
...
This diff is collapsed.
Click to expand it.
drivers/net/wireless/iwlwifi/iwl-tx.c
浏览文件 @
db4148da
...
...
@@ -1200,10 +1200,9 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
/* If a Tx command is being handled and it isn't in the actual
* command queue then there a command routing bug has been introduced
* in the queue management code. */
if
(
txq_id
!=
IWL_CMD_QUEUE_NUM
)
IWL_ERROR
(
"Error wrong command queue %d command id 0x%X
\n
"
,
txq_id
,
pkt
->
hdr
.
cmd
);
BUG_ON
(
txq_id
!=
IWL_CMD_QUEUE_NUM
);
if
(
WARN
(
txq_id
!=
IWL_CMD_QUEUE_NUM
,
"wrong command queue %d, command id 0x%X
\n
"
,
txq_id
,
pkt
->
hdr
.
cmd
))
return
;
cmd_index
=
get_cmd_index
(
&
priv
->
txq
[
IWL_CMD_QUEUE_NUM
].
q
,
index
,
huge
);
cmd
=
priv
->
txq
[
IWL_CMD_QUEUE_NUM
].
cmd
[
cmd_index
];
...
...
This diff is collapsed.
Click to expand it.
drivers/net/wireless/iwlwifi/iwl3945-base.c
浏览文件 @
db4148da
...
...
@@ -7370,15 +7370,6 @@ static ssize_t show_temperature(struct device *d,
static
DEVICE_ATTR
(
temperature
,
S_IRUGO
,
show_temperature
,
NULL
);
static
ssize_t
show_rs_window
(
struct
device
*
d
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
struct
iwl3945_priv
*
priv
=
d
->
driver_data
;
return
iwl3945_fill_rs_info
(
priv
->
hw
,
buf
,
IWL_AP_ID
);
}
static
DEVICE_ATTR
(
rs_window
,
S_IRUGO
,
show_rs_window
,
NULL
);
static
ssize_t
show_tx_power
(
struct
device
*
d
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
...
...
@@ -7840,7 +7831,6 @@ static struct attribute *iwl3945_sysfs_entries[] = {
#endif
&
dev_attr_power_level
.
attr
,
&
dev_attr_retry_rate
.
attr
,
&
dev_attr_rs_window
.
attr
,
&
dev_attr_statistics
.
attr
,
&
dev_attr_status
.
attr
,
&
dev_attr_temperature
.
attr
,
...
...
@@ -7908,6 +7898,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
SET_IEEE80211_DEV
(
hw
,
&
pdev
->
dev
);
hw
->
rate_control_algorithm
=
"iwl-3945-rs"
;
hw
->
sta_data_size
=
sizeof
(
struct
iwl3945_sta_priv
);
IWL_DEBUG_INFO
(
"*** LOAD DRIVER ***
\n
"
);
priv
=
hw
->
priv
;
...
...
This diff is collapsed.
Click to expand it.
drivers/net/wireless/libertas/dev.h
浏览文件 @
db4148da
...
...
@@ -58,6 +58,7 @@ struct lbs_802_11_security {
u8
WPA2enabled
;
u8
wep_enabled
;
u8
auth_mode
;
u32
key_mgmt
;
};
/** Current Basic Service Set State Structure */
...
...
This diff is collapsed.
Click to expand it.
drivers/net/wireless/libertas/wext.c
浏览文件 @
db4148da
...
...
@@ -1598,8 +1598,20 @@ static int lbs_set_encodeext(struct net_device *dev,
}
out:
if
(
ret
==
0
)
{
/* key installation is time critical: postpone not! */
lbs_do_association_work
(
priv
);
if
(
ret
==
0
)
{
/* 802.1x and WPA rekeying must happen as quickly as possible,
* especially during the 4-way handshake; thus if in
* infrastructure mode, and either (a) 802.1x is enabled or
* (b) WPA is being used, set the key right away.
*/
if
(
assoc_req
->
mode
==
IW_MODE_INFRA
&&
((
assoc_req
->
secinfo
.
key_mgmt
&
IW_AUTH_KEY_MGMT_802_1X
)
||
(
assoc_req
->
secinfo
.
key_mgmt
&
IW_AUTH_KEY_MGMT_PSK
)
||
assoc_req
->
secinfo
.
WPAenabled
||
assoc_req
->
secinfo
.
WPA2enabled
))
{
lbs_do_association_work
(
priv
);
}
else
lbs_postpone_association_work
(
priv
);
}
else
{
lbs_cancel_association_work
(
priv
);
}
...
...
@@ -1707,13 +1719,17 @@ static int lbs_set_auth(struct net_device *dev,
case
IW_AUTH_TKIP_COUNTERMEASURES
:
case
IW_AUTH_CIPHER_PAIRWISE
:
case
IW_AUTH_CIPHER_GROUP
:
case
IW_AUTH_KEY_MGMT
:
case
IW_AUTH_DROP_UNENCRYPTED
:
/*
* libertas does not use these parameters
*/
break
;
case
IW_AUTH_KEY_MGMT
:
assoc_req
->
secinfo
.
key_mgmt
=
dwrq
->
value
;
updated
=
1
;
break
;
case
IW_AUTH_WPA_VERSION
:
if
(
dwrq
->
value
&
IW_AUTH_WPA_VERSION_DISABLED
)
{
assoc_req
->
secinfo
.
WPAenabled
=
0
;
...
...
@@ -1793,6 +1809,10 @@ static int lbs_get_auth(struct net_device *dev,
lbs_deb_enter
(
LBS_DEB_WEXT
);
switch
(
dwrq
->
flags
&
IW_AUTH_INDEX
)
{
case
IW_AUTH_KEY_MGMT
:
dwrq
->
value
=
priv
->
secinfo
.
key_mgmt
;
break
;
case
IW_AUTH_WPA_VERSION
:
dwrq
->
value
=
0
;
if
(
priv
->
secinfo
.
WPAenabled
)
...
...
This diff is collapsed.
Click to expand it.
drivers/net/wireless/netwave_cs.c
浏览文件 @
db4148da
...
...
@@ -398,7 +398,7 @@ static int netwave_probe(struct pcmcia_device *link)
link
->
io
.
IOAddrLines
=
5
;
/* Interrupt setup */
link
->
irq
.
Attributes
=
IRQ_TYPE_
EXCLUSIVE
|
IRQ_HANDLE_PRESENT
;
link
->
irq
.
Attributes
=
IRQ_TYPE_
DYNAMIC_SHARING
|
IRQ_HANDLE_PRESENT
;
link
->
irq
.
IRQInfo1
=
IRQ_LEVEL_ID
;
link
->
irq
.
Handler
=
&
netwave_interrupt
;
...
...
This diff is collapsed.
Click to expand it.
drivers/net/wireless/orinoco.c
浏览文件 @
db4148da
...
...
@@ -5291,7 +5291,7 @@ static int orinoco_ioctl_getrid(struct net_device *dev,
/* Trigger a scan (look for other cells in the vicinity) */
static
int
orinoco_ioctl_setscan
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
struct
iw_p
aram
*
srq
,
struct
iw_p
oint
*
srq
,
char
*
extra
)
{
struct
orinoco_private
*
priv
=
netdev_priv
(
dev
);
...
...
This diff is collapsed.
Click to expand it.
drivers/net/wireless/orinoco_cs.c
浏览文件 @
db4148da
...
...
@@ -121,7 +121,7 @@ orinoco_cs_probe(struct pcmcia_device *link)
link
->
priv
=
dev
;
/* Interrupt setup */
link
->
irq
.
Attributes
=
IRQ_TYPE_
EXCLUSIVE
|
IRQ_HANDLE_PRESENT
;
link
->
irq
.
Attributes
=
IRQ_TYPE_
DYNAMIC_SHARING
|
IRQ_HANDLE_PRESENT
;
link
->
irq
.
IRQInfo1
=
IRQ_LEVEL_ID
;
link
->
irq
.
Handler
=
orinoco_interrupt
;
link
->
irq
.
Instance
=
dev
;
...
...
This diff is collapsed.
Click to expand it.
drivers/net/wireless/ray_cs.c
浏览文件 @
db4148da
...
...
@@ -325,7 +325,7 @@ static int ray_probe(struct pcmcia_device *p_dev)
p_dev
->
io
.
IOAddrLines
=
5
;
/* Interrupt setup. For PCMCIA, driver takes what's given */
p_dev
->
irq
.
Attributes
=
IRQ_TYPE_
EXCLUSIVE
|
IRQ_HANDLE_PRESENT
;
p_dev
->
irq
.
Attributes
=
IRQ_TYPE_
DYNAMIC_SHARING
|
IRQ_HANDLE_PRESENT
;
p_dev
->
irq
.
IRQInfo1
=
IRQ_LEVEL_ID
;
p_dev
->
irq
.
Handler
=
&
ray_interrupt
;
...
...
This diff is collapsed.
Click to expand it.
drivers/net/wireless/rndis_wlan.c
浏览文件 @
db4148da
...
...
@@ -1627,7 +1627,6 @@ static int rndis_iw_set_encode_ext(struct net_device *dev,
static
int
rndis_iw_set_scan
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
union
iwreq_data
*
wrqu
,
char
*
extra
)
{
struct
iw_param
*
param
=
&
wrqu
->
param
;
struct
usbnet
*
usbdev
=
dev
->
priv
;
union
iwreq_data
evt
;
int
ret
=
-
EINVAL
;
...
...
@@ -1635,7 +1634,7 @@ static int rndis_iw_set_scan(struct net_device *dev,
devdbg
(
usbdev
,
"SIOCSIWSCAN"
);
if
(
param
->
flags
==
0
)
{
if
(
wrqu
->
data
.
flags
==
0
)
{
tmp
=
ccpu2
(
1
);
ret
=
rndis_set_oid
(
usbdev
,
OID_802_11_BSSID_LIST_SCAN
,
&
tmp
,
sizeof
(
tmp
));
...
...
This diff is collapsed.
Click to expand it.
drivers/net/wireless/rt2x00/rt2x00mac.c
浏览文件 @
db4148da
...
...
@@ -543,7 +543,8 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
* provided but key 0 is not, then the key is not found
* by the hardware during RX).
*/
key
->
hw_key_idx
=
0
;
if
(
cmd
==
SET_KEY
)
key
->
hw_key_idx
=
0
;
if
(
key
->
flags
&
IEEE80211_KEY_FLAG_PAIRWISE
)
set_key
=
rt2x00dev
->
ops
->
lib
->
config_pairwise_key
;
...
...
This diff is collapsed.
Click to expand it.
drivers/net/wireless/rt2x00/rt61pci.c
浏览文件 @
db4148da
...
...
@@ -381,7 +381,7 @@ static int rt61pci_config_shared_key(struct rt2x00_dev *rt2x00dev,
if
(
reg
&&
reg
==
mask
)
return
-
ENOSPC
;
key
->
hw_key_idx
+=
reg
?
(
ffz
(
reg
)
-
1
)
:
0
;
key
->
hw_key_idx
+=
reg
?
ffz
(
reg
)
:
0
;
/*
* Upload key to hardware
...
...
@@ -477,7 +477,7 @@ static int rt61pci_config_pairwise_key(struct rt2x00_dev *rt2x00dev,
return
-
ENOSPC
;
}
key
->
hw_key_idx
+=
reg
?
(
ffz
(
reg
)
-
1
)
:
0
;
key
->
hw_key_idx
+=
reg
?
ffz
(
reg
)
:
0
;
/*
* Upload key to hardware
...
...
This diff is collapsed.
Click to expand it.
drivers/net/wireless/rt2x00/rt73usb.c
浏览文件 @
db4148da
...
...
@@ -393,7 +393,7 @@ static int rt73usb_config_shared_key(struct rt2x00_dev *rt2x00dev,
if
(
reg
&&
reg
==
mask
)
return
-
ENOSPC
;
key
->
hw_key_idx
+=
reg
?
(
ffz
(
reg
)
-
1
)
:
0
;
key
->
hw_key_idx
+=
reg
?
ffz
(
reg
)
:
0
;
/*
* Upload key to hardware
...
...
@@ -494,7 +494,7 @@ static int rt73usb_config_pairwise_key(struct rt2x00_dev *rt2x00dev,
return
-
ENOSPC
;
}
key
->
hw_key_idx
+=
reg
?
(
ffz
(
reg
)
-
1
)
:
0
;
key
->
hw_key_idx
+=
reg
?
ffz
(
reg
)
:
0
;
/*
* Upload key to hardware
...
...
This diff is collapsed.
Click to expand it.
drivers/net/wireless/spectrum_cs.c
浏览文件 @
db4148da
...
...
@@ -195,7 +195,7 @@ spectrum_cs_probe(struct pcmcia_device *link)
link
->
priv
=
dev
;
/* Interrupt setup */
link
->
irq
.
Attributes
=
IRQ_TYPE_
EXCLUSIVE
|
IRQ_HANDLE_PRESENT
;
link
->
irq
.
Attributes
=
IRQ_TYPE_
DYNAMIC_SHARING
|
IRQ_HANDLE_PRESENT
;
link
->
irq
.
IRQInfo1
=
IRQ_LEVEL_ID
;
link
->
irq
.
Handler
=
orinoco_interrupt
;
link
->
irq
.
Instance
=
dev
;
...
...
This diff is collapsed.
Click to expand it.
drivers/net/wireless/wavelan_cs.c
浏览文件 @
db4148da
...
...
@@ -4496,7 +4496,7 @@ wavelan_probe(struct pcmcia_device *p_dev)
p_dev
->
io
.
IOAddrLines
=
3
;
/* Interrupt setup */
p_dev
->
irq
.
Attributes
=
IRQ_TYPE_
EXCLUSIVE
|
IRQ_HANDLE_PRESENT
;
p_dev
->
irq
.
Attributes
=
IRQ_TYPE_
DYNAMIC_SHARING
|
IRQ_HANDLE_PRESENT
;
p_dev
->
irq
.
IRQInfo1
=
IRQ_LEVEL_ID
;
p_dev
->
irq
.
Handler
=
wavelan_interrupt
;
...
...
This diff is collapsed.
Click to expand it.
drivers/net/wireless/wl3501_cs.c
浏览文件 @
db4148da
...
...
@@ -1917,7 +1917,7 @@ static int wl3501_probe(struct pcmcia_device *p_dev)
p_dev
->
io
.
IOAddrLines
=
5
;
/* Interrupt setup */
p_dev
->
irq
.
Attributes
=
IRQ_TYPE_
EXCLUSIVE
|
IRQ_HANDLE_PRESENT
;
p_dev
->
irq
.
Attributes
=
IRQ_TYPE_
DYNAMIC_SHARING
|
IRQ_HANDLE_PRESENT
;
p_dev
->
irq
.
IRQInfo1
=
IRQ_LEVEL_ID
;
p_dev
->
irq
.
Handler
=
wl3501_interrupt
;
...
...
This diff is collapsed.
Click to expand it.
include/linux/ieee80211.h
浏览文件 @
db4148da
...
...
@@ -471,6 +471,11 @@ struct ieee80211s_hdr {
u8
eaddr3
[
6
];
}
__attribute__
((
packed
));
/* Mesh flags */
#define MESH_FLAGS_AE_A4 0x1
#define MESH_FLAGS_AE_A5_A6 0x2
#define MESH_FLAGS_PS_DEEP 0x4
/**
* struct ieee80211_quiet_ie
*
...
...
This diff is collapsed.
Click to expand it.
include/net/cfg80211.h
浏览文件 @
db4148da
...
...
@@ -363,11 +363,13 @@ struct wiphy;
* wireless extensions but this is subject to reevaluation as soon as this
* code is used more widely and we have a first user without wext.
*
* @add_virtual_intf: create a new virtual interface with the given name
* @add_virtual_intf: create a new virtual interface with the given name,
* must set the struct wireless_dev's iftype.
*
* @del_virtual_intf: remove the virtual interface determined by ifindex.
*
* @change_virtual_intf: change type of virtual interface
* @change_virtual_intf: change type/configuration of virtual interface,
* keep the struct wireless_dev's iftype updated.
*
* @add_key: add a key with the given parameters. @mac_addr will be %NULL
* when adding a group key.
...
...
This diff is collapsed.
Click to expand it.
include/net/mac80211.h
浏览文件 @
db4148da
...
...
@@ -1800,4 +1800,72 @@ void ieee80211_notify_mac(struct ieee80211_hw *hw,
struct
ieee80211_sta
*
ieee80211_find_sta
(
struct
ieee80211_hw
*
hw
,
const
u8
*
addr
);
/* Rate control API */
/**
* struct rate_selection - rate information for/from rate control algorithms
*
* @rate_idx: selected transmission rate index
* @nonerp_idx: Non-ERP rate to use instead if ERP cannot be used
* @probe_idx: rate for probing (or -1)
* @max_rate_idx: maximum rate index that can be used, this is
* input to the algorithm and will be enforced
*/
struct
rate_selection
{
s8
rate_idx
,
nonerp_idx
,
probe_idx
,
max_rate_idx
;
};
struct
rate_control_ops
{
struct
module
*
module
;
const
char
*
name
;
void
*
(
*
alloc
)(
struct
ieee80211_hw
*
hw
,
struct
dentry
*
debugfsdir
);
void
(
*
clear
)(
void
*
priv
);
void
(
*
free
)(
void
*
priv
);
void
*
(
*
alloc_sta
)(
void
*
priv
,
struct
ieee80211_sta
*
sta
,
gfp_t
gfp
);
void
(
*
rate_init
)(
void
*
priv
,
struct
ieee80211_supported_band
*
sband
,
struct
ieee80211_sta
*
sta
,
void
*
priv_sta
);
void
(
*
free_sta
)(
void
*
priv
,
struct
ieee80211_sta
*
sta
,
void
*
priv_sta
);
void
(
*
tx_status
)(
void
*
priv
,
struct
ieee80211_supported_band
*
sband
,
struct
ieee80211_sta
*
sta
,
void
*
priv_sta
,
struct
sk_buff
*
skb
);
void
(
*
get_rate
)(
void
*
priv
,
struct
ieee80211_supported_band
*
sband
,
struct
ieee80211_sta
*
sta
,
void
*
priv_sta
,
struct
sk_buff
*
skb
,
struct
rate_selection
*
sel
);
void
(
*
add_sta_debugfs
)(
void
*
priv
,
void
*
priv_sta
,
struct
dentry
*
dir
);
void
(
*
remove_sta_debugfs
)(
void
*
priv
,
void
*
priv_sta
);
};
static
inline
int
rate_supported
(
struct
ieee80211_sta
*
sta
,
enum
ieee80211_band
band
,
int
index
)
{
return
(
sta
==
NULL
||
sta
->
supp_rates
[
band
]
&
BIT
(
index
));
}
static
inline
s8
rate_lowest_index
(
struct
ieee80211_supported_band
*
sband
,
struct
ieee80211_sta
*
sta
)
{
int
i
;
for
(
i
=
0
;
i
<
sband
->
n_bitrates
;
i
++
)
if
(
rate_supported
(
sta
,
sband
->
band
,
i
))
return
i
;
/* warn when we cannot find a rate. */
WARN_ON
(
1
);
return
0
;
}
int
ieee80211_rate_control_register
(
struct
rate_control_ops
*
ops
);
void
ieee80211_rate_control_unregister
(
struct
rate_control_ops
*
ops
);
#endif
/* MAC80211_H */
This diff is collapsed.
Click to expand it.
include/net/wireless.h
浏览文件 @
db4148da
...
...
@@ -223,9 +223,11 @@ struct wiphy {
* the netdev.)
*
* @wiphy: pointer to hardware description
* @iftype: interface type
*/
struct
wireless_dev
{
struct
wiphy
*
wiphy
;
enum
nl80211_iftype
iftype
;
/* private to the generic wireless code */
struct
list_head
list
;
...
...
@@ -328,6 +330,15 @@ extern int ieee80211_frequency_to_channel(int freq);
*/
extern
struct
ieee80211_channel
*
__ieee80211_get_channel
(
struct
wiphy
*
wiphy
,
int
freq
);
/**
* ieee80211_get_channel - get channel struct from wiphy for specified frequency
*/
static
inline
struct
ieee80211_channel
*
ieee80211_get_channel
(
struct
wiphy
*
wiphy
,
int
freq
)
{
return
__ieee80211_get_channel
(
wiphy
,
freq
);
}
/**
* __regulatory_hint - hint to the wireless core a regulatory domain
* @wiphy: if a driver is providing the hint this is the driver's very
...
...
@@ -380,13 +391,4 @@ extern int __regulatory_hint(struct wiphy *wiphy, enum reg_set_by set_by,
*/
extern
int
regulatory_hint
(
struct
wiphy
*
wiphy
,
const
char
*
alpha2
,
struct
ieee80211_regdomain
*
rd
);
/**
* ieee80211_get_channel - get channel struct from wiphy for specified frequency
*/
static
inline
struct
ieee80211_channel
*
ieee80211_get_channel
(
struct
wiphy
*
wiphy
,
int
freq
)
{
return
__ieee80211_get_channel
(
wiphy
,
freq
);
}
#endif
/* __NET_WIRELESS_H */
This diff is collapsed.
Click to expand it.
net/mac80211/cfg.c
浏览文件 @
db4148da
...
...
@@ -82,7 +82,6 @@ static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex,
enum
nl80211_iftype
type
,
u32
*
flags
,
struct
vif_params
*
params
)
{
struct
ieee80211_local
*
local
=
wiphy_priv
(
wiphy
);
struct
net_device
*
dev
;
struct
ieee80211_sub_if_data
*
sdata
;
int
ret
;
...
...
@@ -95,15 +94,15 @@ static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex,
if
(
!
nl80211_type_check
(
type
))
return
-
EINVAL
;
if
(
dev
==
local
->
mdev
)
return
-
EOPNOTSUPP
;
sdata
=
IEEE80211_DEV_TO_SUB_IF
(
dev
);
ret
=
ieee80211_if_change_type
(
sdata
,
type
);
if
(
ret
)
return
ret
;
if
(
netif_running
(
sdata
->
dev
))
return
-
EBUSY
;
if
(
ieee80211_vif_is_mesh
(
&
sdata
->
vif
)
&&
params
->
mesh_id_len
)
ieee80211_sdata_set_mesh_id
(
sdata
,
params
->
mesh_id_len
,
...
...
@@ -120,16 +119,12 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
u8
key_idx
,
u8
*
mac_addr
,
struct
key_params
*
params
)
{
struct
ieee80211_local
*
local
=
wiphy_priv
(
wiphy
);
struct
ieee80211_sub_if_data
*
sdata
;
struct
sta_info
*
sta
=
NULL
;
enum
ieee80211_key_alg
alg
;
struct
ieee80211_key
*
key
;
int
err
;
if
(
dev
==
local
->
mdev
)
return
-
EOPNOTSUPP
;
sdata
=
IEEE80211_DEV_TO_SUB_IF
(
dev
);
switch
(
params
->
cipher
)
{
...
...
@@ -174,14 +169,10 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
static
int
ieee80211_del_key
(
struct
wiphy
*
wiphy
,
struct
net_device
*
dev
,
u8
key_idx
,
u8
*
mac_addr
)
{
struct
ieee80211_local
*
local
=
wiphy_priv
(
wiphy
);
struct
ieee80211_sub_if_data
*
sdata
;
struct
sta_info
*
sta
;
int
ret
;
if
(
dev
==
local
->
mdev
)
return
-
EOPNOTSUPP
;
sdata
=
IEEE80211_DEV_TO_SUB_IF
(
dev
);
rcu_read_lock
();
...
...
@@ -222,7 +213,6 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
void
(
*
callback
)(
void
*
cookie
,
struct
key_params
*
params
))
{
struct
ieee80211_local
*
local
=
wiphy_priv
(
wiphy
);
struct
ieee80211_sub_if_data
*
sdata
;
struct
sta_info
*
sta
=
NULL
;
u8
seq
[
6
]
=
{
0
};
...
...
@@ -232,9 +222,6 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
u16
iv16
;
int
err
=
-
ENOENT
;
if
(
dev
==
local
->
mdev
)
return
-
EOPNOTSUPP
;
sdata
=
IEEE80211_DEV_TO_SUB_IF
(
dev
);
rcu_read_lock
();
...
...
@@ -310,12 +297,8 @@ static int ieee80211_config_default_key(struct wiphy *wiphy,
struct
net_device
*
dev
,
u8
key_idx
)
{
struct
ieee80211_local
*
local
=
wiphy_priv
(
wiphy
);
struct
ieee80211_sub_if_data
*
sdata
;
if
(
dev
==
local
->
mdev
)
return
-
EOPNOTSUPP
;
rcu_read_lock
();
sdata
=
IEEE80211_DEV_TO_SUB_IF
(
dev
);
...
...
@@ -496,13 +479,9 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
static
int
ieee80211_add_beacon
(
struct
wiphy
*
wiphy
,
struct
net_device
*
dev
,
struct
beacon_parameters
*
params
)
{
struct
ieee80211_local
*
local
=
wiphy_priv
(
wiphy
);
struct
ieee80211_sub_if_data
*
sdata
;
struct
beacon_data
*
old
;
if
(
dev
==
local
->
mdev
)
return
-
EOPNOTSUPP
;
sdata
=
IEEE80211_DEV_TO_SUB_IF
(
dev
);
if
(
sdata
->
vif
.
type
!=
NL80211_IFTYPE_AP
)
...
...
@@ -519,13 +498,9 @@ static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev,
static
int
ieee80211_set_beacon
(
struct
wiphy
*
wiphy
,
struct
net_device
*
dev
,
struct
beacon_parameters
*
params
)
{
struct
ieee80211_local
*
local
=
wiphy_priv
(
wiphy
);
struct
ieee80211_sub_if_data
*
sdata
;
struct
beacon_data
*
old
;
if
(
dev
==
local
->
mdev
)
return
-
EOPNOTSUPP
;
sdata
=
IEEE80211_DEV_TO_SUB_IF
(
dev
);
if
(
sdata
->
vif
.
type
!=
NL80211_IFTYPE_AP
)
...
...
@@ -541,13 +516,9 @@ static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
static
int
ieee80211_del_beacon
(
struct
wiphy
*
wiphy
,
struct
net_device
*
dev
)
{
struct
ieee80211_local
*
local
=
wiphy_priv
(
wiphy
);
struct
ieee80211_sub_if_data
*
sdata
;
struct
beacon_data
*
old
;
if
(
dev
==
local
->
mdev
)
return
-
EOPNOTSUPP
;
sdata
=
IEEE80211_DEV_TO_SUB_IF
(
dev
);
if
(
sdata
->
vif
.
type
!=
NL80211_IFTYPE_AP
)
...
...
@@ -695,9 +666,6 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
struct
ieee80211_sub_if_data
*
sdata
;
int
err
;
if
(
dev
==
local
->
mdev
||
params
->
vlan
==
local
->
mdev
)
return
-
EOPNOTSUPP
;
/* Prevent a race with changing the rate control algorithm */
if
(
!
netif_running
(
dev
))
return
-
ENETDOWN
;
...
...
@@ -725,7 +693,7 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
sta_apply_parameters
(
local
,
sta
,
params
);
rate_control_rate_init
(
sta
,
local
);
rate_control_rate_init
(
sta
);
rcu_read_lock
();
...
...
@@ -752,9 +720,6 @@ static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev,
struct
ieee80211_sub_if_data
*
sdata
;
struct
sta_info
*
sta
;
if
(
dev
==
local
->
mdev
)
return
-
EOPNOTSUPP
;
sdata
=
IEEE80211_DEV_TO_SUB_IF
(
dev
);
if
(
mac
)
{
...
...
@@ -786,9 +751,6 @@ static int ieee80211_change_station(struct wiphy *wiphy,
struct
sta_info
*
sta
;
struct
ieee80211_sub_if_data
*
vlansdata
;
if
(
dev
==
local
->
mdev
||
params
->
vlan
==
local
->
mdev
)
return
-
EOPNOTSUPP
;
rcu_read_lock
();
/* XXX: get sta belonging to dev */
...
...
@@ -828,9 +790,6 @@ static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev,
struct
sta_info
*
sta
;
int
err
;
if
(
dev
==
local
->
mdev
)
return
-
EOPNOTSUPP
;
if
(
!
netif_running
(
dev
))
return
-
ENETDOWN
;
...
...
@@ -884,9 +843,6 @@ static int ieee80211_change_mpath(struct wiphy *wiphy,
struct
mesh_path
*
mpath
;
struct
sta_info
*
sta
;
if
(
dev
==
local
->
mdev
)
return
-
EOPNOTSUPP
;
if
(
!
netif_running
(
dev
))
return
-
ENETDOWN
;
...
...
@@ -958,13 +914,9 @@ static int ieee80211_get_mpath(struct wiphy *wiphy, struct net_device *dev,
u8
*
dst
,
u8
*
next_hop
,
struct
mpath_info
*
pinfo
)
{
struct
ieee80211_local
*
local
=
wiphy_priv
(
wiphy
);
struct
ieee80211_sub_if_data
*
sdata
;
struct
mesh_path
*
mpath
;
if
(
dev
==
local
->
mdev
)
return
-
EOPNOTSUPP
;
sdata
=
IEEE80211_DEV_TO_SUB_IF
(
dev
);
if
(
sdata
->
vif
.
type
!=
NL80211_IFTYPE_MESH_POINT
)
...
...
@@ -986,13 +938,9 @@ static int ieee80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev,
int
idx
,
u8
*
dst
,
u8
*
next_hop
,
struct
mpath_info
*
pinfo
)
{
struct
ieee80211_local
*
local
=
wiphy_priv
(
wiphy
);
struct
ieee80211_sub_if_data
*
sdata
;
struct
mesh_path
*
mpath
;
if
(
dev
==
local
->
mdev
)
return
-
EOPNOTSUPP
;
sdata
=
IEEE80211_DEV_TO_SUB_IF
(
dev
);
if
(
sdata
->
vif
.
type
!=
NL80211_IFTYPE_MESH_POINT
)
...
...
@@ -1015,13 +963,9 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
struct
net_device
*
dev
,
struct
bss_parameters
*
params
)
{
struct
ieee80211_local
*
local
=
wiphy_priv
(
wiphy
);
struct
ieee80211_sub_if_data
*
sdata
;
u32
changed
=
0
;
if
(
dev
==
local
->
mdev
)
return
-
EOPNOTSUPP
;
sdata
=
IEEE80211_DEV_TO_SUB_IF
(
dev
);
if
(
sdata
->
vif
.
type
!=
NL80211_IFTYPE_AP
)
...
...
This diff is collapsed.
Click to expand it.
net/mac80211/debugfs_sta.c
浏览文件 @
db4148da
...
...
@@ -173,8 +173,7 @@ static ssize_t sta_agg_status_write(struct file *file,
const
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
sta_info
*
sta
=
file
->
private_data
;
struct
net_device
*
dev
=
sta
->
sdata
->
dev
;
struct
ieee80211_local
*
local
=
wdev_priv
(
dev
->
ieee80211_ptr
);
struct
ieee80211_local
*
local
=
sta
->
sdata
->
local
;
struct
ieee80211_hw
*
hw
=
&
local
->
hw
;
u8
*
da
=
sta
->
sta
.
addr
;
static
int
tid_static_tx
[
16
]
=
{
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
...
...
This diff is collapsed.
Click to expand it.
net/mac80211/ieee80211_i.h
浏览文件 @
db4148da
...
...
@@ -573,6 +573,10 @@ enum {
/* maximum number of hardware queues we support. */
#define QD_MAX_QUEUES (IEEE80211_MAX_AMPDU_QUEUES + IEEE80211_MAX_QUEUES)
struct
ieee80211_master_priv
{
struct
ieee80211_local
*
local
;
};
struct
ieee80211_local
{
/* embed the driver visible part.
* don't cast (use the static inlines below), but we keep
...
...
@@ -720,6 +724,8 @@ struct ieee80211_local {
#ifdef CONFIG_MAC80211_DEBUGFS
struct
local_debugfsdentries
{
struct
dentry
*
rcdir
;
struct
dentry
*
rcname
;
struct
dentry
*
frequency
;
struct
dentry
*
antenna_sel_tx
;
struct
dentry
*
antenna_sel_rx
;
...
...
This diff is collapsed.
Click to expand it.
net/mac80211/iface.c
浏览文件 @
db4148da
...
...
@@ -625,6 +625,7 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
/* and set some type-dependent values */
sdata
->
vif
.
type
=
type
;
sdata
->
dev
->
hard_start_xmit
=
ieee80211_subif_start_xmit
;
sdata
->
wdev
.
iftype
=
type
;
/* only monitor differs */
sdata
->
dev
->
type
=
ARPHRD_ETHER
;
...
...
This diff is collapsed.
Click to expand it.
net/mac80211/main.c
浏览文件 @
db4148da
...
...
@@ -106,7 +106,8 @@ static const struct header_ops ieee80211_header_ops = {
static
int
ieee80211_master_open
(
struct
net_device
*
dev
)
{
struct
ieee80211_local
*
local
=
wdev_priv
(
dev
->
ieee80211_ptr
);
struct
ieee80211_master_priv
*
mpriv
=
netdev_priv
(
dev
);
struct
ieee80211_local
*
local
=
mpriv
->
local
;
struct
ieee80211_sub_if_data
*
sdata
;
int
res
=
-
EOPNOTSUPP
;
...
...
@@ -128,7 +129,8 @@ static int ieee80211_master_open(struct net_device *dev)
static
int
ieee80211_master_stop
(
struct
net_device
*
dev
)
{
struct
ieee80211_local
*
local
=
wdev_priv
(
dev
->
ieee80211_ptr
);
struct
ieee80211_master_priv
*
mpriv
=
netdev_priv
(
dev
);
struct
ieee80211_local
*
local
=
mpriv
->
local
;
struct
ieee80211_sub_if_data
*
sdata
;
/* we hold the RTNL here so can safely walk the list */
...
...
@@ -141,7 +143,8 @@ static int ieee80211_master_stop(struct net_device *dev)
static
void
ieee80211_master_set_multicast_list
(
struct
net_device
*
dev
)
{
struct
ieee80211_local
*
local
=
wdev_priv
(
dev
->
ieee80211_ptr
);
struct
ieee80211_master_priv
*
mpriv
=
netdev_priv
(
dev
);
struct
ieee80211_local
*
local
=
mpriv
->
local
;
ieee80211_configure_filter
(
local
);
}
...
...
@@ -539,6 +542,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
struct
ieee80211_tx_info
*
info
=
IEEE80211_SKB_CB
(
skb
);
u16
frag
,
type
;
__le16
fc
;
struct
ieee80211_supported_band
*
sband
;
struct
ieee80211_tx_status_rtap_hdr
*
rthdr
;
struct
ieee80211_sub_if_data
*
sdata
;
struct
net_device
*
prev_dev
=
NULL
;
...
...
@@ -585,7 +589,8 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
sta
->
tx_retry_count
+=
info
->
status
.
retry_count
;
}
rate_control_tx_status
(
local
->
mdev
,
skb
);
sband
=
local
->
hw
.
wiphy
->
bands
[
info
->
band
];
rate_control_tx_status
(
local
,
sband
,
sta
,
skb
);
}
rcu_read_unlock
();
...
...
@@ -787,7 +792,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
int
result
;
enum
ieee80211_band
band
;
struct
net_device
*
mdev
;
struct
wireless_dev
*
mwde
v
;
struct
ieee80211_master_priv
*
mpri
v
;
/*
* generic code guarantees at least one band,
...
...
@@ -829,16 +834,14 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
if
(
hw
->
queues
<
4
)
hw
->
ampdu_queues
=
0
;
mdev
=
alloc_netdev_mq
(
sizeof
(
struct
wireless_de
v
),
mdev
=
alloc_netdev_mq
(
sizeof
(
struct
ieee80211_master_pri
v
),
"wmaster%d"
,
ether_setup
,
ieee80211_num_queues
(
hw
));
if
(
!
mdev
)
goto
fail_mdev_alloc
;
mwdev
=
netdev_priv
(
mdev
);
mdev
->
ieee80211_ptr
=
mwdev
;
mwdev
->
wiphy
=
local
->
hw
.
wiphy
;
mpriv
=
netdev_priv
(
mdev
);
mpriv
->
local
=
local
;
local
->
mdev
=
mdev
;
ieee80211_rx_bss_list_init
(
local
);
...
...
This diff is collapsed.
Click to expand it.
net/mac80211/mesh.c
浏览文件 @
db4148da
...
...
@@ -351,7 +351,7 @@ static void ieee80211_mesh_path_timer(unsigned long data)
struct
ieee80211_sub_if_data
*
sdata
=
(
struct
ieee80211_sub_if_data
*
)
data
;
struct
ieee80211_if_mesh
*
ifmsh
=
&
sdata
->
u
.
mesh
;
struct
ieee80211_local
*
local
=
wdev_priv
(
&
sdata
->
wdev
)
;
struct
ieee80211_local
*
local
=
sdata
->
local
;
queue_work
(
local
->
hw
.
workqueue
,
&
ifmsh
->
work
);
}
...
...
This diff is collapsed.
Click to expand it.
net/mac80211/mesh.h
浏览文件 @
db4148da
...
...
@@ -71,6 +71,7 @@ enum mesh_path_flags {
*/
struct
mesh_path
{
u8
dst
[
ETH_ALEN
];
u8
mpp
[
ETH_ALEN
];
/* used for MPP or MAP */
struct
ieee80211_sub_if_data
*
sdata
;
struct
sta_info
*
next_hop
;
struct
timer_list
timer
;
...
...
@@ -226,6 +227,9 @@ int mesh_nexthop_lookup(struct sk_buff *skb,
void
mesh_path_start_discovery
(
struct
ieee80211_sub_if_data
*
sdata
);
struct
mesh_path
*
mesh_path_lookup
(
u8
*
dst
,
struct
ieee80211_sub_if_data
*
sdata
);
struct
mesh_path
*
mpp_path_lookup
(
u8
*
dst
,
struct
ieee80211_sub_if_data
*
sdata
);
int
mpp_path_add
(
u8
*
dst
,
u8
*
mpp
,
struct
ieee80211_sub_if_data
*
sdata
);
struct
mesh_path
*
mesh_path_lookup_by_idx
(
int
idx
,
struct
ieee80211_sub_if_data
*
sdata
);
void
mesh_path_fix_nexthop
(
struct
mesh_path
*
mpath
,
struct
sta_info
*
next_hop
);
...
...
This diff is collapsed.
Click to expand it.
net/mac80211/mesh_pathtbl.c
浏览文件 @
db4148da
...
...
@@ -36,6 +36,7 @@ struct mpath_node {
};
static
struct
mesh_table
*
mesh_paths
;
static
struct
mesh_table
*
mpp_paths
;
/* Store paths for MPP&MAP */
/* This lock will have the grow table function as writer and add / delete nodes
* as readers. When reading the table (i.e. doing lookups) we are well protected
...
...
@@ -94,6 +95,34 @@ struct mesh_path *mesh_path_lookup(u8 *dst, struct ieee80211_sub_if_data *sdata)
return
NULL
;
}
struct
mesh_path
*
mpp_path_lookup
(
u8
*
dst
,
struct
ieee80211_sub_if_data
*
sdata
)
{
struct
mesh_path
*
mpath
;
struct
hlist_node
*
n
;
struct
hlist_head
*
bucket
;
struct
mesh_table
*
tbl
;
struct
mpath_node
*
node
;
tbl
=
rcu_dereference
(
mpp_paths
);
bucket
=
&
tbl
->
hash_buckets
[
mesh_table_hash
(
dst
,
sdata
,
tbl
)];
hlist_for_each_entry_rcu
(
node
,
n
,
bucket
,
list
)
{
mpath
=
node
->
mpath
;
if
(
mpath
->
sdata
==
sdata
&&
memcmp
(
dst
,
mpath
->
dst
,
ETH_ALEN
)
==
0
)
{
if
(
MPATH_EXPIRED
(
mpath
))
{
spin_lock_bh
(
&
mpath
->
state_lock
);
if
(
MPATH_EXPIRED
(
mpath
))
mpath
->
flags
&=
~
MESH_PATH_ACTIVE
;
spin_unlock_bh
(
&
mpath
->
state_lock
);
}
return
mpath
;
}
}
return
NULL
;
}
/**
* mesh_path_lookup_by_idx - look up a path in the mesh path table by its index
* @idx: index
...
...
@@ -226,6 +255,91 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata)
}
int
mpp_path_add
(
u8
*
dst
,
u8
*
mpp
,
struct
ieee80211_sub_if_data
*
sdata
)
{
struct
mesh_path
*
mpath
,
*
new_mpath
;
struct
mpath_node
*
node
,
*
new_node
;
struct
hlist_head
*
bucket
;
struct
hlist_node
*
n
;
int
grow
=
0
;
int
err
=
0
;
u32
hash_idx
;
if
(
memcmp
(
dst
,
sdata
->
dev
->
dev_addr
,
ETH_ALEN
)
==
0
)
/* never add ourselves as neighbours */
return
-
ENOTSUPP
;
if
(
is_multicast_ether_addr
(
dst
))
return
-
ENOTSUPP
;
err
=
-
ENOMEM
;
new_mpath
=
kzalloc
(
sizeof
(
struct
mesh_path
),
GFP_KERNEL
);
if
(
!
new_mpath
)
goto
err_path_alloc
;
new_node
=
kmalloc
(
sizeof
(
struct
mpath_node
),
GFP_KERNEL
);
if
(
!
new_node
)
goto
err_node_alloc
;
read_lock
(
&
pathtbl_resize_lock
);
memcpy
(
new_mpath
->
dst
,
dst
,
ETH_ALEN
);
memcpy
(
new_mpath
->
mpp
,
mpp
,
ETH_ALEN
);
new_mpath
->
sdata
=
sdata
;
new_mpath
->
flags
=
0
;
skb_queue_head_init
(
&
new_mpath
->
frame_queue
);
new_node
->
mpath
=
new_mpath
;
new_mpath
->
exp_time
=
jiffies
;
spin_lock_init
(
&
new_mpath
->
state_lock
);
hash_idx
=
mesh_table_hash
(
dst
,
sdata
,
mpp_paths
);
bucket
=
&
mpp_paths
->
hash_buckets
[
hash_idx
];
spin_lock
(
&
mpp_paths
->
hashwlock
[
hash_idx
]);
err
=
-
EEXIST
;
hlist_for_each_entry
(
node
,
n
,
bucket
,
list
)
{
mpath
=
node
->
mpath
;
if
(
mpath
->
sdata
==
sdata
&&
memcmp
(
dst
,
mpath
->
dst
,
ETH_ALEN
)
==
0
)
goto
err_exists
;
}
hlist_add_head_rcu
(
&
new_node
->
list
,
bucket
);
if
(
atomic_inc_return
(
&
mpp_paths
->
entries
)
>=
mpp_paths
->
mean_chain_len
*
(
mpp_paths
->
hash_mask
+
1
))
grow
=
1
;
spin_unlock
(
&
mpp_paths
->
hashwlock
[
hash_idx
]);
read_unlock
(
&
pathtbl_resize_lock
);
if
(
grow
)
{
struct
mesh_table
*
oldtbl
,
*
newtbl
;
write_lock
(
&
pathtbl_resize_lock
);
oldtbl
=
mpp_paths
;
newtbl
=
mesh_table_grow
(
mpp_paths
);
if
(
!
newtbl
)
{
write_unlock
(
&
pathtbl_resize_lock
);
return
0
;
}
rcu_assign_pointer
(
mpp_paths
,
newtbl
);
write_unlock
(
&
pathtbl_resize_lock
);
synchronize_rcu
();
mesh_table_free
(
oldtbl
,
false
);
}
return
0
;
err_exists:
spin_unlock
(
&
mpp_paths
->
hashwlock
[
hash_idx
]);
read_unlock
(
&
pathtbl_resize_lock
);
kfree
(
new_node
);
err_node_alloc:
kfree
(
new_mpath
);
err_path_alloc:
return
err
;
}
/**
* mesh_plink_broken - deactivates paths and sends perr when a link breaks
*
...
...
@@ -475,11 +589,21 @@ static int mesh_path_node_copy(struct hlist_node *p, struct mesh_table *newtbl)
int
mesh_pathtbl_init
(
void
)
{
mesh_paths
=
mesh_table_alloc
(
INIT_PATHS_SIZE_ORDER
);
if
(
!
mesh_paths
)
return
-
ENOMEM
;
mesh_paths
->
free_node
=
&
mesh_path_node_free
;
mesh_paths
->
copy_node
=
&
mesh_path_node_copy
;
mesh_paths
->
mean_chain_len
=
MEAN_CHAIN_LEN
;
if
(
!
mesh_paths
)
mpp_paths
=
mesh_table_alloc
(
INIT_PATHS_SIZE_ORDER
);
if
(
!
mpp_paths
)
{
mesh_table_free
(
mesh_paths
,
true
);
return
-
ENOMEM
;
}
mpp_paths
->
free_node
=
&
mesh_path_node_free
;
mpp_paths
->
copy_node
=
&
mesh_path_node_copy
;
mpp_paths
->
mean_chain_len
=
MEAN_CHAIN_LEN
;
return
0
;
}
...
...
@@ -511,4 +635,5 @@ void mesh_path_expire(struct ieee80211_sub_if_data *sdata)
void
mesh_pathtbl_unregister
(
void
)
{
mesh_table_free
(
mesh_paths
,
true
);
mesh_table_free
(
mpp_paths
,
true
);
}
This diff is collapsed.
Click to expand it.
net/mac80211/mlme.c
浏览文件 @
db4148da
...
...
@@ -942,8 +942,8 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata,
disassoc
=
1
;
}
else
ieee80211_send_probe_req
(
sdata
,
ifsta
->
bssid
,
local
->
scan_
ssid
,
local
->
scan_
ssid_len
);
ifsta
->
ssid
,
ifsta
->
ssid_len
);
ifsta
->
flags
^=
IEEE80211_STA_PROBEREQ_POLL
;
}
else
{
ifsta
->
flags
&=
~
IEEE80211_STA_PROBEREQ_POLL
;
...
...
@@ -1323,7 +1323,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
ieee80211_handle_ht
(
local
,
1
,
&
sta
->
sta
.
ht_info
,
&
bss_info
);
}
rate_control_rate_init
(
sta
,
local
);
rate_control_rate_init
(
sta
);
if
(
elems
.
wmm_param
)
{
set_sta_flags
(
sta
,
WLAN_STA_WME
);
...
...
@@ -1452,6 +1452,8 @@ static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
ifsta
->
state
=
IEEE80211_STA_MLME_IBSS_JOINED
;
mod_timer
(
&
ifsta
->
timer
,
jiffies
+
IEEE80211_IBSS_MERGE_INTERVAL
);
ieee80211_led_assoc
(
local
,
true
);
memset
(
&
wrqu
,
0
,
sizeof
(
wrqu
));
memcpy
(
wrqu
.
ap_addr
.
sa_data
,
bss
->
bssid
,
ETH_ALEN
);
wireless_send_event
(
sdata
->
dev
,
SIOCGIWAP
,
&
wrqu
,
NULL
);
...
...
@@ -2342,7 +2344,7 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
sta
->
sta
.
supp_rates
[
band
]
=
supp_rates
|
ieee80211_mandatory_rates
(
local
,
band
);
rate_control_rate_init
(
sta
,
local
);
rate_control_rate_init
(
sta
);
if
(
sta_info_insert
(
sta
))
return
NULL
;
...
...
This diff is collapsed.
Click to expand it.
net/mac80211/rate.c
浏览文件 @
db4148da
...
...
@@ -12,6 +12,7 @@
#include <linux/rtnetlink.h>
#include "rate.h"
#include "ieee80211_i.h"
#include "debugfs.h"
struct
rate_control_alg
{
struct
list_head
list
;
...
...
@@ -127,19 +128,46 @@ static void ieee80211_rate_control_ops_put(struct rate_control_ops *ops)
module_put
(
ops
->
module
);
}
#ifdef CONFIG_MAC80211_DEBUGFS
static
ssize_t
rcname_read
(
struct
file
*
file
,
char
__user
*
userbuf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
rate_control_ref
*
ref
=
file
->
private_data
;
int
len
=
strlen
(
ref
->
ops
->
name
);
return
simple_read_from_buffer
(
userbuf
,
count
,
ppos
,
ref
->
ops
->
name
,
len
);
}
static
const
struct
file_operations
rcname_ops
=
{
.
read
=
rcname_read
,
.
open
=
mac80211_open_file_generic
,
};
#endif
struct
rate_control_ref
*
rate_control_alloc
(
const
char
*
name
,
struct
ieee80211_local
*
local
)
{
struct
dentry
*
debugfsdir
=
NULL
;
struct
rate_control_ref
*
ref
;
ref
=
kmalloc
(
sizeof
(
struct
rate_control_ref
),
GFP_KERNEL
);
if
(
!
ref
)
goto
fail_ref
;
kref_init
(
&
ref
->
kref
);
ref
->
local
=
local
;
ref
->
ops
=
ieee80211_rate_control_ops_get
(
name
);
if
(
!
ref
->
ops
)
goto
fail_ops
;
ref
->
priv
=
ref
->
ops
->
alloc
(
local
);
#ifdef CONFIG_MAC80211_DEBUGFS
debugfsdir
=
debugfs_create_dir
(
"rc"
,
local
->
hw
.
wiphy
->
debugfsdir
);
local
->
debugfs
.
rcdir
=
debugfsdir
;
local
->
debugfs
.
rcname
=
debugfs_create_file
(
"name"
,
0400
,
debugfsdir
,
ref
,
&
rcname_ops
);
#endif
ref
->
priv
=
ref
->
ops
->
alloc
(
&
local
->
hw
,
debugfsdir
);
if
(
!
ref
->
priv
)
goto
fail_priv
;
return
ref
;
...
...
@@ -158,29 +186,46 @@ static void rate_control_release(struct kref *kref)
ctrl_ref
=
container_of
(
kref
,
struct
rate_control_ref
,
kref
);
ctrl_ref
->
ops
->
free
(
ctrl_ref
->
priv
);
#ifdef CONFIG_MAC80211_DEBUGFS
debugfs_remove
(
ctrl_ref
->
local
->
debugfs
.
rcname
);
ctrl_ref
->
local
->
debugfs
.
rcname
=
NULL
;
debugfs_remove
(
ctrl_ref
->
local
->
debugfs
.
rcdir
);
ctrl_ref
->
local
->
debugfs
.
rcdir
=
NULL
;
#endif
ieee80211_rate_control_ops_put
(
ctrl_ref
->
ops
);
kfree
(
ctrl_ref
);
}
void
rate_control_get_rate
(
struct
net_device
*
dev
,
void
rate_control_get_rate
(
struct
ieee80211_sub_if_data
*
sdata
,
struct
ieee80211_supported_band
*
sband
,
struct
sk_buff
*
skb
,
struct
s
ta_info
*
sta
,
struct
s
k_buff
*
skb
,
struct
rate_selection
*
sel
)
{
struct
ieee80211_local
*
local
=
wdev_priv
(
dev
->
ieee80211_ptr
);
struct
rate_control_ref
*
ref
=
local
->
rate_ctrl
;
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
skb
->
data
;
struct
sta_info
*
sta
;
struct
rate_control_ref
*
ref
=
sdata
->
local
->
rate_ctrl
;
void
*
priv_sta
=
NULL
;
struct
ieee80211_sta
*
ista
=
NULL
;
int
i
;
rcu_read_lock
();
sta
=
sta_info_get
(
local
,
hdr
->
addr1
);
sel
->
rate_idx
=
-
1
;
sel
->
nonerp_idx
=
-
1
;
sel
->
probe_idx
=
-
1
;
sel
->
max_rate_idx
=
sdata
->
max_ratectrl_rateidx
;
if
(
sta
)
{
ista
=
&
sta
->
sta
;
priv_sta
=
sta
->
rate_ctrl_priv
;
}
if
(
sta
&&
sdata
->
force_unicast_rateidx
>
-
1
)
sel
->
rate_idx
=
sdata
->
force_unicast_rateidx
;
else
ref
->
ops
->
get_rate
(
ref
->
priv
,
sband
,
ista
,
priv_sta
,
skb
,
sel
);
ref
->
ops
->
get_rate
(
ref
->
priv
,
dev
,
sband
,
skb
,
sel
);
if
(
sdata
->
max_ratectrl_rateidx
>
-
1
&&
sel
->
rate_idx
>
sdata
->
max_ratectrl_rateidx
)
sel
->
rate_idx
=
sdata
->
max_ratectrl_rateidx
;
BUG_ON
(
sel
->
rate_idx
<
0
);
...
...
@@ -191,13 +236,11 @@ void rate_control_get_rate(struct net_device *dev,
if
(
sband
->
bitrates
[
sel
->
rate_idx
].
bitrate
<
rate
->
bitrate
)
break
;
if
(
rate_supported
(
sta
,
sband
->
band
,
i
)
&&
if
(
rate_supported
(
i
sta
,
sband
->
band
,
i
)
&&
!
(
rate
->
flags
&
IEEE80211_RATE_ERP_G
))
sel
->
nonerp_idx
=
i
;
}
}
rcu_read_unlock
();
}
struct
rate_control_ref
*
rate_control_get
(
struct
rate_control_ref
*
ref
)
...
...
This diff is collapsed.
Click to expand it.
net/mac80211/rate.h
浏览文件 @
db4148da
...
...
@@ -19,77 +19,48 @@
#include "ieee80211_i.h"
#include "sta_info.h"
/**
* struct rate_selection - rate selection for rate control algos
* @rate: selected transmission rate index
* @nonerp: Non-ERP rate to use instead if ERP cannot be used
* @probe: rate for probing (or -1)
*
*/
struct
rate_selection
{
s8
rate_idx
,
nonerp_idx
,
probe_idx
;
};
struct
rate_control_ops
{
struct
module
*
module
;
const
char
*
name
;
void
(
*
tx_status
)(
void
*
priv
,
struct
net_device
*
dev
,
struct
sk_buff
*
skb
);
void
(
*
get_rate
)(
void
*
priv
,
struct
net_device
*
dev
,
struct
ieee80211_supported_band
*
band
,
struct
sk_buff
*
skb
,
struct
rate_selection
*
sel
);
void
(
*
rate_init
)(
void
*
priv
,
void
*
priv_sta
,
struct
ieee80211_local
*
local
,
struct
sta_info
*
sta
);
void
(
*
clear
)(
void
*
priv
);
void
*
(
*
alloc
)(
struct
ieee80211_local
*
local
);
void
(
*
free
)(
void
*
priv
);
void
*
(
*
alloc_sta
)(
void
*
priv
,
gfp_t
gfp
);
void
(
*
free_sta
)(
void
*
priv
,
void
*
priv_sta
);
int
(
*
add_attrs
)(
void
*
priv
,
struct
kobject
*
kobj
);
void
(
*
remove_attrs
)(
void
*
priv
,
struct
kobject
*
kobj
);
void
(
*
add_sta_debugfs
)(
void
*
priv
,
void
*
priv_sta
,
struct
dentry
*
dir
);
void
(
*
remove_sta_debugfs
)(
void
*
priv
,
void
*
priv_sta
);
};
struct
rate_control_ref
{
struct
ieee80211_local
*
local
;
struct
rate_control_ops
*
ops
;
void
*
priv
;
struct
kref
kref
;
};
int
ieee80211_rate_control_register
(
struct
rate_control_ops
*
ops
);
void
ieee80211_rate_control_unregister
(
struct
rate_control_ops
*
ops
);
/* Get a reference to the rate control algorithm. If `name' is NULL, get the
* first available algorithm. */
struct
rate_control_ref
*
rate_control_alloc
(
const
char
*
name
,
struct
ieee80211_local
*
local
);
void
rate_control_get_rate
(
struct
net_device
*
dev
,
void
rate_control_get_rate
(
struct
ieee80211_sub_if_data
*
sdata
,
struct
ieee80211_supported_band
*
sband
,
struct
sk_buff
*
skb
,
struct
s
ta_info
*
sta
,
struct
s
k_buff
*
skb
,
struct
rate_selection
*
sel
);
struct
rate_control_ref
*
rate_control_get
(
struct
rate_control_ref
*
ref
);
void
rate_control_put
(
struct
rate_control_ref
*
ref
);
static
inline
void
rate_control_tx_status
(
struct
net_device
*
dev
,
static
inline
void
rate_control_tx_status
(
struct
ieee80211_local
*
local
,
struct
ieee80211_supported_band
*
sband
,
struct
sta_info
*
sta
,
struct
sk_buff
*
skb
)
{
struct
ieee80211_local
*
local
=
wdev_priv
(
dev
->
ieee80211_ptr
);
struct
rate_control_ref
*
ref
=
local
->
rate_ctrl
;
struct
ieee80211_sta
*
ista
=
&
sta
->
sta
;
void
*
priv_sta
=
sta
->
rate_ctrl_priv
;
ref
->
ops
->
tx_status
(
ref
->
priv
,
dev
,
skb
);
ref
->
ops
->
tx_status
(
ref
->
priv
,
sband
,
ista
,
priv_sta
,
skb
);
}
static
inline
void
rate_control_rate_init
(
struct
sta_info
*
sta
,
struct
ieee80211_local
*
local
)
static
inline
void
rate_control_rate_init
(
struct
sta_info
*
sta
)
{
struct
ieee80211_local
*
local
=
sta
->
sdata
->
local
;
struct
rate_control_ref
*
ref
=
sta
->
rate_ctrl
;
ref
->
ops
->
rate_init
(
ref
->
priv
,
sta
->
rate_ctrl_priv
,
local
,
sta
);
struct
ieee80211_sta
*
ista
=
&
sta
->
sta
;
void
*
priv_sta
=
sta
->
rate_ctrl_priv
;
struct
ieee80211_supported_band
*
sband
;
sband
=
local
->
hw
.
wiphy
->
bands
[
local
->
hw
.
conf
.
channel
->
band
];
ref
->
ops
->
rate_init
(
ref
->
priv
,
sband
,
ista
,
priv_sta
);
}
...
...
@@ -100,15 +71,19 @@ static inline void rate_control_clear(struct ieee80211_local *local)
}
static
inline
void
*
rate_control_alloc_sta
(
struct
rate_control_ref
*
ref
,
struct
ieee80211_sta
*
sta
,
gfp_t
gfp
)
{
return
ref
->
ops
->
alloc_sta
(
ref
->
priv
,
gfp
);
return
ref
->
ops
->
alloc_sta
(
ref
->
priv
,
sta
,
gfp
);
}
static
inline
void
rate_control_free_sta
(
struct
rate_control_ref
*
ref
,
void
*
priv
)
static
inline
void
rate_control_free_sta
(
struct
sta_info
*
sta
)
{
ref
->
ops
->
free_sta
(
ref
->
priv
,
priv
);
struct
rate_control_ref
*
ref
=
sta
->
rate_ctrl
;
struct
ieee80211_sta
*
ista
=
&
sta
->
sta
;
void
*
priv_sta
=
sta
->
rate_ctrl_priv
;
ref
->
ops
->
free_sta
(
ref
->
priv
,
ista
,
priv_sta
);
}
static
inline
void
rate_control_add_sta_debugfs
(
struct
sta_info
*
sta
)
...
...
@@ -130,31 +105,6 @@ static inline void rate_control_remove_sta_debugfs(struct sta_info *sta)
#endif
}
static
inline
int
rate_supported
(
struct
sta_info
*
sta
,
enum
ieee80211_band
band
,
int
index
)
{
return
(
sta
==
NULL
||
sta
->
sta
.
supp_rates
[
band
]
&
BIT
(
index
));
}
static
inline
s8
rate_lowest_index
(
struct
ieee80211_local
*
local
,
struct
ieee80211_supported_band
*
sband
,
struct
sta_info
*
sta
)
{
int
i
;
for
(
i
=
0
;
i
<
sband
->
n_bitrates
;
i
++
)
if
(
rate_supported
(
sta
,
sband
->
band
,
i
))
return
i
;
/* warn when we cannot find a rate. */
WARN_ON
(
1
);
return
0
;
}
/* functions for rate control related to a device */
int
ieee80211_init_rate_ctrl_alg
(
struct
ieee80211_local
*
local
,
const
char
*
name
);
...
...
This diff is collapsed.
Click to expand it.
net/mac80211/rc80211_pid.h
浏览文件 @
db4148da
...
...
@@ -124,7 +124,6 @@ struct rc_pid_events_file_info {
* struct rc_pid_debugfs_entries - tunable parameters
*
* Algorithm parameters, tunable via debugfs.
* @dir: the debugfs directory for a specific phy
* @target: target percentage for failed frames
* @sampling_period: error sampling interval in milliseconds
* @coeff_p: absolute value of the proportional coefficient
...
...
@@ -143,7 +142,6 @@ struct rc_pid_events_file_info {
* ordering of rates)
*/
struct
rc_pid_debugfs_entries
{
struct
dentry
*
dir
;
struct
dentry
*
target
;
struct
dentry
*
sampling_period
;
struct
dentry
*
coeff_p
;
...
...
This diff is collapsed.
Click to expand it.
net/mac80211/rc80211_pid_algo.c
浏览文件 @
db4148da
...
...
@@ -68,18 +68,14 @@
* exhibited a worse failed frames behaviour and we'll choose the highest rate
* whose failed frames behaviour is not worse than the one of the original rate
* target. While at it, check that the new rate is valid. */
static
void
rate_control_pid_adjust_rate
(
struct
ieee80211_local
*
local
,
struct
sta_info
*
sta
,
int
adj
,
static
void
rate_control_pid_adjust_rate
(
struct
ieee80211_supported_band
*
sband
,
struct
ieee80211_sta
*
sta
,
struct
rc_pid_sta_info
*
spinfo
,
int
adj
,
struct
rc_pid_rateinfo
*
rinfo
)
{
struct
ieee80211_sub_if_data
*
sdata
;
struct
ieee80211_supported_band
*
sband
;
int
cur_sorted
,
new_sorted
,
probe
,
tmp
,
n_bitrates
,
band
;
struct
rc_pid_sta_info
*
spinfo
=
(
void
*
)
sta
->
rate_ctrl_priv
;
int
cur
=
spinfo
->
txrate_idx
;
sdata
=
sta
->
sdata
;
sband
=
local
->
hw
.
wiphy
->
bands
[
local
->
hw
.
conf
.
channel
->
band
];
band
=
sband
->
band
;
n_bitrates
=
sband
->
n_bitrates
;
...
...
@@ -146,13 +142,11 @@ static void rate_control_pid_normalize(struct rc_pid_info *pinfo, int l)
}
static
void
rate_control_pid_sample
(
struct
rc_pid_info
*
pinfo
,
struct
ieee80211_local
*
local
,
struct
sta_info
*
sta
)
struct
ieee80211_supported_band
*
sband
,
struct
ieee80211_sta
*
sta
,
struct
rc_pid_sta_info
*
spinfo
)
{
struct
ieee80211_sub_if_data
*
sdata
=
sta
->
sdata
;
struct
rc_pid_sta_info
*
spinfo
=
sta
->
rate_ctrl_priv
;
struct
rc_pid_rateinfo
*
rinfo
=
pinfo
->
rinfo
;
struct
ieee80211_supported_band
*
sband
;
u32
pf
;
s32
err_avg
;
u32
err_prop
;
...
...
@@ -161,9 +155,6 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo,
int
adj
,
i
,
j
,
tmp
;
unsigned
long
period
;
sband
=
local
->
hw
.
wiphy
->
bands
[
local
->
hw
.
conf
.
channel
->
band
];
spinfo
=
sta
->
rate_ctrl_priv
;
/* In case nothing happened during the previous control interval, turn
* the sharpening factor on. */
period
=
(
HZ
*
pinfo
->
sampling_period
+
500
)
/
1000
;
...
...
@@ -179,11 +170,15 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo,
if
(
unlikely
(
spinfo
->
tx_num_xmit
==
0
))
pf
=
spinfo
->
last_pf
;
else
{
/* XXX: BAD HACK!!! */
struct
sta_info
*
si
=
container_of
(
sta
,
struct
sta_info
,
sta
);
pf
=
spinfo
->
tx_num_failed
*
100
/
spinfo
->
tx_num_xmit
;
if
(
ieee80211_vif_is_mesh
(
&
sdata
->
vif
)
&&
pf
==
100
)
mesh_plink_broken
(
sta
);
if
(
ieee80211_vif_is_mesh
(
&
si
->
sdata
->
vif
)
&&
pf
==
100
)
mesh_plink_broken
(
si
);
pf
<<=
RC_PID_ARITH_SHIFT
;
s
ta
->
fail_avg
=
((
pf
+
(
spinfo
->
last_pf
<<
3
))
/
9
)
s
i
->
fail_avg
=
((
pf
+
(
spinfo
->
last_pf
<<
3
))
/
9
)
>>
RC_PID_ARITH_SHIFT
;
}
...
...
@@ -229,43 +224,25 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo,
/* Change rate. */
if
(
adj
)
rate_control_pid_adjust_rate
(
local
,
sta
,
adj
,
rinfo
);
rate_control_pid_adjust_rate
(
sband
,
sta
,
spinfo
,
adj
,
rinfo
);
}
static
void
rate_control_pid_tx_status
(
void
*
priv
,
struct
net_device
*
dev
,
static
void
rate_control_pid_tx_status
(
void
*
priv
,
struct
ieee80211_supported_band
*
sband
,
struct
ieee80211_sta
*
sta
,
void
*
priv_sta
,
struct
sk_buff
*
skb
)
{
struct
ieee80211_local
*
local
=
wdev_priv
(
dev
->
ieee80211_ptr
);
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
skb
->
data
;
struct
ieee80211_sub_if_data
*
sdata
;
struct
rc_pid_info
*
pinfo
=
priv
;
struct
sta_info
*
sta
;
struct
rc_pid_sta_info
*
spinfo
;
struct
rc_pid_sta_info
*
spinfo
=
priv_sta
;
unsigned
long
period
;
struct
ieee80211_supported_band
*
sband
;
struct
ieee80211_tx_info
*
info
=
IEEE80211_SKB_CB
(
skb
);
rcu_read_lock
();
sta
=
sta_info_get
(
local
,
hdr
->
addr1
);
sband
=
local
->
hw
.
wiphy
->
bands
[
local
->
hw
.
conf
.
channel
->
band
];
if
(
!
sta
)
goto
unlock
;
spinfo
=
sta
->
rate_ctrl_priv
;
/* Don't update the state if we're not controlling the rate. */
sdata
=
sta
->
sdata
;
if
(
sdata
->
force_unicast_rateidx
>
-
1
)
{
spinfo
->
txrate_idx
=
sdata
->
max_ratectrl_rateidx
;
goto
unlock
;
}
if
(
!
spinfo
)
return
;
/* Ignore all frames that were sent with a different rate than the rate
* we currently advise mac80211 to use. */
if
(
info
->
tx_rate_idx
!=
spinfo
->
txrate_idx
)
goto
unlock
;
return
;
spinfo
->
tx_num_xmit
++
;
...
...
@@ -289,78 +266,63 @@ static void rate_control_pid_tx_status(void *priv, struct net_device *dev,
if
(
!
period
)
period
=
1
;
if
(
time_after
(
jiffies
,
spinfo
->
last_sample
+
period
))
rate_control_pid_sample
(
pinfo
,
local
,
sta
);
unlock:
rcu_read_unlock
();
rate_control_pid_sample
(
pinfo
,
sband
,
sta
,
spinfo
);
}
static
void
rate_control_pid_get_rate
(
void
*
priv
,
struct
net_device
*
dev
,
struct
ieee80211_supported_band
*
sband
,
struct
sk_buff
*
skb
,
struct
rate_selection
*
sel
)
static
void
rate_control_pid_get_rate
(
void
*
priv
,
struct
ieee80211_supported_band
*
sband
,
struct
ieee80211_sta
*
sta
,
void
*
priv_sta
,
struct
sk_buff
*
skb
,
struct
rate_selection
*
sel
)
{
struct
ieee80211_local
*
local
=
wdev_priv
(
dev
->
ieee80211_ptr
);
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
skb
->
data
;
struct
ieee80211_sub_if_data
*
sdata
;
struct
rc_pid_sta_info
*
spinfo
;
struct
sta_info
*
sta
;
struct
rc_pid_sta_info
*
spinfo
=
priv_sta
;
int
rateidx
;
u16
fc
;
rcu_read_lock
();
sta
=
sta_info_get
(
local
,
hdr
->
addr1
);
/* Send management frames and broadcast/multicast data using lowest
* rate. */
fc
=
le16_to_cpu
(
hdr
->
frame_control
);
if
(
(
fc
&
IEEE80211_FCTL_FTYPE
)
!=
IEEE80211_FTYPE_DATA
||
is_multicast_ether_addr
(
hdr
->
addr1
)
||
!
sta
)
{
sel
->
rate_idx
=
rate_lowest_index
(
local
,
sband
,
sta
);
rcu_read_unlock
(
);
if
(
!
sta
||
!
spinfo
||
(
fc
&
IEEE80211_FCTL_FTYPE
)
!=
IEEE80211_FTYPE_DATA
||
is_multicast_ether_addr
(
hdr
->
addr1
))
{
sel
->
rate_idx
=
rate_lowest_index
(
sband
,
sta
);
return
;
}
/* If a forced rate is in effect, select it. */
sdata
=
IEEE80211_DEV_TO_SUB_IF
(
dev
);
spinfo
=
(
struct
rc_pid_sta_info
*
)
sta
->
rate_ctrl_priv
;
if
(
sdata
->
force_unicast_rateidx
>
-
1
)
spinfo
->
txrate_idx
=
sdata
->
force_unicast_rateidx
;
rateidx
=
spinfo
->
txrate_idx
;
if
(
rateidx
>=
sband
->
n_bitrates
)
rateidx
=
sband
->
n_bitrates
-
1
;
rcu_read_unlock
();
sel
->
rate_idx
=
rateidx
;
#ifdef CONFIG_MAC80211_DEBUGFS
rate_control_pid_event_tx_rate
(
&
((
struct
rc_pid_sta_info
*
)
sta
->
rate_ctrl_priv
)
->
events
,
rate_control_pid_event_tx_rate
(
&
spinfo
->
events
,
rateidx
,
sband
->
bitrates
[
rateidx
].
bitrate
);
#endif
}
static
void
rate_control_pid_rate_init
(
void
*
priv
,
void
*
priv_sta
,
struct
ieee80211_local
*
local
,
struct
sta_info
*
sta
)
static
void
rate_control_pid_rate_init
(
void
*
priv
,
struct
ieee80211_supported_band
*
sband
,
struct
ieee80211_sta
*
sta
,
void
*
priv_
sta
)
{
struct
rc_pid_sta_info
*
spinfo
=
priv_sta
;
struct
sta_info
*
si
;
/* TODO: This routine should consider using RSSI from previous packets
* as we need to have IEEE 802.1X auth succeed immediately after assoc..
* Until that method is implemented, we will use the lowest supported
* rate as a workaround. */
struct
ieee80211_supported_band
*
sband
;
struct
rc_pid_sta_info
*
spinfo
=
(
void
*
)
sta
->
rate_ctrl_priv
;
sband
=
local
->
hw
.
wiphy
->
bands
[
local
->
hw
.
conf
.
channel
->
band
];
spinfo
->
txrate_idx
=
rate_lowest_index
(
local
,
sband
,
sta
);
sta
->
fail_avg
=
0
;
spinfo
->
txrate_idx
=
rate_lowest_index
(
sband
,
sta
);
/* HACK */
si
=
container_of
(
sta
,
struct
sta_info
,
sta
);
si
->
fail_avg
=
0
;
}
static
void
*
rate_control_pid_alloc
(
struct
ieee80211_local
*
local
)
static
void
*
rate_control_pid_alloc
(
struct
ieee80211_hw
*
hw
,
struct
dentry
*
debugfsdir
)
{
struct
rc_pid_info
*
pinfo
;
struct
rc_pid_rateinfo
*
rinfo
;
...
...
@@ -371,7 +333,7 @@ static void *rate_control_pid_alloc(struct ieee80211_local *local)
struct
rc_pid_debugfs_entries
*
de
;
#endif
sband
=
local
->
hw
.
wiphy
->
bands
[
local
->
hw
.
conf
.
channel
->
band
];
sband
=
hw
->
wiphy
->
bands
[
hw
->
conf
.
channel
->
band
];
pinfo
=
kmalloc
(
sizeof
(
*
pinfo
),
GFP_ATOMIC
);
if
(
!
pinfo
)
...
...
@@ -426,30 +388,28 @@ static void *rate_control_pid_alloc(struct ieee80211_local *local)
#ifdef CONFIG_MAC80211_DEBUGFS
de
=
&
pinfo
->
dentries
;
de
->
dir
=
debugfs_create_dir
(
"rc80211_pid"
,
local
->
hw
.
wiphy
->
debugfsdir
);
de
->
target
=
debugfs_create_u32
(
"target_pf"
,
S_IRUSR
|
S_IWUSR
,
de
->
dir
,
&
pinfo
->
target
);
de
bugfs
dir
,
&
pinfo
->
target
);
de
->
sampling_period
=
debugfs_create_u32
(
"sampling_period"
,
S_IRUSR
|
S_IWUSR
,
de
->
dir
,
S_IRUSR
|
S_IWUSR
,
de
bugfs
dir
,
&
pinfo
->
sampling_period
);
de
->
coeff_p
=
debugfs_create_u32
(
"coeff_p"
,
S_IRUSR
|
S_IWUSR
,
de
->
dir
,
&
pinfo
->
coeff_p
);
de
bugfs
dir
,
&
pinfo
->
coeff_p
);
de
->
coeff_i
=
debugfs_create_u32
(
"coeff_i"
,
S_IRUSR
|
S_IWUSR
,
de
->
dir
,
&
pinfo
->
coeff_i
);
de
bugfs
dir
,
&
pinfo
->
coeff_i
);
de
->
coeff_d
=
debugfs_create_u32
(
"coeff_d"
,
S_IRUSR
|
S_IWUSR
,
de
->
dir
,
&
pinfo
->
coeff_d
);
de
bugfs
dir
,
&
pinfo
->
coeff_d
);
de
->
smoothing_shift
=
debugfs_create_u32
(
"smoothing_shift"
,
S_IRUSR
|
S_IWUSR
,
de
->
dir
,
S_IRUSR
|
S_IWUSR
,
de
bugfs
dir
,
&
pinfo
->
smoothing_shift
);
de
->
sharpen_factor
=
debugfs_create_u32
(
"sharpen_factor"
,
S_IRUSR
|
S_IWUSR
,
de
->
dir
,
S_IRUSR
|
S_IWUSR
,
de
bugfs
dir
,
&
pinfo
->
sharpen_factor
);
de
->
sharpen_duration
=
debugfs_create_u32
(
"sharpen_duration"
,
S_IRUSR
|
S_IWUSR
,
de
->
dir
,
S_IRUSR
|
S_IWUSR
,
de
bugfs
dir
,
&
pinfo
->
sharpen_duration
);
de
->
norm_offset
=
debugfs_create_u32
(
"norm_offset"
,
S_IRUSR
|
S_IWUSR
,
de
->
dir
,
S_IRUSR
|
S_IWUSR
,
de
bugfs
dir
,
&
pinfo
->
norm_offset
);
#endif
...
...
@@ -471,7 +431,6 @@ static void rate_control_pid_free(void *priv)
debugfs_remove
(
de
->
coeff_p
);
debugfs_remove
(
de
->
sampling_period
);
debugfs_remove
(
de
->
target
);
debugfs_remove
(
de
->
dir
);
#endif
kfree
(
pinfo
->
rinfo
);
...
...
@@ -482,7 +441,8 @@ static void rate_control_pid_clear(void *priv)
{
}
static
void
*
rate_control_pid_alloc_sta
(
void
*
priv
,
gfp_t
gfp
)
static
void
*
rate_control_pid_alloc_sta
(
void
*
priv
,
struct
ieee80211_sta
*
sta
,
gfp_t
gfp
)
{
struct
rc_pid_sta_info
*
spinfo
;
...
...
@@ -500,10 +460,10 @@ static void *rate_control_pid_alloc_sta(void *priv, gfp_t gfp)
return
spinfo
;
}
static
void
rate_control_pid_free_sta
(
void
*
priv
,
void
*
priv_sta
)
static
void
rate_control_pid_free_sta
(
void
*
priv
,
struct
ieee80211_sta
*
sta
,
void
*
priv_sta
)
{
struct
rc_pid_sta_info
*
spinfo
=
priv_sta
;
kfree
(
spinfo
);
kfree
(
priv_sta
);
}
static
struct
rate_control_ops
mac80211_rcpid
=
{
...
...
This diff is collapsed.
Click to expand it.
net/mac80211/rx.c
浏览文件 @
db4148da
...
...
@@ -650,32 +650,28 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
return
result
;
}
static
void
ap_sta_ps_start
(
struct
net_device
*
dev
,
struct
sta_info
*
sta
)
static
void
ap_sta_ps_start
(
struct
sta_info
*
sta
)
{
struct
ieee80211_sub_if_data
*
sdata
;
struct
ieee80211_sub_if_data
*
sdata
=
sta
->
sdata
;
DECLARE_MAC_BUF
(
mac
);
sdata
=
sta
->
sdata
;
atomic_inc
(
&
sdata
->
bss
->
num_sta_ps
);
set_and_clear_sta_flags
(
sta
,
WLAN_STA_PS
,
WLAN_STA_PSPOLL
);
#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
printk
(
KERN_DEBUG
"%s: STA %s aid %d enters power save mode
\n
"
,
dev
->
name
,
print_mac
(
mac
,
sta
->
sta
.
addr
),
sta
->
sta
.
aid
);
sdata
->
dev
->
name
,
print_mac
(
mac
,
sta
->
sta
.
addr
),
sta
->
sta
.
aid
);
#endif
/* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
}
static
int
ap_sta_ps_end
(
struct
net_device
*
dev
,
struct
sta_info
*
sta
)
static
int
ap_sta_ps_end
(
struct
sta_info
*
sta
)
{
struct
ieee80211_local
*
local
=
wdev_priv
(
dev
->
ieee80211_ptr
);
struct
ieee80211_sub_if_data
*
sdata
=
sta
->
sdata
;
struct
ieee80211_local
*
local
=
sdata
->
local
;
struct
sk_buff
*
skb
;
int
sent
=
0
;
struct
ieee80211_sub_if_data
*
sdata
;
struct
ieee80211_tx_info
*
info
;
DECLARE_MAC_BUF
(
mac
);
sdata
=
sta
->
sdata
;
atomic_dec
(
&
sdata
->
bss
->
num_sta_ps
);
clear_sta_flags
(
sta
,
WLAN_STA_PS
|
WLAN_STA_PSPOLL
);
...
...
@@ -685,7 +681,7 @@ static int ap_sta_ps_end(struct net_device *dev, struct sta_info *sta)
#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
printk
(
KERN_DEBUG
"%s: STA %s aid %d exits power save mode
\n
"
,
dev
->
name
,
print_mac
(
mac
,
sta
->
sta
.
addr
),
sta
->
sta
.
aid
);
sdata
->
dev
->
name
,
print_mac
(
mac
,
sta
->
sta
.
addr
),
sta
->
sta
.
aid
);
#endif
/* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
/* Send all buffered frames to the station */
...
...
@@ -701,7 +697,7 @@ static int ap_sta_ps_end(struct net_device *dev, struct sta_info *sta)
sent
++
;
#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
printk
(
KERN_DEBUG
"%s: STA %s aid %d send PS frame "
"since STA not sleeping anymore
\n
"
,
dev
->
name
,
"since STA not sleeping anymore
\n
"
,
sdata
->
dev
->
name
,
print_mac
(
mac
,
sta
->
sta
.
addr
),
sta
->
sta
.
aid
);
#endif
/* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
info
->
flags
|=
IEEE80211_TX_CTL_REQUEUE
;
...
...
@@ -715,7 +711,6 @@ static ieee80211_rx_result debug_noinline
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
;
if
(
!
sta
)
...
...
@@ -757,10 +752,10 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
* exchange sequence */
if
(
test_sta_flags
(
sta
,
WLAN_STA_PS
)
&&
!
ieee80211_has_pm
(
hdr
->
frame_control
))
rx
->
sent_ps_buffered
+=
ap_sta_ps_end
(
dev
,
sta
);
rx
->
sent_ps_buffered
+=
ap_sta_ps_end
(
sta
);
else
if
(
!
test_sta_flags
(
sta
,
WLAN_STA_PS
)
&&
ieee80211_has_pm
(
hdr
->
frame_control
))
ap_sta_ps_start
(
dev
,
sta
);
ap_sta_ps_start
(
sta
);
}
/* Drop data::nullfunc frames silently, since they are used only to
...
...
@@ -1112,10 +1107,6 @@ ieee80211_data_to_8023(struct ieee80211_rx_data *rx)
hdrlen
=
ieee80211_hdrlen
(
hdr
->
frame_control
);
if
(
ieee80211_vif_is_mesh
(
&
sdata
->
vif
))
hdrlen
+=
ieee80211_get_mesh_hdrlen
(
(
struct
ieee80211s_hdr
*
)
(
skb
->
data
+
hdrlen
));
/* convert IEEE 802.11 header + possible LLC headers into Ethernet
* header
* IEEE 802.11 address fields:
...
...
@@ -1139,6 +1130,15 @@ ieee80211_data_to_8023(struct ieee80211_rx_data *rx)
if
(
unlikely
(
sdata
->
vif
.
type
!=
NL80211_IFTYPE_WDS
&&
sdata
->
vif
.
type
!=
NL80211_IFTYPE_MESH_POINT
))
return
-
1
;
if
(
ieee80211_vif_is_mesh
(
&
sdata
->
vif
))
{
struct
ieee80211s_hdr
*
meshdr
=
(
struct
ieee80211s_hdr
*
)
(
skb
->
data
+
hdrlen
);
hdrlen
+=
ieee80211_get_mesh_hdrlen
(
meshdr
);
if
(
meshdr
->
flags
&
MESH_FLAGS_AE_A5_A6
)
{
memcpy
(
dst
,
meshdr
->
eaddr1
,
ETH_ALEN
);
memcpy
(
src
,
meshdr
->
eaddr2
,
ETH_ALEN
);
}
}
break
;
case
__constant_cpu_to_le16
(
IEEE80211_FCTL_FROMDS
):
if
(
sdata
->
vif
.
type
!=
NL80211_IFTYPE_STATION
||
...
...
@@ -1398,6 +1398,25 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
/* illegal frame */
return
RX_DROP_MONITOR
;
if
(
mesh_hdr
->
flags
&
MESH_FLAGS_AE_A5_A6
){
struct
ieee80211_sub_if_data
*
sdata
;
struct
mesh_path
*
mppath
;
sdata
=
IEEE80211_DEV_TO_SUB_IF
(
rx
->
dev
);
rcu_read_lock
();
mppath
=
mpp_path_lookup
(
mesh_hdr
->
eaddr2
,
sdata
);
if
(
!
mppath
)
{
mpp_path_add
(
mesh_hdr
->
eaddr2
,
hdr
->
addr4
,
sdata
);
}
else
{
spin_lock_bh
(
&
mppath
->
state_lock
);
mppath
->
exp_time
=
jiffies
;
if
(
compare_ether_addr
(
mppath
->
mpp
,
hdr
->
addr4
)
!=
0
)
memcpy
(
mppath
->
mpp
,
hdr
->
addr4
,
ETH_ALEN
);
spin_unlock_bh
(
&
mppath
->
state_lock
);
}
rcu_read_unlock
();
}
if
(
compare_ether_addr
(
rx
->
dev
->
dev_addr
,
hdr
->
addr3
)
==
0
)
return
RX_CONTINUE
;
...
...
@@ -1538,7 +1557,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
*/
if
(
sdata
->
vif
.
type
!=
NL80211_IFTYPE_STATION
&&
sdata
->
vif
.
type
!=
NL80211_IFTYPE_ADHOC
)
return
RX_
DROP_MONITOR
;
return
RX_
CONTINUE
;
switch
(
mgmt
->
u
.
action
.
category
)
{
case
WLAN_CATEGORY_BACK
:
...
...
This diff is collapsed.
Click to expand it.
net/mac80211/sta_info.c
浏览文件 @
db4148da
...
...
@@ -93,8 +93,7 @@ static int sta_info_hash_del(struct ieee80211_local *local,
}
/* protected by RCU */
static
struct
sta_info
*
__sta_info_find
(
struct
ieee80211_local
*
local
,
const
u8
*
addr
)
struct
sta_info
*
sta_info_get
(
struct
ieee80211_local
*
local
,
const
u8
*
addr
)
{
struct
sta_info
*
sta
;
...
...
@@ -107,12 +106,6 @@ static struct sta_info *__sta_info_find(struct ieee80211_local *local,
return
sta
;
}
struct
sta_info
*
sta_info_get
(
struct
ieee80211_local
*
local
,
u8
*
addr
)
{
return
__sta_info_find
(
local
,
addr
);
}
EXPORT_SYMBOL
(
sta_info_get
);
struct
sta_info
*
sta_info_get_by_idx
(
struct
ieee80211_local
*
local
,
int
idx
,
struct
net_device
*
dev
)
{
...
...
@@ -146,7 +139,7 @@ static void __sta_info_free(struct ieee80211_local *local,
{
DECLARE_MAC_BUF
(
mbuf
);
rate_control_free_sta
(
sta
->
rate_ctrl
,
sta
->
rate_ctrl_priv
);
rate_control_free_sta
(
sta
);
rate_control_put
(
sta
->
rate_ctrl
);
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
...
...
@@ -244,7 +237,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
sta
->
rate_ctrl
=
rate_control_get
(
local
->
rate_ctrl
);
sta
->
rate_ctrl_priv
=
rate_control_alloc_sta
(
sta
->
rate_ctrl
,
gfp
);
&
sta
->
sta
,
gfp
);
if
(
!
sta
->
rate_ctrl_priv
)
{
rate_control_put
(
sta
->
rate_ctrl
);
kfree
(
sta
);
...
...
@@ -308,7 +301,7 @@ int sta_info_insert(struct sta_info *sta)
spin_lock_irqsave
(
&
local
->
sta_lock
,
flags
);
/* check if STA exists already */
if
(
__sta_info_find
(
local
,
sta
->
sta
.
addr
))
{
if
(
sta_info_get
(
local
,
sta
->
sta
.
addr
))
{
spin_unlock_irqrestore
(
&
local
->
sta_lock
,
flags
);
err
=
-
EEXIST
;
goto
out_free
;
...
...
@@ -834,7 +827,7 @@ void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
struct
ieee80211_sta
*
ieee80211_find_sta
(
struct
ieee80211_hw
*
hw
,
const
u8
*
addr
)
{
struct
sta_info
*
sta
=
__sta_info_find
(
hw_to_local
(
hw
),
addr
);
struct
sta_info
*
sta
=
sta_info_get
(
hw_to_local
(
hw
),
addr
);
if
(
!
sta
)
return
NULL
;
...
...
This diff is collapsed.
Click to expand it.
net/mac80211/sta_info.h
浏览文件 @
db4148da
...
...
@@ -416,7 +416,7 @@ static inline u32 get_sta_flags(struct sta_info *sta)
/*
* Get a STA info, must have be under RCU read lock.
*/
struct
sta_info
*
sta_info_get
(
struct
ieee80211_local
*
local
,
u8
*
addr
);
struct
sta_info
*
sta_info_get
(
struct
ieee80211_local
*
local
,
const
u8
*
addr
);
/*
* Get STA info by index, BROKEN!
*/
...
...
This diff is collapsed.
Click to expand it.
net/mac80211/tx.c
浏览文件 @
db4148da
...
...
@@ -165,11 +165,10 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr,
return
cpu_to_le16
(
dur
);
}
static
int
inline
is_ieee80211_device
(
struct
net_device
*
dev
,
struct
net_device
*
master
)
static
int
inline
is_ieee80211_device
(
struct
ieee80211_local
*
local
,
struct
net_device
*
dev
)
{
return
(
wdev_priv
(
dev
->
ieee80211_ptr
)
==
wdev_priv
(
master
->
ieee80211_ptr
));
return
local
==
wdev_priv
(
dev
->
ieee80211_ptr
);
}
/* tx handlers */
...
...
@@ -447,7 +446,8 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
sband
=
tx
->
local
->
hw
.
wiphy
->
bands
[
tx
->
channel
->
band
];
if
(
likely
(
tx
->
rate_idx
<
0
))
{
rate_control_get_rate
(
tx
->
dev
,
sband
,
tx
->
skb
,
&
rsel
);
rate_control_get_rate
(
tx
->
sdata
,
sband
,
tx
->
sta
,
tx
->
skb
,
&
rsel
);
if
(
tx
->
sta
)
tx
->
sta
->
last_txrate_idx
=
rsel
.
rate_idx
;
tx
->
rate_idx
=
rsel
.
rate_idx
;
...
...
@@ -1001,14 +1001,14 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
/*
* NB: @tx is uninitialised when passed in here
*/
static
int
ieee80211_tx_prepare
(
struct
ieee80211_
tx_data
*
tx
,
struct
sk_buff
*
skb
,
struct
net_device
*
mdev
)
static
int
ieee80211_tx_prepare
(
struct
ieee80211_
local
*
local
,
struct
ieee80211_tx_data
*
tx
,
struct
sk_buff
*
skb
)
{
struct
net_device
*
dev
;
dev
=
dev_get_by_index
(
&
init_net
,
skb
->
iif
);
if
(
unlikely
(
dev
&&
!
is_ieee80211_device
(
dev
,
m
dev
)))
{
if
(
unlikely
(
dev
&&
!
is_ieee80211_device
(
local
,
dev
)))
{
dev_put
(
dev
);
dev
=
NULL
;
}
...
...
@@ -1258,6 +1258,8 @@ static int ieee80211_skb_resize(struct ieee80211_local *local,
int
ieee80211_master_start_xmit
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
)
{
struct
ieee80211_master_priv
*
mpriv
=
netdev_priv
(
dev
);
struct
ieee80211_local
*
local
=
mpriv
->
local
;
struct
ieee80211_tx_info
*
info
=
IEEE80211_SKB_CB
(
skb
);
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
skb
->
data
;
struct
net_device
*
odev
=
NULL
;
...
...
@@ -1273,7 +1275,7 @@ int ieee80211_master_start_xmit(struct sk_buff *skb,
if
(
skb
->
iif
)
odev
=
dev_get_by_index
(
&
init_net
,
skb
->
iif
);
if
(
unlikely
(
odev
&&
!
is_ieee80211_device
(
odev
,
dev
)))
{
if
(
unlikely
(
odev
&&
!
is_ieee80211_device
(
local
,
o
dev
)))
{
dev_put
(
odev
);
odev
=
NULL
;
}
...
...
@@ -1449,8 +1451,8 @@ int ieee80211_monitor_start_xmit(struct sk_buff *skb,
int
ieee80211_subif_start_xmit
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
)
{
struct
ieee80211_
local
*
local
=
wdev_priv
(
dev
->
ieee80211_ptr
);
struct
ieee80211_
sub_if_data
*
sdata
;
struct
ieee80211_
sub_if_data
*
sdata
=
IEEE80211_DEV_TO_SUB_IF
(
dev
);
struct
ieee80211_
local
*
local
=
sdata
->
local
;
int
ret
=
1
,
head_need
;
u16
ethertype
,
hdrlen
,
meshhdrlen
=
0
;
__le16
fc
;
...
...
@@ -1462,7 +1464,6 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
struct
sta_info
*
sta
;
u32
sta_flags
=
0
;
sdata
=
IEEE80211_DEV_TO_SUB_IF
(
dev
);
if
(
unlikely
(
skb
->
len
<
ETH_HLEN
))
{
ret
=
0
;
goto
fail
;
...
...
@@ -1498,18 +1499,50 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
#ifdef CONFIG_MAC80211_MESH
case
NL80211_IFTYPE_MESH_POINT
:
fc
|=
cpu_to_le16
(
IEEE80211_FCTL_FROMDS
|
IEEE80211_FCTL_TODS
);
/* RA TA DA SA */
memset
(
hdr
.
addr1
,
0
,
ETH_ALEN
);
memcpy
(
hdr
.
addr2
,
dev
->
dev_addr
,
ETH_ALEN
);
memcpy
(
hdr
.
addr3
,
skb
->
data
,
ETH_ALEN
);
memcpy
(
hdr
.
addr4
,
skb
->
data
+
ETH_ALEN
,
ETH_ALEN
);
if
(
!
sdata
->
u
.
mesh
.
mshcfg
.
dot11MeshTTL
)
{
/* Do not send frames with mesh_ttl == 0 */
sdata
->
u
.
mesh
.
mshstats
.
dropped_frames_ttl
++
;
ret
=
0
;
goto
fail
;
}
meshhdrlen
=
ieee80211_new_mesh_header
(
&
mesh_hdr
,
sdata
);
memset
(
&
mesh_hdr
,
0
,
sizeof
(
mesh_hdr
));
if
(
compare_ether_addr
(
dev
->
dev_addr
,
skb
->
data
+
ETH_ALEN
)
==
0
)
{
/* RA TA DA SA */
memset
(
hdr
.
addr1
,
0
,
ETH_ALEN
);
memcpy
(
hdr
.
addr2
,
dev
->
dev_addr
,
ETH_ALEN
);
memcpy
(
hdr
.
addr3
,
skb
->
data
,
ETH_ALEN
);
memcpy
(
hdr
.
addr4
,
skb
->
data
+
ETH_ALEN
,
ETH_ALEN
);
meshhdrlen
=
ieee80211_new_mesh_header
(
&
mesh_hdr
,
sdata
);
}
else
{
/* packet from other interface */
struct
mesh_path
*
mppath
;
memset
(
hdr
.
addr1
,
0
,
ETH_ALEN
);
memcpy
(
hdr
.
addr2
,
dev
->
dev_addr
,
ETH_ALEN
);
memcpy
(
hdr
.
addr4
,
dev
->
dev_addr
,
ETH_ALEN
);
if
(
is_multicast_ether_addr
(
skb
->
data
))
memcpy
(
hdr
.
addr3
,
skb
->
data
,
ETH_ALEN
);
else
{
rcu_read_lock
();
mppath
=
mpp_path_lookup
(
skb
->
data
,
sdata
);
if
(
mppath
)
memcpy
(
hdr
.
addr3
,
mppath
->
mpp
,
ETH_ALEN
);
else
memset
(
hdr
.
addr3
,
0xff
,
ETH_ALEN
);
rcu_read_unlock
();
}
mesh_hdr
.
flags
|=
MESH_FLAGS_AE_A5_A6
;
mesh_hdr
.
ttl
=
sdata
->
u
.
mesh
.
mshcfg
.
dot11MeshTTL
;
put_unaligned
(
cpu_to_le32
(
sdata
->
u
.
mesh
.
mesh_seqnum
),
&
mesh_hdr
.
seqnum
);
memcpy
(
mesh_hdr
.
eaddr1
,
skb
->
data
,
ETH_ALEN
);
memcpy
(
mesh_hdr
.
eaddr2
,
skb
->
data
+
ETH_ALEN
,
ETH_ALEN
);
sdata
->
u
.
mesh
.
mesh_seqnum
++
;
meshhdrlen
=
18
;
}
hdrlen
=
30
;
break
;
#endif
...
...
@@ -1923,7 +1956,7 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
skb
->
do_not_encrypt
=
1
;
info
->
band
=
band
;
rate_control_get_rate
(
local
->
mdev
,
sband
,
skb
,
&
rsel
);
rate_control_get_rate
(
sdata
,
sband
,
NULL
,
skb
,
&
rsel
);
if
(
unlikely
(
rsel
.
rate_idx
<
0
))
{
if
(
net_ratelimit
())
{
...
...
@@ -2032,7 +2065,7 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
cpu_to_le16
(
IEEE80211_FCTL_MOREDATA
);
}
if
(
!
ieee80211_tx_prepare
(
&
tx
,
skb
,
local
->
mdev
))
if
(
!
ieee80211_tx_prepare
(
local
,
&
tx
,
skb
))
break
;
dev_kfree_skb_any
(
skb
);
}
...
...
This diff is collapsed.
Click to expand it.
net/wireless/core.c
浏览文件 @
db4148da
...
...
@@ -29,113 +29,11 @@ MODULE_AUTHOR("Johannes Berg");
MODULE_LICENSE
(
"GPL"
);
MODULE_DESCRIPTION
(
"wireless configuration support"
);
struct
list_head
regulatory_requests
;
/* Central wireless core regulatory domains, we only need two,
* the current one and a world regulatory domain in case we have no
* information to give us an alpha2 */
struct
ieee80211_regdomain
*
cfg80211_regdomain
;
/* We keep a static world regulatory domain in case of the absence of CRDA */
const
struct
ieee80211_regdomain
world_regdom
=
{
.
n_reg_rules
=
1
,
.
alpha2
=
"00"
,
.
reg_rules
=
{
REG_RULE
(
2402
,
2472
,
40
,
6
,
20
,
NL80211_RRF_PASSIVE_SCAN
|
NL80211_RRF_NO_IBSS
),
}
};
#ifdef CONFIG_WIRELESS_OLD_REGULATORY
/* All this fucking static junk will be removed soon, so
* don't fucking count on it !@#$ */
static
char
*
ieee80211_regdom
=
"US"
;
module_param
(
ieee80211_regdom
,
charp
,
0444
);
MODULE_PARM_DESC
(
ieee80211_regdom
,
"IEEE 802.11 regulatory domain code"
);
/* We assume 40 MHz bandwidth for the old regulatory work.
* We make emphasis we are using the exact same frequencies
* as before */
const
struct
ieee80211_regdomain
us_regdom
=
{
.
n_reg_rules
=
6
,
.
alpha2
=
"US"
,
.
reg_rules
=
{
/* IEEE 802.11b/g, channels 1..11 */
REG_RULE
(
2412
-
20
,
2462
+
20
,
40
,
6
,
27
,
0
),
/* IEEE 802.11a, channel 36 */
REG_RULE
(
5180
-
20
,
5180
+
20
,
40
,
6
,
23
,
0
),
/* IEEE 802.11a, channel 40 */
REG_RULE
(
5200
-
20
,
5200
+
20
,
40
,
6
,
23
,
0
),
/* IEEE 802.11a, channel 44 */
REG_RULE
(
5220
-
20
,
5220
+
20
,
40
,
6
,
23
,
0
),
/* IEEE 802.11a, channels 48..64 */
REG_RULE
(
5240
-
20
,
5320
+
20
,
40
,
6
,
23
,
0
),
/* IEEE 802.11a, channels 149..165, outdoor */
REG_RULE
(
5745
-
20
,
5825
+
20
,
40
,
6
,
30
,
0
),
}
};
const
struct
ieee80211_regdomain
jp_regdom
=
{
.
n_reg_rules
=
3
,
.
alpha2
=
"JP"
,
.
reg_rules
=
{
/* IEEE 802.11b/g, channels 1..14 */
REG_RULE
(
2412
-
20
,
2484
+
20
,
40
,
6
,
20
,
0
),
/* IEEE 802.11a, channels 34..48 */
REG_RULE
(
5170
-
20
,
5240
+
20
,
40
,
6
,
20
,
NL80211_RRF_PASSIVE_SCAN
),
/* IEEE 802.11a, channels 52..64 */
REG_RULE
(
5260
-
20
,
5320
+
20
,
40
,
6
,
20
,
NL80211_RRF_NO_IBSS
|
NL80211_RRF_DFS
),
}
};
const
struct
ieee80211_regdomain
eu_regdom
=
{
.
n_reg_rules
=
6
,
/* This alpha2 is bogus, we leave it here just for stupid
* backward compatibility */
.
alpha2
=
"EU"
,
.
reg_rules
=
{
/* IEEE 802.11b/g, channels 1..13 */
REG_RULE
(
2412
-
20
,
2472
+
20
,
40
,
6
,
20
,
0
),
/* IEEE 802.11a, channel 36 */
REG_RULE
(
5180
-
20
,
5180
+
20
,
40
,
6
,
23
,
NL80211_RRF_PASSIVE_SCAN
),
/* IEEE 802.11a, channel 40 */
REG_RULE
(
5200
-
20
,
5200
+
20
,
40
,
6
,
23
,
NL80211_RRF_PASSIVE_SCAN
),
/* IEEE 802.11a, channel 44 */
REG_RULE
(
5220
-
20
,
5220
+
20
,
40
,
6
,
23
,
NL80211_RRF_PASSIVE_SCAN
),
/* IEEE 802.11a, channels 48..64 */
REG_RULE
(
5240
-
20
,
5320
+
20
,
40
,
6
,
20
,
NL80211_RRF_NO_IBSS
|
NL80211_RRF_DFS
),
/* IEEE 802.11a, channels 100..140 */
REG_RULE
(
5500
-
20
,
5700
+
20
,
40
,
6
,
30
,
NL80211_RRF_NO_IBSS
|
NL80211_RRF_DFS
),
}
};
#endif
struct
ieee80211_regdomain
*
cfg80211_world_regdom
=
(
struct
ieee80211_regdomain
*
)
&
world_regdom
;
LIST_HEAD
(
regulatory_requests
);
DEFINE_MUTEX
(
cfg80211_reg_mutex
);
/* RCU might be appropriate here since we usually
* only read the list, and that can happen quite
* often because we need to do it for each command */
LIST_HEAD
(
cfg80211_drv_list
);
DEFINE_MUTEX
(
cfg80211_drv_mutex
);
static
int
wiphy_counter
;
/* for debugfs */
static
struct
dentry
*
ieee80211_debugfs_dir
;
...
...
@@ -307,6 +205,8 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
struct
wiphy
*
wiphy_new
(
struct
cfg80211_ops
*
ops
,
int
sizeof_priv
)
{
static
int
wiphy_counter
;
struct
cfg80211_registered_device
*
drv
;
int
alloc_size
;
...
...
@@ -323,21 +223,18 @@ struct wiphy *wiphy_new(struct cfg80211_ops *ops, int sizeof_priv)
mutex_lock
(
&
cfg80211_drv_mutex
);
drv
->
idx
=
wiphy_counter
;
/* now increase counter for the next device unless
* it has wrapped previously */
if
(
wiphy_counter
>=
0
)
wiphy_counter
++
;
mutex_unlock
(
&
cfg80211_drv_mutex
);
drv
->
idx
=
wiphy_counter
++
;
if
(
unlikely
(
drv
->
idx
<
0
))
{
wiphy_counter
--
;
mutex_unlock
(
&
cfg80211_drv_mutex
);
/* ugh, wrapped! */
kfree
(
drv
);
return
NULL
;
}
mutex_unlock
(
&
cfg80211_drv_mutex
);
/* give it a proper name */
snprintf
(
drv
->
wiphy
.
dev
.
bus_id
,
BUS_ID_SIZE
,
PHY_NAME
"%d"
,
drv
->
idx
);
...
...
@@ -485,6 +382,8 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
rdev
=
wiphy_to_dev
(
dev
->
ieee80211_ptr
->
wiphy
);
WARN_ON
(
dev
->
ieee80211_ptr
->
iftype
==
NL80211_IFTYPE_UNSPECIFIED
);
switch
(
state
)
{
case
NETDEV_REGISTER
:
mutex_lock
(
&
rdev
->
devlist_mtx
);
...
...
@@ -514,34 +413,10 @@ static struct notifier_block cfg80211_netdev_notifier = {
.
notifier_call
=
cfg80211_netdev_notifier_call
,
};
#ifdef CONFIG_WIRELESS_OLD_REGULATORY
const
struct
ieee80211_regdomain
*
static_regdom
(
char
*
alpha2
)
{
if
(
alpha2
[
0
]
==
'U'
&&
alpha2
[
1
]
==
'S'
)
return
&
us_regdom
;
if
(
alpha2
[
0
]
==
'J'
&&
alpha2
[
1
]
==
'P'
)
return
&
jp_regdom
;
if
(
alpha2
[
0
]
==
'E'
&&
alpha2
[
1
]
==
'U'
)
return
&
eu_regdom
;
/* Default, as per the old rules */
return
&
us_regdom
;
}
#endif
static
int
cfg80211_init
(
void
)
{
int
err
;
#ifdef CONFIG_WIRELESS_OLD_REGULATORY
cfg80211_regdomain
=
(
struct
ieee80211_regdomain
*
)
static_regdom
(
ieee80211_regdom
);
/* Used during reset_regdomains_static() */
cfg80211_world_regdom
=
cfg80211_regdomain
;
#else
cfg80211_regdomain
=
(
struct
ieee80211_regdomain
*
)
cfg80211_world_regdom
;
#endif
err
=
wiphy_sysfs_init
();
if
(
err
)
goto
out_fail_sysfs
;
...
...
@@ -560,25 +435,6 @@ static int cfg80211_init(void)
if
(
err
)
goto
out_fail_reg
;
#ifdef CONFIG_WIRELESS_OLD_REGULATORY
printk
(
KERN_INFO
"cfg80211: Using old static regulatory domain:
\n
"
);
print_regdomain_info
(
cfg80211_regdomain
);
/* The old code still requests for a new regdomain and if
* you have CRDA you get it updated, otherwise you get
* stuck with the static values. We ignore "EU" code as
* that is not a valid ISO / IEC 3166 alpha2 */
if
(
ieee80211_regdom
[
0
]
!=
'E'
&&
ieee80211_regdom
[
1
]
!=
'U'
)
err
=
__regulatory_hint
(
NULL
,
REGDOM_SET_BY_CORE
,
ieee80211_regdom
,
NULL
);
#else
err
=
__regulatory_hint
(
NULL
,
REGDOM_SET_BY_CORE
,
"00"
,
NULL
);
if
(
err
)
printk
(
KERN_ERR
"cfg80211: calling CRDA failed - "
"unable to update world regulatory domain, "
"using static definition
\n
"
);
#endif
return
0
;
out_fail_reg:
...
...
This diff is collapsed.
Click to expand it.
net/wireless/nl80211.c
浏览文件 @
db4148da
...
...
@@ -299,7 +299,7 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags,
NLA_PUT_U32
(
msg
,
NL80211_ATTR_IFINDEX
,
dev
->
ifindex
);
NLA_PUT_STRING
(
msg
,
NL80211_ATTR_IFNAME
,
dev
->
name
);
/* TODO: interface type */
NLA_PUT_U32
(
msg
,
NL80211_ATTR_IFTYPE
,
dev
->
ieee80211_ptr
->
iftype
);
return
genlmsg_end
(
msg
,
hdr
);
nla_put_failure:
...
...
@@ -418,41 +418,56 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
int
err
,
ifindex
;
enum
nl80211_iftype
type
;
struct
net_device
*
dev
;
u32
flags
;
u32
_flags
,
*
flags
=
NULL
;
memset
(
&
params
,
0
,
sizeof
(
params
));
if
(
info
->
attrs
[
NL80211_ATTR_IFTYPE
])
{
type
=
nla_get_u32
(
info
->
attrs
[
NL80211_ATTR_IFTYPE
]);
if
(
type
>
NL80211_IFTYPE_MAX
)
return
-
EINVAL
;
}
else
return
-
EINVAL
;
err
=
get_drv_dev_by_info_ifindex
(
info
->
attrs
,
&
drv
,
&
dev
);
if
(
err
)
return
err
;
ifindex
=
dev
->
ifindex
;
type
=
dev
->
ieee80211_ptr
->
iftype
;
dev_put
(
dev
);
err
=
-
EINVAL
;
if
(
info
->
attrs
[
NL80211_ATTR_IFTYPE
])
{
type
=
nla_get_u32
(
info
->
attrs
[
NL80211_ATTR_IFTYPE
]);
if
(
type
>
NL80211_IFTYPE_MAX
)
goto
unlock
;
}
if
(
!
drv
->
ops
->
change_virtual_intf
||
!
(
drv
->
wiphy
.
interface_modes
&
(
1
<<
type
)))
{
err
=
-
EOPNOTSUPP
;
goto
unlock
;
}
if
(
type
==
NL80211_IFTYPE_MESH_POINT
&&
info
->
attrs
[
NL80211_ATTR_MESH_ID
])
{
if
(
info
->
attrs
[
NL80211_ATTR_MESH_ID
])
{
if
(
type
!=
NL80211_IFTYPE_MESH_POINT
)
{
err
=
-
EINVAL
;
goto
unlock
;
}
params
.
mesh_id
=
nla_data
(
info
->
attrs
[
NL80211_ATTR_MESH_ID
]);
params
.
mesh_id_len
=
nla_len
(
info
->
attrs
[
NL80211_ATTR_MESH_ID
]);
}
if
(
info
->
attrs
[
NL80211_ATTR_MNTR_FLAGS
])
{
if
(
type
!=
NL80211_IFTYPE_MONITOR
)
{
err
=
-
EINVAL
;
goto
unlock
;
}
err
=
parse_monitor_flags
(
info
->
attrs
[
NL80211_ATTR_MNTR_FLAGS
],
&
_flags
);
if
(
!
err
)
flags
=
&
_flags
;
}
rtnl_lock
();
err
=
parse_monitor_flags
(
type
==
NL80211_IFTYPE_MONITOR
?
info
->
attrs
[
NL80211_ATTR_MNTR_FLAGS
]
:
NULL
,
&
flags
);
err
=
drv
->
ops
->
change_virtual_intf
(
&
drv
->
wiphy
,
ifindex
,
type
,
err
?
NULL
:
&
flags
,
&
params
);
type
,
flags
,
&
params
);
dev
=
__dev_get_by_index
(
&
init_net
,
ifindex
);
WARN_ON
(
!
dev
||
(
!
err
&&
dev
->
ieee80211_ptr
->
iftype
!=
type
));
rtnl_unlock
();
unlock:
...
...
This diff is collapsed.
Click to expand it.
net/wireless/reg.c
浏览文件 @
db4148da
...
...
@@ -42,6 +42,18 @@
#include "core.h"
#include "reg.h"
/* wiphy is set if this request's initiator is REGDOM_SET_BY_DRIVER */
struct
regulatory_request
{
struct
list_head
list
;
struct
wiphy
*
wiphy
;
int
granted
;
enum
reg_set_by
initiator
;
char
alpha2
[
2
];
};
static
LIST_HEAD
(
regulatory_requests
);
DEFINE_MUTEX
(
cfg80211_reg_mutex
);
/* To trigger userspace events */
static
struct
platform_device
*
reg_pdev
;
...
...
@@ -51,7 +63,156 @@ static u32 supported_bandwidths[] = {
MHZ_TO_KHZ
(
20
),
};
bool
is_world_regdom
(
char
*
alpha2
)
static
struct
list_head
regulatory_requests
;
/* Central wireless core regulatory domains, we only need two,
* the current one and a world regulatory domain in case we have no
* information to give us an alpha2 */
static
const
struct
ieee80211_regdomain
*
cfg80211_regdomain
;
/* We keep a static world regulatory domain in case of the absence of CRDA */
static
const
struct
ieee80211_regdomain
world_regdom
=
{
.
n_reg_rules
=
1
,
.
alpha2
=
"00"
,
.
reg_rules
=
{
REG_RULE
(
2412
-
10
,
2462
+
10
,
40
,
6
,
20
,
NL80211_RRF_PASSIVE_SCAN
|
NL80211_RRF_NO_IBSS
),
}
};
static
const
struct
ieee80211_regdomain
*
cfg80211_world_regdom
=
&
world_regdom
;
#ifdef CONFIG_WIRELESS_OLD_REGULATORY
static
char
*
ieee80211_regdom
=
"US"
;
module_param
(
ieee80211_regdom
,
charp
,
0444
);
MODULE_PARM_DESC
(
ieee80211_regdom
,
"IEEE 802.11 regulatory domain code"
);
/* We assume 40 MHz bandwidth for the old regulatory work.
* We make emphasis we are using the exact same frequencies
* as before */
static
const
struct
ieee80211_regdomain
us_regdom
=
{
.
n_reg_rules
=
6
,
.
alpha2
=
"US"
,
.
reg_rules
=
{
/* IEEE 802.11b/g, channels 1..11 */
REG_RULE
(
2412
-
10
,
2462
+
10
,
40
,
6
,
27
,
0
),
/* IEEE 802.11a, channel 36 */
REG_RULE
(
5180
-
10
,
5180
+
10
,
40
,
6
,
23
,
0
),
/* IEEE 802.11a, channel 40 */
REG_RULE
(
5200
-
10
,
5200
+
10
,
40
,
6
,
23
,
0
),
/* IEEE 802.11a, channel 44 */
REG_RULE
(
5220
-
10
,
5220
+
10
,
40
,
6
,
23
,
0
),
/* IEEE 802.11a, channels 48..64 */
REG_RULE
(
5240
-
10
,
5320
+
10
,
40
,
6
,
23
,
0
),
/* IEEE 802.11a, channels 149..165, outdoor */
REG_RULE
(
5745
-
10
,
5825
+
10
,
40
,
6
,
30
,
0
),
}
};
static
const
struct
ieee80211_regdomain
jp_regdom
=
{
.
n_reg_rules
=
3
,
.
alpha2
=
"JP"
,
.
reg_rules
=
{
/* IEEE 802.11b/g, channels 1..14 */
REG_RULE
(
2412
-
10
,
2484
+
10
,
40
,
6
,
20
,
0
),
/* IEEE 802.11a, channels 34..48 */
REG_RULE
(
5170
-
10
,
5240
+
10
,
40
,
6
,
20
,
NL80211_RRF_PASSIVE_SCAN
),
/* IEEE 802.11a, channels 52..64 */
REG_RULE
(
5260
-
10
,
5320
+
10
,
40
,
6
,
20
,
NL80211_RRF_NO_IBSS
|
NL80211_RRF_DFS
),
}
};
static
const
struct
ieee80211_regdomain
eu_regdom
=
{
.
n_reg_rules
=
6
,
/* This alpha2 is bogus, we leave it here just for stupid
* backward compatibility */
.
alpha2
=
"EU"
,
.
reg_rules
=
{
/* IEEE 802.11b/g, channels 1..13 */
REG_RULE
(
2412
-
10
,
2472
+
10
,
40
,
6
,
20
,
0
),
/* IEEE 802.11a, channel 36 */
REG_RULE
(
5180
-
10
,
5180
+
10
,
40
,
6
,
23
,
NL80211_RRF_PASSIVE_SCAN
),
/* IEEE 802.11a, channel 40 */
REG_RULE
(
5200
-
10
,
5200
+
10
,
40
,
6
,
23
,
NL80211_RRF_PASSIVE_SCAN
),
/* IEEE 802.11a, channel 44 */
REG_RULE
(
5220
-
10
,
5220
+
10
,
40
,
6
,
23
,
NL80211_RRF_PASSIVE_SCAN
),
/* IEEE 802.11a, channels 48..64 */
REG_RULE
(
5240
-
10
,
5320
+
10
,
40
,
6
,
20
,
NL80211_RRF_NO_IBSS
|
NL80211_RRF_DFS
),
/* IEEE 802.11a, channels 100..140 */
REG_RULE
(
5500
-
10
,
5700
+
10
,
40
,
6
,
30
,
NL80211_RRF_NO_IBSS
|
NL80211_RRF_DFS
),
}
};
static
const
struct
ieee80211_regdomain
*
static_regdom
(
char
*
alpha2
)
{
if
(
alpha2
[
0
]
==
'U'
&&
alpha2
[
1
]
==
'S'
)
return
&
us_regdom
;
if
(
alpha2
[
0
]
==
'J'
&&
alpha2
[
1
]
==
'P'
)
return
&
jp_regdom
;
if
(
alpha2
[
0
]
==
'E'
&&
alpha2
[
1
]
==
'U'
)
return
&
eu_regdom
;
/* Default, as per the old rules */
return
&
us_regdom
;
}
static
bool
is_old_static_regdom
(
const
struct
ieee80211_regdomain
*
rd
)
{
if
(
rd
==
&
us_regdom
||
rd
==
&
jp_regdom
||
rd
==
&
eu_regdom
)
return
true
;
return
false
;
}
#else
static
inline
bool
is_old_static_regdom
(
const
struct
ieee80211_regdomain
*
rd
)
{
return
false
;
}
#endif
static
void
reset_regdomains
(
void
)
{
/* avoid freeing static information or freeing something twice */
if
(
cfg80211_regdomain
==
cfg80211_world_regdom
)
cfg80211_regdomain
=
NULL
;
if
(
cfg80211_world_regdom
==
&
world_regdom
)
cfg80211_world_regdom
=
NULL
;
if
(
cfg80211_regdomain
==
&
world_regdom
)
cfg80211_regdomain
=
NULL
;
if
(
is_old_static_regdom
(
cfg80211_regdomain
))
cfg80211_regdomain
=
NULL
;
kfree
(
cfg80211_regdomain
);
kfree
(
cfg80211_world_regdom
);
cfg80211_world_regdom
=
&
world_regdom
;
cfg80211_regdomain
=
NULL
;
}
/* Dynamic world regulatory domain requested by the wireless
* core upon initialization */
static
void
update_world_regdomain
(
const
struct
ieee80211_regdomain
*
rd
)
{
BUG_ON
(
list_empty
(
&
regulatory_requests
));
reset_regdomains
();
cfg80211_world_regdom
=
rd
;
cfg80211_regdomain
=
rd
;
}
bool
is_world_regdom
(
const
char
*
alpha2
)
{
if
(
!
alpha2
)
return
false
;
...
...
@@ -60,7 +221,7 @@ bool is_world_regdom(char *alpha2)
return
false
;
}
static
bool
is_alpha2_set
(
char
*
alpha2
)
static
bool
is_alpha2_set
(
c
onst
c
har
*
alpha2
)
{
if
(
!
alpha2
)
return
false
;
...
...
@@ -77,7 +238,7 @@ static bool is_alpha_upper(char letter)
return
false
;
}
static
bool
is_unknown_alpha2
(
char
*
alpha2
)
static
bool
is_unknown_alpha2
(
c
onst
c
har
*
alpha2
)
{
if
(
!
alpha2
)
return
false
;
...
...
@@ -88,7 +249,7 @@ static bool is_unknown_alpha2(char *alpha2)
return
false
;
}
static
bool
is_an_alpha2
(
char
*
alpha2
)
static
bool
is_an_alpha2
(
c
onst
c
har
*
alpha2
)
{
if
(
!
alpha2
)
return
false
;
...
...
@@ -97,7 +258,7 @@ static bool is_an_alpha2(char *alpha2)
return
false
;
}
static
bool
alpha2_equal
(
c
har
*
alpha2_x
,
char
*
alpha2_y
)
static
bool
alpha2_equal
(
c
onst
char
*
alpha2_x
,
const
char
*
alpha2_y
)
{
if
(
!
alpha2_x
||
!
alpha2_y
)
return
false
;
...
...
@@ -107,7 +268,7 @@ static bool alpha2_equal(char *alpha2_x, char *alpha2_y)
return
false
;
}
static
bool
regdom_changed
(
char
*
alpha2
)
static
bool
regdom_changed
(
c
onst
c
har
*
alpha2
)
{
if
(
!
cfg80211_regdomain
)
return
true
;
...
...
@@ -130,12 +291,8 @@ static int call_crda(const char *alpha2)
printk
(
KERN_INFO
"cfg80211: Calling CRDA for country: %c%c
\n
"
,
alpha2
[
0
],
alpha2
[
1
]);
else
#ifdef CONFIG_WIRELESS_OLD_REGULATORY
return
-
EINVAL
;
#else
printk
(
KERN_INFO
"cfg80211: Calling CRDA to update world "
"regulatory domain
\n
"
);
#endif
country_env
[
8
]
=
alpha2
[
0
];
country_env
[
9
]
=
alpha2
[
1
];
...
...
@@ -238,7 +395,7 @@ static int ignore_request(struct wiphy *wiphy, enum reg_set_by set_by,
}
}
static
bool
__reg_is_valid_request
(
char
*
alpha2
,
static
bool
__reg_is_valid_request
(
c
onst
c
har
*
alpha2
,
struct
regulatory_request
**
request
)
{
struct
regulatory_request
*
req
;
...
...
@@ -254,16 +411,16 @@ static bool __reg_is_valid_request(char *alpha2,
}
/* Used by nl80211 before kmalloc'ing our regulatory domain */
bool
reg_is_valid_request
(
char
*
alpha2
)
bool
reg_is_valid_request
(
c
onst
c
har
*
alpha2
)
{
struct
regulatory_request
*
request
=
NULL
;
return
__reg_is_valid_request
(
alpha2
,
&
request
);
}
/* Sanity check on a regulatory rule */
static
bool
is_valid_reg_rule
(
struct
ieee80211_reg_rule
*
rule
)
static
bool
is_valid_reg_rule
(
const
struct
ieee80211_reg_rule
*
rule
)
{
struct
ieee80211_freq_range
*
freq_range
=
&
rule
->
freq_range
;
const
struct
ieee80211_freq_range
*
freq_range
=
&
rule
->
freq_range
;
u32
freq_diff
;
if
(
freq_range
->
start_freq_khz
==
0
||
freq_range
->
end_freq_khz
==
0
)
...
...
@@ -280,9 +437,9 @@ static bool is_valid_reg_rule(struct ieee80211_reg_rule *rule)
return
true
;
}
static
bool
is_valid_rd
(
struct
ieee80211_regdomain
*
rd
)
static
bool
is_valid_rd
(
const
struct
ieee80211_regdomain
*
rd
)
{
struct
ieee80211_reg_rule
*
reg_rule
=
NULL
;
const
struct
ieee80211_reg_rule
*
reg_rule
=
NULL
;
unsigned
int
i
;
if
(
!
rd
->
n_reg_rules
)
...
...
@@ -494,12 +651,12 @@ int regulatory_hint(struct wiphy *wiphy, const char *alpha2,
EXPORT_SYMBOL
(
regulatory_hint
);
static
void
print_rd_rules
(
struct
ieee80211_regdomain
*
rd
)
static
void
print_rd_rules
(
const
struct
ieee80211_regdomain
*
rd
)
{
unsigned
int
i
;
struct
ieee80211_reg_rule
*
reg_rule
=
NULL
;
struct
ieee80211_freq_range
*
freq_range
=
NULL
;
struct
ieee80211_power_rule
*
power_rule
=
NULL
;
const
struct
ieee80211_reg_rule
*
reg_rule
=
NULL
;
const
struct
ieee80211_freq_range
*
freq_range
=
NULL
;
const
struct
ieee80211_power_rule
*
power_rule
=
NULL
;
printk
(
KERN_INFO
"
\t
(start_freq - end_freq @ bandwidth), "
"(max_antenna_gain, max_eirp)
\n
"
);
...
...
@@ -529,7 +686,7 @@ static void print_rd_rules(struct ieee80211_regdomain *rd)
}
}
static
void
print_regdomain
(
struct
ieee80211_regdomain
*
rd
)
static
void
print_regdomain
(
const
struct
ieee80211_regdomain
*
rd
)
{
if
(
is_world_regdom
(
rd
->
alpha2
))
...
...
@@ -548,85 +705,25 @@ static void print_regdomain(struct ieee80211_regdomain *rd)
print_rd_rules
(
rd
);
}
void
print_regdomain_info
(
struct
ieee80211_regdomain
*
rd
)
void
print_regdomain_info
(
const
struct
ieee80211_regdomain
*
rd
)
{
printk
(
KERN_INFO
"cfg80211: Regulatory domain: %c%c
\n
"
,
rd
->
alpha2
[
0
],
rd
->
alpha2
[
1
]);
print_rd_rules
(
rd
);
}
#ifdef CONFIG_WIRELESS_OLD_REGULATORY
static
bool
is_old_static_regdom
(
struct
ieee80211_regdomain
*
rd
)
{
if
(
rd
==
&
us_regdom
||
rd
==
&
jp_regdom
||
rd
==
&
eu_regdom
)
return
true
;
return
false
;
}
/* The old crap never deals with a world regulatory domain, it only
* deals with the static regulatory domain passed and if possible
* an updated "US" or "JP" regulatory domain. We do however store the
* old static regulatory domain in cfg80211_world_regdom for convenience
* of use here */
static
void
reset_regdomains_static
(
void
)
{
if
(
!
is_old_static_regdom
(
cfg80211_regdomain
))
kfree
(
cfg80211_regdomain
);
/* This is setting the regdom to the old static regdom */
cfg80211_regdomain
=
(
struct
ieee80211_regdomain
*
)
cfg80211_world_regdom
;
}
#else
static
void
reset_regdomains
(
void
)
{
if
(
cfg80211_world_regdom
&&
cfg80211_world_regdom
!=
&
world_regdom
)
{
if
(
cfg80211_world_regdom
==
cfg80211_regdomain
)
{
kfree
(
cfg80211_regdomain
);
}
else
{
kfree
(
cfg80211_world_regdom
);
kfree
(
cfg80211_regdomain
);
}
}
else
if
(
cfg80211_regdomain
&&
cfg80211_regdomain
!=
&
world_regdom
)
kfree
(
cfg80211_regdomain
);
cfg80211_world_regdom
=
(
struct
ieee80211_regdomain
*
)
&
world_regdom
;
cfg80211_regdomain
=
NULL
;
}
/* Dynamic world regulatory domain requested by the wireless
* core upon initialization */
static
void
update_world_regdomain
(
struct
ieee80211_regdomain
*
rd
)
{
BUG_ON
(
list_empty
(
&
regulatory_requests
));
reset_regdomains
();
cfg80211_world_regdom
=
rd
;
cfg80211_regdomain
=
rd
;
}
#endif
static
int
__set_regdom
(
struct
ieee80211_regdomain
*
rd
)
static
int
__set_regdom
(
const
struct
ieee80211_regdomain
*
rd
)
{
struct
regulatory_request
*
request
=
NULL
;
/* Some basic sanity checks first */
#ifdef CONFIG_WIRELESS_OLD_REGULATORY
/* We ignore the world regdom with the old static regdomains setup
* as there is no point to it with satic regulatory definitions :(
* Don't worry this shit will be removed soon... */
if
(
is_world_regdom
(
rd
->
alpha2
))
return
-
EINVAL
;
#else
if
(
is_world_regdom
(
rd
->
alpha2
))
{
if
(
WARN_ON
(
!
__reg_is_valid_request
(
rd
->
alpha2
,
&
request
)))
return
-
EINVAL
;
update_world_regdomain
(
rd
);
return
0
;
}
#endif
if
(
!
is_alpha2_set
(
rd
->
alpha2
)
&&
!
is_an_alpha2
(
rd
->
alpha2
)
&&
!
is_unknown_alpha2
(
rd
->
alpha2
))
...
...
@@ -635,15 +732,10 @@ static int __set_regdom(struct ieee80211_regdomain *rd)
if
(
list_empty
(
&
regulatory_requests
))
return
-
EINVAL
;
#ifdef CONFIG_WIRELESS_OLD_REGULATORY
/* Static "US" and "JP" will be overridden, but just once */
/* allow overriding the static definitions if CRDA is present */
if
(
!
is_old_static_regdom
(
cfg80211_regdomain
)
&&
!
regdom_changed
(
rd
->
alpha2
))
return
-
EINVAL
;
#else
if
(
!
regdom_changed
(
rd
->
alpha2
))
!
regdom_changed
(
rd
->
alpha2
))
return
-
EINVAL
;
#endif
/* Now lets set the regulatory domain, update all driver channels
* and finally inform them of what we have done, in case they want
...
...
@@ -653,11 +745,7 @@ static int __set_regdom(struct ieee80211_regdomain *rd)
if
(
WARN_ON
(
!
__reg_is_valid_request
(
rd
->
alpha2
,
&
request
)))
return
-
EINVAL
;
#ifdef CONFIG_WIRELESS_OLD_REGULATORY
reset_regdomains_static
();
#else
reset_regdomains
();
#endif
/* Country IE parsing coming soon */
switch
(
request
->
initiator
)
{
...
...
@@ -689,7 +777,7 @@ static int __set_regdom(struct ieee80211_regdomain *rd)
* multiple drivers can be ironed out later. Caller must've already
* kmalloc'd the rd structure. If this calls fails you should kfree()
* the passed rd. Caller must hold cfg80211_drv_mutex */
int
set_regdom
(
struct
ieee80211_regdomain
*
rd
)
int
set_regdom
(
const
struct
ieee80211_regdomain
*
rd
)
{
struct
regulatory_request
*
this_request
=
NULL
,
*
prev_request
=
NULL
;
int
r
;
...
...
@@ -735,25 +823,50 @@ int set_regdom(struct ieee80211_regdomain *rd)
int
regulatory_init
(
void
)
{
int
err
;
reg_pdev
=
platform_device_register_simple
(
"regulatory"
,
0
,
NULL
,
0
);
if
(
IS_ERR
(
reg_pdev
))
return
PTR_ERR
(
reg_pdev
);
#ifdef CONFIG_WIRELESS_OLD_REGULATORY
cfg80211_regdomain
=
static_regdom
(
ieee80211_regdom
);
printk
(
KERN_INFO
"cfg80211: Using static regulatory domain info
\n
"
);
print_regdomain_info
(
cfg80211_regdomain
);
/* The old code still requests for a new regdomain and if
* you have CRDA you get it updated, otherwise you get
* stuck with the static values. We ignore "EU" code as
* that is not a valid ISO / IEC 3166 alpha2 */
if
(
ieee80211_regdom
[
0
]
!=
'E'
&&
ieee80211_regdom
[
1
]
!=
'U'
)
err
=
__regulatory_hint
(
NULL
,
REGDOM_SET_BY_CORE
,
ieee80211_regdom
,
NULL
);
#else
cfg80211_regdomain
=
cfg80211_world_regdom
;
err
=
__regulatory_hint
(
NULL
,
REGDOM_SET_BY_CORE
,
"00"
,
NULL
);
if
(
err
)
printk
(
KERN_ERR
"cfg80211: calling CRDA failed - "
"unable to update world regulatory domain, "
"using static definition
\n
"
);
#endif
return
0
;
}
void
regulatory_exit
(
void
)
{
struct
regulatory_request
*
req
,
*
req_tmp
;
mutex_lock
(
&
cfg80211_drv_mutex
);
#ifdef CONFIG_WIRELESS_OLD_REGULATORY
reset_regdomains_static
();
#else
reset_regdomains
();
#endif
list_for_each_entry_safe
(
req
,
req_tmp
,
&
regulatory_requests
,
list
)
{
list_del
(
&
req
->
list
);
kfree
(
req
);
}
platform_device_unregister
(
reg_pdev
);
mutex_unlock
(
&
cfg80211_drv_mutex
);
}
This diff is collapsed.
Click to expand it.
net/wireless/reg.h
浏览文件 @
db4148da
#ifndef __NET_WIRELESS_REG_H
#define __NET_WIRELESS_REG_H
extern
const
struct
ieee80211_regdomain
world_regdom
;
#ifdef CONFIG_WIRELESS_OLD_REGULATORY
extern
const
struct
ieee80211_regdomain
us_regdom
;
extern
const
struct
ieee80211_regdomain
jp_regdom
;
extern
const
struct
ieee80211_regdomain
eu_regdom
;
#endif
extern
struct
ieee80211_regdomain
*
cfg80211_regdomain
;
extern
struct
ieee80211_regdomain
*
cfg80211_world_regdom
;
extern
struct
list_head
regulatory_requests
;
struct
regdom_last_setby
{
struct
wiphy
*
wiphy
;
u8
initiator
;
};
/* wiphy is set if this request's initiator is REGDOM_SET_BY_DRIVER */
struct
regulatory_request
{
struct
list_head
list
;
struct
wiphy
*
wiphy
;
int
granted
;
enum
reg_set_by
initiator
;
char
alpha2
[
2
];
};
bool
is_world_regdom
(
char
*
alpha2
);
bool
reg_is_valid_request
(
char
*
alpha2
);
int
set_regdom
(
struct
ieee80211_regdomain
*
rd
);
int
__regulatory_hint_alpha2
(
struct
wiphy
*
wiphy
,
enum
reg_set_by
set_by
,
const
char
*
alpha2
);
extern
struct
mutex
cfg80211_reg_mutex
;
bool
is_world_regdom
(
const
char
*
alpha2
);
bool
reg_is_valid_request
(
const
char
*
alpha2
);
int
regulatory_init
(
void
);
void
regulatory_exit
(
void
);
void
print_regdomain_info
(
struct
ieee80211_regdomain
*
);
/* If a char is A-Z */
#define IS_ALPHA(letter) (letter >= 65 && letter <= 90)
int
set_regdom
(
const
struct
ieee80211_regdomain
*
rd
);
#endif
/* __NET_WIRELESS_REG_H */
This diff is collapsed.
Click to expand it.
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录
反馈
建议
客服
返回
顶部