linux/drivers/net/wireless/rsi/rsi_91x_core.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2014 Redpine Signals Inc.
   3 *
   4 * Permission to use, copy, modify, and/or distribute this software for any
   5 * purpose with or without fee is hereby granted, provided that the above
   6 * copyright notice and this permission notice appear in all copies.
   7 *
   8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15 */
  16
  17#include "rsi_mgmt.h"
  18#include "rsi_common.h"
  19#include "rsi_hal.h"
  20#include "rsi_coex.h"
  21
  22/**
  23 * rsi_determine_min_weight_queue() - This function determines the queue with
  24 *                                    the min weight.
  25 * @common: Pointer to the driver private structure.
  26 *
  27 * Return: q_num: Corresponding queue number.
  28 */
  29static u8 rsi_determine_min_weight_queue(struct rsi_common *common)
  30{
  31        struct wmm_qinfo *tx_qinfo = common->tx_qinfo;
  32        u32 q_len = 0;
  33        u8 ii = 0;
  34
  35        for (ii = 0; ii < NUM_EDCA_QUEUES; ii++) {
  36                q_len = skb_queue_len(&common->tx_queue[ii]);
  37                if ((tx_qinfo[ii].pkt_contended) && q_len) {
  38                        common->min_weight = tx_qinfo[ii].weight;
  39                        break;
  40                }
  41        }
  42        return ii;
  43}
  44
  45/**
  46 * rsi_recalculate_weights() - This function recalculates the weights
  47 *                             corresponding to each queue.
  48 * @common: Pointer to the driver private structure.
  49 *
  50 * Return: recontend_queue bool variable
  51 */
  52static bool rsi_recalculate_weights(struct rsi_common *common)
  53{
  54        struct wmm_qinfo *tx_qinfo = common->tx_qinfo;
  55        bool recontend_queue = false;
  56        u8 ii = 0;
  57        u32 q_len = 0;
  58
  59        for (ii = 0; ii < NUM_EDCA_QUEUES; ii++) {
  60                q_len = skb_queue_len(&common->tx_queue[ii]);
  61                /* Check for the need of contention */
  62                if (q_len) {
  63                        if (tx_qinfo[ii].pkt_contended) {
  64                                tx_qinfo[ii].weight =
  65                                ((tx_qinfo[ii].weight > common->min_weight) ?
  66                                 tx_qinfo[ii].weight - common->min_weight : 0);
  67                        } else {
  68                                tx_qinfo[ii].pkt_contended = 1;
  69                                tx_qinfo[ii].weight = tx_qinfo[ii].wme_params;
  70                                recontend_queue = true;
  71                        }
  72                } else { /* No packets so no contention */
  73                        tx_qinfo[ii].weight = 0;
  74                        tx_qinfo[ii].pkt_contended = 0;
  75                }
  76        }
  77
  78        return recontend_queue;
  79}
  80
  81/**
  82 * rsi_get_num_pkts_dequeue() - This function determines the number of
  83 *                              packets to be dequeued based on the number
  84 *                              of bytes calculated using txop.
  85 *
  86 * @common: Pointer to the driver private structure.
  87 * @q_num: the queue from which pkts have to be dequeued
  88 *
  89 * Return: pkt_num: Number of pkts to be dequeued.
  90 */
  91static u32 rsi_get_num_pkts_dequeue(struct rsi_common *common, u8 q_num)
  92{
  93        struct rsi_hw *adapter = common->priv;
  94        struct sk_buff *skb;
  95        u32 pkt_cnt = 0;
  96        s16 txop = common->tx_qinfo[q_num].txop * 32;
  97        __le16 r_txop;
  98        struct ieee80211_rate rate;
  99        struct ieee80211_hdr *wh;
 100        struct ieee80211_vif *vif;
 101
 102        rate.bitrate = RSI_RATE_MCS0 * 5 * 10; /* Convert to Kbps */
 103        if (q_num == VI_Q)
 104                txop = ((txop << 5) / 80);
 105
 106        if (skb_queue_len(&common->tx_queue[q_num]))
 107                skb = skb_peek(&common->tx_queue[q_num]);
 108        else
 109                return 0;
 110
 111        do {
 112                wh = (struct ieee80211_hdr *)skb->data;
 113                vif = rsi_get_vif(adapter, wh->addr2);
 114                r_txop = ieee80211_generic_frame_duration(adapter->hw,
 115                                                          vif,
 116                                                          common->band,
 117                                                          skb->len, &rate);
 118                txop -= le16_to_cpu(r_txop);
 119                pkt_cnt += 1;
 120                /*checking if pkts are still there*/
 121                if (skb_queue_len(&common->tx_queue[q_num]) - pkt_cnt)
 122                        skb = skb->next;
 123                else
 124                        break;
 125
 126        } while (txop > 0);
 127
 128        return pkt_cnt;
 129}
 130
 131/**
 132 * rsi_core_determine_hal_queue() - This function determines the queue from
 133 *                                  which packet has to be dequeued.
 134 * @common: Pointer to the driver private structure.
 135 *
 136 * Return: q_num: Corresponding queue number on success.
 137 */
 138static u8 rsi_core_determine_hal_queue(struct rsi_common *common)
 139{
 140        bool recontend_queue = false;
 141        u32 q_len = 0;
 142        u8 q_num = INVALID_QUEUE;
 143        u8 ii = 0;
 144
 145        if (skb_queue_len(&common->tx_queue[MGMT_BEACON_Q])) {
 146                q_num = MGMT_BEACON_Q;
 147                return q_num;
 148        }
 149        if (skb_queue_len(&common->tx_queue[MGMT_SOFT_Q])) {
 150                if (!common->mgmt_q_block)
 151                        q_num = MGMT_SOFT_Q;
 152                return q_num;
 153        }
 154
 155        if (common->hw_data_qs_blocked)
 156                return q_num;
 157
 158        if (common->pkt_cnt != 0) {
 159                --common->pkt_cnt;
 160                return common->selected_qnum;
 161        }
 162
 163get_queue_num:
 164        recontend_queue = false;
 165
 166        q_num = rsi_determine_min_weight_queue(common);
 167
 168        ii = q_num;
 169
 170        /* Selecting the queue with least back off */
 171        for (; ii < NUM_EDCA_QUEUES; ii++) {
 172                q_len = skb_queue_len(&common->tx_queue[ii]);
 173                if (((common->tx_qinfo[ii].pkt_contended) &&
 174                     (common->tx_qinfo[ii].weight < common->min_weight)) &&
 175                      q_len) {
 176                        common->min_weight = common->tx_qinfo[ii].weight;
 177                        q_num = ii;
 178                }
 179        }
 180
 181        if (q_num < NUM_EDCA_QUEUES)
 182                common->tx_qinfo[q_num].pkt_contended = 0;
 183
 184        /* Adjust the back off values for all queues again */
 185        recontend_queue = rsi_recalculate_weights(common);
 186
 187        q_len = skb_queue_len(&common->tx_queue[q_num]);
 188        if (!q_len) {
 189                /* If any queues are freshly contended and the selected queue
 190                 * doesn't have any packets
 191                 * then get the queue number again with fresh values
 192                 */
 193                if (recontend_queue)
 194                        goto get_queue_num;
 195
 196                return INVALID_QUEUE;
 197        }
 198
 199        common->selected_qnum = q_num;
 200        q_len = skb_queue_len(&common->tx_queue[q_num]);
 201
 202        if (q_num == VO_Q || q_num == VI_Q) {
 203                common->pkt_cnt = rsi_get_num_pkts_dequeue(common, q_num);
 204                common->pkt_cnt -= 1;
 205        }
 206
 207        return q_num;
 208}
 209
 210/**
 211 * rsi_core_queue_pkt() - This functions enqueues the packet to the queue
 212 *                        specified by the queue number.
 213 * @common: Pointer to the driver private structure.
 214 * @skb: Pointer to the socket buffer structure.
 215 *
 216 * Return: None.
 217 */
 218static void rsi_core_queue_pkt(struct rsi_common *common,
 219                               struct sk_buff *skb)
 220{
 221        u8 q_num = skb->priority;
 222        if (q_num >= NUM_SOFT_QUEUES) {
 223                rsi_dbg(ERR_ZONE, "%s: Invalid Queue Number: q_num = %d\n",
 224                        __func__, q_num);
 225                dev_kfree_skb(skb);
 226                return;
 227        }
 228
 229        skb_queue_tail(&common->tx_queue[q_num], skb);
 230}
 231
 232/**
 233 * rsi_core_dequeue_pkt() - This functions dequeues the packet from the queue
 234 *                          specified by the queue number.
 235 * @common: Pointer to the driver private structure.
 236 * @q_num: Queue number.
 237 *
 238 * Return: Pointer to sk_buff structure.
 239 */
 240static struct sk_buff *rsi_core_dequeue_pkt(struct rsi_common *common,
 241                                            u8 q_num)
 242{
 243        if (q_num >= NUM_SOFT_QUEUES) {
 244                rsi_dbg(ERR_ZONE, "%s: Invalid Queue Number: q_num = %d\n",
 245                        __func__, q_num);
 246                return NULL;
 247        }
 248
 249        return skb_dequeue(&common->tx_queue[q_num]);
 250}
 251
 252/**
 253 * rsi_core_qos_processor() - This function is used to determine the wmm queue
 254 *                            based on the backoff procedure. Data packets are
 255 *                            dequeued from the selected hal queue and sent to
 256 *                            the below layers.
 257 * @common: Pointer to the driver private structure.
 258 *
 259 * Return: None.
 260 */
 261void rsi_core_qos_processor(struct rsi_common *common)
 262{
 263        struct rsi_hw *adapter = common->priv;
 264        struct sk_buff *skb;
 265        unsigned long tstamp_1, tstamp_2;
 266        u8 q_num;
 267        int status;
 268
 269        tstamp_1 = jiffies;
 270        while (1) {
 271                q_num = rsi_core_determine_hal_queue(common);
 272                rsi_dbg(DATA_TX_ZONE,
 273                        "%s: Queue number = %d\n", __func__, q_num);
 274
 275                if (q_num == INVALID_QUEUE) {
 276                        rsi_dbg(DATA_TX_ZONE, "%s: No More Pkt\n", __func__);
 277                        break;
 278                }
 279                if (common->hibernate_resume)
 280                        break;
 281
 282                mutex_lock(&common->tx_lock);
 283
 284                status = adapter->check_hw_queue_status(adapter, q_num);
 285                if ((status <= 0)) {
 286                        mutex_unlock(&common->tx_lock);
 287                        break;
 288                }
 289
 290                if ((q_num < MGMT_SOFT_Q) &&
 291                    ((skb_queue_len(&common->tx_queue[q_num])) <=
 292                      MIN_DATA_QUEUE_WATER_MARK)) {
 293                        if (ieee80211_queue_stopped(adapter->hw, WME_AC(q_num)))
 294                                ieee80211_wake_queue(adapter->hw,
 295                                                     WME_AC(q_num));
 296                }
 297
 298                skb = rsi_core_dequeue_pkt(common, q_num);
 299                if (skb == NULL) {
 300                        rsi_dbg(ERR_ZONE, "skb null\n");
 301                        mutex_unlock(&common->tx_lock);
 302                        break;
 303                }
 304                if (q_num == MGMT_BEACON_Q) {
 305                        status = rsi_send_pkt_to_bus(common, skb);
 306                        dev_kfree_skb(skb);
 307                } else {
 308#ifdef CONFIG_RSI_COEX
 309                        if (common->coex_mode > 1) {
 310                                status = rsi_coex_send_pkt(common, skb,
 311                                                           RSI_WLAN_Q);
 312                        } else {
 313#endif
 314                                if (q_num == MGMT_SOFT_Q)
 315                                        status = rsi_send_mgmt_pkt(common, skb);
 316                                else
 317                                        status = rsi_send_data_pkt(common, skb);
 318#ifdef CONFIG_RSI_COEX
 319                        }
 320#endif
 321                }
 322
 323                if (status) {
 324                        mutex_unlock(&common->tx_lock);
 325                        break;
 326                }
 327
 328                common->tx_stats.total_tx_pkt_send[q_num]++;
 329
 330                tstamp_2 = jiffies;
 331                mutex_unlock(&common->tx_lock);
 332
 333                if (time_after(tstamp_2, tstamp_1 + (300 * HZ) / 1000))
 334                        schedule();
 335        }
 336}
 337
 338struct rsi_sta *rsi_find_sta(struct rsi_common *common, u8 *mac_addr)
 339{
 340        int i;
 341
 342        for (i = 0; i < common->max_stations; i++) {
 343                if (!common->stations[i].sta)
 344                        continue;
 345                if (!(memcmp(common->stations[i].sta->addr,
 346                             mac_addr, ETH_ALEN)))
 347                        return &common->stations[i];
 348        }
 349        return NULL;
 350}
 351
 352struct ieee80211_vif *rsi_get_vif(struct rsi_hw *adapter, u8 *mac)
 353{
 354        struct ieee80211_vif *vif;
 355        int i;
 356
 357        for (i = 0; i < RSI_MAX_VIFS; i++) {
 358                vif = adapter->vifs[i];
 359                if (!vif)
 360                        continue;
 361                if (!memcmp(vif->addr, mac, ETH_ALEN))
 362                        return vif;
 363        }
 364        return NULL;
 365}
 366
 367/**
 368 * rsi_core_xmit() - This function transmits the packets received from mac80211
 369 * @common: Pointer to the driver private structure.
 370 * @skb: Pointer to the socket buffer structure.
 371 *
 372 * Return: None.
 373 */
 374void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb)
 375{
 376        struct rsi_hw *adapter = common->priv;
 377        struct ieee80211_tx_info *info;
 378        struct skb_info *tx_params;
 379        struct ieee80211_hdr *wh = NULL;
 380        struct ieee80211_vif *vif;
 381        u8 q_num, tid = 0;
 382        struct rsi_sta *rsta = NULL;
 383
 384        if ((!skb) || (!skb->len)) {
 385                rsi_dbg(ERR_ZONE, "%s: Null skb/zero Length packet\n",
 386                        __func__);
 387                goto xmit_fail;
 388        }
 389        if (common->fsm_state != FSM_MAC_INIT_DONE) {
 390                rsi_dbg(ERR_ZONE, "%s: FSM state not open\n", __func__);
 391                goto xmit_fail;
 392        }
 393        if (common->wow_flags & RSI_WOW_ENABLED) {
 394                rsi_dbg(ERR_ZONE,
 395                        "%s: Blocking Tx_packets when WOWLAN is enabled\n",
 396                        __func__);
 397                goto xmit_fail;
 398        }
 399
 400        info = IEEE80211_SKB_CB(skb);
 401        tx_params = (struct skb_info *)info->driver_data;
 402        wh = (struct ieee80211_hdr *)&skb->data[0];
 403        tx_params->sta_id = 0;
 404
 405        vif = rsi_get_vif(adapter, wh->addr2);
 406        if (!vif)
 407                goto xmit_fail;
 408        tx_params->vif = vif;
 409        tx_params->vap_id = ((struct vif_priv *)vif->drv_priv)->vap_id;
 410        if ((ieee80211_is_mgmt(wh->frame_control)) ||
 411            (ieee80211_is_ctl(wh->frame_control)) ||
 412            (ieee80211_is_qos_nullfunc(wh->frame_control))) {
 413                if (ieee80211_is_assoc_req(wh->frame_control) ||
 414                    ieee80211_is_reassoc_req(wh->frame_control)) {
 415                        struct ieee80211_bss_conf *bss = &vif->bss_conf;
 416
 417                        common->eapol4_confirm = false;
 418                        rsi_hal_send_sta_notify_frame(common,
 419                                                      RSI_IFTYPE_STATION,
 420                                                      STA_CONNECTED, bss->bssid,
 421                                                      bss->qos, bss->aid, 0,
 422                                                      vif);
 423                }
 424
 425                q_num = MGMT_SOFT_Q;
 426                skb->priority = q_num;
 427
 428                if (rsi_prepare_mgmt_desc(common, skb)) {
 429                        rsi_dbg(ERR_ZONE, "Failed to prepare desc\n");
 430                        goto xmit_fail;
 431                }
 432        } else {
 433                if (ieee80211_is_data_qos(wh->frame_control)) {
 434                        u8 *qos = ieee80211_get_qos_ctl(wh);
 435
 436                        tid = *qos & IEEE80211_QOS_CTL_TID_MASK;
 437                        skb->priority = TID_TO_WME_AC(tid);
 438                } else {
 439                        tid = IEEE80211_NONQOS_TID;
 440                        skb->priority = BE_Q;
 441                }
 442
 443                q_num = skb->priority;
 444                tx_params->tid = tid;
 445
 446                if (((vif->type == NL80211_IFTYPE_AP) ||
 447                     (vif->type == NL80211_IFTYPE_P2P_GO)) &&
 448                    (!is_broadcast_ether_addr(wh->addr1)) &&
 449                    (!is_multicast_ether_addr(wh->addr1))) {
 450                        rsta = rsi_find_sta(common, wh->addr1);
 451                        if (!rsta)
 452                                goto xmit_fail;
 453                        tx_params->sta_id = rsta->sta_id;
 454                } else {
 455                        tx_params->sta_id = 0;
 456                }
 457
 458                if (rsta) {
 459                        /* Start aggregation if not done for this tid */
 460                        if (!rsta->start_tx_aggr[tid]) {
 461                                rsta->start_tx_aggr[tid] = true;
 462                                ieee80211_start_tx_ba_session(rsta->sta,
 463                                                              tid, 0);
 464                        }
 465                }
 466                if (skb->protocol == cpu_to_be16(ETH_P_PAE)) {
 467                        q_num = MGMT_SOFT_Q;
 468                        skb->priority = q_num;
 469                }
 470                if (rsi_prepare_data_desc(common, skb)) {
 471                        rsi_dbg(ERR_ZONE, "Failed to prepare data desc\n");
 472                        goto xmit_fail;
 473                }
 474        }
 475
 476        if ((q_num < MGMT_SOFT_Q) &&
 477            ((skb_queue_len(&common->tx_queue[q_num]) + 1) >=
 478             DATA_QUEUE_WATER_MARK)) {
 479                rsi_dbg(ERR_ZONE, "%s: sw queue full\n", __func__);
 480                if (!ieee80211_queue_stopped(adapter->hw, WME_AC(q_num)))
 481                        ieee80211_stop_queue(adapter->hw, WME_AC(q_num));
 482                rsi_set_event(&common->tx_thread.event);
 483                goto xmit_fail;
 484        }
 485
 486        rsi_core_queue_pkt(common, skb);
 487        rsi_dbg(DATA_TX_ZONE, "%s: ===> Scheduling TX thread <===\n", __func__);
 488        rsi_set_event(&common->tx_thread.event);
 489
 490        return;
 491
 492xmit_fail:
 493        rsi_dbg(ERR_ZONE, "%s: Failed to queue packet\n", __func__);
 494        /* Dropping pkt here */
 495        ieee80211_free_txskb(common->priv->hw, skb);
 496}
 497