diff options
Diffstat (limited to 'drivers/net/wireless/wl12xx/wl1271_cmd.c')
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_cmd.c | 143 |
1 files changed, 89 insertions, 54 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/wl1271_cmd.c index ce503ddd5a41..5d3e8485ea4e 100644 --- a/drivers/net/wireless/wl12xx/wl1271_cmd.c +++ b/drivers/net/wireless/wl12xx/wl1271_cmd.c | |||
@@ -94,6 +94,7 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len, | |||
94 | status = le16_to_cpu(cmd->status); | 94 | status = le16_to_cpu(cmd->status); |
95 | if (status != CMD_STATUS_SUCCESS) { | 95 | if (status != CMD_STATUS_SUCCESS) { |
96 | wl1271_error("command execute failure %d", status); | 96 | wl1271_error("command execute failure %d", status); |
97 | ieee80211_queue_work(wl->hw, &wl->recovery_work); | ||
97 | ret = -EIO; | 98 | ret = -EIO; |
98 | } | 99 | } |
99 | 100 | ||
@@ -107,6 +108,8 @@ out: | |||
107 | int wl1271_cmd_general_parms(struct wl1271 *wl) | 108 | int wl1271_cmd_general_parms(struct wl1271 *wl) |
108 | { | 109 | { |
109 | struct wl1271_general_parms_cmd *gen_parms; | 110 | struct wl1271_general_parms_cmd *gen_parms; |
111 | struct wl1271_ini_general_params *gp = &wl->nvs->general_params; | ||
112 | bool answer = false; | ||
110 | int ret; | 113 | int ret; |
111 | 114 | ||
112 | if (!wl->nvs) | 115 | if (!wl->nvs) |
@@ -118,13 +121,24 @@ int wl1271_cmd_general_parms(struct wl1271 *wl) | |||
118 | 121 | ||
119 | gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM; | 122 | gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM; |
120 | 123 | ||
121 | memcpy(&gen_parms->general_params, &wl->nvs->general_params, | 124 | memcpy(&gen_parms->general_params, gp, sizeof(*gp)); |
122 | sizeof(struct wl1271_ini_general_params)); | ||
123 | 125 | ||
124 | ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), 0); | 126 | if (gp->tx_bip_fem_auto_detect) |
125 | if (ret < 0) | 127 | answer = true; |
128 | |||
129 | ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer); | ||
130 | if (ret < 0) { | ||
126 | wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed"); | 131 | wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed"); |
132 | goto out; | ||
133 | } | ||
134 | |||
135 | gp->tx_bip_fem_manufacturer = | ||
136 | gen_parms->general_params.tx_bip_fem_manufacturer; | ||
137 | |||
138 | wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n", | ||
139 | answer ? "auto" : "manual", gp->tx_bip_fem_manufacturer); | ||
127 | 140 | ||
141 | out: | ||
128 | kfree(gen_parms); | 142 | kfree(gen_parms); |
129 | return ret; | 143 | return ret; |
130 | } | 144 | } |
@@ -170,6 +184,39 @@ int wl1271_cmd_radio_parms(struct wl1271 *wl) | |||
170 | return ret; | 184 | return ret; |
171 | } | 185 | } |
172 | 186 | ||
187 | int wl1271_cmd_ext_radio_parms(struct wl1271 *wl) | ||
188 | { | ||
189 | struct wl1271_ext_radio_parms_cmd *ext_radio_parms; | ||
190 | struct conf_rf_settings *rf = &wl->conf.rf; | ||
191 | int ret; | ||
192 | |||
193 | if (!wl->nvs) | ||
194 | return -ENODEV; | ||
195 | |||
196 | ext_radio_parms = kzalloc(sizeof(*ext_radio_parms), GFP_KERNEL); | ||
197 | if (!ext_radio_parms) | ||
198 | return -ENOMEM; | ||
199 | |||
200 | ext_radio_parms->test.id = TEST_CMD_INI_FILE_RF_EXTENDED_PARAM; | ||
201 | |||
202 | memcpy(ext_radio_parms->tx_per_channel_power_compensation_2, | ||
203 | rf->tx_per_channel_power_compensation_2, | ||
204 | CONF_TX_PWR_COMPENSATION_LEN_2); | ||
205 | memcpy(ext_radio_parms->tx_per_channel_power_compensation_5, | ||
206 | rf->tx_per_channel_power_compensation_5, | ||
207 | CONF_TX_PWR_COMPENSATION_LEN_5); | ||
208 | |||
209 | wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_EXT_RADIO_PARAM: ", | ||
210 | ext_radio_parms, sizeof(*ext_radio_parms)); | ||
211 | |||
212 | ret = wl1271_cmd_test(wl, ext_radio_parms, sizeof(*ext_radio_parms), 0); | ||
213 | if (ret < 0) | ||
214 | wl1271_warning("TEST_CMD_INI_FILE_RF_EXTENDED_PARAM failed"); | ||
215 | |||
216 | kfree(ext_radio_parms); | ||
217 | return ret; | ||
218 | } | ||
219 | |||
173 | /* | 220 | /* |
174 | * Poll the mailbox event field until any of the bits in the mask is set or a | 221 | * Poll the mailbox event field until any of the bits in the mask is set or a |
175 | * timeout occurs (WL1271_EVENT_TIMEOUT in msecs) | 222 | * timeout occurs (WL1271_EVENT_TIMEOUT in msecs) |
@@ -182,8 +229,10 @@ static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask) | |||
182 | timeout = jiffies + msecs_to_jiffies(WL1271_EVENT_TIMEOUT); | 229 | timeout = jiffies + msecs_to_jiffies(WL1271_EVENT_TIMEOUT); |
183 | 230 | ||
184 | do { | 231 | do { |
185 | if (time_after(jiffies, timeout)) | 232 | if (time_after(jiffies, timeout)) { |
233 | ieee80211_queue_work(wl->hw, &wl->recovery_work); | ||
186 | return -ETIMEDOUT; | 234 | return -ETIMEDOUT; |
235 | } | ||
187 | 236 | ||
188 | msleep(1); | 237 | msleep(1); |
189 | 238 | ||
@@ -390,18 +439,11 @@ out: | |||
390 | return ret; | 439 | return ret; |
391 | } | 440 | } |
392 | 441 | ||
393 | int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send) | 442 | int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, u32 rates, bool send) |
394 | { | 443 | { |
395 | struct wl1271_cmd_ps_params *ps_params = NULL; | 444 | struct wl1271_cmd_ps_params *ps_params = NULL; |
396 | int ret = 0; | 445 | int ret = 0; |
397 | 446 | ||
398 | /* FIXME: this should be in ps.c */ | ||
399 | ret = wl1271_acx_wake_up_conditions(wl); | ||
400 | if (ret < 0) { | ||
401 | wl1271_error("couldn't set wake up conditions"); | ||
402 | goto out; | ||
403 | } | ||
404 | |||
405 | wl1271_debug(DEBUG_CMD, "cmd set ps mode"); | 447 | wl1271_debug(DEBUG_CMD, "cmd set ps mode"); |
406 | 448 | ||
407 | ps_params = kzalloc(sizeof(*ps_params), GFP_KERNEL); | 449 | ps_params = kzalloc(sizeof(*ps_params), GFP_KERNEL); |
@@ -412,9 +454,9 @@ int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send) | |||
412 | 454 | ||
413 | ps_params->ps_mode = ps_mode; | 455 | ps_params->ps_mode = ps_mode; |
414 | ps_params->send_null_data = send; | 456 | ps_params->send_null_data = send; |
415 | ps_params->retries = 5; | 457 | ps_params->retries = wl->conf.conn.psm_entry_nullfunc_retries; |
416 | ps_params->hang_over_period = 1; | 458 | ps_params->hang_over_period = wl->conf.conn.psm_entry_hangover_period; |
417 | ps_params->null_data_rate = cpu_to_le32(wl->basic_rate_set); | 459 | ps_params->null_data_rate = cpu_to_le32(rates); |
418 | 460 | ||
419 | ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params, | 461 | ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params, |
420 | sizeof(*ps_params), 0); | 462 | sizeof(*ps_params), 0); |
@@ -428,41 +470,6 @@ out: | |||
428 | return ret; | 470 | return ret; |
429 | } | 471 | } |
430 | 472 | ||
431 | int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer, | ||
432 | size_t len) | ||
433 | { | ||
434 | struct cmd_read_write_memory *cmd; | ||
435 | int ret = 0; | ||
436 | |||
437 | wl1271_debug(DEBUG_CMD, "cmd read memory"); | ||
438 | |||
439 | cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); | ||
440 | if (!cmd) { | ||
441 | ret = -ENOMEM; | ||
442 | goto out; | ||
443 | } | ||
444 | |||
445 | WARN_ON(len > MAX_READ_SIZE); | ||
446 | len = min_t(size_t, len, MAX_READ_SIZE); | ||
447 | |||
448 | cmd->addr = cpu_to_le32(addr); | ||
449 | cmd->size = cpu_to_le32(len); | ||
450 | |||
451 | ret = wl1271_cmd_send(wl, CMD_READ_MEMORY, cmd, sizeof(*cmd), | ||
452 | sizeof(*cmd)); | ||
453 | if (ret < 0) { | ||
454 | wl1271_error("read memory command failed: %d", ret); | ||
455 | goto out; | ||
456 | } | ||
457 | |||
458 | /* the read command got in */ | ||
459 | memcpy(answer, cmd->value, len); | ||
460 | |||
461 | out: | ||
462 | kfree(cmd); | ||
463 | return ret; | ||
464 | } | ||
465 | |||
466 | int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id, | 473 | int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id, |
467 | void *buf, size_t buf_len, int index, u32 rates) | 474 | void *buf, size_t buf_len, int index, u32 rates) |
468 | { | 475 | { |
@@ -523,7 +530,7 @@ int wl1271_cmd_build_null_data(struct wl1271 *wl) | |||
523 | } | 530 | } |
524 | 531 | ||
525 | ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, ptr, size, 0, | 532 | ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, ptr, size, 0, |
526 | WL1271_RATE_AUTOMATIC); | 533 | wl->basic_rate); |
527 | 534 | ||
528 | out: | 535 | out: |
529 | dev_kfree_skb(skb); | 536 | dev_kfree_skb(skb); |
@@ -546,7 +553,7 @@ int wl1271_cmd_build_klv_null_data(struct wl1271 *wl) | |||
546 | ret = wl1271_cmd_template_set(wl, CMD_TEMPL_KLV, | 553 | ret = wl1271_cmd_template_set(wl, CMD_TEMPL_KLV, |
547 | skb->data, skb->len, | 554 | skb->data, skb->len, |
548 | CMD_TEMPL_KLV_IDX_NULL_DATA, | 555 | CMD_TEMPL_KLV_IDX_NULL_DATA, |
549 | WL1271_RATE_AUTOMATIC); | 556 | wl->basic_rate); |
550 | 557 | ||
551 | out: | 558 | out: |
552 | dev_kfree_skb(skb); | 559 | dev_kfree_skb(skb); |
@@ -623,7 +630,7 @@ int wl1271_build_qos_null_data(struct wl1271 *wl) | |||
623 | 630 | ||
624 | return wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, &template, | 631 | return wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, &template, |
625 | sizeof(template), 0, | 632 | sizeof(template), 0, |
626 | WL1271_RATE_AUTOMATIC); | 633 | wl->basic_rate); |
627 | } | 634 | } |
628 | 635 | ||
629 | int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id) | 636 | int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id) |
@@ -746,3 +753,31 @@ out_free: | |||
746 | out: | 753 | out: |
747 | return ret; | 754 | return ret; |
748 | } | 755 | } |
756 | |||
757 | int wl1271_cmd_set_sta_state(struct wl1271 *wl) | ||
758 | { | ||
759 | struct wl1271_cmd_set_sta_state *cmd; | ||
760 | int ret = 0; | ||
761 | |||
762 | wl1271_debug(DEBUG_CMD, "cmd set sta state"); | ||
763 | |||
764 | cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); | ||
765 | if (!cmd) { | ||
766 | ret = -ENOMEM; | ||
767 | goto out; | ||
768 | } | ||
769 | |||
770 | cmd->state = WL1271_CMD_STA_STATE_CONNECTED; | ||
771 | |||
772 | ret = wl1271_cmd_send(wl, CMD_SET_STA_STATE, cmd, sizeof(*cmd), 0); | ||
773 | if (ret < 0) { | ||
774 | wl1271_error("failed to send set STA state command"); | ||
775 | goto out_free; | ||
776 | } | ||
777 | |||
778 | out_free: | ||
779 | kfree(cmd); | ||
780 | |||
781 | out: | ||
782 | return ret; | ||
783 | } | ||