162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
462306a36Sopenharmony_ci * All rights reserved.
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#ifndef WILC_NETDEV_H
862306a36Sopenharmony_ci#define WILC_NETDEV_H
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include <linux/tcp.h>
1162306a36Sopenharmony_ci#include <linux/ieee80211.h>
1262306a36Sopenharmony_ci#include <net/cfg80211.h>
1362306a36Sopenharmony_ci#include <net/ieee80211_radiotap.h>
1462306a36Sopenharmony_ci#include <linux/if_arp.h>
1562306a36Sopenharmony_ci#include <linux/gpio/consumer.h>
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci#include "hif.h"
1862306a36Sopenharmony_ci#include "wlan.h"
1962306a36Sopenharmony_ci#include "wlan_cfg.h"
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci#define FLOW_CONTROL_LOWER_THRESHOLD		128
2262306a36Sopenharmony_ci#define FLOW_CONTROL_UPPER_THRESHOLD		256
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci#define PMKID_FOUND				1
2562306a36Sopenharmony_ci#define NUM_STA_ASSOCIATED			8
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci#define TCP_ACK_FILTER_LINK_SPEED_THRESH	54
2862306a36Sopenharmony_ci#define DEFAULT_LINK_SPEED			72
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_cistruct wilc_wfi_stats {
3162306a36Sopenharmony_ci	unsigned long rx_packets;
3262306a36Sopenharmony_ci	unsigned long tx_packets;
3362306a36Sopenharmony_ci	unsigned long rx_bytes;
3462306a36Sopenharmony_ci	unsigned long tx_bytes;
3562306a36Sopenharmony_ci	u64 rx_time;
3662306a36Sopenharmony_ci	u64 tx_time;
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci};
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_cistruct wilc_wfi_key {
4162306a36Sopenharmony_ci	u8 *key;
4262306a36Sopenharmony_ci	u8 *seq;
4362306a36Sopenharmony_ci	int key_len;
4462306a36Sopenharmony_ci	int seq_len;
4562306a36Sopenharmony_ci	u32 cipher;
4662306a36Sopenharmony_ci};
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_cistruct sta_info {
4962306a36Sopenharmony_ci	u8 sta_associated_bss[WILC_MAX_NUM_STA][ETH_ALEN];
5062306a36Sopenharmony_ci};
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci/* Parameters needed for host interface for remaining on channel */
5362306a36Sopenharmony_cistruct wilc_wfi_p2p_listen_params {
5462306a36Sopenharmony_ci	struct ieee80211_channel *listen_ch;
5562306a36Sopenharmony_ci	u32 listen_duration;
5662306a36Sopenharmony_ci	u64 listen_cookie;
5762306a36Sopenharmony_ci};
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_cistatic const u32 wilc_cipher_suites[] = {
6062306a36Sopenharmony_ci	WLAN_CIPHER_SUITE_TKIP,
6162306a36Sopenharmony_ci	WLAN_CIPHER_SUITE_CCMP,
6262306a36Sopenharmony_ci	WLAN_CIPHER_SUITE_AES_CMAC
6362306a36Sopenharmony_ci};
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci#define CHAN2G(_channel, _freq, _flags) {	 \
6662306a36Sopenharmony_ci	.band             = NL80211_BAND_2GHZ, \
6762306a36Sopenharmony_ci	.center_freq      = (_freq),		 \
6862306a36Sopenharmony_ci	.hw_value         = (_channel),		 \
6962306a36Sopenharmony_ci	.flags            = (_flags),		 \
7062306a36Sopenharmony_ci	.max_antenna_gain = 0,			 \
7162306a36Sopenharmony_ci	.max_power        = 30,			 \
7262306a36Sopenharmony_ci}
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_cistatic const struct ieee80211_channel wilc_2ghz_channels[] = {
7562306a36Sopenharmony_ci	CHAN2G(1,  2412, 0),
7662306a36Sopenharmony_ci	CHAN2G(2,  2417, 0),
7762306a36Sopenharmony_ci	CHAN2G(3,  2422, 0),
7862306a36Sopenharmony_ci	CHAN2G(4,  2427, 0),
7962306a36Sopenharmony_ci	CHAN2G(5,  2432, 0),
8062306a36Sopenharmony_ci	CHAN2G(6,  2437, 0),
8162306a36Sopenharmony_ci	CHAN2G(7,  2442, 0),
8262306a36Sopenharmony_ci	CHAN2G(8,  2447, 0),
8362306a36Sopenharmony_ci	CHAN2G(9,  2452, 0),
8462306a36Sopenharmony_ci	CHAN2G(10, 2457, 0),
8562306a36Sopenharmony_ci	CHAN2G(11, 2462, 0),
8662306a36Sopenharmony_ci	CHAN2G(12, 2467, 0),
8762306a36Sopenharmony_ci	CHAN2G(13, 2472, 0),
8862306a36Sopenharmony_ci	CHAN2G(14, 2484, 0)
8962306a36Sopenharmony_ci};
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci#define RATETAB_ENT(_rate, _hw_value, _flags) {	\
9262306a36Sopenharmony_ci	.bitrate  = (_rate),			\
9362306a36Sopenharmony_ci	.hw_value = (_hw_value),		\
9462306a36Sopenharmony_ci	.flags    = (_flags),			\
9562306a36Sopenharmony_ci}
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_cistatic struct ieee80211_rate wilc_bitrates[] = {
9862306a36Sopenharmony_ci	RATETAB_ENT(10,  0,  0),
9962306a36Sopenharmony_ci	RATETAB_ENT(20,  1,  0),
10062306a36Sopenharmony_ci	RATETAB_ENT(55,  2,  0),
10162306a36Sopenharmony_ci	RATETAB_ENT(110, 3,  0),
10262306a36Sopenharmony_ci	RATETAB_ENT(60,  9,  0),
10362306a36Sopenharmony_ci	RATETAB_ENT(90,  6,  0),
10462306a36Sopenharmony_ci	RATETAB_ENT(120, 7,  0),
10562306a36Sopenharmony_ci	RATETAB_ENT(180, 8,  0),
10662306a36Sopenharmony_ci	RATETAB_ENT(240, 9,  0),
10762306a36Sopenharmony_ci	RATETAB_ENT(360, 10, 0),
10862306a36Sopenharmony_ci	RATETAB_ENT(480, 11, 0),
10962306a36Sopenharmony_ci	RATETAB_ENT(540, 12, 0)
11062306a36Sopenharmony_ci};
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_cistruct wilc_priv {
11362306a36Sopenharmony_ci	struct wireless_dev wdev;
11462306a36Sopenharmony_ci	struct cfg80211_scan_request *scan_req;
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_ci	struct wilc_wfi_p2p_listen_params remain_on_ch_params;
11762306a36Sopenharmony_ci	u64 tx_cookie;
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci	bool cfg_scanning;
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci	u8 associated_bss[ETH_ALEN];
12262306a36Sopenharmony_ci	struct sta_info assoc_stainfo;
12362306a36Sopenharmony_ci	struct sk_buff *skb;
12462306a36Sopenharmony_ci	struct net_device *dev;
12562306a36Sopenharmony_ci	struct host_if_drv *hif_drv;
12662306a36Sopenharmony_ci	struct wilc_pmkid_attr pmkid_list;
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_ci	/* The real interface that the monitor is on */
12962306a36Sopenharmony_ci	struct net_device *real_ndev;
13062306a36Sopenharmony_ci	struct wilc_wfi_key *wilc_gtk[WILC_MAX_NUM_STA];
13162306a36Sopenharmony_ci	struct wilc_wfi_key *wilc_ptk[WILC_MAX_NUM_STA];
13262306a36Sopenharmony_ci	struct wilc_wfi_key *wilc_igtk[2];
13362306a36Sopenharmony_ci	u8 wilc_groupkey;
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ci	/* mutexes */
13662306a36Sopenharmony_ci	struct mutex scan_req_lock;
13762306a36Sopenharmony_ci	bool p2p_listen_state;
13862306a36Sopenharmony_ci	int scanned_cnt;
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci	u64 inc_roc_cookie;
14162306a36Sopenharmony_ci};
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci#define MAX_TCP_SESSION                25
14462306a36Sopenharmony_ci#define MAX_PENDING_ACKS               256
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_cistruct ack_session_info {
14762306a36Sopenharmony_ci	u32 seq_num;
14862306a36Sopenharmony_ci	u32 bigger_ack_num;
14962306a36Sopenharmony_ci	u16 src_port;
15062306a36Sopenharmony_ci	u16 dst_port;
15162306a36Sopenharmony_ci	u16 status;
15262306a36Sopenharmony_ci};
15362306a36Sopenharmony_ci
15462306a36Sopenharmony_cistruct pending_acks {
15562306a36Sopenharmony_ci	u32 ack_num;
15662306a36Sopenharmony_ci	u32 session_index;
15762306a36Sopenharmony_ci	struct txq_entry_t  *txqe;
15862306a36Sopenharmony_ci};
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_cistruct tcp_ack_filter {
16162306a36Sopenharmony_ci	struct ack_session_info ack_session_info[2 * MAX_TCP_SESSION];
16262306a36Sopenharmony_ci	struct pending_acks pending_acks[MAX_PENDING_ACKS];
16362306a36Sopenharmony_ci	u32 pending_base;
16462306a36Sopenharmony_ci	u32 tcp_session;
16562306a36Sopenharmony_ci	u32 pending_acks_idx;
16662306a36Sopenharmony_ci	bool enabled;
16762306a36Sopenharmony_ci};
16862306a36Sopenharmony_ci
16962306a36Sopenharmony_cistruct wilc_vif {
17062306a36Sopenharmony_ci	u8 idx;
17162306a36Sopenharmony_ci	u8 iftype;
17262306a36Sopenharmony_ci	int monitor_flag;
17362306a36Sopenharmony_ci	int mac_opened;
17462306a36Sopenharmony_ci	u32 mgmt_reg_stypes;
17562306a36Sopenharmony_ci	struct net_device_stats netstats;
17662306a36Sopenharmony_ci	struct wilc *wilc;
17762306a36Sopenharmony_ci	u8 bssid[ETH_ALEN];
17862306a36Sopenharmony_ci	struct host_if_drv *hif_drv;
17962306a36Sopenharmony_ci	struct net_device *ndev;
18062306a36Sopenharmony_ci	struct timer_list during_ip_timer;
18162306a36Sopenharmony_ci	struct timer_list periodic_rssi;
18262306a36Sopenharmony_ci	struct rf_info periodic_stat;
18362306a36Sopenharmony_ci	struct tcp_ack_filter ack_filter;
18462306a36Sopenharmony_ci	bool connecting;
18562306a36Sopenharmony_ci	struct wilc_priv priv;
18662306a36Sopenharmony_ci	struct list_head list;
18762306a36Sopenharmony_ci	struct cfg80211_bss *bss;
18862306a36Sopenharmony_ci	struct cfg80211_external_auth_params auth;
18962306a36Sopenharmony_ci};
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_cistruct wilc_tx_queue_status {
19262306a36Sopenharmony_ci	u8 buffer[AC_BUFFER_SIZE];
19362306a36Sopenharmony_ci	u16 end_index;
19462306a36Sopenharmony_ci	u16 cnt[NQUEUES];
19562306a36Sopenharmony_ci	u16 sum;
19662306a36Sopenharmony_ci	bool initialized;
19762306a36Sopenharmony_ci};
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_cistruct wilc {
20062306a36Sopenharmony_ci	struct wiphy *wiphy;
20162306a36Sopenharmony_ci	const struct wilc_hif_func *hif_func;
20262306a36Sopenharmony_ci	int io_type;
20362306a36Sopenharmony_ci	s8 mac_status;
20462306a36Sopenharmony_ci	struct clk *rtc_clk;
20562306a36Sopenharmony_ci	bool initialized;
20662306a36Sopenharmony_ci	u32 chipid;
20762306a36Sopenharmony_ci	bool power_save_mode;
20862306a36Sopenharmony_ci	int dev_irq_num;
20962306a36Sopenharmony_ci	int close;
21062306a36Sopenharmony_ci	u8 vif_num;
21162306a36Sopenharmony_ci	struct list_head vif_list;
21262306a36Sopenharmony_ci
21362306a36Sopenharmony_ci	/* protect vif list */
21462306a36Sopenharmony_ci	struct mutex vif_mutex;
21562306a36Sopenharmony_ci	struct srcu_struct srcu;
21662306a36Sopenharmony_ci	u8 open_ifcs;
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_ci	/* protect head of transmit queue */
21962306a36Sopenharmony_ci	struct mutex txq_add_to_head_cs;
22062306a36Sopenharmony_ci
22162306a36Sopenharmony_ci	/* protect txq_entry_t transmit queue */
22262306a36Sopenharmony_ci	spinlock_t txq_spinlock;
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_ci	/* protect rxq_entry_t receiver queue */
22562306a36Sopenharmony_ci	struct mutex rxq_cs;
22662306a36Sopenharmony_ci
22762306a36Sopenharmony_ci	/* lock to protect hif access */
22862306a36Sopenharmony_ci	struct mutex hif_cs;
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_ci	struct completion cfg_event;
23162306a36Sopenharmony_ci	struct completion sync_event;
23262306a36Sopenharmony_ci	struct completion txq_event;
23362306a36Sopenharmony_ci	struct completion txq_thread_started;
23462306a36Sopenharmony_ci
23562306a36Sopenharmony_ci	struct task_struct *txq_thread;
23662306a36Sopenharmony_ci
23762306a36Sopenharmony_ci	int quit;
23862306a36Sopenharmony_ci
23962306a36Sopenharmony_ci	/* lock to protect issue of wid command to firmware */
24062306a36Sopenharmony_ci	struct mutex cfg_cmd_lock;
24162306a36Sopenharmony_ci	struct wilc_cfg_frame cfg_frame;
24262306a36Sopenharmony_ci	u32 cfg_frame_offset;
24362306a36Sopenharmony_ci	u8 cfg_seq_no;
24462306a36Sopenharmony_ci
24562306a36Sopenharmony_ci	u8 *rx_buffer;
24662306a36Sopenharmony_ci	u32 rx_buffer_offset;
24762306a36Sopenharmony_ci	u8 *tx_buffer;
24862306a36Sopenharmony_ci	u32 *vmm_table;
24962306a36Sopenharmony_ci
25062306a36Sopenharmony_ci	struct txq_handle txq[NQUEUES];
25162306a36Sopenharmony_ci	int txq_entries;
25262306a36Sopenharmony_ci
25362306a36Sopenharmony_ci	struct wilc_tx_queue_status tx_q_limit;
25462306a36Sopenharmony_ci	struct rxq_entry_t rxq_head;
25562306a36Sopenharmony_ci
25662306a36Sopenharmony_ci	const struct firmware *firmware;
25762306a36Sopenharmony_ci
25862306a36Sopenharmony_ci	struct device *dev;
25962306a36Sopenharmony_ci	bool suspend_event;
26062306a36Sopenharmony_ci
26162306a36Sopenharmony_ci	struct workqueue_struct *hif_workqueue;
26262306a36Sopenharmony_ci	struct wilc_cfg cfg;
26362306a36Sopenharmony_ci	void *bus_data;
26462306a36Sopenharmony_ci	struct net_device *monitor_dev;
26562306a36Sopenharmony_ci
26662306a36Sopenharmony_ci	/* deinit lock */
26762306a36Sopenharmony_ci	struct mutex deinit_lock;
26862306a36Sopenharmony_ci	u8 sta_ch;
26962306a36Sopenharmony_ci	u8 op_ch;
27062306a36Sopenharmony_ci	struct ieee80211_channel channels[ARRAY_SIZE(wilc_2ghz_channels)];
27162306a36Sopenharmony_ci	struct ieee80211_rate bitrates[ARRAY_SIZE(wilc_bitrates)];
27262306a36Sopenharmony_ci	struct ieee80211_supported_band band;
27362306a36Sopenharmony_ci	u32 cipher_suites[ARRAY_SIZE(wilc_cipher_suites)];
27462306a36Sopenharmony_ci};
27562306a36Sopenharmony_ci
27662306a36Sopenharmony_cistruct wilc_wfi_mon_priv {
27762306a36Sopenharmony_ci	struct net_device *real_ndev;
27862306a36Sopenharmony_ci};
27962306a36Sopenharmony_ci
28062306a36Sopenharmony_civoid wilc_frmw_to_host(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset);
28162306a36Sopenharmony_civoid wilc_mac_indicate(struct wilc *wilc);
28262306a36Sopenharmony_civoid wilc_netdev_cleanup(struct wilc *wilc);
28362306a36Sopenharmony_civoid wilc_wfi_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size, bool is_auth);
28462306a36Sopenharmony_civoid wilc_wlan_set_bssid(struct net_device *wilc_netdev, const u8 *bssid,
28562306a36Sopenharmony_ci			 u8 mode);
28662306a36Sopenharmony_cistruct wilc_vif *wilc_netdev_ifc_init(struct wilc *wl, const char *name,
28762306a36Sopenharmony_ci				      int vif_type, enum nl80211_iftype type,
28862306a36Sopenharmony_ci				      bool rtnl_locked);
28962306a36Sopenharmony_ci#endif
290