Skip to contentSkip to conversation

ath5k: Add rfkill_disable module parameter

PATCH In review Nick Kossifidis 4 participants 6 messages Sep 19, 2011 – Sep 28, 2011 Atheros ATH5K wireless driver

lore
Share & tools
lore

Nick Kossifidis

author maintainer
#0 lore raw

PATCH 1/1 ath5k: Add rfkill_disable module parameter

Add a module parameter to disable hw rf kill (GPIO interrupt) because in some cases when the card doesn't come with the laptop, EEPROM configuration doesn't match laptop's configuration and rf kill interrupt always fires up and disables hw. I thought of moving this to debugfs and make it per-card but this way it's easier for users and distros to handle.

drivers/net/wireless/ath/ath5k/base.c +8 -2
index e9ea38d..000a65d 100644
@@ -80,6 +80,10 @@ static int modparam_fastchanswitch;
 module_param_named(fastchanswitch, modparam_fastchanswitch, bool, S_IRUGO);
 MODULE_PARM_DESC(fastchanswitch, "Enable fast channel switching for AR2413/AR5413 radios.");
 
+static int ath5k_modparam_rfkill_disable;
+module_param_named(rfkill_disable, ath5k_modparam_rfkill_disable, bool, S_IRUGO);
+MODULE_PARM_DESC(rfkill_disable, "Disable hw rfkill support (GPIO interrupt).");
+
 
 /* Module info */
 MODULE_AUTHOR("Jiri Slaby");
@@ -2558,7 +2562,8 @@ int ath5k_start(struct ieee80211_hw *hw)
 	if (ret)
 		goto done;
 
-	ath5k_rfkill_hw_start(ah);
+	if (!ath5k_modparam_rfkill_disable)
+		ath5k_rfkill_hw_start(ah);
 
 	/*
 	 * Reset the key cache since some parts do not reset the
@@ -2643,7 +2648,8 @@ void ath5k_stop(struct ieee80211_hw *hw)
 
 	cancel_delayed_work_sync(&ah->tx_complete_work);
 
-	ath5k_rfkill_hw_stop(ah);
+	if (!ath5k_modparam_rfkill_disable)
+		ath5k_rfkill_hw_stop(ah);
 }
 
 /*
#1 lore raw

Hi Nick,

Quoted 2 lines · Nick Kossifidis

Add a module parameter to disable hw rf kill (GPIO interrupt) because in some cases when the card doesn't come with the laptop, EEPROM configuration doesn't match laptop's configuration and rf kill interrupt always fires up and disables hw. I thought of moving this to debugfs and make it per-card

i think this seems to happen with a card that comes with laptop. AR5212802.11abg NIC (rev 01) in the lenovo T61

i just cannot bring up the card again once i toggle the rfkill switch (unblock -> block -> unblock)
the card is still hard blocked.

quickly, i just commented out those function calls(same as your patch)
in compat-wireless
ath5k_rfkill_hw_start(ah);
ath5k_rfkill_stop(ah);
as expected the problem disappears, but i can unblock the card via soft-rfkill even when it is hard blocked.
is it ok to unblock via software unblock when the card is hard-blocked?. please share your thoughts. meanwhile i will start comparing ath5k and ath9k for this. thanks!

Quoted 45 lines

but this way it's easier for users and distros to handle.

drivers/net/wireless/ath/ath5k/base.c +8 -3
index e9ea38d..000a65d 100644
@@ -80,6 +80,10 @@ static int modparam_fastchanswitch;
  module_param_named(fastchanswitch, modparam_fastchanswitch, bool, S_IRUGO);
  MODULE_PARM_DESC(fastchanswitch, "Enable fast channel switching for AR2413/AR5413 radios.");
 
+static int ath5k_modparam_rfkill_disable;
+module_param_named(rfkill_disable, ath5k_modparam_rfkill_disable, bool, S_IRUGO);
+MODULE_PARM_DESC(rfkill_disable, "Disable hw rfkill support (GPIO interrupt).");
+
 
  /* Module info */
  MODULE_AUTHOR("Jiri Slaby");
@@ -2558,7 +2562,8 @@ int ath5k_start(struct ieee80211_hw *hw)
        if (ret)
                goto done;
 
-       ath5k_rfkill_hw_start(ah);
+       if (!ath5k_modparam_rfkill_disable)
+               ath5k_rfkill_hw_start(ah);
 
        /*
         * Reset the key cache since some parts do not reset the
@@ -2643,7 +2648,8 @@ void ath5k_stop(struct ieee80211_hw *hw)
 
        cancel_delayed_work_sync(&ah->tx_complete_work);
 
-       ath5k_rfkill_hw_stop(ah);
+       if (!ath5k_modparam_rfkill_disable)
+               ath5k_rfkill_hw_stop(ah);
  }
 
  /*
 
--

To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Signature · 1 line
shafi
author maintainer
#2 lore raw

2011/9/20 Mohammed Shafi <[email protected]>:

Quoted 13 lines

Hi Nick,

Quoted 2 lines · Nick Kossifidis

Add a module parameter to disable hw rf kill (GPIO interrupt) because in some cases when the card doesn't come with the laptop, EEPROM configuration doesn't match laptop's configuration and rf kill interrupt always fires up and disables hw. I thought of moving this to debugfs and make it per-card

i think this seems to happen with a card that comes with laptop. AR5212802.11abg NIC (rev 01) in the lenovo T61

i just cannot bring up the card again once i toggle the rfkill switch (unblock -> block -> unblock)
the card is still hard blocked.

Quoted 10 lines

quickly, i just commented out those function calls(same as your patch) in compat-wireless
ath5k_rfkill_hw_start(ah);
ath5k_rfkill_stop(ah);
as expected the problem disappears, but i can unblock the card via soft-rfkill even when it is hard blocked.
is it ok to unblock via software unblock when the card is hard-blocked?. please share your thoughts. meanwhile i will start comparing ath5k and ath9k for this. thanks!

Soft-blocked -> The rfkill subsystem indicates the card is blocked by the system so cfg80211 doesn't allow you to bring it up and notifies the driver to do any additional steps to reduce power consumption (eg. unload firmware or sending some firmware commands etc).

Hard-blocked -> The hardware/driver indicates that hw is on a power-save state on it's own -probably due to an rfkill switch connected directly to the card- and can't be used until this state changes, so the rf-kill subsystem marks it as "hard blocked" and cfg80211 brings it down and doesn't allow you to bring it up. In some cards this can also be related to internal firmware operations so the driver can't directly switch state -can't bypass the firmware block- (I haven't seen such card but that's the theory).

In our case there is no such thing, when the rfkill switch changes state, the card just generates an interrupt and lets driver do the rest which means bringing the interface down (almost the same as power-off) and marking the interface as "hard blocked" on the rf-kill subsystem (through cfg80211), so "hard blocked" and "soft blocked" are the same in our case -> bring the interface down.

What this patch disables is the interrupt generation because some laptops don't implement this correctly, they have the switch plugged on a different pin than the one indicated on the EEPROM or they don't use that approach at all and are based on BIOS/acpi or other switches (we 've even seen a switch that turns off the whole pci-e bus :P) + some cards that don't come with the laptop don't match laptop's configuration (different pin/polarity or again no hw switch at all).

MadWiFi had a module parameter that did the same and I think even windows driver has a parameter for this, it makes sense to have a way to disable rfkill interrupt generation.

Signature · 3 lines
GPG ID: 0xD21DB2DB
As you read this post global entropy rises. Have Fun ;-)
Nick
#3 lore raw

I haven't read the ath5k code, but I do know the HAL code has stuff to glue the GPIO pin in question to the baseband so it becomes a "hard" kill.

Also, as I said privately, I think interrupt may be broken on some NICs. Have you guys thought about doing polling to see if the GPIO pin is actually measurably going up/down, and just not sendng an interrupt?

(Going by conjecture/reading here; I've not tinkered with rfkill yet.)

Adrian

#4 lore raw
In reply to Nick Kossifidis
Quoted 39 lines · Nick Kossifidis

2011/9/20 Mohammed Shafi <[email protected]>:

Quoted 13 lines

Hi Nick,

Quoted 2 lines · Nick Kossifidis

Add a module parameter to disable hw rf kill (GPIO interrupt) because in some cases when the card doesn't come with the laptop, EEPROM configuration doesn't match laptop's configuration and rf kill interrupt always fires up and disables hw. I thought of moving this to debugfs and make it per-card

i think this seems to happen with a card that comes with laptop. AR5212802.11abg NIC (rev 01) in the lenovo T61

i just cannot bring up the card again once i toggle the rfkill switch (unblock -> block -> unblock)
the card is still hard blocked.

Quoted 10 lines

quickly, i just commented out those function calls(same as your patch) in compat-wireless
ath5k_rfkill_hw_start(ah);
ath5k_rfkill_stop(ah);
as expected the problem disappears, but i can unblock the card via soft-rfkill even when it is hard blocked.
is it ok to unblock via software unblock when the card is hard-blocked?. please share your thoughts. meanwhile i will start comparing ath5k and ath9k for this. thanks!

Soft-blocked -> The rfkill subsystem indicates the card is blocked by the system so cfg80211 doesn't allow you to bring it up and notifies the driver to do any additional steps to reduce power consumption (eg. unload firmware or sending some firmware commands etc).

Hard-blocked -> The hardware/driver indicates that hw is on a power-save state on it's own -probably due to an rfkill switch connected directly to the card- and can't be used until this state changes, so the rf-kill subsystem marks it as "hard blocked" and cfg80211 brings it down and doesn't allow you to bring it up. In some cards this can also be related to internal firmware operations so the driver can't directly switch state -can't bypass the firmware block- (I haven't seen such card but that's the theory).

Quoted 6 lines

In our case there is no such thing, when the rfkill switch changes state, the card just generates an interrupt and lets driver do the rest which means bringing the interface down (almost the same as power-off) and marking the interface as "hard blocked" on the rf-kill subsystem (through cfg80211), so "hard blocked" and "soft blocked" are the same in our case -> bring the interface down.

Nick, thanks a lot for taking time and explaining about rfkill, it implementation completely.
just now tested with an on-board ath9k laptop and it seems to work fine. the drv_rfkill_poll(which is polled for every 5s from cfg80211) callback returns the proper value when the hardware rfkill is toggled. looks like the gpio pins are properly matched with the system.

Quoted 19 lines

What this patch disables is the interrupt generation because some laptops don't implement this correctly, they have the switch plugged on a different pin than the one indicated on the EEPROM or they don't use that approach at all and are based on BIOS/acpi or other switches (we 've even seen a switch that turns off the whole pci-e bus :P) + some cards that don't come with the laptop don't match laptop's configuration (different pin/polarity or again no hw switch at all).

MadWiFi had a module parameter that did the same and I think even windows driver has a parameter for this, it makes sense to have a way to disable rfkill interrupt generation.

--
GPG ID: 0xD21DB2DB
As you read this post global entropy rises. Have Fun ;-) Nick

Signature · 1 line
shafi
Tested-by on v1 1/1
#5 lore raw
In reply to Nick Kossifidis
Quoted 8 lines · On Mon, 19 Sep 2011 19:01:24 +0300 Nick Kossifidis <[email protected]> wrote:

Add a module parameter to disable hw rf kill (GPIO interrupt) because in some cases when the card doesn't come with the laptop, EEPROM configuration doesn't match laptop's configuration and rf kill interrupt always fires up and disables hw. I thought of moving this to debugfs and make it per-card but this way it's easier for users and distros to handle.

Tested on 2 cards in Mikrotik RB-14 adapter. One was OK without the patch. The other was shown as hard-blocked by rfkill and didn't work. With the rfkill_disable=1, both cards work. Soft rfkill is still working properly.

Please consider a parameter name that indicates that only hard rfkill is affected, for instance "no_hw_rfkill".

Signature · 2 lines
Regards,
Pavel Roskin