Skip to content

Commit

Permalink
wl12xx: move to new firmware (6.1.3.50.49)
Browse files Browse the repository at this point in the history
This patch adds support for the new wl12xx firmware (Rev 6.1.3.50.49)

Since this fw is not backward compatible with previous fw versions,
a new fw (with different name) is being fetched.

(the patch is big because it contains all the required fw api changes.
splitting it into multiple patches will result in corrupted intermediate
commits)

Signed-off-by: Eliad Peller <eliad@wizery.com>
Reviewed-by: Luciano Coelho <coelho@ti.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
  • Loading branch information
Eliad Peller authored and Luciano Coelho committed Feb 9, 2011
1 parent ee60833 commit c8bde24
Show file tree
Hide file tree
Showing 13 changed files with 162 additions and 60 deletions.
44 changes: 38 additions & 6 deletions drivers/net/wireless/wl12xx/acx.c
Original file line number Diff line number Diff line change
Expand Up @@ -947,9 +947,9 @@ int wl1271_acx_tx_config_options(struct wl1271 *wl)
return ret;
}

int wl1271_acx_mem_cfg(struct wl1271 *wl)
int wl1271_acx_ap_mem_cfg(struct wl1271 *wl)
{
struct wl1271_acx_config_memory *mem_conf;
struct wl1271_acx_ap_config_memory *mem_conf;
int ret;

wl1271_debug(DEBUG_ACX, "wl1271 mem cfg");
Expand Down Expand Up @@ -979,13 +979,45 @@ int wl1271_acx_mem_cfg(struct wl1271 *wl)
return ret;
}

int wl1271_acx_init_mem_config(struct wl1271 *wl)
int wl1271_acx_sta_mem_cfg(struct wl1271 *wl)
{
struct wl1271_acx_sta_config_memory *mem_conf;
int ret;

ret = wl1271_acx_mem_cfg(wl);
if (ret < 0)
return ret;
wl1271_debug(DEBUG_ACX, "wl1271 mem cfg");

mem_conf = kzalloc(sizeof(*mem_conf), GFP_KERNEL);
if (!mem_conf) {
ret = -ENOMEM;
goto out;
}

/* memory config */
mem_conf->num_stations = DEFAULT_NUM_STATIONS;
mem_conf->rx_mem_block_num = ACX_RX_MEM_BLOCKS;
mem_conf->tx_min_mem_block_num = ACX_TX_MIN_MEM_BLOCKS;
mem_conf->num_ssid_profiles = ACX_NUM_SSID_PROFILES;
mem_conf->total_tx_descriptors = cpu_to_le32(ACX_TX_DESCRIPTORS);
mem_conf->dyn_mem_enable = wl->conf.mem.dynamic_memory;
mem_conf->tx_free_req = wl->conf.mem.min_req_tx_blocks;
mem_conf->rx_free_req = wl->conf.mem.min_req_rx_blocks;
mem_conf->tx_min = wl->conf.mem.tx_min;

ret = wl1271_cmd_configure(wl, ACX_MEM_CFG, mem_conf,
sizeof(*mem_conf));
if (ret < 0) {
wl1271_warning("wl1271 mem config failed: %d", ret);
goto out;
}

out:
kfree(mem_conf);
return ret;
}

int wl1271_acx_init_mem_config(struct wl1271 *wl)
{
int ret;

wl->target_mem_map = kzalloc(sizeof(struct wl1271_acx_mem_map),
GFP_KERNEL);
Expand Down
26 changes: 20 additions & 6 deletions drivers/net/wireless/wl12xx/acx.h
Original file line number Diff line number Diff line change
Expand Up @@ -802,7 +802,7 @@ struct acx_tx_config_options {
#define ACX_TX_DESCRIPTORS 32
#define ACX_NUM_SSID_PROFILES 1

struct wl1271_acx_config_memory {
struct wl1271_acx_ap_config_memory {
struct acx_header header;

u8 rx_mem_block_num;
Expand All @@ -812,6 +812,20 @@ struct wl1271_acx_config_memory {
__le32 total_tx_descriptors;
} __packed;

struct wl1271_acx_sta_config_memory {
struct acx_header header;

u8 rx_mem_block_num;
u8 tx_min_mem_block_num;
u8 num_stations;
u8 num_ssid_profiles;
__le32 total_tx_descriptors;
u8 dyn_mem_enable;
u8 tx_free_req;
u8 rx_free_req;
u8 tx_min;
} __packed;

struct wl1271_acx_mem_map {
struct acx_header header;

Expand Down Expand Up @@ -1202,6 +1216,8 @@ enum {
ACX_HT_BSS_OPERATION = 0x0058,
ACX_COEX_ACTIVITY = 0x0059,
ACX_SET_DCO_ITRIM_PARAMS = 0x0061,
ACX_GEN_FW_CMD = 0x0070,
ACX_HOST_IF_CFG_BITMAP = 0x0071,
ACX_MAX_TX_FAILURE = 0x0072,
DOT11_RX_MSDU_LIFE_TIME = 0x1004,
DOT11_CUR_TX_PWR = 0x100D,
Expand All @@ -1210,10 +1226,7 @@ enum {
DOT11_GROUP_ADDRESS_TBL = 0x1014,
ACX_PM_CONFIG = 0x1016,
ACX_CONFIG_PS = 0x1017,

MAX_DOT11_IE = DOT11_GROUP_ADDRESS_TBL,

MAX_IE = 0xFFFF
ACX_CONFIG_HANGOVER = 0x1018,
};


Expand Down Expand Up @@ -1255,7 +1268,8 @@ int wl1271_acx_tid_cfg(struct wl1271 *wl, u8 queue_id, u8 channel_type,
u32 apsd_conf0, u32 apsd_conf1);
int wl1271_acx_frag_threshold(struct wl1271 *wl, u16 frag_threshold);
int wl1271_acx_tx_config_options(struct wl1271 *wl);
int wl1271_acx_mem_cfg(struct wl1271 *wl);
int wl1271_acx_ap_mem_cfg(struct wl1271 *wl);
int wl1271_acx_sta_mem_cfg(struct wl1271 *wl);
int wl1271_acx_init_mem_config(struct wl1271 *wl);
int wl1271_acx_init_rx_interrupt(struct wl1271 *wl);
int wl1271_acx_smart_reflex(struct wl1271 *wl);
Expand Down
13 changes: 8 additions & 5 deletions drivers/net/wireless/wl12xx/cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,13 @@ int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type)
join->rx_filter_options = cpu_to_le32(wl->rx_filter);
join->bss_type = bss_type;
join->basic_rate_set = cpu_to_le32(wl->basic_rate_set);
/*
* for supported_rate_set, we should use wl->rate_set. however,
* it seems that acx_rate_policies doesn't affect full_rate, and
* since we want to avoid additional join, we'll use a 0xffffffff value,
* and let the fw find the actual supported rates
*/
join->supported_rate_set = cpu_to_le32(0xffffffff);

if (wl->band == IEEE80211_BAND_5GHZ)
join->bss_type |= WL1271_JOIN_CMD_BSS_TYPE_5GHZ;
Expand Down Expand Up @@ -454,7 +461,7 @@ int wl1271_cmd_data_path(struct wl1271 *wl, bool enable)
return ret;
}

int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, u32 rates, bool send)
int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode)
{
struct wl1271_cmd_ps_params *ps_params = NULL;
int ret = 0;
Expand All @@ -468,10 +475,6 @@ int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, u32 rates, bool send)
}

ps_params->ps_mode = ps_mode;
ps_params->send_null_data = send;
ps_params->retries = wl->conf.conn.psm_entry_nullfunc_retries;
ps_params->hang_over_period = wl->conf.conn.psm_entry_hangover_period;
ps_params->null_data_rate = cpu_to_le32(rates);

ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params,
sizeof(*ps_params), 0);
Expand Down
14 changes: 4 additions & 10 deletions drivers/net/wireless/wl12xx/cmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer);
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, u8 ps_mode, u32 rates, bool send);
int wl1271_cmd_ps_mode(struct wl1271 *wl, 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,
Expand Down Expand Up @@ -140,6 +140,7 @@ enum cmd_templ {
* For CTS-to-self (FastCTS) mechanism
* for BT/WLAN coexistence (SoftGemini). */
CMD_TEMPL_ARP_RSP,
CMD_TEMPL_LINK_MEASUREMENT_REPORT,

/* AP-mode specific */
CMD_TEMPL_AP_BEACON = 13,
Expand Down Expand Up @@ -216,6 +217,7 @@ struct wl1271_cmd_join {
* ACK or CTS frames).
*/
__le32 basic_rate_set;
__le32 supported_rate_set;
u8 dtim_interval;
/*
* bits 0-2: This bitwise field specifies the type
Expand Down Expand Up @@ -278,15 +280,7 @@ struct wl1271_cmd_ps_params {
struct wl1271_cmd_header header;

u8 ps_mode; /* STATION_* */
u8 send_null_data; /* Do we have to send NULL data packet ? */
u8 retries; /* Number of retires for the initial NULL data packet */

/*
* TUs during which the target stays awake after switching
* to power save mode.
*/
u8 hang_over_period;
__le32 null_data_rate;
u8 padding[3];
} __packed;

/* HW encryption keys */
Expand Down
29 changes: 29 additions & 0 deletions drivers/net/wireless/wl12xx/conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -1151,6 +1151,34 @@ struct conf_ht_setting {
u16 inactivity_timeout;
};

struct conf_memory_settings {
/* Disable/Enable dynamic memory */
u8 dynamic_memory;

/*
* Minimum required free tx memory blocks in order to assure optimum
* performence
*
* Range: 0-120
*/
u8 min_req_tx_blocks;

/*
* Minimum required free rx memory blocks in order to assure optimum
* performence
*
* Range: 0-120
*/
u8 min_req_rx_blocks;

/*
* Minimum number of mem blocks (free+used) guaranteed for TX
*
* Range: 0-120
*/
u8 tx_min;
};

struct conf_drv_settings {
struct conf_sg_settings sg;
struct conf_rx_settings rx;
Expand All @@ -1162,6 +1190,7 @@ struct conf_drv_settings {
struct conf_scan_settings scan;
struct conf_rf_settings rf;
struct conf_ht_setting ht;
struct conf_memory_settings mem;
};

#endif
14 changes: 0 additions & 14 deletions drivers/net/wireless/wl12xx/event.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,20 +135,6 @@ static int wl1271_event_ps_report(struct wl1271 *wl,
/* go to extremely low power mode */
wl1271_ps_elp_sleep(wl);
break;
case EVENT_EXIT_POWER_SAVE_FAIL:
wl1271_debug(DEBUG_PSM, "PSM exit failed");

if (test_bit(WL1271_FLAG_PSM, &wl->flags)) {
wl->psm_entry_retry = 0;
break;
}

/* make sure the firmware goes to active mode - the frame to
be sent next will indicate to the AP, that we are active. */
ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE,
wl->basic_rate, false);
break;
case EVENT_EXIT_POWER_SAVE_SUCCESS:
default:
break;
}
Expand Down
2 changes: 0 additions & 2 deletions drivers/net/wireless/wl12xx/event.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,6 @@ enum {
enum {
EVENT_ENTER_POWER_SAVE_FAIL = 0,
EVENT_ENTER_POWER_SAVE_SUCCESS,
EVENT_EXIT_POWER_SAVE_FAIL,
EVENT_EXIT_POWER_SAVE_SUCCESS,
};

struct event_debug_report {
Expand Down
13 changes: 13 additions & 0 deletions drivers/net/wireless/wl12xx/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,11 @@ static int wl1271_sta_hw_init(struct wl1271 *wl)
if (ret < 0)
return ret;

/* PS config */
ret = wl1271_acx_config_ps(wl);
if (ret < 0)
return ret;

ret = wl1271_sta_init_templates_config(wl);
if (ret < 0)
return ret;
Expand Down Expand Up @@ -367,6 +372,10 @@ static int wl1271_sta_hw_init(struct wl1271 *wl)
if (ret < 0)
return ret;

ret = wl1271_acx_sta_mem_cfg(wl);
if (ret < 0)
return ret;

return 0;
}

Expand Down Expand Up @@ -433,6 +442,10 @@ static int wl1271_ap_hw_init(struct wl1271 *wl)
if (ret < 0)
return ret;

ret = wl1271_acx_ap_mem_cfg(wl);
if (ret < 0)
return ret;

return 0;
}

Expand Down
22 changes: 17 additions & 5 deletions drivers/net/wireless/wl12xx/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,12 @@ static struct conf_drv_settings default_conf = {
.tx_ba_win_size = 64,
.inactivity_timeout = 10000,
},
.mem = {
.dynamic_memory = 0,
.min_req_tx_blocks = 104,
.min_req_rx_blocks = 22,
.tx_min = 27,
}
};

static void __wl1271_op_remove_interface(struct wl1271 *wl);
Expand Down Expand Up @@ -524,13 +530,19 @@ static int wl1271_plt_init(struct wl1271 *wl)
}

static void wl1271_fw_status(struct wl1271 *wl,
struct wl1271_fw_status *status)
struct wl1271_fw_full_status *full_status)
{
struct wl1271_fw_common_status *status = &full_status->common;
struct timespec ts;
u32 total = 0;
int i;

wl1271_raw_read(wl, FW_STATUS_ADDR, status, sizeof(*status), false);
if (wl->bss_type == BSS_TYPE_AP_BSS)
wl1271_raw_read(wl, FW_STATUS_ADDR, status,
sizeof(struct wl1271_fw_ap_status), false);
else
wl1271_raw_read(wl, FW_STATUS_ADDR, status,
sizeof(struct wl1271_fw_sta_status), false);

wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, "
"drv_rx_counter = %d, tx_results_counter = %d)",
Expand Down Expand Up @@ -589,7 +601,7 @@ static void wl1271_irq_work(struct work_struct *work)
loopcount--;

wl1271_fw_status(wl, wl->fw_status);
intr = le32_to_cpu(wl->fw_status->intr);
intr = le32_to_cpu(wl->fw_status->common.intr);
if (!intr) {
wl1271_debug(DEBUG_IRQ, "Zero interrupt received.");
spin_lock_irqsave(&wl->wl_lock, flags);
Expand All @@ -611,7 +623,7 @@ static void wl1271_irq_work(struct work_struct *work)
wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA");

/* check for tx results */
if (wl->fw_status->tx_results_counter !=
if (wl->fw_status->common.tx_results_counter !=
(wl->tx_results_count & 0xff))
wl1271_tx_complete(wl);

Expand All @@ -625,7 +637,7 @@ static void wl1271_irq_work(struct work_struct *work)
wl1271_tx_work_locked(wl);
}

wl1271_rx(wl, wl->fw_status);
wl1271_rx(wl, &wl->fw_status->common);
}

if (intr & WL1271_ACX_INTR_EVENT_A) {
Expand Down
6 changes: 2 additions & 4 deletions drivers/net/wireless/wl12xx/ps.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,7 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode,
return ret;
}

ret = wl1271_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE,
rates, send);
ret = wl1271_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE);
if (ret < 0)
return ret;

Expand All @@ -163,8 +162,7 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode,
if (ret < 0)
return ret;

ret = wl1271_cmd_ps_mode(wl, STATION_ACTIVE_MODE,
rates, send);
ret = wl1271_cmd_ps_mode(wl, STATION_ACTIVE_MODE);
if (ret < 0)
return ret;

Expand Down
Loading

0 comments on commit c8bde24

Please sign in to comment.