linux/drivers/net/wireless/st/cw1200/sta.c
<<
>>
Prefs
   1/*
   2 * Mac80211 STA API for ST-Ericsson CW1200 drivers
   3 *
   4 * Copyright (c) 2010, ST-Ericsson
   5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License version 2 as
   9 * published by the Free Software Foundation.
  10 */
  11
  12#include <linux/vmalloc.h>
  13#include <linux/sched.h>
  14#include <linux/firmware.h>
  15#include <linux/module.h>
  16#include <linux/etherdevice.h>
  17
  18#include "cw1200.h"
  19#include "sta.h"
  20#include "fwio.h"
  21#include "bh.h"
  22#include "debug.h"
  23
  24#ifndef ERP_INFO_BYTE_OFFSET
  25#define ERP_INFO_BYTE_OFFSET 2
  26#endif
  27
  28static void cw1200_do_join(struct cw1200_common *priv);
  29static void cw1200_do_unjoin(struct cw1200_common *priv);
  30
  31static int cw1200_upload_beacon(struct cw1200_common *priv);
  32static int cw1200_upload_pspoll(struct cw1200_common *priv);
  33static int cw1200_upload_null(struct cw1200_common *priv);
  34static int cw1200_upload_qosnull(struct cw1200_common *priv);
  35static int cw1200_start_ap(struct cw1200_common *priv);
  36static int cw1200_update_beaconing(struct cw1200_common *priv);
  37static int cw1200_enable_beaconing(struct cw1200_common *priv,
  38                                   bool enable);
  39static void __cw1200_sta_notify(struct ieee80211_hw *dev,
  40                                struct ieee80211_vif *vif,
  41                                enum sta_notify_cmd notify_cmd,
  42                                int link_id);
  43static int __cw1200_flush(struct cw1200_common *priv, bool drop);
  44
  45static inline void __cw1200_free_event_queue(struct list_head *list)
  46{
  47        struct cw1200_wsm_event *event, *tmp;
  48        list_for_each_entry_safe(event, tmp, list, link) {
  49                list_del(&event->link);
  50                kfree(event);
  51        }
  52}
  53
  54/* ******************************************************************** */
  55/* STA API                                                              */
  56
  57int cw1200_start(struct ieee80211_hw *dev)
  58{
  59        struct cw1200_common *priv = dev->priv;
  60        int ret = 0;
  61
  62        cw1200_pm_stay_awake(&priv->pm_state, HZ);
  63
  64        mutex_lock(&priv->conf_mutex);
  65
  66        /* default EDCA */
  67        WSM_EDCA_SET(&priv->edca, 0, 0x0002, 0x0003, 0x0007, 47, 0xc8, false);
  68        WSM_EDCA_SET(&priv->edca, 1, 0x0002, 0x0007, 0x000f, 94, 0xc8, false);
  69        WSM_EDCA_SET(&priv->edca, 2, 0x0003, 0x000f, 0x03ff, 0, 0xc8, false);
  70        WSM_EDCA_SET(&priv->edca, 3, 0x0007, 0x000f, 0x03ff, 0, 0xc8, false);
  71        ret = wsm_set_edca_params(priv, &priv->edca);
  72        if (ret)
  73                goto out;
  74
  75        ret = cw1200_set_uapsd_param(priv, &priv->edca);
  76        if (ret)
  77                goto out;
  78
  79        priv->setbssparams_done = false;
  80
  81        memcpy(priv->mac_addr, dev->wiphy->perm_addr, ETH_ALEN);
  82        priv->mode = NL80211_IFTYPE_MONITOR;
  83        priv->wep_default_key_id = -1;
  84
  85        priv->cqm_beacon_loss_count = 10;
  86
  87        ret = cw1200_setup_mac(priv);
  88        if (ret)
  89                goto out;
  90
  91out:
  92        mutex_unlock(&priv->conf_mutex);
  93        return ret;
  94}
  95
  96void cw1200_stop(struct ieee80211_hw *dev)
  97{
  98        struct cw1200_common *priv = dev->priv;
  99        LIST_HEAD(list);
 100        int i;
 101
 102        wsm_lock_tx(priv);
 103
 104        while (down_trylock(&priv->scan.lock)) {
 105                /* Scan is in progress. Force it to stop. */
 106                priv->scan.req = NULL;
 107                schedule();
 108        }
 109        up(&priv->scan.lock);
 110
 111        cancel_delayed_work_sync(&priv->scan.probe_work);
 112        cancel_delayed_work_sync(&priv->scan.timeout);
 113        cancel_delayed_work_sync(&priv->clear_recent_scan_work);
 114        cancel_delayed_work_sync(&priv->join_timeout);
 115        cw1200_cqm_bssloss_sm(priv, 0, 0, 0);
 116        cancel_work_sync(&priv->unjoin_work);
 117        cancel_delayed_work_sync(&priv->link_id_gc_work);
 118        flush_workqueue(priv->workqueue);
 119        del_timer_sync(&priv->mcast_timeout);
 120        mutex_lock(&priv->conf_mutex);
 121        priv->mode = NL80211_IFTYPE_UNSPECIFIED;
 122        priv->listening = false;
 123
 124        spin_lock(&priv->event_queue_lock);
 125        list_splice_init(&priv->event_queue, &list);
 126        spin_unlock(&priv->event_queue_lock);
 127        __cw1200_free_event_queue(&list);
 128
 129
 130        priv->join_status = CW1200_JOIN_STATUS_PASSIVE;
 131        priv->join_pending = false;
 132
 133        for (i = 0; i < 4; i++)
 134                cw1200_queue_clear(&priv->tx_queue[i]);
 135        mutex_unlock(&priv->conf_mutex);
 136        tx_policy_clean(priv);
 137
 138        /* HACK! */
 139        if (atomic_xchg(&priv->tx_lock, 1) != 1)
 140                pr_debug("[STA] TX is force-unlocked due to stop request.\n");
 141
 142        wsm_unlock_tx(priv);
 143        atomic_xchg(&priv->tx_lock, 0); /* for recovery to work */
 144}
 145
 146static int cw1200_bssloss_mitigation = 1;
 147module_param(cw1200_bssloss_mitigation, int, 0644);
 148MODULE_PARM_DESC(cw1200_bssloss_mitigation, "BSS Loss mitigation. 0 == disabled, 1 == enabled (default)");
 149
 150
 151void __cw1200_cqm_bssloss_sm(struct cw1200_common *priv,
 152                             int init, int good, int bad)
 153{
 154        int tx = 0;
 155
 156        priv->delayed_link_loss = 0;
 157        cancel_work_sync(&priv->bss_params_work);
 158
 159        pr_debug("[STA] CQM BSSLOSS_SM: state: %d init %d good %d bad: %d txlock: %d uj: %d\n",
 160                 priv->bss_loss_state,
 161                 init, good, bad,
 162                 atomic_read(&priv->tx_lock),
 163                 priv->delayed_unjoin);
 164
 165        /* If we have a pending unjoin */
 166        if (priv->delayed_unjoin)
 167                return;
 168
 169        if (init) {
 170                queue_delayed_work(priv->workqueue,
 171                                   &priv->bss_loss_work,
 172                                   HZ);
 173                priv->bss_loss_state = 0;
 174
 175                /* Skip the confimration procedure in P2P case */
 176                if (!priv->vif->p2p && !atomic_read(&priv->tx_lock))
 177                        tx = 1;
 178        } else if (good) {
 179                cancel_delayed_work_sync(&priv->bss_loss_work);
 180                priv->bss_loss_state = 0;
 181                queue_work(priv->workqueue, &priv->bss_params_work);
 182        } else if (bad) {
 183                /* XXX Should we just keep going until we time out? */
 184                if (priv->bss_loss_state < 3)
 185                        tx = 1;
 186        } else {
 187                cancel_delayed_work_sync(&priv->bss_loss_work);
 188                priv->bss_loss_state = 0;
 189        }
 190
 191        /* Bypass mitigation if it's disabled */
 192        if (!cw1200_bssloss_mitigation)
 193                tx = 0;
 194
 195        /* Spit out a NULL packet to our AP if necessary */
 196        if (tx) {
 197                struct sk_buff *skb;
 198
 199                priv->bss_loss_state++;
 200
 201                skb = ieee80211_nullfunc_get(priv->hw, priv->vif);
 202                WARN_ON(!skb);
 203                if (skb)
 204                        cw1200_tx(priv->hw, NULL, skb);
 205        }
 206}
 207
 208int cw1200_add_interface(struct ieee80211_hw *dev,
 209                         struct ieee80211_vif *vif)
 210{
 211        int ret;
 212        struct cw1200_common *priv = dev->priv;
 213        /* __le32 auto_calibration_mode = __cpu_to_le32(1); */
 214
 215        vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER |
 216                             IEEE80211_VIF_SUPPORTS_UAPSD |
 217                             IEEE80211_VIF_SUPPORTS_CQM_RSSI;
 218
 219        mutex_lock(&priv->conf_mutex);
 220
 221        if (priv->mode != NL80211_IFTYPE_MONITOR) {
 222                mutex_unlock(&priv->conf_mutex);
 223                return -EOPNOTSUPP;
 224        }
 225
 226        switch (vif->type) {
 227        case NL80211_IFTYPE_STATION:
 228        case NL80211_IFTYPE_ADHOC:
 229        case NL80211_IFTYPE_MESH_POINT:
 230        case NL80211_IFTYPE_AP:
 231                priv->mode = vif->type;
 232                break;
 233        default:
 234                mutex_unlock(&priv->conf_mutex);
 235                return -EOPNOTSUPP;
 236        }
 237
 238        priv->vif = vif;
 239        memcpy(priv->mac_addr, vif->addr, ETH_ALEN);
 240        ret = cw1200_setup_mac(priv);
 241        /* Enable auto-calibration */
 242        /* Exception in subsequent channel switch; disabled.
 243         *  wsm_write_mib(priv, WSM_MIB_ID_SET_AUTO_CALIBRATION_MODE,
 244         *      &auto_calibration_mode, sizeof(auto_calibration_mode));
 245        */
 246
 247        mutex_unlock(&priv->conf_mutex);
 248        return ret;
 249}
 250
 251void cw1200_remove_interface(struct ieee80211_hw *dev,
 252                             struct ieee80211_vif *vif)
 253{
 254        struct cw1200_common *priv = dev->priv;
 255        struct wsm_reset reset = {
 256                .reset_statistics = true,
 257        };
 258        int i;
 259
 260        mutex_lock(&priv->conf_mutex);
 261        switch (priv->join_status) {
 262        case CW1200_JOIN_STATUS_JOINING:
 263        case CW1200_JOIN_STATUS_PRE_STA:
 264        case CW1200_JOIN_STATUS_STA:
 265        case CW1200_JOIN_STATUS_IBSS:
 266                wsm_lock_tx(priv);
 267                if (queue_work(priv->workqueue, &priv->unjoin_work) <= 0)
 268                        wsm_unlock_tx(priv);
 269                break;
 270        case CW1200_JOIN_STATUS_AP:
 271                for (i = 0; priv->link_id_map; ++i) {
 272                        if (priv->link_id_map & BIT(i)) {
 273                                reset.link_id = i;
 274                                wsm_reset(priv, &reset);
 275                                priv->link_id_map &= ~BIT(i);
 276                        }
 277                }
 278                memset(priv->link_id_db, 0, sizeof(priv->link_id_db));
 279                priv->sta_asleep_mask = 0;
 280                priv->enable_beacon = false;
 281                priv->tx_multicast = false;
 282                priv->aid0_bit_set = false;
 283                priv->buffered_multicasts = false;
 284                priv->pspoll_mask = 0;
 285                reset.link_id = 0;
 286                wsm_reset(priv, &reset);
 287                break;
 288        case CW1200_JOIN_STATUS_MONITOR:
 289                cw1200_update_listening(priv, false);
 290                break;
 291        default:
 292                break;
 293        }
 294        priv->vif = NULL;
 295        priv->mode = NL80211_IFTYPE_MONITOR;
 296        eth_zero_addr(priv->mac_addr);
 297        memset(&priv->p2p_ps_modeinfo, 0, sizeof(priv->p2p_ps_modeinfo));
 298        cw1200_free_keys(priv);
 299        cw1200_setup_mac(priv);
 300        priv->listening = false;
 301        priv->join_status = CW1200_JOIN_STATUS_PASSIVE;
 302        if (!__cw1200_flush(priv, true))
 303                wsm_unlock_tx(priv);
 304
 305        mutex_unlock(&priv->conf_mutex);
 306}
 307
 308int cw1200_change_interface(struct ieee80211_hw *dev,
 309                            struct ieee80211_vif *vif,
 310                            enum nl80211_iftype new_type,
 311                            bool p2p)
 312{
 313        int ret = 0;
 314        pr_debug("change_interface new: %d (%d), old: %d (%d)\n", new_type,
 315                 p2p, vif->type, vif->p2p);
 316
 317        if (new_type != vif->type || vif->p2p != p2p) {
 318                cw1200_remove_interface(dev, vif);
 319                vif->type = new_type;
 320                vif->p2p = p2p;
 321                ret = cw1200_add_interface(dev, vif);
 322        }
 323
 324        return ret;
 325}
 326
 327int cw1200_config(struct ieee80211_hw *dev, u32 changed)
 328{
 329        int ret = 0;
 330        struct cw1200_common *priv = dev->priv;
 331        struct ieee80211_conf *conf = &dev->conf;
 332
 333        pr_debug("CONFIG CHANGED:  %08x\n", changed);
 334
 335        down(&priv->scan.lock);
 336        mutex_lock(&priv->conf_mutex);
 337        /* TODO: IEEE80211_CONF_CHANGE_QOS */
 338        /* TODO: IEEE80211_CONF_CHANGE_LISTEN_INTERVAL */
 339
 340        if (changed & IEEE80211_CONF_CHANGE_POWER) {
 341                priv->output_power = conf->power_level;
 342                pr_debug("[STA] TX power: %d\n", priv->output_power);
 343                wsm_set_output_power(priv, priv->output_power * 10);
 344        }
 345
 346        if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) &&
 347            (priv->channel != conf->chandef.chan)) {
 348                struct ieee80211_channel *ch = conf->chandef.chan;
 349                struct wsm_switch_channel channel = {
 350                        .channel_number = ch->hw_value,
 351                };
 352                pr_debug("[STA] Freq %d (wsm ch: %d).\n",
 353                         ch->center_freq, ch->hw_value);
 354
 355                /* __cw1200_flush() implicitly locks tx, if successful */
 356                if (!__cw1200_flush(priv, false)) {
 357                        if (!wsm_switch_channel(priv, &channel)) {
 358                                ret = wait_event_timeout(priv->channel_switch_done,
 359                                                         !priv->channel_switch_in_progress,
 360                                                         3 * HZ);
 361                                if (ret) {
 362                                        /* Already unlocks if successful */
 363                                        priv->channel = ch;
 364                                        ret = 0;
 365                                } else {
 366                                        ret = -ETIMEDOUT;
 367                                }
 368                        } else {
 369                                /* Unlock if switch channel fails */
 370                                wsm_unlock_tx(priv);
 371                        }
 372                }
 373        }
 374
 375        if (changed & IEEE80211_CONF_CHANGE_PS) {
 376                if (!(conf->flags & IEEE80211_CONF_PS))
 377                        priv->powersave_mode.mode = WSM_PSM_ACTIVE;
 378                else if (conf->dynamic_ps_timeout <= 0)
 379                        priv->powersave_mode.mode = WSM_PSM_PS;
 380                else
 381                        priv->powersave_mode.mode = WSM_PSM_FAST_PS;
 382
 383                /* Firmware requires that value for this 1-byte field must
 384                 * be specified in units of 500us. Values above the 128ms
 385                 * threshold are not supported.
 386                 */
 387                if (conf->dynamic_ps_timeout >= 0x80)
 388                        priv->powersave_mode.fast_psm_idle_period = 0xFF;
 389                else
 390                        priv->powersave_mode.fast_psm_idle_period =
 391                                        conf->dynamic_ps_timeout << 1;
 392
 393                if (priv->join_status == CW1200_JOIN_STATUS_STA &&
 394                    priv->bss_params.aid)
 395                        cw1200_set_pm(priv, &priv->powersave_mode);
 396        }
 397
 398        if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
 399                /* TBD: It looks like it's transparent
 400                 * there's a monitor interface present -- use this
 401                 * to determine for example whether to calculate
 402                 * timestamps for packets or not, do not use instead
 403                 * of filter flags!
 404                 */
 405        }
 406
 407        if (changed & IEEE80211_CONF_CHANGE_IDLE) {
 408                struct wsm_operational_mode mode = {
 409                        .power_mode = cw1200_power_mode,
 410                        .disable_more_flag_usage = true,
 411                };
 412
 413                wsm_lock_tx(priv);
 414                /* Disable p2p-dev mode forced by TX request */
 415                if ((priv->join_status == CW1200_JOIN_STATUS_MONITOR) &&
 416                    (conf->flags & IEEE80211_CONF_IDLE) &&
 417                    !priv->listening) {
 418                        cw1200_disable_listening(priv);
 419                        priv->join_status = CW1200_JOIN_STATUS_PASSIVE;
 420                }
 421                wsm_set_operational_mode(priv, &mode);
 422                wsm_unlock_tx(priv);
 423        }
 424
 425        if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
 426                pr_debug("[STA] Retry limits: %d (long), %d (short).\n",
 427                         conf->long_frame_max_tx_count,
 428                         conf->short_frame_max_tx_count);
 429                spin_lock_bh(&priv->tx_policy_cache.lock);
 430                priv->long_frame_max_tx_count = conf->long_frame_max_tx_count;
 431                priv->short_frame_max_tx_count =
 432                        (conf->short_frame_max_tx_count < 0x0F) ?
 433                        conf->short_frame_max_tx_count : 0x0F;
 434                priv->hw->max_rate_tries = priv->short_frame_max_tx_count;
 435                spin_unlock_bh(&priv->tx_policy_cache.lock);
 436        }
 437        mutex_unlock(&priv->conf_mutex);
 438        up(&priv->scan.lock);
 439        return ret;
 440}
 441
 442void cw1200_update_filtering(struct cw1200_common *priv)
 443{
 444        int ret;
 445        bool bssid_filtering = !priv->rx_filter.bssid;
 446        bool is_p2p = priv->vif && priv->vif->p2p;
 447        bool is_sta = priv->vif && NL80211_IFTYPE_STATION == priv->vif->type;
 448
 449        static struct wsm_beacon_filter_control bf_ctrl;
 450        static struct wsm_mib_beacon_filter_table bf_tbl = {
 451                .entry[0].ie_id = WLAN_EID_VENDOR_SPECIFIC,
 452                .entry[0].flags = WSM_BEACON_FILTER_IE_HAS_CHANGED |
 453                                        WSM_BEACON_FILTER_IE_NO_LONGER_PRESENT |
 454                                        WSM_BEACON_FILTER_IE_HAS_APPEARED,
 455                .entry[0].oui[0] = 0x50,
 456                .entry[0].oui[1] = 0x6F,
 457                .entry[0].oui[2] = 0x9A,
 458                .entry[1].ie_id = WLAN_EID_HT_OPERATION,
 459                .entry[1].flags = WSM_BEACON_FILTER_IE_HAS_CHANGED |
 460                                        WSM_BEACON_FILTER_IE_NO_LONGER_PRESENT |
 461                                        WSM_BEACON_FILTER_IE_HAS_APPEARED,
 462                .entry[2].ie_id = WLAN_EID_ERP_INFO,
 463                .entry[2].flags = WSM_BEACON_FILTER_IE_HAS_CHANGED |
 464                                        WSM_BEACON_FILTER_IE_NO_LONGER_PRESENT |
 465                                        WSM_BEACON_FILTER_IE_HAS_APPEARED,
 466        };
 467
 468        if (priv->join_status == CW1200_JOIN_STATUS_PASSIVE)
 469                return;
 470        else if (priv->join_status == CW1200_JOIN_STATUS_MONITOR)
 471                bssid_filtering = false;
 472
 473        if (priv->disable_beacon_filter) {
 474                bf_ctrl.enabled = 0;
 475                bf_ctrl.bcn_count = 1;
 476                bf_tbl.num = __cpu_to_le32(0);
 477        } else if (is_p2p || !is_sta) {
 478                bf_ctrl.enabled = WSM_BEACON_FILTER_ENABLE |
 479                        WSM_BEACON_FILTER_AUTO_ERP;
 480                bf_ctrl.bcn_count = 0;
 481                bf_tbl.num = __cpu_to_le32(2);
 482        } else {
 483                bf_ctrl.enabled = WSM_BEACON_FILTER_ENABLE;
 484                bf_ctrl.bcn_count = 0;
 485                bf_tbl.num = __cpu_to_le32(3);
 486        }
 487
 488        /* When acting as p2p client being connected to p2p GO, in order to
 489         * receive frames from a different p2p device, turn off bssid filter.
 490         *
 491         * WARNING: FW dependency!
 492         * This can only be used with FW WSM371 and its successors.
 493         * In that FW version even with bssid filter turned off,
 494         * device will block most of the unwanted frames.
 495         */
 496        if (is_p2p)
 497                bssid_filtering = false;
 498
 499        ret = wsm_set_rx_filter(priv, &priv->rx_filter);
 500        if (!ret)
 501                ret = wsm_set_beacon_filter_table(priv, &bf_tbl);
 502        if (!ret)
 503                ret = wsm_beacon_filter_control(priv, &bf_ctrl);
 504        if (!ret)
 505                ret = wsm_set_bssid_filtering(priv, bssid_filtering);
 506        if (!ret)
 507                ret = wsm_set_multicast_filter(priv, &priv->multicast_filter);
 508        if (ret)
 509                wiphy_err(priv->hw->wiphy,
 510                          "Update filtering failed: %d.\n", ret);
 511        return;
 512}
 513
 514void cw1200_update_filtering_work(struct work_struct *work)
 515{
 516        struct cw1200_common *priv =
 517                container_of(work, struct cw1200_common,
 518                             update_filtering_work);
 519
 520        cw1200_update_filtering(priv);
 521}
 522
 523void cw1200_set_beacon_wakeup_period_work(struct work_struct *work)
 524{
 525        struct cw1200_common *priv =
 526                container_of(work, struct cw1200_common,
 527                             set_beacon_wakeup_period_work);
 528
 529        wsm_set_beacon_wakeup_period(priv,
 530                                     priv->beacon_int * priv->join_dtim_period >
 531                                     MAX_BEACON_SKIP_TIME_MS ? 1 :
 532                                     priv->join_dtim_period, 0);
 533}
 534
 535u64 cw1200_prepare_multicast(struct ieee80211_hw *hw,
 536                             struct netdev_hw_addr_list *mc_list)
 537{
 538        static u8 broadcast_ipv6[ETH_ALEN] = {
 539                0x33, 0x33, 0x00, 0x00, 0x00, 0x01
 540        };
 541        static u8 broadcast_ipv4[ETH_ALEN] = {
 542                0x01, 0x00, 0x5e, 0x00, 0x00, 0x01
 543        };
 544        struct cw1200_common *priv = hw->priv;
 545        struct netdev_hw_addr *ha;
 546        int count = 0;
 547
 548        /* Disable multicast filtering */
 549        priv->has_multicast_subscription = false;
 550        memset(&priv->multicast_filter, 0x00, sizeof(priv->multicast_filter));
 551
 552        if (netdev_hw_addr_list_count(mc_list) > WSM_MAX_GRP_ADDRTABLE_ENTRIES)
 553                return 0;
 554
 555        /* Enable if requested */
 556        netdev_hw_addr_list_for_each(ha, mc_list) {
 557                pr_debug("[STA] multicast: %pM\n", ha->addr);
 558                memcpy(&priv->multicast_filter.macaddrs[count],
 559                       ha->addr, ETH_ALEN);
 560                if (!ether_addr_equal(ha->addr, broadcast_ipv4) &&
 561                    !ether_addr_equal(ha->addr, broadcast_ipv6))
 562                        priv->has_multicast_subscription = true;
 563                count++;
 564        }
 565
 566        if (count) {
 567                priv->multicast_filter.enable = __cpu_to_le32(1);
 568                priv->multicast_filter.num_addrs = __cpu_to_le32(count);
 569        }
 570
 571        return netdev_hw_addr_list_count(mc_list);
 572}
 573
 574void cw1200_configure_filter(struct ieee80211_hw *dev,
 575                             unsigned int changed_flags,
 576                             unsigned int *total_flags,
 577                             u64 multicast)
 578{
 579        struct cw1200_common *priv = dev->priv;
 580        bool listening = !!(*total_flags &
 581                            (FIF_OTHER_BSS |
 582                             FIF_BCN_PRBRESP_PROMISC |
 583                             FIF_PROBE_REQ));
 584
 585        *total_flags &= FIF_OTHER_BSS |
 586                        FIF_FCSFAIL |
 587                        FIF_BCN_PRBRESP_PROMISC |
 588                        FIF_PROBE_REQ;
 589
 590        down(&priv->scan.lock);
 591        mutex_lock(&priv->conf_mutex);
 592
 593        priv->rx_filter.promiscuous = 0;
 594        priv->rx_filter.bssid = (*total_flags & (FIF_OTHER_BSS |
 595                        FIF_PROBE_REQ)) ? 1 : 0;
 596        priv->rx_filter.fcs = (*total_flags & FIF_FCSFAIL) ? 1 : 0;
 597        priv->disable_beacon_filter = !(*total_flags &
 598                                        (FIF_BCN_PRBRESP_PROMISC |
 599                                         FIF_PROBE_REQ));
 600        if (priv->listening != listening) {
 601                priv->listening = listening;
 602                wsm_lock_tx(priv);
 603                cw1200_update_listening(priv, listening);
 604                wsm_unlock_tx(priv);
 605        }
 606        cw1200_update_filtering(priv);
 607        mutex_unlock(&priv->conf_mutex);
 608        up(&priv->scan.lock);
 609}
 610
 611int cw1200_conf_tx(struct ieee80211_hw *dev, struct ieee80211_vif *vif,
 612                   u16 queue, const struct ieee80211_tx_queue_params *params)
 613{
 614        struct cw1200_common *priv = dev->priv;
 615        int ret = 0;
 616        /* To prevent re-applying PM request OID again and again*/
 617        bool old_uapsd_flags;
 618
 619        mutex_lock(&priv->conf_mutex);
 620
 621        if (queue < dev->queues) {
 622                old_uapsd_flags = le16_to_cpu(priv->uapsd_info.uapsd_flags);
 623
 624                WSM_TX_QUEUE_SET(&priv->tx_queue_params, queue, 0, 0, 0);
 625                ret = wsm_set_tx_queue_params(priv,
 626                                              &priv->tx_queue_params.params[queue], queue);
 627                if (ret) {
 628                        ret = -EINVAL;
 629                        goto out;
 630                }
 631
 632                WSM_EDCA_SET(&priv->edca, queue, params->aifs,
 633                             params->cw_min, params->cw_max,
 634                             params->txop, 0xc8,
 635                             params->uapsd);
 636                ret = wsm_set_edca_params(priv, &priv->edca);
 637                if (ret) {
 638                        ret = -EINVAL;
 639                        goto out;
 640                }
 641
 642                if (priv->mode == NL80211_IFTYPE_STATION) {
 643                        ret = cw1200_set_uapsd_param(priv, &priv->edca);
 644                        if (!ret && priv->setbssparams_done &&
 645                            (priv->join_status == CW1200_JOIN_STATUS_STA) &&
 646                            (old_uapsd_flags != le16_to_cpu(priv->uapsd_info.uapsd_flags)))
 647                                ret = cw1200_set_pm(priv, &priv->powersave_mode);
 648                }
 649        } else {
 650                ret = -EINVAL;
 651        }
 652
 653out:
 654        mutex_unlock(&priv->conf_mutex);
 655        return ret;
 656}
 657
 658int cw1200_get_stats(struct ieee80211_hw *dev,
 659                     struct ieee80211_low_level_stats *stats)
 660{
 661        struct cw1200_common *priv = dev->priv;
 662
 663        memcpy(stats, &priv->stats, sizeof(*stats));
 664        return 0;
 665}
 666
 667int cw1200_set_pm(struct cw1200_common *priv, const struct wsm_set_pm *arg)
 668{
 669        struct wsm_set_pm pm = *arg;
 670
 671        if (priv->uapsd_info.uapsd_flags != 0)
 672                pm.mode &= ~WSM_PSM_FAST_PS_FLAG;
 673
 674        if (memcmp(&pm, &priv->firmware_ps_mode,
 675                   sizeof(struct wsm_set_pm))) {
 676                priv->firmware_ps_mode = pm;
 677                return wsm_set_pm(priv, &pm);
 678        } else {
 679                return 0;
 680        }
 681}
 682
 683int cw1200_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
 684                   struct ieee80211_vif *vif, struct ieee80211_sta *sta,
 685                   struct ieee80211_key_conf *key)
 686{
 687        int ret = -EOPNOTSUPP;
 688        struct cw1200_common *priv = dev->priv;
 689        struct ieee80211_key_seq seq;
 690
 691        mutex_lock(&priv->conf_mutex);
 692
 693        if (cmd == SET_KEY) {
 694                u8 *peer_addr = NULL;
 695                int pairwise = (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) ?
 696                        1 : 0;
 697                int idx = cw1200_alloc_key(priv);
 698                struct wsm_add_key *wsm_key = &priv->keys[idx];
 699
 700                if (idx < 0) {
 701                        ret = -EINVAL;
 702                        goto finally;
 703                }
 704
 705                if (sta)
 706                        peer_addr = sta->addr;
 707
 708                key->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE |
 709                              IEEE80211_KEY_FLAG_RESERVE_TAILROOM;
 710
 711                switch (key->cipher) {
 712                case WLAN_CIPHER_SUITE_WEP40:
 713                case WLAN_CIPHER_SUITE_WEP104:
 714                        if (key->keylen > 16) {
 715                                cw1200_free_key(priv, idx);
 716                                ret = -EINVAL;
 717                                goto finally;
 718                        }
 719
 720                        if (pairwise) {
 721                                wsm_key->type = WSM_KEY_TYPE_WEP_PAIRWISE;
 722                                memcpy(wsm_key->wep_pairwise.peer,
 723                                       peer_addr, ETH_ALEN);
 724                                memcpy(wsm_key->wep_pairwise.keydata,
 725                                       &key->key[0], key->keylen);
 726                                wsm_key->wep_pairwise.keylen = key->keylen;
 727                        } else {
 728                                wsm_key->type = WSM_KEY_TYPE_WEP_DEFAULT;
 729                                memcpy(wsm_key->wep_group.keydata,
 730                                       &key->key[0], key->keylen);
 731                                wsm_key->wep_group.keylen = key->keylen;
 732                                wsm_key->wep_group.keyid = key->keyidx;
 733                        }
 734                        break;
 735                case WLAN_CIPHER_SUITE_TKIP:
 736                        ieee80211_get_key_rx_seq(key, 0, &seq);
 737                        if (pairwise) {
 738                                wsm_key->type = WSM_KEY_TYPE_TKIP_PAIRWISE;
 739                                memcpy(wsm_key->tkip_pairwise.peer,
 740                                       peer_addr, ETH_ALEN);
 741                                memcpy(wsm_key->tkip_pairwise.keydata,
 742                                       &key->key[0], 16);
 743                                memcpy(wsm_key->tkip_pairwise.tx_mic_key,
 744                                       &key->key[16], 8);
 745                                memcpy(wsm_key->tkip_pairwise.rx_mic_key,
 746                                       &key->key[24], 8);
 747                        } else {
 748                                size_t mic_offset =
 749                                        (priv->mode == NL80211_IFTYPE_AP) ?
 750                                        16 : 24;
 751                                wsm_key->type = WSM_KEY_TYPE_TKIP_GROUP;
 752                                memcpy(wsm_key->tkip_group.keydata,
 753                                       &key->key[0], 16);
 754                                memcpy(wsm_key->tkip_group.rx_mic_key,
 755                                       &key->key[mic_offset], 8);
 756
 757                                wsm_key->tkip_group.rx_seqnum[0] = seq.tkip.iv16 & 0xff;
 758                                wsm_key->tkip_group.rx_seqnum[1] = (seq.tkip.iv16 >> 8) & 0xff;
 759                                wsm_key->tkip_group.rx_seqnum[2] = seq.tkip.iv32 & 0xff;
 760                                wsm_key->tkip_group.rx_seqnum[3] = (seq.tkip.iv32 >> 8) & 0xff;
 761                                wsm_key->tkip_group.rx_seqnum[4] = (seq.tkip.iv32 >> 16) & 0xff;
 762                                wsm_key->tkip_group.rx_seqnum[5] = (seq.tkip.iv32 >> 24) & 0xff;
 763                                wsm_key->tkip_group.rx_seqnum[6] = 0;
 764                                wsm_key->tkip_group.rx_seqnum[7] = 0;
 765
 766                                wsm_key->tkip_group.keyid = key->keyidx;
 767                        }
 768                        break;
 769                case WLAN_CIPHER_SUITE_CCMP:
 770                        ieee80211_get_key_rx_seq(key, 0, &seq);
 771                        if (pairwise) {
 772                                wsm_key->type = WSM_KEY_TYPE_AES_PAIRWISE;
 773                                memcpy(wsm_key->aes_pairwise.peer,
 774                                       peer_addr, ETH_ALEN);
 775                                memcpy(wsm_key->aes_pairwise.keydata,
 776                                       &key->key[0], 16);
 777                        } else {
 778                                wsm_key->type = WSM_KEY_TYPE_AES_GROUP;
 779                                memcpy(wsm_key->aes_group.keydata,
 780                                       &key->key[0], 16);
 781
 782                                wsm_key->aes_group.rx_seqnum[0] = seq.ccmp.pn[5];
 783                                wsm_key->aes_group.rx_seqnum[1] = seq.ccmp.pn[4];
 784                                wsm_key->aes_group.rx_seqnum[2] = seq.ccmp.pn[3];
 785                                wsm_key->aes_group.rx_seqnum[3] = seq.ccmp.pn[2];
 786                                wsm_key->aes_group.rx_seqnum[4] = seq.ccmp.pn[1];
 787                                wsm_key->aes_group.rx_seqnum[5] = seq.ccmp.pn[0];
 788                                wsm_key->aes_group.rx_seqnum[6] = 0;
 789                                wsm_key->aes_group.rx_seqnum[7] = 0;
 790                                wsm_key->aes_group.keyid = key->keyidx;
 791                        }
 792                        break;
 793                case WLAN_CIPHER_SUITE_SMS4:
 794                        if (pairwise) {
 795                                wsm_key->type = WSM_KEY_TYPE_WAPI_PAIRWISE;
 796                                memcpy(wsm_key->wapi_pairwise.peer,
 797                                       peer_addr, ETH_ALEN);
 798                                memcpy(wsm_key->wapi_pairwise.keydata,
 799                                       &key->key[0], 16);
 800                                memcpy(wsm_key->wapi_pairwise.mic_key,
 801                                       &key->key[16], 16);
 802                                wsm_key->wapi_pairwise.keyid = key->keyidx;
 803                        } else {
 804                                wsm_key->type = WSM_KEY_TYPE_WAPI_GROUP;
 805                                memcpy(wsm_key->wapi_group.keydata,
 806                                       &key->key[0],  16);
 807                                memcpy(wsm_key->wapi_group.mic_key,
 808                                       &key->key[16], 16);
 809                                wsm_key->wapi_group.keyid = key->keyidx;
 810                        }
 811                        break;
 812                default:
 813                        pr_warn("Unhandled key type %d\n", key->cipher);
 814                        cw1200_free_key(priv, idx);
 815                        ret = -EOPNOTSUPP;
 816                        goto finally;
 817                }
 818                ret = wsm_add_key(priv, wsm_key);
 819                if (!ret)
 820                        key->hw_key_idx = idx;
 821                else
 822                        cw1200_free_key(priv, idx);
 823        } else if (cmd == DISABLE_KEY) {
 824                struct wsm_remove_key wsm_key = {
 825                        .index = key->hw_key_idx,
 826                };
 827
 828                if (wsm_key.index > WSM_KEY_MAX_INDEX) {
 829                        ret = -EINVAL;
 830                        goto finally;
 831                }
 832
 833                cw1200_free_key(priv, wsm_key.index);
 834                ret = wsm_remove_key(priv, &wsm_key);
 835        } else {
 836                pr_warn("Unhandled key command %d\n", cmd);
 837        }
 838
 839finally:
 840        mutex_unlock(&priv->conf_mutex);
 841        return ret;
 842}
 843
 844void cw1200_wep_key_work(struct work_struct *work)
 845{
 846        struct cw1200_common *priv =
 847                container_of(work, struct cw1200_common, wep_key_work);
 848        u8 queue_id = cw1200_queue_get_queue_id(priv->pending_frame_id);
 849        struct cw1200_queue *queue = &priv->tx_queue[queue_id];
 850        __le32 wep_default_key_id = __cpu_to_le32(
 851                priv->wep_default_key_id);
 852
 853        pr_debug("[STA] Setting default WEP key: %d\n",
 854                 priv->wep_default_key_id);
 855        wsm_flush_tx(priv);
 856        wsm_write_mib(priv, WSM_MIB_ID_DOT11_WEP_DEFAULT_KEY_ID,
 857                      &wep_default_key_id, sizeof(wep_default_key_id));
 858        cw1200_queue_requeue(queue, priv->pending_frame_id);
 859        wsm_unlock_tx(priv);
 860}
 861
 862int cw1200_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
 863{
 864        int ret = 0;
 865        __le32 val32;
 866        struct cw1200_common *priv = hw->priv;
 867
 868        if (priv->mode == NL80211_IFTYPE_UNSPECIFIED)
 869                return 0;
 870
 871        if (value != (u32) -1)
 872                val32 = __cpu_to_le32(value);
 873        else
 874                val32 = 0; /* disabled */
 875
 876        if (priv->rts_threshold == value)
 877                goto out;
 878
 879        pr_debug("[STA] Setting RTS threshold: %d\n",
 880                 priv->rts_threshold);
 881
 882        /* mutex_lock(&priv->conf_mutex); */
 883        ret = wsm_write_mib(priv, WSM_MIB_ID_DOT11_RTS_THRESHOLD,
 884                            &val32, sizeof(val32));
 885        if (!ret)
 886                priv->rts_threshold = value;
 887        /* mutex_unlock(&priv->conf_mutex); */
 888
 889out:
 890        return ret;
 891}
 892
 893/* If successful, LOCKS the TX queue! */
 894static int __cw1200_flush(struct cw1200_common *priv, bool drop)
 895{
 896        int i, ret;
 897
 898        for (;;) {
 899                /* TODO: correct flush handling is required when dev_stop.
 900                 * Temporary workaround: 2s
 901                 */
 902                if (drop) {
 903                        for (i = 0; i < 4; ++i)
 904                                cw1200_queue_clear(&priv->tx_queue[i]);
 905                } else {
 906                        ret = wait_event_timeout(
 907                                priv->tx_queue_stats.wait_link_id_empty,
 908                                cw1200_queue_stats_is_empty(
 909                                        &priv->tx_queue_stats, -1),
 910                                2 * HZ);
 911                }
 912
 913                if (!drop && ret <= 0) {
 914                        ret = -ETIMEDOUT;
 915                        break;
 916                } else {
 917                        ret = 0;
 918                }
 919
 920                wsm_lock_tx(priv);
 921                if (!cw1200_queue_stats_is_empty(&priv->tx_queue_stats, -1)) {
 922                        /* Highly unlikely: WSM requeued frames. */
 923                        wsm_unlock_tx(priv);
 924                        continue;
 925                }
 926                break;
 927        }
 928        return ret;
 929}
 930
 931void cw1200_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 932                  u32 queues, bool drop)
 933{
 934        struct cw1200_common *priv = hw->priv;
 935
 936        switch (priv->mode) {
 937        case NL80211_IFTYPE_MONITOR:
 938                drop = true;
 939                break;
 940        case NL80211_IFTYPE_AP:
 941                if (!priv->enable_beacon)
 942                        drop = true;
 943                break;
 944        }
 945
 946        if (!__cw1200_flush(priv, drop))
 947                wsm_unlock_tx(priv);
 948
 949        return;
 950}
 951
 952/* ******************************************************************** */
 953/* WSM callbacks                                                        */
 954
 955void cw1200_free_event_queue(struct cw1200_common *priv)
 956{
 957        LIST_HEAD(list);
 958
 959        spin_lock(&priv->event_queue_lock);
 960        list_splice_init(&priv->event_queue, &list);
 961        spin_unlock(&priv->event_queue_lock);
 962
 963        __cw1200_free_event_queue(&list);
 964}
 965
 966void cw1200_event_handler(struct work_struct *work)
 967{
 968        struct cw1200_common *priv =
 969                container_of(work, struct cw1200_common, event_handler);
 970        struct cw1200_wsm_event *event;
 971        LIST_HEAD(list);
 972
 973        spin_lock(&priv->event_queue_lock);
 974        list_splice_init(&priv->event_queue, &list);
 975        spin_unlock(&priv->event_queue_lock);
 976
 977        list_for_each_entry(event, &list, link) {
 978                switch (event->evt.id) {
 979                case WSM_EVENT_ERROR:
 980                        pr_err("Unhandled WSM Error from LMAC\n");
 981                        break;
 982                case WSM_EVENT_BSS_LOST:
 983                        pr_debug("[CQM] BSS lost.\n");
 984                        cancel_work_sync(&priv->unjoin_work);
 985                        if (!down_trylock(&priv->scan.lock)) {
 986                                cw1200_cqm_bssloss_sm(priv, 1, 0, 0);
 987                                up(&priv->scan.lock);
 988                        } else {
 989                                /* Scan is in progress. Delay reporting.
 990                                 * Scan complete will trigger bss_loss_work
 991                                 */
 992                                priv->delayed_link_loss = 1;
 993                                /* Also start a watchdog. */
 994                                queue_delayed_work(priv->workqueue,
 995                                                   &priv->bss_loss_work, 5*HZ);
 996                        }
 997                        break;
 998                case WSM_EVENT_BSS_REGAINED:
 999                        pr_debug("[CQM] BSS regained.\n");
1000                        cw1200_cqm_bssloss_sm(priv, 0, 0, 0);
1001                        cancel_work_sync(&priv->unjoin_work);
1002                        break;
1003                case WSM_EVENT_RADAR_DETECTED:
1004                        wiphy_info(priv->hw->wiphy, "radar pulse detected\n");
1005                        break;
1006                case WSM_EVENT_RCPI_RSSI:
1007                {
1008                        /* RSSI: signed Q8.0, RCPI: unsigned Q7.1
1009                         * RSSI = RCPI / 2 - 110
1010                         */
1011                        int rcpi_rssi = (int)(event->evt.data & 0xFF);
1012                        int cqm_evt;
1013                        if (priv->cqm_use_rssi)
1014                                rcpi_rssi = (s8)rcpi_rssi;
1015                        else
1016                                rcpi_rssi =  rcpi_rssi / 2 - 110;
1017
1018                        cqm_evt = (rcpi_rssi <= priv->cqm_rssi_thold) ?
1019                                NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW :
1020                                NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH;
1021                        pr_debug("[CQM] RSSI event: %d.\n", rcpi_rssi);
1022                        ieee80211_cqm_rssi_notify(priv->vif, cqm_evt, rcpi_rssi,
1023                                                  GFP_KERNEL);
1024                        break;
1025                }
1026                case WSM_EVENT_BT_INACTIVE:
1027                        pr_warn("Unhandled BT INACTIVE from LMAC\n");
1028                        break;
1029                case WSM_EVENT_BT_ACTIVE:
1030                        pr_warn("Unhandled BT ACTIVE from LMAC\n");
1031                        break;
1032                }
1033        }
1034        __cw1200_free_event_queue(&list);
1035}
1036
1037void cw1200_bss_loss_work(struct work_struct *work)
1038{
1039        struct cw1200_common *priv =
1040                container_of(work, struct cw1200_common, bss_loss_work.work);
1041
1042        pr_debug("[CQM] Reporting connection loss.\n");
1043        wsm_lock_tx(priv);
1044        if (queue_work(priv->workqueue, &priv->unjoin_work) <= 0)
1045                wsm_unlock_tx(priv);
1046}
1047
1048void cw1200_bss_params_work(struct work_struct *work)
1049{
1050        struct cw1200_common *priv =
1051                container_of(work, struct cw1200_common, bss_params_work);
1052        mutex_lock(&priv->conf_mutex);
1053
1054        priv->bss_params.reset_beacon_loss = 1;
1055        wsm_set_bss_params(priv, &priv->bss_params);
1056        priv->bss_params.reset_beacon_loss = 0;
1057
1058        mutex_unlock(&priv->conf_mutex);
1059}
1060
1061/* ******************************************************************** */
1062/* Internal API                                                         */
1063
1064/* This function is called to Parse the SDD file
1065 * to extract listen_interval and PTA related information
1066 * sdd is a TLV: u8 id, u8 len, u8 data[]
1067 */
1068static int cw1200_parse_sdd_file(struct cw1200_common *priv)
1069{
1070        const u8 *p = priv->sdd->data;
1071        int ret = 0;
1072
1073        while (p + 2 <= priv->sdd->data + priv->sdd->size) {
1074                if (p + p[1] + 2 > priv->sdd->data + priv->sdd->size) {
1075                        pr_warn("Malformed sdd structure\n");
1076                        return -1;
1077                }
1078                switch (p[0]) {
1079                case SDD_PTA_CFG_ELT_ID: {
1080                        u16 v;
1081                        if (p[1] < 4) {
1082                                pr_warn("SDD_PTA_CFG_ELT_ID malformed\n");
1083                                ret = -1;
1084                                break;
1085                        }
1086                        v = le16_to_cpu(*((__le16 *)(p + 2)));
1087                        if (!v)  /* non-zero means this is enabled */
1088                                break;
1089
1090                        v = le16_to_cpu(*((__le16 *)(p + 4)));
1091                        priv->conf_listen_interval = (v >> 7) & 0x1F;
1092                        pr_debug("PTA found; Listen Interval %d\n",
1093                                 priv->conf_listen_interval);
1094                        break;
1095                }
1096                case SDD_REFERENCE_FREQUENCY_ELT_ID: {
1097                        u16 clk = le16_to_cpu(*((__le16 *)(p + 2)));
1098                        if (clk != priv->hw_refclk)
1099                                pr_warn("SDD file doesn't match configured refclk (%d vs %d)\n",
1100                                        clk, priv->hw_refclk);
1101                        break;
1102                }
1103                default:
1104                        break;
1105                }
1106                p += p[1] + 2;
1107        }
1108
1109        if (!priv->bt_present) {
1110                pr_debug("PTA element NOT found.\n");
1111                priv->conf_listen_interval = 0;
1112        }
1113        return ret;
1114}
1115
1116int cw1200_setup_mac(struct cw1200_common *priv)
1117{
1118        int ret = 0;
1119
1120        /* NOTE: There is a bug in FW: it reports signal
1121         * as RSSI if RSSI subscription is enabled.
1122         * It's not enough to set WSM_RCPI_RSSI_USE_RSSI.
1123         *
1124         * NOTE2: RSSI based reports have been switched to RCPI, since
1125         * FW has a bug and RSSI reported values are not stable,
1126         * what can leads to signal level oscilations in user-end applications
1127         */
1128        struct wsm_rcpi_rssi_threshold threshold = {
1129                .rssiRcpiMode = WSM_RCPI_RSSI_THRESHOLD_ENABLE |
1130                WSM_RCPI_RSSI_DONT_USE_UPPER |
1131                WSM_RCPI_RSSI_DONT_USE_LOWER,
1132                .rollingAverageCount = 16,
1133        };
1134
1135        struct wsm_configuration cfg = {
1136                .dot11StationId = &priv->mac_addr[0],
1137        };
1138
1139        /* Remember the decission here to make sure, we will handle
1140         * the RCPI/RSSI value correctly on WSM_EVENT_RCPI_RSS
1141         */
1142        if (threshold.rssiRcpiMode & WSM_RCPI_RSSI_USE_RSSI)
1143                priv->cqm_use_rssi = true;
1144
1145        if (!priv->sdd) {
1146                ret = request_firmware(&priv->sdd, priv->sdd_path, priv->pdev);
1147                if (ret) {
1148                        pr_err("Can't load sdd file %s.\n", priv->sdd_path);
1149                        return ret;
1150                }
1151                cw1200_parse_sdd_file(priv);
1152        }
1153
1154        cfg.dpdData = priv->sdd->data;
1155        cfg.dpdData_size = priv->sdd->size;
1156        ret = wsm_configuration(priv, &cfg);
1157        if (ret)
1158                return ret;
1159
1160        /* Configure RSSI/SCPI reporting as RSSI. */
1161        wsm_set_rcpi_rssi_threshold(priv, &threshold);
1162
1163        return 0;
1164}
1165
1166static void cw1200_join_complete(struct cw1200_common *priv)
1167{
1168        pr_debug("[STA] Join complete (%d)\n", priv->join_complete_status);
1169
1170        priv->join_pending = false;
1171        if (priv->join_complete_status) {
1172                priv->join_status = CW1200_JOIN_STATUS_PASSIVE;
1173                cw1200_update_listening(priv, priv->listening);
1174                cw1200_do_unjoin(priv);
1175                ieee80211_connection_loss(priv->vif);
1176        } else {
1177                if (priv->mode == NL80211_IFTYPE_ADHOC)
1178                        priv->join_status = CW1200_JOIN_STATUS_IBSS;
1179                else
1180                        priv->join_status = CW1200_JOIN_STATUS_PRE_STA;
1181        }
1182        wsm_unlock_tx(priv); /* Clearing the lock held before do_join() */
1183}
1184
1185void cw1200_join_complete_work(struct work_struct *work)
1186{
1187        struct cw1200_common *priv =
1188                container_of(work, struct cw1200_common, join_complete_work);
1189        mutex_lock(&priv->conf_mutex);
1190        cw1200_join_complete(priv);
1191        mutex_unlock(&priv->conf_mutex);
1192}
1193
1194void cw1200_join_complete_cb(struct cw1200_common *priv,
1195                             struct wsm_join_complete *arg)
1196{
1197        pr_debug("[STA] cw1200_join_complete_cb called, status=%d.\n",
1198                 arg->status);
1199
1200        if (cancel_delayed_work(&priv->join_timeout)) {
1201                priv->join_complete_status = arg->status;
1202                queue_work(priv->workqueue, &priv->join_complete_work);
1203        }
1204}
1205
1206/* MUST be called with tx_lock held!  It will be unlocked for us. */
1207static void cw1200_do_join(struct cw1200_common *priv)
1208{
1209        const u8 *bssid;
1210        struct ieee80211_bss_conf *conf = &priv->vif->bss_conf;
1211        struct cfg80211_bss *bss = NULL;
1212        struct wsm_protected_mgmt_policy mgmt_policy;
1213        struct wsm_join join = {
1214                .mode = conf->ibss_joined ?
1215                                WSM_JOIN_MODE_IBSS : WSM_JOIN_MODE_BSS,
1216                .preamble_type = WSM_JOIN_PREAMBLE_LONG,
1217                .probe_for_join = 1,
1218                .atim_window = 0,
1219                .basic_rate_set = cw1200_rate_mask_to_wsm(priv,
1220                                                          conf->basic_rates),
1221        };
1222        if (delayed_work_pending(&priv->join_timeout)) {
1223                pr_warn("[STA] - Join request already pending, skipping..\n");
1224                wsm_unlock_tx(priv);
1225                return;
1226        }
1227
1228        if (priv->join_status)
1229                cw1200_do_unjoin(priv);
1230
1231        bssid = priv->vif->bss_conf.bssid;
1232
1233        bss = cfg80211_get_bss(priv->hw->wiphy, priv->channel, bssid, NULL, 0,
1234                               IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY);
1235
1236        if (!bss && !conf->ibss_joined) {
1237                wsm_unlock_tx(priv);
1238                return;
1239        }
1240
1241        mutex_lock(&priv->conf_mutex);
1242
1243        /* Under the conf lock: check scan status and
1244         * bail out if it is in progress.
1245         */
1246        if (atomic_read(&priv->scan.in_progress)) {
1247                wsm_unlock_tx(priv);
1248                goto done_put;
1249        }
1250
1251        priv->join_pending = true;
1252
1253        /* Sanity check basic rates */
1254        if (!join.basic_rate_set)
1255                join.basic_rate_set = 7;
1256
1257        /* Sanity check beacon interval */
1258        if (!priv->beacon_int)
1259                priv->beacon_int = 1;
1260
1261        join.beacon_interval = priv->beacon_int;
1262
1263        /* BT Coex related changes */
1264        if (priv->bt_present) {
1265                if (((priv->conf_listen_interval * 100) %
1266                     priv->beacon_int) == 0)
1267                        priv->listen_interval =
1268                                ((priv->conf_listen_interval * 100) /
1269                                 priv->beacon_int);
1270                else
1271                        priv->listen_interval =
1272                                ((priv->conf_listen_interval * 100) /
1273                                 priv->beacon_int + 1);
1274        }
1275
1276        if (priv->hw->conf.ps_dtim_period)
1277                priv->join_dtim_period = priv->hw->conf.ps_dtim_period;
1278        join.dtim_period = priv->join_dtim_period;
1279
1280        join.channel_number = priv->channel->hw_value;
1281        join.band = (priv->channel->band == NL80211_BAND_5GHZ) ?
1282                WSM_PHY_BAND_5G : WSM_PHY_BAND_2_4G;
1283
1284        memcpy(join.bssid, bssid, sizeof(join.bssid));
1285
1286        pr_debug("[STA] Join BSSID: %pM DTIM: %d, interval: %d\n",
1287                 join.bssid,
1288                 join.dtim_period, priv->beacon_int);
1289
1290        if (!conf->ibss_joined) {
1291                const u8 *ssidie;
1292                rcu_read_lock();
1293                ssidie = ieee80211_bss_get_ie(bss, WLAN_EID_SSID);
1294                if (ssidie) {
1295                        join.ssid_len = ssidie[1];
1296                        memcpy(join.ssid, &ssidie[2], join.ssid_len);
1297                }
1298                rcu_read_unlock();
1299        }
1300
1301        if (priv->vif->p2p) {
1302                join.flags |= WSM_JOIN_FLAGS_P2P_GO;
1303                join.basic_rate_set =
1304                        cw1200_rate_mask_to_wsm(priv, 0xFF0);
1305        }
1306
1307        /* Enable asynchronous join calls */
1308        if (!conf->ibss_joined) {
1309                join.flags |= WSM_JOIN_FLAGS_FORCE;
1310                join.flags |= WSM_JOIN_FLAGS_FORCE_WITH_COMPLETE_IND;
1311        }
1312
1313        wsm_flush_tx(priv);
1314
1315        /* Stay Awake for Join and Auth Timeouts and a bit more */
1316        cw1200_pm_stay_awake(&priv->pm_state,
1317                             CW1200_JOIN_TIMEOUT + CW1200_AUTH_TIMEOUT);
1318
1319        cw1200_update_listening(priv, false);
1320
1321        /* Turn on Block ACKs */
1322        wsm_set_block_ack_policy(priv, priv->ba_tx_tid_mask,
1323                                 priv->ba_rx_tid_mask);
1324
1325        /* Set up timeout */
1326        if (join.flags & WSM_JOIN_FLAGS_FORCE_WITH_COMPLETE_IND) {
1327                priv->join_status = CW1200_JOIN_STATUS_JOINING;
1328                queue_delayed_work(priv->workqueue,
1329                                   &priv->join_timeout,
1330                                   CW1200_JOIN_TIMEOUT);
1331        }
1332
1333        /* 802.11w protected mgmt frames */
1334        mgmt_policy.protectedMgmtEnable = 0;
1335        mgmt_policy.unprotectedMgmtFramesAllowed = 1;
1336        mgmt_policy.encryptionForAuthFrame = 1;
1337        wsm_set_protected_mgmt_policy(priv, &mgmt_policy);
1338
1339        /* Perform actual join */
1340        if (wsm_join(priv, &join)) {
1341                pr_err("[STA] cw1200_join_work: wsm_join failed!\n");
1342                cancel_delayed_work_sync(&priv->join_timeout);
1343                cw1200_update_listening(priv, priv->listening);
1344                /* Tx lock still held, unjoin will clear it. */
1345                if (queue_work(priv->workqueue, &priv->unjoin_work) <= 0)
1346                        wsm_unlock_tx(priv);
1347        } else {
1348                if (!(join.flags & WSM_JOIN_FLAGS_FORCE_WITH_COMPLETE_IND))
1349                        cw1200_join_complete(priv); /* Will clear tx_lock */
1350
1351                /* Upload keys */
1352                cw1200_upload_keys(priv);
1353
1354                /* Due to beacon filtering it is possible that the
1355                 * AP's beacon is not known for the mac80211 stack.
1356                 * Disable filtering temporary to make sure the stack
1357                 * receives at least one
1358                 */
1359                priv->disable_beacon_filter = true;
1360        }
1361        cw1200_update_filtering(priv);
1362
1363done_put:
1364        mutex_unlock(&priv->conf_mutex);
1365        if (bss)
1366                cfg80211_put_bss(priv->hw->wiphy, bss);
1367}
1368
1369void cw1200_join_timeout(struct work_struct *work)
1370{
1371        struct cw1200_common *priv =
1372                container_of(work, struct cw1200_common, join_timeout.work);
1373        pr_debug("[WSM] Join timed out.\n");
1374        wsm_lock_tx(priv);
1375        if (queue_work(priv->workqueue, &priv->unjoin_work) <= 0)
1376                wsm_unlock_tx(priv);
1377}
1378
1379static void cw1200_do_unjoin(struct cw1200_common *priv)
1380{
1381        struct wsm_reset reset = {
1382                .reset_statistics = true,
1383        };
1384
1385        cancel_delayed_work_sync(&priv->join_timeout);
1386
1387        mutex_lock(&priv->conf_mutex);
1388        priv->join_pending = false;
1389
1390        if (atomic_read(&priv->scan.in_progress)) {
1391                if (priv->delayed_unjoin)
1392                        wiphy_dbg(priv->hw->wiphy, "Delayed unjoin is already scheduled.\n");
1393                else
1394                        priv->delayed_unjoin = true;
1395                goto done;
1396        }
1397
1398        priv->delayed_link_loss = false;
1399
1400        if (!priv->join_status)
1401                goto done;
1402
1403        if (priv->join_status == CW1200_JOIN_STATUS_AP)
1404                goto done;
1405
1406        cancel_work_sync(&priv->update_filtering_work);
1407        cancel_work_sync(&priv->set_beacon_wakeup_period_work);
1408        priv->join_status = CW1200_JOIN_STATUS_PASSIVE;
1409
1410        /* Unjoin is a reset. */
1411        wsm_flush_tx(priv);
1412        wsm_keep_alive_period(priv, 0);
1413        wsm_reset(priv, &reset);
1414        wsm_set_output_power(priv, priv->output_power * 10);
1415        priv->join_dtim_period = 0;
1416        cw1200_setup_mac(priv);
1417        cw1200_free_event_queue(priv);
1418        cancel_work_sync(&priv->event_handler);
1419        cw1200_update_listening(priv, priv->listening);
1420        cw1200_cqm_bssloss_sm(priv, 0, 0, 0);
1421
1422        /* Disable Block ACKs */
1423        wsm_set_block_ack_policy(priv, 0, 0);
1424
1425        priv->disable_beacon_filter = false;
1426        cw1200_update_filtering(priv);
1427        memset(&priv->association_mode, 0,
1428               sizeof(priv->association_mode));
1429        memset(&priv->bss_params, 0, sizeof(priv->bss_params));
1430        priv->setbssparams_done = false;
1431        memset(&priv->firmware_ps_mode, 0,
1432               sizeof(priv->firmware_ps_mode));
1433
1434        pr_debug("[STA] Unjoin completed.\n");
1435
1436done:
1437        mutex_unlock(&priv->conf_mutex);
1438}
1439
1440void cw1200_unjoin_work(struct work_struct *work)
1441{
1442        struct cw1200_common *priv =
1443                container_of(work, struct cw1200_common, unjoin_work);
1444
1445        cw1200_do_unjoin(priv);
1446
1447        /* Tell the stack we're dead */
1448        ieee80211_connection_loss(priv->vif);
1449
1450        wsm_unlock_tx(priv);
1451}
1452
1453int cw1200_enable_listening(struct cw1200_common *priv)
1454{
1455        struct wsm_start start = {
1456                .mode = WSM_START_MODE_P2P_DEV,
1457                .band = WSM_PHY_BAND_2_4G,
1458                .beacon_interval = 100,
1459                .dtim_period = 1,
1460                .probe_delay = 0,
1461                .basic_rate_set = 0x0F,
1462        };
1463
1464        if (priv->channel) {
1465                start.band = priv->channel->band == NL80211_BAND_5GHZ ?
1466                             WSM_PHY_BAND_5G : WSM_PHY_BAND_2_4G;
1467                start.channel_number = priv->channel->hw_value;
1468        } else {
1469                start.band = WSM_PHY_BAND_2_4G;
1470                start.channel_number = 1;
1471        }
1472
1473        return wsm_start(priv, &start);
1474}
1475
1476int cw1200_disable_listening(struct cw1200_common *priv)
1477{
1478        int ret;
1479        struct wsm_reset reset = {
1480                .reset_statistics = true,
1481        };
1482        ret = wsm_reset(priv, &reset);
1483        return ret;
1484}
1485
1486void cw1200_update_listening(struct cw1200_common *priv, bool enabled)
1487{
1488        if (enabled) {
1489                if (priv->join_status == CW1200_JOIN_STATUS_PASSIVE) {
1490                        if (!cw1200_enable_listening(priv))
1491                                priv->join_status = CW1200_JOIN_STATUS_MONITOR;
1492                        wsm_set_probe_responder(priv, true);
1493                }
1494        } else {
1495                if (priv->join_status == CW1200_JOIN_STATUS_MONITOR) {
1496                        if (!cw1200_disable_listening(priv))
1497                                priv->join_status = CW1200_JOIN_STATUS_PASSIVE;
1498                        wsm_set_probe_responder(priv, false);
1499                }
1500        }
1501}
1502
1503int cw1200_set_uapsd_param(struct cw1200_common *priv,
1504                           const struct wsm_edca_params *arg)
1505{
1506        int ret;
1507        u16 uapsd_flags = 0;
1508
1509        /* Here's the mapping AC [queue, bit]
1510         *  VO [0,3], VI [1, 2], BE [2, 1], BK [3, 0]
1511         */
1512
1513        if (arg->uapsd_enable[0])
1514                uapsd_flags |= 1 << 3;
1515
1516        if (arg->uapsd_enable[1])
1517                uapsd_flags |= 1 << 2;
1518
1519        if (arg->uapsd_enable[2])
1520                uapsd_flags |= 1 << 1;
1521
1522        if (arg->uapsd_enable[3])
1523                uapsd_flags |= 1;
1524
1525        /* Currently pseudo U-APSD operation is not supported, so setting
1526         * MinAutoTriggerInterval, MaxAutoTriggerInterval and
1527         * AutoTriggerStep to 0
1528         */
1529
1530        priv->uapsd_info.uapsd_flags = cpu_to_le16(uapsd_flags);
1531        priv->uapsd_info.min_auto_trigger_interval = 0;
1532        priv->uapsd_info.max_auto_trigger_interval = 0;
1533        priv->uapsd_info.auto_trigger_step = 0;
1534
1535        ret = wsm_set_uapsd_info(priv, &priv->uapsd_info);
1536        return ret;
1537}
1538
1539/* ******************************************************************** */
1540/* AP API                                                               */
1541
1542int cw1200_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1543                   struct ieee80211_sta *sta)
1544{
1545        struct cw1200_common *priv = hw->priv;
1546        struct cw1200_sta_priv *sta_priv =
1547                        (struct cw1200_sta_priv *)&sta->drv_priv;
1548        struct cw1200_link_entry *entry;
1549        struct sk_buff *skb;
1550
1551        if (priv->mode != NL80211_IFTYPE_AP)
1552                return 0;
1553
1554        sta_priv->link_id = cw1200_find_link_id(priv, sta->addr);
1555        if (WARN_ON(!sta_priv->link_id)) {
1556                wiphy_info(priv->hw->wiphy,
1557                           "[AP] No more link IDs available.\n");
1558                return -ENOENT;
1559        }
1560
1561        entry = &priv->link_id_db[sta_priv->link_id - 1];
1562        spin_lock_bh(&priv->ps_state_lock);
1563        if ((sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK) ==
1564                                        IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
1565                priv->sta_asleep_mask |= BIT(sta_priv->link_id);
1566        entry->status = CW1200_LINK_HARD;
1567        while ((skb = skb_dequeue(&entry->rx_queue)))
1568                ieee80211_rx_irqsafe(priv->hw, skb);
1569        spin_unlock_bh(&priv->ps_state_lock);
1570        return 0;
1571}
1572
1573int cw1200_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1574                      struct ieee80211_sta *sta)
1575{
1576        struct cw1200_common *priv = hw->priv;
1577        struct cw1200_sta_priv *sta_priv =
1578                        (struct cw1200_sta_priv *)&sta->drv_priv;
1579        struct cw1200_link_entry *entry;
1580
1581        if (priv->mode != NL80211_IFTYPE_AP || !sta_priv->link_id)
1582                return 0;
1583
1584        entry = &priv->link_id_db[sta_priv->link_id - 1];
1585        spin_lock_bh(&priv->ps_state_lock);
1586        entry->status = CW1200_LINK_RESERVE;
1587        entry->timestamp = jiffies;
1588        wsm_lock_tx_async(priv);
1589        if (queue_work(priv->workqueue, &priv->link_id_work) <= 0)
1590                wsm_unlock_tx(priv);
1591        spin_unlock_bh(&priv->ps_state_lock);
1592        flush_workqueue(priv->workqueue);
1593        return 0;
1594}
1595
1596static void __cw1200_sta_notify(struct ieee80211_hw *dev,
1597                                struct ieee80211_vif *vif,
1598                                enum sta_notify_cmd notify_cmd,
1599                                int link_id)
1600{
1601        struct cw1200_common *priv = dev->priv;
1602        u32 bit, prev;
1603
1604        /* Zero link id means "for all link IDs" */
1605        if (link_id)
1606                bit = BIT(link_id);
1607        else if (WARN_ON_ONCE(notify_cmd != STA_NOTIFY_AWAKE))
1608                bit = 0;
1609        else
1610                bit = priv->link_id_map;
1611        prev = priv->sta_asleep_mask & bit;
1612
1613        switch (notify_cmd) {
1614        case STA_NOTIFY_SLEEP:
1615                if (!prev) {
1616                        if (priv->buffered_multicasts &&
1617                            !priv->sta_asleep_mask)
1618                                queue_work(priv->workqueue,
1619                                           &priv->multicast_start_work);
1620                        priv->sta_asleep_mask |= bit;
1621                }
1622                break;
1623        case STA_NOTIFY_AWAKE:
1624                if (prev) {
1625                        priv->sta_asleep_mask &= ~bit;
1626                        priv->pspoll_mask &= ~bit;
1627                        if (priv->tx_multicast && link_id &&
1628                            !priv->sta_asleep_mask)
1629                                queue_work(priv->workqueue,
1630                                           &priv->multicast_stop_work);
1631                        cw1200_bh_wakeup(priv);
1632                }
1633                break;
1634        }
1635}
1636
1637void cw1200_sta_notify(struct ieee80211_hw *dev,
1638                       struct ieee80211_vif *vif,
1639                       enum sta_notify_cmd notify_cmd,
1640                       struct ieee80211_sta *sta)
1641{
1642        struct cw1200_common *priv = dev->priv;
1643        struct cw1200_sta_priv *sta_priv =
1644                (struct cw1200_sta_priv *)&sta->drv_priv;
1645
1646        spin_lock_bh(&priv->ps_state_lock);
1647        __cw1200_sta_notify(dev, vif, notify_cmd, sta_priv->link_id);
1648        spin_unlock_bh(&priv->ps_state_lock);
1649}
1650
1651static void cw1200_ps_notify(struct cw1200_common *priv,
1652                      int link_id, bool ps)
1653{
1654        if (link_id > CW1200_MAX_STA_IN_AP_MODE)
1655                return;
1656
1657        pr_debug("%s for LinkId: %d. STAs asleep: %.8X\n",
1658                 ps ? "Stop" : "Start",
1659                 link_id, priv->sta_asleep_mask);
1660
1661        __cw1200_sta_notify(priv->hw, priv->vif,
1662                            ps ? STA_NOTIFY_SLEEP : STA_NOTIFY_AWAKE, link_id);
1663}
1664
1665static int cw1200_set_tim_impl(struct cw1200_common *priv, bool aid0_bit_set)
1666{
1667        struct sk_buff *skb;
1668        struct wsm_update_ie update_ie = {
1669                .what = WSM_UPDATE_IE_BEACON,
1670                .count = 1,
1671        };
1672        u16 tim_offset, tim_length;
1673
1674        pr_debug("[AP] mcast: %s.\n", aid0_bit_set ? "ena" : "dis");
1675
1676        skb = ieee80211_beacon_get_tim(priv->hw, priv->vif,
1677                        &tim_offset, &tim_length);
1678        if (!skb) {
1679                if (!__cw1200_flush(priv, true))
1680                        wsm_unlock_tx(priv);
1681                return -ENOENT;
1682        }
1683
1684        if (tim_offset && tim_length >= 6) {
1685                /* Ignore DTIM count from mac80211:
1686                 * firmware handles DTIM internally.
1687                 */
1688                skb->data[tim_offset + 2] = 0;
1689
1690                /* Set/reset aid0 bit */
1691                if (aid0_bit_set)
1692                        skb->data[tim_offset + 4] |= 1;
1693                else
1694                        skb->data[tim_offset + 4] &= ~1;
1695        }
1696
1697        update_ie.ies = &skb->data[tim_offset];
1698        update_ie.length = tim_length;
1699        wsm_update_ie(priv, &update_ie);
1700
1701        dev_kfree_skb(skb);
1702
1703        return 0;
1704}
1705
1706void cw1200_set_tim_work(struct work_struct *work)
1707{
1708        struct cw1200_common *priv =
1709                container_of(work, struct cw1200_common, set_tim_work);
1710        (void)cw1200_set_tim_impl(priv, priv->aid0_bit_set);
1711}
1712
1713int cw1200_set_tim(struct ieee80211_hw *dev, struct ieee80211_sta *sta,
1714                   bool set)
1715{
1716        struct cw1200_common *priv = dev->priv;
1717        queue_work(priv->workqueue, &priv->set_tim_work);
1718        return 0;
1719}
1720
1721void cw1200_set_cts_work(struct work_struct *work)
1722{
1723        struct cw1200_common *priv =
1724                container_of(work, struct cw1200_common, set_cts_work);
1725
1726        u8 erp_ie[3] = {WLAN_EID_ERP_INFO, 0x1, 0};
1727        struct wsm_update_ie update_ie = {
1728                .what = WSM_UPDATE_IE_BEACON,
1729                .count = 1,
1730                .ies = erp_ie,
1731                .length = 3,
1732        };
1733        u32 erp_info;
1734        __le32 use_cts_prot;
1735        mutex_lock(&priv->conf_mutex);
1736        erp_info = priv->erp_info;
1737        mutex_unlock(&priv->conf_mutex);
1738        use_cts_prot =
1739                erp_info & WLAN_ERP_USE_PROTECTION ?
1740                __cpu_to_le32(1) : 0;
1741
1742        erp_ie[ERP_INFO_BYTE_OFFSET] = erp_info;
1743
1744        pr_debug("[STA] ERP information 0x%x\n", erp_info);
1745
1746        wsm_write_mib(priv, WSM_MIB_ID_NON_ERP_PROTECTION,
1747                      &use_cts_prot, sizeof(use_cts_prot));
1748        wsm_update_ie(priv, &update_ie);
1749
1750        return;
1751}
1752
1753static int cw1200_set_btcoexinfo(struct cw1200_common *priv)
1754{
1755        struct wsm_override_internal_txrate arg;
1756        int ret = 0;
1757
1758        if (priv->mode == NL80211_IFTYPE_STATION) {
1759                /* Plumb PSPOLL and NULL template */
1760                cw1200_upload_pspoll(priv);
1761                cw1200_upload_null(priv);
1762                cw1200_upload_qosnull(priv);
1763        } else {
1764                return 0;
1765        }
1766
1767        memset(&arg, 0, sizeof(struct wsm_override_internal_txrate));
1768
1769        if (!priv->vif->p2p) {
1770                /* STATION mode */
1771                if (priv->bss_params.operational_rate_set & ~0xF) {
1772                        pr_debug("[STA] STA has ERP rates\n");
1773                        /* G or BG mode */
1774                        arg.internalTxRate = (__ffs(
1775                        priv->bss_params.operational_rate_set & ~0xF));
1776                } else {
1777                        pr_debug("[STA] STA has non ERP rates\n");
1778                        /* B only mode */
1779                        arg.internalTxRate = (__ffs(le32_to_cpu(priv->association_mode.basic_rate_set)));
1780                }
1781                arg.nonErpInternalTxRate = (__ffs(le32_to_cpu(priv->association_mode.basic_rate_set)));
1782        } else {
1783                /* P2P mode */
1784                arg.internalTxRate = (__ffs(priv->bss_params.operational_rate_set & ~0xF));
1785                arg.nonErpInternalTxRate = (__ffs(priv->bss_params.operational_rate_set & ~0xF));
1786        }
1787
1788        pr_debug("[STA] BTCOEX_INFO MODE %d, internalTxRate : %x, nonErpInternalTxRate: %x\n",
1789                 priv->mode,
1790                 arg.internalTxRate,
1791                 arg.nonErpInternalTxRate);
1792
1793        ret = wsm_write_mib(priv, WSM_MIB_ID_OVERRIDE_INTERNAL_TX_RATE,
1794                            &arg, sizeof(arg));
1795
1796        return ret;
1797}
1798
1799void cw1200_bss_info_changed(struct ieee80211_hw *dev,
1800                             struct ieee80211_vif *vif,
1801                             struct ieee80211_bss_conf *info,
1802                             u32 changed)
1803{
1804        struct cw1200_common *priv = dev->priv;
1805        bool do_join = false;
1806
1807        mutex_lock(&priv->conf_mutex);
1808
1809        pr_debug("BSS CHANGED:  %08x\n", changed);
1810
1811        /* TODO: BSS_CHANGED_QOS */
1812        /* TODO: BSS_CHANGED_TXPOWER */
1813
1814        if (changed & BSS_CHANGED_ARP_FILTER) {
1815                struct wsm_mib_arp_ipv4_filter filter = {0};
1816                int i;
1817
1818                pr_debug("[STA] BSS_CHANGED_ARP_FILTER cnt: %d\n",
1819                         info->arp_addr_cnt);
1820
1821                /* Currently only one IP address is supported by firmware.
1822                 * In case of more IPs arp filtering will be disabled.
1823                 */
1824                if (info->arp_addr_cnt > 0 &&
1825                    info->arp_addr_cnt <= WSM_MAX_ARP_IP_ADDRTABLE_ENTRIES) {
1826                        for (i = 0; i < info->arp_addr_cnt; i++) {
1827                                filter.ipv4addrs[i] = info->arp_addr_list[i];
1828                                pr_debug("[STA] addr[%d]: 0x%X\n",
1829                                         i, filter.ipv4addrs[i]);
1830                        }
1831                        filter.enable = __cpu_to_le32(1);
1832                }
1833
1834                pr_debug("[STA] arp ip filter enable: %d\n",
1835                         __le32_to_cpu(filter.enable));
1836
1837                wsm_set_arp_ipv4_filter(priv, &filter);
1838        }
1839
1840        if (changed &
1841            (BSS_CHANGED_BEACON |
1842             BSS_CHANGED_AP_PROBE_RESP |
1843             BSS_CHANGED_BSSID |
1844             BSS_CHANGED_SSID |
1845             BSS_CHANGED_IBSS)) {
1846                pr_debug("BSS_CHANGED_BEACON\n");
1847                priv->beacon_int = info->beacon_int;
1848                cw1200_update_beaconing(priv);
1849                cw1200_upload_beacon(priv);
1850        }
1851
1852        if (changed & BSS_CHANGED_BEACON_ENABLED) {
1853                pr_debug("BSS_CHANGED_BEACON_ENABLED (%d)\n", info->enable_beacon);
1854
1855                if (priv->enable_beacon != info->enable_beacon) {
1856                        cw1200_enable_beaconing(priv, info->enable_beacon);
1857                        priv->enable_beacon = info->enable_beacon;
1858                }
1859        }
1860
1861        if (changed & BSS_CHANGED_BEACON_INT) {
1862                pr_debug("CHANGED_BEACON_INT\n");
1863                if (info->ibss_joined)
1864                        do_join = true;
1865                else if (priv->join_status == CW1200_JOIN_STATUS_AP)
1866                        cw1200_update_beaconing(priv);
1867        }
1868
1869        /* assoc/disassoc, or maybe AID changed */
1870        if (changed & BSS_CHANGED_ASSOC) {
1871                wsm_lock_tx(priv);
1872                priv->wep_default_key_id = -1;
1873                wsm_unlock_tx(priv);
1874        }
1875
1876        if (changed & BSS_CHANGED_BSSID) {
1877                pr_debug("BSS_CHANGED_BSSID\n");
1878                do_join = true;
1879        }
1880
1881        if (changed &
1882            (BSS_CHANGED_ASSOC |
1883             BSS_CHANGED_BSSID |
1884             BSS_CHANGED_IBSS |
1885             BSS_CHANGED_BASIC_RATES |
1886             BSS_CHANGED_HT)) {
1887                pr_debug("BSS_CHANGED_ASSOC\n");
1888                if (info->assoc) {
1889                        if (priv->join_status < CW1200_JOIN_STATUS_PRE_STA) {
1890                                ieee80211_connection_loss(vif);
1891                                mutex_unlock(&priv->conf_mutex);
1892                                return;
1893                        } else if (priv->join_status == CW1200_JOIN_STATUS_PRE_STA) {
1894                                priv->join_status = CW1200_JOIN_STATUS_STA;
1895                        }
1896                } else {
1897                        do_join = true;
1898                }
1899
1900                if (info->assoc || info->ibss_joined) {
1901                        struct ieee80211_sta *sta = NULL;
1902                        __le32 htprot = 0;
1903
1904                        if (info->dtim_period)
1905                                priv->join_dtim_period = info->dtim_period;
1906                        priv->beacon_int = info->beacon_int;
1907
1908                        rcu_read_lock();
1909
1910                        if (info->bssid && !info->ibss_joined)
1911                                sta = ieee80211_find_sta(vif, info->bssid);
1912                        if (sta) {
1913                                priv->ht_info.ht_cap = sta->ht_cap;
1914                                priv->bss_params.operational_rate_set =
1915                                        cw1200_rate_mask_to_wsm(priv,
1916                                                                sta->supp_rates[priv->channel->band]);
1917                                priv->ht_info.channel_type = cfg80211_get_chandef_type(&dev->conf.chandef);
1918                                priv->ht_info.operation_mode = info->ht_operation_mode;
1919                        } else {
1920                                memset(&priv->ht_info, 0,
1921                                       sizeof(priv->ht_info));
1922                                priv->bss_params.operational_rate_set = -1;
1923                        }
1924                        rcu_read_unlock();
1925
1926                        /* Non Greenfield stations present */
1927                        if (priv->ht_info.operation_mode &
1928                            IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT)
1929                                htprot |= cpu_to_le32(WSM_NON_GREENFIELD_STA_PRESENT);
1930
1931                        /* Set HT protection method */
1932                        htprot |= cpu_to_le32((priv->ht_info.operation_mode & IEEE80211_HT_OP_MODE_PROTECTION) << 2);
1933
1934                        /* TODO:
1935                         * STBC_param.dual_cts
1936                         *  STBC_param.LSIG_TXOP_FILL
1937                         */
1938
1939                        wsm_write_mib(priv, WSM_MIB_ID_SET_HT_PROTECTION,
1940                                      &htprot, sizeof(htprot));
1941
1942                        priv->association_mode.greenfield =
1943                                cw1200_ht_greenfield(&priv->ht_info);
1944                        priv->association_mode.flags =
1945                                WSM_ASSOCIATION_MODE_SNOOP_ASSOC_FRAMES |
1946                                WSM_ASSOCIATION_MODE_USE_PREAMBLE_TYPE |
1947                                WSM_ASSOCIATION_MODE_USE_HT_MODE |
1948                                WSM_ASSOCIATION_MODE_USE_BASIC_RATE_SET |
1949                                WSM_ASSOCIATION_MODE_USE_MPDU_START_SPACING;
1950                        priv->association_mode.preamble =
1951                                info->use_short_preamble ?
1952                                WSM_JOIN_PREAMBLE_SHORT :
1953                                WSM_JOIN_PREAMBLE_LONG;
1954                        priv->association_mode.basic_rate_set = __cpu_to_le32(
1955                                cw1200_rate_mask_to_wsm(priv,
1956                                                        info->basic_rates));
1957                        priv->association_mode.mpdu_start_spacing =
1958                                cw1200_ht_ampdu_density(&priv->ht_info);
1959
1960                        cw1200_cqm_bssloss_sm(priv, 0, 0, 0);
1961                        cancel_work_sync(&priv->unjoin_work);
1962
1963                        priv->bss_params.beacon_lost_count = priv->cqm_beacon_loss_count;
1964                        priv->bss_params.aid = info->aid;
1965
1966                        if (priv->join_dtim_period < 1)
1967                                priv->join_dtim_period = 1;
1968
1969                        pr_debug("[STA] DTIM %d, interval: %d\n",
1970                                 priv->join_dtim_period, priv->beacon_int);
1971                        pr_debug("[STA] Preamble: %d, Greenfield: %d, Aid: %d, Rates: 0x%.8X, Basic: 0x%.8X\n",
1972                                 priv->association_mode.preamble,
1973                                 priv->association_mode.greenfield,
1974                                 priv->bss_params.aid,
1975                                 priv->bss_params.operational_rate_set,
1976                                 priv->association_mode.basic_rate_set);
1977                        wsm_set_association_mode(priv, &priv->association_mode);
1978
1979                        if (!info->ibss_joined) {
1980                                wsm_keep_alive_period(priv, 30 /* sec */);
1981                                wsm_set_bss_params(priv, &priv->bss_params);
1982                                priv->setbssparams_done = true;
1983                                cw1200_set_beacon_wakeup_period_work(&priv->set_beacon_wakeup_period_work);
1984                                cw1200_set_pm(priv, &priv->powersave_mode);
1985                        }
1986                        if (priv->vif->p2p) {
1987                                pr_debug("[STA] Setting p2p powersave configuration.\n");
1988                                wsm_set_p2p_ps_modeinfo(priv,
1989                                                        &priv->p2p_ps_modeinfo);
1990                        }
1991                        if (priv->bt_present)
1992                                cw1200_set_btcoexinfo(priv);
1993                } else {
1994                        memset(&priv->association_mode, 0,
1995                               sizeof(priv->association_mode));
1996                        memset(&priv->bss_params, 0, sizeof(priv->bss_params));
1997                }
1998        }
1999
2000        /* ERP Protection */
2001        if (changed & (BSS_CHANGED_ASSOC |
2002                       BSS_CHANGED_ERP_CTS_PROT |
2003                       BSS_CHANGED_ERP_PREAMBLE)) {
2004                u32 prev_erp_info = priv->erp_info;
2005                if (info->use_cts_prot)
2006                        priv->erp_info |= WLAN_ERP_USE_PROTECTION;
2007                else if (!(prev_erp_info & WLAN_ERP_NON_ERP_PRESENT))
2008                        priv->erp_info &= ~WLAN_ERP_USE_PROTECTION;
2009
2010                if (info->use_short_preamble)
2011                        priv->erp_info |= WLAN_ERP_BARKER_PREAMBLE;
2012                else
2013                        priv->erp_info &= ~WLAN_ERP_BARKER_PREAMBLE;
2014
2015                pr_debug("[STA] ERP Protection: %x\n", priv->erp_info);
2016
2017                if (prev_erp_info != priv->erp_info)
2018                        queue_work(priv->workqueue, &priv->set_cts_work);
2019        }
2020
2021        /* ERP Slottime */
2022        if (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_ERP_SLOT)) {
2023                __le32 slot_time = info->use_short_slot ?
2024                        __cpu_to_le32(9) : __cpu_to_le32(20);
2025                pr_debug("[STA] Slot time: %d us.\n",
2026                         __le32_to_cpu(slot_time));
2027                wsm_write_mib(priv, WSM_MIB_ID_DOT11_SLOT_TIME,
2028                              &slot_time, sizeof(slot_time));
2029        }
2030
2031        if (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_CQM)) {
2032                struct wsm_rcpi_rssi_threshold threshold = {
2033                        .rollingAverageCount = 8,
2034                };
2035                pr_debug("[CQM] RSSI threshold subscribe: %d +- %d\n",
2036                         info->cqm_rssi_thold, info->cqm_rssi_hyst);
2037                priv->cqm_rssi_thold = info->cqm_rssi_thold;
2038                priv->cqm_rssi_hyst = info->cqm_rssi_hyst;
2039
2040                if (info->cqm_rssi_thold || info->cqm_rssi_hyst) {
2041                        /* RSSI subscription enabled */
2042                        /* TODO: It's not a correct way of setting threshold.
2043                         * Upper and lower must be set equal here and adjusted
2044                         * in callback. However current implementation is much
2045                         * more relaible and stable.
2046                         */
2047
2048                        /* RSSI: signed Q8.0, RCPI: unsigned Q7.1
2049                         * RSSI = RCPI / 2 - 110
2050                         */
2051                        if (priv->cqm_use_rssi) {
2052                                threshold.upperThreshold =
2053                                        info->cqm_rssi_thold + info->cqm_rssi_hyst;
2054                                threshold.lowerThreshold =
2055                                        info->cqm_rssi_thold;
2056                                threshold.rssiRcpiMode |= WSM_RCPI_RSSI_USE_RSSI;
2057                        } else {
2058                                threshold.upperThreshold = (info->cqm_rssi_thold + info->cqm_rssi_hyst + 110) * 2;
2059                                threshold.lowerThreshold = (info->cqm_rssi_thold + 110) * 2;
2060                        }
2061                        threshold.rssiRcpiMode |= WSM_RCPI_RSSI_THRESHOLD_ENABLE;
2062                } else {
2063                        /* There is a bug in FW, see sta.c. We have to enable
2064                         * dummy subscription to get correct RSSI values.
2065                         */
2066                        threshold.rssiRcpiMode |=
2067                                WSM_RCPI_RSSI_THRESHOLD_ENABLE |
2068                                WSM_RCPI_RSSI_DONT_USE_UPPER |
2069                                WSM_RCPI_RSSI_DONT_USE_LOWER;
2070                        if (priv->cqm_use_rssi)
2071                                threshold.rssiRcpiMode |= WSM_RCPI_RSSI_USE_RSSI;
2072                }
2073                wsm_set_rcpi_rssi_threshold(priv, &threshold);
2074        }
2075        mutex_unlock(&priv->conf_mutex);
2076
2077        if (do_join) {
2078                wsm_lock_tx(priv);
2079                cw1200_do_join(priv); /* Will unlock it for us */
2080        }
2081}
2082
2083void cw1200_multicast_start_work(struct work_struct *work)
2084{
2085        struct cw1200_common *priv =
2086                container_of(work, struct cw1200_common, multicast_start_work);
2087        long tmo = priv->join_dtim_period *
2088                        (priv->beacon_int + 20) * HZ / 1024;
2089
2090        cancel_work_sync(&priv->multicast_stop_work);
2091
2092        if (!priv->aid0_bit_set) {
2093                wsm_lock_tx(priv);
2094                cw1200_set_tim_impl(priv, true);
2095                priv->aid0_bit_set = true;
2096                mod_timer(&priv->mcast_timeout, jiffies + tmo);
2097                wsm_unlock_tx(priv);
2098        }
2099}
2100
2101void cw1200_multicast_stop_work(struct work_struct *work)
2102{
2103        struct cw1200_common *priv =
2104                container_of(work, struct cw1200_common, multicast_stop_work);
2105
2106        if (priv->aid0_bit_set) {
2107                del_timer_sync(&priv->mcast_timeout);
2108                wsm_lock_tx(priv);
2109                priv->aid0_bit_set = false;
2110                cw1200_set_tim_impl(priv, false);
2111                wsm_unlock_tx(priv);
2112        }
2113}
2114
2115void cw1200_mcast_timeout(unsigned long arg)
2116{
2117        struct cw1200_common *priv =
2118                (struct cw1200_common *)arg;
2119
2120        wiphy_warn(priv->hw->wiphy,
2121                   "Multicast delivery timeout.\n");
2122        spin_lock_bh(&priv->ps_state_lock);
2123        priv->tx_multicast = priv->aid0_bit_set &&
2124                        priv->buffered_multicasts;
2125        if (priv->tx_multicast)
2126                cw1200_bh_wakeup(priv);
2127        spin_unlock_bh(&priv->ps_state_lock);
2128}
2129
2130int cw1200_ampdu_action(struct ieee80211_hw *hw,
2131                        struct ieee80211_vif *vif,
2132                        struct ieee80211_ampdu_params *params)
2133{
2134        /* Aggregation is implemented fully in firmware,
2135         * including block ack negotiation. Do not allow
2136         * mac80211 stack to do anything: it interferes with
2137         * the firmware.
2138         */
2139
2140        /* Note that we still need this function stubbed. */
2141        return -ENOTSUPP;
2142}
2143
2144/* ******************************************************************** */
2145/* WSM callback                                                         */
2146void cw1200_suspend_resume(struct cw1200_common *priv,
2147                          struct wsm_suspend_resume *arg)
2148{
2149        pr_debug("[AP] %s: %s\n",
2150                 arg->stop ? "stop" : "start",
2151                 arg->multicast ? "broadcast" : "unicast");
2152
2153        if (arg->multicast) {
2154                bool cancel_tmo = false;
2155                spin_lock_bh(&priv->ps_state_lock);
2156                if (arg->stop) {
2157                        priv->tx_multicast = false;
2158                } else {
2159                        /* Firmware sends this indication every DTIM if there
2160                         * is a STA in powersave connected. There is no reason
2161                         * to suspend, following wakeup will consume much more
2162                         * power than it could be saved.
2163                         */
2164                        cw1200_pm_stay_awake(&priv->pm_state,
2165                                             priv->join_dtim_period *
2166                                             (priv->beacon_int + 20) * HZ / 1024);
2167                        priv->tx_multicast = (priv->aid0_bit_set &&
2168                                              priv->buffered_multicasts);
2169                        if (priv->tx_multicast) {
2170                                cancel_tmo = true;
2171                                cw1200_bh_wakeup(priv);
2172                        }
2173                }
2174                spin_unlock_bh(&priv->ps_state_lock);
2175                if (cancel_tmo)
2176                        del_timer_sync(&priv->mcast_timeout);
2177        } else {
2178                spin_lock_bh(&priv->ps_state_lock);
2179                cw1200_ps_notify(priv, arg->link_id, arg->stop);
2180                spin_unlock_bh(&priv->ps_state_lock);
2181                if (!arg->stop)
2182                        cw1200_bh_wakeup(priv);
2183        }
2184        return;
2185}
2186
2187/* ******************************************************************** */
2188/* AP privates                                                          */
2189
2190static int cw1200_upload_beacon(struct cw1200_common *priv)
2191{
2192        int ret = 0;
2193        struct ieee80211_mgmt *mgmt;
2194        struct wsm_template_frame frame = {
2195                .frame_type = WSM_FRAME_TYPE_BEACON,
2196        };
2197
2198        u16 tim_offset;
2199        u16 tim_len;
2200
2201        if (priv->mode == NL80211_IFTYPE_STATION ||
2202            priv->mode == NL80211_IFTYPE_MONITOR ||
2203            priv->mode == NL80211_IFTYPE_UNSPECIFIED)
2204                goto done;
2205
2206        if (priv->vif->p2p)
2207                frame.rate = WSM_TRANSMIT_RATE_6;
2208
2209        frame.skb = ieee80211_beacon_get_tim(priv->hw, priv->vif,
2210                                             &tim_offset, &tim_len);
2211        if (!frame.skb)
2212                return -ENOMEM;
2213
2214        ret = wsm_set_template_frame(priv, &frame);
2215
2216        if (ret)
2217                goto done;
2218
2219        /* TODO: Distill probe resp; remove TIM
2220         * and any other beacon-specific IEs
2221         */
2222        mgmt = (void *)frame.skb->data;
2223        mgmt->frame_control =
2224                __cpu_to_le16(IEEE80211_FTYPE_MGMT |
2225                              IEEE80211_STYPE_PROBE_RESP);
2226
2227        frame.frame_type = WSM_FRAME_TYPE_PROBE_RESPONSE;
2228        if (priv->vif->p2p) {
2229                ret = wsm_set_probe_responder(priv, true);
2230        } else {
2231                ret = wsm_set_template_frame(priv, &frame);
2232                wsm_set_probe_responder(priv, false);
2233        }
2234
2235done:
2236        dev_kfree_skb(frame.skb);
2237
2238        return ret;
2239}
2240
2241static int cw1200_upload_pspoll(struct cw1200_common *priv)
2242{
2243        int ret = 0;
2244        struct wsm_template_frame frame = {
2245                .frame_type = WSM_FRAME_TYPE_PS_POLL,
2246                .rate = 0xFF,
2247        };
2248
2249
2250        frame.skb = ieee80211_pspoll_get(priv->hw, priv->vif);
2251        if (!frame.skb)
2252                return -ENOMEM;
2253
2254        ret = wsm_set_template_frame(priv, &frame);
2255
2256        dev_kfree_skb(frame.skb);
2257
2258        return ret;
2259}
2260
2261static int cw1200_upload_null(struct cw1200_common *priv)
2262{
2263        int ret = 0;
2264        struct wsm_template_frame frame = {
2265                .frame_type = WSM_FRAME_TYPE_NULL,
2266                .rate = 0xFF,
2267        };
2268
2269        frame.skb = ieee80211_nullfunc_get(priv->hw, priv->vif);
2270        if (!frame.skb)
2271                return -ENOMEM;
2272
2273        ret = wsm_set_template_frame(priv, &frame);
2274
2275        dev_kfree_skb(frame.skb);
2276
2277        return ret;
2278}
2279
2280static int cw1200_upload_qosnull(struct cw1200_common *priv)
2281{
2282        /* TODO:  This needs to be implemented
2283
2284        struct wsm_template_frame frame = {
2285                .frame_type = WSM_FRAME_TYPE_QOS_NULL,
2286                .rate = 0xFF,
2287        };
2288
2289        frame.skb = ieee80211_qosnullfunc_get(priv->hw, priv->vif);
2290        if (!frame.skb)
2291                return -ENOMEM;
2292
2293        ret = wsm_set_template_frame(priv, &frame);
2294
2295        dev_kfree_skb(frame.skb);
2296
2297        */
2298        return 0;
2299}
2300
2301static int cw1200_enable_beaconing(struct cw1200_common *priv,
2302                                   bool enable)
2303{
2304        struct wsm_beacon_transmit transmit = {
2305                .enable_beaconing = enable,
2306        };
2307
2308        return wsm_beacon_transmit(priv, &transmit);
2309}
2310
2311static int cw1200_start_ap(struct cw1200_common *priv)
2312{
2313        int ret;
2314        struct ieee80211_bss_conf *conf = &priv->vif->bss_conf;
2315        struct wsm_start start = {
2316                .mode = priv->vif->p2p ?
2317                                WSM_START_MODE_P2P_GO : WSM_START_MODE_AP,
2318                .band = (priv->channel->band == NL80211_BAND_5GHZ) ?
2319                                WSM_PHY_BAND_5G : WSM_PHY_BAND_2_4G,
2320                .channel_number = priv->channel->hw_value,
2321                .beacon_interval = conf->beacon_int,
2322                .dtim_period = conf->dtim_period,
2323                .preamble = conf->use_short_preamble ?
2324                                WSM_JOIN_PREAMBLE_SHORT :
2325                                WSM_JOIN_PREAMBLE_LONG,
2326                .probe_delay = 100,
2327                .basic_rate_set = cw1200_rate_mask_to_wsm(priv,
2328                                conf->basic_rates),
2329        };
2330        struct wsm_operational_mode mode = {
2331                .power_mode = cw1200_power_mode,
2332                .disable_more_flag_usage = true,
2333        };
2334
2335        memset(start.ssid, 0, sizeof(start.ssid));
2336        if (!conf->hidden_ssid) {
2337                start.ssid_len = conf->ssid_len;
2338                memcpy(start.ssid, conf->ssid, start.ssid_len);
2339        }
2340
2341        priv->beacon_int = conf->beacon_int;
2342        priv->join_dtim_period = conf->dtim_period;
2343
2344        memset(&priv->link_id_db, 0, sizeof(priv->link_id_db));
2345
2346        pr_debug("[AP] ch: %d(%d), bcn: %d(%d), brt: 0x%.8X, ssid: %.*s.\n",
2347                 start.channel_number, start.band,
2348                 start.beacon_interval, start.dtim_period,
2349                 start.basic_rate_set,
2350                 start.ssid_len, start.ssid);
2351        ret = wsm_start(priv, &start);
2352        if (!ret)
2353                ret = cw1200_upload_keys(priv);
2354        if (!ret && priv->vif->p2p) {
2355                pr_debug("[AP] Setting p2p powersave configuration.\n");
2356                wsm_set_p2p_ps_modeinfo(priv, &priv->p2p_ps_modeinfo);
2357        }
2358        if (!ret) {
2359                wsm_set_block_ack_policy(priv, 0, 0);
2360                priv->join_status = CW1200_JOIN_STATUS_AP;
2361                cw1200_update_filtering(priv);
2362        }
2363        wsm_set_operational_mode(priv, &mode);
2364        return ret;
2365}
2366
2367static int cw1200_update_beaconing(struct cw1200_common *priv)
2368{
2369        struct ieee80211_bss_conf *conf = &priv->vif->bss_conf;
2370        struct wsm_reset reset = {
2371                .link_id = 0,
2372                .reset_statistics = true,
2373        };
2374
2375        if (priv->mode == NL80211_IFTYPE_AP) {
2376                /* TODO: check if changed channel, band */
2377                if (priv->join_status != CW1200_JOIN_STATUS_AP ||
2378                    priv->beacon_int != conf->beacon_int) {
2379                        pr_debug("ap restarting\n");
2380                        wsm_lock_tx(priv);
2381                        if (priv->join_status != CW1200_JOIN_STATUS_PASSIVE)
2382                                wsm_reset(priv, &reset);
2383                        priv->join_status = CW1200_JOIN_STATUS_PASSIVE;
2384                        cw1200_start_ap(priv);
2385                        wsm_unlock_tx(priv);
2386                } else
2387                        pr_debug("ap started join_status: %d\n",
2388                                 priv->join_status);
2389        }
2390        return 0;
2391}
2392