summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/microchip/wilc1000/netdev.h
blob: 95bc8b8fe65a584615b6b9021d08d11e4b36408b (plain)
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
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
 * All rights reserved.
 */

#ifndef WILC_NETDEV_H
#define WILC_NETDEV_H

#include <linux/tcp.h>
#include <linux/ieee80211.h>
#include <net/cfg80211.h>
#include <net/ieee80211_radiotap.h>
#include <linux/if_arp.h>
#include <linux/gpio/consumer.h>
#include <linux/rculist.h>
#include <uapi/linux/if_ether.h>

#include "hif.h"
#include "wlan.h"
#include "wlan_cfg.h"

#define FLOW_CONTROL_LOWER_THRESHOLD		128
#define FLOW_CONTROL_UPPER_THRESHOLD		256

#define PMKID_FOUND				1
#define NUM_STA_ASSOCIATED			8

#define TCP_ACK_FILTER_LINK_SPEED_THRESH	54
#define DEFAULT_LINK_SPEED			72

#define TX_BACKOFF_WEIGHT_MS			1

#define wilc_for_each_vif(w, v) \
	struct wilc *_w = w; \
	list_for_each_entry_srcu(v, &_w->vif_list, list, \
				 srcu_read_lock_held(&_w->srcu))

struct wilc_wfi_stats {
	unsigned long rx_packets;
	unsigned long tx_packets;
	unsigned long rx_bytes;
	unsigned long tx_bytes;
	u64 rx_time;
	u64 tx_time;

};

struct wilc_wfi_key {
	u8 *key;
	u8 *seq;
	int key_len;
	int seq_len;
	u32 cipher;
};

struct sta_info {
	u8 sta_associated_bss[WILC_MAX_NUM_STA][ETH_ALEN];
};

/* Parameters needed for host interface for remaining on channel */
struct wilc_wfi_p2p_listen_params {
	struct ieee80211_channel *listen_ch;
	u32 listen_duration;
	u64 listen_cookie;
};

static const u32 wilc_cipher_suites[] = {
	WLAN_CIPHER_SUITE_TKIP,
	WLAN_CIPHER_SUITE_CCMP,
	WLAN_CIPHER_SUITE_AES_CMAC
};

#define CHAN2G(_channel, _freq, _flags) {	 \
	.band             = NL80211_BAND_2GHZ, \
	.center_freq      = (_freq),		 \
	.hw_value         = (_channel),		 \
	.flags            = (_flags),		 \
	.max_antenna_gain = 0,			 \
	.max_power        = 30,			 \
}

static const struct ieee80211_channel wilc_2ghz_channels[] = {
	CHAN2G(1,  2412, 0),
	CHAN2G(2,  2417, 0),
	CHAN2G(3,  2422, 0),
	CHAN2G(4,  2427, 0),
	CHAN2G(5,  2432, 0),
	CHAN2G(6,  2437, 0),
	CHAN2G(7,  2442, 0),
	CHAN2G(8,  2447, 0),
	CHAN2G(9,  2452, 0),
	CHAN2G(10, 2457, 0),
	CHAN2G(11, 2462, 0),
	CHAN2G(12, 2467, 0),
	CHAN2G(13, 2472, 0),
	CHAN2G(14, 2484, 0)
};

#define RATETAB_ENT(_rate, _hw_value, _flags) {	\
	.bitrate  = (_rate),			\
	.hw_value = (_hw_value),		\
	.flags    = (_flags),			\
}

static struct ieee80211_rate wilc_bitrates[] = {
	RATETAB_ENT(10,  0,  0),
	RATETAB_ENT(20,  1,  0),
	RATETAB_ENT(55,  2,  0),
	RATETAB_ENT(110, 3,  0),
	RATETAB_ENT(60,  9,  0),
	RATETAB_ENT(90,  6,  0),
	RATETAB_ENT(120, 7,  0),
	RATETAB_ENT(180, 8,  0),
	RATETAB_ENT(240, 9,  0),
	RATETAB_ENT(360, 10, 0),
	RATETAB_ENT(480, 11, 0),
	RATETAB_ENT(540, 12, 0)
};

struct wilc_priv {
	struct wireless_dev wdev;
	struct cfg80211_scan_request *scan_req;

	struct wilc_wfi_p2p_listen_params remain_on_ch_params;
	u64 tx_cookie;

	bool cfg_scanning;

	u8 associated_bss[ETH_ALEN];
	struct sta_info assoc_stainfo;
	struct sk_buff *skb;
	struct net_device *dev;
	struct host_if_drv *hif_drv;
	struct wilc_pmkid_attr pmkid_list;

	/* The real interface that the monitor is on */
	struct net_device *real_ndev;
	struct wilc_wfi_key *wilc_gtk[WILC_MAX_NUM_STA];
	struct wilc_wfi_key *wilc_ptk[WILC_MAX_NUM_STA];
	struct wilc_wfi_key *wilc_igtk[2];
	u8 wilc_groupkey;

	/* mutexes */
	struct mutex scan_req_lock;
	bool p2p_listen_state;
	int scanned_cnt;

	u64 inc_roc_cookie;
};

#define MAX_TCP_SESSION                25
#define MAX_PENDING_ACKS               256

struct ack_session_info {
	u32 seq_num;
	u32 bigger_ack_num;
	u16 src_port;
	u16 dst_port;
	u16 status;
};

struct pending_acks {
	u32 ack_num;
	u32 session_index;
	struct txq_entry_t  *txqe;
};

struct tcp_ack_filter {
	struct ack_session_info ack_session_info[2 * MAX_TCP_SESSION];
	struct pending_acks pending_acks[MAX_PENDING_ACKS];
	u32 pending_base;
	u32 tcp_session;
	u32 pending_acks_idx;
	bool enabled;
};

struct wilc_vif {
	u8 idx;
	u8 iftype;
	int monitor_flag;
	int mac_opened;
	u32 mgmt_reg_stypes;
	struct net_device_stats netstats;
	struct wilc *wilc;
	u8 bssid[ETH_ALEN];
	struct host_if_drv *hif_drv;
	struct net_device *ndev;
	struct timer_list during_ip_timer;
	struct timer_list periodic_rssi;
	struct rf_info periodic_stat;
	struct tcp_ack_filter ack_filter;
	bool connecting;
	struct wilc_priv priv;
	struct list_head list;
	struct cfg80211_bss *bss;
	struct cfg80211_external_auth_params auth;
};

struct wilc_tx_queue_status {
	u8 buffer[AC_BUFFER_SIZE];
	u16 end_index;
	u16 cnt[NQUEUES];
	u16 sum;
	bool initialized;
};

struct wilc {
	struct wiphy *wiphy;
	const struct wilc_hif_func *hif_func;
	int io_type;
	s8 mac_status;
	struct clk *rtc_clk;
	bool initialized;
	u32 chipid;
	bool power_save_mode;
	int dev_irq_num;
	int close;
	u8 vif_num;
	struct list_head vif_list;

	/* protect vif list */
	struct mutex vif_mutex;
	/* Sleepable RCU struct to manipulate vif list. Sleepable version is
	 * needed over the classic RCU version because the driver's current
	 * design involves some sleeping code while manipulating a vif
	 * retrieved from vif list (so in a SRCU critical section), like:
	 * - sending commands to the chip, using info from retrieved vif
	 * - registering a new monitoring net device
	 */
	struct srcu_struct srcu;
	u8 open_ifcs;

	/* protect head of transmit queue */
	struct mutex txq_add_to_head_cs;

	/* protect txq_entry_t transmit queue */
	spinlock_t txq_spinlock;

	/* protect rxq_entry_t receiver queue */
	struct mutex rxq_cs;

	/* lock to protect hif access */
	struct mutex hif_cs;

	struct completion cfg_event;
	struct completion sync_event;
	struct completion txq_event;
	struct completion txq_thread_started;

	struct task_struct *txq_thread;

	int quit;

	/* lock to protect issue of wid command to firmware */
	struct mutex cfg_cmd_lock;
	struct wilc_cfg_frame cfg_frame;
	u32 cfg_frame_offset;
	u8 cfg_seq_no;

	u8 *rx_buffer;
	u32 rx_buffer_offset;
	u8 *tx_buffer;
	u32 *vmm_table;

	struct txq_handle txq[NQUEUES];
	int txq_entries;

	struct wilc_tx_queue_status tx_q_limit;
	struct rxq_entry_t rxq_head;

	const struct firmware *firmware;

	struct device *dev;

	struct workqueue_struct *hif_workqueue;
	struct wilc_cfg cfg;
	void *bus_data;
	struct net_device *monitor_dev;

	/* deinit lock */
	struct mutex deinit_lock;
	u8 sta_ch;
	u8 op_ch;
	struct ieee80211_channel channels[ARRAY_SIZE(wilc_2ghz_channels)];
	struct ieee80211_rate bitrates[ARRAY_SIZE(wilc_bitrates)];
	struct ieee80211_supported_band band;
	u32 cipher_suites[ARRAY_SIZE(wilc_cipher_suites)];
	u8 nv_mac_address[ETH_ALEN];
};

struct wilc_wfi_mon_priv {
	struct net_device *real_ndev;
};

void wilc_frmw_to_host(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset);
void wilc_mac_indicate(struct wilc *wilc);
void wilc_netdev_cleanup(struct wilc *wilc);
void wilc_wfi_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size, bool is_auth);
void wilc_wlan_set_bssid(struct net_device *wilc_netdev, const u8 *bssid,
			 u8 mode);
struct wilc_vif *wilc_netdev_ifc_init(struct wilc *wl, const char *name,
				      int vif_type, enum nl80211_iftype type,
				      bool rtnl_locked);
#endif