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