forked from SiliconLabs/wfx-linux-driver
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwfx.h
214 lines (181 loc) · 4.92 KB
/
wfx.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Common private data.
*
* Copyright (c) 2017-2020, Silicon Laboratories, Inc.
* Copyright (c) 2010, ST-Ericsson
* Copyright (c) 2006, Michael Wu <[email protected]>
* Copyright 2004-2006 Jean-Baptiste Note <[email protected]>, et al.
*/
#ifndef WFX_H
#define WFX_H
#include <linux/version.h>
#include <linux/completion.h>
#include <linux/workqueue.h>
#include <linux/mutex.h>
#include <net/mac80211.h>
#include "bh.h"
#include "data_tx.h"
#include "main.h"
#include "queue.h"
#include "secure_link.h"
#include "hif_tx.h"
#define USEC_PER_TXOP 32 /* see struct ieee80211_tx_queue_params */
#define USEC_PER_TU 1024
#if (KERNEL_VERSION(4, 16, 0) > LINUX_VERSION_CODE)
#define array_index_nospec(index, size) index
#else
#include <linux/nospec.h>
#endif
#if (KERNEL_VERSION(4, 2, 0) > LINUX_VERSION_CODE)
static inline void _ieee80211_hw_set(struct ieee80211_hw *hw,
enum ieee80211_hw_flags flg)
{
hw->flags |= flg;
}
#define ieee80211_hw_set(hw, flg) _ieee80211_hw_set(hw, IEEE80211_HW_##flg)
#endif
#if (KERNEL_VERSION(4, 7, 0) > LINUX_VERSION_CODE)
#define nl80211_band ieee80211_band
#define NL80211_BAND_2GHZ IEEE80211_BAND_2GHZ
#define NUM_NL80211_BANDS IEEE80211_NUM_BANDS
#endif
#if (KERNEL_VERSION(4, 1, 0) > LINUX_VERSION_CODE)
/* In kernels < 4.1, if we transate these define with 0, it is sufficient to
* make cfg80211_get_bss() happy. However, their values in kernel > 4.1 are not
* 0. So, only use them as parameters to cfg80211_get_bss().
*/
#define IEEE80211_BSS_TYPE_ANY 0
#define IEEE80211_PRIVACY_ANY 0
#endif
#if (KERNEL_VERSION(4, 17, 0) > LINUX_VERSION_CODE)
#define struct_size(p, member, n) \
(n * sizeof(*(p)->member) + __must_be_array((p)->member) + sizeof(*(p)))
#endif
#if KERNEL_VERSION(5, 3, 10) > LINUX_VERSION_CODE
#if KERNEL_VERSION(4, 19, 83) > LINUX_VERSION_CODE || KERNEL_VERSION(4, 20, 0) < LINUX_VERSION_CODE
#if KERNEL_VERSION(4, 14, 153) > LINUX_VERSION_CODE || KERNEL_VERSION(4, 15, 0) < LINUX_VERSION_CODE
static inline bool skb_queue_empty_lockless(const struct sk_buff_head *list)
{
return READ_ONCE(list->next) == (const struct sk_buff *) list;
}
#endif
#endif
#endif
struct hwbus_ops;
struct wfx_dev {
struct wfx_platform_data pdata;
struct device *dev;
struct ieee80211_hw *hw;
struct ieee80211_vif *vif[2];
struct mac_address addresses[2];
const struct hwbus_ops *hwbus_ops;
void *hwbus_priv;
u8 keyset;
struct completion firmware_ready;
struct hif_ind_startup hw_caps;
struct wfx_hif hif;
struct sl_context sl;
struct delayed_work cooling_timeout_work;
bool poll_irq;
bool chip_frozen;
struct mutex conf_mutex;
struct wfx_hif_cmd hif_cmd;
struct sk_buff_head tx_pending;
wait_queue_head_t tx_dequeue;
atomic_t tx_lock;
atomic_t packet_id;
u32 key_map;
struct hif_rx_stats rx_stats;
struct mutex rx_stats_lock;
struct hif_tx_power_loop_info tx_power_loop_info;
struct mutex tx_power_loop_info_lock;
int force_ps_timeout;
bool pta_enable;
u32 pta_priority;
struct hif_req_pta_settings pta_settings;
};
struct wfx_vif {
struct wfx_dev *wdev;
struct ieee80211_vif *vif;
struct ieee80211_channel *channel;
int id;
unsigned long uapsd_mask;
u32 link_id_map;
bool after_dtim_tx_allowed;
struct work_struct update_tim_work;
struct completion set_pm_mode_complete;
bool join_in_progress;
struct delayed_work beacon_loss_work;
struct wfx_queue tx_queue[4];
struct tx_policy_cache tx_policy_cache;
struct work_struct tx_policy_upload_work;
/* avoid some operations in parallel with scan */
struct mutex scan_lock;
struct work_struct scan_work;
struct completion scan_complete;
int scan_nb_chan_done;
bool scan_abort;
struct ieee80211_scan_request *scan_req;
};
static inline struct wfx_vif *wdev_to_wvif(struct wfx_dev *wdev, int vif_id)
{
if (vif_id >= ARRAY_SIZE(wdev->vif)) {
dev_dbg(wdev->dev, "requesting non-existent vif: %d\n", vif_id);
return NULL;
}
vif_id = array_index_nospec(vif_id, ARRAY_SIZE(wdev->vif));
if (!wdev->vif[vif_id])
return NULL;
return (struct wfx_vif *)wdev->vif[vif_id]->drv_priv;
}
static inline struct wfx_vif *wvif_iterate(struct wfx_dev *wdev,
struct wfx_vif *cur)
{
int i;
int mark = 0;
struct wfx_vif *tmp;
if (!cur)
mark = 1;
for (i = 0; i < ARRAY_SIZE(wdev->vif); i++) {
tmp = wdev_to_wvif(wdev, i);
if (mark && tmp)
return tmp;
if (tmp == cur)
mark = 1;
}
return NULL;
}
static inline int wvif_count(struct wfx_dev *wdev)
{
int i;
int ret = 0;
struct wfx_vif *wvif;
for (i = 0; i < ARRAY_SIZE(wdev->vif); i++) {
wvif = wdev_to_wvif(wdev, i);
if (wvif)
ret++;
}
return ret;
}
static inline void memreverse(u8 *src, u8 length)
{
u8 *lo = src;
u8 *hi = src + length - 1;
u8 swap;
while (lo < hi) {
swap = *lo;
*lo++ = *hi;
*hi-- = swap;
}
}
static inline int memzcmp(void *src, unsigned int size)
{
u8 *buf = src;
if (!size)
return 0;
if (*buf)
return 1;
return memcmp(buf, buf + 1, size - 1);
}
#endif