Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
c3da63f3
Commit
c3da63f3
authored
Jun 20, 2009
by
David S. Miller
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of
git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
parents
73e42897
a97f4424
Changes
17
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
338 additions
and
89 deletions
+338
-89
Documentation/rfkill.txt
Documentation/rfkill.txt
+2
-0
MAINTAINERS
MAINTAINERS
+3
-3
drivers/net/wireless/ath/ath5k/base.c
drivers/net/wireless/ath/ath5k/base.c
+8
-3
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/ath/ath9k/main.c
+1
-1
drivers/net/wireless/ath/ath9k/pci.c
drivers/net/wireless/ath/ath9k/pci.c
+18
-0
drivers/net/wireless/ath/ath9k/recv.c
drivers/net/wireless/ath/ath9k/recv.c
+5
-2
drivers/net/wireless/iwmc3200wifi/iwm.h
drivers/net/wireless/iwmc3200wifi/iwm.h
+4
-0
drivers/net/wireless/iwmc3200wifi/main.c
drivers/net/wireless/iwmc3200wifi/main.c
+58
-6
drivers/net/wireless/iwmc3200wifi/netdev.c
drivers/net/wireless/iwmc3200wifi/netdev.c
+31
-18
drivers/net/wireless/iwmc3200wifi/sdio.c
drivers/net/wireless/iwmc3200wifi/sdio.c
+10
-1
drivers/net/wireless/zd1211rw/zd_usb.c
drivers/net/wireless/zd1211rw/zd_usb.c
+1
-0
drivers/platform/x86/acer-wmi.c
drivers/platform/x86/acer-wmi.c
+2
-2
drivers/platform/x86/eeepc-laptop.c
drivers/platform/x86/eeepc-laptop.c
+42
-8
drivers/platform/x86/thinkpad_acpi.c
drivers/platform/x86/thinkpad_acpi.c
+7
-7
include/linux/rfkill.h
include/linux/rfkill.h
+28
-5
net/rfkill/core.c
net/rfkill/core.c
+38
-18
net/wireless/nl80211.c
net/wireless/nl80211.c
+80
-15
No files found.
Documentation/rfkill.txt
View file @
c3da63f3
...
...
@@ -111,6 +111,8 @@ following attributes:
name: Name assigned by driver to this key (interface or driver name).
type: Driver type string ("wlan", "bluetooth", etc).
persistent: Whether the soft blocked state is initialised from
non-volatile storage at startup.
state: Current state of the transmitter
0: RFKILL_STATE_SOFT_BLOCKED
transmitter is turned off by software
...
...
MAINTAINERS
View file @
c3da63f3
...
...
@@ -940,7 +940,7 @@ M: me@bobcopeland.com
L: linux-wireless@vger.kernel.org
L: ath5k-devel@lists.ath5k.org
S: Maintained
F: drivers/net/wireless/ath5k/
F: drivers/net/wireless/ath
/ath
5k/
ATHEROS ATH9K WIRELESS DRIVER
P: Luis R. Rodriguez
...
...
@@ -956,7 +956,7 @@ M: senthilkumar@atheros.com
L: linux-wireless@vger.kernel.org
L: ath9k-devel@lists.ath9k.org
S: Supported
F: drivers/net/wireless/ath9k/
F: drivers/net/wireless/ath
/ath
9k/
ATHEROS AR9170 WIRELESS DRIVER
P: Christian Lamparter
...
...
@@ -964,7 +964,7 @@ M: chunkeey@web.de
L: linux-wireless@vger.kernel.org
W: http://wireless.kernel.org/en/users/Drivers/ar9170
S: Maintained
F: drivers/net/wireless/ar9170/
F: drivers/net/wireless/a
th/a
r9170/
ATI_REMOTE2 DRIVER
P: Ville Syrjala
...
...
drivers/net/wireless/ath/ath5k/base.c
View file @
c3da63f3
...
...
@@ -538,6 +538,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
sc
->
iobase
=
mem
;
/* So we can unmap it on detach */
sc
->
cachelsz
=
csz
*
sizeof
(
u32
);
/* convert to bytes */
sc
->
opmode
=
NL80211_IFTYPE_STATION
;
sc
->
bintval
=
1000
;
mutex_init
(
&
sc
->
lock
);
spin_lock_init
(
&
sc
->
rxbuflock
);
spin_lock_init
(
&
sc
->
txbuflock
);
...
...
@@ -686,6 +687,13 @@ ath5k_pci_resume(struct pci_dev *pdev)
if
(
err
)
return
err
;
/*
* Suspend/Resume resets the PCI configuration space, so we have to
* re-disable the RETRY_TIMEOUT register (0x41) to keep
* PCI Tx retries from interfering with C3 CPU state
*/
pci_write_config_byte
(
pdev
,
0x41
,
0
);
err
=
request_irq
(
pdev
->
irq
,
ath5k_intr
,
IRQF_SHARED
,
"ath"
,
sc
);
if
(
err
)
{
ATH5K_ERR
(
sc
,
"request_irq failed
\n
"
);
...
...
@@ -2748,9 +2756,6 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
goto
end
;
}
/* Set to a reasonable value. Note that this will
* be set to mac80211's value at ath5k_config(). */
sc
->
bintval
=
1000
;
ath5k_hw_set_lladdr
(
sc
->
ah
,
conf
->
mac_addr
);
ret
=
0
;
...
...
drivers/net/wireless/ath/ath9k/main.c
View file @
c3da63f3
...
...
@@ -1196,8 +1196,8 @@ void ath_radio_disable(struct ath_softc *sc)
ath9k_hw_phy_disable
(
ah
);
ath9k_hw_configpcipowersave
(
ah
,
1
);
ath9k_hw_setpower
(
ah
,
ATH9K_PM_FULL_SLEEP
);
ath9k_ps_restore
(
sc
);
ath9k_hw_setpower
(
ah
,
ATH9K_PM_FULL_SLEEP
);
}
/*******************/
...
...
drivers/net/wireless/ath/ath9k/pci.c
View file @
c3da63f3
...
...
@@ -87,6 +87,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
;
u32
val
;
int
ret
=
0
;
struct
ath_hw
*
ah
;
...
...
@@ -133,6 +134,14 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
pci_set_master
(
pdev
);
/*
* Disable the RETRY_TIMEOUT register (0x41) to keep
* PCI Tx retries from interfering with C3 CPU state.
*/
pci_read_config_dword
(
pdev
,
0x40
,
&
val
);
if
((
val
&
0x0000ff00
)
!=
0
)
pci_write_config_dword
(
pdev
,
0x40
,
val
&
0xffff00ff
);
ret
=
pci_request_region
(
pdev
,
0
,
"ath9k"
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"PCI memory region reserve error
\n
"
);
...
...
@@ -239,12 +248,21 @@ static int ath_pci_resume(struct pci_dev *pdev)
struct
ieee80211_hw
*
hw
=
pci_get_drvdata
(
pdev
);
struct
ath_wiphy
*
aphy
=
hw
->
priv
;
struct
ath_softc
*
sc
=
aphy
->
sc
;
u32
val
;
int
err
;
err
=
pci_enable_device
(
pdev
);
if
(
err
)
return
err
;
pci_restore_state
(
pdev
);
/*
* Suspend/Resume resets the PCI configuration space, so we have to
* re-disable the RETRY_TIMEOUT register (0x41) to keep
* PCI Tx retries from interfering with C3 CPU state
*/
pci_read_config_dword
(
pdev
,
0x40
,
&
val
);
if
((
val
&
0x0000ff00
)
!=
0
)
pci_write_config_dword
(
pdev
,
0x40
,
val
&
0xffff00ff
);
/* Enable LED */
ath9k_hw_cfg_output
(
sc
->
sc_ah
,
ATH_LED_PIN
,
...
...
drivers/net/wireless/ath/ath9k/recv.c
View file @
c3da63f3
...
...
@@ -539,11 +539,14 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
if
(
ath_beacon_dtim_pending_cab
(
skb
))
{
/*
* Remain awake waiting for buffered broadcast/multicast
* frames.
* frames. If the last broadcast/multicast frame is not
* received properly, the next beacon frame will work as
* a backup trigger for returning into NETWORK SLEEP state,
* so we are waiting for it as well.
*/
DPRINTF
(
sc
,
ATH_DBG_PS
,
"Received DTIM beacon indicating "
"buffered broadcast/multicast frame(s)
\n
"
);
sc
->
sc_flags
|=
SC_OP_WAIT_FOR_CAB
;
sc
->
sc_flags
|=
SC_OP_WAIT_FOR_CAB
|
SC_OP_WAIT_FOR_BEACON
;
return
;
}
...
...
drivers/net/wireless/iwmc3200wifi/iwm.h
View file @
c3da63f3
...
...
@@ -288,6 +288,7 @@ struct iwm_priv {
u8
*
eeprom
;
struct
timer_list
watchdog
;
struct
work_struct
reset_worker
;
struct
mutex
mutex
;
struct
rfkill
*
rfkill
;
char
private
[
0
]
__attribute__
((
__aligned__
(
NETDEV_ALIGN
)));
...
...
@@ -315,8 +316,11 @@ extern const struct iw_handler_def iwm_iw_handler_def;
void
*
iwm_if_alloc
(
int
sizeof_bus
,
struct
device
*
dev
,
struct
iwm_if_ops
*
if_ops
);
void
iwm_if_free
(
struct
iwm_priv
*
iwm
);
int
iwm_if_add
(
struct
iwm_priv
*
iwm
);
void
iwm_if_remove
(
struct
iwm_priv
*
iwm
);
int
iwm_mode_to_nl80211_iftype
(
int
mode
);
int
iwm_priv_init
(
struct
iwm_priv
*
iwm
);
void
iwm_priv_deinit
(
struct
iwm_priv
*
iwm
);
void
iwm_reset
(
struct
iwm_priv
*
iwm
);
void
iwm_tx_credit_init_pools
(
struct
iwm_priv
*
iwm
,
struct
iwm_umac_notif_alive
*
alive
);
...
...
drivers/net/wireless/iwmc3200wifi/main.c
View file @
c3da63f3
...
...
@@ -112,6 +112,9 @@ static void iwm_statistics_request(struct work_struct *work)
iwm_send_umac_stats_req
(
iwm
,
0
);
}
int
__iwm_up
(
struct
iwm_priv
*
iwm
);
int
__iwm_down
(
struct
iwm_priv
*
iwm
);
static
void
iwm_reset_worker
(
struct
work_struct
*
work
)
{
struct
iwm_priv
*
iwm
;
...
...
@@ -120,6 +123,19 @@ static void iwm_reset_worker(struct work_struct *work)
iwm
=
container_of
(
work
,
struct
iwm_priv
,
reset_worker
);
/*
* XXX: The iwm->mutex is introduced purely for this reset work,
* because the other users for iwm_up and iwm_down are only netdev
* ndo_open and ndo_stop which are already protected by rtnl.
* Please remove iwm->mutex together if iwm_reset_worker() is not
* required in the future.
*/
if
(
!
mutex_trylock
(
&
iwm
->
mutex
))
{
IWM_WARN
(
iwm
,
"We are in the middle of interface bringing "
"UP/DOWN. Skip driver resetting.
\n
"
);
return
;
}
if
(
iwm
->
umac_profile_active
)
{
profile
=
kmalloc
(
sizeof
(
struct
iwm_umac_profile
),
GFP_KERNEL
);
if
(
profile
)
...
...
@@ -128,10 +144,10 @@ static void iwm_reset_worker(struct work_struct *work)
IWM_ERR
(
iwm
,
"Couldn't alloc memory for profile
\n
"
);
}
iwm_down
(
iwm
);
__
iwm_down
(
iwm
);
while
(
retry
++
<
3
)
{
ret
=
iwm_up
(
iwm
);
ret
=
__
iwm_up
(
iwm
);
if
(
!
ret
)
break
;
...
...
@@ -142,7 +158,7 @@ static void iwm_reset_worker(struct work_struct *work)
IWM_WARN
(
iwm
,
"iwm_up() failed: %d
\n
"
,
ret
);
kfree
(
profile
);
return
;
goto
out
;
}
if
(
profile
)
{
...
...
@@ -151,6 +167,9 @@ static void iwm_reset_worker(struct work_struct *work)
iwm_send_mlme_profile
(
iwm
);
kfree
(
profile
);
}
out:
mutex_unlock
(
&
iwm
->
mutex
);
}
static
void
iwm_watchdog
(
unsigned
long
data
)
...
...
@@ -215,10 +234,21 @@ int iwm_priv_init(struct iwm_priv *iwm)
init_timer
(
&
iwm
->
watchdog
);
iwm
->
watchdog
.
function
=
iwm_watchdog
;
iwm
->
watchdog
.
data
=
(
unsigned
long
)
iwm
;
mutex_init
(
&
iwm
->
mutex
);
return
0
;
}
void
iwm_priv_deinit
(
struct
iwm_priv
*
iwm
)
{
int
i
;
for
(
i
=
0
;
i
<
IWM_TX_QUEUES
;
i
++
)
destroy_workqueue
(
iwm
->
txq
[
i
].
wq
);
destroy_workqueue
(
iwm
->
rx_wq
);
}
/*
* We reset all the structures, and we reset the UMAC.
* After calling this routine, you're expected to reload
...
...
@@ -466,7 +496,7 @@ void iwm_link_off(struct iwm_priv *iwm)
iwm_rx_free
(
iwm
);
cancel_delayed_work
(
&
iwm
->
stats_request
);
cancel_delayed_work
_sync
(
&
iwm
->
stats_request
);
memset
(
wstats
,
0
,
sizeof
(
struct
iw_statistics
));
wstats
->
qual
.
updated
=
IW_QUAL_ALL_INVALID
;
...
...
@@ -511,7 +541,7 @@ static int iwm_channels_init(struct iwm_priv *iwm)
return
0
;
}
int
iwm_up
(
struct
iwm_priv
*
iwm
)
int
__
iwm_up
(
struct
iwm_priv
*
iwm
)
{
int
ret
;
struct
iwm_notif
*
notif_reboot
,
*
notif_ack
=
NULL
;
...
...
@@ -647,7 +677,18 @@ int iwm_up(struct iwm_priv *iwm)
return
-
EIO
;
}
int
iwm_down
(
struct
iwm_priv
*
iwm
)
int
iwm_up
(
struct
iwm_priv
*
iwm
)
{
int
ret
;
mutex_lock
(
&
iwm
->
mutex
);
ret
=
__iwm_up
(
iwm
);
mutex_unlock
(
&
iwm
->
mutex
);
return
ret
;
}
int
__iwm_down
(
struct
iwm_priv
*
iwm
)
{
int
ret
;
...
...
@@ -678,3 +719,14 @@ int iwm_down(struct iwm_priv *iwm)
return
0
;
}
int
iwm_down
(
struct
iwm_priv
*
iwm
)
{
int
ret
;
mutex_lock
(
&
iwm
->
mutex
);
ret
=
__iwm_down
(
iwm
);
mutex_unlock
(
&
iwm
->
mutex
);
return
ret
;
}
drivers/net/wireless/iwmc3200wifi/netdev.c
View file @
c3da63f3
...
...
@@ -114,32 +114,31 @@ void *iwm_if_alloc(int sizeof_bus, struct device *dev,
iwm
=
wdev_to_iwm
(
wdev
);
iwm
->
bus_ops
=
if_ops
;
iwm
->
wdev
=
wdev
;
iwm_priv_init
(
iwm
);
ret
=
iwm_priv_init
(
iwm
);
if
(
ret
)
{
dev_err
(
dev
,
"failed to init iwm_priv
\n
"
);
goto
out_wdev
;
}
wdev
->
iftype
=
iwm_mode_to_nl80211_iftype
(
iwm
->
conf
.
mode
);
ndev
=
alloc_netdev_mq
(
0
,
"wlan%d"
,
ether_setup
,
IWM_TX_QUEUES
);
ndev
=
alloc_netdev_mq
(
0
,
"wlan%d"
,
ether_setup
,
IWM_TX_QUEUES
);
if
(
!
ndev
)
{
dev_err
(
dev
,
"no memory for network device instance
\n
"
);
goto
out_
wde
v
;
goto
out_
pri
v
;
}
ndev
->
netdev_ops
=
&
iwm_netdev_ops
;
ndev
->
wireless_handlers
=
&
iwm_iw_handler_def
;
ndev
->
ieee80211_ptr
=
wdev
;
SET_NETDEV_DEV
(
ndev
,
wiphy_dev
(
wdev
->
wiphy
));
ret
=
register_netdev
(
ndev
);
if
(
ret
<
0
)
{
dev_err
(
dev
,
"Failed to register netdev: %d
\n
"
,
ret
);
goto
out_ndev
;
}
wdev
->
netdev
=
ndev
;
return
iwm
;
out_
nde
v:
free_netdev
(
ndev
);
out_
pri
v:
iwm_priv_deinit
(
iwm
);
out_wdev:
iwm_wdev_free
(
iwm
);
...
...
@@ -148,15 +147,29 @@ void *iwm_if_alloc(int sizeof_bus, struct device *dev,
void
iwm_if_free
(
struct
iwm_priv
*
iwm
)
{
int
i
;
if
(
!
iwm_to_ndev
(
iwm
))
return
;
unregister_netdev
(
iwm_to_ndev
(
iwm
));
free_netdev
(
iwm_to_ndev
(
iwm
));
iwm_wdev_free
(
iwm
);
destroy_workqueue
(
iwm
->
rx_wq
);
for
(
i
=
0
;
i
<
IWM_TX_QUEUES
;
i
++
)
destroy_workqueue
(
iwm
->
txq
[
i
].
wq
);
iwm_priv_deinit
(
iwm
);
}
int
iwm_if_add
(
struct
iwm_priv
*
iwm
)
{
struct
net_device
*
ndev
=
iwm_to_ndev
(
iwm
);
int
ret
;
ret
=
register_netdev
(
ndev
);
if
(
ret
<
0
)
{
dev_err
(
&
ndev
->
dev
,
"Failed to register netdev: %d
\n
"
,
ret
);
return
ret
;
}
return
0
;
}
void
iwm_if_remove
(
struct
iwm_priv
*
iwm
)
{
unregister_netdev
(
iwm_to_ndev
(
iwm
));
}
drivers/net/wireless/iwmc3200wifi/sdio.c
View file @
c3da63f3
...
...
@@ -454,10 +454,18 @@ static int iwm_sdio_probe(struct sdio_func *func,
INIT_WORK
(
&
hw
->
isr_worker
,
iwm_sdio_isr_worker
);
ret
=
iwm_if_add
(
iwm
);
if
(
ret
)
{
dev_err
(
dev
,
"add SDIO interface failed
\n
"
);
goto
destroy_wq
;
}
dev_info
(
dev
,
"IWM SDIO probe
\n
"
);
return
0
;
destroy_wq:
destroy_workqueue
(
hw
->
isr_wq
);
debugfs_exit:
iwm_debugfs_exit
(
iwm
);
if_free:
...
...
@@ -471,9 +479,10 @@ static void iwm_sdio_remove(struct sdio_func *func)
struct
iwm_priv
*
iwm
=
hw_to_iwm
(
hw
);
struct
device
*
dev
=
&
func
->
dev
;
iwm_if_remove
(
iwm
);
destroy_workqueue
(
hw
->
isr_wq
);
iwm_debugfs_exit
(
iwm
);
iwm_if_free
(
iwm
);
destroy_workqueue
(
hw
->
isr_wq
);
sdio_set_drvdata
(
func
,
NULL
);
...
...
drivers/net/wireless/zd1211rw/zd_usb.c
View file @
c3da63f3
...
...
@@ -67,6 +67,7 @@ static struct usb_device_id usb_ids[] = {
{
USB_DEVICE
(
0x079b
,
0x0062
),
.
driver_info
=
DEVICE_ZD1211B
},
{
USB_DEVICE
(
0x1582
,
0x6003
),
.
driver_info
=
DEVICE_ZD1211B
},
{
USB_DEVICE
(
0x050d
,
0x705c
),
.
driver_info
=
DEVICE_ZD1211B
},
{
USB_DEVICE
(
0x083a
,
0xe503
),
.
driver_info
=
DEVICE_ZD1211B
},
{
USB_DEVICE
(
0x083a
,
0xe506
),
.
driver_info
=
DEVICE_ZD1211B
},
{
USB_DEVICE
(
0x083a
,
0x4505
),
.
driver_info
=
DEVICE_ZD1211B
},
{
USB_DEVICE
(
0x0471
,
0x1236
),
.
driver_info
=
DEVICE_ZD1211B
},
...
...
drivers/platform/x86/acer-wmi.c
View file @
c3da63f3
...
...
@@ -958,12 +958,12 @@ static void acer_rfkill_update(struct work_struct *ignored)
status
=
get_u32
(
&
state
,
ACER_CAP_WIRELESS
);
if
(
ACPI_SUCCESS
(
status
))
rfkill_set_sw_state
(
wireless_rfkill
,
!
!
state
);
rfkill_set_sw_state
(
wireless_rfkill
,
!
state
);
if
(
has_cap
(
ACER_CAP_BLUETOOTH
))
{
status
=
get_u32
(
&
state
,
ACER_CAP_BLUETOOTH
);
if
(
ACPI_SUCCESS
(
status
))
rfkill_set_sw_state
(
bluetooth_rfkill
,
!
!
state
);
rfkill_set_sw_state
(
bluetooth_rfkill
,
!
state
);
}
schedule_delayed_work
(
&
acer_rfkill_work
,
round_jiffies_relative
(
HZ
));
...
...
drivers/platform/x86/eeepc-laptop.c
View file @
c3da63f3
...
...
@@ -180,6 +180,7 @@ static struct key_entry eeepc_keymap[] = {
*/
static
int
eeepc_hotk_add
(
struct
acpi_device
*
device
);
static
int
eeepc_hotk_remove
(
struct
acpi_device
*
device
,
int
type
);
static
int
eeepc_hotk_resume
(
struct
acpi_device
*
device
);
static
const
struct
acpi_device_id
eeepc_device_ids
[]
=
{
{
EEEPC_HOTK_HID
,
0
},
...
...
@@ -194,6 +195,7 @@ static struct acpi_driver eeepc_hotk_driver = {
.
ops
=
{
.
add
=
eeepc_hotk_add
,
.
remove
=
eeepc_hotk_remove
,
.
resume
=
eeepc_hotk_resume
,
},
};
...
...
@@ -512,15 +514,12 @@ static int notify_brn(void)
return
-
1
;
}
static
void
eeepc_rfkill_
notify
(
acpi_handle
handle
,
u32
event
,
void
*
data
)
static
void
eeepc_rfkill_
hotplug
(
void
)
{
struct
pci_dev
*
dev
;
struct
pci_bus
*
bus
=
pci_find_bus
(
0
,
1
);
bool
blocked
;
if
(
event
!=
ACPI_NOTIFY_BUS_CHECK
)
return
;
if
(
!
bus
)
{
printk
(
EEEPC_WARNING
"Unable to find PCI bus 1?
\n
"
);
return
;
...
...
@@ -551,6 +550,14 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
rfkill_set_sw_state
(
ehotk
->
eeepc_wlan_rfkill
,
blocked
);
}
static
void
eeepc_rfkill_notify
(
acpi_handle
handle
,
u32
event
,
void
*
data
)
{
if
(
event
!=
ACPI_NOTIFY_BUS_CHECK
)
return
;
eeepc_rfkill_hotplug
();
}
static
void
eeepc_hotk_notify
(
acpi_handle
handle
,
u32
event
,
void
*
data
)
{
static
struct
key_entry
*
key
;
...
...
@@ -675,8 +682,8 @@ static int eeepc_hotk_add(struct acpi_device *device)
if
(
!
ehotk
->
eeepc_wlan_rfkill
)
goto
wlan_fail
;
rfkill_
se
t_sw_state
(
ehotk
->
eeepc_wlan_rfkill
,
get_acpi
(
CM_ASL_WLAN
)
!=
1
);
rfkill_
ini
t_sw_state
(
ehotk
->
eeepc_wlan_rfkill
,
get_acpi
(
CM_ASL_WLAN
)
!=
1
);
result
=
rfkill_register
(
ehotk
->
eeepc_wlan_rfkill
);
if
(
result
)
goto
wlan_fail
;
...
...
@@ -693,8 +700,8 @@ static int eeepc_hotk_add(struct acpi_device *device)
if
(
!
ehotk
->
eeepc_bluetooth_rfkill
)
goto
bluetooth_fail
;
rfkill_
se
t_sw_state
(
ehotk
->
eeepc_bluetooth_rfkill
,
get_acpi
(
CM_ASL_BLUETOOTH
)
!=
1
);
rfkill_
ini
t_sw_state
(
ehotk
->
eeepc_bluetooth_rfkill
,
get_acpi
(
CM_ASL_BLUETOOTH
)
!=
1
);
result
=
rfkill_register
(
ehotk
->
eeepc_bluetooth_rfkill
);
if
(
result
)
goto
bluetooth_fail
;
...
...
@@ -734,6 +741,33 @@ static int eeepc_hotk_remove(struct acpi_device *device, int type)
return
0
;
}
static
int
eeepc_hotk_resume
(
struct
acpi_device
*
device
)
{
if
(
ehotk
->
eeepc_wlan_rfkill
)
{
bool
wlan
;
/* Workaround - it seems that _PTS disables the wireless
without notification or changing the value read by WLAN.
Normally this is fine because the correct value is restored
from the non-volatile storage on resume, but we need to do
it ourself if case suspend is aborted, or we lose wireless.
*/
wlan
=
get_acpi
(
CM_ASL_WLAN
);
set_acpi
(
CM_ASL_WLAN
,
wlan
);
rfkill_set_sw_state
(
ehotk
->
eeepc_wlan_rfkill
,
wlan
!=
1
);
eeepc_rfkill_hotplug
();
}
if
(
ehotk
->
eeepc_bluetooth_rfkill
)
rfkill_set_sw_state
(
ehotk
->
eeepc_bluetooth_rfkill
,
get_acpi
(
CM_ASL_BLUETOOTH
)
!=
1
);
return
0
;
}
/*
* Hwmon
*/
...
...
drivers/platform/x86/thinkpad_acpi.c
View file @
c3da63f3
...
...
@@ -1163,8 +1163,8 @@ static int __init tpacpi_new_rfkill(const enum tpacpi_rfk_id id,
{
struct
tpacpi_rfk
*
atp_rfk
;
int
res
;
bool
initial_
sw_state
=
false
;
int
initial_
sw_status
;
bool
sw_state
=
false
;
int
sw_status
;
BUG_ON
(
id
>=
TPACPI_RFK_SW_MAX
||
tpacpi_rfkill_switches
[
id
]);
...
...
@@ -1185,17 +1185,17 @@ static int __init tpacpi_new_rfkill(const enum tpacpi_rfk_id id,
atp_rfk
->
id
=
id
;
atp_rfk
->
ops
=
tp_rfkops
;
initial_
sw_status
=
(
tp_rfkops
->
get_status
)();
if
(
initial_
sw_status
<
0
)
{
sw_status
=
(
tp_rfkops
->
get_status
)();
if
(
sw_status
<
0
)
{
printk
(
TPACPI_ERR
"failed to read initial state for %s, error %d
\n
"
,
name
,
initial_
sw_status
);
name
,
sw_status
);
}
else
{
initial_sw_state
=
(
initial_
sw_status
==
TPACPI_RFK_RADIO_OFF
);
sw_state
=
(
sw_status
==
TPACPI_RFK_RADIO_OFF
);
if
(
set_default
)
{
/* try to keep the initial state, since we ask the
* firmware to preserve it across S5 in NVRAM */
rfkill_
set_sw_state
(
atp_rfk
->
rfkill
,
initial_
sw_state
);
rfkill_
init_sw_state
(
atp_rfk
->
rfkill
,
sw_state
);
}
}
rfkill_set_hw_state
(
atp_rfk
->
rfkill
,
tpacpi_rfk_check_hwblock_state
());
...
...
include/linux/rfkill.h
View file @
c3da63f3
...
...
@@ -160,8 +160,9 @@ struct rfkill * __must_check rfkill_alloc(const char *name,
* the rfkill structure. Before calling this function the driver needs
* to be ready to service method calls from rfkill.
*
* If the software blocked state is not set before registration,
* set_block will be called to initialize it to a default value.
* If rfkill_init_sw_state() is not called before registration,
* set_block() will be called to initialize the software blocked state
* to a default value.
*
* If the hardware blocked state is not set before registration,
* it is assumed to be unblocked.
...
...
@@ -234,9 +235,11 @@ bool __must_check rfkill_set_hw_state(struct rfkill *rfkill, bool blocked);
* rfkill drivers that get events when the soft-blocked state changes
* (yes, some platforms directly act on input but allow changing again)
* use this function to notify the rfkill core (and through that also
* userspace) of the current state. It is not necessary to notify on
* resume; since hibernation can always change the soft-blocked state,
* the rfkill core will unconditionally restore the previous state.
* userspace) of the current state.
*
* Drivers should also call this function after resume if the state has
* been changed by the user. This only makes sense for "persistent"
* devices (see rfkill_init_sw_state()).
*
* This function can be called in any context, even from within rfkill
* callbacks.
...
...
@@ -246,6 +249,22 @@ bool __must_check rfkill_set_hw_state(struct rfkill *rfkill, bool blocked);
*/
bool
rfkill_set_sw_state
(
struct
rfkill
*
rfkill
,
bool
blocked
);
/**
* rfkill_init_sw_state - Initialize persistent software block state
* @rfkill: pointer to the rfkill class to modify.
* @state: the current software block state to set
*
* rfkill drivers that preserve their software block state over power off
* use this function to notify the rfkill core (and through that also
* userspace) of their initial state. It should only be used before
* registration.
*
* In addition, it marks the device as "persistent", an attribute which
* can be read by userspace. Persistent devices are expected to preserve
* their own state when suspended.
*/
void
rfkill_init_sw_state
(
struct
rfkill
*
rfkill
,
bool
blocked
);
/**
* rfkill_set_states - Set the internal rfkill block states
* @rfkill: pointer to the rfkill class to modify.
...
...
@@ -307,6 +326,10 @@ static inline bool rfkill_set_sw_state(struct rfkill *rfkill, bool blocked)
return
blocked
;
}
static
inline
void
rfkill_init_sw_state
(
struct
rfkill
*
rfkill
,
bool
blocked
)
{
}
static
inline
void
rfkill_set_states
(
struct
rfkill
*
rfkill
,
bool
sw
,
bool
hw
)
{
}
...
...
net/rfkill/core.c
View file @
c3da63f3
...
...
@@ -56,7 +56,6 @@ struct rfkill {
u32
idx
;
bool
registered
;
bool
suspended
;
bool
persistent
;
const
struct
rfkill_ops
*
ops
;
...
...
@@ -224,7 +223,7 @@ static void rfkill_send_events(struct rfkill *rfkill, enum rfkill_operation op)
static
void
rfkill_event
(
struct
rfkill
*
rfkill
)
{
if
(
!
rfkill
->
registered
||
rfkill
->
suspended
)
if
(
!
rfkill
->
registered
)
return
;
kobject_uevent
(
&
rfkill
->
dev
.
kobj
,
KOBJ_CHANGE
);
...
...
@@ -270,6 +269,9 @@ static void rfkill_set_block(struct rfkill *rfkill, bool blocked)
unsigned
long
flags
;
int
err
;
if
(
unlikely
(
rfkill
->
dev
.
power
.
power_state
.
event
&
PM_EVENT_SLEEP
))
return
;
/*
* Some platforms (...!) generate input events which affect the
* _hard_ kill state -- whenever something tries to change the
...
...
@@ -292,9 +294,6 @@ static void rfkill_set_block(struct rfkill *rfkill, bool blocked)
rfkill
->
state
|=
RFKILL_BLOCK_SW_SETCALL
;
spin_unlock_irqrestore
(
&
rfkill
->
lock
,
flags
);
if
(
unlikely
(
rfkill
->
dev
.
power
.
power_state
.
event
&
PM_EVENT_SLEEP
))
return
;
err
=
rfkill
->
ops
->
set_block
(
rfkill
->
data
,
blocked
);
spin_lock_irqsave
(
&
rfkill
->
lock
,
flags
);
...
...
@@ -508,19 +507,32 @@ bool rfkill_set_sw_state(struct rfkill *rfkill, bool blocked)
blocked
=
blocked
||
hwblock
;
spin_unlock_irqrestore
(
&
rfkill
->
lock
,
flags
);
if
(
!
rfkill
->
registered
)
{
rfkill
->
persistent
=
true
;
}
else
{
if
(
prev
!=
blocked
&&
!
hwblock
)
schedule_work
(
&
rfkill
->
uevent_work
);
if
(
!
rfkill
->
registered
)
return
blocked
;
rfkill_led_trigger_event
(
rfkill
);
}
if
(
prev
!=
blocked
&&
!
hwblock
)
schedule_work
(
&
rfkill
->
uevent_work
);
rfkill_led_trigger_event
(
rfkill
);
return
blocked
;
}
EXPORT_SYMBOL
(
rfkill_set_sw_state
);
void
rfkill_init_sw_state
(
struct
rfkill
*
rfkill
,
bool
blocked
)
{
unsigned
long
flags
;
BUG_ON
(
!
rfkill
);
BUG_ON
(
rfkill
->
registered
);
spin_lock_irqsave
(
&
rfkill
->
lock
,
flags
);
__rfkill_set_sw_state
(
rfkill
,
blocked
);
rfkill
->
persistent
=
true
;
spin_unlock_irqrestore
(
&
rfkill
->
lock
,
flags
);
}
EXPORT_SYMBOL
(
rfkill_init_sw_state
);
void
rfkill_set_states
(
struct
rfkill
*
rfkill
,
bool
sw
,
bool
hw
)
{
unsigned
long
flags
;
...
...
@@ -598,6 +610,15 @@ static ssize_t rfkill_idx_show(struct device *dev,
return
sprintf
(
buf
,
"%d
\n
"
,
rfkill
->
idx
);
}
static
ssize_t
rfkill_persistent_show
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
struct
rfkill
*
rfkill
=
to_rfkill
(
dev
);
return
sprintf
(
buf
,
"%d
\n
"
,
rfkill
->
persistent
);
}
static
u8
user_state_from_blocked
(
unsigned
long
state
)
{
if
(
state
&
RFKILL_BLOCK_HW
)
...
...
@@ -656,6 +677,7 @@ static struct device_attribute rfkill_dev_attrs[] = {
__ATTR
(
name
,
S_IRUGO
,
rfkill_name_show
,
NULL
),
__ATTR
(
type
,
S_IRUGO
,
rfkill_type_show
,
NULL
),
__ATTR
(
index
,
S_IRUGO
,
rfkill_idx_show
,
NULL
),
__ATTR
(
persistent
,
S_IRUGO
,
rfkill_persistent_show
,
NULL
),
__ATTR
(
state
,
S_IRUGO
|
S_IWUSR
,
rfkill_state_show
,
rfkill_state_store
),
__ATTR
(
claim
,
S_IRUGO
|
S_IWUSR
,
rfkill_claim_show
,
rfkill_claim_store
),
__ATTR_NULL
...
...
@@ -718,8 +740,6 @@ static int rfkill_suspend(struct device *dev, pm_message_t state)
rfkill_pause_polling
(
rfkill
);
rfkill
->
suspended
=
true
;
return
0
;
}
...
...
@@ -728,10 +748,10 @@ static int rfkill_resume(struct device *dev)
struct
rfkill
*
rfkill
=
to_rfkill
(
dev
);
bool
cur
;
cur
=
!!
(
rfkill
->
state
&
RFKILL_BLOCK_SW
);
rfkill_set_block
(
rfkill
,
cur
);
rfkill
->
suspended
=
false
;
if
(
!
rfkill
->
persistent
)
{
cur
=
!!
(
rfkill
->
state
&
RFKILL_BLOCK_SW
);
rfkill_set_block
(
rfkill
,
cur
);
}
rfkill_resume_polling
(
rfkill
);
...
...
net/wireless/nl80211.c
View file @
c3da63f3
...
...
@@ -1687,13 +1687,52 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
if
(
err
)
goto
out_rtnl
;
if
(
dev
->
ieee80211_ptr
->
iftype
!=
NL80211_IFTYPE_AP
&&
dev
->
ieee80211_ptr
->
iftype
!=
NL80211_IFTYPE_AP_VLAN
)
{
err
=
-
EINVAL
;
err
=
get_vlan
(
info
->
attrs
[
NL80211_ATTR_STA_VLAN
],
drv
,
&
params
.
vlan
);
if
(
err
)
goto
out
;
/* validate settings */
err
=
0
;
switch
(
dev
->
ieee80211_ptr
->
iftype
)
{
case
NL80211_IFTYPE_AP
:
case
NL80211_IFTYPE_AP_VLAN
:
/* disallow mesh-specific things */
if
(
params
.
plink_action
)
err
=
-
EINVAL
;
break
;
case
NL80211_IFTYPE_STATION
:
/* disallow everything but AUTHORIZED flag */
if
(
params
.
plink_action
)
err
=
-
EINVAL
;
if
(
params
.
vlan
)
err
=
-
EINVAL
;
if
(
params
.
supported_rates
)
err
=
-
EINVAL
;
if
(
params
.
ht_capa
)
err
=
-
EINVAL
;
if
(
params
.
listen_interval
>=
0
)
err
=
-
EINVAL
;
if
(
params
.
sta_flags_mask
&
~
BIT
(
NL80211_STA_FLAG_AUTHORIZED
))
err
=
-
EINVAL
;
break
;
case
NL80211_IFTYPE_MESH_POINT
:
/* disallow things mesh doesn't support */
if
(
params
.
vlan
)
err
=
-
EINVAL
;
if
(
params
.
ht_capa
)
err
=
-
EINVAL
;
if
(
params
.
listen_interval
>=
0
)
err
=
-
EINVAL
;
if
(
params
.
supported_rates
)
err
=
-
EINVAL
;
if
(
params
.
sta_flags_mask
)
err
=
-
EINVAL
;
break
;
default:
err
=
-
EINVAL
;
}
err
=
get_vlan
(
info
->
attrs
[
NL80211_ATTR_STA_VLAN
],
drv
,
&
params
.
vlan
);
if
(
err
)
goto
out
;
...
...
@@ -1728,9 +1767,6 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
if
(
!
info
->
attrs
[
NL80211_ATTR_MAC
])
return
-
EINVAL
;
if
(
!
info
->
attrs
[
NL80211_ATTR_STA_AID
])
return
-
EINVAL
;
if
(
!
info
->
attrs
[
NL80211_ATTR_STA_LISTEN_INTERVAL
])
return
-
EINVAL
;
...
...
@@ -1745,9 +1781,11 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
params
.
listen_interval
=
nla_get_u16
(
info
->
attrs
[
NL80211_ATTR_STA_LISTEN_INTERVAL
]);
params
.
aid
=
nla_get_u16
(
info
->
attrs
[
NL80211_ATTR_STA_AID
]);
if
(
!
params
.
aid
||
params
.
aid
>
IEEE80211_MAX_AID
)
return
-
EINVAL
;
if
(
info
->
attrs
[
NL80211_ATTR_STA_AID
])
{
params
.
aid
=
nla_get_u16
(
info
->
attrs
[
NL80211_ATTR_STA_AID
]);
if
(
!
params
.
aid
||
params
.
aid
>
IEEE80211_MAX_AID
)
return
-
EINVAL
;
}
if
(
info
->
attrs
[
NL80211_ATTR_HT_CAPABILITY
])
params
.
ht_capa
=
...
...
@@ -1762,13 +1800,39 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
if
(
err
)
goto
out_rtnl
;
if
(
dev
->
ieee80211_ptr
->
iftype
!=
NL80211_IFTYPE_AP
&&
dev
->
ieee80211_ptr
->
iftype
!=
NL80211_IFTYPE_AP_VLAN
)
{
err
=
-
EINVAL
;
err
=
get_vlan
(
info
->
attrs
[
NL80211_ATTR_STA_VLAN
],
drv
,
&
params
.
vlan
);
if
(
err
)
goto
out
;
/* validate settings */
err
=
0
;
switch
(
dev
->
ieee80211_ptr
->
iftype
)
{
case
NL80211_IFTYPE_AP
:
case
NL80211_IFTYPE_AP_VLAN
:
/* all ok but must have AID */
if
(
!
params
.
aid
)
err
=
-
EINVAL
;
break
;
case
NL80211_IFTYPE_MESH_POINT
:
/* disallow things mesh doesn't support */
if
(
params
.
vlan
)
err
=
-
EINVAL
;
if
(
params
.
aid
)
err
=
-
EINVAL
;
if
(
params
.
ht_capa
)
err
=
-
EINVAL
;
if
(
params
.
listen_interval
>=
0
)
err
=
-
EINVAL
;
if
(
params
.
supported_rates
)
err
=
-
EINVAL
;
if
(
params
.
sta_flags_mask
)
err
=
-
EINVAL
;
break
;
default:
err
=
-
EINVAL
;
}
err
=
get_vlan
(
info
->
attrs
[
NL80211_ATTR_STA_VLAN
],
drv
,
&
params
.
vlan
);
if
(
err
)
goto
out
;
...
...
@@ -1812,7 +1876,8 @@ static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
goto
out_rtnl
;
if
(
dev
->
ieee80211_ptr
->
iftype
!=
NL80211_IFTYPE_AP
&&
dev
->
ieee80211_ptr
->
iftype
!=
NL80211_IFTYPE_AP_VLAN
)
{
dev
->
ieee80211_ptr
->
iftype
!=
NL80211_IFTYPE_AP_VLAN
&&
dev
->
ieee80211_ptr
->
iftype
!=
NL80211_IFTYPE_MESH_POINT
)
{
err
=
-
EINVAL
;
goto
out
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment