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