2009-10-16 05:19:57

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 01/16] iwmc3200wifi: add BGN sdio device id

Add BGN SKU sdio device id.

Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwmc3200wifi/sdio.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/iwmc3200wifi/sdio.c b/drivers/net/wireless/iwmc3200wifi/sdio.c
index 8b1de84..38026b7 100644
--- a/drivers/net/wireless/iwmc3200wifi/sdio.c
+++ b/drivers/net/wireless/iwmc3200wifi/sdio.c
@@ -493,8 +493,10 @@ static void iwm_sdio_remove(struct sdio_func *func)
}

static const struct sdio_device_id iwm_sdio_ids[] = {
- { SDIO_DEVICE(SDIO_VENDOR_ID_INTEL,
- SDIO_DEVICE_ID_INTEL_IWMC3200WIFI) },
+ /* Global/AGN SKU */
+ { SDIO_DEVICE(SDIO_VENDOR_ID_INTEL, 0x1403) },
+ /* BGN SKU */
+ { SDIO_DEVICE(SDIO_VENDOR_ID_INTEL, 0x1408) },
{ /* end: all zeroes */ },
};
MODULE_DEVICE_TABLE(sdio, iwm_sdio_ids);
--
1.6.0.4



2009-10-16 20:25:30

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [PATCH 03/16] iwmc3200wifi: WPS support

Hi John,

> > > From: Samuel Ortiz <[email protected]>
> > >
> > > By setting the WSC profile flag, we now support WPS as an enrollee.
> > >
> > > Signed-off-by: Samuel Ortiz <[email protected]>
> > > Signed-off-by: Zhu Yi <[email protected]>
> > > ---
> > > drivers/net/wireless/iwmc3200wifi/cfg80211.c | 7 +++++++
> > > drivers/net/wireless/iwmc3200wifi/commands.h | 3 +++
> > > 2 files changed, 10 insertions(+), 0 deletions(-)
> > >
> > > diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
> > > index 0d2e719..a6d2f20 100644
> > > --- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c
> > > +++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
> > > @@ -628,6 +628,13 @@ static int iwm_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
> > > iwm->default_key = sme->key_idx;
> > > }
> > >
> > > + /* WPA and open AUTH type from wpa_s means WPS (a.k.a. WSC) */
> > > + if ((iwm->umac_profile->sec.flags &
> > > + (UMAC_SEC_FLG_WPA_ON_MSK | UMAC_SEC_FLG_RSNA_ON_MSK)) &&
> > > + iwm->umac_profile->sec.auth_type == UMAC_AUTH_TYPE_OPEN) {
> > > + iwm->umac_profile->sec.flags = UMAC_SEC_FLG_WSC_ON_MSK;
> > > + }
> > > +
> >
> > I don't wanna be picky, but what coding style are you following here?
> > The indentation makes no sense and doesn't improve readability.
>
> Given the length and complication of the conditions, the indentation
> seems fine to me. How would you do it?

it is double indentation of iwm->umac_profile... and (UMAC... and
iwm->uwm_profile are not even on the same vertical. If I stare long
enough at it, I can see a certain reasoning for it, but it is an ugly
block. Some extra macros might make this more readable. However if you
are fine with it, then that is good enough. I just mentioned it, because
I read the if clause wrongly when reviewing the patches.

Regards

Marcel



2009-10-16 05:20:54

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 09/16] iwmc3200wifi: Tx power setting

From: Samuel Ortiz <[email protected]>

We can now set the Tx power from e.g. iwconfig.

Signed-off-by: Samuel Ortiz <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwmc3200wifi/cfg80211.c | 12 +++++++++++-
drivers/net/wireless/iwmc3200wifi/commands.c | 13 +++++++++++++
drivers/net/wireless/iwmc3200wifi/commands.h | 6 ++++++
3 files changed, 30 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
index ea0ed32..2e00a4b 100644
--- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c
+++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
@@ -671,9 +671,19 @@ static int iwm_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
static int iwm_cfg80211_set_txpower(struct wiphy *wiphy,
enum tx_power_setting type, int dbm)
{
+ struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
+ int ret;
+
switch (type) {
case TX_POWER_AUTOMATIC:
return 0;
+ case TX_POWER_FIXED:
+ ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
+ CFG_TX_PWR_LIMIT_USR, dbm * 2);
+ if (ret < 0)
+ return ret;
+
+ return iwm_tx_power_trigger(iwm);
default:
return -EOPNOTSUPP;
}
@@ -685,7 +695,7 @@ static int iwm_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
{
struct iwm_priv *iwm = wiphy_to_iwm(wiphy);

- *dbm = iwm->txpower;
+ *dbm = iwm->txpower >> 1;

return 0;
}
diff --git a/drivers/net/wireless/iwmc3200wifi/commands.c b/drivers/net/wireless/iwmc3200wifi/commands.c
index 1ba839c..0641bc7 100644
--- a/drivers/net/wireless/iwmc3200wifi/commands.c
+++ b/drivers/net/wireless/iwmc3200wifi/commands.c
@@ -794,6 +794,19 @@ int iwm_invalidate_mlme_profile(struct iwm_priv *iwm)
return ret ? 0 : -EBUSY;
}

+int iwm_tx_power_trigger(struct iwm_priv *iwm)
+{
+ struct iwm_umac_pwr_trigger pwr_trigger;
+
+ pwr_trigger.hdr.oid = UMAC_WIFI_IF_CMD_TX_PWR_TRIGGER;
+ pwr_trigger.hdr.buf_size =
+ cpu_to_le16(sizeof(struct iwm_umac_pwr_trigger) -
+ sizeof(struct iwm_umac_wifi_if));
+
+
+ return iwm_send_wifi_if_cmd(iwm, &pwr_trigger, sizeof(pwr_trigger), 1);
+}
+
int iwm_send_umac_stats_req(struct iwm_priv *iwm, u32 flags)
{
struct iwm_udma_wifi_cmd udma_cmd = UDMA_UMAC_INIT;
diff --git a/drivers/net/wireless/iwmc3200wifi/commands.h b/drivers/net/wireless/iwmc3200wifi/commands.h
index 511b6e3..b36be2b 100644
--- a/drivers/net/wireless/iwmc3200wifi/commands.h
+++ b/drivers/net/wireless/iwmc3200wifi/commands.h
@@ -441,6 +441,11 @@ struct iwm_umac_tx_key_id {
u8 reserved[3];
} __attribute__ ((packed));

+struct iwm_umac_pwr_trigger {
+ struct iwm_umac_wifi_if hdr;
+ __le32 reseved;
+} __attribute__ ((packed));
+
struct iwm_umac_cmd_stats_req {
__le32 flags;
} __attribute__ ((packed));
@@ -467,6 +472,7 @@ int iwm_invalidate_mlme_profile(struct iwm_priv *iwm);
int iwm_send_packet(struct iwm_priv *iwm, struct sk_buff *skb, int pool_id);
int iwm_set_tx_key(struct iwm_priv *iwm, u8 key_idx);
int iwm_set_key(struct iwm_priv *iwm, bool remove, struct iwm_key *key);
+int iwm_tx_power_trigger(struct iwm_priv *iwm);
int iwm_send_umac_stats_req(struct iwm_priv *iwm, u32 flags);
int iwm_send_umac_channel_list(struct iwm_priv *iwm);
int iwm_scan_ssids(struct iwm_priv *iwm, struct cfg80211_ssid *ssids,
--
1.6.0.4


2009-10-16 05:20:53

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 08/16] iwmc3200wifi: Update fixed size config definitions

From: Samuel Ortiz <[email protected]>

We need to be in sync with the latest firmware API.

Signed-off-by: Samuel Ortiz <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwmc3200wifi/commands.h | 60 +++++++++++++++++++++++++-
1 files changed, 58 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/iwmc3200wifi/commands.h b/drivers/net/wireless/iwmc3200wifi/commands.h
index e486f8e..511b6e3 100644
--- a/drivers/net/wireless/iwmc3200wifi/commands.h
+++ b/drivers/net/wireless/iwmc3200wifi/commands.h
@@ -102,7 +102,6 @@ enum {
CFG_SCAN_NUM_PASSIVE_CHAN_PER_PARTIAL_SCAN,
CFG_TLC_SUPPORTED_TX_HT_RATES,
CFG_TLC_SUPPORTED_TX_RATES,
- CFG_TLC_VALID_ANTENNA,
CFG_TLC_SPATIAL_STREAM_SUPPORTED,
CFG_TLC_RETRY_PER_RATE,
CFG_TLC_RETRY_PER_HT_RATE,
@@ -136,6 +135,10 @@ enum {
CFG_TLC_RENEW_ADDBA_DELAY,
CFG_TLC_NUM_OF_MULTISEC_TO_COUN_LOAD,
CFG_TLC_IS_STABLE_IN_HT,
+ CFG_TLC_SR_SIC_1ST_FAIL,
+ CFG_TLC_SR_SIC_1ST_PASS,
+ CFG_TLC_SR_SIC_TOTAL_FAIL,
+ CFG_TLC_SR_SIC_TOTAL_PASS,
CFG_RLC_CHAIN_CTRL,
CFG_TRK_TABLE_OP_MODE,
CFG_TRK_TABLE_RSSI_THRESHOLD,
@@ -147,6 +150,58 @@ enum {
CFG_MLME_DBG_NOTIF_BLOCK,
CFG_BT_OFF_BECONS_INTERVALS,
CFG_BT_FRAG_DURATION,
+ CFG_ACTIVE_CHAINS,
+ CFG_CALIB_CTRL,
+ CFG_CAPABILITY_SUPPORTED_HT_RATES,
+ CFG_HT_MAC_PARAM_INFO,
+ CFG_MIMO_PS_MODE,
+ CFG_HT_DEFAULT_CAPABILIES_INFO,
+ CFG_LED_SC_RESOLUTION_FACTOR,
+ CFG_PTAM_ENERGY_CCK_DET_DEFAULT,
+ CFG_PTAM_CORR40_4_TH_ADD_MIN_MRC_DEFAULT,
+ CFG_PTAM_CORR40_4_TH_ADD_MIN_DEFAULT,
+ CFG_PTAM_CORR32_4_TH_ADD_MIN_MRC_DEFAULT,
+ CFG_PTAM_CORR32_4_TH_ADD_MIN_DEFAULT,
+ CFG_PTAM_CORR32_1_TH_ADD_MIN_MRC_DEFAULT,
+ CFG_PTAM_CORR32_1_TH_ADD_MIN_DEFAULT,
+ CFG_PTAM_ENERGY_CCK_DET_MIN_VAL,
+ CFG_PTAM_CORR40_4_TH_ADD_MIN_MRC_MIN_VAL,
+ CFG_PTAM_CORR40_4_TH_ADD_MIN_MIN_VAL,
+ CFG_PTAM_CORR32_4_TH_ADD_MIN_MRC_MIN_VAL,
+ CFG_PTAM_CORR32_4_TH_ADD_MIN_MIN_VAL,
+ CFG_PTAM_CORR32_1_TH_ADD_MIN_MRC_MIN_VAL,
+ CFG_PTAM_CORR32_1_TH_ADD_MIN_MIN_VAL,
+ CFG_PTAM_ENERGY_CCK_DET_MAX_VAL,
+ CFG_PTAM_CORR40_4_TH_ADD_MIN_MRC_MAX_VAL,
+ CFG_PTAM_CORR40_4_TH_ADD_MIN_MAX_VAL,
+ CFG_PTAM_CORR32_4_TH_ADD_MIN_MRC_MAX_VAL,
+ CFG_PTAM_CORR32_4_TH_ADD_MIN_MAX_VAL,
+ CFG_PTAM_CORR32_1_TH_ADD_MIN_MRC_MAX_VAL,
+ CFG_PTAM_CORR32_1_TH_ADD_MIN_MAX_VAL,
+ CFG_PTAM_ENERGY_CCK_DET_STEP_VAL,
+ CFG_PTAM_CORR40_4_TH_ADD_MIN_MRC_STEP_VAL,
+ CFG_PTAM_CORR40_4_TH_ADD_MIN_STEP_VAL,
+ CFG_PTAM_CORR32_4_TH_ADD_MIN_MRC_STEP_VAL,
+ CFG_PTAM_CORR32_4_TH_ADD_MIN_STEP_VAL,
+ CFG_PTAM_CORR32_1_TH_ADD_MIN_MRC_STEP_VAL,
+ CFG_PTAM_CORR32_1_TH_ADD_MIN_STEP_VAL,
+ CFG_PTAM_LINK_SENS_FA_OFDM_MAX,
+ CFG_PTAM_LINK_SENS_FA_OFDM_MIN,
+ CFG_PTAM_LINK_SENS_FA_CCK_MAX,
+ CFG_PTAM_LINK_SENS_FA_CCK_MIN,
+ CFG_PTAM_LINK_SENS_NRG_DIFF,
+ CFG_PTAM_LINK_SENS_NRG_MARGIN,
+ CFG_PTAM_LINK_SENS_MAX_NUMBER_OF_TIMES_IN_CCK_NO_FA,
+ CFG_PTAM_LINK_SENS_AUTO_CORR_MAX_TH_CCK,
+ CFG_AGG_MGG_TID_LOAD_ADDBA_THRESHOLD,
+ CFG_AGG_MGG_TID_LOAD_DELBA_THRESHOLD,
+ CFG_AGG_MGG_ADDBA_BUF_SIZE,
+ CFG_AGG_MGG_ADDBA_INACTIVE_TIMEOUT,
+ CFG_AGG_MGG_ADDBA_DEBUG_FLAGS,
+ CFG_SCAN_PERIODIC_RSSI_HIGH_THRESHOLD,
+ CFG_SCAN_PERIODIC_COEF_RSSI_HIGH,
+ CFG_11D_ENABLED,
+ CFG_11H_FEATURE_FLAGS,

/* <-- LAST --> */
CFG_TBL_FIX_LAST
@@ -155,7 +210,8 @@ enum {
/* variable size table */
enum {
CFG_NET_ADDR = 0,
- CFG_PROFILE,
+ CFG_LED_PATTERN_TABLE,
+
/* <-- LAST --> */
CFG_TBL_VAR_LAST
};
--
1.6.0.4


2009-10-16 18:31:12

by John W. Linville

[permalink] [raw]
Subject: Re: [PATCH 03/16] iwmc3200wifi: WPS support

On Fri, Oct 16, 2009 at 06:18:07PM +0200, Marcel Holtmann wrote:
> Hi Yi,
>
> > From: Samuel Ortiz <[email protected]>
> >
> > By setting the WSC profile flag, we now support WPS as an enrollee.
> >
> > Signed-off-by: Samuel Ortiz <[email protected]>
> > Signed-off-by: Zhu Yi <[email protected]>
> > ---
> > drivers/net/wireless/iwmc3200wifi/cfg80211.c | 7 +++++++
> > drivers/net/wireless/iwmc3200wifi/commands.h | 3 +++
> > 2 files changed, 10 insertions(+), 0 deletions(-)
> >
> > diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
> > index 0d2e719..a6d2f20 100644
> > --- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c
> > +++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
> > @@ -628,6 +628,13 @@ static int iwm_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
> > iwm->default_key = sme->key_idx;
> > }
> >
> > + /* WPA and open AUTH type from wpa_s means WPS (a.k.a. WSC) */
> > + if ((iwm->umac_profile->sec.flags &
> > + (UMAC_SEC_FLG_WPA_ON_MSK | UMAC_SEC_FLG_RSNA_ON_MSK)) &&
> > + iwm->umac_profile->sec.auth_type == UMAC_AUTH_TYPE_OPEN) {
> > + iwm->umac_profile->sec.flags = UMAC_SEC_FLG_WSC_ON_MSK;
> > + }
> > +
>
> I don't wanna be picky, but what coding style are you following here?
> The indentation makes no sense and doesn't improve readability.

Given the length and complication of the conditions, the indentation
seems fine to me. How would you do it?

John
--
John W. Linville Someday the world will need a hero, and you
[email protected] might be all we have. Be ready.

2009-10-16 05:20:59

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 10/16] iwmc3200wifi: SDIO disable race fix

From: Samuel Ortiz <[email protected]>

When calling sdio->bus_disable(), we are flushing the command lists before
disabling the sdio function. We can thus potentially get a command response
after having flushed the command list.
To avoid that race, we have to call iwm_reset() after disabling the sdio
function.

Signed-off-by: Samuel Ortiz <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwmc3200wifi/sdio.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/iwmc3200wifi/sdio.c b/drivers/net/wireless/iwmc3200wifi/sdio.c
index 38026b7..cf86294 100644
--- a/drivers/net/wireless/iwmc3200wifi/sdio.c
+++ b/drivers/net/wireless/iwmc3200wifi/sdio.c
@@ -224,8 +224,6 @@ static int if_sdio_disable(struct iwm_priv *iwm)
struct iwm_sdio_priv *hw = iwm_to_if_sdio(iwm);
int ret;

- iwm_reset(iwm);
-
sdio_claim_host(hw->func);
sdio_writeb(hw->func, 0, IWM_SDIO_INTR_ENABLE_ADDR, &ret);
if (ret < 0)
@@ -237,6 +235,8 @@ static int if_sdio_disable(struct iwm_priv *iwm)

iwm_sdio_rx_free(hw);

+ iwm_reset(iwm);
+
IWM_DBG_SDIO(iwm, INFO, "IWM SDIO disable\n");

return 0;
--
1.6.0.4


2009-10-16 05:20:38

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 06/16] iwmc3200wifi: Improve rx debug

From: Samuel Ortiz <[email protected]>

We display the correct DROP/RELEASE string for each rx packets, and when
it's dropped we also display the reason.

Signed-off-by: Samuel Ortiz <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwmc3200wifi/rx.c | 7 +++++--
1 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c
index 813e1b3..a6b1811 100644
--- a/drivers/net/wireless/iwmc3200wifi/rx.c
+++ b/drivers/net/wireless/iwmc3200wifi/rx.c
@@ -423,7 +423,9 @@ static int iwm_ntf_rx_ticket(struct iwm_priv *iwm, u8 *buf,
if (IS_ERR(ticket_node))
return PTR_ERR(ticket_node);

- IWM_DBG_RX(iwm, DBG, "TICKET RELEASE(%d)\n",
+ IWM_DBG_RX(iwm, DBG, "TICKET %s(%d)\n",
+ ticket->action == IWM_RX_TICKET_RELEASE ?
+ "RELEASE" : "DROP",
ticket->id);
list_add_tail(&ticket_node->node, &iwm->rx_tickets);

@@ -1458,7 +1460,8 @@ static void iwm_rx_process_packet(struct iwm_priv *iwm,
}
break;
case IWM_RX_TICKET_DROP:
- IWM_DBG_RX(iwm, DBG, "DROP packet\n");
+ IWM_DBG_RX(iwm, DBG, "DROP packet: 0x%x\n",
+ le16_to_cpu(ticket_node->ticket->flags));
kfree_skb(packet->skb);
break;
default:
--
1.6.0.4


2009-10-16 05:21:09

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 12/16] iwmc3200wifi: Do not handle wifi command if the interface is not ready

From: Samuel Ortiz <[email protected]>

When resetting or bringing the interface down, we should just reject any wifi
related command.

Signed-off-by: Samuel Ortiz <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwmc3200wifi/commands.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/iwmc3200wifi/commands.c b/drivers/net/wireless/iwmc3200wifi/commands.c
index 0641bc7..2911ace 100644
--- a/drivers/net/wireless/iwmc3200wifi/commands.c
+++ b/drivers/net/wireless/iwmc3200wifi/commands.c
@@ -77,6 +77,11 @@ int iwm_send_wifi_if_cmd(struct iwm_priv *iwm, void *payload, u16 payload_size,
int ret;
u8 oid = hdr->oid;

+ if (!test_bit(IWM_STATUS_READY, &iwm->status)) {
+ IWM_ERR(iwm, "Interface is not ready yet");
+ return -EAGAIN;
+ }
+
umac_cmd.id = UMAC_CMD_OPCODE_WIFI_IF_WRAPPER;
umac_cmd.resp = resp;

--
1.6.0.4


2009-10-16 05:20:12

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 02/16] iwmc3200wifi: allow joining an existed IBSS network

We used to only support creating a new IBSS network. Now joining to
an existed IBSS network is supported as well.

Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwmc3200wifi/cfg80211.c | 22 ++--------------------
1 files changed, 2 insertions(+), 20 deletions(-)

diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
index f3c5565..0d2e719 100644
--- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c
+++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
@@ -405,39 +405,21 @@ static int iwm_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
{
struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
struct ieee80211_channel *chan = params->channel;
- struct cfg80211_bss *bss;

if (!test_bit(IWM_STATUS_READY, &iwm->status))
return -EIO;

- /* UMAC doesn't support creating IBSS network with specified bssid.
- * This should be removed after we have join only mode supported. */
+ /* UMAC doesn't support creating or joining an IBSS network
+ * with specified bssid. */
if (params->bssid)
return -EOPNOTSUPP;

- bss = cfg80211_get_ibss(iwm_to_wiphy(iwm), NULL,
- params->ssid, params->ssid_len);
- if (!bss) {
- iwm_scan_one_ssid(iwm, params->ssid, params->ssid_len);
- schedule_timeout_interruptible(2 * HZ);
- bss = cfg80211_get_ibss(iwm_to_wiphy(iwm), NULL,
- params->ssid, params->ssid_len);
- }
- /* IBSS join only mode is not supported by UMAC ATM */
- if (bss) {
- cfg80211_put_bss(bss);
- return -EOPNOTSUPP;
- }
-
iwm->channel = ieee80211_frequency_to_channel(chan->center_freq);
iwm->umac_profile->ibss.band = chan->band;
iwm->umac_profile->ibss.channel = iwm->channel;
iwm->umac_profile->ssid.ssid_len = params->ssid_len;
memcpy(iwm->umac_profile->ssid.ssid, params->ssid, params->ssid_len);

- if (params->bssid)
- memcpy(&iwm->umac_profile->bssid[0], params->bssid, ETH_ALEN);
-
return iwm_send_mlme_profile(iwm);
}

--
1.6.0.4


2009-10-16 05:21:09

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 11/16] iwmc3200wifi: Check for cmd pointer before dereferencing it

From: Samuel Ortiz <[email protected]>

The wifi_if_wrapper notification handling code uses a cmd pointer without
checking if it's valid or not. We're dereferencing it because we assume that
we only get to that point if there was a pending command for us. That's not
always true, so we'd better check.

Signed-off-by: Samuel Ortiz <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwmc3200wifi/rx.c | 10 ++++++++--
1 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c
index a6b1811..0fa3f5c 100644
--- a/drivers/net/wireless/iwmc3200wifi/rx.c
+++ b/drivers/net/wireless/iwmc3200wifi/rx.c
@@ -1058,8 +1058,14 @@ static int iwm_ntf_wifi_if_wrapper(struct iwm_priv *iwm, u8 *buf,
unsigned long buf_size,
struct iwm_wifi_cmd *cmd)
{
- struct iwm_umac_wifi_if *hdr =
- (struct iwm_umac_wifi_if *)cmd->buf.payload;
+ struct iwm_umac_wifi_if *hdr;
+
+ if (cmd == NULL) {
+ IWM_ERR(iwm, "Couldn't find expected wifi command\n");
+ return -EINVAL;
+ }
+
+ hdr = (struct iwm_umac_wifi_if *)cmd->buf.payload;

IWM_DBG_NTF(iwm, DBG, "WIFI_IF_WRAPPER cmd is delivered to UMAC: "
"oid is 0x%x\n", hdr->oid);
--
1.6.0.4


2009-10-16 05:20:28

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 03/16] iwmc3200wifi: WPS support

From: Samuel Ortiz <[email protected]>

By setting the WSC profile flag, we now support WPS as an enrollee.

Signed-off-by: Samuel Ortiz <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwmc3200wifi/cfg80211.c | 7 +++++++
drivers/net/wireless/iwmc3200wifi/commands.h | 3 +++
2 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
index 0d2e719..a6d2f20 100644
--- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c
+++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
@@ -628,6 +628,13 @@ static int iwm_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
iwm->default_key = sme->key_idx;
}

+ /* WPA and open AUTH type from wpa_s means WPS (a.k.a. WSC) */
+ if ((iwm->umac_profile->sec.flags &
+ (UMAC_SEC_FLG_WPA_ON_MSK | UMAC_SEC_FLG_RSNA_ON_MSK)) &&
+ iwm->umac_profile->sec.auth_type == UMAC_AUTH_TYPE_OPEN) {
+ iwm->umac_profile->sec.flags = UMAC_SEC_FLG_WSC_ON_MSK;
+ }
+
ret = iwm_send_mlme_profile(iwm);

if (iwm->umac_profile->sec.auth_type != UMAC_AUTH_TYPE_LEGACY_PSK ||
diff --git a/drivers/net/wireless/iwmc3200wifi/commands.h b/drivers/net/wireless/iwmc3200wifi/commands.h
index e24d5b6..4e183be 100644
--- a/drivers/net/wireless/iwmc3200wifi/commands.h
+++ b/drivers/net/wireless/iwmc3200wifi/commands.h
@@ -288,6 +288,9 @@ struct iwm_umac_cmd_scan_request {
/* iwm_umac_security.flag is WSC mode on -- bits [2:2] */
#define UMAC_SEC_FLG_WSC_ON_POS 2
#define UMAC_SEC_FLG_WSC_ON_SEED 1
+#define UMAC_SEC_FLG_WSC_ON_MSK (UMAC_SEC_FLG_WSC_ON_SEED << \
+ UMAC_SEC_FLG_WSC_ON_POS)
+

/* Legacy profile can use only WEP40 and WEP104 for encryption and
* OPEN or PSK for authentication */
--
1.6.0.4


2009-10-16 05:21:24

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 14/16] iwmc3200wifi: Support unexpected reboot barker

From: Samuel Ortiz <[email protected]>

We can receive unexpected reboot barker at any time, and we're supposed to
reset the whole device then.

Signed-off-by: Samuel Ortiz <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwmc3200wifi/rx.c | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c
index c0fa853..95deb0a 100644
--- a/drivers/net/wireless/iwmc3200wifi/rx.c
+++ b/drivers/net/wireless/iwmc3200wifi/rx.c
@@ -1322,6 +1322,14 @@ int iwm_rx_handle(struct iwm_priv *iwm, u8 *buf, unsigned long buf_size)

switch (le32_to_cpu(hdr->cmd)) {
case UMAC_REBOOT_BARKER:
+ if (test_bit(IWM_STATUS_READY, &iwm->status)) {
+ IWM_ERR(iwm, "Unexpected BARKER\n");
+
+ schedule_work(&iwm->reset_worker);
+
+ return 0;
+ }
+
return iwm_notif_send(iwm, NULL, IWM_BARKER_REBOOT_NOTIFICATION,
IWM_SRC_UDMA, buf, buf_size);
case UMAC_ACK_BARKER:
--
1.6.0.4


2009-10-16 16:18:22

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [PATCH 03/16] iwmc3200wifi: WPS support

Hi Yi,

> From: Samuel Ortiz <[email protected]>
>
> By setting the WSC profile flag, we now support WPS as an enrollee.
>
> Signed-off-by: Samuel Ortiz <[email protected]>
> Signed-off-by: Zhu Yi <[email protected]>
> ---
> drivers/net/wireless/iwmc3200wifi/cfg80211.c | 7 +++++++
> drivers/net/wireless/iwmc3200wifi/commands.h | 3 +++
> 2 files changed, 10 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
> index 0d2e719..a6d2f20 100644
> --- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c
> +++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
> @@ -628,6 +628,13 @@ static int iwm_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
> iwm->default_key = sme->key_idx;
> }
>
> + /* WPA and open AUTH type from wpa_s means WPS (a.k.a. WSC) */
> + if ((iwm->umac_profile->sec.flags &
> + (UMAC_SEC_FLG_WPA_ON_MSK | UMAC_SEC_FLG_RSNA_ON_MSK)) &&
> + iwm->umac_profile->sec.auth_type == UMAC_AUTH_TYPE_OPEN) {
> + iwm->umac_profile->sec.flags = UMAC_SEC_FLG_WSC_ON_MSK;
> + }
> +

I don't wanna be picky, but what coding style are you following here?
The indentation makes no sense and doesn't improve readability.

Regards

Marcel



2009-10-16 05:20:23

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 04/16] iwmc3200wifi: CT kill support

From: Samuel Ortiz <[email protected]>

We set the initial CT (Temperature control) value to 110 degrees.
If the chip goes over that threshold, we hard block the device which will turn
it down. At the same time we schedule a 30 seconds delayed work that unblock
the device (and userspace is supposed to bring it back up), hoping that the
chip will have cooled down by then...

Signed-off-by: Samuel Ortiz <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwmc3200wifi/commands.c | 11 +++++++++++
drivers/net/wireless/iwmc3200wifi/commands.h | 1 +
drivers/net/wireless/iwmc3200wifi/fw.c | 2 ++
drivers/net/wireless/iwmc3200wifi/iwm.h | 3 +++
drivers/net/wireless/iwmc3200wifi/lmac.h | 8 ++++++++
drivers/net/wireless/iwmc3200wifi/main.c | 14 ++++++++++++++
drivers/net/wireless/iwmc3200wifi/netdev.c | 1 +
drivers/net/wireless/iwmc3200wifi/rx.c | 16 +++++++++++++++-
8 files changed, 55 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/iwmc3200wifi/commands.c b/drivers/net/wireless/iwmc3200wifi/commands.c
index 84158b6..1ba839c 100644
--- a/drivers/net/wireless/iwmc3200wifi/commands.c
+++ b/drivers/net/wireless/iwmc3200wifi/commands.c
@@ -275,6 +275,17 @@ int iwm_send_calib_results(struct iwm_priv *iwm)
return ret;
}

+int iwm_send_ct_kill_cfg(struct iwm_priv *iwm, u8 entry, u8 exit)
+{
+ struct iwm_ct_kill_cfg_cmd cmd;
+
+ cmd.entry_threshold = entry;
+ cmd.exit_threshold = exit;
+
+ return iwm_send_lmac_ptrough_cmd(iwm, REPLY_CT_KILL_CONFIG_CMD, &cmd,
+ sizeof(struct iwm_ct_kill_cfg_cmd), 0);
+}
+
int iwm_send_umac_reset(struct iwm_priv *iwm, __le32 reset_flags, bool resp)
{
struct iwm_udma_wifi_cmd udma_cmd = UDMA_UMAC_INIT;
diff --git a/drivers/net/wireless/iwmc3200wifi/commands.h b/drivers/net/wireless/iwmc3200wifi/commands.h
index 4e183be..e486f8e 100644
--- a/drivers/net/wireless/iwmc3200wifi/commands.h
+++ b/drivers/net/wireless/iwmc3200wifi/commands.h
@@ -396,6 +396,7 @@ int iwm_send_init_calib_cfg(struct iwm_priv *iwm, u8 calib_requested);
int iwm_send_periodic_calib_cfg(struct iwm_priv *iwm, u8 calib_requested);
int iwm_send_calib_results(struct iwm_priv *iwm);
int iwm_store_rxiq_calib_result(struct iwm_priv *iwm);
+int iwm_send_ct_kill_cfg(struct iwm_priv *iwm, u8 entry, u8 exit);

/* UMAC commands */
int iwm_send_wifi_if_cmd(struct iwm_priv *iwm, void *payload, u16 payload_size,
diff --git a/drivers/net/wireless/iwmc3200wifi/fw.c b/drivers/net/wireless/iwmc3200wifi/fw.c
index 6b0bcad..f02d571 100644
--- a/drivers/net/wireless/iwmc3200wifi/fw.c
+++ b/drivers/net/wireless/iwmc3200wifi/fw.c
@@ -398,6 +398,8 @@ int iwm_load_fw(struct iwm_priv *iwm)
iwm_send_prio_table(iwm);
iwm_send_calib_results(iwm);
iwm_send_periodic_calib_cfg(iwm, periodic_calib_map);
+ iwm_send_ct_kill_cfg(iwm, iwm->conf.ct_kill_entry,
+ iwm->conf.ct_kill_exit);

return 0;

diff --git a/drivers/net/wireless/iwmc3200wifi/iwm.h b/drivers/net/wireless/iwmc3200wifi/iwm.h
index 1b02a4e..fe0ab80 100644
--- a/drivers/net/wireless/iwmc3200wifi/iwm.h
+++ b/drivers/net/wireless/iwmc3200wifi/iwm.h
@@ -65,6 +65,8 @@ struct iwm_conf {
u32 sdio_ior_timeout;
unsigned long calib_map;
unsigned long expected_calib_map;
+ u8 ct_kill_entry;
+ u8 ct_kill_exit;
bool reset_on_fatal_err;
bool auto_connect;
bool wimax_not_present;
@@ -276,6 +278,7 @@ struct iwm_priv {
struct iw_statistics wstats;
struct delayed_work stats_request;
struct delayed_work disconnect;
+ struct delayed_work ct_kill_delay;

struct iwm_debugfs dbg;

diff --git a/drivers/net/wireless/iwmc3200wifi/lmac.h b/drivers/net/wireless/iwmc3200wifi/lmac.h
index 6c1a14c..a3a79b5 100644
--- a/drivers/net/wireless/iwmc3200wifi/lmac.h
+++ b/drivers/net/wireless/iwmc3200wifi/lmac.h
@@ -187,6 +187,14 @@ struct iwm_coex_prio_table_cmd {
COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_MSK | \
COEX_EVT_FLAG_DELAY_MEDIUM_FREE_NTFY_MSK)

+/* CT kill config command */
+struct iwm_ct_kill_cfg_cmd {
+ u32 exit_threshold;
+ u32 reserved;
+ u32 entry_threshold;
+} __attribute__ ((packed));
+
+
/* LMAC OP CODES */
#define REPLY_PAD 0x0
#define REPLY_ALIVE 0x1
diff --git a/drivers/net/wireless/iwmc3200wifi/main.c b/drivers/net/wireless/iwmc3200wifi/main.c
index 68fb3dc..dfc8fd4 100644
--- a/drivers/net/wireless/iwmc3200wifi/main.c
+++ b/drivers/net/wireless/iwmc3200wifi/main.c
@@ -64,6 +64,8 @@ static struct iwm_conf def_iwm_conf = {
BIT(PHY_CALIBRATE_TX_IQ_CMD) |
BIT(PHY_CALIBRATE_RX_IQ_CMD) |
BIT(SHILOH_PHY_CALIBRATE_BASE_BAND_CMD),
+ .ct_kill_entry = 110,
+ .ct_kill_exit = 110,
.reset_on_fatal_err = 1,
.auto_connect = 1,
.wimax_not_present = 0,
@@ -134,6 +136,17 @@ static void iwm_disconnect_work(struct work_struct *work)
cfg80211_disconnected(iwm_to_ndev(iwm), 0, NULL, 0, GFP_KERNEL);
}

+static void iwm_ct_kill_work(struct work_struct *work)
+{
+ struct iwm_priv *iwm =
+ container_of(work, struct iwm_priv, ct_kill_delay.work);
+ struct wiphy *wiphy = iwm_to_wiphy(iwm);
+
+ IWM_INFO(iwm, "CT kill delay timeout\n");
+
+ wiphy_rfkill_set_hw_state(wiphy, false);
+}
+
static int __iwm_up(struct iwm_priv *iwm);
static int __iwm_down(struct iwm_priv *iwm);

@@ -226,6 +239,7 @@ int iwm_priv_init(struct iwm_priv *iwm)
iwm->scan_id = 1;
INIT_DELAYED_WORK(&iwm->stats_request, iwm_statistics_request);
INIT_DELAYED_WORK(&iwm->disconnect, iwm_disconnect_work);
+ INIT_DELAYED_WORK(&iwm->ct_kill_delay, iwm_ct_kill_work);
INIT_WORK(&iwm->reset_worker, iwm_reset_worker);
INIT_LIST_HEAD(&iwm->bss_list);

diff --git a/drivers/net/wireless/iwmc3200wifi/netdev.c b/drivers/net/wireless/iwmc3200wifi/netdev.c
index 35ec006..4f8dbdd 100644
--- a/drivers/net/wireless/iwmc3200wifi/netdev.c
+++ b/drivers/net/wireless/iwmc3200wifi/netdev.c
@@ -152,6 +152,7 @@ void iwm_if_free(struct iwm_priv *iwm)
if (!iwm_to_ndev(iwm))
return;

+ cancel_delayed_work_sync(&iwm->ct_kill_delay);
free_netdev(iwm_to_ndev(iwm));
iwm_priv_deinit(iwm);
kfree(iwm->umac_profile);
diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c
index 771a301..813e1b3 100644
--- a/drivers/net/wireless/iwmc3200wifi/rx.c
+++ b/drivers/net/wireless/iwmc3200wifi/rx.c
@@ -1079,6 +1079,7 @@ static int iwm_ntf_wifi_if_wrapper(struct iwm_priv *iwm, u8 *buf,
return 0;
}

+#define CT_KILL_DELAY (30 * HZ)
static int iwm_ntf_card_state(struct iwm_priv *iwm, u8 *buf,
unsigned long buf_size, struct iwm_wifi_cmd *cmd)
{
@@ -1091,7 +1092,20 @@ static int iwm_ntf_card_state(struct iwm_priv *iwm, u8 *buf,
flags & IWM_CARD_STATE_HW_DISABLED ? "ON" : "OFF",
flags & IWM_CARD_STATE_CTKILL_DISABLED ? "ON" : "OFF");

- wiphy_rfkill_set_hw_state(wiphy, flags & IWM_CARD_STATE_HW_DISABLED);
+ if (flags & IWM_CARD_STATE_CTKILL_DISABLED) {
+ /*
+ * We got a CTKILL event: We bring the interface down in
+ * oder to cool the device down, and try to bring it up
+ * 30 seconds later. If it's still too hot, we'll go through
+ * this code path again.
+ */
+ cancel_delayed_work_sync(&iwm->ct_kill_delay);
+ schedule_delayed_work(&iwm->ct_kill_delay, CT_KILL_DELAY);
+ }
+
+ wiphy_rfkill_set_hw_state(wiphy, flags &
+ (IWM_CARD_STATE_HW_DISABLED |
+ IWM_CARD_STATE_CTKILL_DISABLED));

return 0;
}
--
1.6.0.4


2009-10-17 08:24:13

by Zhu Yi

[permalink] [raw]
Subject: RE: [PATCH 14/16] iwmc3200wifi: Support unexpected reboot barker

SGkgVG9tYXMhDQoNCj4gLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4gRnJvbTogVG9tYXMg
V2lua2xlciBbbWFpbHRvOnRvbWFzd0BnbWFpbC5jb21dDQo+IFNlbnQ6IDIwMDnE6jEw1MIxN8jV
IDY6MDcNCj4gVG86IFpodSwgWWkNCj4gQ2M6IGxpbnZpbGxlQHR1eGRyaXZlci5jb207IGxpbnV4
LXdpcmVsZXNzQHZnZXIua2VybmVsLm9yZzsgU2FtdWVsIE9ydGl6DQo+IFN1YmplY3Q6IFJlOiBb
UEFUQ0ggMTQvMTZdIGl3bWMzMjAwd2lmaTogU3VwcG9ydCB1bmV4cGVjdGVkIHJlYm9vdCBiYXJr
ZXINCj4gDQo+IE9uIEZyaSwgT2N0IDE2LCAyMDA5IGF0IDc6MTggQU0sIFpodSBZaSA8eWkuemh1
QGludGVsLmNvbT4gd3JvdGU6DQo+ID4gRnJvbTogU2FtdWVsIE9ydGl6IDxzYW1lb0BsaW51eC5p
bnRlbC5jb20+DQo+ID4NCj4gPiBXZSBjYW4gcmVjZWl2ZSB1bmV4cGVjdGVkIHJlYm9vdCBiYXJr
ZXIgYXQgYW55IHRpbWUsIGFuZCB3ZSdyZSBzdXBwb3NlZCB0bw0KPiA+IHJlc2V0IHRoZSB3aG9s
ZSBkZXZpY2UgdGhlbi4NCj4gDQo+IFdoYXQgZG8geW8gbWVhbiwgYnkgd2hvbGUgZGV2aWNlID8g
QW5kIHdobyBpcyB3ZSBpbiB0aGlzIGNvbnRleHQ/DQoNCldlIGFyZSB0YWxraW5nIGZyb20gdGhl
IHdpZmkgZHJpdmVyJ3MgcGVyc3BlY3RpdmUuIFRoZSBjb2RlIGlzIG9yaWdpbmFsbHkgdXNlZCBv
bmx5IGZvciBTViB0ZXN0aW5nLiBUaGVuIHdlIGZpbmQgaXQgbWlnaHQgYmUgdXNlZnVsIGluIHRo
ZSBnZW5lcmFsIGNhc2UuIFN1cHBvc2UgdGhlIGRyaXZlciBnZXQgYSBSRUJPT1RfQkFSS0VSIGZy
b20gdGhlIGNhcmQgKGZvciB3aGF0ZXZlciByZWFzb24pLCBpcyByZXNldHRpbmcgdGhlIGRldmlj
ZSB0aGUgY29ycmVjdCBiZWhhdmlvcj8NCg0KVGhhbmtzLA0KLXlpDQo=

2009-10-16 22:11:14

by Tomas Winkler

[permalink] [raw]
Subject: Re: [PATCH 01/16] iwmc3200wifi: add BGN sdio device id

On Fri, Oct 16, 2009 at 7:18 AM, Zhu Yi <[email protected]> wrote:
> Add BGN SKU sdio device id.
>
> Signed-off-by: Zhu Yi <[email protected]>
Acked-by: Tomas Winkler <[email protected]>

I will remove SDIO_DEVICE_ID_INTEL_IWMC3200WIF from sdio_ids.h


> ---
>  drivers/net/wireless/iwmc3200wifi/sdio.c |    6 ++++--
>  1 files changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/wireless/iwmc3200wifi/sdio.c b/drivers/net/wireless/iwmc3200wifi/sdio.c
> index 8b1de84..38026b7 100644
> --- a/drivers/net/wireless/iwmc3200wifi/sdio.c
> +++ b/drivers/net/wireless/iwmc3200wifi/sdio.c
> @@ -493,8 +493,10 @@ static void iwm_sdio_remove(struct sdio_func *func)
>  }
>
>  static const struct sdio_device_id iwm_sdio_ids[] = {
> -       { SDIO_DEVICE(SDIO_VENDOR_ID_INTEL,
> -                     SDIO_DEVICE_ID_INTEL_IWMC3200WIFI) },
> +       /* Global/AGN SKU */
> +       { SDIO_DEVICE(SDIO_VENDOR_ID_INTEL, 0x1403) },
> +       /* BGN SKU */
> +       { SDIO_DEVICE(SDIO_VENDOR_ID_INTEL, 0x1408) },
>        { /* end: all zeroes */ },
>  };
>  MODULE_DEVICE_TABLE(sdio, iwm_sdio_ids);
> --
> 1.6.0.4
>
> --
> 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
>

2009-10-16 05:20:38

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 05/16] iwmc3200wifi: Profile flags can be WPA1 or WPA2 not both

From: Samuel Ortiz <[email protected]>

UMAC will ASSERT if the profile security flag is WPA1 | WPA2, so we can only
accept one of those.
Moreover wpa_s wext and nl80211 drivers dont try to send WPA1 | WPA2, but only
one at a time.

Signed-off-by: Samuel Ortiz <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwmc3200wifi/cfg80211.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
index a6d2f20..ea0ed32 100644
--- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c
+++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
@@ -472,12 +472,12 @@ static int iwm_set_wpa_version(struct iwm_priv *iwm, u32 wpa_version)
return 0;
}

+ if (wpa_version & NL80211_WPA_VERSION_1)
+ iwm->umac_profile->sec.flags = UMAC_SEC_FLG_WPA_ON_MSK;
+
if (wpa_version & NL80211_WPA_VERSION_2)
iwm->umac_profile->sec.flags = UMAC_SEC_FLG_RSNA_ON_MSK;

- if (wpa_version & NL80211_WPA_VERSION_1)
- iwm->umac_profile->sec.flags |= UMAC_SEC_FLG_WPA_ON_MSK;
-
return 0;
}

--
1.6.0.4


2009-10-16 05:21:25

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 15/16] iwmc3200wifi: Set wiphy firmware version

From: Samuel Ortiz <[email protected]>

Our wiphy firmware version is a combination of the UMAC and LMAC ones.

Signed-off-by: Samuel Ortiz <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwmc3200wifi/fw.c | 7 +++++++
drivers/net/wireless/iwmc3200wifi/iwm.h | 2 ++
drivers/net/wireless/iwmc3200wifi/main.c | 4 ++++
3 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/iwmc3200wifi/fw.c b/drivers/net/wireless/iwmc3200wifi/fw.c
index f02d571..4906709 100644
--- a/drivers/net/wireless/iwmc3200wifi/fw.c
+++ b/drivers/net/wireless/iwmc3200wifi/fw.c
@@ -217,6 +217,13 @@ static int iwm_load_img(struct iwm_priv *iwm, const char *img_name)
IWM_BUILD_YEAR(build_date), IWM_BUILD_MONTH(build_date),
IWM_BUILD_DAY(build_date));

+ if (!strcmp(img_name, iwm->bus_ops->umac_name))
+ sprintf(iwm->umac_version, "%02X.%02X",
+ ver->major, ver->minor);
+
+ if (!strcmp(img_name, iwm->bus_ops->lmac_name))
+ sprintf(iwm->lmac_version, "%02X.%02X",
+ ver->major, ver->minor);

err_release_fw:
release_firmware(fw);
diff --git a/drivers/net/wireless/iwmc3200wifi/iwm.h b/drivers/net/wireless/iwmc3200wifi/iwm.h
index c4a01f2..a9bf6bc 100644
--- a/drivers/net/wireless/iwmc3200wifi/iwm.h
+++ b/drivers/net/wireless/iwmc3200wifi/iwm.h
@@ -294,6 +294,8 @@ struct iwm_priv {
int resp_ie_len;

struct iwm_fw_error_hdr *last_fw_err;
+ char umac_version[8];
+ char lmac_version[8];

char private[0] __attribute__((__aligned__(NETDEV_ALIGN)));
};
diff --git a/drivers/net/wireless/iwmc3200wifi/main.c b/drivers/net/wireless/iwmc3200wifi/main.c
index 97c6f5a..75f105a 100644
--- a/drivers/net/wireless/iwmc3200wifi/main.c
+++ b/drivers/net/wireless/iwmc3200wifi/main.c
@@ -629,6 +629,7 @@ static int __iwm_up(struct iwm_priv *iwm)
{
int ret;
struct iwm_notif *notif_reboot, *notif_ack = NULL;
+ struct wiphy *wiphy = iwm_to_wiphy(iwm);

ret = iwm_bus_enable(iwm);
if (ret) {
@@ -690,6 +691,9 @@ static int __iwm_up(struct iwm_priv *iwm)
goto err_disable;
}

+ snprintf(wiphy->fw_version, sizeof(wiphy->fw_version), "L%s_U%s",
+ iwm->lmac_version, iwm->umac_version);
+
/* We configure the UMAC and enable the wifi module */
ret = iwm_send_umac_config(iwm,
cpu_to_le32(UMAC_RST_CTRL_FLG_WIFI_CORE_EN) |
--
1.6.0.4


2009-10-16 05:21:15

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 13/16] iwmc3200wifi: Try shared auth when open WEP fails

From: Samuel Ortiz <[email protected]>

When we fail to associate with an open WEP AP, we fall back to shared auth.
This allows us to support joining a shared auth WEP AP with iwconfig.

Signed-off-by: Samuel Ortiz <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwmc3200wifi/commands.c | 2 +-
drivers/net/wireless/iwmc3200wifi/iwm.h | 1 +
drivers/net/wireless/iwmc3200wifi/main.c | 28 ++++++++++++++++++++++++++
drivers/net/wireless/iwmc3200wifi/rx.c | 28 +++++++++++++++++++++----
4 files changed, 53 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/iwmc3200wifi/commands.c b/drivers/net/wireless/iwmc3200wifi/commands.c
index 2911ace..7e12438 100644
--- a/drivers/net/wireless/iwmc3200wifi/commands.c
+++ b/drivers/net/wireless/iwmc3200wifi/commands.c
@@ -794,7 +794,7 @@ int iwm_invalidate_mlme_profile(struct iwm_priv *iwm)
return ret;

ret = wait_event_interruptible_timeout(iwm->mlme_queue,
- (iwm->umac_profile_active == 0), 2 * HZ);
+ (iwm->umac_profile_active == 0), 5 * HZ);

return ret ? 0 : -EBUSY;
}
diff --git a/drivers/net/wireless/iwmc3200wifi/iwm.h b/drivers/net/wireless/iwmc3200wifi/iwm.h
index fe0ab80..c4a01f2 100644
--- a/drivers/net/wireless/iwmc3200wifi/iwm.h
+++ b/drivers/net/wireless/iwmc3200wifi/iwm.h
@@ -285,6 +285,7 @@ struct iwm_priv {
u8 *eeprom;
struct timer_list watchdog;
struct work_struct reset_worker;
+ struct work_struct auth_retry_worker;
struct mutex mutex;

u8 *req_ie;
diff --git a/drivers/net/wireless/iwmc3200wifi/main.c b/drivers/net/wireless/iwmc3200wifi/main.c
index dfc8fd4..97c6f5a 100644
--- a/drivers/net/wireless/iwmc3200wifi/main.c
+++ b/drivers/net/wireless/iwmc3200wifi/main.c
@@ -208,6 +208,33 @@ static void iwm_reset_worker(struct work_struct *work)
mutex_unlock(&iwm->mutex);
}

+static void iwm_auth_retry_worker(struct work_struct *work)
+{
+ struct iwm_priv *iwm;
+ int i, ret;
+
+ iwm = container_of(work, struct iwm_priv, auth_retry_worker);
+ if (iwm->umac_profile_active) {
+ ret = iwm_invalidate_mlme_profile(iwm);
+ if (ret < 0)
+ return;
+ }
+
+ iwm->umac_profile->sec.auth_type = UMAC_AUTH_TYPE_LEGACY_PSK;
+
+ ret = iwm_send_mlme_profile(iwm);
+ if (ret < 0)
+ return;
+
+ for (i = 0; i < IWM_NUM_KEYS; i++)
+ if (iwm->keys[i].key_len)
+ iwm_set_key(iwm, 0, &iwm->keys[i]);
+
+ iwm_set_tx_key(iwm, iwm->default_key);
+}
+
+
+
static void iwm_watchdog(unsigned long data)
{
struct iwm_priv *iwm = (struct iwm_priv *)data;
@@ -241,6 +268,7 @@ int iwm_priv_init(struct iwm_priv *iwm)
INIT_DELAYED_WORK(&iwm->disconnect, iwm_disconnect_work);
INIT_DELAYED_WORK(&iwm->ct_kill_delay, iwm_ct_kill_work);
INIT_WORK(&iwm->reset_worker, iwm_reset_worker);
+ INIT_WORK(&iwm->auth_retry_worker, iwm_auth_retry_worker);
INIT_LIST_HEAD(&iwm->bss_list);

skb_queue_head_init(&iwm->rx_list);
diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c
index 0fa3f5c..c0fa853 100644
--- a/drivers/net/wireless/iwmc3200wifi/rx.c
+++ b/drivers/net/wireless/iwmc3200wifi/rx.c
@@ -502,6 +502,18 @@ static int iwm_mlme_assoc_start(struct iwm_priv *iwm, u8 *buf,
return 0;
}

+static u8 iwm_is_open_wep_profile(struct iwm_priv *iwm)
+{
+ if ((iwm->umac_profile->sec.ucast_cipher == UMAC_CIPHER_TYPE_WEP_40 ||
+ iwm->umac_profile->sec.ucast_cipher == UMAC_CIPHER_TYPE_WEP_104) &&
+ (iwm->umac_profile->sec.ucast_cipher ==
+ iwm->umac_profile->sec.mcast_cipher) &&
+ (iwm->umac_profile->sec.auth_type == UMAC_AUTH_TYPE_OPEN))
+ return 1;
+
+ return 0;
+}
+
static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf,
unsigned long buf_size,
struct iwm_wifi_cmd *cmd)
@@ -567,11 +579,17 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf,
goto ibss;

if (!test_bit(IWM_STATUS_RESETTING, &iwm->status))
- cfg80211_connect_result(iwm_to_ndev(iwm),
- complete->bssid,
- NULL, 0, NULL, 0,
- WLAN_STATUS_UNSPECIFIED_FAILURE,
- GFP_KERNEL);
+ if (!iwm_is_open_wep_profile(iwm)) {
+ cfg80211_connect_result(iwm_to_ndev(iwm),
+ complete->bssid,
+ NULL, 0, NULL, 0,
+ WLAN_STATUS_UNSPECIFIED_FAILURE,
+ GFP_KERNEL);
+ } else {
+ /* Let's try shared WEP auth */
+ IWM_ERR(iwm, "Trying WEP shared auth\n");
+ schedule_work(&iwm->auth_retry_worker);
+ }
else
cfg80211_disconnected(iwm_to_ndev(iwm), 0, NULL, 0,
GFP_KERNEL);
--
1.6.0.4


2009-10-16 05:20:43

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 07/16] iwmc3200wifi: Update statistics notification structure

From: Samuel Ortiz <[email protected]>

The latest firmware adds a ht_rates and a chain_energy field. The latter is
needed as we want to eventually support RSSI/antenna handling.

Signed-off-by: Samuel Ortiz <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwmc3200wifi/umac.h | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/iwmc3200wifi/umac.h b/drivers/net/wireless/iwmc3200wifi/umac.h
index c5a14ae..be90354 100644
--- a/drivers/net/wireless/iwmc3200wifi/umac.h
+++ b/drivers/net/wireless/iwmc3200wifi/umac.h
@@ -687,6 +687,9 @@ struct iwm_umac_notif_rx_ticket {
/* Tx/Rx rates window (number of max of last update window per second) */
#define UMAC_NTF_RATE_SAMPLE_NR 4

+/* Max numbers of bits required to go through all antennae in bitmasks */
+#define UMAC_PHY_NUM_CHAINS 3
+
#define IWM_UMAC_MGMT_TID 8
#define IWM_UMAC_TID_NR 8

@@ -697,9 +700,11 @@ struct iwm_umac_notif_stats {
__le16 tid_load[IWM_UMAC_TID_NR + 2]; /* 1 non-QoS + 1 dword align */
__le16 tx_rate[UMAC_NTF_RATE_SAMPLE_NR];
__le16 rx_rate[UMAC_NTF_RATE_SAMPLE_NR];
+ __le32 chain_energy[UMAC_PHY_NUM_CHAINS];
s32 rssi_dbm;
s32 noise_dbm;
__le32 supp_rates;
+ __le32 supp_ht_rates;
__le32 missed_beacons;
__le32 rx_beacons;
__le32 rx_dir_pkts;
--
1.6.0.4


2009-10-16 22:06:29

by Tomas Winkler

[permalink] [raw]
Subject: Re: [PATCH 14/16] iwmc3200wifi: Support unexpected reboot barker

On Fri, Oct 16, 2009 at 7:18 AM, Zhu Yi <[email protected]> wrote:
> From: Samuel Ortiz <[email protected]>
>
> We can receive unexpected reboot barker at any time, and we're supposed to
> reset the whole device then.

What do yo mean, by whole device ? And who is we in this context?

Thanks
Tomas

>
> Signed-off-by: Samuel Ortiz <[email protected]>
> Signed-off-by: Zhu Yi <[email protected]>
> ---
>  drivers/net/wireless/iwmc3200wifi/rx.c |    8 ++++++++
>  1 files changed, 8 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c
> index c0fa853..95deb0a 100644
> --- a/drivers/net/wireless/iwmc3200wifi/rx.c
> +++ b/drivers/net/wireless/iwmc3200wifi/rx.c
> @@ -1322,6 +1322,14 @@ int iwm_rx_handle(struct iwm_priv *iwm, u8 *buf, unsigned long buf_size)
>
>        switch (le32_to_cpu(hdr->cmd)) {
>        case UMAC_REBOOT_BARKER:
> +               if (test_bit(IWM_STATUS_READY, &iwm->status)) {
> +                       IWM_ERR(iwm, "Unexpected BARKER\n");
> +
> +                       schedule_work(&iwm->reset_worker);
> +
> +                       return 0;
> +               }
> +
>                return iwm_notif_send(iwm, NULL, IWM_BARKER_REBOOT_NOTIFICATION,
>                                      IWM_SRC_UDMA, buf, buf_size);
>        case UMAC_ACK_BARKER:
> --
> 1.6.0.4
>
> --
> 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
>

2009-10-16 05:21:30

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 16/16] iwmc3200wifi: handle coexistence radio notification

Handle WiFi/WiMax coexistence radio preemption notification event.

Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwmc3200wifi/rx.c | 15 +++++++++++++++
1 files changed, 15 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c
index 95deb0a..bdb1d7e 100644
--- a/drivers/net/wireless/iwmc3200wifi/rx.c
+++ b/drivers/net/wireless/iwmc3200wifi/rx.c
@@ -733,6 +733,19 @@ static int iwm_mlme_update_sta_table(struct iwm_priv *iwm, u8 *buf,
return 0;
}

+static int iwm_mlme_medium_lost(struct iwm_priv *iwm, u8 *buf,
+ unsigned long buf_size,
+ struct iwm_wifi_cmd *cmd)
+{
+ struct wiphy *wiphy = iwm_to_wiphy(iwm);
+
+ IWM_DBG_NTF(iwm, DBG, "WiFi/WiMax coexistence radio is OFF\n");
+
+ wiphy_rfkill_set_hw_state(wiphy, true);
+
+ return 0;
+}
+
static int iwm_mlme_update_bss_table(struct iwm_priv *iwm, u8 *buf,
unsigned long buf_size,
struct iwm_wifi_cmd *cmd)
@@ -919,6 +932,8 @@ static int iwm_ntf_mlme(struct iwm_priv *iwm, u8 *buf,
case WIFI_IF_NTFY_EXTENDED_IE_REQUIRED:
IWM_DBG_MLME(iwm, DBG, "Extended IE required\n");
break;
+ case WIFI_IF_NTFY_RADIO_PREEMPTION:
+ return iwm_mlme_medium_lost(iwm, buf, buf_size, cmd);
case WIFI_IF_NTFY_BSS_TRK_TABLE_CHANGED:
return iwm_mlme_update_bss_table(iwm, buf, buf_size, cmd);
case WIFI_IF_NTFY_BSS_TRK_ENTRIES_REMOVED:
--
1.6.0.4