2012-01-30 11:57:36

by Eliad Peller

[permalink] [raw]
Subject: [PATCH 00/12] wl12xx: update fw api

The fw api was changed in the latest FWs (6.3.5.0.95 for wl127x
and 7.3.5.0.95 for wl128x).

Along with some small adjustments, the main changes
inroduced by this patheset are configuring the
templates per-role, and moving to IEEE80211_HW_SUPPORTS_DYNAMIC_PS
mode.

Eliad Peller (5):
wl12xx: fw api change - add role_id to set_template
wl12xx: use dev_role_id for scans
wl12xx: use dev_role_id for sched scan
wl12xx: fw api change - add role_id to tsf_info
wl12xx: fw api change - update cmd/acx/event enums

Eyal Shapira (7):
wl12xx: Driver-FW API changes
wl12xx: remove PS management code
wl12xx: add support for HW dynamic PS
wl12xx: add dynamic_ps_timeout debugfs file
wl12xx: remove 2 unused parameters in wl1271_ps_set_mode()
wl12xx: enable/disable BET with AUTO_PS/ACTIVE
wl12xx: change WLVIF_FLAG_PSM name and remove
WLVIF_FLAG_PSM_REQUESTED

drivers/net/wireless/wl12xx/acx.c | 7 +-
drivers/net/wireless/wl12xx/acx.h | 146 ++++++++++++++++---------------
drivers/net/wireless/wl12xx/boot.c | 3 +-
drivers/net/wireless/wl12xx/cmd.c | 55 ++++++++----
drivers/net/wireless/wl12xx/cmd.h | 145 +++++++++++++++++-------------
drivers/net/wireless/wl12xx/conf.h | 13 ++--
drivers/net/wireless/wl12xx/debugfs.c | 66 ++++++++++++++-
drivers/net/wireless/wl12xx/event.c | 151 -------------------------------
drivers/net/wireless/wl12xx/event.h | 20 +++--
drivers/net/wireless/wl12xx/init.c | 45 ++++++---
drivers/net/wireless/wl12xx/main.c | 158 +++++++--------------------------
drivers/net/wireless/wl12xx/ps.c | 32 +++++--
drivers/net/wireless/wl12xx/ps.h | 2 +-
drivers/net/wireless/wl12xx/scan.c | 42 ++++++---
drivers/net/wireless/wl12xx/wl12xx.h | 13 +--
15 files changed, 399 insertions(+), 499 deletions(-)

--
1.7.6.401.g6a319



2012-01-30 11:57:53

by Eliad Peller

[permalink] [raw]
Subject: [PATCH 09/12] wl12xx: add dynamic_ps_timeout debugfs file

From: Eyal Shapira <[email protected]>

Enable read/write of dynamic_ps_timeout which controls the timeout
of the dynamic PS implemented in the FW.
dynamic_ps_timeout is the timeout (in msec) until going back to PS
when there's no Rx/Tx

Signed-off-by: Eyal Shapira <[email protected]>
Signed-off-by: Eliad Peller <[email protected]>
---
drivers/net/wireless/wl12xx/debugfs.c | 67 +++++++++++++++++++++++++++++++++
1 files changed, 67 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c
index 5e96e05..156a774 100644
--- a/drivers/net/wireless/wl12xx/debugfs.c
+++ b/drivers/net/wireless/wl12xx/debugfs.c
@@ -312,6 +312,72 @@ static const struct file_operations start_recovery_ops = {
.llseek = default_llseek,
};

+static ssize_t dynamic_ps_timeout_read(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct wl1271 *wl = file->private_data;
+
+ return wl1271_format_buffer(user_buf, count,
+ ppos, "%d\n",
+ wl->conf.conn.dynamic_ps_timeout);
+}
+
+static ssize_t dynamic_ps_timeout_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct wl1271 *wl = file->private_data;
+ struct wl12xx_vif *wlvif;
+ unsigned long value;
+ int ret;
+
+ ret = kstrtoul_from_user(user_buf, count, 10, &value);
+ if (ret < 0) {
+ wl1271_warning("illegal value in dynamic_ps");
+ return -EINVAL;
+ }
+
+ if (value < 1 || value > 65535) {
+ wl1271_warning("dyanmic_ps_timeout is not in valid range");
+ return -ERANGE;
+ }
+
+ mutex_lock(&wl->mutex);
+
+ wl->conf.conn.dynamic_ps_timeout = value;
+
+ if (wl->state == WL1271_STATE_OFF)
+ goto out;
+
+ ret = wl1271_ps_elp_wakeup(wl);
+ if (ret < 0)
+ goto out;
+
+ /* In case we're already in PSM, trigger it again to set new timeout
+ * immediately without waiting for re-association
+ */
+
+ wl12xx_for_each_wlvif_sta(wl, wlvif) {
+ if (test_bit(WLVIF_FLAG_PSM, &wlvif->flags))
+ wl1271_ps_set_mode(wl, wlvif, STATION_AUTO_PS_MODE,
+ wlvif->basic_rate, true);
+
+ }
+
+ wl1271_ps_elp_sleep(wl);
+
+out:
+ mutex_unlock(&wl->mutex);
+ return count;
+}
+
+static const struct file_operations dynamic_ps_timeout_ops = {
+ .read = dynamic_ps_timeout_read,
+ .write = dynamic_ps_timeout_write,
+ .open = wl1271_open_file_generic,
+ .llseek = default_llseek,
+};
+
static ssize_t driver_state_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
@@ -887,6 +953,7 @@ static int wl1271_debugfs_add_files(struct wl1271 *wl,
DEBUGFS_ADD(dtim_interval, rootdir);
DEBUGFS_ADD(beacon_interval, rootdir);
DEBUGFS_ADD(beacon_filtering, rootdir);
+ DEBUGFS_ADD(dynamic_ps_timeout, rootdir);

streaming = debugfs_create_dir("rx_streaming", rootdir);
if (!streaming || IS_ERR(streaming))
--
1.7.6.401.g6a319


2012-01-30 11:57:59

by Eliad Peller

[permalink] [raw]
Subject: [PATCH 12/12] wl12xx: change WLVIF_FLAG_PSM name and remove WLVIF_FLAG_PSM_REQUESTED

From: Eyal Shapira <[email protected]>

WLVIF_FLAG_PSM turned to WLVIF_FLAG_IN_AUTO_PS which
marks that this vif is in AUTO PS.

WLVIF_FLAG_PSM_REQUESTED is not required as mac80211
calls op_config with CONF_PS after association.

wl12xx_config_vif() handling of CONF_PS was simplified
and cleaned up.

Signed-off-by: Eyal Shapira <[email protected]>
Signed-off-by: Eliad Peller <[email protected]>
---
drivers/net/wireless/wl12xx/debugfs.c | 2 +-
drivers/net/wireless/wl12xx/main.c | 42 ++++++++++++--------------------
drivers/net/wireless/wl12xx/ps.c | 8 +++---
drivers/net/wireless/wl12xx/wl12xx.h | 3 +-
4 files changed, 22 insertions(+), 33 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c
index 4436851..4dcb3f7 100644
--- a/drivers/net/wireless/wl12xx/debugfs.c
+++ b/drivers/net/wireless/wl12xx/debugfs.c
@@ -358,7 +358,7 @@ static ssize_t dynamic_ps_timeout_write(struct file *file,
*/

wl12xx_for_each_wlvif_sta(wl, wlvif) {
- if (test_bit(WLVIF_FLAG_PSM, &wlvif->flags))
+ if (test_bit(WLVIF_FLAG_IN_AUTO_PS, &wlvif->flags))
wl1271_ps_set_mode(wl, wlvif, STATION_AUTO_PS_MODE);
}

diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 21841d4..2bb1c24 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -2432,29 +2432,29 @@ static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif,
}
}

- if (conf->flags & IEEE80211_CONF_PS &&
- !test_bit(WLVIF_FLAG_PSM_REQUESTED, &wlvif->flags)) {
- set_bit(WLVIF_FLAG_PSM_REQUESTED, &wlvif->flags);
+ if ((changed & IEEE80211_CONF_CHANGE_PS) && !is_ap) {
+
+ if ((conf->flags & IEEE80211_CONF_PS) &&
+ test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) &&
+ !test_bit(WLVIF_FLAG_IN_AUTO_PS, &wlvif->flags)) {
+
+ wl1271_debug(DEBUG_PSM, "auto ps enabled");

- /*
- * We enter PSM only if we're already associated.
- * If we're not, we'll enter it when joining an SSID,
- * through the bss_info_changed() hook.
- */
- if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) {
- wl1271_debug(DEBUG_PSM, "psm enabled");
ret = wl1271_ps_set_mode(wl, wlvif,
STATION_AUTO_PS_MODE);
- }
- } else if (!(conf->flags & IEEE80211_CONF_PS) &&
- test_bit(WLVIF_FLAG_PSM_REQUESTED, &wlvif->flags)) {
- wl1271_debug(DEBUG_PSM, "psm disabled");
+ if (ret < 0)
+ wl1271_warning("enter auto ps failed %d", ret);

- clear_bit(WLVIF_FLAG_PSM_REQUESTED, &wlvif->flags);
+ } else if (!(conf->flags & IEEE80211_CONF_PS) &&
+ test_bit(WLVIF_FLAG_IN_AUTO_PS, &wlvif->flags)) {
+
+ wl1271_debug(DEBUG_PSM, "auto ps disabled");

- if (test_bit(WLVIF_FLAG_PSM, &wlvif->flags))
ret = wl1271_ps_set_mode(wl, wlvif,
STATION_ACTIVE_MODE);
+ if (ret < 0)
+ wl1271_warning("exit auto ps failed %d", ret);
+ }
}

if (conf->power_level != wlvif->power_level) {
@@ -3788,16 +3788,6 @@ sta_not_found:
if (ret < 0)
goto out;
}
-
- /* If we want to go in PSM but we're not there yet */
- if (test_bit(WLVIF_FLAG_PSM_REQUESTED, &wlvif->flags) &&
- !test_bit(WLVIF_FLAG_PSM, &wlvif->flags)) {
-
- ret = wl1271_ps_set_mode(wl, wlvif,
- STATION_AUTO_PS_MODE);
- if (ret < 0)
- goto out;
- }
}

/* Handle new association with HT. Do this after join. */
diff --git a/drivers/net/wireless/wl12xx/ps.c b/drivers/net/wireless/wl12xx/ps.c
index d7a91d3..e209e29 100644
--- a/drivers/net/wireless/wl12xx/ps.c
+++ b/drivers/net/wireless/wl12xx/ps.c
@@ -56,7 +56,7 @@ void wl1271_elp_work(struct work_struct *work)
if (wlvif->bss_type == BSS_TYPE_AP_BSS)
goto out;

- if (!test_bit(WLVIF_FLAG_PSM, &wlvif->flags) &&
+ if (!test_bit(WLVIF_FLAG_IN_AUTO_PS, &wlvif->flags) &&
test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags))
goto out;
}
@@ -84,7 +84,7 @@ void wl1271_ps_elp_sleep(struct wl1271 *wl)
if (wlvif->bss_type == BSS_TYPE_AP_BSS)
return;

- if (!test_bit(WLVIF_FLAG_PSM, &wlvif->flags) &&
+ if (!test_bit(WLVIF_FLAG_IN_AUTO_PS, &wlvif->flags) &&
test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags))
return;
}
@@ -180,7 +180,7 @@ int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
if (ret < 0)
return ret;

- set_bit(WLVIF_FLAG_PSM, &wlvif->flags);
+ set_bit(WLVIF_FLAG_IN_AUTO_PS, &wlvif->flags);

/* enable beacon early termination. Not relevant for 5GHz */
if (wlvif->band == IEEE80211_BAND_2GHZ) {
@@ -203,7 +203,7 @@ int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
if (ret < 0)
return ret;

- clear_bit(WLVIF_FLAG_PSM, &wlvif->flags);
+ clear_bit(WLVIF_FLAG_IN_AUTO_PS, &wlvif->flags);
break;
case STATION_POWER_SAVE_MODE:
default:
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
index af1cedc..9cc7051 100644
--- a/drivers/net/wireless/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/wl12xx/wl12xx.h
@@ -254,8 +254,7 @@ enum wl12xx_vif_flags {
WLVIF_FLAG_STA_ASSOCIATED,
WLVIF_FLAG_IBSS_JOINED,
WLVIF_FLAG_AP_STARTED,
- WLVIF_FLAG_PSM,
- WLVIF_FLAG_PSM_REQUESTED,
+ WLVIF_FLAG_IN_AUTO_PS,
WLVIF_FLAG_STA_STATE_SENT,
WLVIF_FLAG_RX_STREAMING_STARTED,
WLVIF_FLAG_PSPOLL_FAILURE,
--
1.7.6.401.g6a319


2012-01-30 19:53:09

by Luciano Coelho

[permalink] [raw]
Subject: Re: [PATCH 01/12] wl12xx: fw api change - add role_id to set_template

On Mon, 2012-01-30 at 14:00 +0200, Eliad Peller wrote:
> @@ -191,7 +193,7 @@ enum cmd_templ {
> /* unit ms */
> #define WL1271_COMMAND_TIMEOUT 2000
> #define WL1271_CMD_TEMPL_DFLT_SIZE 252
> -#define WL1271_CMD_TEMPL_MAX_SIZE 548
> +#define WL1271_CMD_TEMPL_MAX_SIZE 512
> #define WL1271_EVENT_TIMEOUT 750

Is this change here on purpose? Is it really related to the FW API
change?


--
Cheers,
Luca.


2012-01-30 11:57:44

by Eliad Peller

[permalink] [raw]
Subject: [PATCH 04/12] wl12xx: fw api change - add role_id to tsf_info

The ACX_TSF_INFO command now takes role_id as param.
change the struct accordingly, and pass the wlvif
to the wl1271_acx_tsf_info() function.

Signed-off-by: Eliad Peller <[email protected]>
---
drivers/net/wireless/wl12xx/acx.c | 7 +++++--
drivers/net/wireless/wl12xx/acx.h | 9 ++++++---
drivers/net/wireless/wl12xx/main.c | 3 ++-
3 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c
index 7537c40..af2c312 100644
--- a/drivers/net/wireless/wl12xx/acx.c
+++ b/drivers/net/wireless/wl12xx/acx.c
@@ -1459,9 +1459,10 @@ out:
return ret;
}

-int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime)
+int wl12xx_acx_tsf_info(struct wl1271 *wl, struct wl12xx_vif *wlvif,
+ u64 *mactime)
{
- struct wl1271_acx_fw_tsf_information *tsf_info;
+ struct wl12xx_acx_fw_tsf_information *tsf_info;
int ret;

tsf_info = kzalloc(sizeof(*tsf_info), GFP_KERNEL);
@@ -1470,6 +1471,8 @@ int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime)
goto out;
}

+ tsf_info->role_id = wlvif->role_id;
+
ret = wl1271_cmd_interrogate(wl, ACX_TSF_INFO,
tsf_info, sizeof(*tsf_info));
if (ret < 0) {
diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h
index 69892b4..a5bf761 100644
--- a/drivers/net/wireless/wl12xx/acx.h
+++ b/drivers/net/wireless/wl12xx/acx.h
@@ -995,15 +995,17 @@ struct wl1271_acx_ba_receiver_setup {
u8 padding[2];
} __packed;

-struct wl1271_acx_fw_tsf_information {
+struct wl12xx_acx_fw_tsf_information {
struct acx_header header;

+ u8 role_id;
+ u8 padding1[3];
__le32 current_tsf_high;
__le32 current_tsf_low;
__le32 last_bttt_high;
__le32 last_tbtt_low;
u8 last_dtim_count;
- u8 padding[3];
+ u8 padding2[3];
} __packed;

struct wl1271_acx_ps_rx_streaming {
@@ -1296,7 +1298,8 @@ int wl12xx_acx_set_ba_initiator_policy(struct wl1271 *wl,
struct wl12xx_vif *wlvif);
int wl12xx_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index,
u16 ssn, bool enable, u8 peer_hlid);
-int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime);
+int wl12xx_acx_tsf_info(struct wl1271 *wl, struct wl12xx_vif *wlvif,
+ u64 *mactime);
int wl1271_acx_ps_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif,
bool enable);
int wl1271_acx_ap_max_tx_retry(struct wl1271 *wl, struct wl12xx_vif *wlvif);
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 51059a8..1c73c01 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -4019,6 +4019,7 @@ static u64 wl1271_op_get_tsf(struct ieee80211_hw *hw,
{

struct wl1271 *wl = hw->priv;
+ struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
u64 mactime = ULLONG_MAX;
int ret;

@@ -4033,7 +4034,7 @@ static u64 wl1271_op_get_tsf(struct ieee80211_hw *hw,
if (ret < 0)
goto out;

- ret = wl1271_acx_tsf_info(wl, &mactime);
+ ret = wl12xx_acx_tsf_info(wl, wlvif, &mactime);
if (ret < 0)
goto out_sleep;

--
1.7.6.401.g6a319


2012-01-30 19:48:43

by Luciano Coelho

[permalink] [raw]
Subject: Re: [PATCH 06/12] wl12xx: Driver-FW API changes

On Mon, 2012-01-30 at 14:00 +0200, Eliad Peller wrote:
> From: Eyal Shapira <[email protected]>
>
> - New ACX enum
> - Added DFS commands
> - Changes to channel switch command/event
> - Added reset_tsf to ap role start command
> - Added ACX for PROTECTION configuration
>
> Signed-off-by: Eyal Shapira <[email protected]>
> Signed-off-by: Eliad Peller <[email protected]>
> ---

I think this shold also be squashed with the previous one. Especially
because this commit log says it does things that were actually already
done in the previous one. ;)


--
Cheers,
Luca.


2012-01-31 09:43:05

by Eliad Peller

[permalink] [raw]
Subject: Re: [PATCH 00/12] wl12xx: update fw api

On Tue, Jan 31, 2012 at 9:50 AM, Kalle Valo <[email protected]> wrote:
> Eliad Peller <[email protected]> writes:
>
>> On Mon, Jan 30, 2012 at 3:29 PM, Kalle Valo <[email protected]> wrote:
>>> Eliad Peller <[email protected]> writes:
>>>
>>>> The fw api was changed in the latest FWs (6.3.5.0.95 for wl127x
>>>> and 7.3.5.0.95 for wl128x).
>>>>
>>>> Along with some small adjustments, the main changes
>>>> inroduced by this patheset are configuring the
>>>> templates per-role, and moving to IEEE80211_HW_SUPPORTS_DYNAMIC_PS
>>>> mode.
>>>
>>> I didn't look so carefully, but doesn't this break bisect? I mean if you
>>> change the firmware api in small patches wl12xx can't work properly
>>> until all patches are applied, right?
>>>
>>> I would say that a huge patch doing all the necessary changes in one go
>>> is better, even it's ugly.
>>>
>> yes. it will break bisect (although it shouldn't break compilations).
>> i guess it's a matter of taste, but i think keeping the patches
>> manageable is more important than being able to bisect.
>
> Yeah, it's just matter of taste. It's easy to skip commits during bisect
> but someone not familiar with wl12xx does not know what commits to
> skip and that will cause problems.
>
> But I don't care how you do it, I just wanted to point out this aspect :)
>
ok, thanks :)

i took Luca's approach, and added an error message to the driver, and
prevented it from starting in the transitional commits. i'll send an
updated patchset soon.

Eliad.

2012-01-30 19:47:49

by Luciano Coelho

[permalink] [raw]
Subject: Re: [PATCH 03/12] wl12xx: use dev_role_id for sched scan

On Mon, 2012-01-30 at 14:00 +0200, Eliad Peller wrote:
> sched_scan is used only when the sta is
> not associated, and thus should use
> the dev role (instead of sta role)
>
> Signed-off-by: Eliad Peller <[email protected]>
> ---

Can you squash this with 02/12?

--
Cheers,
Luca.


2012-01-31 09:40:58

by Eliad Peller

[permalink] [raw]
Subject: Re: [PATCH 01/12] wl12xx: fw api change - add role_id to set_template

On Mon, Jan 30, 2012 at 9:53 PM, Luciano Coelho <[email protected]> wrote:
> On Mon, 2012-01-30 at 14:00 +0200, Eliad Peller wrote:
>> @@ -191,7 +193,7 @@ enum cmd_templ {
>> ?/* unit ms */
>> ?#define WL1271_COMMAND_TIMEOUT ? ? 2000
>> ?#define WL1271_CMD_TEMPL_DFLT_SIZE 252
>> -#define WL1271_CMD_TEMPL_MAX_SIZE ?548
>> +#define WL1271_CMD_TEMPL_MAX_SIZE ?512
>> #define WL1271_EVENT_TIMEOUT ? ? ? 750
>
> Is this change here on purpose? Is it really related to the FW API
> change?
>
yes. this const determines the size of the wl1271_cmd_template_set struct.

Eliad.

2012-01-30 13:29:29

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH 00/12] wl12xx: update fw api

Eliad Peller <[email protected]> writes:

> The fw api was changed in the latest FWs (6.3.5.0.95 for wl127x
> and 7.3.5.0.95 for wl128x).
>
> Along with some small adjustments, the main changes
> inroduced by this patheset are configuring the
> templates per-role, and moving to IEEE80211_HW_SUPPORTS_DYNAMIC_PS
> mode.

I didn't look so carefully, but doesn't this break bisect? I mean if you
change the firmware api in small patches wl12xx can't work properly
until all patches are applied, right?

I would say that a huge patch doing all the necessary changes in one go
is better, even it's ugly.

--
Kalle Valo

2012-01-30 13:52:07

by Eliad Peller

[permalink] [raw]
Subject: Re: [PATCH 00/12] wl12xx: update fw api

On Mon, Jan 30, 2012 at 3:29 PM, Kalle Valo <[email protected]> wrote:
> Eliad Peller <[email protected]> writes:
>
>> The fw api was changed in the latest FWs (6.3.5.0.95 for wl127x
>> and 7.3.5.0.95 for wl128x).
>>
>> Along with some small adjustments, the main changes
>> inroduced by this patheset are configuring the
>> templates per-role, and moving to IEEE80211_HW_SUPPORTS_DYNAMIC_PS
>> mode.
>
> I didn't look so carefully, but doesn't this break bisect? I mean if you
> change the firmware api in small patches wl12xx can't work properly
> until all patches are applied, right?
>
> I would say that a huge patch doing all the necessary changes in one go
> is better, even it's ugly.
>
yes. it will break bisect (although it shouldn't break compilations).
i guess it's a matter of taste, but i think keeping the patches
manageable is more important than being able to bisect.

Eliad.

2012-01-31 07:50:07

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH 00/12] wl12xx: update fw api

Eliad Peller <[email protected]> writes:

> On Mon, Jan 30, 2012 at 3:29 PM, Kalle Valo <[email protected]> wrote:
>> Eliad Peller <[email protected]> writes:
>>
>>> The fw api was changed in the latest FWs (6.3.5.0.95 for wl127x
>>> and 7.3.5.0.95 for wl128x).
>>>
>>> Along with some small adjustments, the main changes
>>> inroduced by this patheset are configuring the
>>> templates per-role, and moving to IEEE80211_HW_SUPPORTS_DYNAMIC_PS
>>> mode.
>>
>> I didn't look so carefully, but doesn't this break bisect? I mean if you
>> change the firmware api in small patches wl12xx can't work properly
>> until all patches are applied, right?
>>
>> I would say that a huge patch doing all the necessary changes in one go
>> is better, even it's ugly.
>>
> yes. it will break bisect (although it shouldn't break compilations).
> i guess it's a matter of taste, but i think keeping the patches
> manageable is more important than being able to bisect.

Yeah, it's just matter of taste. It's easy to skip commits during bisect
but someone not familiar with wl12xx does not know what commits to
skip and that will cause problems.

But I don't care how you do it, I just wanted to point out this aspect :)

--
Kalle Valo

2012-01-30 11:57:55

by Eliad Peller

[permalink] [raw]
Subject: [PATCH 10/12] wl12xx: remove 2 unused parameters in wl1271_ps_set_mode()

From: Eyal Shapira <[email protected]>

cleanup 2 unused parameters of wl1271_ps_set_mode

Signed-off-by: Eyal Shapira <[email protected]>
Signed-off-by: Eliad Peller <[email protected]>
---
drivers/net/wireless/wl12xx/debugfs.c | 4 +---
drivers/net/wireless/wl12xx/main.c | 10 +++-------
drivers/net/wireless/wl12xx/ps.c | 2 +-
drivers/net/wireless/wl12xx/ps.h | 2 +-
4 files changed, 6 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c
index 156a774..4436851 100644
--- a/drivers/net/wireless/wl12xx/debugfs.c
+++ b/drivers/net/wireless/wl12xx/debugfs.c
@@ -359,9 +359,7 @@ static ssize_t dynamic_ps_timeout_write(struct file *file,

wl12xx_for_each_wlvif_sta(wl, wlvif) {
if (test_bit(WLVIF_FLAG_PSM, &wlvif->flags))
- wl1271_ps_set_mode(wl, wlvif, STATION_AUTO_PS_MODE,
- wlvif->basic_rate, true);
-
+ wl1271_ps_set_mode(wl, wlvif, STATION_AUTO_PS_MODE);
}

wl1271_ps_elp_sleep(wl);
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 2b6dda5..21841d4 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -2444,8 +2444,7 @@ static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif,
if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) {
wl1271_debug(DEBUG_PSM, "psm enabled");
ret = wl1271_ps_set_mode(wl, wlvif,
- STATION_POWER_SAVE_MODE,
- wlvif->basic_rate, true);
+ STATION_AUTO_PS_MODE);
}
} else if (!(conf->flags & IEEE80211_CONF_PS) &&
test_bit(WLVIF_FLAG_PSM_REQUESTED, &wlvif->flags)) {
@@ -2455,8 +2454,7 @@ static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif,

if (test_bit(WLVIF_FLAG_PSM, &wlvif->flags))
ret = wl1271_ps_set_mode(wl, wlvif,
- STATION_ACTIVE_MODE,
- wlvif->basic_rate, true);
+ STATION_ACTIVE_MODE);
}

if (conf->power_level != wlvif->power_level) {
@@ -3796,9 +3794,7 @@ sta_not_found:
!test_bit(WLVIF_FLAG_PSM, &wlvif->flags)) {

ret = wl1271_ps_set_mode(wl, wlvif,
- STATION_AUTO_PS_MODE,
- wlvif->basic_rate,
- true);
+ STATION_AUTO_PS_MODE);
if (ret < 0)
goto out;
}
diff --git a/drivers/net/wireless/wl12xx/ps.c b/drivers/net/wireless/wl12xx/ps.c
index 60f03c4..5074c2a 100644
--- a/drivers/net/wireless/wl12xx/ps.c
+++ b/drivers/net/wireless/wl12xx/ps.c
@@ -160,7 +160,7 @@ out:
}

int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- enum wl1271_cmd_ps_mode mode, u32 rates, bool send)
+ enum wl1271_cmd_ps_mode mode)
{
int ret;
u16 timeout = wl->conf.conn.dynamic_ps_timeout;
diff --git a/drivers/net/wireless/wl12xx/ps.h b/drivers/net/wireless/wl12xx/ps.h
index a12052f..5f19d4f 100644
--- a/drivers/net/wireless/wl12xx/ps.h
+++ b/drivers/net/wireless/wl12xx/ps.h
@@ -28,7 +28,7 @@
#include "acx.h"

int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- enum wl1271_cmd_ps_mode mode, u32 rates, bool send);
+ enum wl1271_cmd_ps_mode mode);
void wl1271_ps_elp_sleep(struct wl1271 *wl);
int wl1271_ps_elp_wakeup(struct wl1271 *wl);
void wl1271_elp_work(struct work_struct *work);
--
1.7.6.401.g6a319


2012-01-30 11:57:56

by Eliad Peller

[permalink] [raw]
Subject: [PATCH 11/12] wl12xx: enable/disable BET with AUTO_PS/ACTIVE

From: Eyal Shapira <[email protected]>

While the FW with dynamic PS controls BET when going to PSM and back
internally within the FW, there's still a need to enable it from the driver
at least once (so enable on every entry to AUTO_PS)
and disable it once we explicitly go back to STATION_ACTIVE_MODE.
BET isn't relevant for 5GHz

Signed-off-by: Eyal Shapira <[email protected]>
Signed-off-by: Eliad Peller <[email protected]>
---
drivers/net/wireless/wl12xx/ps.c | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/ps.c b/drivers/net/wireless/wl12xx/ps.c
index 5074c2a..d7a91d3 100644
--- a/drivers/net/wireless/wl12xx/ps.c
+++ b/drivers/net/wireless/wl12xx/ps.c
@@ -181,6 +181,13 @@ int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
return ret;

set_bit(WLVIF_FLAG_PSM, &wlvif->flags);
+
+ /* enable beacon early termination. Not relevant for 5GHz */
+ if (wlvif->band == IEEE80211_BAND_2GHZ) {
+ ret = wl1271_acx_bet_enable(wl, wlvif, true);
+ if (ret < 0)
+ return ret;
+ }
break;
case STATION_ACTIVE_MODE:
wl1271_debug(DEBUG_PSM, "leaving psm");
--
1.7.6.401.g6a319


2012-01-30 11:57:45

by Eliad Peller

[permalink] [raw]
Subject: [PATCH 05/12] wl12xx: fw api change - update cmd/acx/event enums

Update enums/structs to the new fw api.

Signed-off-by: Eliad Peller <[email protected]>
---
drivers/net/wireless/wl12xx/acx.h | 137 ++++++++++++++++++-----------------
drivers/net/wireless/wl12xx/boot.c | 2 +-
drivers/net/wireless/wl12xx/cmd.c | 2 +-
drivers/net/wireless/wl12xx/cmd.h | 105 ++++++++++++++-------------
drivers/net/wireless/wl12xx/event.h | 15 +++--
5 files changed, 135 insertions(+), 126 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h
index a5bf761..0749df5 100644
--- a/drivers/net/wireless/wl12xx/acx.h
+++ b/drivers/net/wireless/wl12xx/acx.h
@@ -1153,74 +1153,75 @@ struct wl12xx_acx_config_hangover {
} __packed;

enum {
- ACX_WAKE_UP_CONDITIONS = 0x0002,
- ACX_MEM_CFG = 0x0003,
- ACX_SLOT = 0x0004,
- ACX_AC_CFG = 0x0007,
- ACX_MEM_MAP = 0x0008,
- ACX_AID = 0x000A,
- ACX_MEDIUM_USAGE = 0x000F,
- ACX_TX_QUEUE_CFG = 0x0011, /* FIXME: only used by wl1251 */
- ACX_STATISTICS = 0x0013, /* Debug API */
- ACX_PWR_CONSUMPTION_STATISTICS = 0x0014,
- ACX_FEATURE_CFG = 0x0015,
- ACX_TID_CFG = 0x001A,
- ACX_PS_RX_STREAMING = 0x001B,
- ACX_BEACON_FILTER_OPT = 0x001F,
- ACX_NOISE_HIST = 0x0021,
- ACX_HDK_VERSION = 0x0022, /* ??? */
- ACX_PD_THRESHOLD = 0x0023,
- ACX_TX_CONFIG_OPT = 0x0024,
- ACX_CCA_THRESHOLD = 0x0025,
- ACX_EVENT_MBOX_MASK = 0x0026,
- ACX_CONN_MONIT_PARAMS = 0x002D,
- ACX_BCN_DTIM_OPTIONS = 0x0031,
- ACX_SG_ENABLE = 0x0032,
- ACX_SG_CFG = 0x0033,
- ACX_FM_COEX_CFG = 0x0034,
- ACX_BEACON_FILTER_TABLE = 0x0038,
- ACX_ARP_IP_FILTER = 0x0039,
- ACX_ROAMING_STATISTICS_TBL = 0x003B,
- ACX_RATE_POLICY = 0x003D,
- ACX_CTS_PROTECTION = 0x003E,
- ACX_SLEEP_AUTH = 0x003F,
- ACX_PREAMBLE_TYPE = 0x0040,
- ACX_ERROR_CNT = 0x0041,
- ACX_IBSS_FILTER = 0x0044,
- ACX_SERVICE_PERIOD_TIMEOUT = 0x0045,
- ACX_TSF_INFO = 0x0046,
- ACX_CONFIG_PS_WMM = 0x0049,
- ACX_ENABLE_RX_DATA_FILTER = 0x004A,
- ACX_SET_RX_DATA_FILTER = 0x004B,
- ACX_GET_DATA_FILTER_STATISTICS = 0x004C,
- ACX_RX_CONFIG_OPT = 0x004E,
- ACX_FRAG_CFG = 0x004F,
- ACX_BET_ENABLE = 0x0050,
- ACX_RSSI_SNR_TRIGGER = 0x0051,
- ACX_RSSI_SNR_WEIGHTS = 0x0052,
- ACX_KEEP_ALIVE_MODE = 0x0053,
- ACX_SET_KEEP_ALIVE_CONFIG = 0x0054,
- ACX_BA_SESSION_INIT_POLICY = 0x0055,
- ACX_BA_SESSION_RX_SETUP = 0x0056,
- ACX_PEER_HT_CAP = 0x0057,
- ACX_HT_BSS_OPERATION = 0x0058,
- ACX_COEX_ACTIVITY = 0x0059,
- ACX_BURST_MODE = 0x005C,
- ACX_SET_RATE_MGMT_PARAMS = 0x005D,
- ACX_SET_RATE_ADAPT_PARAMS = 0x0060,
- ACX_SET_DCO_ITRIM_PARAMS = 0x0061,
- ACX_GEN_FW_CMD = 0x0070,
- ACX_HOST_IF_CFG_BITMAP = 0x0071,
- ACX_MAX_TX_FAILURE = 0x0072,
- ACX_UPDATE_INCONNECTION_STA_LIST = 0x0073,
- DOT11_RX_MSDU_LIFE_TIME = 0x1004,
- DOT11_CUR_TX_PWR = 0x100D,
- DOT11_RX_DOT11_MODE = 0x1012,
- DOT11_RTS_THRESHOLD = 0x1013,
- DOT11_GROUP_ADDRESS_TBL = 0x1014,
- ACX_PM_CONFIG = 0x1016,
- ACX_CONFIG_PS = 0x1017,
- ACX_CONFIG_HANGOVER = 0x1018,
+ ACX_WAKE_UP_CONDITIONS = 0x0000,
+ ACX_MEM_CFG = 0x0001,
+ ACX_SLOT = 0x0002,
+ ACX_AC_CFG = 0x0003,
+ ACX_MEM_MAP = 0x0004,
+ ACX_AID = 0x0005,
+ ACX_MEDIUM_USAGE = 0x0006,
+ ACX_STATISTICS = 0x0007,
+ ACX_PWR_CONSUMPTION_STATISTICS = 0x0008,
+ ACX_TID_CFG = 0x0009,
+ ACX_PS_RX_STREAMING = 0x000A,
+ ACX_BEACON_FILTER_OPT = 0x000B,
+ ACX_NOISE_HIST = 0x000C,
+ ACX_HDK_VERSION = 0x000D,
+ ACX_PD_THRESHOLD = 0x000E,
+ ACX_TX_CONFIG_OPT = 0x000F,
+ ACX_CCA_THRESHOLD = 0x0010,
+ ACX_EVENT_MBOX_MASK = 0x0011,
+ ACX_CONN_MONIT_PARAMS = 0x0012,
+ ACX_DISABLE_BROADCASTS = 0x0013,
+ ACX_BCN_DTIM_OPTIONS = 0x0014,
+ ACX_SG_ENABLE = 0x0015,
+ ACX_SG_CFG = 0x0016,
+ ACX_FM_COEX_CFG = 0x0017,
+ ACX_BEACON_FILTER_TABLE = 0x0018,
+ ACX_ARP_IP_FILTER = 0x0019,
+ ACX_ROAMING_STATISTICS_TBL = 0x001A,
+ ACX_RATE_POLICY = 0x001B,
+ ACX_CTS_PROTECTION = 0x001C,
+ ACX_SLEEP_AUTH = 0x001D,
+ ACX_PREAMBLE_TYPE = 0x001E,
+ ACX_ERROR_CNT = 0x001F,
+ ACX_IBSS_FILTER = 0x0020,
+ ACX_SERVICE_PERIOD_TIMEOUT = 0x0021,
+ ACX_TSF_INFO = 0x0022,
+ ACX_CONFIG_PS_WMM = 0x0023,
+ ACX_ENABLE_RX_DATA_FILTER = 0x0024,
+ ACX_SET_RX_DATA_FILTER = 0x0025,
+ ACX_GET_DATA_FILTER_STATISTICS = 0x0026,
+ ACX_RX_CONFIG_OPT = 0x0027,
+ ACX_FRAG_CFG = 0x0028,
+ ACX_BET_ENABLE = 0x0029,
+ ACX_RSSI_SNR_TRIGGER = 0x002A,
+ ACX_RSSI_SNR_WEIGHTS = 0x002B,
+ ACX_KEEP_ALIVE_MODE = 0x002C,
+ ACX_SET_KEEP_ALIVE_CONFIG = 0x002D,
+ ACX_BA_SESSION_INIT_POLICY = 0x002E,
+ ACX_BA_SESSION_RX_SETUP = 0x002F,
+ ACX_PEER_HT_CAP = 0x0030,
+ ACX_HT_BSS_OPERATION = 0x0031,
+ ACX_COEX_ACTIVITY = 0x0032,
+ ACX_BURST_MODE = 0x0033,
+ ACX_SET_RATE_MGMT_PARAMS = 0x0034,
+ ACX_GET_RATE_MGMT_PARAMS = 0x0035,
+ ACX_SET_RATE_ADAPT_PARAMS = 0x0036,
+ ACX_SET_DCO_ITRIM_PARAMS = 0x0037,
+ ACX_GEN_FW_CMD = 0x0038,
+ ACX_HOST_IF_CFG_BITMAP = 0x0039,
+ ACX_MAX_TX_FAILURE = 0x003A,
+ ACX_UPDATE_INCONNECTION_STA_LIST = 0x003B,
+ DOT11_RX_MSDU_LIFE_TIME = 0x003C,
+ DOT11_CUR_TX_PWR = 0x003D,
+ DOT11_RTS_THRESHOLD = 0x003E,
+ DOT11_GROUP_ADDRESS_TBL = 0x003F,
+ ACX_PM_CONFIG = 0x0040,
+ ACX_CONFIG_PS = 0x0041,
+ ACX_CONFIG_HANGOVER = 0x0042,
+ ACX_FEATURE_CFG = 0x0043,
+ ACX_PROTECTION_CFG = 0x0044,
};


diff --git a/drivers/net/wireless/wl12xx/boot.c b/drivers/net/wireless/wl12xx/boot.c
index 8f9cf5a..7843028 100644
--- a/drivers/net/wireless/wl12xx/boot.c
+++ b/drivers/net/wireless/wl12xx/boot.c
@@ -508,7 +508,7 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl)
wl->event_mask = BSS_LOSE_EVENT_ID |
SCAN_COMPLETE_EVENT_ID |
PS_REPORT_EVENT_ID |
- DISCONNECT_EVENT_COMPLETE_ID |
+ ROLE_STOP_COMPLETE_EVENT_ID |
RSSI_SNR_TRIGGER_0_EVENT_ID |
PSPOLL_DELIVERY_FAILURE_EVENT_ID |
SOFT_GEMINI_SENSE_EVENT_ID |
diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c
index 10dba19..c4990da 100644
--- a/drivers/net/wireless/wl12xx/cmd.c
+++ b/drivers/net/wireless/wl12xx/cmd.c
@@ -566,7 +566,7 @@ static int wl12xx_cmd_role_stop_dev(struct wl1271 *wl,
goto out_free;
}

- ret = wl1271_cmd_wait_for_event(wl, DISCONNECT_EVENT_COMPLETE_ID);
+ ret = wl1271_cmd_wait_for_event(wl, ROLE_STOP_COMPLETE_EVENT_ID);
if (ret < 0) {
wl1271_error("cmd role stop dev event completion error");
goto out_free;
diff --git a/drivers/net/wireless/wl12xx/cmd.h b/drivers/net/wireless/wl12xx/cmd.h
index 8e8035d..faf046b 100644
--- a/drivers/net/wireless/wl12xx/cmd.h
+++ b/drivers/net/wireless/wl12xx/cmd.h
@@ -98,62 +98,65 @@ int wl12xx_allocate_link(struct wl1271 *wl, struct wl12xx_vif *wlvif,
void wl12xx_free_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid);

enum wl1271_commands {
- CMD_INTERROGATE = 1, /*use this to read information elements*/
- CMD_CONFIGURE = 2, /*use this to write information elements*/
- CMD_ENABLE_RX = 3,
- CMD_ENABLE_TX = 4,
- CMD_DISABLE_RX = 5,
- CMD_DISABLE_TX = 6,
- CMD_SCAN = 8,
- CMD_STOP_SCAN = 9,
- CMD_SET_KEYS = 12,
- CMD_READ_MEMORY = 13,
- CMD_WRITE_MEMORY = 14,
- CMD_SET_TEMPLATE = 19,
- CMD_TEST = 23,
- CMD_NOISE_HIST = 28,
- CMD_QUIET_ELEMENT_SET_STATE = 29,
- CMD_SET_BCN_MODE = 33,
- CMD_MEASUREMENT = 34,
- CMD_STOP_MEASUREMENT = 35,
- CMD_SET_PS_MODE = 37,
- CMD_CHANNEL_SWITCH = 38,
- CMD_STOP_CHANNEL_SWICTH = 39,
- CMD_AP_DISCOVERY = 40,
- CMD_STOP_AP_DISCOVERY = 41,
- CMD_HEALTH_CHECK = 45,
- CMD_DEBUG = 46,
- CMD_TRIGGER_SCAN_TO = 47,
- CMD_CONNECTION_SCAN_CFG = 48,
- CMD_CONNECTION_SCAN_SSID_CFG = 49,
- CMD_START_PERIODIC_SCAN = 50,
- CMD_STOP_PERIODIC_SCAN = 51,
- CMD_SET_PEER_STATE = 52,
- CMD_REMAIN_ON_CHANNEL = 53,
- CMD_CANCEL_REMAIN_ON_CHANNEL = 54,
-
- CMD_CONFIG_FWLOGGER = 55,
- CMD_START_FWLOGGER = 56,
- CMD_STOP_FWLOGGER = 57,
-
- /* AP commands */
- CMD_ADD_PEER = 62,
- CMD_REMOVE_PEER = 63,
+ CMD_INTERROGATE = 1, /* use this to read information elements */
+ CMD_CONFIGURE = 2, /* use this to write information elements */
+ CMD_ENABLE_RX = 3,
+ CMD_ENABLE_TX = 4,
+ CMD_DISABLE_RX = 5,
+ CMD_DISABLE_TX = 6,
+ CMD_SCAN = 7,
+ CMD_STOP_SCAN = 8,
+ CMD_SET_KEYS = 9,
+ CMD_READ_MEMORY = 10,
+ CMD_WRITE_MEMORY = 11,
+ CMD_SET_TEMPLATE = 12,
+ CMD_TEST = 13,
+ CMD_NOISE_HIST = 14,
+ CMD_QUIET_ELEMENT_SET_STATE = 15,
+ CMD_SET_BCN_MODE = 16,
+
+ CMD_MEASUREMENT = 17,
+ CMD_STOP_MEASUREMENT = 18,
+ CMD_SET_PS_MODE = 19,
+ CMD_CHANNEL_SWITCH = 20,
+ CMD_STOP_CHANNEL_SWICTH = 21,
+ CMD_AP_DISCOVERY = 22,
+ CMD_STOP_AP_DISCOVERY = 23,
+ CMD_HEALTH_CHECK = 24,
+ CMD_DEBUG = 25,
+ CMD_TRIGGER_SCAN_TO = 26,
+ CMD_CONNECTION_SCAN_CFG = 27,
+ CMD_CONNECTION_SCAN_SSID_CFG = 28,
+ CMD_START_PERIODIC_SCAN = 29,
+ CMD_STOP_PERIODIC_SCAN = 30,
+ CMD_SET_PEER_STATE = 31,
+ CMD_REMAIN_ON_CHANNEL = 32,
+ CMD_CANCEL_REMAIN_ON_CHANNEL = 33,
+ CMD_CONFIG_FWLOGGER = 34,
+ CMD_START_FWLOGGER = 35,
+ CMD_STOP_FWLOGGER = 36,
+
+ /* Access point commands */
+ CMD_ADD_PEER = 37,
+ CMD_REMOVE_PEER = 38,

/* Role API */
- CMD_ROLE_ENABLE = 70,
- CMD_ROLE_DISABLE = 71,
- CMD_ROLE_START = 72,
- CMD_ROLE_STOP = 73,
+ CMD_ROLE_ENABLE = 39,
+ CMD_ROLE_DISABLE = 40,
+ CMD_ROLE_START = 41,
+ CMD_ROLE_STOP = 42,

- /* WIFI Direct */
- CMD_WFD_START_DISCOVERY = 80,
- CMD_WFD_STOP_DISCOVERY = 81,
- CMD_WFD_ATTRIBUTE_CONFIG = 82,
+ /* DFS */
+ CMD_START_RADAR_DETECTION = 43,
+ CMD_STOP_RADAR_DETECTION = 44,

- CMD_NOP = 100,
+ /* WIFI Direct */
+ CMD_WFD_START_DISCOVERY = 45,
+ CMD_WFD_STOP_DISCOVERY = 46,
+ CMD_WFD_ATTRIBUTE_CONFIG = 47,
+ CMD_NOP = 48,
+ CMD_LAST_COMMAND,

- NUM_COMMANDS,
MAX_COMMAND_ID = 0xFFFF,
};

diff --git a/drivers/net/wireless/wl12xx/event.h b/drivers/net/wireless/wl12xx/event.h
index 1d878ba..b41f730 100644
--- a/drivers/net/wireless/wl12xx/event.h
+++ b/drivers/net/wireless/wl12xx/event.h
@@ -53,8 +53,8 @@ enum {
AP_DISCOVERY_COMPLETE_EVENT_ID = BIT(12),
PS_REPORT_EVENT_ID = BIT(13),
PSPOLL_DELIVERY_FAILURE_EVENT_ID = BIT(14),
- DISCONNECT_EVENT_COMPLETE_ID = BIT(15),
- /* BIT(16) is reserved */
+ ROLE_STOP_COMPLETE_EVENT_ID = BIT(15),
+ RADAR_DETECTED_EVENT_ID = BIT(16),
CHANNEL_SWITCH_COMPLETE_EVENT_ID = BIT(17),
BSS_LOSE_EVENT_ID = BIT(18),
REGAINED_BSS_EVENT_ID = BIT(19),
@@ -94,7 +94,7 @@ struct event_mailbox {
u8 soft_gemini_sense_info;
u8 soft_gemini_protective_info;
s8 rssi_snr_trigger_metric[NUM_OF_RSSI_SNR_TRIGGERS];
- u8 channel_switch_status;
+ u8 change_auto_mode_timeout;
u8 scheduled_scan_status;
u8 ps_status;
/* tuned channel (roc) */
@@ -119,12 +119,17 @@ struct event_mailbox {
u8 rx_ba_allowed;
u8 reserved_6[2];

+ /* Channel switch results */
+
+ u8 channel_switch_role_id;
+ u8 channel_switch_status;
+ u8 reserved_7[2];
+
u8 ps_poll_delivery_failure_role_ids;
u8 stopped_role_ids;
u8 started_role_ids;
- u8 change_auto_mode_timeout;

- u8 reserved_7[12];
+ u8 reserved_8[9];
} __packed;

int wl1271_event_unmask(struct wl1271 *wl);
--
1.7.6.401.g6a319


2012-01-30 11:57:38

by Eliad Peller

[permalink] [raw]
Subject: [PATCH 01/12] wl12xx: fw api change - add role_id to set_template

The set_template commands now takes the role_id as
parameter.

Usually, we'll use the vif's main role_id.
However, sometimes we'll want to use
wlvif->dev_role_id instead of wlvif->role_id,
so pass the wanted role_id as param.

Update WL127X_FW_NAME/WL128X_FW_NAME.

Signed-off-by: Eliad Peller <[email protected]>
---
drivers/net/wireless/wl12xx/cmd.c | 37 ++++++++++++++++++----------
drivers/net/wireless/wl12xx/cmd.h | 18 +++++++++----
drivers/net/wireless/wl12xx/init.c | 45 ++++++++++++++++++++++-----------
drivers/net/wireless/wl12xx/main.c | 11 ++++----
drivers/net/wireless/wl12xx/scan.c | 28 +++++++++++++--------
drivers/net/wireless/wl12xx/wl12xx.h | 4 +-
6 files changed, 91 insertions(+), 52 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c
index 25990bd..28e0a56 100644
--- a/drivers/net/wireless/wl12xx/cmd.c
+++ b/drivers/net/wireless/wl12xx/cmd.c
@@ -1022,8 +1022,9 @@ out:
return ret;
}

-int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
- void *buf, size_t buf_len, int index, u32 rates)
+int wl1271_cmd_template_set(struct wl1271 *wl, u8 role_id,
+ u16 template_id, void *buf, size_t buf_len,
+ int index, u32 rates)
{
struct wl1271_cmd_template_set *cmd;
int ret = 0;
@@ -1039,6 +1040,8 @@ int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
goto out;
}

+ /* during initialization wlvif is NULL */
+ cmd->role_id = role_id;
cmd->len = cpu_to_le16(buf_len);
cmd->template_type = template_id;
cmd->enabled_rates = cpu_to_le32(rates);
@@ -1082,7 +1085,8 @@ int wl12xx_cmd_build_null_data(struct wl1271 *wl, struct wl12xx_vif *wlvif)
ptr = skb->data;
}

- ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, ptr, size, 0,
+ ret = wl1271_cmd_template_set(wl, wlvif->role_id,
+ CMD_TEMPL_NULL_DATA, ptr, size, 0,
wlvif->basic_rate);

out:
@@ -1105,7 +1109,7 @@ int wl12xx_cmd_build_klv_null_data(struct wl1271 *wl,
if (!skb)
goto out;

- ret = wl1271_cmd_template_set(wl, CMD_TEMPL_KLV,
+ ret = wl1271_cmd_template_set(wl, wlvif->role_id, CMD_TEMPL_KLV,
skb->data, skb->len,
CMD_TEMPL_KLV_IDX_NULL_DATA,
wlvif->basic_rate);
@@ -1130,7 +1134,8 @@ int wl1271_cmd_build_ps_poll(struct wl1271 *wl, struct wl12xx_vif *wlvif,
if (!skb)
goto out;

- ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, skb->data,
+ ret = wl1271_cmd_template_set(wl, wlvif->role_id,
+ CMD_TEMPL_PS_POLL, skb->data,
skb->len, 0, wlvif->basic_rate_set);

out:
@@ -1138,9 +1143,10 @@ out:
return ret;
}

-int wl1271_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif,
+int wl12xx_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif,
+ u8 role_id, u8 band,
const u8 *ssid, size_t ssid_len,
- const u8 *ie, size_t ie_len, u8 band)
+ const u8 *ie, size_t ie_len)
{
struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
struct sk_buff *skb;
@@ -1158,10 +1164,12 @@ int wl1271_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif,

rate = wl1271_tx_min_rate_get(wl, wlvif->bitrate_masks[band]);
if (band == IEEE80211_BAND_2GHZ)
- ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4,
+ ret = wl1271_cmd_template_set(wl, role_id,
+ CMD_TEMPL_CFG_PROBE_REQ_2_4,
skb->data, skb->len, 0, rate);
else
- ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
+ ret = wl1271_cmd_template_set(wl, role_id,
+ CMD_TEMPL_CFG_PROBE_REQ_5,
skb->data, skb->len, 0, rate);

out:
@@ -1186,10 +1194,12 @@ struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl,

rate = wl1271_tx_min_rate_get(wl, wlvif->bitrate_masks[wlvif->band]);
if (wlvif->band == IEEE80211_BAND_2GHZ)
- ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4,
+ ret = wl1271_cmd_template_set(wl, wlvif->role_id,
+ CMD_TEMPL_CFG_PROBE_REQ_2_4,
skb->data, skb->len, 0, rate);
else
- ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
+ ret = wl1271_cmd_template_set(wl, wlvif->role_id,
+ CMD_TEMPL_CFG_PROBE_REQ_5,
skb->data, skb->len, 0, rate);

if (ret < 0)
@@ -1235,7 +1245,7 @@ int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, struct wl12xx_vif *wlvif,
memcpy(tmpl.sender_hw, vif->addr, ETH_ALEN);
tmpl.sender_ip = ip_addr;

- ret = wl1271_cmd_template_set(wl, CMD_TEMPL_ARP_RSP,
+ ret = wl1271_cmd_template_set(wl, wlvif->role_id, CMD_TEMPL_ARP_RSP,
&tmpl, sizeof(tmpl), 0,
wlvif->basic_rate);

@@ -1260,7 +1270,8 @@ int wl1271_build_qos_null_data(struct wl1271 *wl, struct ieee80211_vif *vif)
/* FIXME: not sure what priority to use here */
template.qos_ctrl = cpu_to_le16(0);

- return wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, &template,
+ return wl1271_cmd_template_set(wl, wlvif->role_id,
+ CMD_TEMPL_QOS_NULL_DATA, &template,
sizeof(template), 0,
wlvif->basic_rate);
}
diff --git a/drivers/net/wireless/wl12xx/cmd.h b/drivers/net/wireless/wl12xx/cmd.h
index 3f7d0b9..8e8035d 100644
--- a/drivers/net/wireless/wl12xx/cmd.h
+++ b/drivers/net/wireless/wl12xx/cmd.h
@@ -54,14 +54,16 @@ int wl1271_cmd_ps_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
u8 ps_mode);
int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer,
size_t len);
-int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
- void *buf, size_t buf_len, int index, u32 rates);
+int wl1271_cmd_template_set(struct wl1271 *wl, u8 role_id,
+ u16 template_id, void *buf, size_t buf_len,
+ int index, u32 rates);
int wl12xx_cmd_build_null_data(struct wl1271 *wl, struct wl12xx_vif *wlvif);
int wl1271_cmd_build_ps_poll(struct wl1271 *wl, struct wl12xx_vif *wlvif,
u16 aid);
-int wl1271_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif,
+int wl12xx_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif,
+ u8 role_id, u8 band,
const u8 *ssid, size_t ssid_len,
- const u8 *ie, size_t ie_len, u8 band);
+ const u8 *ie, size_t ie_len);
struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl,
struct wl12xx_vif *wlvif,
struct sk_buff *skb);
@@ -191,7 +193,7 @@ enum cmd_templ {
/* unit ms */
#define WL1271_COMMAND_TIMEOUT 2000
#define WL1271_CMD_TEMPL_DFLT_SIZE 252
-#define WL1271_CMD_TEMPL_MAX_SIZE 548
+#define WL1271_CMD_TEMPL_MAX_SIZE 512
#define WL1271_EVENT_TIMEOUT 750

struct wl1271_cmd_header {
@@ -364,14 +366,18 @@ struct cmd_enabledisable_path {
struct wl1271_cmd_template_set {
struct wl1271_cmd_header header;

- __le16 len;
+ u8 role_id;
u8 template_type;
+ __le16 len;
u8 index; /* relevant only for KLV_TEMPLATE type */
+ u8 padding[3];
+
__le32 enabled_rates;
u8 short_retry_limit;
u8 long_retry_limit;
u8 aflags;
u8 reserved;
+
u8 template_data[WL1271_CMD_TEMPL_MAX_SIZE];
} __packed;

diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c
index ca7ee59..fcf2b12 100644
--- a/drivers/net/wireless/wl12xx/init.c
+++ b/drivers/net/wireless/wl12xx/init.c
@@ -39,50 +39,58 @@ int wl1271_init_templates_config(struct wl1271 *wl)
int ret, i;

/* send empty templates for fw memory reservation */
- ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, NULL,
+ ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
+ CMD_TEMPL_CFG_PROBE_REQ_2_4, NULL,
WL1271_CMD_TEMPL_DFLT_SIZE,
0, WL1271_RATE_AUTOMATIC);
if (ret < 0)
return ret;

- ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
+ ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
+ CMD_TEMPL_CFG_PROBE_REQ_5,
NULL, WL1271_CMD_TEMPL_DFLT_SIZE, 0,
WL1271_RATE_AUTOMATIC);
if (ret < 0)
return ret;

- ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, NULL,
+ ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
+ CMD_TEMPL_NULL_DATA, NULL,
sizeof(struct wl12xx_null_data_template),
0, WL1271_RATE_AUTOMATIC);
if (ret < 0)
return ret;

- ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, NULL,
+ ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
+ CMD_TEMPL_PS_POLL, NULL,
sizeof(struct wl12xx_ps_poll_template),
0, WL1271_RATE_AUTOMATIC);
if (ret < 0)
return ret;

- ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, NULL,
+ ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
+ CMD_TEMPL_QOS_NULL_DATA, NULL,
sizeof
(struct ieee80211_qos_hdr),
0, WL1271_RATE_AUTOMATIC);
if (ret < 0)
return ret;

- ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PROBE_RESPONSE, NULL,
+ ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
+ CMD_TEMPL_PROBE_RESPONSE, NULL,
WL1271_CMD_TEMPL_DFLT_SIZE,
0, WL1271_RATE_AUTOMATIC);
if (ret < 0)
return ret;

- ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON, NULL,
+ ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
+ CMD_TEMPL_BEACON, NULL,
WL1271_CMD_TEMPL_DFLT_SIZE,
0, WL1271_RATE_AUTOMATIC);
if (ret < 0)
return ret;

- ret = wl1271_cmd_template_set(wl, CMD_TEMPL_ARP_RSP, NULL,
+ ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
+ CMD_TEMPL_ARP_RSP, NULL,
sizeof
(struct wl12xx_arp_rsp_template),
0, WL1271_RATE_AUTOMATIC);
@@ -93,19 +101,22 @@ int wl1271_init_templates_config(struct wl1271 *wl)
* Put very large empty placeholders for all templates. These
* reserve memory for later.
*/
- ret = wl1271_cmd_template_set(wl, CMD_TEMPL_AP_PROBE_RESPONSE, NULL,
+ ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
+ CMD_TEMPL_AP_PROBE_RESPONSE, NULL,
WL1271_CMD_TEMPL_MAX_SIZE,
0, WL1271_RATE_AUTOMATIC);
if (ret < 0)
return ret;

- ret = wl1271_cmd_template_set(wl, CMD_TEMPL_AP_BEACON, NULL,
+ ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
+ CMD_TEMPL_AP_BEACON, NULL,
WL1271_CMD_TEMPL_MAX_SIZE,
0, WL1271_RATE_AUTOMATIC);
if (ret < 0)
return ret;

- ret = wl1271_cmd_template_set(wl, CMD_TEMPL_DEAUTH_AP, NULL,
+ ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
+ CMD_TEMPL_DEAUTH_AP, NULL,
sizeof
(struct wl12xx_disconn_template),
0, WL1271_RATE_AUTOMATIC);
@@ -113,7 +124,8 @@ int wl1271_init_templates_config(struct wl1271 *wl)
return ret;

for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) {
- ret = wl1271_cmd_template_set(wl, CMD_TEMPL_KLV, NULL,
+ ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
+ CMD_TEMPL_KLV, NULL,
sizeof(struct ieee80211_qos_hdr),
i, WL1271_RATE_AUTOMATIC);
if (ret < 0)
@@ -140,7 +152,8 @@ static int wl1271_ap_init_deauth_template(struct wl1271 *wl,
IEEE80211_STYPE_DEAUTH);

rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
- ret = wl1271_cmd_template_set(wl, CMD_TEMPL_DEAUTH_AP,
+ ret = wl1271_cmd_template_set(wl, wlvif->role_id,
+ CMD_TEMPL_DEAUTH_AP,
tmpl, sizeof(*tmpl), 0, rate);

out:
@@ -172,7 +185,8 @@ static int wl1271_ap_init_null_template(struct wl1271 *wl,
memcpy(nullfunc->addr3, vif->addr, ETH_ALEN);

rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
- ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, nullfunc,
+ ret = wl1271_cmd_template_set(wl, wlvif->role_id,
+ CMD_TEMPL_NULL_DATA, nullfunc,
sizeof(*nullfunc), 0, rate);

out:
@@ -204,7 +218,8 @@ static int wl1271_ap_init_qos_null_template(struct wl1271 *wl,
memcpy(qosnull->addr3, vif->addr, ETH_ALEN);

rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
- ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, qosnull,
+ ret = wl1271_cmd_template_set(wl, wlvif->role_id,
+ CMD_TEMPL_QOS_NULL_DATA, qosnull,
sizeof(*qosnull), 0, rate);

out:
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 91c03d8..0509816 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -3271,6 +3271,7 @@ static void wl12xx_remove_vendor_ie(struct sk_buff *skb,
static int wl1271_ap_set_probe_resp_tmpl(struct wl1271 *wl, u32 rates,
struct ieee80211_vif *vif)
{
+ struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
struct sk_buff *skb;
int ret;

@@ -3278,7 +3279,7 @@ static int wl1271_ap_set_probe_resp_tmpl(struct wl1271 *wl, u32 rates,
if (!skb)
return -EOPNOTSUPP;

- ret = wl1271_cmd_template_set(wl,
+ ret = wl1271_cmd_template_set(wl, wlvif->role_id,
CMD_TEMPL_AP_PROBE_RESPONSE,
skb->data,
skb->len, 0,
@@ -3302,7 +3303,7 @@ static int wl1271_ap_set_probe_resp_tmpl_legacy(struct wl1271 *wl,

/* no need to change probe response if the SSID is set correctly */
if (wlvif->ssid_len > 0)
- return wl1271_cmd_template_set(wl,
+ return wl1271_cmd_template_set(wl, wlvif->role_id,
CMD_TEMPL_AP_PROBE_RESPONSE,
probe_rsp_data,
probe_rsp_len, 0,
@@ -3339,7 +3340,7 @@ static int wl1271_ap_set_probe_resp_tmpl_legacy(struct wl1271 *wl,
ptr, probe_rsp_len - (ptr - probe_rsp_data));
templ_len += probe_rsp_len - (ptr - probe_rsp_data);

- return wl1271_cmd_template_set(wl,
+ return wl1271_cmd_template_set(wl, wlvif->role_id,
CMD_TEMPL_AP_PROBE_RESPONSE,
probe_rsp_templ,
templ_len, 0,
@@ -3436,7 +3437,7 @@ static int wl1271_bss_beacon_info_changed(struct wl1271 *wl,
min_rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
tmpl_id = is_ap ? CMD_TEMPL_AP_BEACON :
CMD_TEMPL_BEACON;
- ret = wl1271_cmd_template_set(wl, tmpl_id,
+ ret = wl1271_cmd_template_set(wl, wlvif->role_id, tmpl_id,
beacon->data,
beacon->len, 0,
min_rate);
@@ -3475,7 +3476,7 @@ static int wl1271_bss_beacon_info_changed(struct wl1271 *wl,
beacon->len,
min_rate);
else
- ret = wl1271_cmd_template_set(wl,
+ ret = wl1271_cmd_template_set(wl, wlvif->role_id,
CMD_TEMPL_PROBE_RESPONSE,
beacon->data,
beacon->len, 0,
diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/wl12xx/scan.c
index e24111e..416ae91 100644
--- a/drivers/net/wireless/wl12xx/scan.c
+++ b/drivers/net/wireless/wl12xx/scan.c
@@ -217,9 +217,11 @@ static int wl1271_scan_send(struct wl1271 *wl, struct ieee80211_vif *vif,

memcpy(cmd->addr, vif->addr, ETH_ALEN);

- ret = wl1271_cmd_build_probe_req(wl, wlvif, wl->scan.ssid,
- wl->scan.ssid_len, wl->scan.req->ie,
- wl->scan.req->ie_len, band);
+ ret = wl12xx_cmd_build_probe_req(wl, wlvif,
+ wlvif->role_id, band,
+ wl->scan.ssid, wl->scan.ssid_len,
+ wl->scan.req->ie,
+ wl->scan.req->ie_len);
if (ret < 0) {
wl1271_error("PROBE request template failed");
goto out;
@@ -658,11 +660,13 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl,
}

if (!force_passive && cfg->active[0]) {
- ret = wl1271_cmd_build_probe_req(wl, wlvif, req->ssids[0].ssid,
+ u8 band = IEEE80211_BAND_2GHZ;
+ ret = wl12xx_cmd_build_probe_req(wl, wlvif,
+ wlvif->role_id, band,
+ req->ssids[0].ssid,
req->ssids[0].ssid_len,
- ies->ie[IEEE80211_BAND_2GHZ],
- ies->len[IEEE80211_BAND_2GHZ],
- IEEE80211_BAND_2GHZ);
+ ies->ie[band],
+ ies->len[band]);
if (ret < 0) {
wl1271_error("2.4GHz PROBE request template failed");
goto out;
@@ -670,11 +674,13 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl,
}

if (!force_passive && cfg->active[1]) {
- ret = wl1271_cmd_build_probe_req(wl, wlvif, req->ssids[0].ssid,
+ u8 band = IEEE80211_BAND_5GHZ;
+ ret = wl12xx_cmd_build_probe_req(wl, wlvif,
+ wlvif->role_id, band,
+ req->ssids[0].ssid,
req->ssids[0].ssid_len,
- ies->ie[IEEE80211_BAND_5GHZ],
- ies->len[IEEE80211_BAND_5GHZ],
- IEEE80211_BAND_5GHZ);
+ ies->ie[band],
+ ies->len[band]);
if (ret < 0) {
wl1271_error("5GHz PROBE request template failed");
goto out;
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
index b2b09cd..6e025ca 100644
--- a/drivers/net/wireless/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/wl12xx/wl12xx.h
@@ -35,8 +35,8 @@
#include "conf.h"
#include "ini.h"

-#define WL127X_FW_NAME "ti-connectivity/wl127x-fw-3.bin"
-#define WL128X_FW_NAME "ti-connectivity/wl128x-fw-3.bin"
+#define WL127X_FW_NAME "ti-connectivity/wl127x-fw-4-sr.bin"
+#define WL128X_FW_NAME "ti-connectivity/wl128x-fw-4-sr.bin"

/*
* wl127x and wl128x are using the same NVS file name. However, the
--
1.7.6.401.g6a319


2012-01-30 11:57:49

by Eliad Peller

[permalink] [raw]
Subject: [PATCH 07/12] wl12xx: remove PS management code

From: Eyal Shapira <[email protected]>

Removal of PS management code from the driver as PS
is handled by the FW (dynamic PS)

Signed-off-by: Eyal Shapira <[email protected]>
Signed-off-by: Eliad Peller <[email protected]>
---
drivers/net/wireless/wl12xx/boot.c | 1 -
drivers/net/wireless/wl12xx/conf.h | 7 --
drivers/net/wireless/wl12xx/debugfs.c | 1 -
drivers/net/wireless/wl12xx/event.c | 143 ---------------------------------
drivers/net/wireless/wl12xx/event.h | 5 +-
drivers/net/wireless/wl12xx/main.c | 81 +------------------
drivers/net/wireless/wl12xx/wl12xx.h | 6 --
7 files changed, 5 insertions(+), 239 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/boot.c b/drivers/net/wireless/wl12xx/boot.c
index 7843028..8e698c8 100644
--- a/drivers/net/wireless/wl12xx/boot.c
+++ b/drivers/net/wireless/wl12xx/boot.c
@@ -507,7 +507,6 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl)
/* unmask required mbox events */
wl->event_mask = BSS_LOSE_EVENT_ID |
SCAN_COMPLETE_EVENT_ID |
- PS_REPORT_EVENT_ID |
ROLE_STOP_COMPLETE_EVENT_ID |
RSSI_SNR_TRIGGER_0_EVENT_ID |
PSPOLL_DELIVERY_FAILURE_EVENT_ID |
diff --git a/drivers/net/wireless/wl12xx/conf.h b/drivers/net/wireless/wl12xx/conf.h
index 1bcfb01..47cf80f 100644
--- a/drivers/net/wireless/wl12xx/conf.h
+++ b/drivers/net/wireless/wl12xx/conf.h
@@ -868,13 +868,6 @@ struct conf_conn_settings {
u8 ps_poll_threshold;

/*
- * PS Poll failure recovery ACTIVE period length
- *
- * Range: u32 (ms)
- */
- u32 ps_poll_recovery_period;
-
- /*
* Configuration of signal average weights.
*/
struct conf_sig_weights sig_weights;
diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c
index 15eb3a9..5e96e05 100644
--- a/drivers/net/wireless/wl12xx/debugfs.c
+++ b/drivers/net/wireless/wl12xx/debugfs.c
@@ -471,7 +471,6 @@ static ssize_t vifs_state_read(struct file *file, char __user *user_buf,
VIF_STATE_PRINT_INT(default_key);
VIF_STATE_PRINT_INT(aid);
VIF_STATE_PRINT_INT(session_counter);
- VIF_STATE_PRINT_INT(ps_poll_failures);
VIF_STATE_PRINT_INT(psm_entry_retry);
VIF_STATE_PRINT_INT(power_level);
VIF_STATE_PRINT_INT(rssi_thold);
diff --git a/drivers/net/wireless/wl12xx/event.c b/drivers/net/wireless/wl12xx/event.c
index d3280df68..2ec5d21 100644
--- a/drivers/net/wireless/wl12xx/event.c
+++ b/drivers/net/wireless/wl12xx/event.c
@@ -30,133 +30,6 @@
#include "scan.h"
#include "wl12xx_80211.h"

-void wl1271_pspoll_work(struct work_struct *work)
-{
- struct ieee80211_vif *vif;
- struct wl12xx_vif *wlvif;
- struct delayed_work *dwork;
- struct wl1271 *wl;
- int ret;
-
- dwork = container_of(work, struct delayed_work, work);
- wlvif = container_of(dwork, struct wl12xx_vif, pspoll_work);
- vif = container_of((void *)wlvif, struct ieee80211_vif, drv_priv);
- wl = wlvif->wl;
-
- wl1271_debug(DEBUG_EVENT, "pspoll work");
-
- mutex_lock(&wl->mutex);
-
- if (unlikely(wl->state == WL1271_STATE_OFF))
- goto out;
-
- if (!test_and_clear_bit(WLVIF_FLAG_PSPOLL_FAILURE, &wlvif->flags))
- goto out;
-
- if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
- goto out;
-
- /*
- * if we end up here, then we were in powersave when the pspoll
- * delivery failure occurred, and no-one changed state since, so
- * we should go back to powersave.
- */
- ret = wl1271_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out;
-
- wl1271_ps_set_mode(wl, wlvif, STATION_POWER_SAVE_MODE,
- wlvif->basic_rate, true);
-
- wl1271_ps_elp_sleep(wl);
-out:
- mutex_unlock(&wl->mutex);
-};
-
-static void wl1271_event_pspoll_delivery_fail(struct wl1271 *wl,
- struct wl12xx_vif *wlvif)
-{
- int delay = wl->conf.conn.ps_poll_recovery_period;
- int ret;
-
- wlvif->ps_poll_failures++;
- if (wlvif->ps_poll_failures == 1)
- wl1271_info("AP with dysfunctional ps-poll, "
- "trying to work around it.");
-
- /* force active mode receive data from the AP */
- if (test_bit(WLVIF_FLAG_PSM, &wlvif->flags)) {
- ret = wl1271_ps_set_mode(wl, wlvif, STATION_ACTIVE_MODE,
- wlvif->basic_rate, true);
- if (ret < 0)
- return;
- set_bit(WLVIF_FLAG_PSPOLL_FAILURE, &wlvif->flags);
- ieee80211_queue_delayed_work(wl->hw, &wlvif->pspoll_work,
- msecs_to_jiffies(delay));
- }
-
- /*
- * If already in active mode, lets we should be getting data from
- * the AP right away. If we enter PSM too fast after this, and data
- * remains on the AP, we will get another event like this, and we'll
- * go into active once more.
- */
-}
-
-static int wl1271_event_ps_report(struct wl1271 *wl,
- struct wl12xx_vif *wlvif,
- struct event_mailbox *mbox,
- bool *beacon_loss)
-{
- int ret = 0;
- u32 total_retries = wl->conf.conn.psm_entry_retries;
-
- wl1271_debug(DEBUG_EVENT, "ps_status: 0x%x", mbox->ps_status);
-
- switch (mbox->ps_status) {
- case EVENT_ENTER_POWER_SAVE_FAIL:
- wl1271_debug(DEBUG_PSM, "PSM entry failed");
-
- if (!test_bit(WLVIF_FLAG_PSM, &wlvif->flags)) {
- /* remain in active mode */
- wlvif->psm_entry_retry = 0;
- break;
- }
-
- if (wlvif->psm_entry_retry < total_retries) {
- wlvif->psm_entry_retry++;
- ret = wl1271_ps_set_mode(wl, wlvif,
- STATION_POWER_SAVE_MODE,
- wlvif->basic_rate, true);
- } else {
- wl1271_info("No ack to nullfunc from AP.");
- wlvif->psm_entry_retry = 0;
- *beacon_loss = true;
- }
- break;
- case EVENT_ENTER_POWER_SAVE_SUCCESS:
- wlvif->psm_entry_retry = 0;
-
- /*
- * BET has only a minor effect in 5GHz and masks
- * channel switch IEs, so we only enable BET on 2.4GHz
- */
- if (wlvif->band == IEEE80211_BAND_2GHZ)
- /* enable beacon early termination */
- ret = wl1271_acx_bet_enable(wl, wlvif, true);
-
- if (wlvif->ps_compl) {
- complete(wlvif->ps_compl);
- wlvif->ps_compl = NULL;
- }
- break;
- default:
- break;
- }
-
- return ret;
-}
-
static void wl1271_event_rssi_trigger(struct wl1271 *wl,
struct wl12xx_vif *wlvif,
struct event_mailbox *mbox)
@@ -237,7 +110,6 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
{
struct ieee80211_vif *vif;
struct wl12xx_vif *wlvif;
- int ret;
u32 vector;
bool beacon_loss = false;
bool disconnect_sta = false;
@@ -293,21 +165,6 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
beacon_loss = true;
}

- if (vector & PS_REPORT_EVENT_ID) {
- wl1271_debug(DEBUG_EVENT, "PS_REPORT_EVENT");
- wl12xx_for_each_wlvif_sta(wl, wlvif) {
- ret = wl1271_event_ps_report(wl, wlvif,
- mbox, &beacon_loss);
- if (ret < 0)
- return ret;
- }
- }
-
- if (vector & PSPOLL_DELIVERY_FAILURE_EVENT_ID)
- wl12xx_for_each_wlvif_sta(wl, wlvif) {
- wl1271_event_pspoll_delivery_fail(wl, wlvif);
- }
-
if (vector & RSSI_SNR_TRIGGER_0_EVENT_ID) {
/* TODO: check actual multi-role support */
wl1271_debug(DEBUG_EVENT, "RSSI_SNR_TRIGGER_0_EVENT");
diff --git a/drivers/net/wireless/wl12xx/event.h b/drivers/net/wireless/wl12xx/event.h
index b41f730..057d193 100644
--- a/drivers/net/wireless/wl12xx/event.h
+++ b/drivers/net/wireless/wl12xx/event.h
@@ -51,7 +51,7 @@ enum {
SCAN_COMPLETE_EVENT_ID = BIT(10),
WFD_DISCOVERY_COMPLETE_EVENT_ID = BIT(11),
AP_DISCOVERY_COMPLETE_EVENT_ID = BIT(12),
- PS_REPORT_EVENT_ID = BIT(13),
+ RESERVED1 = BIT(13),
PSPOLL_DELIVERY_FAILURE_EVENT_ID = BIT(14),
ROLE_STOP_COMPLETE_EVENT_ID = BIT(15),
RADAR_DETECTED_EVENT_ID = BIT(16),
@@ -96,7 +96,7 @@ struct event_mailbox {
s8 rssi_snr_trigger_metric[NUM_OF_RSSI_SNR_TRIGGERS];
u8 change_auto_mode_timeout;
u8 scheduled_scan_status;
- u8 ps_status;
+ u8 reserved4;
/* tuned channel (roc) */
u8 roc_channel;

@@ -135,6 +135,5 @@ struct event_mailbox {
int wl1271_event_unmask(struct wl1271 *wl);
void wl1271_event_mbox_config(struct wl1271 *wl);
int wl1271_event_handle(struct wl1271 *wl, u8 mbox);
-void wl1271_pspoll_work(struct work_struct *work);

#endif
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index eac5d52..58da515 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -235,7 +235,6 @@ static struct conf_drv_settings default_conf = {
.broadcast_timeout = 20000,
.rx_broadcast_in_ps = 1,
.ps_poll_threshold = 10,
- .ps_poll_recovery_period = 700,
.bet_enable = CONF_BET_MODE_ENABLE,
.bet_max_consecutive = 50,
.psm_entry_retries = 8,
@@ -1560,57 +1559,6 @@ static struct notifier_block wl1271_dev_notifier = {
};

#ifdef CONFIG_PM
-static int wl1271_configure_suspend_sta(struct wl1271 *wl,
- struct wl12xx_vif *wlvif)
-{
- int ret = 0;
-
- mutex_lock(&wl->mutex);
-
- if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
- goto out_unlock;
-
- ret = wl1271_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out_unlock;
-
- /* enter psm if needed*/
- if (!test_bit(WLVIF_FLAG_PSM, &wlvif->flags)) {
- DECLARE_COMPLETION_ONSTACK(compl);
-
- wlvif->ps_compl = &compl;
- ret = wl1271_ps_set_mode(wl, wlvif, STATION_POWER_SAVE_MODE,
- wlvif->basic_rate, true);
- if (ret < 0)
- goto out_sleep;
-
- /* we must unlock here so we will be able to get events */
- wl1271_ps_elp_sleep(wl);
- mutex_unlock(&wl->mutex);
-
- ret = wait_for_completion_timeout(
- &compl, msecs_to_jiffies(WL1271_PS_COMPLETE_TIMEOUT));
-
- mutex_lock(&wl->mutex);
- if (ret <= 0) {
- wl1271_warning("couldn't enter ps mode!");
- ret = -EBUSY;
- goto out_cleanup;
- }
-
- ret = wl1271_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out_cleanup;
- }
-out_sleep:
- wl1271_ps_elp_sleep(wl);
-out_cleanup:
- wlvif->ps_compl = NULL;
-out_unlock:
- mutex_unlock(&wl->mutex);
- return ret;
-
-}

static int wl1271_configure_suspend_ap(struct wl1271 *wl,
struct wl12xx_vif *wlvif)
@@ -1638,8 +1586,6 @@ out_unlock:
static int wl1271_configure_suspend(struct wl1271 *wl,
struct wl12xx_vif *wlvif)
{
- if (wlvif->bss_type == BSS_TYPE_STA_BSS)
- return wl1271_configure_suspend_sta(wl, wlvif);
if (wlvif->bss_type == BSS_TYPE_AP_BSS)
return wl1271_configure_suspend_ap(wl, wlvif);
return 0;
@@ -1649,10 +1595,9 @@ static void wl1271_configure_resume(struct wl1271 *wl,
struct wl12xx_vif *wlvif)
{
int ret;
- bool is_sta = wlvif->bss_type == BSS_TYPE_STA_BSS;
bool is_ap = wlvif->bss_type == BSS_TYPE_AP_BSS;

- if (!is_sta && !is_ap)
+ if (!is_ap)
return;

mutex_lock(&wl->mutex);
@@ -1660,14 +1605,7 @@ static void wl1271_configure_resume(struct wl1271 *wl,
if (ret < 0)
goto out;

- if (is_sta) {
- /* exit psm if it wasn't configured */
- if (!test_bit(WLVIF_FLAG_PSM_REQUESTED, &wlvif->flags))
- wl1271_ps_set_mode(wl, wlvif, STATION_ACTIVE_MODE,
- wlvif->basic_rate, true);
- } else if (is_ap) {
- wl1271_acx_beacon_filter_opt(wl, wlvif, false);
- }
+ wl1271_acx_beacon_filter_opt(wl, wlvif, false);

wl1271_ps_elp_sleep(wl);
out:
@@ -1709,9 +1647,6 @@ static int wl1271_op_suspend(struct ieee80211_hw *hw,

wl1271_enable_interrupts(wl);
flush_work(&wl->tx_work);
- wl12xx_for_each_wlvif(wl, wlvif) {
- flush_delayed_work(&wlvif->pspoll_work);
- }
flush_delayed_work(&wl->elp_work);

return 0;
@@ -1969,7 +1904,6 @@ static int wl12xx_init_vif_data(struct wl1271 *wl, struct ieee80211_vif *vif)
wl1271_rx_streaming_enable_work);
INIT_WORK(&wlvif->rx_streaming_disable_work,
wl1271_rx_streaming_disable_work);
- INIT_DELAYED_WORK(&wlvif->pspoll_work, wl1271_pspoll_work);
INIT_LIST_HEAD(&wlvif->list);

setup_timer(&wlvif->rx_streaming_timer, wl1271_rx_streaming_timer,
@@ -2250,10 +2184,10 @@ deinit:
wl->sta_count--;

mutex_unlock(&wl->mutex);
+
del_timer_sync(&wlvif->rx_streaming_timer);
cancel_work_sync(&wlvif->rx_streaming_enable_work);
cancel_work_sync(&wlvif->rx_streaming_disable_work);
- cancel_delayed_work_sync(&wlvif->pspoll_work);

mutex_lock(&wl->mutex);
}
@@ -2500,13 +2434,6 @@ static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif,
}
}

- /*
- * if mac80211 changes the PSM mode, make sure the mode is not
- * incorrectly changed after the pspoll failure active window.
- */
- if (changed & IEEE80211_CONF_CHANGE_PS)
- clear_bit(WLVIF_FLAG_PSPOLL_FAILURE, &wlvif->flags);
-
if (conf->flags & IEEE80211_CONF_PS &&
!test_bit(WLVIF_FLAG_PSM_REQUESTED, &wlvif->flags)) {
set_bit(WLVIF_FLAG_PSM_REQUESTED, &wlvif->flags);
@@ -3680,8 +3607,6 @@ sta_not_found:
wlvif->aid = bss_conf->aid;
set_assoc = true;

- wlvif->ps_poll_failures = 0;
-
/*
* use basic rates from AP, and determine lowest rate
* to use with control frames.
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
index 6e025ca..af1cedc 100644
--- a/drivers/net/wireless/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/wl12xx/wl12xx.h
@@ -560,12 +560,6 @@ struct wl12xx_vif {
/* Session counter for the chipset */
int session_counter;

- struct completion *ps_compl;
- struct delayed_work pspoll_work;
-
- /* counter for ps-poll delivery failures */
- int ps_poll_failures;
-
/* retry counter for PSM entries */
u8 psm_entry_retry;

--
1.7.6.401.g6a319


2012-01-30 19:59:31

by Luciano Coelho

[permalink] [raw]
Subject: Re: [PATCH 00/12] wl12xx: update fw api

On Mon, 2012-01-30 at 15:55 +0200, Luciano Coelho wrote:
> On Mon, 2012-01-30 at 15:52 +0200, Eliad Peller wrote:
> > On Mon, Jan 30, 2012 at 3:29 PM, Kalle Valo <[email protected]> wrote:
> > > Eliad Peller <[email protected]> writes:
> > >
> > >> The fw api was changed in the latest FWs (6.3.5.0.95 for wl127x
> > >> and 7.3.5.0.95 for wl128x).
> > >>
> > >> Along with some small adjustments, the main changes
> > >> inroduced by this patheset are configuring the
> > >> templates per-role, and moving to IEEE80211_HW_SUPPORTS_DYNAMIC_PS
> > >> mode.
> > >
> > > I didn't look so carefully, but doesn't this break bisect? I mean if you
> > > change the firmware api in small patches wl12xx can't work properly
> > > until all patches are applied, right?
> > >
> > > I would say that a huge patch doing all the necessary changes in one go
> > > is better, even it's ugly.
> > >
> > yes. it will break bisect (although it shouldn't break compilations).
> > i guess it's a matter of taste, but i think keeping the patches
> > manageable is more important than being able to bisect.
>
> I tend to agree with Eliad. If we do all in one go, git blame will be
> horrible.
>
> But it's a good point and I'm not fully convinced what is the best way
> to go. :\

I think this is okay. With the 2 squashes I proposed, there will be
only 3 patches where bisect would be broken.

We could add an info in the first patch and remove it in the last one to
make it clear that we're in the middle of the change.

Does anyone go against this?

--
Cheers,
Luca.


2012-01-30 11:57:40

by Eliad Peller

[permalink] [raw]
Subject: [PATCH 02/12] wl12xx: use dev_role_id for scans

Use device role for scans when the sta is not
associated.

Signed-off-by: Eliad Peller <[email protected]>
---
drivers/net/wireless/wl12xx/cmd.c | 3 ++-
drivers/net/wireless/wl12xx/main.c | 2 +-
drivers/net/wireless/wl12xx/scan.c | 16 ++++++++++++----
3 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c
index 28e0a56..10dba19 100644
--- a/drivers/net/wireless/wl12xx/cmd.c
+++ b/drivers/net/wireless/wl12xx/cmd.c
@@ -1029,7 +1029,8 @@ int wl1271_cmd_template_set(struct wl1271 *wl, u8 role_id,
struct wl1271_cmd_template_set *cmd;
int ret = 0;

- wl1271_debug(DEBUG_CMD, "cmd template_set %d", template_id);
+ wl1271_debug(DEBUG_CMD, "cmd template_set %d (role %d)",
+ template_id, role_id);

WARN_ON(buf_len > WL1271_CMD_TEMPL_MAX_SIZE);
buf_len = min_t(size_t, buf_len, WL1271_CMD_TEMPL_MAX_SIZE);
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 0509816..51059a8 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -3042,7 +3042,7 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw,

/* cancel ROC before scanning */
if (wl12xx_dev_role_started(wlvif))
- wl12xx_stop_dev(wl, wlvif);
+ wl12xx_croc(wl, wlvif->dev_role_id);

ret = wl1271_scan(hw->priv, vif, ssid, len, req);
out_sleep:
diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/wl12xx/scan.c
index 416ae91..3e3f2f5 100644
--- a/drivers/net/wireless/wl12xx/scan.c
+++ b/drivers/net/wireless/wl12xx/scan.c
@@ -77,7 +77,10 @@ void wl1271_scan_complete_work(struct work_struct *work)
(is_ibss && !test_bit(WLVIF_FLAG_IBSS_JOINED, &wlvif->flags))) &&
!test_bit(wlvif->dev_role_id, wl->roc_map)) {
/* restore remain on channel */
- wl12xx_start_dev(wl, wlvif);
+ if (wlvif->dev_hlid == WL12XX_INVALID_LINK_ID)
+ wl12xx_start_dev(wl, wlvif);
+ else
+ wl12xx_roc(wl, wlvif, wlvif->dev_role_id);
}
wl1271_ps_elp_sleep(wl);

@@ -185,11 +188,16 @@ static int wl1271_scan_send(struct wl1271 *wl, struct ieee80211_vif *vif,
if (passive)
scan_options |= WL1271_SCAN_OPT_PASSIVE;

- if (WARN_ON(wlvif->role_id == WL12XX_INVALID_ROLE_ID)) {
+ if (WARN_ON(wlvif->role_id == WL12XX_INVALID_ROLE_ID ||
+ wlvif->dev_role_id == WL12XX_INVALID_ROLE_ID)) {
ret = -EINVAL;
goto out;
}
- cmd->params.role_id = wlvif->role_id;
+ if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
+ cmd->params.role_id = wlvif->role_id;
+ else
+ cmd->params.role_id = wlvif->dev_role_id;
+
cmd->params.scan_options = cpu_to_le16(scan_options);

cmd->params.n_ch = wl1271_get_scan_channels(wl, wl->scan.req,
@@ -218,7 +226,7 @@ static int wl1271_scan_send(struct wl1271 *wl, struct ieee80211_vif *vif,
memcpy(cmd->addr, vif->addr, ETH_ALEN);

ret = wl12xx_cmd_build_probe_req(wl, wlvif,
- wlvif->role_id, band,
+ cmd->params.role_id, band,
wl->scan.ssid, wl->scan.ssid_len,
wl->scan.req->ie,
wl->scan.req->ie_len);
--
1.7.6.401.g6a319


2012-01-30 11:57:48

by Eliad Peller

[permalink] [raw]
Subject: [PATCH 06/12] wl12xx: Driver-FW API changes

From: Eyal Shapira <[email protected]>

- New ACX enum
- Added DFS commands
- Changes to channel switch command/event
- Added reset_tsf to ap role start command
- Added ACX for PROTECTION configuration

Signed-off-by: Eyal Shapira <[email protected]>
Signed-off-by: Eliad Peller <[email protected]>
---
drivers/net/wireless/wl12xx/cmd.c | 10 ++++++++--
drivers/net/wireless/wl12xx/cmd.h | 17 ++++++++++++-----
drivers/net/wireless/wl12xx/main.c | 2 +-
3 files changed, 21 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c
index c4990da..88e94c5 100644
--- a/drivers/net/wireless/wl12xx/cmd.c
+++ b/drivers/net/wireless/wl12xx/cmd.c
@@ -715,6 +715,8 @@ int wl12xx_cmd_role_start_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif)
cmd->ap.beacon_interval = cpu_to_le16(wlvif->beacon_int);
cmd->ap.dtim_interval = bss_conf->dtim_period;
cmd->ap.beacon_expiry = WL1271_AP_DEF_BEACON_EXP;
+ /* FIXME: Change when adding DFS */
+ cmd->ap.reset_tsf = 1; /* By default reset AP TSF */
cmd->channel = wlvif->channel;

if (!bss_conf->hidden_ssid) {
@@ -1756,6 +1758,7 @@ out:
}

int wl12xx_cmd_channel_switch(struct wl1271 *wl,
+ struct wl12xx_vif *wlvif,
struct ieee80211_channel_switch *ch_switch)
{
struct wl12xx_cmd_channel_switch *cmd;
@@ -1769,10 +1772,13 @@ int wl12xx_cmd_channel_switch(struct wl1271 *wl,
goto out;
}

+ cmd->role_id = wlvif->role_id;
cmd->channel = ch_switch->channel->hw_value;
cmd->switch_time = ch_switch->count;
- cmd->tx_suspend = ch_switch->block_tx;
- cmd->flush = 0; /* this value is ignored by the FW */
+ cmd->stop_tx = ch_switch->block_tx;
+
+ /* FIXME: control from mac80211 in the future */
+ cmd->post_switch_tx_disable = 0; /* Enable TX on the target channel */

ret = wl1271_cmd_send(wl, CMD_CHANNEL_SWITCH, cmd, sizeof(*cmd), 0);
if (ret < 0) {
diff --git a/drivers/net/wireless/wl12xx/cmd.h b/drivers/net/wireless/wl12xx/cmd.h
index faf046b..edd240d 100644
--- a/drivers/net/wireless/wl12xx/cmd.h
+++ b/drivers/net/wireless/wl12xx/cmd.h
@@ -91,6 +91,7 @@ int wl12xx_cmd_config_fwlog(struct wl1271 *wl);
int wl12xx_cmd_start_fwlog(struct wl1271 *wl);
int wl12xx_cmd_stop_fwlog(struct wl1271 *wl);
int wl12xx_cmd_channel_switch(struct wl1271 *wl,
+ struct wl12xx_vif *wlvif,
struct ieee80211_channel_switch *ch_switch);
int wl12xx_cmd_stop_channel_switch(struct wl1271 *wl);
int wl12xx_allocate_link(struct wl1271 *wl, struct wl12xx_vif *wlvif,
@@ -344,7 +345,9 @@ struct wl12xx_cmd_role_start {
u8 ssid_len;
u8 ssid[IEEE80211_MAX_SSID_LEN];

- u8 padding_1[5];
+ u8 reset_tsf;
+
+ u8 padding_1[4];
} __packed ap;
};
} __packed;
@@ -704,14 +707,18 @@ struct wl12xx_cmd_stop_fwlog {
struct wl12xx_cmd_channel_switch {
struct wl1271_cmd_header header;

+ u8 role_id;
+
/* The new serving channel */
u8 channel;
/* Relative time of the serving channel switch in TBTT units */
u8 switch_time;
- /* 1: Suspend TX till switch time; 0: Do not suspend TX */
- u8 tx_suspend;
- /* 1: Flush TX at switch time; 0: Do not flush */
- u8 flush;
+ /* Stop the role TX, should expect it after radar detection */
+ u8 stop_tx;
+ /* The target channel tx status 1-stopped 0-open*/
+ u8 post_switch_tx_disable;
+
+ u8 padding[3];
} __packed;

struct wl12xx_cmd_stop_channel_switch {
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 1c73c01..eac5d52 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -4381,7 +4381,7 @@ static void wl12xx_op_channel_switch(struct ieee80211_hw *hw,

/* TODO: change mac80211 to pass vif as param */
wl12xx_for_each_wlvif_sta(wl, wlvif) {
- ret = wl12xx_cmd_channel_switch(wl, ch_switch);
+ ret = wl12xx_cmd_channel_switch(wl, wlvif, ch_switch);

if (!ret)
set_bit(WLVIF_FLAG_CS_PROGRESS, &wlvif->flags);
--
1.7.6.401.g6a319


2012-01-30 11:57:51

by Eliad Peller

[permalink] [raw]
Subject: [PATCH 08/12] wl12xx: add support for HW dynamic PS

From: Eyal Shapira <[email protected]>

FW now supports dynamic PS so we don't need to use mac80211 support.
FW will go to PSM after a specified timeout with no Rx/Tx traffic.
- Changed FW API to include new PS mode (AUTO_MODE) and including timeout parameter
- The default PS mode would be dynamic PS
- Default timeout is 100ms (same as it used to be in mac80211)
- Avoid using mac80211 APIs to disable/enable dynamic PS as we're not
using mac80211 PS control anymore.
- COEX is handled by the FW while in dynamic PS so removed
handling of SOFT_GEMINI

Signed-off-by: Eyal Shapira <[email protected]>
Signed-off-by: Eliad Peller <[email protected]>
---
drivers/net/wireless/wl12xx/cmd.c | 3 ++-
drivers/net/wireless/wl12xx/cmd.h | 5 +++--
drivers/net/wireless/wl12xx/conf.h | 6 ++++++
drivers/net/wireless/wl12xx/event.c | 8 --------
drivers/net/wireless/wl12xx/main.c | 15 +++++----------
drivers/net/wireless/wl12xx/ps.c | 15 ++++++++++-----
6 files changed, 26 insertions(+), 26 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c
index 88e94c5..bf3c37b 100644
--- a/drivers/net/wireless/wl12xx/cmd.c
+++ b/drivers/net/wireless/wl12xx/cmd.c
@@ -996,7 +996,7 @@ out:
}

int wl1271_cmd_ps_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- u8 ps_mode)
+ u8 ps_mode, u16 auto_ps_timeout)
{
struct wl1271_cmd_ps_params *ps_params = NULL;
int ret = 0;
@@ -1011,6 +1011,7 @@ int wl1271_cmd_ps_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,

ps_params->role_id = wlvif->role_id;
ps_params->ps_mode = ps_mode;
+ ps_params->auto_ps_timeout = auto_ps_timeout;

ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params,
sizeof(*ps_params), 0);
diff --git a/drivers/net/wireless/wl12xx/cmd.h b/drivers/net/wireless/wl12xx/cmd.h
index edd240d..83a2a2e 100644
--- a/drivers/net/wireless/wl12xx/cmd.h
+++ b/drivers/net/wireless/wl12xx/cmd.h
@@ -51,7 +51,7 @@ int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len);
int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len);
int wl1271_cmd_data_path(struct wl1271 *wl, bool enable);
int wl1271_cmd_ps_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- u8 ps_mode);
+ u8 ps_mode, u16 auto_ps_timeout);
int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer,
size_t len);
int wl1271_cmd_template_set(struct wl1271 *wl, u8 role_id,
@@ -400,6 +400,7 @@ struct wl1271_tim {
} __packed;

enum wl1271_cmd_ps_mode {
+ STATION_AUTO_PS_MODE, /* Dynamic Power Save */
STATION_ACTIVE_MODE,
STATION_POWER_SAVE_MODE
};
@@ -409,7 +410,7 @@ struct wl1271_cmd_ps_params {

u8 role_id;
u8 ps_mode; /* STATION_* */
- u8 padding[2];
+ u16 auto_ps_timeout;
} __packed;

/* HW encryption keys */
diff --git a/drivers/net/wireless/wl12xx/conf.h b/drivers/net/wireless/wl12xx/conf.h
index 47cf80f..10e5e3d 100644
--- a/drivers/net/wireless/wl12xx/conf.h
+++ b/drivers/net/wireless/wl12xx/conf.h
@@ -915,6 +915,12 @@ struct conf_conn_settings {
u8 psm_entry_nullfunc_retries;

/*
+ * Specifies the dynamic PS timeout in ms that will be used
+ * by the FW when in AUTO_PS mode
+ */
+ u16 dynamic_ps_timeout;
+
+ /*
*
* Specifies the interval of the connection keep-alive null-func
* frame in ms.
diff --git a/drivers/net/wireless/wl12xx/event.c b/drivers/net/wireless/wl12xx/event.c
index 2ec5d21..71a02b6 100644
--- a/drivers/net/wireless/wl12xx/event.c
+++ b/drivers/net/wireless/wl12xx/event.c
@@ -78,21 +78,13 @@ static void wl1271_stop_ba_event(struct wl1271 *wl, struct wl12xx_vif *wlvif)
static void wl12xx_event_soft_gemini_sense(struct wl1271 *wl,
u8 enable)
{
- struct ieee80211_vif *vif;
struct wl12xx_vif *wlvif;

if (enable) {
- /* disable dynamic PS when requested by the firmware */
- wl12xx_for_each_wlvif_sta(wl, wlvif) {
- vif = wl12xx_wlvif_to_vif(wlvif);
- ieee80211_disable_dyn_ps(vif);
- }
set_bit(WL1271_FLAG_SOFT_GEMINI, &wl->flags);
} else {
clear_bit(WL1271_FLAG_SOFT_GEMINI, &wl->flags);
wl12xx_for_each_wlvif_sta(wl, wlvif) {
- vif = wl12xx_wlvif_to_vif(wlvif);
- ieee80211_enable_dyn_ps(vif);
wl1271_recalc_rx_streaming(wl, wlvif);
}
}
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 58da515..2b6dda5 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -1,3 +1,4 @@
+
/*
* This file is part of wl1271
*
@@ -240,6 +241,7 @@ static struct conf_drv_settings default_conf = {
.psm_entry_retries = 8,
.psm_exit_retries = 16,
.psm_entry_nullfunc_retries = 3,
+ .dynamic_ps_timeout = 100,
.keep_alive_interval = 55000,
.max_listen_interval = 20,
},
@@ -2114,10 +2116,6 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,

wl1271_info("down");

- /* enable dyn ps just in case (if left on due to fw crash etc) */
- if (wlvif->bss_type == BSS_TYPE_STA_BSS)
- ieee80211_enable_dyn_ps(vif);
-
if (wl->scan.state != WL1271_SCAN_STATE_IDLE &&
wl->scan_vif == vif) {
wl->scan.state = WL1271_SCAN_STATE_IDLE;
@@ -3666,9 +3664,6 @@ sta_not_found:
dev_kfree_skb(wlvif->probereq);
wlvif->probereq = NULL;

- /* re-enable dynamic ps - just in case */
- ieee80211_enable_dyn_ps(vif);
-
/* revert back to minimum rates for the current band */
wl1271_set_band_rate(wl, wlvif);
wlvif->basic_rate =
@@ -3799,10 +3794,9 @@ sta_not_found:
/* If we want to go in PSM but we're not there yet */
if (test_bit(WLVIF_FLAG_PSM_REQUESTED, &wlvif->flags) &&
!test_bit(WLVIF_FLAG_PSM, &wlvif->flags)) {
- enum wl1271_cmd_ps_mode mode;

- mode = STATION_POWER_SAVE_MODE;
- ret = wl1271_ps_set_mode(wl, wlvif, mode,
+ ret = wl1271_ps_set_mode(wl, wlvif,
+ STATION_AUTO_PS_MODE,
wlvif->basic_rate,
true);
if (ret < 0)
@@ -4836,6 +4830,7 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
wl->hw->flags = IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_BEACON_FILTER |
IEEE80211_HW_SUPPORTS_PS |
+ IEEE80211_HW_SUPPORTS_DYNAMIC_PS |
IEEE80211_HW_SUPPORTS_UAPSD |
IEEE80211_HW_HAS_RATE_CONTROL |
IEEE80211_HW_CONNECTION_MONITOR |
diff --git a/drivers/net/wireless/wl12xx/ps.c b/drivers/net/wireless/wl12xx/ps.c
index a2bdacd..60f03c4 100644
--- a/drivers/net/wireless/wl12xx/ps.c
+++ b/drivers/net/wireless/wl12xx/ps.c
@@ -163,10 +163,12 @@ int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
enum wl1271_cmd_ps_mode mode, u32 rates, bool send)
{
int ret;
+ u16 timeout = wl->conf.conn.dynamic_ps_timeout;

switch (mode) {
- case STATION_POWER_SAVE_MODE:
- wl1271_debug(DEBUG_PSM, "entering psm");
+ case STATION_AUTO_PS_MODE:
+ wl1271_debug(DEBUG_PSM, "entering psm (mode=%d,timeout=%u)",
+ mode, timeout);

ret = wl1271_acx_wake_up_conditions(wl, wlvif);
if (ret < 0) {
@@ -174,14 +176,13 @@ int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
return ret;
}

- ret = wl1271_cmd_ps_mode(wl, wlvif, STATION_POWER_SAVE_MODE);
+ ret = wl1271_cmd_ps_mode(wl, wlvif, mode, timeout);
if (ret < 0)
return ret;

set_bit(WLVIF_FLAG_PSM, &wlvif->flags);
break;
case STATION_ACTIVE_MODE:
- default:
wl1271_debug(DEBUG_PSM, "leaving psm");

/* disable beacon early termination */
@@ -191,12 +192,16 @@ int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
return ret;
}

- ret = wl1271_cmd_ps_mode(wl, wlvif, STATION_ACTIVE_MODE);
+ ret = wl1271_cmd_ps_mode(wl, wlvif, mode, 0);
if (ret < 0)
return ret;

clear_bit(WLVIF_FLAG_PSM, &wlvif->flags);
break;
+ case STATION_POWER_SAVE_MODE:
+ default:
+ wl1271_warning("trying to set ps to unsupported mode %d", mode);
+ ret = -EINVAL;
}

return ret;
--
1.7.6.401.g6a319


2012-01-30 11:57:42

by Eliad Peller

[permalink] [raw]
Subject: [PATCH 03/12] wl12xx: use dev_role_id for sched scan

sched_scan is used only when the sta is
not associated, and thus should use
the dev role (instead of sta role)

Signed-off-by: Eliad Peller <[email protected]>
---
drivers/net/wireless/wl12xx/scan.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/wl12xx/scan.c
index 3e3f2f5..6adc733 100644
--- a/drivers/net/wireless/wl12xx/scan.c
+++ b/drivers/net/wireless/wl12xx/scan.c
@@ -670,7 +670,7 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl,
if (!force_passive && cfg->active[0]) {
u8 band = IEEE80211_BAND_2GHZ;
ret = wl12xx_cmd_build_probe_req(wl, wlvif,
- wlvif->role_id, band,
+ wlvif->dev_role_id, band,
req->ssids[0].ssid,
req->ssids[0].ssid_len,
ies->ie[band],
@@ -684,7 +684,7 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl,
if (!force_passive && cfg->active[1]) {
u8 band = IEEE80211_BAND_5GHZ;
ret = wl12xx_cmd_build_probe_req(wl, wlvif,
- wlvif->role_id, band,
+ wlvif->dev_role_id, band,
req->ssids[0].ssid,
req->ssids[0].ssid_len,
ies->ie[band],
--
1.7.6.401.g6a319


2012-01-30 13:55:37

by Luciano Coelho

[permalink] [raw]
Subject: Re: [PATCH 00/12] wl12xx: update fw api

On Mon, 2012-01-30 at 15:52 +0200, Eliad Peller wrote:
> On Mon, Jan 30, 2012 at 3:29 PM, Kalle Valo <[email protected]> wrote:
> > Eliad Peller <[email protected]> writes:
> >
> >> The fw api was changed in the latest FWs (6.3.5.0.95 for wl127x
> >> and 7.3.5.0.95 for wl128x).
> >>
> >> Along with some small adjustments, the main changes
> >> inroduced by this patheset are configuring the
> >> templates per-role, and moving to IEEE80211_HW_SUPPORTS_DYNAMIC_PS
> >> mode.
> >
> > I didn't look so carefully, but doesn't this break bisect? I mean if you
> > change the firmware api in small patches wl12xx can't work properly
> > until all patches are applied, right?
> >
> > I would say that a huge patch doing all the necessary changes in one go
> > is better, even it's ugly.
> >
> yes. it will break bisect (although it shouldn't break compilations).
> i guess it's a matter of taste, but i think keeping the patches
> manageable is more important than being able to bisect.

I tend to agree with Eliad. If we do all in one go, git blame will be
horrible.

But it's a good point and I'm not fully convinced what is the best way
to go. :\

--
Cheers,
Luca.