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