linux/drivers/staging/wfx/wfx.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-only */
   2/*
   3 * Common private data for Silicon Labs WFx chips.
   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        bool                    scan_abort;
  89        struct ieee80211_scan_request *scan_req;
  90
  91        struct completion       set_pm_mode_complete;
  92};
  93
  94static inline struct wfx_vif *wdev_to_wvif(struct wfx_dev *wdev, int vif_id)
  95{
  96        if (vif_id >= ARRAY_SIZE(wdev->vif)) {
  97                dev_dbg(wdev->dev, "requesting non-existent vif: %d\n", vif_id);
  98                return NULL;
  99        }
 100        vif_id = array_index_nospec(vif_id, ARRAY_SIZE(wdev->vif));
 101        if (!wdev->vif[vif_id]) {
 102                dev_dbg(wdev->dev, "requesting non-allocated vif: %d\n",
 103                        vif_id);
 104                return NULL;
 105        }
 106        return (struct wfx_vif *) wdev->vif[vif_id]->drv_priv;
 107}
 108
 109static inline struct wfx_vif *wvif_iterate(struct wfx_dev *wdev,
 110                                           struct wfx_vif *cur)
 111{
 112        int i;
 113        int mark = 0;
 114        struct wfx_vif *tmp;
 115
 116        if (!cur)
 117                mark = 1;
 118        for (i = 0; i < ARRAY_SIZE(wdev->vif); i++) {
 119                tmp = wdev_to_wvif(wdev, i);
 120                if (mark && tmp)
 121                        return tmp;
 122                if (tmp == cur)
 123                        mark = 1;
 124        }
 125        return NULL;
 126}
 127
 128static inline int wvif_count(struct wfx_dev *wdev)
 129{
 130        int i;
 131        int ret = 0;
 132        struct wfx_vif *wvif;
 133
 134        for (i = 0; i < ARRAY_SIZE(wdev->vif); i++) {
 135                wvif = wdev_to_wvif(wdev, i);
 136                if (wvif)
 137                        ret++;
 138        }
 139        return ret;
 140}
 141
 142static inline void memreverse(u8 *src, u8 length)
 143{
 144        u8 *lo = src;
 145        u8 *hi = src + length - 1;
 146        u8 swap;
 147
 148        while (lo < hi) {
 149                swap = *lo;
 150                *lo++ = *hi;
 151                *hi-- = swap;
 152        }
 153}
 154
 155static inline int memzcmp(void *src, unsigned int size)
 156{
 157        u8 *buf = src;
 158
 159        if (!size)
 160                return 0;
 161        if (*buf)
 162                return 1;
 163        return memcmp(buf, buf + 1, size - 1);
 164}
 165
 166#endif /* WFX_H */
 167