Merge tag 'staging-5.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh...
[linux-2.6-microblaze.git] / drivers / staging / wfx / wfx.h
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Common private data for Silicon Labs WFx chips.
4  *
5  * Copyright (c) 2017-2019, 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 "secure_link.h"
24 #include "sta.h"
25 #include "scan.h"
26 #include "hif_tx.h"
27 #include "hif_api_general.h"
28
29 #define USEC_PER_TXOP 32 // see struct ieee80211_tx_queue_params
30 #define USEC_PER_TU 1024
31
32 struct hwbus_ops;
33
34 struct wfx_dev {
35         struct wfx_platform_data pdata;
36         struct device           *dev;
37         struct ieee80211_hw     *hw;
38         struct ieee80211_vif    *vif[2];
39         struct mac_address      addresses[2];
40         const struct hwbus_ops  *hwbus_ops;
41         void                    *hwbus_priv;
42
43         u8                      keyset;
44         struct completion       firmware_ready;
45         struct hif_ind_startup  hw_caps;
46         struct wfx_hif          hif;
47         struct sl_context       sl;
48         int                     chip_frozen;
49         struct mutex            conf_mutex;
50
51         struct wfx_hif_cmd      hif_cmd;
52         struct wfx_queue        tx_queue[4];
53         struct wfx_queue_stats  tx_queue_stats;
54         int                     tx_burst_idx;
55         atomic_t                tx_lock;
56
57         atomic_t                packet_id;
58         u32                     key_map;
59         struct hif_req_add_key  keys[MAX_KEY_ENTRIES];
60
61         struct hif_rx_stats     rx_stats;
62         struct mutex            rx_stats_lock;
63 };
64
65 struct wfx_vif {
66         struct wfx_dev          *wdev;
67         struct ieee80211_vif    *vif;
68         struct ieee80211_channel *channel;
69         int                     id;
70         enum wfx_state          state;
71
72         int                     bss_loss_state;
73         u32                     bss_loss_confirm_id;
74         struct mutex            bss_loss_lock;
75         struct delayed_work     bss_loss_work;
76
77         u32                     link_id_map;
78
79         bool                    after_dtim_tx_allowed;
80         struct wfx_grp_addr_table mcast_filter;
81
82         s8                      wep_default_key_id;
83         struct sk_buff          *wep_pending_skb;
84         struct work_struct      wep_key_work;
85
86         struct tx_policy_cache  tx_policy_cache;
87         struct work_struct      tx_policy_upload_work;
88
89         u32                     sta_asleep_mask;
90         spinlock_t              ps_state_lock;
91         struct work_struct      update_tim_work;
92
93         int                     beacon_int;
94         bool                    filter_bssid;
95         bool                    fwd_probe_req;
96         bool                    disable_beacon_filter;
97         struct work_struct      update_filtering_work;
98
99         unsigned long           uapsd_mask;
100         struct ieee80211_tx_queue_params edca_params[IEEE80211_NUM_ACS];
101         struct hif_req_set_bss_params bss_params;
102         struct work_struct      bss_params_work;
103
104         int                     join_complete_status;
105         struct work_struct      unjoin_work;
106
107         /* avoid some operations in parallel with scan */
108         struct mutex            scan_lock;
109         struct work_struct      scan_work;
110         struct completion       scan_complete;
111         bool                    scan_abort;
112         struct ieee80211_scan_request *scan_req;
113
114         struct completion       set_pm_mode_complete;
115
116         struct list_head        event_queue;
117         spinlock_t              event_queue_lock;
118         struct work_struct      event_handler_work;
119 };
120
121 static inline struct wfx_vif *wdev_to_wvif(struct wfx_dev *wdev, int vif_id)
122 {
123         if (vif_id >= ARRAY_SIZE(wdev->vif)) {
124                 dev_dbg(wdev->dev, "requesting non-existent vif: %d\n", vif_id);
125                 return NULL;
126         }
127         vif_id = array_index_nospec(vif_id, ARRAY_SIZE(wdev->vif));
128         if (!wdev->vif[vif_id]) {
129                 dev_dbg(wdev->dev, "requesting non-allocated vif: %d\n",
130                         vif_id);
131                 return NULL;
132         }
133         return (struct wfx_vif *) wdev->vif[vif_id]->drv_priv;
134 }
135
136 static inline struct wfx_vif *wvif_iterate(struct wfx_dev *wdev,
137                                            struct wfx_vif *cur)
138 {
139         int i;
140         int mark = 0;
141         struct wfx_vif *tmp;
142
143         if (!cur)
144                 mark = 1;
145         for (i = 0; i < ARRAY_SIZE(wdev->vif); i++) {
146                 tmp = wdev_to_wvif(wdev, i);
147                 if (mark && tmp)
148                         return tmp;
149                 if (tmp == cur)
150                         mark = 1;
151         }
152         return NULL;
153 }
154
155 static inline int wvif_count(struct wfx_dev *wdev)
156 {
157         int i;
158         int ret = 0;
159         struct wfx_vif *wvif;
160
161         for (i = 0; i < ARRAY_SIZE(wdev->vif); i++) {
162                 wvif = wdev_to_wvif(wdev, i);
163                 if (wvif)
164                         ret++;
165         }
166         return ret;
167 }
168
169 static inline void memreverse(u8 *src, u8 length)
170 {
171         u8 *lo = src;
172         u8 *hi = src + length - 1;
173         u8 swap;
174
175         while (lo < hi) {
176                 swap = *lo;
177                 *lo++ = *hi;
178                 *hi-- = swap;
179         }
180 }
181
182 static inline int memzcmp(void *src, unsigned int size)
183 {
184         u8 *buf = src;
185
186         if (!size)
187                 return 0;
188         if (*buf)
189                 return 1;
190         return memcmp(buf, buf + 1, size - 1);
191 }
192
193 #endif /* WFX_H */