Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
ea6a634e
cloud-kernel
项目概览
openanolis
/
cloud-kernel
大约 1 年 前同步成功
通知
158
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
ea6a634e
编写于
9月 09, 2009
作者:
D
David S. Miller
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' of
git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
上级
fa1a9c68
b2e3abdc
变更
52
展开全部
隐藏空白更改
内联
并排
Showing
52 changed file
with
1673 addition
and
539 deletion
+1673
-539
Documentation/feature-removal-schedule.txt
Documentation/feature-removal-schedule.txt
+29
-0
MAINTAINERS
MAINTAINERS
+2
-0
drivers/net/b44.c
drivers/net/b44.c
+8
-2
drivers/net/wireless/Kconfig
drivers/net/wireless/Kconfig
+16
-41
drivers/net/wireless/ath/ar9170/phy.c
drivers/net/wireless/ath/ar9170/phy.c
+419
-1
drivers/net/wireless/ath/ath9k/ahb.c
drivers/net/wireless/ath/ath9k/ahb.c
+4
-6
drivers/net/wireless/ath/ath9k/ath9k.h
drivers/net/wireless/ath/ath9k/ath9k.h
+1
-1
drivers/net/wireless/ath/ath9k/btcoex.c
drivers/net/wireless/ath/ath9k/btcoex.c
+23
-0
drivers/net/wireless/ath/ath9k/btcoex.h
drivers/net/wireless/ath/ath9k/btcoex.h
+2
-0
drivers/net/wireless/ath/ath9k/hw.c
drivers/net/wireless/ath/ath9k/hw.c
+22
-8
drivers/net/wireless/ath/ath9k/hw.h
drivers/net/wireless/ath/ath9k/hw.h
+10
-0
drivers/net/wireless/ath/ath9k/mac.h
drivers/net/wireless/ath/ath9k/mac.h
+1
-0
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/ath/ath9k/main.c
+7
-5
drivers/net/wireless/ath/ath9k/pci.c
drivers/net/wireless/ath/ath9k/pci.c
+12
-10
drivers/net/wireless/ath/ath9k/recv.c
drivers/net/wireless/ath/ath9k/recv.c
+3
-0
drivers/net/wireless/ath/ath9k/reg.h
drivers/net/wireless/ath/ath9k/reg.h
+0
-1
drivers/net/wireless/ath/regd.h
drivers/net/wireless/ath/regd.h
+6
-0
drivers/net/wireless/ath/regd_common.h
drivers/net/wireless/ath/regd_common.h
+0
-6
drivers/net/wireless/b43/Kconfig
drivers/net/wireless/b43/Kconfig
+2
-2
drivers/net/wireless/b43/b43.h
drivers/net/wireless/b43/b43.h
+13
-17
drivers/net/wireless/b43/debugfs.c
drivers/net/wireless/b43/debugfs.c
+20
-47
drivers/net/wireless/b43/debugfs.h
drivers/net/wireless/b43/debugfs.h
+2
-1
drivers/net/wireless/b43/dma.c
drivers/net/wireless/b43/dma.c
+5
-26
drivers/net/wireless/b43/dma.h
drivers/net/wireless/b43/dma.h
+0
-3
drivers/net/wireless/b43/main.c
drivers/net/wireless/b43/main.c
+229
-231
drivers/net/wireless/b43/main.h
drivers/net/wireless/b43/main.h
+0
-4
drivers/net/wireless/b43/phy_common.c
drivers/net/wireless/b43/phy_common.c
+0
-1
drivers/net/wireless/b43/phy_common.h
drivers/net/wireless/b43/phy_common.h
+1
-2
drivers/net/wireless/b43/phy_g.c
drivers/net/wireless/b43/phy_g.c
+0
-7
drivers/net/wireless/b43/phy_g.h
drivers/net/wireless/b43/phy_g.h
+1
-2
drivers/net/wireless/b43/pio.c
drivers/net/wireless/b43/pio.c
+13
-58
drivers/net/wireless/b43/pio.h
drivers/net/wireless/b43/pio.h
+0
-6
drivers/net/wireless/b43/sysfs.c
drivers/net/wireless/b43/sysfs.c
+0
-3
drivers/net/wireless/b43/xmit.c
drivers/net/wireless/b43/xmit.c
+5
-5
drivers/net/wireless/b43legacy/main.c
drivers/net/wireless/b43legacy/main.c
+6
-2
drivers/net/wireless/rt2x00/rt2400pci.c
drivers/net/wireless/rt2x00/rt2400pci.c
+2
-3
drivers/net/wireless/rt2x00/rt2500pci.c
drivers/net/wireless/rt2x00/rt2500pci.c
+2
-3
drivers/net/wireless/rt2x00/rt2500usb.c
drivers/net/wireless/rt2x00/rt2500usb.c
+0
-4
drivers/net/wireless/rt2x00/rt2800usb.c
drivers/net/wireless/rt2x00/rt2800usb.c
+1
-2
drivers/net/wireless/rt2x00/rt2x00.h
drivers/net/wireless/rt2x00/rt2x00.h
+0
-3
drivers/net/wireless/rt2x00/rt2x00config.c
drivers/net/wireless/rt2x00/rt2x00config.c
+0
-11
drivers/net/wireless/rt2x00/rt61pci.c
drivers/net/wireless/rt2x00/rt61pci.c
+1
-1
drivers/net/wireless/rt2x00/rt73usb.c
drivers/net/wireless/rt2x00/rt73usb.c
+1
-1
drivers/ssb/Kconfig
drivers/ssb/Kconfig
+14
-0
drivers/ssb/Makefile
drivers/ssb/Makefile
+1
-0
drivers/ssb/main.c
drivers/ssb/main.c
+61
-3
drivers/ssb/scan.c
drivers/ssb/scan.c
+11
-0
drivers/ssb/sdio.c
drivers/ssb/sdio.c
+610
-0
drivers/ssb/ssb_private.h
drivers/ssb/ssb_private.h
+40
-0
include/linux/ssb/ssb.h
include/linux/ssb/ssb.h
+23
-2
net/wireless/Kconfig
net/wireless/Kconfig
+10
-1
net/wireless/scan.c
net/wireless/scan.c
+34
-7
未找到文件。
Documentation/feature-removal-schedule.txt
浏览文件 @
ea6a634e
...
...
@@ -6,6 +6,35 @@ be removed from this file.
---------------------------
What: PRISM54
When: 2.6.34
Why: prism54 FullMAC PCI / Cardbus devices used to be supported only by the
prism54 wireless driver. After Intersil stopped selling these
devices in preference for the newer more flexible SoftMAC devices
a SoftMAC device driver was required and prism54 did not support
them. The p54pci driver now exists and has been present in the kernel for
a while. This driver supports both SoftMAC devices and FullMAC devices.
The main difference between these devices was the amount of memory which
could be used for the firmware. The SoftMAC devices support a smaller
amount of memory. Because of this the SoftMAC firmware fits into FullMAC
devices's memory. p54pci supports not only PCI / Cardbus but also USB
and SPI. Since p54pci supports all devices prism54 supports
you will have a conflict. I'm not quite sure how distributions are
handling this conflict right now. prism54 was kept around due to
claims users may experience issues when using the SoftMAC driver.
Time has passed users have not reported issues. If you use prism54
and for whatever reason you cannot use p54pci please let us know!
E-mail us at: linux-wireless@vger.kernel.org
For more information see the p54 wiki page:
http://wireless.kernel.org/en/users/Drivers/p54
Who: Luis R. Rodriguez <lrodriguez@atheros.com>
---------------------------
What: IRQF_SAMPLE_RANDOM
Check: IRQF_SAMPLE_RANDOM
When: July 2009
...
...
MAINTAINERS
浏览文件 @
ea6a634e
...
...
@@ -876,6 +876,7 @@ M: "Luis R. Rodriguez" <lrodriguez@atheros.com>
M: Bob Copeland <me@bobcopeland.com>
L: linux-wireless@vger.kernel.org
L: ath5k-devel@lists.ath5k.org
W: http://wireless.kernel.org/en/users/Drivers/ath5k
S: Maintained
F: drivers/net/wireless/ath/ath5k/
...
...
@@ -887,6 +888,7 @@ M: Vasanthakumar Thiagarajan <vasanth@atheros.com>
M: Senthil Balasubramanian <senthilkumar@atheros.com>
L: linux-wireless@vger.kernel.org
L: ath9k-devel@lists.ath9k.org
W: http://wireless.kernel.org/en/users/Drivers/ath9k
S: Supported
F: drivers/net/wireless/ath/ath9k/
...
...
drivers/net/b44.c
浏览文件 @
ea6a634e
...
...
@@ -1303,10 +1303,13 @@ static void b44_chip_reset(struct b44 *bp, int reset_kind)
&
MDIO_CTRL_MAXF_MASK
)));
break
;
case
SSB_BUSTYPE_PCI
:
case
SSB_BUSTYPE_PCMCIA
:
bw32
(
bp
,
B44_MDIO_CTRL
,
(
MDIO_CTRL_PREAMBLE
|
(
0x0d
&
MDIO_CTRL_MAXF_MASK
)));
break
;
case
SSB_BUSTYPE_PCMCIA
:
case
SSB_BUSTYPE_SDIO
:
WARN_ON
(
1
);
/* A device with this bus does not exist. */
break
;
}
br32
(
bp
,
B44_MDIO_CTRL
);
...
...
@@ -1764,10 +1767,13 @@ static void b44_get_drvinfo (struct net_device *dev, struct ethtool_drvinfo *inf
case
SSB_BUSTYPE_PCI
:
strlcpy
(
info
->
bus_info
,
pci_name
(
bus
->
host_pci
),
sizeof
(
info
->
bus_info
));
break
;
case
SSB_BUSTYPE_PCMCIA
:
case
SSB_BUSTYPE_SSB
:
strlcpy
(
info
->
bus_info
,
"SSB"
,
sizeof
(
info
->
bus_info
));
break
;
case
SSB_BUSTYPE_PCMCIA
:
case
SSB_BUSTYPE_SDIO
:
WARN_ON
(
1
);
/* A device with this bus does not exist. */
break
;
}
}
...
...
drivers/net/wireless/Kconfig
浏览文件 @
ea6a634e
...
...
@@ -275,51 +275,26 @@ config PCMCIA_WL3501
micro support for ethtool.
config PRISM54
tristate 'Intersil Prism GT/Duette/Indigo PCI/Cardbus
'
tristate 'Intersil Prism GT/Duette/Indigo PCI/Cardbus
(DEPRECATED)'
depends on PCI && EXPERIMENTAL && WLAN_80211
select WIRELESS_EXT
select FW_LOADER
---help---
Enable PCI and Cardbus support for the following chipset based cards:
ISL3880 - Prism GT 802.11 b/g
ISL3877 - Prism Indigo 802.11 a
ISL3890 - Prism Duette 802.11 a/b/g
For a complete list of supported cards visit <http://prism54.org>.
Here is the latest confirmed list of supported cards:
3com OfficeConnect 11g Cardbus Card aka 3CRWE154G72 (version 1)
Allnet ALL0271 PCI Card
Compex WL54G Cardbus Card
Corega CG-WLCB54GT Cardbus Card
D-Link Air Plus Xtreme G A1 Cardbus Card aka DWL-g650
I-O Data WN-G54/CB Cardbus Card
Kobishi XG-300 aka Z-Com Cardbus Card
Netgear WG511 Cardbus Card
Ovislink WL-5400PCI PCI Card
Peabird WLG-PCI PCI Card
Sitecom WL-100i Cardbus Card
Sitecom WL-110i PCI Card
SMC2802W - EZ Connect g 2.4GHz 54 Mbps Wireless PCI Card
SMC2835W - EZ Connect g 2.4GHz 54 Mbps Wireless Cardbus Card
SMC2835W-V2 - EZ Connect g 2.4GHz 54 Mbps Wireless Cardbus Card
Z-Com XG-900 PCI Card
Zyxel G-100 Cardbus Card
If you enable this you will need a firmware file as well.
You will need to copy this to /usr/lib/hotplug/firmware/isl3890.
You can get this non-GPL'd firmware file from the Prism54 project page:
<http://prism54.org>
You will also need the /etc/hotplug/firmware.agent script from
a current hotplug package.
Note: You need a motherboard with DMA support to use any of these cards
If you want to compile the driver as a module ( = code which can be
inserted in and removed from the running kernel whenever you want),
say M here and read <file:Documentation/kbuild/modules.txt>.
The module will be called prism54.
This enables support for FullMAC PCI/Cardbus prism54 devices. This
driver is now deprecated in favor for the SoftMAC driver, p54pci.
p54pci supports FullMAC PCI/Cardbus devices as well. For details on
the scheduled removal of this driver on the kernel see the feature
removal schedule:
Documentation/feature-removal-schedule.txt
For more information refer to the p54 wiki:
http://wireless.kernel.org/en/users/Drivers/p54
Note: You need a motherboard with DMA support to use any of these cards
When built as module you get the module prism54
config USB_ZD1201
tristate "USB ZD1201 based Wireless device support"
...
...
drivers/net/wireless/ath/ar9170/phy.c
浏览文件 @
ea6a634e
...
...
@@ -396,6 +396,136 @@ static struct ar9170_phy_init ar5416_phy_init[] = {
{
0x1c9384
,
0xf3307ff0
,
0xf3307ff0
,
0xf3307ff0
,
0xf3307ff0
,
}
};
/*
* look up a certain register in ar5416_phy_init[] and return the init. value
* for the band and bandwidth given. Return 0 if register address not found.
*/
static
u32
ar9170_get_default_phy_reg_val
(
u32
reg
,
bool
is_2ghz
,
bool
is_40mhz
)
{
unsigned
int
i
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
ar5416_phy_init
);
i
++
)
{
if
(
ar5416_phy_init
[
i
].
reg
!=
reg
)
continue
;
if
(
is_2ghz
)
{
if
(
is_40mhz
)
return
ar5416_phy_init
[
i
].
_2ghz_40
;
else
return
ar5416_phy_init
[
i
].
_2ghz_20
;
}
else
{
if
(
is_40mhz
)
return
ar5416_phy_init
[
i
].
_5ghz_40
;
else
return
ar5416_phy_init
[
i
].
_5ghz_20
;
}
}
return
0
;
}
/*
* initialize some phy regs from eeprom values in modal_header[]
* acc. to band and bandwith
*/
static
int
ar9170_init_phy_from_eeprom
(
struct
ar9170
*
ar
,
bool
is_2ghz
,
bool
is_40mhz
)
{
static
const
u8
xpd2pd
[
16
]
=
{
0x2
,
0x2
,
0x2
,
0x1
,
0x2
,
0x2
,
0x6
,
0x2
,
0x2
,
0x3
,
0x7
,
0x2
,
0xB
,
0x2
,
0x2
,
0x2
};
u32
defval
,
newval
;
/* pointer to the modal_header acc. to band */
struct
ar9170_eeprom_modal
*
m
=
&
ar
->
eeprom
.
modal_header
[
is_2ghz
];
ar9170_regwrite_begin
(
ar
);
/* ant common control (index 0) */
newval
=
le32_to_cpu
(
m
->
antCtrlCommon
);
ar9170_regwrite
(
0x1c5964
,
newval
);
/* ant control chain 0 (index 1) */
newval
=
le32_to_cpu
(
m
->
antCtrlChain
[
0
]);
ar9170_regwrite
(
0x1c5960
,
newval
);
/* ant control chain 2 (index 2) */
newval
=
le32_to_cpu
(
m
->
antCtrlChain
[
1
]);
ar9170_regwrite
(
0x1c7960
,
newval
);
/* SwSettle (index 3) */
if
(
!
is_40mhz
)
{
defval
=
ar9170_get_default_phy_reg_val
(
0x1c5844
,
is_2ghz
,
is_40mhz
);
newval
=
(
defval
&
~
0x3f80
)
|
((
m
->
switchSettling
&
0x7f
)
<<
7
);
ar9170_regwrite
(
0x1c5844
,
newval
);
}
/* adcDesired, pdaDesired (index 4) */
defval
=
ar9170_get_default_phy_reg_val
(
0x1c5850
,
is_2ghz
,
is_40mhz
);
newval
=
(
defval
&
~
0xffff
)
|
((
u8
)
m
->
pgaDesiredSize
<<
8
)
|
((
u8
)
m
->
adcDesiredSize
);
ar9170_regwrite
(
0x1c5850
,
newval
);
/* TxEndToXpaOff, TxFrameToXpaOn (index 5) */
defval
=
ar9170_get_default_phy_reg_val
(
0x1c5834
,
is_2ghz
,
is_40mhz
);
newval
=
(
m
->
txEndToXpaOff
<<
24
)
|
(
m
->
txEndToXpaOff
<<
16
)
|
(
m
->
txFrameToXpaOn
<<
8
)
|
m
->
txFrameToXpaOn
;
ar9170_regwrite
(
0x1c5834
,
newval
);
/* TxEndToRxOn (index 6) */
defval
=
ar9170_get_default_phy_reg_val
(
0x1c5828
,
is_2ghz
,
is_40mhz
);
newval
=
(
defval
&
~
0xff0000
)
|
(
m
->
txEndToRxOn
<<
16
);
ar9170_regwrite
(
0x1c5828
,
newval
);
/* thresh62 (index 7) */
defval
=
ar9170_get_default_phy_reg_val
(
0x1c8864
,
is_2ghz
,
is_40mhz
);
newval
=
(
defval
&
~
0x7f000
)
|
(
m
->
thresh62
<<
12
);
ar9170_regwrite
(
0x1c8864
,
newval
);
/* tx/rx attenuation chain 0 (index 8) */
defval
=
ar9170_get_default_phy_reg_val
(
0x1c5848
,
is_2ghz
,
is_40mhz
);
newval
=
(
defval
&
~
0x3f000
)
|
((
m
->
txRxAttenCh
[
0
]
&
0x3f
)
<<
12
);
ar9170_regwrite
(
0x1c5848
,
newval
);
/* tx/rx attenuation chain 2 (index 9) */
defval
=
ar9170_get_default_phy_reg_val
(
0x1c7848
,
is_2ghz
,
is_40mhz
);
newval
=
(
defval
&
~
0x3f000
)
|
((
m
->
txRxAttenCh
[
1
]
&
0x3f
)
<<
12
);
ar9170_regwrite
(
0x1c7848
,
newval
);
/* tx/rx margin chain 0 (index 10) */
defval
=
ar9170_get_default_phy_reg_val
(
0x1c620c
,
is_2ghz
,
is_40mhz
);
newval
=
(
defval
&
~
0xfc0000
)
|
((
m
->
rxTxMarginCh
[
0
]
&
0x3f
)
<<
18
);
/* bsw margin chain 0 for 5GHz only */
if
(
!
is_2ghz
)
newval
=
(
newval
&
~
0x3c00
)
|
((
m
->
bswMargin
[
0
]
&
0xf
)
<<
10
);
ar9170_regwrite
(
0x1c620c
,
newval
);
/* tx/rx margin chain 2 (index 11) */
defval
=
ar9170_get_default_phy_reg_val
(
0x1c820c
,
is_2ghz
,
is_40mhz
);
newval
=
(
defval
&
~
0xfc0000
)
|
((
m
->
rxTxMarginCh
[
1
]
&
0x3f
)
<<
18
);
ar9170_regwrite
(
0x1c820c
,
newval
);
/* iqCall, iqCallq chain 0 (index 12) */
defval
=
ar9170_get_default_phy_reg_val
(
0x1c5920
,
is_2ghz
,
is_40mhz
);
newval
=
(
defval
&
~
0x7ff
)
|
(((
u8
)
m
->
iqCalICh
[
0
]
&
0x3f
)
<<
5
)
|
((
u8
)
m
->
iqCalQCh
[
0
]
&
0x1f
);
ar9170_regwrite
(
0x1c5920
,
newval
);
/* iqCall, iqCallq chain 2 (index 13) */
defval
=
ar9170_get_default_phy_reg_val
(
0x1c7920
,
is_2ghz
,
is_40mhz
);
newval
=
(
defval
&
~
0x7ff
)
|
(((
u8
)
m
->
iqCalICh
[
1
]
&
0x3f
)
<<
5
)
|
((
u8
)
m
->
iqCalQCh
[
1
]
&
0x1f
);
ar9170_regwrite
(
0x1c7920
,
newval
);
/* xpd gain mask (index 14) */
defval
=
ar9170_get_default_phy_reg_val
(
0x1c6258
,
is_2ghz
,
is_40mhz
);
newval
=
(
defval
&
~
0xf0000
)
|
(
xpd2pd
[
m
->
xpdGain
&
0xf
]
<<
16
);
ar9170_regwrite
(
0x1c6258
,
newval
);
ar9170_regwrite_finish
();
return
ar9170_regwrite_result
();
}
int
ar9170_init_phy
(
struct
ar9170
*
ar
,
enum
ieee80211_band
band
)
{
int
i
,
err
;
...
...
@@ -426,7 +556,9 @@ int ar9170_init_phy(struct ar9170 *ar, enum ieee80211_band band)
if
(
err
)
return
err
;
/* XXX: use EEPROM data here! */
err
=
ar9170_init_phy_from_eeprom
(
ar
,
is_2ghz
,
is_40mhz
);
if
(
err
)
return
err
;
err
=
ar9170_init_power_cal
(
ar
);
if
(
err
)
...
...
@@ -987,6 +1119,282 @@ static u8 ar9170_interpolate_u8(u8 x, u8 x1, u8 y1, u8 x2, u8 y2)
#undef SHIFT
}
static
u8
ar9170_interpolate_val
(
u8
x
,
u8
*
x_array
,
u8
*
y_array
)
{
int
i
;
for
(
i
=
0
;
i
<
3
;
i
++
)
if
(
x
<=
x_array
[
i
+
1
])
break
;
return
ar9170_interpolate_u8
(
x
,
x_array
[
i
],
y_array
[
i
],
x_array
[
i
+
1
],
y_array
[
i
+
1
]);
}
static
int
ar9170_set_freq_cal_data
(
struct
ar9170
*
ar
,
struct
ieee80211_channel
*
channel
)
{
u8
*
cal_freq_pier
;
u8
vpds
[
2
][
AR5416_PD_GAIN_ICEPTS
];
u8
pwrs
[
2
][
AR5416_PD_GAIN_ICEPTS
];
int
chain
,
idx
,
i
;
u8
f
;
switch
(
channel
->
band
)
{
case
IEEE80211_BAND_2GHZ
:
f
=
channel
->
center_freq
-
2300
;
cal_freq_pier
=
ar
->
eeprom
.
cal_freq_pier_2G
;
i
=
AR5416_NUM_2G_CAL_PIERS
-
1
;
break
;
case
IEEE80211_BAND_5GHZ
:
f
=
(
channel
->
center_freq
-
4800
)
/
5
;
cal_freq_pier
=
ar
->
eeprom
.
cal_freq_pier_5G
;
i
=
AR5416_NUM_5G_CAL_PIERS
-
1
;
break
;
default:
return
-
EINVAL
;
break
;
}
for
(;
i
>=
0
;
i
--
)
{
if
(
cal_freq_pier
[
i
]
!=
0xff
)
break
;
}
if
(
i
<
0
)
return
-
EINVAL
;
idx
=
ar9170_find_freq_idx
(
i
,
cal_freq_pier
,
f
);
ar9170_regwrite_begin
(
ar
);
for
(
chain
=
0
;
chain
<
AR5416_MAX_CHAINS
;
chain
++
)
{
for
(
i
=
0
;
i
<
AR5416_PD_GAIN_ICEPTS
;
i
++
)
{
struct
ar9170_calibration_data_per_freq
*
cal_pier_data
;
int
j
;
switch
(
channel
->
band
)
{
case
IEEE80211_BAND_2GHZ
:
cal_pier_data
=
&
ar
->
eeprom
.
cal_pier_data_2G
[
chain
][
idx
];
break
;
case
IEEE80211_BAND_5GHZ
:
cal_pier_data
=
&
ar
->
eeprom
.
cal_pier_data_5G
[
chain
][
idx
];
break
;
default:
return
-
EINVAL
;
}
for
(
j
=
0
;
j
<
2
;
j
++
)
{
vpds
[
j
][
i
]
=
ar9170_interpolate_u8
(
f
,
cal_freq_pier
[
idx
],
cal_pier_data
->
vpd_pdg
[
j
][
i
],
cal_freq_pier
[
idx
+
1
],
cal_pier_data
[
1
].
vpd_pdg
[
j
][
i
]);
pwrs
[
j
][
i
]
=
ar9170_interpolate_u8
(
f
,
cal_freq_pier
[
idx
],
cal_pier_data
->
pwr_pdg
[
j
][
i
],
cal_freq_pier
[
idx
+
1
],
cal_pier_data
[
1
].
pwr_pdg
[
j
][
i
])
/
2
;
}
}
for
(
i
=
0
;
i
<
76
;
i
++
)
{
u32
phy_data
;
u8
tmp
;
if
(
i
<
25
)
{
tmp
=
ar9170_interpolate_val
(
i
,
&
pwrs
[
0
][
0
],
&
vpds
[
0
][
0
]);
}
else
{
tmp
=
ar9170_interpolate_val
(
i
-
12
,
&
pwrs
[
1
][
0
],
&
vpds
[
1
][
0
]);
}
phy_data
|=
tmp
<<
((
i
&
3
)
<<
3
);
if
((
i
&
3
)
==
3
)
{
ar9170_regwrite
(
0x1c6280
+
chain
*
0x1000
+
(
i
&
~
3
),
phy_data
);
phy_data
=
0
;
}
}
for
(
i
=
19
;
i
<
32
;
i
++
)
ar9170_regwrite
(
0x1c6280
+
chain
*
0x1000
+
(
i
<<
2
),
0x0
);
}
ar9170_regwrite_finish
();
return
ar9170_regwrite_result
();
}
static
u8
ar9170_get_max_edge_power
(
struct
ar9170
*
ar
,
struct
ar9170_calctl_edges
edges
[],
u32
freq
)
{
/* TODO: move somewhere else */
#define AR5416_MAX_RATE_POWER 63
int
i
;
u8
rc
=
AR5416_MAX_RATE_POWER
;
u8
f
;
if
(
freq
<
3000
)
f
=
freq
-
2300
;
else
f
=
(
freq
-
4800
)
/
5
;
for
(
i
=
0
;
i
<
AR5416_NUM_BAND_EDGES
;
i
++
)
{
if
(
edges
[
i
].
channel
==
0xff
)
break
;
if
(
f
==
edges
[
i
].
channel
)
{
/* exact freq match */
rc
=
edges
[
i
].
power_flags
&
~
AR9170_CALCTL_EDGE_FLAGS
;
break
;
}
if
(
i
>
0
&&
f
<
edges
[
i
].
channel
)
{
if
(
f
>
edges
[
i
-
1
].
channel
&&
edges
[
i
-
1
].
power_flags
&
AR9170_CALCTL_EDGE_FLAGS
)
{
/* lower channel has the inband flag set */
rc
=
edges
[
i
-
1
].
power_flags
&
~
AR9170_CALCTL_EDGE_FLAGS
;
}
break
;
}
}
if
(
i
==
AR5416_NUM_BAND_EDGES
)
{
if
(
f
>
edges
[
i
-
1
].
channel
&&
edges
[
i
-
1
].
power_flags
&
AR9170_CALCTL_EDGE_FLAGS
)
{
/* lower channel has the inband flag set */
rc
=
edges
[
i
-
1
].
power_flags
&
~
AR9170_CALCTL_EDGE_FLAGS
;
}
}
return
rc
;
}
/* calculate the conformance test limits and apply them to ar->power*
* (derived from otus hal/hpmain.c, line 3706 ff.)
*/
static
void
ar9170_calc_ctl
(
struct
ar9170
*
ar
,
u32
freq
,
enum
ar9170_bw
bw
)
{
u8
ctl_grp
;
/* CTL group */
u8
ctl_idx
;
/* CTL index */
int
i
,
j
;
struct
ctl_modes
{
u8
ctl_mode
;
u8
max_power
;
u8
*
pwr_cal_data
;
int
pwr_cal_len
;
}
*
modes
;
/* order is relevant in the mode_list_*: we fall back to the
* lower indices if any mode is missed in the EEPROM.
*/
struct
ctl_modes
mode_list_2ghz
[]
=
{
{
CTL_11B
,
0
,
ar
->
power_2G_cck
,
4
},
{
CTL_11G
,
0
,
ar
->
power_2G_ofdm
,
4
},
{
CTL_2GHT20
,
0
,
ar
->
power_2G_ht20
,
8
},
{
CTL_2GHT40
,
0
,
ar
->
power_2G_ht40
,
8
},
};
struct
ctl_modes
mode_list_5ghz
[]
=
{
{
CTL_11A
,
0
,
ar
->
power_5G_leg
,
4
},
{
CTL_5GHT20
,
0
,
ar
->
power_5G_ht20
,
8
},
{
CTL_5GHT40
,
0
,
ar
->
power_5G_ht40
,
8
},
};
int
nr_modes
;
#define EDGES(c, n) (ar->eeprom.ctl_data[c].control_edges[n])
/* TODO: investigate the differences between OTUS'
* hpreg.c::zfHpGetRegulatoryDomain() and
* ath/regd.c::ath_regd_get_band_ctl() -
* e.g. for FCC3_WORLD the OTUS procedure
* always returns CTL_FCC, while the one in ath/ delivers
* CTL_ETSI for 2GHz and CTL_FCC for 5GHz.
*/
ctl_grp
=
ath_regd_get_band_ctl
(
&
ar
->
common
.
regulatory
,
ar
->
hw
->
conf
.
channel
->
band
);
/* ctl group not found - either invalid band (NO_CTL) or ww roaming */
if
(
ctl_grp
==
NO_CTL
||
ctl_grp
==
SD_NO_CTL
)
ctl_grp
=
CTL_FCC
;
if
(
ctl_grp
!=
CTL_FCC
)
/* skip CTL and heavy clip for CTL_MKK and CTL_ETSI */
return
;
if
(
ar
->
hw
->
conf
.
channel
->
band
==
IEEE80211_BAND_2GHZ
)
{
modes
=
mode_list_2ghz
;
nr_modes
=
ARRAY_SIZE
(
mode_list_2ghz
);
}
else
{
modes
=
mode_list_5ghz
;
nr_modes
=
ARRAY_SIZE
(
mode_list_5ghz
);
}
for
(
i
=
0
;
i
<
nr_modes
;
i
++
)
{
u8
c
=
ctl_grp
|
modes
[
i
].
ctl_mode
;
for
(
ctl_idx
=
0
;
ctl_idx
<
AR5416_NUM_CTLS
;
ctl_idx
++
)
if
(
c
==
ar
->
eeprom
.
ctl_index
[
ctl_idx
])
break
;
if
(
ctl_idx
<
AR5416_NUM_CTLS
)
{
int
f_off
=
0
;
/* adjust freq for 40MHz */
if
(
modes
[
i
].
ctl_mode
==
CTL_2GHT40
||
modes
[
i
].
ctl_mode
==
CTL_5GHT40
)
{
if
(
bw
==
AR9170_BW_40_BELOW
)
f_off
=
-
10
;
else
f_off
=
10
;
}
modes
[
i
].
max_power
=
ar9170_get_max_edge_power
(
ar
,
EDGES
(
ctl_idx
,
1
),
freq
+
f_off
);
/* TODO: check if the regulatory max. power is
* controlled by cfg80211 for DFS
* (hpmain applies it to max_power itself for DFS freq)
*/
}
else
{
/* Workaround in otus driver, hpmain.c, line 3906:
* if no data for 5GHT20 are found, take the
* legacy 5G value.
* We extend this here to fallback from any other *HT or
* 11G, too.
*/
int
k
=
i
;
modes
[
i
].
max_power
=
AR5416_MAX_RATE_POWER
;
while
(
k
--
>
0
)
{
if
(
modes
[
k
].
max_power
!=
AR5416_MAX_RATE_POWER
)
{
modes
[
i
].
max_power
=
modes
[
k
].
max_power
;
break
;
}
}
}
/* apply max power to pwr_cal_data (ar->power_*) */
for
(
j
=
0
;
j
<
modes
[
i
].
pwr_cal_len
;
j
++
)
{
modes
[
i
].
pwr_cal_data
[
j
]
=
min
(
modes
[
i
].
pwr_cal_data
[
j
],
modes
[
i
].
max_power
);
}
}
#undef EDGES
}
static
int
ar9170_set_power_cal
(
struct
ar9170
*
ar
,
u32
freq
,
enum
ar9170_bw
bw
)
{
struct
ar9170_calibration_target_power_legacy
*
ctpl
;
...
...
@@ -1089,6 +1497,12 @@ static int ar9170_set_power_cal(struct ar9170 *ar, u32 freq, enum ar9170_bw bw)
ctph
[
idx
+
1
].
power
[
n
]);
}
/* calc. conformance test limits and apply to ar->power*[] */
ar9170_calc_ctl
(
ar
,
freq
,
bw
);
/* TODO: (heavy clip) regulatory domain power level fine-tuning. */
/* set ACK/CTS TX power */
ar9170_regwrite_begin
(
ar
);
...
...
@@ -1207,6 +1621,10 @@ int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
if
(
err
)
return
err
;
err
=
ar9170_set_freq_cal_data
(
ar
,
channel
);
if
(
err
)
return
err
;
err
=
ar9170_set_power_cal
(
ar
,
channel
->
center_freq
,
bw
);
if
(
err
)
return
err
;
...
...
drivers/net/wireless/ath/ath9k/ahb.c
浏览文件 @
ea6a634e
...
...
@@ -119,17 +119,15 @@ static int ath_ahb_probe(struct platform_device *pdev)
sc
->
bus_ops
=
&
ath_ahb_bus_ops
;
sc
->
irq
=
irq
;
ret
=
ath_init_device
(
AR5416_AR9100_DEVID
,
sc
);
if
(
ret
!=
0
)
{
dev_err
(
&
pdev
->
dev
,
"failed to attach device, err=%d
\n
"
,
ret
);
ret
=
-
ENODEV
;
ret
=
ath_init_device
(
AR5416_AR9100_DEVID
,
sc
,
0x0
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"failed to initialize device
\n
"
);
goto
err_free_hw
;
}
ret
=
request_irq
(
irq
,
ath_isr
,
IRQF_SHARED
,
"ath9k"
,
sc
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"request_irq failed, err=%d
\n
"
,
ret
);
ret
=
-
EIO
;
dev_err
(
&
pdev
->
dev
,
"request_irq failed
\n
"
);
goto
err_detach
;
}
...
...
drivers/net/wireless/ath/ath9k/ath9k.h
浏览文件 @
ea6a634e
...
...
@@ -658,7 +658,7 @@ extern struct ieee80211_ops ath9k_ops;
irqreturn_t
ath_isr
(
int
irq
,
void
*
dev
);
void
ath_cleanup
(
struct
ath_softc
*
sc
);
int
ath_init_device
(
u16
devid
,
struct
ath_softc
*
sc
);
int
ath_init_device
(
u16
devid
,
struct
ath_softc
*
sc
,
u16
subsysid
);
void
ath_detach
(
struct
ath_softc
*
sc
);
const
char
*
ath_mac_bb_name
(
u32
mac_bb_version
);
const
char
*
ath_rf_name
(
u16
rf_version
);
...
...
drivers/net/wireless/ath/ath9k/btcoex.c
浏览文件 @
ea6a634e
...
...
@@ -19,6 +19,29 @@
static
const
struct
ath_btcoex_config
ath_bt_config
=
{
0
,
true
,
true
,
ATH_BT_COEX_MODE_SLOTTED
,
true
,
true
,
2
,
5
,
true
};
static
const
u16
ath_subsysid_tbl
[]
=
{
AR9280_COEX2WIRE_SUBSYSID
,
AT9285_COEX3WIRE_SA_SUBSYSID
,
AT9285_COEX3WIRE_DA_SUBSYSID
};
/*
* Checks the subsystem id of the device to see if it
* supports btcoex
*/
bool
ath_btcoex_supported
(
u16
subsysid
)
{
int
i
;
if
(
!
subsysid
)
return
false
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
ath_subsysid_tbl
);
i
++
)
if
(
subsysid
==
ath_subsysid_tbl
[
i
])
return
true
;
return
false
;
}
/*
* Detects if there is any priority bt traffic
...
...
drivers/net/wireless/ath/ath9k/btcoex.h
浏览文件 @
ea6a634e
...
...
@@ -19,6 +19,7 @@
#define ATH_WLANACTIVE_GPIO 5
#define ATH_BTACTIVE_GPIO 6
#define ATH_BTPRIORITY_GPIO 7
#define ATH_BTCOEX_DEF_BT_PERIOD 45
#define ATH_BTCOEX_DEF_DUTY_CYCLE 55
...
...
@@ -79,6 +80,7 @@ struct ath_btcoex_info {
struct
ath_gen_timer
*
no_stomp_timer
;
/*Timer for no BT stomping*/
};
bool
ath_btcoex_supported
(
u16
subsysid
);
int
ath9k_hw_btcoex_init
(
struct
ath_hw
*
ah
);
void
ath9k_hw_btcoex_enable
(
struct
ath_hw
*
ah
);
void
ath9k_hw_btcoex_disable
(
struct
ath_hw
*
ah
);
...
...
drivers/net/wireless/ath/ath9k/hw.c
浏览文件 @
ea6a634e
...
...
@@ -16,14 +16,11 @@
#include <linux/io.h>
#include <asm/unaligned.h>
#include <linux/pci.h>
#include "ath9k.h"
#include "initvals.h"
static
int
btcoex_enable
;
module_param
(
btcoex_enable
,
bool
,
0
);
MODULE_PARM_DESC
(
btcoex_enable
,
"Enable Bluetooth coexistence support"
);
#define ATH9K_CLOCK_RATE_CCK 22
#define ATH9K_CLOCK_RATE_5GHZ_OFDM 40
#define ATH9K_CLOCK_RATE_2GHZ_OFDM 44
...
...
@@ -3689,14 +3686,17 @@ void ath9k_hw_fill_cap_info(struct ath_hw *ah)
pCap
->
num_antcfg_2ghz
=
ah
->
eep_ops
->
get_num_ant_config
(
ah
,
ATH9K_HAL_FREQ_BAND_2GHZ
);
if
(
AR_SREV_9280_10_OR_LATER
(
ah
)
&&
btcoex_enable
)
{
if
(
AR_SREV_9280_10_OR_LATER
(
ah
)
&&
ath_btcoex_supported
(
ah
->
hw_version
.
subsysid
))
{
btcoex_info
->
btactive_gpio
=
ATH_BTACTIVE_GPIO
;
btcoex_info
->
wlanactive_gpio
=
ATH_WLANACTIVE_GPIO
;
if
(
AR_SREV_9285
(
ah
))
if
(
AR_SREV_9285
(
ah
))
{
btcoex_info
->
btcoex_scheme
=
ATH_BTCOEX_CFG_3WIRE
;
else
btcoex_info
->
btpriority_gpio
=
ATH_BTPRIORITY_GPIO
;
}
else
{
btcoex_info
->
btcoex_scheme
=
ATH_BTCOEX_CFG_2WIRE
;
}
}
else
{
btcoex_info
->
btcoex_scheme
=
ATH_BTCOEX_CFG_NONE
;
}
...
...
@@ -3967,7 +3967,8 @@ void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits)
{
u32
phybits
;
REG_WRITE
(
ah
,
AR_RX_FILTER
,
(
bits
&
0xffff
)
|
AR_RX_COMPR_BAR
);
REG_WRITE
(
ah
,
AR_RX_FILTER
,
bits
);
phybits
=
0
;
if
(
bits
&
ATH9K_RX_FILTER_PHYRADAR
)
phybits
|=
AR_PHY_ERR_RADAR
;
...
...
@@ -4297,3 +4298,16 @@ void ath_gen_timer_isr(struct ath_hw *ah)
timer
->
trigger
(
timer
->
arg
);
}
}
/*
* Primitive to disable ASPM
*/
void
ath_pcie_aspm_disable
(
struct
ath_softc
*
sc
)
{
struct
pci_dev
*
pdev
=
to_pci_dev
(
sc
->
dev
);
u8
aspm
;
pci_read_config_byte
(
pdev
,
ATH_PCIE_CAP_LINK_CTRL
,
&
aspm
);
aspm
&=
~
(
ATH_PCIE_CAP_LINK_L0S
|
ATH_PCIE_CAP_LINK_L1
);
pci_write_config_byte
(
pdev
,
ATH_PCIE_CAP_LINK_CTRL
,
aspm
);
}
drivers/net/wireless/ath/ath9k/hw.h
浏览文件 @
ea6a634e
...
...
@@ -45,6 +45,10 @@
#define AR5416_DEVID_AR9287_PCI 0x002D
#define AR5416_DEVID_AR9287_PCIE 0x002E
#define AR9280_COEX2WIRE_SUBSYSID 0x309b
#define AT9285_COEX3WIRE_SA_SUBSYSID 0x30aa
#define AT9285_COEX3WIRE_DA_SUBSYSID 0x30ab
/* Register read/write primitives */
#define REG_WRITE(_ah, _reg, _val) ath9k_iowrite32((_ah), (_reg), (_val))
#define REG_READ(_ah, _reg) ath9k_ioread32((_ah), (_reg))
...
...
@@ -390,6 +394,7 @@ struct ath9k_hw_version {
u16
phyRev
;
u16
analog5GhzRev
;
u16
analog2GhzRev
;
u16
subsysid
;
};
/* Generic TSF timer definitions */
...
...
@@ -665,4 +670,9 @@ void ath_gen_timer_free(struct ath_hw *ah, struct ath_gen_timer *timer);
void
ath_gen_timer_isr
(
struct
ath_hw
*
hw
);
u32
ath9k_hw_gettsf32
(
struct
ath_hw
*
ah
);
#define ATH_PCIE_CAP_LINK_CTRL 0x70
#define ATH_PCIE_CAP_LINK_L0S 1
#define ATH_PCIE_CAP_LINK_L1 2
void
ath_pcie_aspm_disable
(
struct
ath_softc
*
sc
);
#endif
drivers/net/wireless/ath/ath9k/mac.h
浏览文件 @
ea6a634e
...
...
@@ -568,6 +568,7 @@ enum ath9k_rx_filter {
ATH9K_RX_FILTER_PROBEREQ
=
0x00000080
,
ATH9K_RX_FILTER_PHYERR
=
0x00000100
,
ATH9K_RX_FILTER_MYBEACON
=
0x00000200
,
ATH9K_RX_FILTER_COMP_BAR
=
0x00000400
,
ATH9K_RX_FILTER_PSPOLL
=
0x00004000
,
ATH9K_RX_FILTER_PHYRADAR
=
0x00002000
,
ATH9K_RX_FILTER_MCAST_BCAST_ALL
=
0x00008000
,
...
...
drivers/net/wireless/ath/ath9k/main.c
浏览文件 @
ea6a634e
...
...
@@ -1310,7 +1310,7 @@ static int ath9k_reg_notifier(struct wiphy *wiphy,
* to allow the separation between hardware specific
* variables (now in ath_hw) and driver specific variables.
*/
static
int
ath_init_softc
(
u16
devid
,
struct
ath_softc
*
sc
)
static
int
ath_init_softc
(
u16
devid
,
struct
ath_softc
*
sc
,
u16
subsysid
)
{
struct
ath_hw
*
ah
=
NULL
;
int
r
=
0
,
i
;
...
...
@@ -1348,6 +1348,7 @@ static int ath_init_softc(u16 devid, struct ath_softc *sc)
ah
->
ah_sc
=
sc
;
ah
->
hw_version
.
devid
=
devid
;
ah
->
hw_version
.
subsysid
=
subsysid
;
sc
->
sc_ah
=
ah
;
r
=
ath9k_hw_init
(
ah
);
...
...
@@ -1577,7 +1578,7 @@ void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
}
/* Device driver core initialization */
int
ath_init_device
(
u16
devid
,
struct
ath_softc
*
sc
)
int
ath_init_device
(
u16
devid
,
struct
ath_softc
*
sc
,
u16
subsysid
)
{
struct
ieee80211_hw
*
hw
=
sc
->
hw
;
int
error
=
0
,
i
;
...
...
@@ -1585,7 +1586,7 @@ int ath_init_device(u16 devid, struct ath_softc *sc)
DPRINTF
(
sc
,
ATH_DBG_CONFIG
,
"Attach ATH hw
\n
"
);
error
=
ath_init_softc
(
devid
,
sc
);
error
=
ath_init_softc
(
devid
,
sc
,
subsysid
);
if
(
error
!=
0
)
return
error
;
...
...
@@ -1879,7 +1880,7 @@ void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw,
if
(
chan
->
band
==
IEEE80211_BAND_2GHZ
)
{
ichan
->
chanmode
=
CHANNEL_G
;
ichan
->
channelFlags
=
CHANNEL_2GHZ
|
CHANNEL_OFDM
;
ichan
->
channelFlags
=
CHANNEL_2GHZ
|
CHANNEL_OFDM
|
CHANNEL_G
;
}
else
{
ichan
->
chanmode
=
CHANNEL_A
;
ichan
->
channelFlags
=
CHANNEL_5GHZ
|
CHANNEL_OFDM
;
...
...
@@ -2010,6 +2011,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
AR_STOMP_LOW_WLAN_WGHT
);
ath9k_hw_btcoex_enable
(
sc
->
sc_ah
);
ath_pcie_aspm_disable
(
sc
);
if
(
sc
->
btcoex_info
.
btcoex_scheme
==
ATH_BTCOEX_CFG_3WIRE
)
ath_btcoex_timer_resume
(
sc
,
&
sc
->
btcoex_info
);
}
...
...
@@ -2433,7 +2435,7 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw,
ath9k_hw_setrxfilter
(
sc
->
sc_ah
,
rfilt
);
ath9k_ps_restore
(
sc
);
DPRINTF
(
sc
,
ATH_DBG_CONFIG
,
"Set HW RX filter: 0x%x
\n
"
,
sc
->
rx
.
rxfilter
);
DPRINTF
(
sc
,
ATH_DBG_CONFIG
,
"Set HW RX filter: 0x%x
\n
"
,
rfilt
);
}
static
void
ath9k_sta_notify
(
struct
ieee80211_hw
*
hw
,
...
...
drivers/net/wireless/ath/ath9k/pci.c
浏览文件 @
ea6a634e
...
...
@@ -35,8 +35,7 @@ static void ath_pci_read_cachesize(struct ath_softc *sc, int *csz)
{
u8
u8tmp
;
pci_read_config_byte
(
to_pci_dev
(
sc
->
dev
),
PCI_CACHE_LINE_SIZE
,
(
u8
*
)
&
u8tmp
);
pci_read_config_byte
(
to_pci_dev
(
sc
->
dev
),
PCI_CACHE_LINE_SIZE
,
&
u8tmp
);
*
csz
=
(
int
)
u8tmp
;
/*
...
...
@@ -89,6 +88,7 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
struct
ath_softc
*
sc
;
struct
ieee80211_hw
*
hw
;
u8
csz
;
u16
subsysid
;
u32
val
;
int
ret
=
0
;
struct
ath_hw
*
ah
;
...
...
@@ -160,8 +160,9 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
hw
=
ieee80211_alloc_hw
(
sizeof
(
struct
ath_wiphy
)
+
sizeof
(
struct
ath_softc
),
&
ath9k_ops
);
if
(
hw
==
NULL
)
{
printk
(
KERN_ERR
"ath_pci: no memory for ieee80211_hw
\n
"
);
if
(
!
hw
)
{
dev_err
(
&
pdev
->
dev
,
"no memory for ieee80211_hw
\n
"
);
ret
=
-
ENOMEM
;
goto
bad2
;
}
...
...
@@ -178,17 +179,18 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
sc
->
mem
=
mem
;
sc
->
bus_ops
=
&
ath_pci_bus_ops
;
if
(
ath_init_device
(
id
->
device
,
sc
)
!=
0
)
{
ret
=
-
ENODEV
;
pci_read_config_word
(
pdev
,
PCI_SUBSYSTEM_ID
,
&
subsysid
);
ret
=
ath_init_device
(
id
->
device
,
sc
,
subsysid
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"failed to initialize device
\n
"
);
goto
bad3
;
}
/* setup interrupt service routine */
if
(
request_irq
(
pdev
->
irq
,
ath_isr
,
IRQF_SHARED
,
"ath"
,
sc
))
{
printk
(
KERN_ERR
"%s: request_irq failed
\n
"
,
wiphy_name
(
hw
->
wiphy
));
ret
=
-
EIO
;
ret
=
request_irq
(
pdev
->
irq
,
ath_isr
,
IRQF_SHARED
,
"ath9k"
,
sc
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"request_irq failed
\n
"
);
goto
bad4
;
}
...
...
drivers/net/wireless/ath/ath9k/recv.c
浏览文件 @
ea6a634e
...
...
@@ -423,6 +423,9 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
if
(
sc
->
rx
.
rxfilter
&
FIF_PSPOLL
)
rfilt
|=
ATH9K_RX_FILTER_PSPOLL
;
if
(
conf_is_ht
(
&
sc
->
hw
->
conf
))
rfilt
|=
ATH9K_RX_FILTER_COMP_BAR
;
if
(
sc
->
sec_wiphy
||
(
sc
->
rx
.
rxfilter
&
FIF_OTHER_BSS
))
{
/* TODO: only needed if more than one BSSID is in use in
* station/adhoc mode */
...
...
drivers/net/wireless/ath/ath9k/reg.h
浏览文件 @
ea6a634e
...
...
@@ -1325,7 +1325,6 @@ enum {
#define AR_CFP_VAL 0x0000FFFF
#define AR_RX_FILTER 0x803C
#define AR_RX_COMPR_BAR 0x00000400
#define AR_MCAST_FIL0 0x8040
#define AR_MCAST_FIL1 0x8044
...
...
drivers/net/wireless/ath/regd.h
浏览文件 @
ea6a634e
...
...
@@ -22,6 +22,12 @@
#include "ath.h"
enum
ctl_group
{
CTL_FCC
=
0x10
,
CTL_MKK
=
0x40
,
CTL_ETSI
=
0x30
,
};
#define NO_CTL 0xff
#define SD_NO_CTL 0xE0
#define NO_CTL 0xff
...
...
drivers/net/wireless/ath/regd_common.h
浏览文件 @
ea6a634e
...
...
@@ -154,12 +154,6 @@ enum EnumRd {
DEBUG_REG_DMN
=
0x01ff
,
};
enum
ctl_group
{
CTL_FCC
=
0x10
,
CTL_MKK
=
0x40
,
CTL_ETSI
=
0x30
,
};
/* Regpair to CTL band mapping */
static
struct
reg_dmn_pair_mapping
regDomainPairs
[]
=
{
/* regpair, 5 GHz CTL, 2 GHz CTL */
...
...
drivers/net/wireless/b43/Kconfig
浏览文件 @
ea6a634e
...
...
@@ -42,8 +42,8 @@ config B43_PCICORE_AUTOSELECT
default y
config B43_PCMCIA
bool "Broadcom 43xx PCMCIA device support
(EXPERIMENTAL)
"
depends on B43 && SSB_PCMCIAHOST_POSSIBLE
&& EXPERIMENTAL
bool "Broadcom 43xx PCMCIA device support"
depends on B43 && SSB_PCMCIAHOST_POSSIBLE
select SSB_PCMCIAHOST
---help---
Broadcom 43xx PCMCIA device support.
...
...
drivers/net/wireless/b43/b43.h
浏览文件 @
ea6a634e
...
...
@@ -616,6 +616,12 @@ struct b43_wl {
/* Pointer to the ieee80211 hardware data structure */
struct
ieee80211_hw
*
hw
;
/* Global driver mutex. Every operation must run with this mutex locked. */
struct
mutex
mutex
;
/* Hard-IRQ spinlock. This lock protects things used in the hard-IRQ
* handler, only. This basically is just the IRQ mask register. */
spinlock_t
hardirq_lock
;
/* The number of queues that were registered with the mac80211 subsystem
* initially. This is a backup copy of hw->queues in case hw->queues has
* to be dynamically lowered at runtime (Firmware does not support QoS).
...
...
@@ -623,16 +629,12 @@ struct b43_wl {
* from the mac80211 subsystem. */
u16
mac80211_initially_registered_queues
;
struct
mutex
mutex
;
spinlock_t
irq_lock
;
/* R/W lock for data transmission.
* Transmissions on 2+ queues can run concurrently, but somebody else
* might sync with TX by write_lock_irqsave()'ing. */
rwlock_t
tx_lock
;
/* Lock for LEDs access. */
spinlock_t
leds_lock
;
/* Lock for SHM access. */
spinlock_t
shm_lock
;
/* We can only have one operating interface (802.11 core)
* at a time. General information about this interface follows.
...
...
@@ -665,8 +667,7 @@ struct b43_wl {
bool
radiotap_enabled
;
bool
radio_enabled
;
/* The beacon we are currently using (AP or IBSS mode).
* This beacon stuff is protected by the irq_lock. */
/* The beacon we are currently using (AP or IBSS mode). */
struct
sk_buff
*
current_beacon
;
bool
beacon0_uploaded
;
bool
beacon1_uploaded
;
...
...
@@ -680,6 +681,11 @@ struct b43_wl {
* This is scheduled when we determine that the actual TX output
* power doesn't match what we want. */
struct
work_struct
txpower_adjust_work
;
/* Packet transmit work */
struct
work_struct
tx_work
;
/* Queue of packets to be transmitted. */
struct
sk_buff_head
tx_queue
;
};
/* The type of the firmware file. */
...
...
@@ -754,14 +760,6 @@ enum {
smp_wmb(); \
} while (0)
/* XXX--- HOW LOCKING WORKS IN B43 ---XXX
*
* You should always acquire both, wl->mutex and wl->irq_lock unless:
* - You don't need to acquire wl->irq_lock, if the interface is stopped.
* - You don't need to acquire wl->mutex in the IRQ handler, IRQ tasklet
* and packet TX path (and _ONLY_ there.)
*/
/* Data structure for one wireless device (802.11 core) */
struct
b43_wldev
{
struct
ssb_device
*
dev
;
...
...
@@ -807,14 +805,12 @@ struct b43_wldev {
u32
dma_reason
[
6
];
/* The currently active generic-interrupt mask. */
u32
irq_mask
;
/* Link Quality calculation context. */
struct
b43_noise_calculation
noisecalc
;
/* if > 0 MAC is suspended. if == 0 MAC is enabled. */
int
mac_suspended
;
/* Interrupt Service Routine tasklet (bottom-half) */
struct
tasklet_struct
isr_tasklet
;
/* Periodic tasks */
struct
delayed_work
periodic_work
;
unsigned
int
periodic_state
;
...
...
drivers/net/wireless/b43/debugfs.c
浏览文件 @
ea6a634e
...
...
@@ -46,8 +46,6 @@ struct b43_debugfs_fops {
struct
file_operations
fops
;
/* Offset of struct b43_dfs_file in struct b43_dfsentry */
size_t
file_struct_offset
;
/* Take wl->irq_lock before calling read/write? */
bool
take_irqlock
;
};
static
inline
...
...
@@ -127,7 +125,6 @@ static int shm16write__write_file(struct b43_wldev *dev,
unsigned
int
routing
,
addr
,
mask
,
set
;
u16
val
;
int
res
;
unsigned
long
flags
;
res
=
sscanf
(
buf
,
"0x%X 0x%X 0x%X 0x%X"
,
&
routing
,
&
addr
,
&
mask
,
&
set
);
...
...
@@ -144,15 +141,13 @@ static int shm16write__write_file(struct b43_wldev *dev,
if
((
mask
>
0xFFFF
)
||
(
set
>
0xFFFF
))
return
-
E2BIG
;
spin_lock_irqsave
(
&
dev
->
wl
->
shm_lock
,
flags
);
if
(
mask
==
0
)
val
=
0
;
else
val
=
__
b43_shm_read16
(
dev
,
routing
,
addr
);
val
=
b43_shm_read16
(
dev
,
routing
,
addr
);
val
&=
mask
;
val
|=
set
;
__b43_shm_write16
(
dev
,
routing
,
addr
,
val
);
spin_unlock_irqrestore
(
&
dev
->
wl
->
shm_lock
,
flags
);
b43_shm_write16
(
dev
,
routing
,
addr
,
val
);
return
0
;
}
...
...
@@ -206,7 +201,6 @@ static int shm32write__write_file(struct b43_wldev *dev,
unsigned
int
routing
,
addr
,
mask
,
set
;
u32
val
;
int
res
;
unsigned
long
flags
;
res
=
sscanf
(
buf
,
"0x%X 0x%X 0x%X 0x%X"
,
&
routing
,
&
addr
,
&
mask
,
&
set
);
...
...
@@ -223,15 +217,13 @@ static int shm32write__write_file(struct b43_wldev *dev,
if
((
mask
>
0xFFFFFFFF
)
||
(
set
>
0xFFFFFFFF
))
return
-
E2BIG
;
spin_lock_irqsave
(
&
dev
->
wl
->
shm_lock
,
flags
);
if
(
mask
==
0
)
val
=
0
;
else
val
=
__
b43_shm_read32
(
dev
,
routing
,
addr
);
val
=
b43_shm_read32
(
dev
,
routing
,
addr
);
val
&=
mask
;
val
|=
set
;
__b43_shm_write32
(
dev
,
routing
,
addr
,
val
);
spin_unlock_irqrestore
(
&
dev
->
wl
->
shm_lock
,
flags
);
b43_shm_write32
(
dev
,
routing
,
addr
,
val
);
return
0
;
}
...
...
@@ -372,14 +364,12 @@ static ssize_t txstat_read_file(struct b43_wldev *dev,
{
struct
b43_txstatus_log
*
log
=
&
dev
->
dfsentry
->
txstatlog
;
ssize_t
count
=
0
;
unsigned
long
flags
;
int
i
,
idx
;
struct
b43_txstatus
*
stat
;
spin_lock_irqsave
(
&
log
->
lock
,
flags
);
if
(
log
->
end
<
0
)
{
fappend
(
"Nothing transmitted, yet
\n
"
);
goto
out
_unlock
;
goto
out
;
}
fappend
(
"b43 TX status reports:
\n\n
"
"index | cookie | seq | phy_stat | frame_count | "
...
...
@@ -409,13 +399,11 @@ static ssize_t txstat_read_file(struct b43_wldev *dev,
break
;
i
++
;
}
out_unlock:
spin_unlock_irqrestore
(
&
log
->
lock
,
flags
);
out:
return
count
;
}
/* wl->irq_lock is locked */
static
int
restart_write_file
(
struct
b43_wldev
*
dev
,
const
char
*
buf
,
size_t
count
)
{
...
...
@@ -556,12 +544,7 @@ static ssize_t b43_debugfs_read(struct file *file, char __user *userbuf,
goto
out_unlock
;
}
memset
(
buf
,
0
,
bufsize
);
if
(
dfops
->
take_irqlock
)
{
spin_lock_irq
(
&
dev
->
wl
->
irq_lock
);
ret
=
dfops
->
read
(
dev
,
buf
,
bufsize
);
spin_unlock_irq
(
&
dev
->
wl
->
irq_lock
);
}
else
ret
=
dfops
->
read
(
dev
,
buf
,
bufsize
);
ret
=
dfops
->
read
(
dev
,
buf
,
bufsize
);
if
(
ret
<=
0
)
{
free_pages
((
unsigned
long
)
buf
,
buforder
);
err
=
ret
;
...
...
@@ -623,12 +606,7 @@ static ssize_t b43_debugfs_write(struct file *file,
err
=
-
EFAULT
;
goto
out_freepage
;
}
if
(
dfops
->
take_irqlock
)
{
spin_lock_irq
(
&
dev
->
wl
->
irq_lock
);
err
=
dfops
->
write
(
dev
,
buf
,
count
);
spin_unlock_irq
(
&
dev
->
wl
->
irq_lock
);
}
else
err
=
dfops
->
write
(
dev
,
buf
,
count
);
err
=
dfops
->
write
(
dev
,
buf
,
count
);
if
(
err
)
goto
out_freepage
;
...
...
@@ -641,7 +619,7 @@ static ssize_t b43_debugfs_write(struct file *file,
}
#define B43_DEBUGFS_FOPS(name, _read, _write
, _take_irqlock)
\
#define B43_DEBUGFS_FOPS(name, _read, _write
)
\
static struct b43_debugfs_fops fops_##name = { \
.read = _read, \
.write = _write, \
...
...
@@ -652,20 +630,19 @@ static ssize_t b43_debugfs_write(struct file *file,
}, \
.file_struct_offset = offsetof(struct b43_dfsentry, \
file_##name), \
.take_irqlock = _take_irqlock, \
}
B43_DEBUGFS_FOPS
(
shm16read
,
shm16read__read_file
,
shm16read__write_file
,
1
);
B43_DEBUGFS_FOPS
(
shm16write
,
NULL
,
shm16write__write_file
,
1
);
B43_DEBUGFS_FOPS
(
shm32read
,
shm32read__read_file
,
shm32read__write_file
,
1
);
B43_DEBUGFS_FOPS
(
shm32write
,
NULL
,
shm32write__write_file
,
1
);
B43_DEBUGFS_FOPS
(
mmio16read
,
mmio16read__read_file
,
mmio16read__write_file
,
1
);
B43_DEBUGFS_FOPS
(
mmio16write
,
NULL
,
mmio16write__write_file
,
1
);
B43_DEBUGFS_FOPS
(
mmio32read
,
mmio32read__read_file
,
mmio32read__write_file
,
1
);
B43_DEBUGFS_FOPS
(
mmio32write
,
NULL
,
mmio32write__write_file
,
1
);
B43_DEBUGFS_FOPS
(
txstat
,
txstat_read_file
,
NULL
,
0
);
B43_DEBUGFS_FOPS
(
restart
,
NULL
,
restart_write_file
,
1
);
B43_DEBUGFS_FOPS
(
loctls
,
loctls_read_file
,
NULL
,
0
);
B43_DEBUGFS_FOPS
(
shm16read
,
shm16read__read_file
,
shm16read__write_file
);
B43_DEBUGFS_FOPS
(
shm16write
,
NULL
,
shm16write__write_file
);
B43_DEBUGFS_FOPS
(
shm32read
,
shm32read__read_file
,
shm32read__write_file
);
B43_DEBUGFS_FOPS
(
shm32write
,
NULL
,
shm32write__write_file
);
B43_DEBUGFS_FOPS
(
mmio16read
,
mmio16read__read_file
,
mmio16read__write_file
);
B43_DEBUGFS_FOPS
(
mmio16write
,
NULL
,
mmio16write__write_file
);
B43_DEBUGFS_FOPS
(
mmio32read
,
mmio32read__read_file
,
mmio32read__write_file
);
B43_DEBUGFS_FOPS
(
mmio32write
,
NULL
,
mmio32write__write_file
);
B43_DEBUGFS_FOPS
(
txstat
,
txstat_read_file
,
NULL
);
B43_DEBUGFS_FOPS
(
restart
,
NULL
,
restart_write_file
);
B43_DEBUGFS_FOPS
(
loctls
,
loctls_read_file
,
NULL
);
bool
b43_debug
(
struct
b43_wldev
*
dev
,
enum
b43_dyndbg
feature
)
...
...
@@ -738,7 +715,6 @@ void b43_debugfs_add_device(struct b43_wldev *dev)
return
;
}
log
->
end
=
-
1
;
spin_lock_init
(
&
log
->
lock
);
dev
->
dfsentry
=
e
;
...
...
@@ -822,7 +798,6 @@ void b43_debugfs_remove_device(struct b43_wldev *dev)
kfree
(
e
);
}
/* Called with IRQs disabled. */
void
b43_debugfs_log_txstat
(
struct
b43_wldev
*
dev
,
const
struct
b43_txstatus
*
status
)
{
...
...
@@ -834,14 +809,12 @@ void b43_debugfs_log_txstat(struct b43_wldev *dev,
if
(
!
e
)
return
;
log
=
&
e
->
txstatlog
;
spin_lock
(
&
log
->
lock
);
/* IRQs are already disabled. */
i
=
log
->
end
+
1
;
if
(
i
==
B43_NR_LOGGED_TXSTATUS
)
i
=
0
;
log
->
end
=
i
;
cur
=
&
(
log
->
log
[
i
]);
memcpy
(
cur
,
status
,
sizeof
(
*
cur
));
spin_unlock
(
&
log
->
lock
);
}
void
b43_debugfs_init
(
void
)
...
...
drivers/net/wireless/b43/debugfs.h
浏览文件 @
ea6a634e
...
...
@@ -23,9 +23,10 @@ struct dentry;
#define B43_NR_LOGGED_TXSTATUS 100
struct
b43_txstatus_log
{
/* This structure is protected by wl->mutex */
struct
b43_txstatus
*
log
;
int
end
;
spinlock_t
lock
;
};
struct
b43_dfs_file
{
...
...
drivers/net/wireless/b43/dma.c
浏览文件 @
ea6a634e
...
...
@@ -856,7 +856,6 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
}
else
B43_WARN_ON
(
1
);
}
spin_lock_init
(
&
ring
->
lock
);
#ifdef CONFIG_B43_DEBUG
ring
->
last_injected_overflow
=
jiffies
;
#endif
...
...
@@ -1315,7 +1314,6 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb)
struct
b43_dmaring
*
ring
;
struct
ieee80211_hdr
*
hdr
;
int
err
=
0
;
unsigned
long
flags
;
struct
ieee80211_tx_info
*
info
=
IEEE80211_SKB_CB
(
skb
);
hdr
=
(
struct
ieee80211_hdr
*
)
skb
->
data
;
...
...
@@ -1331,8 +1329,6 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb)
dev
,
skb_get_queue_mapping
(
skb
));
}
spin_lock_irqsave
(
&
ring
->
lock
,
flags
);
B43_WARN_ON
(
!
ring
->
tx
);
if
(
unlikely
(
ring
->
stopped
))
{
...
...
@@ -1343,7 +1339,7 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb)
if
(
b43_debug
(
dev
,
B43_DBG_DMAVERBOSE
))
b43err
(
dev
->
wl
,
"Packet after queue stopped
\n
"
);
err
=
-
ENOSPC
;
goto
out
_unlock
;
goto
out
;
}
if
(
unlikely
(
WARN_ON
(
free_slots
(
ring
)
<
TX_SLOTS_PER_FRAME
)))
{
...
...
@@ -1351,7 +1347,7 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb)
* full, but queues not stopped. */
b43err
(
dev
->
wl
,
"DMA queue overflow
\n
"
);
err
=
-
ENOSPC
;
goto
out
_unlock
;
goto
out
;
}
/* Assign the queue number to the ring (if not already done before)
...
...
@@ -1365,11 +1361,11 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb)
* anymore and must not transmit it unencrypted. */
dev_kfree_skb_any
(
skb
);
err
=
0
;
goto
out
_unlock
;
goto
out
;
}
if
(
unlikely
(
err
))
{
b43err
(
dev
->
wl
,
"DMA tx mapping failure
\n
"
);
goto
out
_unlock
;
goto
out
;
}
ring
->
nr_tx_packets
++
;
if
((
free_slots
(
ring
)
<
TX_SLOTS_PER_FRAME
)
||
...
...
@@ -1381,13 +1377,11 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb)
b43dbg
(
dev
->
wl
,
"Stopped TX ring %d
\n
"
,
ring
->
index
);
}
}
out_unlock:
spin_unlock_irqrestore
(
&
ring
->
lock
,
flags
);
out:
return
err
;
}
/* Called with IRQs disabled. */
void
b43_dma_handle_txstatus
(
struct
b43_wldev
*
dev
,
const
struct
b43_txstatus
*
status
)
{
...
...
@@ -1402,8 +1396,6 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
if
(
unlikely
(
!
ring
))
return
;
spin_lock
(
&
ring
->
lock
);
/* IRQs are already disabled. */
B43_WARN_ON
(
!
ring
->
tx
);
ops
=
ring
->
ops
;
while
(
1
)
{
...
...
@@ -1462,8 +1454,6 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
b43dbg
(
dev
->
wl
,
"Woke up TX ring %d
\n
"
,
ring
->
index
);
}
}
spin_unlock
(
&
ring
->
lock
);
}
void
b43_dma_get_tx_stats
(
struct
b43_wldev
*
dev
,
...
...
@@ -1471,17 +1461,14 @@ void b43_dma_get_tx_stats(struct b43_wldev *dev,
{
const
int
nr_queues
=
dev
->
wl
->
hw
->
queues
;
struct
b43_dmaring
*
ring
;
unsigned
long
flags
;
int
i
;
for
(
i
=
0
;
i
<
nr_queues
;
i
++
)
{
ring
=
select_ring_by_priority
(
dev
,
i
);
spin_lock_irqsave
(
&
ring
->
lock
,
flags
);
stats
[
i
].
len
=
ring
->
used_slots
/
TX_SLOTS_PER_FRAME
;
stats
[
i
].
limit
=
ring
->
nr_slots
/
TX_SLOTS_PER_FRAME
;
stats
[
i
].
count
=
ring
->
nr_tx_packets
;
spin_unlock_irqrestore
(
&
ring
->
lock
,
flags
);
}
}
...
...
@@ -1592,22 +1579,14 @@ void b43_dma_rx(struct b43_dmaring *ring)
static
void
b43_dma_tx_suspend_ring
(
struct
b43_dmaring
*
ring
)
{
unsigned
long
flags
;
spin_lock_irqsave
(
&
ring
->
lock
,
flags
);
B43_WARN_ON
(
!
ring
->
tx
);
ring
->
ops
->
tx_suspend
(
ring
);
spin_unlock_irqrestore
(
&
ring
->
lock
,
flags
);
}
static
void
b43_dma_tx_resume_ring
(
struct
b43_dmaring
*
ring
)
{
unsigned
long
flags
;
spin_lock_irqsave
(
&
ring
->
lock
,
flags
);
B43_WARN_ON
(
!
ring
->
tx
);
ring
->
ops
->
tx_resume
(
ring
);
spin_unlock_irqrestore
(
&
ring
->
lock
,
flags
);
}
void
b43_dma_tx_suspend
(
struct
b43_wldev
*
dev
)
...
...
drivers/net/wireless/b43/dma.h
浏览文件 @
ea6a634e
...
...
@@ -2,7 +2,6 @@
#define B43_DMA_H_
#include <linux/ieee80211.h>
#include <linux/spinlock.h>
#include "b43.h"
...
...
@@ -244,8 +243,6 @@ struct b43_dmaring {
/* The QOS priority assigned to this ring. Only used for TX rings.
* This is the mac80211 "queue" value. */
u8
queue_prio
;
/* Lock, only used for TX. */
spinlock_t
lock
;
struct
b43_wldev
*
dev
;
#ifdef CONFIG_B43_DEBUG
/* Maximum number of used slots. */
...
...
drivers/net/wireless/b43/main.c
浏览文件 @
ea6a634e
此差异已折叠。
点击以展开。
drivers/net/wireless/b43/main.h
浏览文件 @
ea6a634e
...
...
@@ -112,13 +112,9 @@ void b43_tsf_read(struct b43_wldev *dev, u64 * tsf);
void
b43_tsf_write
(
struct
b43_wldev
*
dev
,
u64
tsf
);
u32
b43_shm_read32
(
struct
b43_wldev
*
dev
,
u16
routing
,
u16
offset
);
u32
__b43_shm_read32
(
struct
b43_wldev
*
dev
,
u16
routing
,
u16
offset
);
u16
b43_shm_read16
(
struct
b43_wldev
*
dev
,
u16
routing
,
u16
offset
);
u16
__b43_shm_read16
(
struct
b43_wldev
*
dev
,
u16
routing
,
u16
offset
);
void
b43_shm_write32
(
struct
b43_wldev
*
dev
,
u16
routing
,
u16
offset
,
u32
value
);
void
__b43_shm_write32
(
struct
b43_wldev
*
dev
,
u16
routing
,
u16
offset
,
u32
value
);
void
b43_shm_write16
(
struct
b43_wldev
*
dev
,
u16
routing
,
u16
offset
,
u16
value
);
void
__b43_shm_write16
(
struct
b43_wldev
*
dev
,
u16
routing
,
u16
offset
,
u16
value
);
u64
b43_hf_read
(
struct
b43_wldev
*
dev
);
void
b43_hf_write
(
struct
b43_wldev
*
dev
,
u64
value
);
...
...
drivers/net/wireless/b43/phy_common.c
浏览文件 @
ea6a634e
...
...
@@ -347,7 +347,6 @@ void b43_phy_txpower_adjust_work(struct work_struct *work)
mutex_unlock
(
&
wl
->
mutex
);
}
/* Called with wl->irq_lock locked */
void
b43_phy_txpower_check
(
struct
b43_wldev
*
dev
,
unsigned
int
flags
)
{
struct
b43_phy
*
phy
=
&
dev
->
phy
;
...
...
drivers/net/wireless/b43/phy_common.h
浏览文件 @
ea6a634e
...
...
@@ -131,7 +131,7 @@ enum b43_txpwr_result {
* If the parameter "ignore_tssi" is true, the TSSI values should
* be ignored and a recalculation of the power settings should be
* done even if the TSSI values did not change.
* This
callback is called with wl->irq_lock held and must not sleep
.
* This
function may sleep, but should not
.
* Must not be NULL.
* @adjust_txpower: Write the previously calculated TX power settings
* (from @recalc_txpower) to the hardware.
...
...
@@ -379,7 +379,6 @@ void b43_software_rfkill(struct b43_wldev *dev, bool blocked);
*
* Compare the current TX power output to the desired power emission
* and schedule an adjustment in case it mismatches.
* Requires wl->irq_lock locked.
*
* @flags: OR'ed enum b43_phy_txpower_check_flags flags.
* See the docs below.
...
...
drivers/net/wireless/b43/phy_g.c
浏览文件 @
ea6a634e
...
...
@@ -2823,8 +2823,6 @@ static void b43_gphy_op_adjust_txpower(struct b43_wldev *dev)
b43_mac_suspend
(
dev
);
spin_lock_irq
(
&
dev
->
wl
->
irq_lock
);
/* Calculate the new attenuation values. */
bbatt
=
gphy
->
bbatt
.
att
;
bbatt
+=
gphy
->
bbatt_delta
;
...
...
@@ -2864,11 +2862,6 @@ static void b43_gphy_op_adjust_txpower(struct b43_wldev *dev)
gphy
->
rfatt
.
att
=
rfatt
;
gphy
->
bbatt
.
att
=
bbatt
;
/* We drop the lock early, so we can sleep during hardware
* adjustment. Possible races with op_recalc_txpower are harmless,
* as we will be called once again in case we raced. */
spin_unlock_irq
(
&
dev
->
wl
->
irq_lock
);
if
(
b43_debug
(
dev
,
B43_DBG_XMITPOWER
))
b43dbg
(
dev
->
wl
,
"Adjusting TX power
\n
"
);
...
...
drivers/net/wireless/b43/phy_g.h
浏览文件 @
ea6a634e
...
...
@@ -141,8 +141,7 @@ struct b43_phy_g {
int
tgt_idle_tssi
;
/* Current idle TSSI */
int
cur_idle_tssi
;
/* The current average TSSI.
* Needs irq_lock, as it's updated in the IRQ path. */
/* The current average TSSI. */
u8
average_tssi
;
/* Current TX power level attenuation control values */
struct
b43_bbatt
bbatt
;
...
...
drivers/net/wireless/b43/pio.c
浏览文件 @
ea6a634e
...
...
@@ -32,9 +32,6 @@
#include <linux/delay.h>
static
void
b43_pio_rx_work
(
struct
work_struct
*
work
);
static
u16
generate_cookie
(
struct
b43_pio_txqueue
*
q
,
struct
b43_pio_txpacket
*
pack
)
{
...
...
@@ -144,7 +141,6 @@ static struct b43_pio_txqueue *b43_setup_pioqueue_tx(struct b43_wldev *dev,
q
=
kzalloc
(
sizeof
(
*
q
),
GFP_KERNEL
);
if
(
!
q
)
return
NULL
;
spin_lock_init
(
&
q
->
lock
);
q
->
dev
=
dev
;
q
->
rev
=
dev
->
dev
->
id
.
revision
;
q
->
mmio_base
=
index_to_pioqueue_base
(
dev
,
index
)
+
...
...
@@ -179,12 +175,10 @@ static struct b43_pio_rxqueue *b43_setup_pioqueue_rx(struct b43_wldev *dev,
q
=
kzalloc
(
sizeof
(
*
q
),
GFP_KERNEL
);
if
(
!
q
)
return
NULL
;
spin_lock_init
(
&
q
->
lock
);
q
->
dev
=
dev
;
q
->
rev
=
dev
->
dev
->
id
.
revision
;
q
->
mmio_base
=
index_to_pioqueue_base
(
dev
,
index
)
+
pio_rxqueue_offset
(
dev
);
INIT_WORK
(
&
q
->
rx_work
,
b43_pio_rx_work
);
/* Enable Direct FIFO RX (PIO) on the engine. */
b43_dma_direct_fifo_rx
(
dev
,
index
,
1
);
...
...
@@ -249,13 +243,6 @@ void b43_pio_free(struct b43_wldev *dev)
destroy_queue_tx
(
pio
,
tx_queue_AC_BK
);
}
void
b43_pio_stop
(
struct
b43_wldev
*
dev
)
{
if
(
!
b43_using_pio_transfers
(
dev
))
return
;
cancel_work_sync
(
&
dev
->
pio
.
rx_queue
->
rx_work
);
}
int
b43_pio_init
(
struct
b43_wldev
*
dev
)
{
struct
b43_pio
*
pio
=
&
dev
->
pio
;
...
...
@@ -494,7 +481,6 @@ int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb)
{
struct
b43_pio_txqueue
*
q
;
struct
ieee80211_hdr
*
hdr
;
unsigned
long
flags
;
unsigned
int
hdrlen
,
total_len
;
int
err
=
0
;
struct
ieee80211_tx_info
*
info
=
IEEE80211_SKB_CB
(
skb
);
...
...
@@ -512,20 +498,18 @@ int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb)
q
=
select_queue_by_priority
(
dev
,
skb_get_queue_mapping
(
skb
));
}
spin_lock_irqsave
(
&
q
->
lock
,
flags
);
hdrlen
=
b43_txhdr_size
(
dev
);
total_len
=
roundup
(
skb
->
len
+
hdrlen
,
4
);
if
(
unlikely
(
total_len
>
q
->
buffer_size
))
{
err
=
-
ENOBUFS
;
b43dbg
(
dev
->
wl
,
"PIO: TX packet longer than queue.
\n
"
);
goto
out
_unlock
;
goto
out
;
}
if
(
unlikely
(
q
->
free_packet_slots
==
0
))
{
err
=
-
ENOBUFS
;
b43warn
(
dev
->
wl
,
"PIO: TX packet overflow.
\n
"
);
goto
out
_unlock
;
goto
out
;
}
B43_WARN_ON
(
q
->
buffer_used
>
q
->
buffer_size
);
...
...
@@ -534,7 +518,7 @@ int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb)
err
=
-
EBUSY
;
ieee80211_stop_queue
(
dev
->
wl
->
hw
,
skb_get_queue_mapping
(
skb
));
q
->
stopped
=
1
;
goto
out
_unlock
;
goto
out
;
}
/* Assign the queue number to the ring (if not already done before)
...
...
@@ -548,11 +532,11 @@ int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb)
* anymore and must not transmit it unencrypted. */
dev_kfree_skb_any
(
skb
);
err
=
0
;
goto
out
_unlock
;
goto
out
;
}
if
(
unlikely
(
err
))
{
b43err
(
dev
->
wl
,
"PIO transmission failure
\n
"
);
goto
out
_unlock
;
goto
out
;
}
q
->
nr_tx_packets
++
;
...
...
@@ -564,13 +548,10 @@ int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb)
q
->
stopped
=
1
;
}
out_unlock:
spin_unlock_irqrestore
(
&
q
->
lock
,
flags
);
out:
return
err
;
}
/* Called with IRQs disabled. */
void
b43_pio_handle_txstatus
(
struct
b43_wldev
*
dev
,
const
struct
b43_txstatus
*
status
)
{
...
...
@@ -584,8 +565,6 @@ void b43_pio_handle_txstatus(struct b43_wldev *dev,
return
;
B43_WARN_ON
(
!
pack
);
spin_lock
(
&
q
->
lock
);
/* IRQs are already disabled. */
info
=
IEEE80211_SKB_CB
(
pack
->
skb
);
b43_fill_txstatus_report
(
dev
,
info
,
status
);
...
...
@@ -603,8 +582,6 @@ void b43_pio_handle_txstatus(struct b43_wldev *dev,
ieee80211_wake_queue
(
dev
->
wl
->
hw
,
q
->
queue_prio
);
q
->
stopped
=
0
;
}
spin_unlock
(
&
q
->
lock
);
}
void
b43_pio_get_tx_stats
(
struct
b43_wldev
*
dev
,
...
...
@@ -612,17 +589,14 @@ void b43_pio_get_tx_stats(struct b43_wldev *dev,
{
const
int
nr_queues
=
dev
->
wl
->
hw
->
queues
;
struct
b43_pio_txqueue
*
q
;
unsigned
long
flags
;
int
i
;
for
(
i
=
0
;
i
<
nr_queues
;
i
++
)
{
q
=
select_queue_by_priority
(
dev
,
i
);
spin_lock_irqsave
(
&
q
->
lock
,
flags
);
stats
[
i
].
len
=
B43_PIO_MAX_NR_TXPACKETS
-
q
->
free_packet_slots
;
stats
[
i
].
limit
=
B43_PIO_MAX_NR_TXPACKETS
;
stats
[
i
].
count
=
q
->
nr_tx_packets
;
spin_unlock_irqrestore
(
&
q
->
lock
,
flags
);
}
}
...
...
@@ -760,37 +734,23 @@ static bool pio_rx_frame(struct b43_pio_rxqueue *q)
return
1
;
}
/* RX workqueue. We can sleep, yay! */
static
void
b43_pio_rx_work
(
struct
work_struct
*
work
)
void
b43_pio_rx
(
struct
b43_pio_rxqueue
*
q
)
{
struct
b43_pio_rxqueue
*
q
=
container_of
(
work
,
struct
b43_pio_rxqueue
,
rx_work
);
unsigned
int
budget
=
50
;
unsigned
int
count
=
0
;
bool
stop
;
do
{
spin_lock_irq
(
&
q
->
lock
);
while
(
1
)
{
stop
=
(
pio_rx_frame
(
q
)
==
0
);
spin_unlock_irq
(
&
q
->
lock
);
cond_resched
();
if
(
stop
)
break
;
}
while
(
--
budget
);
}
/* Called with IRQs disabled. */
void
b43_pio_rx
(
struct
b43_pio_rxqueue
*
q
)
{
/* Due to latency issues we must run the RX path in
* a workqueue to be able to schedule between packets. */
ieee80211_queue_work
(
q
->
dev
->
wl
->
hw
,
&
q
->
rx_work
);
cond_resched
();
if
(
WARN_ON_ONCE
(
++
count
>
10000
))
break
;
}
}
static
void
b43_pio_tx_suspend_queue
(
struct
b43_pio_txqueue
*
q
)
{
unsigned
long
flags
;
spin_lock_irqsave
(
&
q
->
lock
,
flags
);
if
(
q
->
rev
>=
8
)
{
b43_piotx_write32
(
q
,
B43_PIO8_TXCTL
,
b43_piotx_read32
(
q
,
B43_PIO8_TXCTL
)
...
...
@@ -800,14 +760,10 @@ static void b43_pio_tx_suspend_queue(struct b43_pio_txqueue *q)
b43_piotx_read16
(
q
,
B43_PIO_TXCTL
)
|
B43_PIO_TXCTL_SUSPREQ
);
}
spin_unlock_irqrestore
(
&
q
->
lock
,
flags
);
}
static
void
b43_pio_tx_resume_queue
(
struct
b43_pio_txqueue
*
q
)
{
unsigned
long
flags
;
spin_lock_irqsave
(
&
q
->
lock
,
flags
);
if
(
q
->
rev
>=
8
)
{
b43_piotx_write32
(
q
,
B43_PIO8_TXCTL
,
b43_piotx_read32
(
q
,
B43_PIO8_TXCTL
)
...
...
@@ -817,7 +773,6 @@ static void b43_pio_tx_resume_queue(struct b43_pio_txqueue *q)
b43_piotx_read16
(
q
,
B43_PIO_TXCTL
)
&
~
B43_PIO_TXCTL_SUSPREQ
);
}
spin_unlock_irqrestore
(
&
q
->
lock
,
flags
);
}
void
b43_pio_tx_suspend
(
struct
b43_wldev
*
dev
)
...
...
drivers/net/wireless/b43/pio.h
浏览文件 @
ea6a634e
...
...
@@ -70,7 +70,6 @@ struct b43_pio_txpacket {
struct
b43_pio_txqueue
{
struct
b43_wldev
*
dev
;
spinlock_t
lock
;
u16
mmio_base
;
/* The device queue buffer size in bytes. */
...
...
@@ -103,12 +102,8 @@ struct b43_pio_txqueue {
struct
b43_pio_rxqueue
{
struct
b43_wldev
*
dev
;
spinlock_t
lock
;
u16
mmio_base
;
/* Work to reduce latency issues on RX. */
struct
work_struct
rx_work
;
/* Shortcut to the 802.11 core revision. This is to
* avoid horrible pointer dereferencing in the fastpaths. */
u8
rev
;
...
...
@@ -162,7 +157,6 @@ static inline void b43_piorx_write32(struct b43_pio_rxqueue *q,
int
b43_pio_init
(
struct
b43_wldev
*
dev
);
void
b43_pio_stop
(
struct
b43_wldev
*
dev
);
void
b43_pio_free
(
struct
b43_wldev
*
dev
);
int
b43_pio_tx
(
struct
b43_wldev
*
dev
,
struct
sk_buff
*
skb
);
...
...
drivers/net/wireless/b43/sysfs.c
浏览文件 @
ea6a634e
...
...
@@ -94,7 +94,6 @@ static ssize_t b43_attr_interfmode_store(struct device *dev,
const
char
*
buf
,
size_t
count
)
{
struct
b43_wldev
*
wldev
=
dev_to_b43_wldev
(
dev
);
unsigned
long
flags
;
int
err
;
int
mode
;
...
...
@@ -120,7 +119,6 @@ static ssize_t b43_attr_interfmode_store(struct device *dev,
}
mutex_lock
(
&
wldev
->
wl
->
mutex
);
spin_lock_irqsave
(
&
wldev
->
wl
->
irq_lock
,
flags
);
if
(
wldev
->
phy
.
ops
->
interf_mitigation
)
{
err
=
wldev
->
phy
.
ops
->
interf_mitigation
(
wldev
,
mode
);
...
...
@@ -132,7 +130,6 @@ static ssize_t b43_attr_interfmode_store(struct device *dev,
err
=
-
ENOSYS
;
mmiowb
();
spin_unlock_irqrestore
(
&
wldev
->
wl
->
irq_lock
,
flags
);
mutex_unlock
(
&
wldev
->
wl
->
mutex
);
return
err
?
err
:
count
;
...
...
drivers/net/wireless/b43/xmit.c
浏览文件 @
ea6a634e
...
...
@@ -267,11 +267,11 @@ int b43_generate_txhdr(struct b43_wldev *dev,
*/
ieee80211_get_tkip_key
(
info
->
control
.
hw_key
,
skb_frag
,
IEEE80211_TKIP_P1_KEY
,
(
u8
*
)
phase1key
);
/* phase1key is in host endian */
for
(
i
=
0
;
i
<
5
;
i
++
)
phase1key
[
i
]
=
cpu_to_le16
(
phase1key
[
i
])
;
memcpy
(
txhdr
->
iv
,
phase1key
,
10
);
/* phase1key is in host endian
. Copy to little-endian txhdr->iv.
*/
for
(
i
=
0
;
i
<
5
;
i
++
)
{
txhdr
->
iv
[
i
*
2
+
0
]
=
phase1key
[
i
]
;
txhdr
->
iv
[
i
*
2
+
1
]
=
phase1key
[
i
]
>>
8
;
}
/* iv16 */
memcpy
(
txhdr
->
iv
+
10
,
((
u8
*
)
wlhdr
)
+
wlhdr_len
,
3
);
}
else
{
...
...
drivers/net/wireless/b43legacy/main.c
浏览文件 @
ea6a634e
...
...
@@ -3106,16 +3106,20 @@ static void b43legacy_imcfglo_timeouts_workaround(struct b43legacy_wldev *dev)
bus
->
pcicore
.
dev
->
id
.
revision
<=
5
)
{
/* IMCFGLO timeouts workaround. */
tmp
=
ssb_read32
(
dev
->
dev
,
SSB_IMCFGLO
);
tmp
&=
~
SSB_IMCFGLO_REQTO
;
tmp
&=
~
SSB_IMCFGLO_SERTO
;
switch
(
bus
->
bustype
)
{
case
SSB_BUSTYPE_PCI
:
case
SSB_BUSTYPE_PCMCIA
:
tmp
&=
~
SSB_IMCFGLO_REQTO
;
tmp
&=
~
SSB_IMCFGLO_SERTO
;
tmp
|=
0x32
;
break
;
case
SSB_BUSTYPE_SSB
:
tmp
&=
~
SSB_IMCFGLO_REQTO
;
tmp
&=
~
SSB_IMCFGLO_SERTO
;
tmp
|=
0x53
;
break
;
default:
break
;
}
ssb_write32
(
dev
->
dev
,
SSB_IMCFGLO
,
tmp
);
}
...
...
drivers/net/wireless/rt2x00/rt2400pci.c
浏览文件 @
ea6a634e
...
...
@@ -331,9 +331,8 @@ static void rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev,
preamble_mask
=
erp
->
short_preamble
<<
3
;
rt2x00pci_register_read
(
rt2x00dev
,
TXCSR1
,
&
reg
);
rt2x00_set_field32
(
&
reg
,
TXCSR1_ACK_TIMEOUT
,
erp
->
ack_timeout
);
rt2x00_set_field32
(
&
reg
,
TXCSR1_ACK_CONSUME_TIME
,
erp
->
ack_consume_time
);
rt2x00_set_field32
(
&
reg
,
TXCSR1_ACK_TIMEOUT
,
0x1ff
);
rt2x00_set_field32
(
&
reg
,
TXCSR1_ACK_CONSUME_TIME
,
0x13a
);
rt2x00_set_field32
(
&
reg
,
TXCSR1_TSF_OFFSET
,
IEEE80211_HEADER
);
rt2x00_set_field32
(
&
reg
,
TXCSR1_AUTORESPONDER
,
1
);
rt2x00pci_register_write
(
rt2x00dev
,
TXCSR1
,
reg
);
...
...
drivers/net/wireless/rt2x00/rt2500pci.c
浏览文件 @
ea6a634e
...
...
@@ -337,9 +337,8 @@ static void rt2500pci_config_erp(struct rt2x00_dev *rt2x00dev,
preamble_mask
=
erp
->
short_preamble
<<
3
;
rt2x00pci_register_read
(
rt2x00dev
,
TXCSR1
,
&
reg
);
rt2x00_set_field32
(
&
reg
,
TXCSR1_ACK_TIMEOUT
,
erp
->
ack_timeout
);
rt2x00_set_field32
(
&
reg
,
TXCSR1_ACK_CONSUME_TIME
,
erp
->
ack_consume_time
);
rt2x00_set_field32
(
&
reg
,
TXCSR1_ACK_TIMEOUT
,
0x162
);
rt2x00_set_field32
(
&
reg
,
TXCSR1_ACK_CONSUME_TIME
,
0xa2
);
rt2x00_set_field32
(
&
reg
,
TXCSR1_TSF_OFFSET
,
IEEE80211_HEADER
);
rt2x00_set_field32
(
&
reg
,
TXCSR1_AUTORESPONDER
,
1
);
rt2x00pci_register_write
(
rt2x00dev
,
TXCSR1
,
reg
);
...
...
drivers/net/wireless/rt2x00/rt2500usb.c
浏览文件 @
ea6a634e
...
...
@@ -488,10 +488,6 @@ static void rt2500usb_config_erp(struct rt2x00_dev *rt2x00dev,
{
u16
reg
;
rt2500usb_register_read
(
rt2x00dev
,
TXRX_CSR1
,
&
reg
);
rt2x00_set_field16
(
&
reg
,
TXRX_CSR1_ACK_TIMEOUT
,
erp
->
ack_timeout
);
rt2500usb_register_write
(
rt2x00dev
,
TXRX_CSR1
,
reg
);
rt2500usb_register_read
(
rt2x00dev
,
TXRX_CSR10
,
&
reg
);
rt2x00_set_field16
(
&
reg
,
TXRX_CSR10_AUTORESPOND_PREAMBLE
,
!!
erp
->
short_preamble
);
...
...
drivers/net/wireless/rt2x00/rt2800usb.c
浏览文件 @
ea6a634e
...
...
@@ -580,8 +580,7 @@ static void rt2800usb_config_erp(struct rt2x00_dev *rt2x00dev,
u32
reg
;
rt2x00usb_register_read
(
rt2x00dev
,
TX_TIMEOUT_CFG
,
&
reg
);
rt2x00_set_field32
(
&
reg
,
TX_TIMEOUT_CFG_RX_ACK_TIMEOUT
,
DIV_ROUND_UP
(
erp
->
ack_timeout
,
erp
->
slot_time
));
rt2x00_set_field32
(
&
reg
,
TX_TIMEOUT_CFG_RX_ACK_TIMEOUT
,
0x20
);
rt2x00usb_register_write
(
rt2x00dev
,
TX_TIMEOUT_CFG
,
reg
);
rt2x00usb_register_read
(
rt2x00dev
,
AUTO_RSP_CFG
,
&
reg
);
...
...
drivers/net/wireless/rt2x00/rt2x00.h
浏览文件 @
ea6a634e
...
...
@@ -417,9 +417,6 @@ struct rt2x00lib_erp {
int
short_preamble
;
int
cts_protection
;
int
ack_timeout
;
int
ack_consume_time
;
u32
basic_rates
;
int
slot_time
;
...
...
drivers/net/wireless/rt2x00/rt2x00config.c
浏览文件 @
ea6a634e
...
...
@@ -94,17 +94,6 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
erp
.
difs
=
bss_conf
->
use_short_slot
?
SHORT_DIFS
:
DIFS
;
erp
.
eifs
=
bss_conf
->
use_short_slot
?
SHORT_EIFS
:
EIFS
;
erp
.
ack_timeout
=
PLCP
+
erp
.
difs
+
GET_DURATION
(
ACK_SIZE
,
10
);
erp
.
ack_consume_time
=
SIFS
+
PLCP
+
GET_DURATION
(
ACK_SIZE
,
10
);
if
(
bss_conf
->
use_short_preamble
)
{
erp
.
ack_timeout
+=
SHORT_PREAMBLE
;
erp
.
ack_consume_time
+=
SHORT_PREAMBLE
;
}
else
{
erp
.
ack_timeout
+=
PREAMBLE
;
erp
.
ack_consume_time
+=
PREAMBLE
;
}
erp
.
basic_rates
=
bss_conf
->
basic_rates
;
erp
.
beacon_int
=
bss_conf
->
beacon_int
;
...
...
drivers/net/wireless/rt2x00/rt61pci.c
浏览文件 @
ea6a634e
...
...
@@ -598,7 +598,7 @@ static void rt61pci_config_erp(struct rt2x00_dev *rt2x00dev,
u32
reg
;
rt2x00pci_register_read
(
rt2x00dev
,
TXRX_CSR0
,
&
reg
);
rt2x00_set_field32
(
&
reg
,
TXRX_CSR0_RX_ACK_TIMEOUT
,
erp
->
ack_timeout
);
rt2x00_set_field32
(
&
reg
,
TXRX_CSR0_RX_ACK_TIMEOUT
,
0x32
);
rt2x00_set_field32
(
&
reg
,
TXRX_CSR0_TSF_OFFSET
,
IEEE80211_HEADER
);
rt2x00pci_register_write
(
rt2x00dev
,
TXRX_CSR0
,
reg
);
...
...
drivers/net/wireless/rt2x00/rt73usb.c
浏览文件 @
ea6a634e
...
...
@@ -561,7 +561,7 @@ static void rt73usb_config_erp(struct rt2x00_dev *rt2x00dev,
u32
reg
;
rt2x00usb_register_read
(
rt2x00dev
,
TXRX_CSR0
,
&
reg
);
rt2x00_set_field32
(
&
reg
,
TXRX_CSR0_RX_ACK_TIMEOUT
,
erp
->
ack_timeout
);
rt2x00_set_field32
(
&
reg
,
TXRX_CSR0_RX_ACK_TIMEOUT
,
0x32
);
rt2x00_set_field32
(
&
reg
,
TXRX_CSR0_TSF_OFFSET
,
IEEE80211_HEADER
);
rt2x00usb_register_write
(
rt2x00dev
,
TXRX_CSR0
,
reg
);
...
...
drivers/ssb/Kconfig
浏览文件 @
ea6a634e
...
...
@@ -66,6 +66,20 @@ config SSB_PCMCIAHOST
If unsure, say N
config SSB_SDIOHOST_POSSIBLE
bool
depends on SSB && (MMC = y || MMC = SSB)
default y
config SSB_SDIOHOST
bool "Support for SSB on SDIO-bus host"
depends on SSB_SDIOHOST_POSSIBLE
help
Support for a Sonics Silicon Backplane on top
of a SDIO device.
If unsure, say N
config SSB_SILENT
bool "No SSB kernel messages"
depends on SSB && EMBEDDED
...
...
drivers/ssb/Makefile
浏览文件 @
ea6a634e
...
...
@@ -6,6 +6,7 @@ ssb-$(CONFIG_SSB_SPROM) += sprom.o
# host support
ssb-$(CONFIG_SSB_PCIHOST)
+=
pci.o pcihost_wrapper.o
ssb-$(CONFIG_SSB_PCMCIAHOST)
+=
pcmcia.o
ssb-$(CONFIG_SSB_SDIOHOST)
+=
sdio.o
# built-in drivers
ssb-y
+=
driver_chipcommon.o
...
...
drivers/ssb/main.c
浏览文件 @
ea6a634e
...
...
@@ -17,6 +17,7 @@
#include <linux/ssb/ssb_driver_gige.h>
#include <linux/dma-mapping.h>
#include <linux/pci.h>
#include <linux/mmc/sdio_func.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
...
...
@@ -88,6 +89,25 @@ struct ssb_bus *ssb_pcmcia_dev_to_bus(struct pcmcia_device *pdev)
}
#endif
/* CONFIG_SSB_PCMCIAHOST */
#ifdef CONFIG_SSB_SDIOHOST
struct
ssb_bus
*
ssb_sdio_func_to_bus
(
struct
sdio_func
*
func
)
{
struct
ssb_bus
*
bus
;
ssb_buses_lock
();
list_for_each_entry
(
bus
,
&
buses
,
list
)
{
if
(
bus
->
bustype
==
SSB_BUSTYPE_SDIO
&&
bus
->
host_sdio
==
func
)
goto
found
;
}
bus
=
NULL
;
found:
ssb_buses_unlock
();
return
bus
;
}
#endif
/* CONFIG_SSB_SDIOHOST */
int
ssb_for_each_bus_call
(
unsigned
long
data
,
int
(
*
func
)(
struct
ssb_bus
*
bus
,
unsigned
long
data
))
{
...
...
@@ -467,6 +487,12 @@ static int ssb_devices_register(struct ssb_bus *bus)
#ifdef CONFIG_SSB_PCMCIAHOST
sdev
->
irq
=
bus
->
host_pcmcia
->
irq
.
AssignedIRQ
;
dev
->
parent
=
&
bus
->
host_pcmcia
->
dev
;
#endif
break
;
case
SSB_BUSTYPE_SDIO
:
#ifdef CONFIG_SSB_SDIO
sdev
->
irq
=
bus
->
host_sdio
->
dev
.
irq
;
dev
->
parent
=
&
bus
->
host_sdio
->
dev
;
#endif
break
;
case
SSB_BUSTYPE_SSB
:
...
...
@@ -724,12 +750,18 @@ static int ssb_bus_register(struct ssb_bus *bus,
err
=
ssb_pci_xtal
(
bus
,
SSB_GPIO_XTAL
|
SSB_GPIO_PLL
,
1
);
if
(
err
)
goto
out
;
/* Init SDIO-host device (if any), before the scan */
err
=
ssb_sdio_init
(
bus
);
if
(
err
)
goto
err_disable_xtal
;
ssb_buses_lock
();
bus
->
busnumber
=
next_busnumber
;
/* Scan for devices (cores) */
err
=
ssb_bus_scan
(
bus
,
baseaddr
);
if
(
err
)
goto
err_
disable_xtal
;
goto
err_
sdio_exit
;
/* Init PCI-host device (if any) */
err
=
ssb_pci_init
(
bus
);
...
...
@@ -776,6 +808,8 @@ static int ssb_bus_register(struct ssb_bus *bus,
ssb_pci_exit
(
bus
);
err_unmap:
ssb_iounmap
(
bus
);
err_sdio_exit:
ssb_sdio_exit
(
bus
);
err_disable_xtal:
ssb_buses_unlock
();
ssb_pci_xtal
(
bus
,
SSB_GPIO_XTAL
|
SSB_GPIO_PLL
,
0
);
...
...
@@ -825,6 +859,28 @@ int ssb_bus_pcmciabus_register(struct ssb_bus *bus,
EXPORT_SYMBOL
(
ssb_bus_pcmciabus_register
);
#endif
/* CONFIG_SSB_PCMCIAHOST */
#ifdef CONFIG_SSB_SDIOHOST
int
ssb_bus_sdiobus_register
(
struct
ssb_bus
*
bus
,
struct
sdio_func
*
func
,
unsigned
int
quirks
)
{
int
err
;
bus
->
bustype
=
SSB_BUSTYPE_SDIO
;
bus
->
host_sdio
=
func
;
bus
->
ops
=
&
ssb_sdio_ops
;
bus
->
quirks
=
quirks
;
err
=
ssb_bus_register
(
bus
,
ssb_sdio_get_invariants
,
~
0
);
if
(
!
err
)
{
ssb_printk
(
KERN_INFO
PFX
"Sonics Silicon Backplane found on "
"SDIO device %s
\n
"
,
sdio_func_id
(
func
));
}
return
err
;
}
EXPORT_SYMBOL
(
ssb_bus_sdiobus_register
);
#endif
/* CONFIG_SSB_PCMCIAHOST */
int
ssb_bus_ssbbus_register
(
struct
ssb_bus
*
bus
,
unsigned
long
baseaddr
,
ssb_invariants_func_t
get_invariants
)
...
...
@@ -1358,8 +1414,10 @@ static int __init ssb_modinit(void)
ssb_buses_lock
();
err
=
ssb_attach_queued_buses
();
ssb_buses_unlock
();
if
(
err
)
if
(
err
)
{
bus_unregister
(
&
ssb_bustype
);
goto
out
;
}
err
=
b43_pci_ssb_bridge_init
();
if
(
err
)
{
...
...
@@ -1375,7 +1433,7 @@ static int __init ssb_modinit(void)
/* don't fail SSB init because of this */
err
=
0
;
}
out:
return
err
;
}
/* ssb must be initialized after PCI but before the ssb drivers.
...
...
drivers/ssb/scan.c
浏览文件 @
ea6a634e
...
...
@@ -175,6 +175,9 @@ static u32 scan_read32(struct ssb_bus *bus, u8 current_coreidx,
}
else
ssb_pcmcia_switch_segment
(
bus
,
0
);
break
;
case
SSB_BUSTYPE_SDIO
:
offset
+=
current_coreidx
*
SSB_CORE_SIZE
;
return
ssb_sdio_scan_read32
(
bus
,
offset
);
}
return
readl
(
bus
->
mmio
+
offset
);
}
...
...
@@ -188,6 +191,8 @@ static int scan_switchcore(struct ssb_bus *bus, u8 coreidx)
return
ssb_pci_switch_coreidx
(
bus
,
coreidx
);
case
SSB_BUSTYPE_PCMCIA
:
return
ssb_pcmcia_switch_coreidx
(
bus
,
coreidx
);
case
SSB_BUSTYPE_SDIO
:
return
ssb_sdio_scan_switch_coreidx
(
bus
,
coreidx
);
}
return
0
;
}
...
...
@@ -206,6 +211,8 @@ void ssb_iounmap(struct ssb_bus *bus)
SSB_BUG_ON
(
1
);
/* Can't reach this code. */
#endif
break
;
case
SSB_BUSTYPE_SDIO
:
break
;
}
bus
->
mmio
=
NULL
;
bus
->
mapped_device
=
NULL
;
...
...
@@ -230,6 +237,10 @@ static void __iomem *ssb_ioremap(struct ssb_bus *bus,
SSB_BUG_ON
(
1
);
/* Can't reach this code. */
#endif
break
;
case
SSB_BUSTYPE_SDIO
:
/* Nothing to ioremap in the SDIO case, just fake it */
mmio
=
(
void
__iomem
*
)
baseaddr
;
break
;
}
return
mmio
;
...
...
drivers/ssb/sdio.c
0 → 100644
浏览文件 @
ea6a634e
/*
* Sonics Silicon Backplane
* SDIO-Hostbus related functions
*
* Copyright 2009 Albert Herranz <albert_herranz@yahoo.es>
*
* Based on drivers/ssb/pcmcia.c
* Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
* Copyright 2007-2008 Michael Buesch <mb@bu3sch.de>
*
* Licensed under the GNU/GPL. See COPYING for details.
*
*/
#include <linux/ssb/ssb.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/etherdevice.h>
#include <linux/mmc/sdio_func.h>
#include "ssb_private.h"
/* Define the following to 1 to enable a printk on each coreswitch. */
#define SSB_VERBOSE_SDIOCORESWITCH_DEBUG 1
/* Hardware invariants CIS tuples */
#define SSB_SDIO_CIS 0x80
#define SSB_SDIO_CIS_SROMREV 0x00
#define SSB_SDIO_CIS_ID 0x01
#define SSB_SDIO_CIS_BOARDREV 0x02
#define SSB_SDIO_CIS_PA 0x03
#define SSB_SDIO_CIS_PA_PA0B0_LO 0
#define SSB_SDIO_CIS_PA_PA0B0_HI 1
#define SSB_SDIO_CIS_PA_PA0B1_LO 2
#define SSB_SDIO_CIS_PA_PA0B1_HI 3
#define SSB_SDIO_CIS_PA_PA0B2_LO 4
#define SSB_SDIO_CIS_PA_PA0B2_HI 5
#define SSB_SDIO_CIS_PA_ITSSI 6
#define SSB_SDIO_CIS_PA_MAXPOW 7
#define SSB_SDIO_CIS_OEMNAME 0x04
#define SSB_SDIO_CIS_CCODE 0x05
#define SSB_SDIO_CIS_ANTENNA 0x06
#define SSB_SDIO_CIS_ANTGAIN 0x07
#define SSB_SDIO_CIS_BFLAGS 0x08
#define SSB_SDIO_CIS_LEDS 0x09
#define CISTPL_FUNCE_LAN_NODE_ID 0x04
/* same as in PCMCIA */
/*
* Function 1 miscellaneous registers.
*
* Definitions match src/include/sbsdio.h from the
* Android Open Source Project
* http://android.git.kernel.org/?p=platform/system/wlan/broadcom.git
*
*/
#define SBSDIO_FUNC1_SBADDRLOW 0x1000a
/* SB Address window Low (b15) */
#define SBSDIO_FUNC1_SBADDRMID 0x1000b
/* SB Address window Mid (b23-b16) */
#define SBSDIO_FUNC1_SBADDRHIGH 0x1000c
/* SB Address window High (b24-b31) */
/* valid bits in SBSDIO_FUNC1_SBADDRxxx regs */
#define SBSDIO_SBADDRLOW_MASK 0x80
/* Valid address bits in SBADDRLOW */
#define SBSDIO_SBADDRMID_MASK 0xff
/* Valid address bits in SBADDRMID */
#define SBSDIO_SBADDRHIGH_MASK 0xff
/* Valid address bits in SBADDRHIGH */
#define SBSDIO_SB_OFT_ADDR_MASK 0x7FFF
/* sb offset addr is <= 15 bits, 32k */
/* REVISIT: this flag doesn't seem to matter */
#define SBSDIO_SB_ACCESS_2_4B_FLAG 0x8000
/* forces 32-bit SB access */
/*
* Address map within the SDIO function address space (128K).
*
* Start End Description
* ------- ------- ------------------------------------------
* 0x00000 0x0ffff selected backplane address window (64K)
* 0x10000 0x1ffff backplane control registers (max 64K)
*
* The current address window is configured by writing to registers
* SBADDRLOW, SBADDRMID and SBADDRHIGH.
*
* In order to access the contents of a 32-bit Silicon Backplane address
* the backplane address window must be first loaded with the highest
* 16 bits of the target address. Then, an access must be done to the
* SDIO function address space using the lower 15 bits of the address.
* Bit 15 of the address must be set when doing 32 bit accesses.
*
* 10987654321098765432109876543210
* WWWWWWWWWWWWWWWWW SB Address Window
* OOOOOOOOOOOOOOOO Offset within SB Address Window
* a 32-bit access flag
*/
/*
* SSB I/O via SDIO.
*
* NOTE: SDIO address @addr is 17 bits long (SDIO address space is 128K).
*/
static
inline
struct
device
*
ssb_sdio_dev
(
struct
ssb_bus
*
bus
)
{
return
&
bus
->
host_sdio
->
dev
;
}
/* host claimed */
static
int
ssb_sdio_writeb
(
struct
ssb_bus
*
bus
,
unsigned
int
addr
,
u8
val
)
{
int
error
=
0
;
sdio_writeb
(
bus
->
host_sdio
,
val
,
addr
,
&
error
);
if
(
unlikely
(
error
))
{
dev_dbg
(
ssb_sdio_dev
(
bus
),
"%08X <- %02x, error %d
\n
"
,
addr
,
val
,
error
);
}
return
error
;
}
#if 0
static u8 ssb_sdio_readb(struct ssb_bus *bus, unsigned int addr)
{
u8 val;
int error = 0;
val = sdio_readb(bus->host_sdio, addr, &error);
if (unlikely(error)) {
dev_dbg(ssb_sdio_dev(bus), "%08X -> %02x, error %d\n",
addr, val, error);
}
return val;
}
#endif
/* host claimed */
static
int
ssb_sdio_set_sbaddr_window
(
struct
ssb_bus
*
bus
,
u32
address
)
{
int
error
;
error
=
ssb_sdio_writeb
(
bus
,
SBSDIO_FUNC1_SBADDRLOW
,
(
address
>>
8
)
&
SBSDIO_SBADDRLOW_MASK
);
if
(
error
)
goto
out
;
error
=
ssb_sdio_writeb
(
bus
,
SBSDIO_FUNC1_SBADDRMID
,
(
address
>>
16
)
&
SBSDIO_SBADDRMID_MASK
);
if
(
error
)
goto
out
;
error
=
ssb_sdio_writeb
(
bus
,
SBSDIO_FUNC1_SBADDRHIGH
,
(
address
>>
24
)
&
SBSDIO_SBADDRHIGH_MASK
);
if
(
error
)
goto
out
;
bus
->
sdio_sbaddr
=
address
;
out:
if
(
error
)
{
dev_dbg
(
ssb_sdio_dev
(
bus
),
"failed to set address window"
" to 0x%08x, error %d
\n
"
,
address
,
error
);
}
return
error
;
}
/* for enumeration use only */
u32
ssb_sdio_scan_read32
(
struct
ssb_bus
*
bus
,
u16
offset
)
{
u32
val
;
int
error
;
sdio_claim_host
(
bus
->
host_sdio
);
val
=
sdio_readl
(
bus
->
host_sdio
,
offset
,
&
error
);
sdio_release_host
(
bus
->
host_sdio
);
if
(
unlikely
(
error
))
{
dev_dbg
(
ssb_sdio_dev
(
bus
),
"%04X:%04X > %08x, error %d
\n
"
,
bus
->
sdio_sbaddr
>>
16
,
offset
,
val
,
error
);
}
return
val
;
}
/* for enumeration use only */
int
ssb_sdio_scan_switch_coreidx
(
struct
ssb_bus
*
bus
,
u8
coreidx
)
{
u32
sbaddr
;
int
error
;
sbaddr
=
(
coreidx
*
SSB_CORE_SIZE
)
+
SSB_ENUM_BASE
;
sdio_claim_host
(
bus
->
host_sdio
);
error
=
ssb_sdio_set_sbaddr_window
(
bus
,
sbaddr
);
sdio_release_host
(
bus
->
host_sdio
);
if
(
error
)
{
dev_err
(
ssb_sdio_dev
(
bus
),
"failed to switch to core %u,"
" error %d
\n
"
,
coreidx
,
error
);
goto
out
;
}
out:
return
error
;
}
/* host must be already claimed */
int
ssb_sdio_switch_core
(
struct
ssb_bus
*
bus
,
struct
ssb_device
*
dev
)
{
u8
coreidx
=
dev
->
core_index
;
u32
sbaddr
;
int
error
=
0
;
sbaddr
=
(
coreidx
*
SSB_CORE_SIZE
)
+
SSB_ENUM_BASE
;
if
(
unlikely
(
bus
->
sdio_sbaddr
!=
sbaddr
))
{
#if SSB_VERBOSE_SDIOCORESWITCH_DEBUG
dev_info
(
ssb_sdio_dev
(
bus
),
"switching to %s core, index %d
\n
"
,
ssb_core_name
(
dev
->
id
.
coreid
),
coreidx
);
#endif
error
=
ssb_sdio_set_sbaddr_window
(
bus
,
sbaddr
);
if
(
error
)
{
dev_dbg
(
ssb_sdio_dev
(
bus
),
"failed to switch to"
" core %u, error %d
\n
"
,
coreidx
,
error
);
goto
out
;
}
bus
->
mapped_device
=
dev
;
}
out:
return
error
;
}
static
u8
ssb_sdio_read8
(
struct
ssb_device
*
dev
,
u16
offset
)
{
struct
ssb_bus
*
bus
=
dev
->
bus
;
u8
val
=
0xff
;
int
error
=
0
;
sdio_claim_host
(
bus
->
host_sdio
);
if
(
unlikely
(
ssb_sdio_switch_core
(
bus
,
dev
)))
goto
out
;
offset
|=
bus
->
sdio_sbaddr
&
0xffff
;
offset
&=
SBSDIO_SB_OFT_ADDR_MASK
;
val
=
sdio_readb
(
bus
->
host_sdio
,
offset
,
&
error
);
if
(
error
)
{
dev_dbg
(
ssb_sdio_dev
(
bus
),
"%04X:%04X > %02x, error %d
\n
"
,
bus
->
sdio_sbaddr
>>
16
,
offset
,
val
,
error
);
}
out:
sdio_release_host
(
bus
->
host_sdio
);
return
val
;
}
static
u16
ssb_sdio_read16
(
struct
ssb_device
*
dev
,
u16
offset
)
{
struct
ssb_bus
*
bus
=
dev
->
bus
;
u16
val
=
0xffff
;
int
error
=
0
;
sdio_claim_host
(
bus
->
host_sdio
);
if
(
unlikely
(
ssb_sdio_switch_core
(
bus
,
dev
)))
goto
out
;
offset
|=
bus
->
sdio_sbaddr
&
0xffff
;
offset
&=
SBSDIO_SB_OFT_ADDR_MASK
;
val
=
sdio_readw
(
bus
->
host_sdio
,
offset
,
&
error
);
if
(
error
)
{
dev_dbg
(
ssb_sdio_dev
(
bus
),
"%04X:%04X > %04x, error %d
\n
"
,
bus
->
sdio_sbaddr
>>
16
,
offset
,
val
,
error
);
}
out:
sdio_release_host
(
bus
->
host_sdio
);
return
val
;
}
static
u32
ssb_sdio_read32
(
struct
ssb_device
*
dev
,
u16
offset
)
{
struct
ssb_bus
*
bus
=
dev
->
bus
;
u32
val
=
0xffffffff
;
int
error
=
0
;
sdio_claim_host
(
bus
->
host_sdio
);
if
(
unlikely
(
ssb_sdio_switch_core
(
bus
,
dev
)))
goto
out
;
offset
|=
bus
->
sdio_sbaddr
&
0xffff
;
offset
&=
SBSDIO_SB_OFT_ADDR_MASK
;
offset
|=
SBSDIO_SB_ACCESS_2_4B_FLAG
;
/* 32 bit data access */
val
=
sdio_readl
(
bus
->
host_sdio
,
offset
,
&
error
);
if
(
error
)
{
dev_dbg
(
ssb_sdio_dev
(
bus
),
"%04X:%04X > %08x, error %d
\n
"
,
bus
->
sdio_sbaddr
>>
16
,
offset
,
val
,
error
);
}
out:
sdio_release_host
(
bus
->
host_sdio
);
return
val
;
}
#ifdef CONFIG_SSB_BLOCKIO
static
void
ssb_sdio_block_read
(
struct
ssb_device
*
dev
,
void
*
buffer
,
size_t
count
,
u16
offset
,
u8
reg_width
)
{
size_t
saved_count
=
count
;
struct
ssb_bus
*
bus
=
dev
->
bus
;
int
error
=
0
;
sdio_claim_host
(
bus
->
host_sdio
);
if
(
unlikely
(
ssb_sdio_switch_core
(
bus
,
dev
)))
{
error
=
-
EIO
;
memset
(
buffer
,
0xff
,
count
);
goto
err_out
;
}
offset
|=
bus
->
sdio_sbaddr
&
0xffff
;
offset
&=
SBSDIO_SB_OFT_ADDR_MASK
;
switch
(
reg_width
)
{
case
sizeof
(
u8
):
{
error
=
sdio_readsb
(
bus
->
host_sdio
,
buffer
,
offset
,
count
);
break
;
}
case
sizeof
(
u16
):
{
SSB_WARN_ON
(
count
&
1
);
error
=
sdio_readsb
(
bus
->
host_sdio
,
buffer
,
offset
,
count
);
break
;
}
case
sizeof
(
u32
):
{
SSB_WARN_ON
(
count
&
3
);
offset
|=
SBSDIO_SB_ACCESS_2_4B_FLAG
;
/* 32 bit data access */
error
=
sdio_readsb
(
bus
->
host_sdio
,
buffer
,
offset
,
count
);
break
;
}
default:
SSB_WARN_ON
(
1
);
}
if
(
!
error
)
goto
out
;
err_out:
dev_dbg
(
ssb_sdio_dev
(
bus
),
"%04X:%04X (width=%u, len=%u), error %d
\n
"
,
bus
->
sdio_sbaddr
>>
16
,
offset
,
reg_width
,
saved_count
,
error
);
out:
sdio_release_host
(
bus
->
host_sdio
);
}
#endif
/* CONFIG_SSB_BLOCKIO */
static
void
ssb_sdio_write8
(
struct
ssb_device
*
dev
,
u16
offset
,
u8
val
)
{
struct
ssb_bus
*
bus
=
dev
->
bus
;
int
error
=
0
;
sdio_claim_host
(
bus
->
host_sdio
);
if
(
unlikely
(
ssb_sdio_switch_core
(
bus
,
dev
)))
goto
out
;
offset
|=
bus
->
sdio_sbaddr
&
0xffff
;
offset
&=
SBSDIO_SB_OFT_ADDR_MASK
;
sdio_writeb
(
bus
->
host_sdio
,
val
,
offset
,
&
error
);
if
(
error
)
{
dev_dbg
(
ssb_sdio_dev
(
bus
),
"%04X:%04X < %02x, error %d
\n
"
,
bus
->
sdio_sbaddr
>>
16
,
offset
,
val
,
error
);
}
out:
sdio_release_host
(
bus
->
host_sdio
);
}
static
void
ssb_sdio_write16
(
struct
ssb_device
*
dev
,
u16
offset
,
u16
val
)
{
struct
ssb_bus
*
bus
=
dev
->
bus
;
int
error
=
0
;
sdio_claim_host
(
bus
->
host_sdio
);
if
(
unlikely
(
ssb_sdio_switch_core
(
bus
,
dev
)))
goto
out
;
offset
|=
bus
->
sdio_sbaddr
&
0xffff
;
offset
&=
SBSDIO_SB_OFT_ADDR_MASK
;
sdio_writew
(
bus
->
host_sdio
,
val
,
offset
,
&
error
);
if
(
error
)
{
dev_dbg
(
ssb_sdio_dev
(
bus
),
"%04X:%04X < %04x, error %d
\n
"
,
bus
->
sdio_sbaddr
>>
16
,
offset
,
val
,
error
);
}
out:
sdio_release_host
(
bus
->
host_sdio
);
}
static
void
ssb_sdio_write32
(
struct
ssb_device
*
dev
,
u16
offset
,
u32
val
)
{
struct
ssb_bus
*
bus
=
dev
->
bus
;
int
error
=
0
;
sdio_claim_host
(
bus
->
host_sdio
);
if
(
unlikely
(
ssb_sdio_switch_core
(
bus
,
dev
)))
goto
out
;
offset
|=
bus
->
sdio_sbaddr
&
0xffff
;
offset
&=
SBSDIO_SB_OFT_ADDR_MASK
;
offset
|=
SBSDIO_SB_ACCESS_2_4B_FLAG
;
/* 32 bit data access */
sdio_writel
(
bus
->
host_sdio
,
val
,
offset
,
&
error
);
if
(
error
)
{
dev_dbg
(
ssb_sdio_dev
(
bus
),
"%04X:%04X < %08x, error %d
\n
"
,
bus
->
sdio_sbaddr
>>
16
,
offset
,
val
,
error
);
}
if
(
bus
->
quirks
&
SSB_QUIRK_SDIO_READ_AFTER_WRITE32
)
sdio_readl
(
bus
->
host_sdio
,
0
,
&
error
);
out:
sdio_release_host
(
bus
->
host_sdio
);
}
#ifdef CONFIG_SSB_BLOCKIO
static
void
ssb_sdio_block_write
(
struct
ssb_device
*
dev
,
const
void
*
buffer
,
size_t
count
,
u16
offset
,
u8
reg_width
)
{
size_t
saved_count
=
count
;
struct
ssb_bus
*
bus
=
dev
->
bus
;
int
error
=
0
;
sdio_claim_host
(
bus
->
host_sdio
);
if
(
unlikely
(
ssb_sdio_switch_core
(
bus
,
dev
)))
{
error
=
-
EIO
;
memset
((
void
*
)
buffer
,
0xff
,
count
);
goto
err_out
;
}
offset
|=
bus
->
sdio_sbaddr
&
0xffff
;
offset
&=
SBSDIO_SB_OFT_ADDR_MASK
;
switch
(
reg_width
)
{
case
sizeof
(
u8
):
error
=
sdio_writesb
(
bus
->
host_sdio
,
offset
,
(
void
*
)
buffer
,
count
);
break
;
case
sizeof
(
u16
):
SSB_WARN_ON
(
count
&
1
);
error
=
sdio_writesb
(
bus
->
host_sdio
,
offset
,
(
void
*
)
buffer
,
count
);
break
;
case
sizeof
(
u32
):
SSB_WARN_ON
(
count
&
3
);
offset
|=
SBSDIO_SB_ACCESS_2_4B_FLAG
;
/* 32 bit data access */
error
=
sdio_writesb
(
bus
->
host_sdio
,
offset
,
(
void
*
)
buffer
,
count
);
break
;
default:
SSB_WARN_ON
(
1
);
}
if
(
!
error
)
goto
out
;
err_out:
dev_dbg
(
ssb_sdio_dev
(
bus
),
"%04X:%04X (width=%u, len=%u), error %d
\n
"
,
bus
->
sdio_sbaddr
>>
16
,
offset
,
reg_width
,
saved_count
,
error
);
out:
sdio_release_host
(
bus
->
host_sdio
);
}
#endif
/* CONFIG_SSB_BLOCKIO */
/* Not "static", as it's used in main.c */
const
struct
ssb_bus_ops
ssb_sdio_ops
=
{
.
read8
=
ssb_sdio_read8
,
.
read16
=
ssb_sdio_read16
,
.
read32
=
ssb_sdio_read32
,
.
write8
=
ssb_sdio_write8
,
.
write16
=
ssb_sdio_write16
,
.
write32
=
ssb_sdio_write32
,
#ifdef CONFIG_SSB_BLOCKIO
.
block_read
=
ssb_sdio_block_read
,
.
block_write
=
ssb_sdio_block_write
,
#endif
};
#define GOTO_ERROR_ON(condition, description) do { \
if (unlikely(condition)) { \
error_description = description; \
goto error; \
} \
} while (0)
int
ssb_sdio_get_invariants
(
struct
ssb_bus
*
bus
,
struct
ssb_init_invariants
*
iv
)
{
struct
ssb_sprom
*
sprom
=
&
iv
->
sprom
;
struct
ssb_boardinfo
*
bi
=
&
iv
->
boardinfo
;
const
char
*
error_description
=
"none"
;
struct
sdio_func_tuple
*
tuple
;
void
*
mac
;
memset
(
sprom
,
0xFF
,
sizeof
(
*
sprom
));
sprom
->
boardflags_lo
=
0
;
sprom
->
boardflags_hi
=
0
;
tuple
=
bus
->
host_sdio
->
tuples
;
while
(
tuple
)
{
switch
(
tuple
->
code
)
{
case
0x22
:
/* extended function */
switch
(
tuple
->
data
[
0
])
{
case
CISTPL_FUNCE_LAN_NODE_ID
:
GOTO_ERROR_ON
((
tuple
->
size
!=
7
)
&&
(
tuple
->
data
[
1
]
!=
6
),
"mac tpl size"
);
/* fetch the MAC address. */
mac
=
tuple
->
data
+
2
;
memcpy
(
sprom
->
il0mac
,
mac
,
ETH_ALEN
);
memcpy
(
sprom
->
et1mac
,
mac
,
ETH_ALEN
);
break
;
default:
break
;
}
break
;
case
0x80
:
/* vendor specific tuple */
switch
(
tuple
->
data
[
0
])
{
case
SSB_SDIO_CIS_SROMREV
:
GOTO_ERROR_ON
(
tuple
->
size
!=
2
,
"sromrev tpl size"
);
sprom
->
revision
=
tuple
->
data
[
1
];
break
;
case
SSB_SDIO_CIS_ID
:
GOTO_ERROR_ON
((
tuple
->
size
!=
5
)
&&
(
tuple
->
size
!=
7
),
"id tpl size"
);
bi
->
vendor
=
tuple
->
data
[
1
]
|
(
tuple
->
data
[
2
]
<<
8
);
break
;
case
SSB_SDIO_CIS_BOARDREV
:
GOTO_ERROR_ON
(
tuple
->
size
!=
2
,
"boardrev tpl size"
);
sprom
->
board_rev
=
tuple
->
data
[
1
];
break
;
case
SSB_SDIO_CIS_PA
:
GOTO_ERROR_ON
((
tuple
->
size
!=
9
)
&&
(
tuple
->
size
!=
10
),
"pa tpl size"
);
sprom
->
pa0b0
=
tuple
->
data
[
1
]
|
((
u16
)
tuple
->
data
[
2
]
<<
8
);
sprom
->
pa0b1
=
tuple
->
data
[
3
]
|
((
u16
)
tuple
->
data
[
4
]
<<
8
);
sprom
->
pa0b2
=
tuple
->
data
[
5
]
|
((
u16
)
tuple
->
data
[
6
]
<<
8
);
sprom
->
itssi_a
=
tuple
->
data
[
7
];
sprom
->
itssi_bg
=
tuple
->
data
[
7
];
sprom
->
maxpwr_a
=
tuple
->
data
[
8
];
sprom
->
maxpwr_bg
=
tuple
->
data
[
8
];
break
;
case
SSB_SDIO_CIS_OEMNAME
:
/* Not present */
break
;
case
SSB_SDIO_CIS_CCODE
:
GOTO_ERROR_ON
(
tuple
->
size
!=
2
,
"ccode tpl size"
);
sprom
->
country_code
=
tuple
->
data
[
1
];
break
;
case
SSB_SDIO_CIS_ANTENNA
:
GOTO_ERROR_ON
(
tuple
->
size
!=
2
,
"ant tpl size"
);
sprom
->
ant_available_a
=
tuple
->
data
[
1
];
sprom
->
ant_available_bg
=
tuple
->
data
[
1
];
break
;
case
SSB_SDIO_CIS_ANTGAIN
:
GOTO_ERROR_ON
(
tuple
->
size
!=
2
,
"antg tpl size"
);
sprom
->
antenna_gain
.
ghz24
.
a0
=
tuple
->
data
[
1
];
sprom
->
antenna_gain
.
ghz24
.
a1
=
tuple
->
data
[
1
];
sprom
->
antenna_gain
.
ghz24
.
a2
=
tuple
->
data
[
1
];
sprom
->
antenna_gain
.
ghz24
.
a3
=
tuple
->
data
[
1
];
sprom
->
antenna_gain
.
ghz5
.
a0
=
tuple
->
data
[
1
];
sprom
->
antenna_gain
.
ghz5
.
a1
=
tuple
->
data
[
1
];
sprom
->
antenna_gain
.
ghz5
.
a2
=
tuple
->
data
[
1
];
sprom
->
antenna_gain
.
ghz5
.
a3
=
tuple
->
data
[
1
];
break
;
case
SSB_SDIO_CIS_BFLAGS
:
GOTO_ERROR_ON
((
tuple
->
size
!=
3
)
&&
(
tuple
->
size
!=
5
),
"bfl tpl size"
);
sprom
->
boardflags_lo
=
tuple
->
data
[
1
]
|
((
u16
)
tuple
->
data
[
2
]
<<
8
);
break
;
case
SSB_SDIO_CIS_LEDS
:
GOTO_ERROR_ON
(
tuple
->
size
!=
5
,
"leds tpl size"
);
sprom
->
gpio0
=
tuple
->
data
[
1
];
sprom
->
gpio1
=
tuple
->
data
[
2
];
sprom
->
gpio2
=
tuple
->
data
[
3
];
sprom
->
gpio3
=
tuple
->
data
[
4
];
break
;
default:
break
;
}
break
;
default:
break
;
}
tuple
=
tuple
->
next
;
}
return
0
;
error:
dev_err
(
ssb_sdio_dev
(
bus
),
"failed to fetch device invariants: %s
\n
"
,
error_description
);
return
-
ENODEV
;
}
void
ssb_sdio_exit
(
struct
ssb_bus
*
bus
)
{
if
(
bus
->
bustype
!=
SSB_BUSTYPE_SDIO
)
return
;
/* Nothing to do here. */
}
int
ssb_sdio_init
(
struct
ssb_bus
*
bus
)
{
if
(
bus
->
bustype
!=
SSB_BUSTYPE_SDIO
)
return
0
;
bus
->
sdio_sbaddr
=
~
0
;
return
0
;
}
drivers/ssb/ssb_private.h
浏览文件 @
ea6a634e
...
...
@@ -114,6 +114,46 @@ static inline int ssb_pcmcia_init(struct ssb_bus *bus)
}
#endif
/* CONFIG_SSB_PCMCIAHOST */
/* sdio.c */
#ifdef CONFIG_SSB_SDIOHOST
extern
int
ssb_sdio_get_invariants
(
struct
ssb_bus
*
bus
,
struct
ssb_init_invariants
*
iv
);
extern
u32
ssb_sdio_scan_read32
(
struct
ssb_bus
*
bus
,
u16
offset
);
extern
int
ssb_sdio_switch_core
(
struct
ssb_bus
*
bus
,
struct
ssb_device
*
dev
);
extern
int
ssb_sdio_scan_switch_coreidx
(
struct
ssb_bus
*
bus
,
u8
coreidx
);
extern
int
ssb_sdio_hardware_setup
(
struct
ssb_bus
*
bus
);
extern
void
ssb_sdio_exit
(
struct
ssb_bus
*
bus
);
extern
int
ssb_sdio_init
(
struct
ssb_bus
*
bus
);
extern
const
struct
ssb_bus_ops
ssb_sdio_ops
;
#else
/* CONFIG_SSB_SDIOHOST */
static
inline
u32
ssb_sdio_scan_read32
(
struct
ssb_bus
*
bus
,
u16
offset
)
{
return
0
;
}
static
inline
int
ssb_sdio_switch_core
(
struct
ssb_bus
*
bus
,
struct
ssb_device
*
dev
)
{
return
0
;
}
static
inline
int
ssb_sdio_scan_switch_coreidx
(
struct
ssb_bus
*
bus
,
u8
coreidx
)
{
return
0
;
}
static
inline
int
ssb_sdio_hardware_setup
(
struct
ssb_bus
*
bus
)
{
return
0
;
}
static
inline
void
ssb_sdio_exit
(
struct
ssb_bus
*
bus
)
{
}
static
inline
int
ssb_sdio_init
(
struct
ssb_bus
*
bus
)
{
return
0
;
}
#endif
/* CONFIG_SSB_SDIOHOST */
/* scan.c */
extern
const
char
*
ssb_core_name
(
u16
coreid
);
...
...
include/linux/ssb/ssb.h
浏览文件 @
ea6a634e
...
...
@@ -238,6 +238,7 @@ enum ssb_bustype {
SSB_BUSTYPE_SSB
,
/* This SSB bus is the system bus */
SSB_BUSTYPE_PCI
,
/* SSB is connected to PCI bus */
SSB_BUSTYPE_PCMCIA
,
/* SSB is connected to PCMCIA bus */
SSB_BUSTYPE_SDIO
,
/* SSB is connected to SDIO bus */
};
/* board_vendor */
...
...
@@ -270,8 +271,12 @@ struct ssb_bus {
/* The core in the basic address register window. (PCI bus only) */
struct
ssb_device
*
mapped_device
;
/* Currently mapped PCMCIA segment. (bustype == SSB_BUSTYPE_PCMCIA only) */
u8
mapped_pcmcia_seg
;
union
{
/* Currently mapped PCMCIA segment. (bustype == SSB_BUSTYPE_PCMCIA only) */
u8
mapped_pcmcia_seg
;
/* Current SSB base address window for SDIO. */
u32
sdio_sbaddr
;
};
/* Lock for core and segment switching.
* On PCMCIA-host busses this is used to protect the whole MMIO access. */
spinlock_t
bar_lock
;
...
...
@@ -282,6 +287,11 @@ struct ssb_bus {
struct
pci_dev
*
host_pci
;
/* Pointer to the PCMCIA device (only if bustype == SSB_BUSTYPE_PCMCIA). */
struct
pcmcia_device
*
host_pcmcia
;
/* Pointer to the SDIO device (only if bustype == SSB_BUSTYPE_SDIO). */
struct
sdio_func
*
host_sdio
;
/* See enum ssb_quirks */
unsigned
int
quirks
;
#ifdef CONFIG_SSB_SPROM
/* Mutex to protect the SPROM writing. */
...
...
@@ -336,6 +346,11 @@ struct ssb_bus {
#endif
/* DEBUG */
};
enum
ssb_quirks
{
/* SDIO connected card requires performing a read after writing a 32-bit value */
SSB_QUIRK_SDIO_READ_AFTER_WRITE32
=
(
1
<<
0
),
};
/* The initialization-invariants. */
struct
ssb_init_invariants
{
/* Versioning information about the PCB. */
...
...
@@ -366,6 +381,12 @@ extern int ssb_bus_pcmciabus_register(struct ssb_bus *bus,
struct
pcmcia_device
*
pcmcia_dev
,
unsigned
long
baseaddr
);
#endif
/* CONFIG_SSB_PCMCIAHOST */
#ifdef CONFIG_SSB_SDIOHOST
extern
int
ssb_bus_sdiobus_register
(
struct
ssb_bus
*
bus
,
struct
sdio_func
*
sdio_func
,
unsigned
int
quirks
);
#endif
/* CONFIG_SSB_SDIOHOST */
extern
void
ssb_bus_unregister
(
struct
ssb_bus
*
bus
);
...
...
net/wireless/Kconfig
浏览文件 @
ea6a634e
config CFG80211
tristate "
Improved
wireless configuration API"
tristate "
cfg80211 -
wireless configuration API"
depends on RFKILL || !RFKILL
---help---
cfg80211 is the Linux wireless LAN (802.11) configuration API.
Enable this if you have a wireless device.
For more information refer to documentation on the wireless wiki:
http://wireless.kernel.org/en/developers/Documentation/cfg80211
When built as a module it will be called cfg80211.
config NL80211_TESTMODE
bool "nl80211 testmode command"
...
...
net/wireless/scan.c
浏览文件 @
ea6a634e
...
...
@@ -607,6 +607,9 @@ int cfg80211_wext_siwscan(struct net_device *dev,
if
(
!
netif_running
(
dev
))
return
-
ENETDOWN
;
if
(
wrqu
->
data
.
length
==
sizeof
(
struct
iw_scan_req
))
wreq
=
(
struct
iw_scan_req
*
)
extra
;
rdev
=
cfg80211_get_dev_from_ifindex
(
dev_net
(
dev
),
dev
->
ifindex
);
if
(
IS_ERR
(
rdev
))
...
...
@@ -619,9 +622,14 @@ int cfg80211_wext_siwscan(struct net_device *dev,
wiphy
=
&
rdev
->
wiphy
;
for
(
band
=
0
;
band
<
IEEE80211_NUM_BANDS
;
band
++
)
if
(
wiphy
->
bands
[
band
])
n_channels
+=
wiphy
->
bands
[
band
]
->
n_channels
;
/* Determine number of channels, needed to allocate creq */
if
(
wreq
&&
wreq
->
num_channels
)
n_channels
=
wreq
->
num_channels
;
else
{
for
(
band
=
0
;
band
<
IEEE80211_NUM_BANDS
;
band
++
)
if
(
wiphy
->
bands
[
band
])
n_channels
+=
wiphy
->
bands
[
band
]
->
n_channels
;
}
creq
=
kzalloc
(
sizeof
(
*
creq
)
+
sizeof
(
struct
cfg80211_ssid
)
+
n_channels
*
sizeof
(
void
*
),
...
...
@@ -638,22 +646,41 @@ int cfg80211_wext_siwscan(struct net_device *dev,
creq
->
n_channels
=
n_channels
;
creq
->
n_ssids
=
1
;
/*
all channels
*/
/*
translate "Scan on frequencies" request
*/
i
=
0
;
for
(
band
=
0
;
band
<
IEEE80211_NUM_BANDS
;
band
++
)
{
int
j
;
if
(
!
wiphy
->
bands
[
band
])
continue
;
for
(
j
=
0
;
j
<
wiphy
->
bands
[
band
]
->
n_channels
;
j
++
)
{
/* If we have a wireless request structure and the
* wireless request specifies frequencies, then search
* for the matching hardware channel.
*/
if
(
wreq
&&
wreq
->
num_channels
)
{
int
k
;
int
wiphy_freq
=
wiphy
->
bands
[
band
]
->
channels
[
j
].
center_freq
;
for
(
k
=
0
;
k
<
wreq
->
num_channels
;
k
++
)
{
int
wext_freq
=
wreq
->
channel_list
[
k
].
m
/
100000
;
if
(
wext_freq
==
wiphy_freq
)
goto
wext_freq_found
;
}
goto
wext_freq_not_found
;
}
wext_freq_found:
creq
->
channels
[
i
]
=
&
wiphy
->
bands
[
band
]
->
channels
[
j
];
i
++
;
wext_freq_not_found:
;
}
}
/* translate scan request */
if
(
wrqu
->
data
.
length
==
sizeof
(
struct
iw_scan_req
))
{
wreq
=
(
struct
iw_scan_req
*
)
extra
;
/* Set real number of channels specified in creq->channels[] */
creq
->
n_channels
=
i
;
/* translate "Scan for SSID" request */
if
(
wreq
)
{
if
(
wrqu
->
data
.
flags
&
IW_SCAN_THIS_ESSID
)
{
if
(
wreq
->
essid_len
>
IEEE80211_MAX_SSID_LEN
)
return
-
EINVAL
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录