cmd.c revision 1e0708a9574aee0136611edc5d3a7a9b2775a113
1/* 2 * This file is part of wl1271 3 * 4 * Copyright (C) 2009-2010 Nokia Corporation 5 * 6 * Contact: Luciano Coelho <luciano.coelho@nokia.com> 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License 10 * version 2 as published by the Free Software Foundation. 11 * 12 * This program is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 20 * 02110-1301 USA 21 * 22 */ 23 24#include <linux/module.h> 25#include <linux/platform_device.h> 26#include <linux/spi/spi.h> 27#include <linux/etherdevice.h> 28#include <linux/ieee80211.h> 29#include <linux/slab.h> 30 31#include "wlcore.h" 32#include "debug.h" 33#include "io.h" 34#include "acx.h" 35#include "wl12xx_80211.h" 36#include "cmd.h" 37#include "event.h" 38#include "tx.h" 39#include "hw_ops.h" 40 41#define WL1271_CMD_FAST_POLL_COUNT 50 42#define WL1271_WAIT_EVENT_FAST_POLL_COUNT 20 43 44/* 45 * send command to firmware 46 * 47 * @wl: wl struct 48 * @id: command id 49 * @buf: buffer containing the command, must work with dma 50 * @len: length of the buffer 51 * return the cmd status code on success. 52 */ 53static int __wlcore_cmd_send(struct wl1271 *wl, u16 id, void *buf, 54 size_t len, size_t res_len) 55{ 56 struct wl1271_cmd_header *cmd; 57 unsigned long timeout; 58 u32 intr; 59 int ret; 60 u16 status; 61 u16 poll_count = 0; 62 63 if (WARN_ON(unlikely(wl->state == WLCORE_STATE_RESTARTING))) 64 return -EIO; 65 66 cmd = buf; 67 cmd->id = cpu_to_le16(id); 68 cmd->status = 0; 69 70 WARN_ON(len % 4 != 0); 71 WARN_ON(test_bit(WL1271_FLAG_IN_ELP, &wl->flags)); 72 73 ret = wlcore_write(wl, wl->cmd_box_addr, buf, len, false); 74 if (ret < 0) 75 return ret; 76 77 /* 78 * TODO: we just need this because one bit is in a different 79 * place. Is there any better way? 80 */ 81 ret = wl->ops->trigger_cmd(wl, wl->cmd_box_addr, buf, len); 82 if (ret < 0) 83 return ret; 84 85 timeout = jiffies + msecs_to_jiffies(WL1271_COMMAND_TIMEOUT); 86 87 ret = wlcore_read_reg(wl, REG_INTERRUPT_NO_CLEAR, &intr); 88 if (ret < 0) 89 return ret; 90 91 while (!(intr & WL1271_ACX_INTR_CMD_COMPLETE)) { 92 if (time_after(jiffies, timeout)) { 93 wl1271_error("command complete timeout"); 94 return -ETIMEDOUT; 95 } 96 97 poll_count++; 98 if (poll_count < WL1271_CMD_FAST_POLL_COUNT) 99 udelay(10); 100 else 101 msleep(1); 102 103 ret = wlcore_read_reg(wl, REG_INTERRUPT_NO_CLEAR, &intr); 104 if (ret < 0) 105 return ret; 106 } 107 108 /* read back the status code of the command */ 109 if (res_len == 0) 110 res_len = sizeof(struct wl1271_cmd_header); 111 112 ret = wlcore_read(wl, wl->cmd_box_addr, cmd, res_len, false); 113 if (ret < 0) 114 return ret; 115 116 status = le16_to_cpu(cmd->status); 117 118 ret = wlcore_write_reg(wl, REG_INTERRUPT_ACK, 119 WL1271_ACX_INTR_CMD_COMPLETE); 120 if (ret < 0) 121 return ret; 122 123 return status; 124} 125 126/* 127 * send command to fw and return cmd status on success 128 * valid_rets contains a bitmap of allowed error codes 129 */ 130int wlcore_cmd_send_failsafe(struct wl1271 *wl, u16 id, void *buf, size_t len, 131 size_t res_len, unsigned long valid_rets) 132{ 133 int ret = __wlcore_cmd_send(wl, id, buf, len, res_len); 134 135 if (ret < 0) 136 goto fail; 137 138 /* success is always a valid status */ 139 valid_rets |= BIT(CMD_STATUS_SUCCESS); 140 141 if (ret >= MAX_COMMAND_STATUS || 142 !test_bit(ret, &valid_rets)) { 143 wl1271_error("command execute failure %d", ret); 144 ret = -EIO; 145 goto fail; 146 } 147 return ret; 148fail: 149 wl12xx_queue_recovery_work(wl); 150 return ret; 151} 152EXPORT_SYMBOL_GPL(wl1271_cmd_send); 153 154/* 155 * wrapper for wlcore_cmd_send that accept only CMD_STATUS_SUCCESS 156 * return 0 on success. 157 */ 158int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len, 159 size_t res_len) 160{ 161 int ret = wlcore_cmd_send_failsafe(wl, id, buf, len, res_len, 0); 162 163 if (ret < 0) 164 return ret; 165 return 0; 166} 167 168/* 169 * Poll the mailbox event field until any of the bits in the mask is set or a 170 * timeout occurs (WL1271_EVENT_TIMEOUT in msecs) 171 */ 172int wlcore_cmd_wait_for_event_or_timeout(struct wl1271 *wl, 173 u32 mask, bool *timeout) 174{ 175 u32 *events_vector; 176 u32 event; 177 unsigned long timeout_time; 178 u16 poll_count = 0; 179 int ret = 0; 180 181 *timeout = false; 182 183 events_vector = kmalloc(sizeof(*events_vector), GFP_KERNEL | GFP_DMA); 184 if (!events_vector) 185 return -ENOMEM; 186 187 timeout_time = jiffies + msecs_to_jiffies(WL1271_EVENT_TIMEOUT); 188 189 do { 190 if (time_after(jiffies, timeout_time)) { 191 wl1271_debug(DEBUG_CMD, "timeout waiting for event %d", 192 (int)mask); 193 *timeout = true; 194 goto out; 195 } 196 197 poll_count++; 198 if (poll_count < WL1271_WAIT_EVENT_FAST_POLL_COUNT) 199 usleep_range(50, 51); 200 else 201 usleep_range(1000, 5000); 202 203 /* read from both event fields */ 204 ret = wlcore_read(wl, wl->mbox_ptr[0], events_vector, 205 sizeof(*events_vector), false); 206 if (ret < 0) 207 goto out; 208 209 event = *events_vector & mask; 210 211 ret = wlcore_read(wl, wl->mbox_ptr[1], events_vector, 212 sizeof(*events_vector), false); 213 if (ret < 0) 214 goto out; 215 216 event |= *events_vector & mask; 217 } while (!event); 218 219out: 220 kfree(events_vector); 221 return ret; 222} 223EXPORT_SYMBOL_GPL(wlcore_cmd_wait_for_event_or_timeout); 224 225int wl12xx_cmd_role_enable(struct wl1271 *wl, u8 *addr, u8 role_type, 226 u8 *role_id) 227{ 228 struct wl12xx_cmd_role_enable *cmd; 229 int ret; 230 231 wl1271_debug(DEBUG_CMD, "cmd role enable"); 232 233 if (WARN_ON(*role_id != WL12XX_INVALID_ROLE_ID)) 234 return -EBUSY; 235 236 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 237 if (!cmd) { 238 ret = -ENOMEM; 239 goto out; 240 } 241 242 /* get role id */ 243 cmd->role_id = find_first_zero_bit(wl->roles_map, WL12XX_MAX_ROLES); 244 if (cmd->role_id >= WL12XX_MAX_ROLES) { 245 ret = -EBUSY; 246 goto out_free; 247 } 248 249 memcpy(cmd->mac_address, addr, ETH_ALEN); 250 cmd->role_type = role_type; 251 252 ret = wl1271_cmd_send(wl, CMD_ROLE_ENABLE, cmd, sizeof(*cmd), 0); 253 if (ret < 0) { 254 wl1271_error("failed to initiate cmd role enable"); 255 goto out_free; 256 } 257 258 __set_bit(cmd->role_id, wl->roles_map); 259 *role_id = cmd->role_id; 260 261out_free: 262 kfree(cmd); 263 264out: 265 return ret; 266} 267 268int wl12xx_cmd_role_disable(struct wl1271 *wl, u8 *role_id) 269{ 270 struct wl12xx_cmd_role_disable *cmd; 271 int ret; 272 273 wl1271_debug(DEBUG_CMD, "cmd role disable"); 274 275 if (WARN_ON(*role_id == WL12XX_INVALID_ROLE_ID)) 276 return -ENOENT; 277 278 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 279 if (!cmd) { 280 ret = -ENOMEM; 281 goto out; 282 } 283 cmd->role_id = *role_id; 284 285 ret = wl1271_cmd_send(wl, CMD_ROLE_DISABLE, cmd, sizeof(*cmd), 0); 286 if (ret < 0) { 287 wl1271_error("failed to initiate cmd role disable"); 288 goto out_free; 289 } 290 291 __clear_bit(*role_id, wl->roles_map); 292 *role_id = WL12XX_INVALID_ROLE_ID; 293 294out_free: 295 kfree(cmd); 296 297out: 298 return ret; 299} 300 301static int wlcore_get_new_session_id(struct wl1271 *wl, u8 hlid) 302{ 303 if (wl->session_ids[hlid] >= SESSION_COUNTER_MAX) 304 wl->session_ids[hlid] = 0; 305 306 wl->session_ids[hlid]++; 307 308 return wl->session_ids[hlid]; 309} 310 311int wl12xx_allocate_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid) 312{ 313 unsigned long flags; 314 u8 link = find_first_zero_bit(wl->links_map, WL12XX_MAX_LINKS); 315 if (link >= WL12XX_MAX_LINKS) 316 return -EBUSY; 317 318 wl->session_ids[link] = wlcore_get_new_session_id(wl, link); 319 320 /* these bits are used by op_tx */ 321 spin_lock_irqsave(&wl->wl_lock, flags); 322 __set_bit(link, wl->links_map); 323 __set_bit(link, wlvif->links_map); 324 spin_unlock_irqrestore(&wl->wl_lock, flags); 325 326 /* take the last "freed packets" value from the current FW status */ 327 wl->links[link].prev_freed_pkts = 328 wl->fw_status_2->counters.tx_lnk_free_pkts[link]; 329 wl->links[link].wlvif = wlvif; 330 *hlid = link; 331 return 0; 332} 333 334void wl12xx_free_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid) 335{ 336 unsigned long flags; 337 338 if (*hlid == WL12XX_INVALID_LINK_ID) 339 return; 340 341 /* these bits are used by op_tx */ 342 spin_lock_irqsave(&wl->wl_lock, flags); 343 __clear_bit(*hlid, wl->links_map); 344 __clear_bit(*hlid, wlvif->links_map); 345 spin_unlock_irqrestore(&wl->wl_lock, flags); 346 347 wl->links[*hlid].allocated_pkts = 0; 348 wl->links[*hlid].prev_freed_pkts = 0; 349 wl->links[*hlid].ba_bitmap = 0; 350 memset(wl->links[*hlid].addr, 0, ETH_ALEN); 351 352 /* 353 * At this point op_tx() will not add more packets to the queues. We 354 * can purge them. 355 */ 356 wl1271_tx_reset_link_queues(wl, *hlid); 357 wl->links[*hlid].wlvif = NULL; 358 359 *hlid = WL12XX_INVALID_LINK_ID; 360} 361 362static u8 wlcore_get_native_channel_type(u8 nl_channel_type) 363{ 364 switch (nl_channel_type) { 365 case NL80211_CHAN_NO_HT: 366 return WLCORE_CHAN_NO_HT; 367 case NL80211_CHAN_HT20: 368 return WLCORE_CHAN_HT20; 369 case NL80211_CHAN_HT40MINUS: 370 return WLCORE_CHAN_HT40MINUS; 371 case NL80211_CHAN_HT40PLUS: 372 return WLCORE_CHAN_HT40PLUS; 373 default: 374 WARN_ON(1); 375 return WLCORE_CHAN_NO_HT; 376 } 377} 378 379static int wl12xx_cmd_role_start_dev(struct wl1271 *wl, 380 struct wl12xx_vif *wlvif, 381 enum ieee80211_band band, 382 int channel) 383{ 384 struct wl12xx_cmd_role_start *cmd; 385 int ret; 386 387 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 388 if (!cmd) { 389 ret = -ENOMEM; 390 goto out; 391 } 392 393 wl1271_debug(DEBUG_CMD, "cmd role start dev %d", wlvif->dev_role_id); 394 395 cmd->role_id = wlvif->dev_role_id; 396 if (band == IEEE80211_BAND_5GHZ) 397 cmd->band = WLCORE_BAND_5GHZ; 398 cmd->channel = channel; 399 400 if (wlvif->dev_hlid == WL12XX_INVALID_LINK_ID) { 401 ret = wl12xx_allocate_link(wl, wlvif, &wlvif->dev_hlid); 402 if (ret) 403 goto out_free; 404 } 405 cmd->device.hlid = wlvif->dev_hlid; 406 cmd->device.session = wl->session_ids[wlvif->dev_hlid]; 407 408 wl1271_debug(DEBUG_CMD, "role start: roleid=%d, hlid=%d, session=%d", 409 cmd->role_id, cmd->device.hlid, cmd->device.session); 410 411 ret = wl1271_cmd_send(wl, CMD_ROLE_START, cmd, sizeof(*cmd), 0); 412 if (ret < 0) { 413 wl1271_error("failed to initiate cmd role enable"); 414 goto err_hlid; 415 } 416 417 goto out_free; 418 419err_hlid: 420 /* clear links on error */ 421 wl12xx_free_link(wl, wlvif, &wlvif->dev_hlid); 422 423out_free: 424 kfree(cmd); 425 426out: 427 return ret; 428} 429 430static int wl12xx_cmd_role_stop_dev(struct wl1271 *wl, 431 struct wl12xx_vif *wlvif) 432{ 433 struct wl12xx_cmd_role_stop *cmd; 434 int ret; 435 436 if (WARN_ON(wlvif->dev_hlid == WL12XX_INVALID_LINK_ID)) 437 return -EINVAL; 438 439 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 440 if (!cmd) { 441 ret = -ENOMEM; 442 goto out; 443 } 444 445 wl1271_debug(DEBUG_CMD, "cmd role stop dev"); 446 447 cmd->role_id = wlvif->dev_role_id; 448 cmd->disc_type = DISCONNECT_IMMEDIATE; 449 cmd->reason = cpu_to_le16(WLAN_REASON_UNSPECIFIED); 450 451 ret = wl1271_cmd_send(wl, CMD_ROLE_STOP, cmd, sizeof(*cmd), 0); 452 if (ret < 0) { 453 wl1271_error("failed to initiate cmd role stop"); 454 goto out_free; 455 } 456 457 wl12xx_free_link(wl, wlvif, &wlvif->dev_hlid); 458 459out_free: 460 kfree(cmd); 461 462out: 463 return ret; 464} 465 466int wl12xx_cmd_role_start_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif) 467{ 468 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); 469 struct wl12xx_cmd_role_start *cmd; 470 u32 supported_rates; 471 int ret; 472 473 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 474 if (!cmd) { 475 ret = -ENOMEM; 476 goto out; 477 } 478 479 wl1271_debug(DEBUG_CMD, "cmd role start sta %d", wlvif->role_id); 480 481 cmd->role_id = wlvif->role_id; 482 if (wlvif->band == IEEE80211_BAND_5GHZ) 483 cmd->band = WLCORE_BAND_5GHZ; 484 cmd->channel = wlvif->channel; 485 cmd->sta.basic_rate_set = cpu_to_le32(wlvif->basic_rate_set); 486 cmd->sta.beacon_interval = cpu_to_le16(wlvif->beacon_int); 487 cmd->sta.ssid_type = WL12XX_SSID_TYPE_ANY; 488 cmd->sta.ssid_len = wlvif->ssid_len; 489 memcpy(cmd->sta.ssid, wlvif->ssid, wlvif->ssid_len); 490 memcpy(cmd->sta.bssid, vif->bss_conf.bssid, ETH_ALEN); 491 492 supported_rates = CONF_TX_ENABLED_RATES | CONF_TX_MCS_RATES | 493 wlcore_hw_sta_get_ap_rate_mask(wl, wlvif); 494 if (wlvif->p2p) 495 supported_rates &= ~CONF_TX_CCK_RATES; 496 497 cmd->sta.local_rates = cpu_to_le32(supported_rates); 498 499 cmd->channel_type = wlcore_get_native_channel_type(wlvif->channel_type); 500 501 if (wlvif->sta.hlid == WL12XX_INVALID_LINK_ID) { 502 ret = wl12xx_allocate_link(wl, wlvif, &wlvif->sta.hlid); 503 if (ret) 504 goto out_free; 505 } 506 cmd->sta.hlid = wlvif->sta.hlid; 507 cmd->sta.session = wl->session_ids[wlvif->sta.hlid]; 508 /* 509 * We don't have the correct remote rates in this stage, and there 510 * is no way to update them later, so use our supported rates instead. 511 * The fw will take the configured rate policies into account anyway. 512 */ 513 cmd->sta.remote_rates = cpu_to_le32(supported_rates); 514 515 wl1271_debug(DEBUG_CMD, "role start: roleid=%d, hlid=%d, session=%d " 516 "basic_rate_set: 0x%x, remote_rates: 0x%x", 517 wlvif->role_id, cmd->sta.hlid, cmd->sta.session, 518 wlvif->basic_rate_set, wlvif->rate_set); 519 520 ret = wl1271_cmd_send(wl, CMD_ROLE_START, cmd, sizeof(*cmd), 0); 521 if (ret < 0) { 522 wl1271_error("failed to initiate cmd role start sta"); 523 goto err_hlid; 524 } 525 526 wlvif->sta.role_chan_type = wlvif->channel_type; 527 goto out_free; 528 529err_hlid: 530 /* clear links on error. */ 531 wl12xx_free_link(wl, wlvif, &wlvif->sta.hlid); 532 533out_free: 534 kfree(cmd); 535 536out: 537 return ret; 538} 539 540/* use this function to stop ibss as well */ 541int wl12xx_cmd_role_stop_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif) 542{ 543 struct wl12xx_cmd_role_stop *cmd; 544 int ret; 545 546 if (WARN_ON(wlvif->sta.hlid == WL12XX_INVALID_LINK_ID)) 547 return -EINVAL; 548 549 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 550 if (!cmd) { 551 ret = -ENOMEM; 552 goto out; 553 } 554 555 wl1271_debug(DEBUG_CMD, "cmd role stop sta %d", wlvif->role_id); 556 557 cmd->role_id = wlvif->role_id; 558 cmd->disc_type = DISCONNECT_IMMEDIATE; 559 cmd->reason = cpu_to_le16(WLAN_REASON_UNSPECIFIED); 560 561 ret = wl1271_cmd_send(wl, CMD_ROLE_STOP, cmd, sizeof(*cmd), 0); 562 if (ret < 0) { 563 wl1271_error("failed to initiate cmd role stop sta"); 564 goto out_free; 565 } 566 567 wl12xx_free_link(wl, wlvif, &wlvif->sta.hlid); 568 569out_free: 570 kfree(cmd); 571 572out: 573 return ret; 574} 575 576int wl12xx_cmd_role_start_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif) 577{ 578 struct wl12xx_cmd_role_start *cmd; 579 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); 580 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; 581 u32 supported_rates; 582 int ret; 583 584 wl1271_debug(DEBUG_CMD, "cmd role start ap %d", wlvif->role_id); 585 586 /* trying to use hidden SSID with an old hostapd version */ 587 if (wlvif->ssid_len == 0 && !bss_conf->hidden_ssid) { 588 wl1271_error("got a null SSID from beacon/bss"); 589 ret = -EINVAL; 590 goto out; 591 } 592 593 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 594 if (!cmd) { 595 ret = -ENOMEM; 596 goto out; 597 } 598 599 ret = wl12xx_allocate_link(wl, wlvif, &wlvif->ap.global_hlid); 600 if (ret < 0) 601 goto out_free; 602 603 ret = wl12xx_allocate_link(wl, wlvif, &wlvif->ap.bcast_hlid); 604 if (ret < 0) 605 goto out_free_global; 606 607 cmd->role_id = wlvif->role_id; 608 cmd->ap.aging_period = cpu_to_le16(wl->conf.tx.ap_aging_period); 609 cmd->ap.bss_index = WL1271_AP_BSS_INDEX; 610 cmd->ap.global_hlid = wlvif->ap.global_hlid; 611 cmd->ap.broadcast_hlid = wlvif->ap.bcast_hlid; 612 cmd->ap.global_session_id = wl->session_ids[wlvif->ap.global_hlid]; 613 cmd->ap.bcast_session_id = wl->session_ids[wlvif->ap.bcast_hlid]; 614 cmd->ap.basic_rate_set = cpu_to_le32(wlvif->basic_rate_set); 615 cmd->ap.beacon_interval = cpu_to_le16(wlvif->beacon_int); 616 cmd->ap.dtim_interval = bss_conf->dtim_period; 617 cmd->ap.beacon_expiry = WL1271_AP_DEF_BEACON_EXP; 618 /* FIXME: Change when adding DFS */ 619 cmd->ap.reset_tsf = 1; /* By default reset AP TSF */ 620 cmd->ap.wmm = wlvif->wmm_enabled; 621 cmd->channel = wlvif->channel; 622 cmd->channel_type = wlcore_get_native_channel_type(wlvif->channel_type); 623 624 if (!bss_conf->hidden_ssid) { 625 /* take the SSID from the beacon for backward compatibility */ 626 cmd->ap.ssid_type = WL12XX_SSID_TYPE_PUBLIC; 627 cmd->ap.ssid_len = wlvif->ssid_len; 628 memcpy(cmd->ap.ssid, wlvif->ssid, wlvif->ssid_len); 629 } else { 630 cmd->ap.ssid_type = WL12XX_SSID_TYPE_HIDDEN; 631 cmd->ap.ssid_len = bss_conf->ssid_len; 632 memcpy(cmd->ap.ssid, bss_conf->ssid, bss_conf->ssid_len); 633 } 634 635 supported_rates = CONF_TX_ENABLED_RATES | CONF_TX_MCS_RATES | 636 wlcore_hw_ap_get_mimo_wide_rate_mask(wl, wlvif); 637 if (wlvif->p2p) 638 supported_rates &= ~CONF_TX_CCK_RATES; 639 640 wl1271_debug(DEBUG_CMD, "cmd role start ap with supported_rates 0x%08x", 641 supported_rates); 642 643 cmd->ap.local_rates = cpu_to_le32(supported_rates); 644 645 switch (wlvif->band) { 646 case IEEE80211_BAND_2GHZ: 647 cmd->band = WLCORE_BAND_2_4GHZ; 648 break; 649 case IEEE80211_BAND_5GHZ: 650 cmd->band = WLCORE_BAND_5GHZ; 651 break; 652 default: 653 wl1271_warning("ap start - unknown band: %d", (int)wlvif->band); 654 cmd->band = WLCORE_BAND_2_4GHZ; 655 break; 656 } 657 658 ret = wl1271_cmd_send(wl, CMD_ROLE_START, cmd, sizeof(*cmd), 0); 659 if (ret < 0) { 660 wl1271_error("failed to initiate cmd role start ap"); 661 goto out_free_bcast; 662 } 663 664 goto out_free; 665 666out_free_bcast: 667 wl12xx_free_link(wl, wlvif, &wlvif->ap.bcast_hlid); 668 669out_free_global: 670 wl12xx_free_link(wl, wlvif, &wlvif->ap.global_hlid); 671 672out_free: 673 kfree(cmd); 674 675out: 676 return ret; 677} 678 679int wl12xx_cmd_role_stop_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif) 680{ 681 struct wl12xx_cmd_role_stop *cmd; 682 int ret; 683 684 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 685 if (!cmd) { 686 ret = -ENOMEM; 687 goto out; 688 } 689 690 wl1271_debug(DEBUG_CMD, "cmd role stop ap %d", wlvif->role_id); 691 692 cmd->role_id = wlvif->role_id; 693 694 ret = wl1271_cmd_send(wl, CMD_ROLE_STOP, cmd, sizeof(*cmd), 0); 695 if (ret < 0) { 696 wl1271_error("failed to initiate cmd role stop ap"); 697 goto out_free; 698 } 699 700 wl12xx_free_link(wl, wlvif, &wlvif->ap.bcast_hlid); 701 wl12xx_free_link(wl, wlvif, &wlvif->ap.global_hlid); 702 703out_free: 704 kfree(cmd); 705 706out: 707 return ret; 708} 709 710int wl12xx_cmd_role_start_ibss(struct wl1271 *wl, struct wl12xx_vif *wlvif) 711{ 712 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); 713 struct wl12xx_cmd_role_start *cmd; 714 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; 715 int ret; 716 717 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 718 if (!cmd) { 719 ret = -ENOMEM; 720 goto out; 721 } 722 723 wl1271_debug(DEBUG_CMD, "cmd role start ibss %d", wlvif->role_id); 724 725 cmd->role_id = wlvif->role_id; 726 if (wlvif->band == IEEE80211_BAND_5GHZ) 727 cmd->band = WLCORE_BAND_5GHZ; 728 cmd->channel = wlvif->channel; 729 cmd->ibss.basic_rate_set = cpu_to_le32(wlvif->basic_rate_set); 730 cmd->ibss.beacon_interval = cpu_to_le16(wlvif->beacon_int); 731 cmd->ibss.dtim_interval = bss_conf->dtim_period; 732 cmd->ibss.ssid_type = WL12XX_SSID_TYPE_ANY; 733 cmd->ibss.ssid_len = wlvif->ssid_len; 734 memcpy(cmd->ibss.ssid, wlvif->ssid, wlvif->ssid_len); 735 memcpy(cmd->ibss.bssid, vif->bss_conf.bssid, ETH_ALEN); 736 cmd->sta.local_rates = cpu_to_le32(wlvif->rate_set); 737 738 if (wlvif->sta.hlid == WL12XX_INVALID_LINK_ID) { 739 ret = wl12xx_allocate_link(wl, wlvif, &wlvif->sta.hlid); 740 if (ret) 741 goto out_free; 742 } 743 cmd->ibss.hlid = wlvif->sta.hlid; 744 cmd->ibss.remote_rates = cpu_to_le32(wlvif->rate_set); 745 746 wl1271_debug(DEBUG_CMD, "role start: roleid=%d, hlid=%d, session=%d " 747 "basic_rate_set: 0x%x, remote_rates: 0x%x", 748 wlvif->role_id, cmd->sta.hlid, cmd->sta.session, 749 wlvif->basic_rate_set, wlvif->rate_set); 750 751 wl1271_debug(DEBUG_CMD, "vif->bss_conf.bssid = %pM", 752 vif->bss_conf.bssid); 753 754 ret = wl1271_cmd_send(wl, CMD_ROLE_START, cmd, sizeof(*cmd), 0); 755 if (ret < 0) { 756 wl1271_error("failed to initiate cmd role enable"); 757 goto err_hlid; 758 } 759 760 goto out_free; 761 762err_hlid: 763 /* clear links on error. */ 764 wl12xx_free_link(wl, wlvif, &wlvif->sta.hlid); 765 766out_free: 767 kfree(cmd); 768 769out: 770 return ret; 771} 772 773 774/** 775 * send test command to firmware 776 * 777 * @wl: wl struct 778 * @buf: buffer containing the command, with all headers, must work with dma 779 * @len: length of the buffer 780 * @answer: is answer needed 781 */ 782int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer) 783{ 784 int ret; 785 size_t res_len = 0; 786 787 wl1271_debug(DEBUG_CMD, "cmd test"); 788 789 if (answer) 790 res_len = buf_len; 791 792 ret = wl1271_cmd_send(wl, CMD_TEST, buf, buf_len, res_len); 793 794 if (ret < 0) { 795 wl1271_warning("TEST command failed"); 796 return ret; 797 } 798 799 return ret; 800} 801EXPORT_SYMBOL_GPL(wl1271_cmd_test); 802 803/** 804 * read acx from firmware 805 * 806 * @wl: wl struct 807 * @id: acx id 808 * @buf: buffer for the response, including all headers, must work with dma 809 * @len: length of buf 810 */ 811int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len) 812{ 813 struct acx_header *acx = buf; 814 int ret; 815 816 wl1271_debug(DEBUG_CMD, "cmd interrogate"); 817 818 acx->id = cpu_to_le16(id); 819 820 /* payload length, does not include any headers */ 821 acx->len = cpu_to_le16(len - sizeof(*acx)); 822 823 ret = wl1271_cmd_send(wl, CMD_INTERROGATE, acx, sizeof(*acx), len); 824 if (ret < 0) 825 wl1271_error("INTERROGATE command failed"); 826 827 return ret; 828} 829 830/** 831 * write acx value to firmware 832 * 833 * @wl: wl struct 834 * @id: acx id 835 * @buf: buffer containing acx, including all headers, must work with dma 836 * @len: length of buf 837 * @valid_rets: bitmap of valid cmd status codes (i.e. return values). 838 * return the cmd status on success. 839 */ 840int wlcore_cmd_configure_failsafe(struct wl1271 *wl, u16 id, void *buf, 841 size_t len, unsigned long valid_rets) 842{ 843 struct acx_header *acx = buf; 844 int ret; 845 846 wl1271_debug(DEBUG_CMD, "cmd configure (%d)", id); 847 848 acx->id = cpu_to_le16(id); 849 850 /* payload length, does not include any headers */ 851 acx->len = cpu_to_le16(len - sizeof(*acx)); 852 853 ret = wlcore_cmd_send_failsafe(wl, CMD_CONFIGURE, acx, len, 0, 854 valid_rets); 855 if (ret < 0) { 856 wl1271_warning("CONFIGURE command NOK"); 857 return ret; 858 } 859 860 return ret; 861} 862 863/* 864 * wrapper for wlcore_cmd_configure that accepts only success status. 865 * return 0 on success 866 */ 867int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len) 868{ 869 int ret = wlcore_cmd_configure_failsafe(wl, id, buf, len, 0); 870 871 if (ret < 0) 872 return ret; 873 return 0; 874} 875EXPORT_SYMBOL_GPL(wl1271_cmd_configure); 876 877int wl1271_cmd_data_path(struct wl1271 *wl, bool enable) 878{ 879 struct cmd_enabledisable_path *cmd; 880 int ret; 881 u16 cmd_rx, cmd_tx; 882 883 wl1271_debug(DEBUG_CMD, "cmd data path"); 884 885 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 886 if (!cmd) { 887 ret = -ENOMEM; 888 goto out; 889 } 890 891 /* the channel here is only used for calibration, so hardcoded to 1 */ 892 cmd->channel = 1; 893 894 if (enable) { 895 cmd_rx = CMD_ENABLE_RX; 896 cmd_tx = CMD_ENABLE_TX; 897 } else { 898 cmd_rx = CMD_DISABLE_RX; 899 cmd_tx = CMD_DISABLE_TX; 900 } 901 902 ret = wl1271_cmd_send(wl, cmd_rx, cmd, sizeof(*cmd), 0); 903 if (ret < 0) { 904 wl1271_error("rx %s cmd for channel %d failed", 905 enable ? "start" : "stop", cmd->channel); 906 goto out; 907 } 908 909 wl1271_debug(DEBUG_BOOT, "rx %s cmd channel %d", 910 enable ? "start" : "stop", cmd->channel); 911 912 ret = wl1271_cmd_send(wl, cmd_tx, cmd, sizeof(*cmd), 0); 913 if (ret < 0) { 914 wl1271_error("tx %s cmd for channel %d failed", 915 enable ? "start" : "stop", cmd->channel); 916 goto out; 917 } 918 919 wl1271_debug(DEBUG_BOOT, "tx %s cmd channel %d", 920 enable ? "start" : "stop", cmd->channel); 921 922out: 923 kfree(cmd); 924 return ret; 925} 926EXPORT_SYMBOL_GPL(wl1271_cmd_data_path); 927 928int wl1271_cmd_ps_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif, 929 u8 ps_mode, u16 auto_ps_timeout) 930{ 931 struct wl1271_cmd_ps_params *ps_params = NULL; 932 int ret = 0; 933 934 wl1271_debug(DEBUG_CMD, "cmd set ps mode"); 935 936 ps_params = kzalloc(sizeof(*ps_params), GFP_KERNEL); 937 if (!ps_params) { 938 ret = -ENOMEM; 939 goto out; 940 } 941 942 ps_params->role_id = wlvif->role_id; 943 ps_params->ps_mode = ps_mode; 944 ps_params->auto_ps_timeout = auto_ps_timeout; 945 946 ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params, 947 sizeof(*ps_params), 0); 948 if (ret < 0) { 949 wl1271_error("cmd set_ps_mode failed"); 950 goto out; 951 } 952 953out: 954 kfree(ps_params); 955 return ret; 956} 957 958int wl1271_cmd_template_set(struct wl1271 *wl, u8 role_id, 959 u16 template_id, void *buf, size_t buf_len, 960 int index, u32 rates) 961{ 962 struct wl1271_cmd_template_set *cmd; 963 int ret = 0; 964 965 wl1271_debug(DEBUG_CMD, "cmd template_set %d (role %d)", 966 template_id, role_id); 967 968 WARN_ON(buf_len > WL1271_CMD_TEMPL_MAX_SIZE); 969 buf_len = min_t(size_t, buf_len, WL1271_CMD_TEMPL_MAX_SIZE); 970 971 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 972 if (!cmd) { 973 ret = -ENOMEM; 974 goto out; 975 } 976 977 /* during initialization wlvif is NULL */ 978 cmd->role_id = role_id; 979 cmd->len = cpu_to_le16(buf_len); 980 cmd->template_type = template_id; 981 cmd->enabled_rates = cpu_to_le32(rates); 982 cmd->short_retry_limit = wl->conf.tx.tmpl_short_retry_limit; 983 cmd->long_retry_limit = wl->conf.tx.tmpl_long_retry_limit; 984 cmd->index = index; 985 986 if (buf) 987 memcpy(cmd->template_data, buf, buf_len); 988 989 ret = wl1271_cmd_send(wl, CMD_SET_TEMPLATE, cmd, sizeof(*cmd), 0); 990 if (ret < 0) { 991 wl1271_warning("cmd set_template failed: %d", ret); 992 goto out_free; 993 } 994 995out_free: 996 kfree(cmd); 997 998out: 999 return ret; 1000} 1001 1002int wl12xx_cmd_build_null_data(struct wl1271 *wl, struct wl12xx_vif *wlvif) 1003{ 1004 struct sk_buff *skb = NULL; 1005 int size; 1006 void *ptr; 1007 int ret = -ENOMEM; 1008 1009 1010 if (wlvif->bss_type == BSS_TYPE_IBSS) { 1011 size = sizeof(struct wl12xx_null_data_template); 1012 ptr = NULL; 1013 } else { 1014 skb = ieee80211_nullfunc_get(wl->hw, 1015 wl12xx_wlvif_to_vif(wlvif)); 1016 if (!skb) 1017 goto out; 1018 size = skb->len; 1019 ptr = skb->data; 1020 } 1021 1022 ret = wl1271_cmd_template_set(wl, wlvif->role_id, 1023 CMD_TEMPL_NULL_DATA, ptr, size, 0, 1024 wlvif->basic_rate); 1025 1026out: 1027 dev_kfree_skb(skb); 1028 if (ret) 1029 wl1271_warning("cmd buld null data failed %d", ret); 1030 1031 return ret; 1032 1033} 1034 1035int wl12xx_cmd_build_klv_null_data(struct wl1271 *wl, 1036 struct wl12xx_vif *wlvif) 1037{ 1038 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); 1039 struct sk_buff *skb = NULL; 1040 int ret = -ENOMEM; 1041 1042 skb = ieee80211_nullfunc_get(wl->hw, vif); 1043 if (!skb) 1044 goto out; 1045 1046 ret = wl1271_cmd_template_set(wl, wlvif->role_id, CMD_TEMPL_KLV, 1047 skb->data, skb->len, 1048 wlvif->sta.klv_template_id, 1049 wlvif->basic_rate); 1050 1051out: 1052 dev_kfree_skb(skb); 1053 if (ret) 1054 wl1271_warning("cmd build klv null data failed %d", ret); 1055 1056 return ret; 1057 1058} 1059 1060int wl1271_cmd_build_ps_poll(struct wl1271 *wl, struct wl12xx_vif *wlvif, 1061 u16 aid) 1062{ 1063 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); 1064 struct sk_buff *skb; 1065 int ret = 0; 1066 1067 skb = ieee80211_pspoll_get(wl->hw, vif); 1068 if (!skb) 1069 goto out; 1070 1071 ret = wl1271_cmd_template_set(wl, wlvif->role_id, 1072 CMD_TEMPL_PS_POLL, skb->data, 1073 skb->len, 0, wlvif->basic_rate_set); 1074 1075out: 1076 dev_kfree_skb(skb); 1077 return ret; 1078} 1079 1080int wl12xx_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif, 1081 u8 role_id, u8 band, 1082 const u8 *ssid, size_t ssid_len, 1083 const u8 *ie, size_t ie_len, bool sched_scan) 1084{ 1085 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); 1086 struct sk_buff *skb; 1087 int ret; 1088 u32 rate; 1089 u16 template_id_2_4 = wl->scan_templ_id_2_4; 1090 u16 template_id_5 = wl->scan_templ_id_5; 1091 1092 skb = ieee80211_probereq_get(wl->hw, vif, ssid, ssid_len, 1093 ie, ie_len); 1094 if (!skb) { 1095 ret = -ENOMEM; 1096 goto out; 1097 } 1098 1099 wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", skb->data, skb->len); 1100 1101 if (sched_scan && 1102 (wl->quirks & WLCORE_QUIRK_DUAL_PROBE_TMPL)) { 1103 template_id_2_4 = wl->sched_scan_templ_id_2_4; 1104 template_id_5 = wl->sched_scan_templ_id_5; 1105 } 1106 1107 rate = wl1271_tx_min_rate_get(wl, wlvif->bitrate_masks[band]); 1108 if (band == IEEE80211_BAND_2GHZ) 1109 ret = wl1271_cmd_template_set(wl, role_id, 1110 template_id_2_4, 1111 skb->data, skb->len, 0, rate); 1112 else 1113 ret = wl1271_cmd_template_set(wl, role_id, 1114 template_id_5, 1115 skb->data, skb->len, 0, rate); 1116 1117out: 1118 dev_kfree_skb(skb); 1119 return ret; 1120} 1121EXPORT_SYMBOL_GPL(wl12xx_cmd_build_probe_req); 1122 1123struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl, 1124 struct wl12xx_vif *wlvif, 1125 struct sk_buff *skb) 1126{ 1127 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); 1128 int ret; 1129 u32 rate; 1130 1131 if (!skb) 1132 skb = ieee80211_ap_probereq_get(wl->hw, vif); 1133 if (!skb) 1134 goto out; 1135 1136 wl1271_dump(DEBUG_SCAN, "AP PROBE REQ: ", skb->data, skb->len); 1137 1138 rate = wl1271_tx_min_rate_get(wl, wlvif->bitrate_masks[wlvif->band]); 1139 if (wlvif->band == IEEE80211_BAND_2GHZ) 1140 ret = wl1271_cmd_template_set(wl, wlvif->role_id, 1141 CMD_TEMPL_CFG_PROBE_REQ_2_4, 1142 skb->data, skb->len, 0, rate); 1143 else 1144 ret = wl1271_cmd_template_set(wl, wlvif->role_id, 1145 CMD_TEMPL_CFG_PROBE_REQ_5, 1146 skb->data, skb->len, 0, rate); 1147 1148 if (ret < 0) 1149 wl1271_error("Unable to set ap probe request template."); 1150 1151out: 1152 return skb; 1153} 1154 1155int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, struct wl12xx_vif *wlvif) 1156{ 1157 int ret, extra = 0; 1158 u16 fc; 1159 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); 1160 struct sk_buff *skb; 1161 struct wl12xx_arp_rsp_template *tmpl; 1162 struct ieee80211_hdr_3addr *hdr; 1163 struct arphdr *arp_hdr; 1164 1165 skb = dev_alloc_skb(sizeof(*hdr) + sizeof(__le16) + sizeof(*tmpl) + 1166 WL1271_EXTRA_SPACE_MAX); 1167 if (!skb) { 1168 wl1271_error("failed to allocate buffer for arp rsp template"); 1169 return -ENOMEM; 1170 } 1171 1172 skb_reserve(skb, sizeof(*hdr) + WL1271_EXTRA_SPACE_MAX); 1173 1174 tmpl = (struct wl12xx_arp_rsp_template *)skb_put(skb, sizeof(*tmpl)); 1175 memset(tmpl, 0, sizeof(*tmpl)); 1176 1177 /* llc layer */ 1178 memcpy(tmpl->llc_hdr, rfc1042_header, sizeof(rfc1042_header)); 1179 tmpl->llc_type = cpu_to_be16(ETH_P_ARP); 1180 1181 /* arp header */ 1182 arp_hdr = &tmpl->arp_hdr; 1183 arp_hdr->ar_hrd = cpu_to_be16(ARPHRD_ETHER); 1184 arp_hdr->ar_pro = cpu_to_be16(ETH_P_IP); 1185 arp_hdr->ar_hln = ETH_ALEN; 1186 arp_hdr->ar_pln = 4; 1187 arp_hdr->ar_op = cpu_to_be16(ARPOP_REPLY); 1188 1189 /* arp payload */ 1190 memcpy(tmpl->sender_hw, vif->addr, ETH_ALEN); 1191 tmpl->sender_ip = wlvif->ip_addr; 1192 1193 /* encryption space */ 1194 switch (wlvif->encryption_type) { 1195 case KEY_TKIP: 1196 if (wl->quirks & WLCORE_QUIRK_TKIP_HEADER_SPACE) 1197 extra = WL1271_EXTRA_SPACE_TKIP; 1198 break; 1199 case KEY_AES: 1200 extra = WL1271_EXTRA_SPACE_AES; 1201 break; 1202 case KEY_NONE: 1203 case KEY_WEP: 1204 case KEY_GEM: 1205 extra = 0; 1206 break; 1207 default: 1208 wl1271_warning("Unknown encryption type: %d", 1209 wlvif->encryption_type); 1210 ret = -EINVAL; 1211 goto out; 1212 } 1213 1214 if (extra) { 1215 u8 *space = skb_push(skb, extra); 1216 memset(space, 0, extra); 1217 } 1218 1219 /* QoS header - BE */ 1220 if (wlvif->sta.qos) 1221 memset(skb_push(skb, sizeof(__le16)), 0, sizeof(__le16)); 1222 1223 /* mac80211 header */ 1224 hdr = (struct ieee80211_hdr_3addr *)skb_push(skb, sizeof(*hdr)); 1225 memset(hdr, 0, sizeof(*hdr)); 1226 fc = IEEE80211_FTYPE_DATA | IEEE80211_FCTL_TODS; 1227 if (wlvif->sta.qos) 1228 fc |= IEEE80211_STYPE_QOS_DATA; 1229 else 1230 fc |= IEEE80211_STYPE_DATA; 1231 if (wlvif->encryption_type != KEY_NONE) 1232 fc |= IEEE80211_FCTL_PROTECTED; 1233 1234 hdr->frame_control = cpu_to_le16(fc); 1235 memcpy(hdr->addr1, vif->bss_conf.bssid, ETH_ALEN); 1236 memcpy(hdr->addr2, vif->addr, ETH_ALEN); 1237 memset(hdr->addr3, 0xff, ETH_ALEN); 1238 1239 ret = wl1271_cmd_template_set(wl, wlvif->role_id, CMD_TEMPL_ARP_RSP, 1240 skb->data, skb->len, 0, 1241 wlvif->basic_rate); 1242out: 1243 dev_kfree_skb(skb); 1244 return ret; 1245} 1246 1247int wl1271_build_qos_null_data(struct wl1271 *wl, struct ieee80211_vif *vif) 1248{ 1249 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 1250 struct ieee80211_qos_hdr template; 1251 1252 memset(&template, 0, sizeof(template)); 1253 1254 memcpy(template.addr1, vif->bss_conf.bssid, ETH_ALEN); 1255 memcpy(template.addr2, vif->addr, ETH_ALEN); 1256 memcpy(template.addr3, vif->bss_conf.bssid, ETH_ALEN); 1257 1258 template.frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA | 1259 IEEE80211_STYPE_QOS_NULLFUNC | 1260 IEEE80211_FCTL_TODS); 1261 1262 /* FIXME: not sure what priority to use here */ 1263 template.qos_ctrl = cpu_to_le16(0); 1264 1265 return wl1271_cmd_template_set(wl, wlvif->role_id, 1266 CMD_TEMPL_QOS_NULL_DATA, &template, 1267 sizeof(template), 0, 1268 wlvif->basic_rate); 1269} 1270 1271int wl12xx_cmd_set_default_wep_key(struct wl1271 *wl, u8 id, u8 hlid) 1272{ 1273 struct wl1271_cmd_set_keys *cmd; 1274 int ret = 0; 1275 1276 wl1271_debug(DEBUG_CMD, "cmd set_default_wep_key %d", id); 1277 1278 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 1279 if (!cmd) { 1280 ret = -ENOMEM; 1281 goto out; 1282 } 1283 1284 cmd->hlid = hlid; 1285 cmd->key_id = id; 1286 cmd->lid_key_type = WEP_DEFAULT_LID_TYPE; 1287 cmd->key_action = cpu_to_le16(KEY_SET_ID); 1288 cmd->key_type = KEY_WEP; 1289 1290 ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd), 0); 1291 if (ret < 0) { 1292 wl1271_warning("cmd set_default_wep_key failed: %d", ret); 1293 goto out; 1294 } 1295 1296out: 1297 kfree(cmd); 1298 1299 return ret; 1300} 1301 1302int wl1271_cmd_set_sta_key(struct wl1271 *wl, struct wl12xx_vif *wlvif, 1303 u16 action, u8 id, u8 key_type, 1304 u8 key_size, const u8 *key, const u8 *addr, 1305 u32 tx_seq_32, u16 tx_seq_16) 1306{ 1307 struct wl1271_cmd_set_keys *cmd; 1308 int ret = 0; 1309 1310 /* hlid might have already been deleted */ 1311 if (wlvif->sta.hlid == WL12XX_INVALID_LINK_ID) 1312 return 0; 1313 1314 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 1315 if (!cmd) { 1316 ret = -ENOMEM; 1317 goto out; 1318 } 1319 1320 cmd->hlid = wlvif->sta.hlid; 1321 1322 if (key_type == KEY_WEP) 1323 cmd->lid_key_type = WEP_DEFAULT_LID_TYPE; 1324 else if (is_broadcast_ether_addr(addr)) 1325 cmd->lid_key_type = BROADCAST_LID_TYPE; 1326 else 1327 cmd->lid_key_type = UNICAST_LID_TYPE; 1328 1329 cmd->key_action = cpu_to_le16(action); 1330 cmd->key_size = key_size; 1331 cmd->key_type = key_type; 1332 1333 cmd->ac_seq_num16[0] = cpu_to_le16(tx_seq_16); 1334 cmd->ac_seq_num32[0] = cpu_to_le32(tx_seq_32); 1335 1336 cmd->key_id = id; 1337 1338 if (key_type == KEY_TKIP) { 1339 /* 1340 * We get the key in the following form: 1341 * TKIP (16 bytes) - TX MIC (8 bytes) - RX MIC (8 bytes) 1342 * but the target is expecting: 1343 * TKIP - RX MIC - TX MIC 1344 */ 1345 memcpy(cmd->key, key, 16); 1346 memcpy(cmd->key + 16, key + 24, 8); 1347 memcpy(cmd->key + 24, key + 16, 8); 1348 1349 } else { 1350 memcpy(cmd->key, key, key_size); 1351 } 1352 1353 wl1271_dump(DEBUG_CRYPT, "TARGET KEY: ", cmd, sizeof(*cmd)); 1354 1355 ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd), 0); 1356 if (ret < 0) { 1357 wl1271_warning("could not set keys"); 1358 goto out; 1359 } 1360 1361out: 1362 kfree(cmd); 1363 1364 return ret; 1365} 1366 1367/* 1368 * TODO: merge with sta/ibss into 1 set_key function. 1369 * note there are slight diffs 1370 */ 1371int wl1271_cmd_set_ap_key(struct wl1271 *wl, struct wl12xx_vif *wlvif, 1372 u16 action, u8 id, u8 key_type, 1373 u8 key_size, const u8 *key, u8 hlid, u32 tx_seq_32, 1374 u16 tx_seq_16) 1375{ 1376 struct wl1271_cmd_set_keys *cmd; 1377 int ret = 0; 1378 u8 lid_type; 1379 1380 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 1381 if (!cmd) 1382 return -ENOMEM; 1383 1384 if (hlid == wlvif->ap.bcast_hlid) { 1385 if (key_type == KEY_WEP) 1386 lid_type = WEP_DEFAULT_LID_TYPE; 1387 else 1388 lid_type = BROADCAST_LID_TYPE; 1389 } else { 1390 lid_type = UNICAST_LID_TYPE; 1391 } 1392 1393 wl1271_debug(DEBUG_CRYPT, "ap key action: %d id: %d lid: %d type: %d" 1394 " hlid: %d", (int)action, (int)id, (int)lid_type, 1395 (int)key_type, (int)hlid); 1396 1397 cmd->lid_key_type = lid_type; 1398 cmd->hlid = hlid; 1399 cmd->key_action = cpu_to_le16(action); 1400 cmd->key_size = key_size; 1401 cmd->key_type = key_type; 1402 cmd->key_id = id; 1403 cmd->ac_seq_num16[0] = cpu_to_le16(tx_seq_16); 1404 cmd->ac_seq_num32[0] = cpu_to_le32(tx_seq_32); 1405 1406 if (key_type == KEY_TKIP) { 1407 /* 1408 * We get the key in the following form: 1409 * TKIP (16 bytes) - TX MIC (8 bytes) - RX MIC (8 bytes) 1410 * but the target is expecting: 1411 * TKIP - RX MIC - TX MIC 1412 */ 1413 memcpy(cmd->key, key, 16); 1414 memcpy(cmd->key + 16, key + 24, 8); 1415 memcpy(cmd->key + 24, key + 16, 8); 1416 } else { 1417 memcpy(cmd->key, key, key_size); 1418 } 1419 1420 wl1271_dump(DEBUG_CRYPT, "TARGET AP KEY: ", cmd, sizeof(*cmd)); 1421 1422 ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd), 0); 1423 if (ret < 0) { 1424 wl1271_warning("could not set ap keys"); 1425 goto out; 1426 } 1427 1428out: 1429 kfree(cmd); 1430 return ret; 1431} 1432 1433int wl12xx_cmd_set_peer_state(struct wl1271 *wl, struct wl12xx_vif *wlvif, 1434 u8 hlid) 1435{ 1436 struct wl12xx_cmd_set_peer_state *cmd; 1437 int ret = 0; 1438 1439 wl1271_debug(DEBUG_CMD, "cmd set peer state (hlid=%d)", hlid); 1440 1441 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 1442 if (!cmd) { 1443 ret = -ENOMEM; 1444 goto out; 1445 } 1446 1447 cmd->hlid = hlid; 1448 cmd->state = WL1271_CMD_STA_STATE_CONNECTED; 1449 1450 /* wmm param is valid only for station role */ 1451 if (wlvif->bss_type == BSS_TYPE_STA_BSS) 1452 cmd->wmm = wlvif->wmm_enabled; 1453 1454 ret = wl1271_cmd_send(wl, CMD_SET_PEER_STATE, cmd, sizeof(*cmd), 0); 1455 if (ret < 0) { 1456 wl1271_error("failed to send set peer state command"); 1457 goto out_free; 1458 } 1459 1460out_free: 1461 kfree(cmd); 1462 1463out: 1464 return ret; 1465} 1466 1467int wl12xx_cmd_add_peer(struct wl1271 *wl, struct wl12xx_vif *wlvif, 1468 struct ieee80211_sta *sta, u8 hlid) 1469{ 1470 struct wl12xx_cmd_add_peer *cmd; 1471 int i, ret; 1472 u32 sta_rates; 1473 1474 wl1271_debug(DEBUG_CMD, "cmd add peer %d", (int)hlid); 1475 1476 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 1477 if (!cmd) { 1478 ret = -ENOMEM; 1479 goto out; 1480 } 1481 1482 memcpy(cmd->addr, sta->addr, ETH_ALEN); 1483 cmd->bss_index = WL1271_AP_BSS_INDEX; 1484 cmd->aid = sta->aid; 1485 cmd->hlid = hlid; 1486 cmd->sp_len = sta->max_sp; 1487 cmd->wmm = sta->wme ? 1 : 0; 1488 cmd->session_id = wl->session_ids[hlid]; 1489 1490 for (i = 0; i < NUM_ACCESS_CATEGORIES_COPY; i++) 1491 if (sta->wme && (sta->uapsd_queues & BIT(i))) 1492 cmd->psd_type[NUM_ACCESS_CATEGORIES_COPY-1-i] = 1493 WL1271_PSD_UPSD_TRIGGER; 1494 else 1495 cmd->psd_type[NUM_ACCESS_CATEGORIES_COPY-1-i] = 1496 WL1271_PSD_LEGACY; 1497 1498 1499 sta_rates = sta->supp_rates[wlvif->band]; 1500 if (sta->ht_cap.ht_supported) 1501 sta_rates |= 1502 (sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET) | 1503 (sta->ht_cap.mcs.rx_mask[1] << HW_MIMO_RATES_OFFSET); 1504 1505 cmd->supported_rates = 1506 cpu_to_le32(wl1271_tx_enabled_rates_get(wl, sta_rates, 1507 wlvif->band)); 1508 1509 wl1271_debug(DEBUG_CMD, "new peer rates=0x%x queues=0x%x", 1510 cmd->supported_rates, sta->uapsd_queues); 1511 1512 ret = wl1271_cmd_send(wl, CMD_ADD_PEER, cmd, sizeof(*cmd), 0); 1513 if (ret < 0) { 1514 wl1271_error("failed to initiate cmd add peer"); 1515 goto out_free; 1516 } 1517 1518out_free: 1519 kfree(cmd); 1520 1521out: 1522 return ret; 1523} 1524 1525int wl12xx_cmd_remove_peer(struct wl1271 *wl, u8 hlid) 1526{ 1527 struct wl12xx_cmd_remove_peer *cmd; 1528 int ret; 1529 bool timeout = false; 1530 1531 wl1271_debug(DEBUG_CMD, "cmd remove peer %d", (int)hlid); 1532 1533 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 1534 if (!cmd) { 1535 ret = -ENOMEM; 1536 goto out; 1537 } 1538 1539 cmd->hlid = hlid; 1540 /* We never send a deauth, mac80211 is in charge of this */ 1541 cmd->reason_opcode = 0; 1542 cmd->send_deauth_flag = 0; 1543 1544 ret = wl1271_cmd_send(wl, CMD_REMOVE_PEER, cmd, sizeof(*cmd), 0); 1545 if (ret < 0) { 1546 wl1271_error("failed to initiate cmd remove peer"); 1547 goto out_free; 1548 } 1549 1550 ret = wl->ops->wait_for_event(wl, 1551 WLCORE_EVENT_PEER_REMOVE_COMPLETE, 1552 &timeout); 1553 1554 /* 1555 * We are ok with a timeout here. The event is sometimes not sent 1556 * due to a firmware bug. In case of another error (like SDIO timeout) 1557 * queue a recovery. 1558 */ 1559 if (ret) 1560 wl12xx_queue_recovery_work(wl); 1561 1562out_free: 1563 kfree(cmd); 1564 1565out: 1566 return ret; 1567} 1568 1569static int wlcore_get_reg_conf_ch_idx(enum ieee80211_band band, u16 ch) 1570{ 1571 int idx = -1; 1572 1573 switch (band) { 1574 case IEEE80211_BAND_5GHZ: 1575 if (ch >= 8 && ch <= 16) 1576 idx = ((ch-8)/4 + 18); 1577 else if (ch >= 34 && ch <= 64) 1578 idx = ((ch-34)/2 + 3 + 18); 1579 else if (ch >= 100 && ch <= 140) 1580 idx = ((ch-100)/4 + 15 + 18); 1581 else if (ch >= 149 && ch <= 165) 1582 idx = ((ch-149)/4 + 26 + 18); 1583 else 1584 idx = -1; 1585 break; 1586 case IEEE80211_BAND_2GHZ: 1587 if (ch >= 1 && ch <= 14) 1588 idx = ch - 1; 1589 else 1590 idx = -1; 1591 break; 1592 default: 1593 wl1271_error("get reg conf ch idx - unknown band: %d", 1594 (int)band); 1595 } 1596 1597 return idx; 1598} 1599 1600void wlcore_set_pending_regdomain_ch(struct wl1271 *wl, u16 channel, 1601 enum ieee80211_band band) 1602{ 1603 int ch_bit_idx = 0; 1604 1605 if (!(wl->quirks & WLCORE_QUIRK_REGDOMAIN_CONF)) 1606 return; 1607 1608 ch_bit_idx = wlcore_get_reg_conf_ch_idx(band, channel); 1609 1610 if (ch_bit_idx > 0 && ch_bit_idx <= WL1271_MAX_CHANNELS) 1611 set_bit(ch_bit_idx, (long *)wl->reg_ch_conf_pending); 1612} 1613 1614int wlcore_cmd_regdomain_config_locked(struct wl1271 *wl) 1615{ 1616 struct wl12xx_cmd_regdomain_dfs_config *cmd = NULL; 1617 int ret = 0, i, b, ch_bit_idx; 1618 struct ieee80211_channel *channel; 1619 u32 tmp_ch_bitmap[2]; 1620 u16 ch; 1621 struct wiphy *wiphy = wl->hw->wiphy; 1622 struct ieee80211_supported_band *band; 1623 bool timeout = false; 1624 1625 if (!(wl->quirks & WLCORE_QUIRK_REGDOMAIN_CONF)) 1626 return 0; 1627 1628 wl1271_debug(DEBUG_CMD, "cmd reg domain config"); 1629 1630 memset(tmp_ch_bitmap, 0, sizeof(tmp_ch_bitmap)); 1631 1632 for (b = IEEE80211_BAND_2GHZ; b <= IEEE80211_BAND_5GHZ; b++) { 1633 band = wiphy->bands[b]; 1634 for (i = 0; i < band->n_channels; i++) { 1635 channel = &band->channels[i]; 1636 ch = channel->hw_value; 1637 1638 if (channel->flags & (IEEE80211_CHAN_DISABLED | 1639 IEEE80211_CHAN_RADAR | 1640 IEEE80211_CHAN_PASSIVE_SCAN)) 1641 continue; 1642 1643 ch_bit_idx = wlcore_get_reg_conf_ch_idx(b, ch); 1644 if (ch_bit_idx < 0) 1645 continue; 1646 1647 set_bit(ch_bit_idx, (long *)tmp_ch_bitmap); 1648 } 1649 } 1650 1651 tmp_ch_bitmap[0] |= wl->reg_ch_conf_pending[0]; 1652 tmp_ch_bitmap[1] |= wl->reg_ch_conf_pending[1]; 1653 1654 if (!memcmp(tmp_ch_bitmap, wl->reg_ch_conf_last, sizeof(tmp_ch_bitmap))) 1655 goto out; 1656 1657 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 1658 if (!cmd) { 1659 ret = -ENOMEM; 1660 goto out; 1661 } 1662 1663 cmd->ch_bit_map1 = cpu_to_le32(tmp_ch_bitmap[0]); 1664 cmd->ch_bit_map2 = cpu_to_le32(tmp_ch_bitmap[1]); 1665 1666 wl1271_debug(DEBUG_CMD, 1667 "cmd reg domain bitmap1: 0x%08x, bitmap2: 0x%08x", 1668 cmd->ch_bit_map1, cmd->ch_bit_map2); 1669 1670 ret = wl1271_cmd_send(wl, CMD_DFS_CHANNEL_CONFIG, cmd, sizeof(*cmd), 0); 1671 if (ret < 0) { 1672 wl1271_error("failed to send reg domain dfs config"); 1673 goto out; 1674 } 1675 1676 ret = wl->ops->wait_for_event(wl, 1677 WLCORE_EVENT_DFS_CONFIG_COMPLETE, 1678 &timeout); 1679 if (ret < 0 || timeout) { 1680 wl1271_error("reg domain conf %serror", 1681 timeout ? "completion " : ""); 1682 ret = timeout ? -ETIMEDOUT : ret; 1683 goto out; 1684 } 1685 1686 memcpy(wl->reg_ch_conf_last, tmp_ch_bitmap, sizeof(tmp_ch_bitmap)); 1687 memset(wl->reg_ch_conf_pending, 0, sizeof(wl->reg_ch_conf_pending)); 1688 1689out: 1690 kfree(cmd); 1691 return ret; 1692} 1693 1694int wl12xx_cmd_config_fwlog(struct wl1271 *wl) 1695{ 1696 struct wl12xx_cmd_config_fwlog *cmd; 1697 int ret = 0; 1698 1699 wl1271_debug(DEBUG_CMD, "cmd config firmware logger"); 1700 1701 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 1702 if (!cmd) { 1703 ret = -ENOMEM; 1704 goto out; 1705 } 1706 1707 cmd->logger_mode = wl->conf.fwlog.mode; 1708 cmd->log_severity = wl->conf.fwlog.severity; 1709 cmd->timestamp = wl->conf.fwlog.timestamp; 1710 cmd->output = wl->conf.fwlog.output; 1711 cmd->threshold = wl->conf.fwlog.threshold; 1712 1713 ret = wl1271_cmd_send(wl, CMD_CONFIG_FWLOGGER, cmd, sizeof(*cmd), 0); 1714 if (ret < 0) { 1715 wl1271_error("failed to send config firmware logger command"); 1716 goto out_free; 1717 } 1718 1719out_free: 1720 kfree(cmd); 1721 1722out: 1723 return ret; 1724} 1725 1726int wl12xx_cmd_start_fwlog(struct wl1271 *wl) 1727{ 1728 struct wl12xx_cmd_start_fwlog *cmd; 1729 int ret = 0; 1730 1731 wl1271_debug(DEBUG_CMD, "cmd start firmware logger"); 1732 1733 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 1734 if (!cmd) { 1735 ret = -ENOMEM; 1736 goto out; 1737 } 1738 1739 ret = wl1271_cmd_send(wl, CMD_START_FWLOGGER, cmd, sizeof(*cmd), 0); 1740 if (ret < 0) { 1741 wl1271_error("failed to send start firmware logger command"); 1742 goto out_free; 1743 } 1744 1745out_free: 1746 kfree(cmd); 1747 1748out: 1749 return ret; 1750} 1751 1752int wl12xx_cmd_stop_fwlog(struct wl1271 *wl) 1753{ 1754 struct wl12xx_cmd_stop_fwlog *cmd; 1755 int ret = 0; 1756 1757 wl1271_debug(DEBUG_CMD, "cmd stop firmware logger"); 1758 1759 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 1760 if (!cmd) { 1761 ret = -ENOMEM; 1762 goto out; 1763 } 1764 1765 ret = wl1271_cmd_send(wl, CMD_STOP_FWLOGGER, cmd, sizeof(*cmd), 0); 1766 if (ret < 0) { 1767 wl1271_error("failed to send stop firmware logger command"); 1768 goto out_free; 1769 } 1770 1771out_free: 1772 kfree(cmd); 1773 1774out: 1775 return ret; 1776} 1777 1778static int wl12xx_cmd_roc(struct wl1271 *wl, struct wl12xx_vif *wlvif, 1779 u8 role_id, enum ieee80211_band band, u8 channel) 1780{ 1781 struct wl12xx_cmd_roc *cmd; 1782 int ret = 0; 1783 1784 wl1271_debug(DEBUG_CMD, "cmd roc %d (%d)", channel, role_id); 1785 1786 if (WARN_ON(role_id == WL12XX_INVALID_ROLE_ID)) 1787 return -EINVAL; 1788 1789 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 1790 if (!cmd) { 1791 ret = -ENOMEM; 1792 goto out; 1793 } 1794 1795 cmd->role_id = role_id; 1796 cmd->channel = channel; 1797 switch (band) { 1798 case IEEE80211_BAND_2GHZ: 1799 cmd->band = WLCORE_BAND_2_4GHZ; 1800 break; 1801 case IEEE80211_BAND_5GHZ: 1802 cmd->band = WLCORE_BAND_5GHZ; 1803 break; 1804 default: 1805 wl1271_error("roc - unknown band: %d", (int)wlvif->band); 1806 ret = -EINVAL; 1807 goto out_free; 1808 } 1809 1810 1811 ret = wl1271_cmd_send(wl, CMD_REMAIN_ON_CHANNEL, cmd, sizeof(*cmd), 0); 1812 if (ret < 0) { 1813 wl1271_error("failed to send ROC command"); 1814 goto out_free; 1815 } 1816 1817out_free: 1818 kfree(cmd); 1819 1820out: 1821 return ret; 1822} 1823 1824static int wl12xx_cmd_croc(struct wl1271 *wl, u8 role_id) 1825{ 1826 struct wl12xx_cmd_croc *cmd; 1827 int ret = 0; 1828 1829 wl1271_debug(DEBUG_CMD, "cmd croc (%d)", role_id); 1830 1831 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 1832 if (!cmd) { 1833 ret = -ENOMEM; 1834 goto out; 1835 } 1836 cmd->role_id = role_id; 1837 1838 ret = wl1271_cmd_send(wl, CMD_CANCEL_REMAIN_ON_CHANNEL, cmd, 1839 sizeof(*cmd), 0); 1840 if (ret < 0) { 1841 wl1271_error("failed to send ROC command"); 1842 goto out_free; 1843 } 1844 1845out_free: 1846 kfree(cmd); 1847 1848out: 1849 return ret; 1850} 1851 1852int wl12xx_roc(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 role_id, 1853 enum ieee80211_band band, u8 channel) 1854{ 1855 int ret = 0; 1856 1857 if (WARN_ON(test_bit(role_id, wl->roc_map))) 1858 return 0; 1859 1860 ret = wl12xx_cmd_roc(wl, wlvif, role_id, band, channel); 1861 if (ret < 0) 1862 goto out; 1863 1864 __set_bit(role_id, wl->roc_map); 1865out: 1866 return ret; 1867} 1868 1869int wl12xx_croc(struct wl1271 *wl, u8 role_id) 1870{ 1871 int ret = 0; 1872 1873 if (WARN_ON(!test_bit(role_id, wl->roc_map))) 1874 return 0; 1875 1876 ret = wl12xx_cmd_croc(wl, role_id); 1877 if (ret < 0) 1878 goto out; 1879 1880 __clear_bit(role_id, wl->roc_map); 1881 1882 /* 1883 * Rearm the tx watchdog when removing the last ROC. This prevents 1884 * recoveries due to just finished ROCs - when Tx hasn't yet had 1885 * a chance to get out. 1886 */ 1887 if (find_first_bit(wl->roc_map, WL12XX_MAX_ROLES) >= WL12XX_MAX_ROLES) 1888 wl12xx_rearm_tx_watchdog_locked(wl); 1889out: 1890 return ret; 1891} 1892 1893int wl12xx_cmd_stop_channel_switch(struct wl1271 *wl, struct wl12xx_vif *wlvif) 1894{ 1895 struct wl12xx_cmd_stop_channel_switch *cmd; 1896 int ret; 1897 1898 wl1271_debug(DEBUG_ACX, "cmd stop channel switch"); 1899 1900 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 1901 if (!cmd) { 1902 ret = -ENOMEM; 1903 goto out; 1904 } 1905 1906 cmd->role_id = wlvif->role_id; 1907 1908 ret = wl1271_cmd_send(wl, CMD_STOP_CHANNEL_SWICTH, cmd, sizeof(*cmd), 0); 1909 if (ret < 0) { 1910 wl1271_error("failed to stop channel switch command"); 1911 goto out_free; 1912 } 1913 1914out_free: 1915 kfree(cmd); 1916 1917out: 1918 return ret; 1919} 1920 1921/* start dev role and roc on its channel */ 1922int wl12xx_start_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif, 1923 enum ieee80211_band band, int channel) 1924{ 1925 int ret; 1926 1927 if (WARN_ON(!(wlvif->bss_type == BSS_TYPE_STA_BSS || 1928 wlvif->bss_type == BSS_TYPE_IBSS))) 1929 return -EINVAL; 1930 1931 ret = wl12xx_cmd_role_enable(wl, 1932 wl12xx_wlvif_to_vif(wlvif)->addr, 1933 WL1271_ROLE_DEVICE, 1934 &wlvif->dev_role_id); 1935 if (ret < 0) 1936 goto out; 1937 1938 ret = wl12xx_cmd_role_start_dev(wl, wlvif, band, channel); 1939 if (ret < 0) 1940 goto out_disable; 1941 1942 ret = wl12xx_roc(wl, wlvif, wlvif->dev_role_id, band, channel); 1943 if (ret < 0) 1944 goto out_stop; 1945 1946 return 0; 1947 1948out_stop: 1949 wl12xx_cmd_role_stop_dev(wl, wlvif); 1950out_disable: 1951 wl12xx_cmd_role_disable(wl, &wlvif->dev_role_id); 1952out: 1953 return ret; 1954} 1955 1956/* croc dev hlid, and stop the role */ 1957int wl12xx_stop_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif) 1958{ 1959 int ret; 1960 1961 if (WARN_ON(!(wlvif->bss_type == BSS_TYPE_STA_BSS || 1962 wlvif->bss_type == BSS_TYPE_IBSS))) 1963 return -EINVAL; 1964 1965 /* flush all pending packets */ 1966 ret = wlcore_tx_work_locked(wl); 1967 if (ret < 0) 1968 goto out; 1969 1970 if (test_bit(wlvif->dev_role_id, wl->roc_map)) { 1971 ret = wl12xx_croc(wl, wlvif->dev_role_id); 1972 if (ret < 0) 1973 goto out; 1974 } 1975 1976 ret = wl12xx_cmd_role_stop_dev(wl, wlvif); 1977 if (ret < 0) 1978 goto out; 1979 1980 ret = wl12xx_cmd_role_disable(wl, &wlvif->dev_role_id); 1981 if (ret < 0) 1982 goto out; 1983 1984out: 1985 return ret; 1986} 1987