From: Christian Lamparter <chunkeey@web.de>
To: linux-wireless@vger.kernel.org
Cc: "Luis R. Rodriguez" <lrodriguez@atheros.com>
Subject: [RFC] ath9k's regulatory domain code changes (for ar9170)
Date: Tue, 24 Mar 2009 19:38:46 +0100 [thread overview]
Message-ID: <200903241938.47155.chunkeey@web.de> (raw)
Hi Luis,
This is more or less what I need from ath9k's regulatory domain code.
What's your opinion? Would you accept the changes, or do you see
a potential conflict/problem with the design?
Regards,
Chr
---
diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c
index 9818945..334a20f 100644
--- a/drivers/net/wireless/ath9k/hw.c
+++ b/drivers/net/wireless/ath9k/hw.c
@@ -1366,7 +1366,7 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
ath9k_olc_init(ah);
status = ah->eep_ops->set_txpower(ah, chan,
- ath9k_regd_get_ctl(ah, chan),
+ ath9k_regd_get_ctl(&ah->regulatory, chan),
channel->max_antenna_gain * 2,
channel->max_power * 2,
min((u32) MAX_RATE_POWER,
@@ -1706,7 +1706,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
}
if (ah->eep_ops->set_txpower(ah, chan,
- ath9k_regd_get_ctl(ah, chan),
+ ath9k_regd_get_ctl(&ah->regulatory, chan),
channel->max_antenna_gain * 2,
channel->max_power * 2,
min((u32) MAX_RATE_POWER,
@@ -3768,7 +3768,7 @@ bool ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit)
ah->regulatory.power_limit = min(limit, (u32) MAX_RATE_POWER);
if (ah->eep_ops->set_txpower(ah, chan,
- ath9k_regd_get_ctl(ah, chan),
+ ath9k_regd_get_ctl(&ah->regulatory, chan),
channel->max_antenna_gain * 2,
channel->max_power * 2,
min((u32) MAX_RATE_POWER,
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c
index c13e4e5..8db019f 100644
--- a/drivers/net/wireless/ath9k/main.c
+++ b/drivers/net/wireless/ath9k/main.c
@@ -1362,6 +1362,16 @@ void ath_detach(struct ath_softc *sc)
ath9k_ps_restore(sc);
}
+struct ath9k_regulatory *ath9k_reg_get_from_wiphy(struct wiphy *wiphy)
+{
+ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
+ struct ath_hw *ah = sc->sc_ah;
+
+ return &ah->regulatory;
+}
+
static int ath_init(u16 devid, struct ath_softc *sc)
{
struct ath_hw *ah = NULL;
@@ -1416,7 +1426,8 @@ static int ath_init(u16 devid, struct ath_softc *sc)
for (i = 0; i < sc->keymax; i++)
ath9k_hw_keyreset(ah, (u16) i);
- if (ath9k_regd_init(sc->sc_ah))
+ sc->sc_ah->regulatory.debug = sc;
+ if (ath9k_regd_init(&sc->sc_ah->regulatory))
goto bad;
/* default to MONITOR mode */
@@ -1666,10 +1677,10 @@ int ath_attach(u16 devid, struct ath_softc *sc)
goto error_attach;
#endif
- if (ath9k_is_world_regd(sc->sc_ah)) {
+ if (ath9k_is_world_regd(&sc->sc_ah->regulatory)) {
/* Anything applied here (prior to wiphy registration) gets
* saved on the wiphy orig_* parameters */
- regd = ath9k_world_regdomain(sc->sc_ah);
+ regd = ath9k_world_regdomain(&sc->sc_ah->regulatory);
hw->wiphy->custom_regulatory = true;
hw->wiphy->strict_regulatory = false;
} else {
@@ -1688,7 +1699,7 @@ int ath_attach(u16 devid, struct ath_softc *sc)
error = ieee80211_register_hw(hw);
- if (!ath9k_is_world_regd(sc->sc_ah)) {
+ if (!ath9k_is_world_regd(&sc->sc_ah->regulatory)) {
error = regulatory_hint(hw->wiphy,
sc->sc_ah->regulatory.alpha2);
if (error)
diff --git a/drivers/net/wireless/ath9k/regd.c b/drivers/net/wireless/ath9k/regd.c
index 4ca6251..017a05f 100644
--- a/drivers/net/wireless/ath9k/regd.c
+++ b/drivers/net/wireless/ath9k/regd.c
@@ -112,14 +112,14 @@ static inline bool is_wwr_sku(u16 regd)
(regd == WORLD);
}
-static u16 ath9k_regd_get_eepromRD(struct ath_hw *ah)
+static u16 ath9k_regd_get_eepromRD(struct ath9k_regulatory *reg)
{
- return ah->regulatory.current_rd & ~WORLDWIDE_ROAMING_FLAG;
+ return reg->current_rd & ~WORLDWIDE_ROAMING_FLAG;
}
-bool ath9k_is_world_regd(struct ath_hw *ah)
+bool ath9k_is_world_regd(struct ath9k_regulatory *reg)
{
- return is_wwr_sku(ath9k_regd_get_eepromRD(ah));
+ return is_wwr_sku(ath9k_regd_get_eepromRD(reg));
}
const struct ieee80211_regdomain *ath9k_default_world_regdomain(void)
@@ -128,9 +128,9 @@ const struct ieee80211_regdomain *ath9k_default_world_regdomain(void)
return &ath9k_world_regdom_64;
}
-const struct ieee80211_regdomain *ath9k_world_regdomain(struct ath_hw *ah)
+const struct ieee80211_regdomain *ath9k_world_regdomain(struct ath9k_regulatory *reg)
{
- switch (ah->regulatory.regpair->regDmnEnum) {
+ switch (reg->regpair->regDmnEnum) {
case 0x60:
case 0x61:
case 0x62:
@@ -313,12 +313,9 @@ void ath9k_reg_apply_radar_flags(struct wiphy *wiphy)
void ath9k_reg_apply_world_flags(struct wiphy *wiphy,
enum nl80211_reg_initiator initiator)
{
- struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
- struct ath_wiphy *aphy = hw->priv;
- struct ath_softc *sc = aphy->sc;
- struct ath_hw *ah = sc->sc_ah;
+ struct ath9k_regulatory *reg = ath9k_reg_get_from_wiphy(wiphy);
- switch (ah->regulatory.regpair->regDmnEnum) {
+ switch (reg->regpair->regDmnEnum) {
case 0x60:
case 0x63:
case 0x66:
@@ -335,9 +332,7 @@ void ath9k_reg_apply_world_flags(struct wiphy *wiphy,
int ath9k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
{
- struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
- struct ath_wiphy *aphy = hw->priv;
- struct ath_softc *sc = aphy->sc;
+ struct ath9k_regulatory *reg = ath9k_reg_get_from_wiphy(wiphy);
/* We always apply this */
ath9k_reg_apply_radar_flags(wiphy);
@@ -348,7 +343,7 @@ int ath9k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
case NL80211_REGDOM_SET_BY_USER:
break;
case NL80211_REGDOM_SET_BY_COUNTRY_IE:
- if (ath9k_is_world_regd(sc->sc_ah))
+ if (ath9k_is_world_regd(reg))
ath9k_reg_apply_world_flags(wiphy, request->initiator);
break;
}
@@ -356,9 +351,9 @@ int ath9k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
return 0;
}
-bool ath9k_regd_is_eeprom_valid(struct ath_hw *ah)
+bool ath9k_regd_is_eeprom_valid(struct ath9k_regulatory *reg)
{
- u16 rd = ath9k_regd_get_eepromRD(ah);
+ u16 rd = ath9k_regd_get_eepromRD(reg);
int i;
if (rd & COUNTRY_ERD_FLAG) {
@@ -373,8 +368,8 @@ bool ath9k_regd_is_eeprom_valid(struct ath_hw *ah)
if (regDomainPairs[i].regDmnEnum == rd)
return true;
}
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "invalid regulatory domain/country code 0x%x\n", rd);
+ DPRINTF(reg->debug, ATH_DBG_REGULATORY,
+ "invalid regulatory domain/country code 0x%x\n", rd);
return false;
}
@@ -433,42 +428,42 @@ ath9k_get_regpair(int regdmn)
return NULL;
}
-int ath9k_regd_init(struct ath_hw *ah)
+int ath9k_regd_init(struct ath9k_regulatory *reg)
{
struct country_code_to_enum_rd *country = NULL;
u16 regdmn;
- if (!ath9k_regd_is_eeprom_valid(ah)) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
+ if (!ath9k_regd_is_eeprom_valid(reg)) {
+ DPRINTF(reg->debug, ATH_DBG_FATAL,
"Invalid EEPROM contents\n");
return -EINVAL;
}
- regdmn = ath9k_regd_get_eepromRD(ah);
- ah->regulatory.country_code = ath9k_regd_get_default_country(regdmn);
+ regdmn = ath9k_regd_get_eepromRD(reg);
+ reg->country_code = ath9k_regd_get_default_country(regdmn);
- if (ah->regulatory.country_code == CTRY_DEFAULT &&
+ if (reg->country_code == CTRY_DEFAULT &&
regdmn == CTRY_DEFAULT)
- ah->regulatory.country_code = CTRY_UNITED_STATES;
+ reg->country_code = CTRY_UNITED_STATES;
- if (ah->regulatory.country_code == CTRY_DEFAULT) {
+ if (reg->country_code == CTRY_DEFAULT) {
country = NULL;
} else {
- country = ath9k_regd_find_country(ah->regulatory.country_code);
+ country = ath9k_regd_find_country(reg->country_code);
if (country == NULL) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
+ DPRINTF(reg->debug, ATH_DBG_FATAL,
"Country is NULL!!!!, cc= %d\n",
- ah->regulatory.country_code);
+ reg->country_code);
return -EINVAL;
} else
regdmn = country->regDmnEnum;
}
- ah->regulatory.regpair = ath9k_get_regpair(regdmn);
+ reg->regpair = ath9k_get_regpair(regdmn);
- if (!ah->regulatory.regpair) {
- DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
- "No regulatory domain pair found, cannot continue\n");
+ if (!reg->regpair) {
+ DPRINTF(reg->debug, ATH_DBG_FATAL, "No regulatory domain "
+ "pair found, cannot continue\n");
return -EINVAL;
}
@@ -476,29 +471,29 @@ int ath9k_regd_init(struct ath_hw *ah)
country = ath9k_regd_find_country_by_rd(regdmn);
if (country) {
- ah->regulatory.alpha2[0] = country->isoName[0];
- ah->regulatory.alpha2[1] = country->isoName[1];
+ reg->alpha2[0] = country->isoName[0];
+ reg->alpha2[1] = country->isoName[1];
} else {
- ah->regulatory.alpha2[0] = '0';
- ah->regulatory.alpha2[1] = '0';
+ reg->alpha2[0] = '0';
+ reg->alpha2[1] = '0';
}
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
+ DPRINTF(reg->debug, ATH_DBG_REGULATORY,
"Country alpha2 being used: %c%c\n"
"Regulatory.Regpair detected: 0x%0x\n",
- ah->regulatory.alpha2[0], ah->regulatory.alpha2[1],
- ah->regulatory.regpair->regDmnEnum);
+ reg->alpha2[0], reg->alpha2[1],
+ reg->regpair->regDmnEnum);
return 0;
}
-u32 ath9k_regd_get_ctl(struct ath_hw *ah, struct ath9k_channel *chan)
+u32 ath9k_regd_get_ctl(struct ath9k_regulatory *reg,
+ struct ath9k_channel *chan)
{
u32 ctl = NO_CTL;
- if (!ah->regulatory.regpair ||
- (ah->regulatory.country_code == CTRY_DEFAULT &&
- is_wwr_sku(ath9k_regd_get_eepromRD(ah)))) {
+ if (!reg->regpair || (reg->country_code == CTRY_DEFAULT &&
+ is_wwr_sku(ath9k_regd_get_eepromRD(reg)))) {
if (IS_CHAN_B(chan))
ctl = SD_NO_CTL | CTL_11B;
else if (IS_CHAN_G(chan))
@@ -509,11 +504,11 @@ u32 ath9k_regd_get_ctl(struct ath_hw *ah, struct ath9k_channel *chan)
}
if (IS_CHAN_B(chan))
- ctl = ah->regulatory.regpair->reg_2ghz_ctl | CTL_11B;
+ ctl = reg->regpair->reg_2ghz_ctl | CTL_11B;
else if (IS_CHAN_G(chan))
- ctl = ah->regulatory.regpair->reg_2ghz_ctl | CTL_11G;
+ ctl = reg->regpair->reg_2ghz_ctl | CTL_11G;
else
- ctl = ah->regulatory.regpair->reg_5ghz_ctl | CTL_11A;
+ ctl = reg->regpair->reg_5ghz_ctl | CTL_11A;
return ctl;
}
diff --git a/drivers/net/wireless/ath9k/regd.h b/drivers/net/wireless/ath9k/regd.h
index 9f5fbd4..dc23883 100644
--- a/drivers/net/wireless/ath9k/regd.h
+++ b/drivers/net/wireless/ath9k/regd.h
@@ -49,6 +49,7 @@ struct ath9k_regulatory {
u16 current_rd_ext;
int16_t power_limit;
struct reg_dmn_pair_mapping *regpair;
+ void *debug;
};
enum CountryCode {
@@ -233,15 +234,17 @@ enum CountryCode {
CTRY_BELGIUM2 = 5002
};
-bool ath9k_is_world_regd(struct ath_hw *ah);
-const struct ieee80211_regdomain *ath9k_world_regdomain(struct ath_hw *ah);
+struct ath9k_channel;
+
+bool ath9k_is_world_regd(struct ath9k_regulatory *reg);
+const struct ieee80211_regdomain *ath9k_world_regdomain(struct ath9k_regulatory *reg);
const struct ieee80211_regdomain *ath9k_default_world_regdomain(void);
void ath9k_reg_apply_world_flags(struct wiphy *wiphy,
enum nl80211_reg_initiator initiator);
void ath9k_reg_apply_radar_flags(struct wiphy *wiphy);
-int ath9k_regd_init(struct ath_hw *ah);
-bool ath9k_regd_is_eeprom_valid(struct ath_hw *ah);
-u32 ath9k_regd_get_ctl(struct ath_hw *ah, struct ath9k_channel *chan);
+int ath9k_regd_init(struct ath9k_regulatory *reg);
+bool ath9k_regd_is_eeprom_valid(struct ath9k_regulatory *reg);
+u32 ath9k_regd_get_ctl(struct ath9k_regulatory *reg, struct ath9k_channel *chan);
int ath9k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request);
-
+struct ath9k_regulatory *ath9k_reg_get_from_wiphy(struct wiphy *wiphy);
#endif
---
of course, here are the ar9170 changes:
---
diff --git a/drivers/net/wireless/ar9170/Makefile b/drivers/net/wireless/ar9170/Makefile
index 8d91c7e..66e89ce 100644
--- a/drivers/net/wireless/ar9170/Makefile
+++ b/drivers/net/wireless/ar9170/Makefile
@@ -1,3 +1,3 @@
-ar9170usb-objs := usb.o main.o cmd.o mac.o phy.o led.o
+ar9170usb-objs := usb.o ../ath9k/regd.o main.o cmd.o mac.o phy.o led.o
obj-$(CONFIG_AR9170_USB) += ar9170usb.o
diff --git a/drivers/net/wireless/ar9170/ar9170.h b/drivers/net/wireless/ar9170/ar9170.h
index f4fb2e9..49d4995 100644
--- a/drivers/net/wireless/ar9170/ar9170.h
+++ b/drivers/net/wireless/ar9170/ar9170.h
@@ -48,6 +48,9 @@
#include "eeprom.h"
#include "hw.h"
+/* ath9k definitions */
+#include "../ath9k/regd.h"
+
#define PAYLOAD_MAX (AR9170_MAX_CMD_LEN/4 - 1)
enum ar9170_bw {
@@ -156,6 +159,9 @@ struct ar9170 {
struct sk_buff_head global_tx_status;
struct sk_buff_head global_tx_status_waste;
struct delayed_work tx_status_janitor;
+
+ /* regulatory domain */
+ struct ath9k_regulatory regulatory;
};
struct ar9170_sta_info {
diff --git a/drivers/net/wireless/ar9170/main.c b/drivers/net/wireless/ar9170/main.c
index 5996ff9..c5a2012 100644
--- a/drivers/net/wireless/ar9170/main.c
+++ b/drivers/net/wireless/ar9170/main.c
@@ -149,6 +149,13 @@ static struct ieee80211_supported_band ar9170_band_2GHz = {
.n_bitrates = ar9170_g_ratetable_size,
};
+static struct ieee80211_supported_band ar9170_band_5GHz = {
+ .channels = ar9170_5ghz_chantable,
+ .n_channels = ARRAY_SIZE(ar9170_5ghz_chantable),
+ .bitrates = ar9170_a_ratetable,
+ .n_bitrates = ar9170_a_ratetable_size,
+};
+
#ifdef AR9170_QUEUE_DEBUG
/*
* In case some wants works with AR9170's crazy tx_status queueing techniques.
@@ -190,12 +197,30 @@ static void ar9170_dump_station_tx_status_queue(struct ar9170 *ar,
}
#endif /* AR9170_QUEUE_DEBUG */
-static struct ieee80211_supported_band ar9170_band_5GHz = {
- .channels = ar9170_5ghz_chantable,
- .n_channels = ARRAY_SIZE(ar9170_5ghz_chantable),
- .bitrates = ar9170_a_ratetable,
- .n_bitrates = ar9170_a_ratetable_size,
-};
+/* regulatory domain glue code */
+struct ath9k_regulatory *ath9k_reg_get_from_wiphy(struct wiphy *wiphy)
+{
+ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+ struct ar9170 *ar = hw->priv;
+
+ return &ar->regulatory;
+}
+
+void DPRINTF(struct ar9170 *ar, int dbg_mask, const char *fmt, ...)
+{
+ if (!ar)
+ return;
+
+ /* print fatal errors */
+ if (dbg_mask & 0x8000) {
+ va_list args;
+
+ va_start(args, fmt);
+ printk(KERN_ERR "%s: ", wiphy_name(ar->hw->wiphy));
+ vprintk(fmt, args);
+ va_end(args);
+ }
+}
void ar9170_handle_tx_status(struct ar9170 *ar, struct sk_buff *skb,
bool valid_status, u16 tx_status)
@@ -1557,6 +1582,11 @@ void *ar9170_alloc(size_t priv_size)
ar->hw->max_rates = 1;
ar->hw->max_rate_tries = 3;
+ ar->regulatory.debug = ar;
+ ar->regulatory.country_code = 0; /* CTRY_DEFAULT */
+ ar->regulatory.power_limit = 63; /* MAX_RATE_POWER */
+ ar->regulatory.tp_scale = 0; /* ATH9K_TP_SCALE_MAX */
+
for (i = 0; i < ARRAY_SIZE(ar->noise); i++)
ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */
@@ -1607,6 +1637,10 @@ static int ar9170_read_eeprom(struct ar9170 *ar)
ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &ar9170_band_5GHz;
bands++;
}
+
+ ar->regulatory.current_rd = le16_to_cpu(ar->eeprom.reg_domain[0]);
+ ar->regulatory.current_rd_ext = le16_to_cpu(ar->eeprom.reg_domain[1]);
+
/*
* I measured this, a bandswitch takes roughly
* 135 ms and a frequency switch about 80.
@@ -1627,6 +1661,7 @@ static int ar9170_read_eeprom(struct ar9170 *ar)
int ar9170_register(struct ar9170 *ar, struct device *pdev)
{
+ const struct ieee80211_regdomain *regd;
int err;
/* try to read EEPROM, init MAC addr */
@@ -1634,10 +1669,38 @@ int ar9170_register(struct ar9170 *ar, struct device *pdev)
if (err)
goto err_out;
+ err = ath9k_regd_init(&ar->regulatory);
+ if (err)
+ goto err_out;
+
+ if (ath9k_is_world_regd(&ar->regulatory)) {
+ /* Anything applied here (prior to wiphy registration) gets
+ * saved on the wiphy orig_* parameters */
+ regd = ath9k_world_regdomain(&ar->regulatory);
+ ar->hw->wiphy->custom_regulatory = true;
+ ar->hw->wiphy->strict_regulatory = false;
+ } else {
+ /* This gets applied in the case of the absense of CRDA,
+ * it's our own custom world regulatory domain, similar to
+ * cfg80211's but we enable passive scanning */
+ regd = ath9k_default_world_regdomain();
+ }
+ wiphy_apply_custom_regulatory(ar->hw->wiphy, regd);
+ ath9k_reg_apply_radar_flags(ar->hw->wiphy);
+ ath9k_reg_apply_world_flags(ar->hw->wiphy,
+ NL80211_REGDOM_SET_BY_DRIVER);
+
err = ieee80211_register_hw(ar->hw);
if (err)
goto err_out;
+ if (!ath9k_is_world_regd(&ar->regulatory)) {
+ err = regulatory_hint(ar->hw->wiphy,
+ ar->regulatory.alpha2);
+ if (err)
+ goto err_unreg;
+ }
+
err = ar9170_init_leds(ar);
if (err)
goto err_unreg;
---
next reply other threads:[~2009-03-24 18:38 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-03-24 18:38 Christian Lamparter [this message]
2009-03-24 18:59 ` [RFC] ath9k's regulatory domain code changes (for ar9170) Bob Copeland
2009-03-24 18:41 ` Luis R. Rodriguez
2009-03-24 20:03 ` Bob Copeland
2009-03-24 20:10 ` Luis R. Rodriguez
2009-03-24 20:31 ` Johannes Berg
2009-03-24 22:04 ` Luis R. Rodriguez
2009-03-28 16:39 ` Bob Copeland
2009-03-29 23:13 ` Nick Kossifidis
2009-03-29 23:15 ` Nick Kossifidis
2009-03-30 12:00 ` Bob Copeland
2009-03-24 20:33 ` Christian Lamparter
2009-03-24 20:58 ` Luis R. Rodriguez
2009-03-24 22:09 ` Bob Copeland
2009-03-24 21:14 ` Luis R. Rodriguez
2009-03-24 22:24 ` Christian Lamparter
2009-03-24 22:30 ` Bob Copeland
2009-03-24 23:13 ` Luis R. Rodriguez
2009-03-24 23:17 ` Luis R. Rodriguez
2009-03-24 23:52 ` Luis R. Rodriguez
2009-03-25 1:06 ` Bob Copeland
2009-03-25 2:30 ` Luis R. Rodriguez
2009-03-25 2:59 ` Luis R. Rodriguez
2009-03-25 3:15 ` Luis R. Rodriguez
2009-03-25 3:45 ` Luis R. Rodriguez
2009-03-29 19:39 ` Bob Copeland
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200903241938.47155.chunkeey@web.de \
--to=chunkeey@web.de \
--cc=linux-wireless@vger.kernel.org \
--cc=lrodriguez@atheros.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.