linux/drivers/staging/wfx/wfx.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-only */
   2/*
   3 * Common private data.
   4 *
   5 * Copyright (c) 2017-2020, Silicon Laboratories, Inc.
   6 * Copyright (c) 2010, ST-Ericsson
   7 * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
   8 * Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
   9 */
  10#ifndef WFX_H
  11#define WFX_H
  12
  13#include <linux/completion.h>
  14#include <linux/workqueue.h>
  15#include <linux/mutex.h>
  16#include <linux/nospec.h>
  17#include <net/mac80211.h>
  18
  19#include "bh.h"
  20#include "data_tx.h"
  21#include "main.h"
  22#include "queue.h"
  23#include "hif_tx.h"
  24
  25#define USEC_PER_TXOP 32 /* see struct ieee80211_tx_queue_params */
  26#define USEC_PER_TU 1024
  27
  28struct hwbus_ops;
  29
  30struct wfx_dev {
  31        struct wfx_platform_data pdata;
  32        struct device           *dev;
  33        struct ieee80211_hw     *hw;
  34        struct ieee80211_vif    *vif[2];
  35        struct mac_address      addresses[2];
  36        const struct hwbus_ops  *hwbus_ops;
  37        void                    *hwbus_priv;
  38
  39        u8                      keyset;
  40        struct completion       firmware_ready;
  41        struct hif_ind_startup  hw_caps;
  42        struct wfx_hif          hif;
  43        struct delayed_work     cooling_timeout_work;
  44        bool                    poll_irq;
  45        bool                    chip_frozen;
  46        struct mutex            conf_mutex;
  47
  48        struct wfx_hif_cmd      hif_cmd;
  49        struct sk_buff_head     tx_pending;
  50        wait_queue_head_t       tx_dequeue;
  51        atomic_t                tx_lock;
  52
  53        atomic_t                packet_id;
  54        u32                     key_map;
  55
  56        struct hif_rx_stats     rx_stats;
  57        struct mutex            rx_stats_lock;
  58        struct hif_tx_power_loop_info tx_power_loop_info;
  59        struct mutex            tx_power_loop_info_lock;
  60        int                     force_ps_timeout;
  61};
  62
  63struct wfx_vif {
  64        struct wfx_dev          *wdev;
  65        struct ieee80211_vif    *vif;
  66        struct ieee80211_channel *channel;
  67        int                     id;
  68
  69        u32                     link_id_map;
  70
  71        bool                    after_dtim_tx_allowed;
  72        bool                    join_in_progress;
  73
  74        struct delayed_work     beacon_loss_work;
  75
  76        struct wfx_queue        tx_queue[4];
  77        struct tx_policy_cache  tx_policy_cache;
  78        struct work_struct      tx_policy_upload_work;
  79
  80        struct work_struct      update_tim_work;
  81
  82        unsigned long           uapsd_mask;
  83
  84        /* avoid some operations in parallel with scan */
  85        struct mutex            scan_lock;
  86        struct work_struct      scan_work;
  87        struct completion       scan_complete;
  88        int                     scan_nb_chan_done;
  89        bool                    scan_abort;
  90        struct ieee80211_scan_request *scan_req;
  91
  92        struct completion       set_pm_mode_complete;
  93};
  94
  95static inline struct wfx_vif *wdev_to_wvif(struct wfx_dev *wdev, int vif_id)
  96{
  97        if (vif_id >= ARRAY_SIZE(wdev->vif)) {
  98                dev_dbg(wdev->dev, "requesting non-existent vif: %d\n", vif_id);
  99                return NULL;
 100        }
 101        vif_id = array_index_nospec(vif_id, ARRAY_SIZE(wdev->vif));
 102        if (!wdev->vif[vif_id])
 103                return NULL;
 104        return (struct wfx_vif *)wdev->vif[vif_id]->drv_priv;
 105}
 106
 107static inline struct wfx_vif *wvif_iterate(struct wfx_dev *wdev,
 108                                           struct wfx_vif *cur)
 109{
 110        int i;
 111        int mark = 0;
 112        struct wfx_vif *tmp;
 113
 114        if (!cur)
 115                mark = 1;
 116        for (i = 0; i < ARRAY_SIZE(wdev->vif); i++) {
 117                tmp = wdev_to_wvif(wdev, i);
 118                if (mark && tmp)
 119                        return tmp;
 120                if (tmp == cur)
 121                        mark = 1;
 122        }
 123        return NULL;
 124}
 125
 126static inline int wvif_count(struct wfx_dev *wdev)
 127{
 128        int i;
 129        int ret = 0;
 130        struct wfx_vif *wvif;
 131
 132        for (i = 0; i < ARRAY_SIZE(wdev->vif); i++) {
 133                wvif = wdev_to_wvif(wdev, i);
 134                if (wvif)
 135                        ret++;
 136        }
 137        return ret;
 138}
 139
 140static inline void memreverse(u8 *src, u8 length)
 141{
 142        u8 *lo = src;
 143        u8 *hi = src + length - 1;
 144        u8 swap;
 145
 146        while (lo < hi) {
 147                swap = *lo;
 148                *lo++ = *hi;
 149                *hi-- = swap;
 150        }
 151}
 152
 153static inline int memzcmp(void *src, unsigned int size)
 154{
 155        u8 *buf = src;
 156
 157        if (!size)
 158                return 0;
 159        if (*buf)
 160                return 1;
 161        return memcmp(buf, buf + 1, size - 1);
 162}
 163
 164#endif
 165