162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * This file contains definitions and data structures specific
462306a36Sopenharmony_ci * to Marvell 802.11 NIC. It contains the Device Information
562306a36Sopenharmony_ci * structure struct lbs_private..
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci#ifndef _LBS_DEV_H_
862306a36Sopenharmony_ci#define _LBS_DEV_H_
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include "defs.h"
1162306a36Sopenharmony_ci#include "decl.h"
1262306a36Sopenharmony_ci#include "host.h"
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#include <linux/kfifo.h>
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci/* sleep_params */
1762306a36Sopenharmony_cistruct sleep_params {
1862306a36Sopenharmony_ci	uint16_t sp_error;
1962306a36Sopenharmony_ci	uint16_t sp_offset;
2062306a36Sopenharmony_ci	uint16_t sp_stabletime;
2162306a36Sopenharmony_ci	uint8_t  sp_calcontrol;
2262306a36Sopenharmony_ci	uint8_t  sp_extsleepclk;
2362306a36Sopenharmony_ci	uint16_t sp_reserved;
2462306a36Sopenharmony_ci};
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci/* Mesh statistics */
2762306a36Sopenharmony_cistruct lbs_mesh_stats {
2862306a36Sopenharmony_ci	u32	fwd_bcast_cnt;		/* Fwd: Broadcast counter */
2962306a36Sopenharmony_ci	u32	fwd_unicast_cnt;	/* Fwd: Unicast counter */
3062306a36Sopenharmony_ci	u32	fwd_drop_ttl;		/* Fwd: TTL zero */
3162306a36Sopenharmony_ci	u32	fwd_drop_rbt;		/* Fwd: Recently Broadcasted */
3262306a36Sopenharmony_ci	u32	fwd_drop_noroute; 	/* Fwd: No route to Destination */
3362306a36Sopenharmony_ci	u32	fwd_drop_nobuf;		/* Fwd: Run out of internal buffers */
3462306a36Sopenharmony_ci	u32	drop_blind;		/* Rx:  Dropped by blinding table */
3562306a36Sopenharmony_ci	u32	tx_failed_cnt;		/* Tx:  Failed transmissions */
3662306a36Sopenharmony_ci};
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci/* Private structure for the MV device */
3962306a36Sopenharmony_cistruct lbs_private {
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci	/* Basic networking */
4262306a36Sopenharmony_ci	struct net_device *dev;
4362306a36Sopenharmony_ci	u32 connect_status;
4462306a36Sopenharmony_ci	struct work_struct mcast_work;
4562306a36Sopenharmony_ci	u32 nr_of_multicastmacaddr;
4662306a36Sopenharmony_ci	u8 multicastlist[MRVDRV_MAX_MULTICAST_LIST_SIZE][ETH_ALEN];
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci	/* CFG80211 */
4962306a36Sopenharmony_ci	struct wireless_dev *wdev;
5062306a36Sopenharmony_ci	bool wiphy_registered;
5162306a36Sopenharmony_ci	struct cfg80211_scan_request *scan_req;
5262306a36Sopenharmony_ci	u8 assoc_bss[ETH_ALEN];
5362306a36Sopenharmony_ci	u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
5462306a36Sopenharmony_ci	u8 disassoc_reason;
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci	/* Mesh */
5762306a36Sopenharmony_ci	struct net_device *mesh_dev; /* Virtual device */
5862306a36Sopenharmony_ci#ifdef CONFIG_LIBERTAS_MESH
5962306a36Sopenharmony_ci	struct lbs_mesh_stats mstats;
6062306a36Sopenharmony_ci	uint16_t mesh_tlv;
6162306a36Sopenharmony_ci	u8 mesh_channel;
6262306a36Sopenharmony_ci#endif
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci	/* Debugfs */
6562306a36Sopenharmony_ci	struct dentry *debugfs_dir;
6662306a36Sopenharmony_ci	struct dentry *debugfs_debug;
6762306a36Sopenharmony_ci	struct dentry *debugfs_files[6];
6862306a36Sopenharmony_ci	struct dentry *events_dir;
6962306a36Sopenharmony_ci	struct dentry *debugfs_events_files[6];
7062306a36Sopenharmony_ci	struct dentry *regs_dir;
7162306a36Sopenharmony_ci	struct dentry *debugfs_regs_files[6];
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci	/* Hardware debugging */
7462306a36Sopenharmony_ci	u32 mac_offset;
7562306a36Sopenharmony_ci	u32 bbp_offset;
7662306a36Sopenharmony_ci	u32 rf_offset;
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci	/* Power management */
7962306a36Sopenharmony_ci	u16 psmode;
8062306a36Sopenharmony_ci	u32 psstate;
8162306a36Sopenharmony_ci	u8 needtowakeup;
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci	/* Deep sleep */
8462306a36Sopenharmony_ci	int is_deep_sleep;
8562306a36Sopenharmony_ci	int deep_sleep_required;
8662306a36Sopenharmony_ci	int is_auto_deep_sleep_enabled;
8762306a36Sopenharmony_ci	int wakeup_dev_required;
8862306a36Sopenharmony_ci	int is_activity_detected;
8962306a36Sopenharmony_ci	int auto_deep_sleep_timeout; /* in ms */
9062306a36Sopenharmony_ci	wait_queue_head_t ds_awake_q;
9162306a36Sopenharmony_ci	struct timer_list auto_deepsleep_timer;
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci	/* Host sleep*/
9462306a36Sopenharmony_ci	int is_host_sleep_configured;
9562306a36Sopenharmony_ci	int is_host_sleep_activated;
9662306a36Sopenharmony_ci	wait_queue_head_t host_sleep_q;
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ci	/* Hardware access */
9962306a36Sopenharmony_ci	void *card;
10062306a36Sopenharmony_ci	bool iface_running;
10162306a36Sopenharmony_ci	u8 is_polling; /* host has to poll the card irq */
10262306a36Sopenharmony_ci	u8 fw_ready;
10362306a36Sopenharmony_ci	u8 surpriseremoved;
10462306a36Sopenharmony_ci	u8 setup_fw_on_resume;
10562306a36Sopenharmony_ci	u8 power_up_on_resume;
10662306a36Sopenharmony_ci	int (*hw_host_to_card) (struct lbs_private *priv, u8 type, u8 *payload, u16 nb);
10762306a36Sopenharmony_ci	void (*reset_card) (struct lbs_private *priv);
10862306a36Sopenharmony_ci	int (*power_save) (struct lbs_private *priv);
10962306a36Sopenharmony_ci	int (*power_restore) (struct lbs_private *priv);
11062306a36Sopenharmony_ci	int (*enter_deep_sleep) (struct lbs_private *priv);
11162306a36Sopenharmony_ci	int (*exit_deep_sleep) (struct lbs_private *priv);
11262306a36Sopenharmony_ci	int (*reset_deep_sleep_wakeup) (struct lbs_private *priv);
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci	/* Adapter info (from EEPROM) */
11562306a36Sopenharmony_ci	u32 fwrelease;
11662306a36Sopenharmony_ci	u32 fwcapinfo;
11762306a36Sopenharmony_ci	u16 regioncode;
11862306a36Sopenharmony_ci	u8 current_addr[ETH_ALEN];
11962306a36Sopenharmony_ci	u8 copied_hwaddr;
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci	/* Command download */
12262306a36Sopenharmony_ci	u8 dnld_sent;
12362306a36Sopenharmony_ci	/* bit0 1/0=data_sent/data_tx_done,
12462306a36Sopenharmony_ci	   bit1 1/0=cmd_sent/cmd_tx_done,
12562306a36Sopenharmony_ci	   all other bits reserved 0 */
12662306a36Sopenharmony_ci	u16 seqnum;
12762306a36Sopenharmony_ci	struct cmd_ctrl_node *cmd_array;
12862306a36Sopenharmony_ci	struct cmd_ctrl_node *cur_cmd;
12962306a36Sopenharmony_ci	struct list_head cmdfreeq;    /* free command buffers */
13062306a36Sopenharmony_ci	struct list_head cmdpendingq; /* pending command buffers */
13162306a36Sopenharmony_ci	struct timer_list command_timer;
13262306a36Sopenharmony_ci	int cmd_timed_out;
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_ci	/* Command responses sent from the hardware to the driver */
13562306a36Sopenharmony_ci	u8 resp_idx;
13662306a36Sopenharmony_ci	u8 resp_buf[2][LBS_UPLD_SIZE];
13762306a36Sopenharmony_ci	u32 resp_len[2];
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_ci	/* Events sent from hardware to driver */
14062306a36Sopenharmony_ci	struct kfifo event_fifo;
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci	/* thread to service interrupts */
14362306a36Sopenharmony_ci	struct task_struct *main_thread;
14462306a36Sopenharmony_ci	wait_queue_head_t waitq;
14562306a36Sopenharmony_ci	struct workqueue_struct *work_thread;
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_ci	/* Encryption stuff */
14862306a36Sopenharmony_ci	u8 authtype_auto;
14962306a36Sopenharmony_ci	u8 wep_tx_key;
15062306a36Sopenharmony_ci	u8 wep_key[4][WLAN_KEY_LEN_WEP104];
15162306a36Sopenharmony_ci	u8 wep_key_len[4];
15262306a36Sopenharmony_ci
15362306a36Sopenharmony_ci	/* Wake On LAN */
15462306a36Sopenharmony_ci	uint32_t wol_criteria;
15562306a36Sopenharmony_ci	uint8_t wol_gpio;
15662306a36Sopenharmony_ci	uint8_t wol_gap;
15762306a36Sopenharmony_ci	bool ehs_remove_supported;
15862306a36Sopenharmony_ci
15962306a36Sopenharmony_ci	/* Transmitting */
16062306a36Sopenharmony_ci	int tx_pending_len;		/* -1 while building packet */
16162306a36Sopenharmony_ci	u8 tx_pending_buf[LBS_UPLD_SIZE];
16262306a36Sopenharmony_ci	/* protected by hard_start_xmit serialization */
16362306a36Sopenharmony_ci	u8 txretrycount;
16462306a36Sopenharmony_ci	struct sk_buff *currenttxskb;
16562306a36Sopenharmony_ci	struct timer_list tx_lockup_timer;
16662306a36Sopenharmony_ci
16762306a36Sopenharmony_ci	/* Locks */
16862306a36Sopenharmony_ci	struct mutex lock;
16962306a36Sopenharmony_ci	spinlock_t driver_lock;
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci	/* NIC/link operation characteristics */
17262306a36Sopenharmony_ci	u16 mac_control;
17362306a36Sopenharmony_ci	u8 radio_on;
17462306a36Sopenharmony_ci	u8 cur_rate;
17562306a36Sopenharmony_ci	u8 channel;
17662306a36Sopenharmony_ci	s16 txpower_cur;
17762306a36Sopenharmony_ci	s16 txpower_min;
17862306a36Sopenharmony_ci	s16 txpower_max;
17962306a36Sopenharmony_ci
18062306a36Sopenharmony_ci	/* Scanning */
18162306a36Sopenharmony_ci	struct delayed_work scan_work;
18262306a36Sopenharmony_ci	int scan_channel;
18362306a36Sopenharmony_ci	/* Queue of things waiting for scan completion */
18462306a36Sopenharmony_ci	wait_queue_head_t scan_q;
18562306a36Sopenharmony_ci	/* Whether the scan was initiated internally and not by cfg80211 */
18662306a36Sopenharmony_ci	bool internal_scan;
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_ci	/* Firmware load */
18962306a36Sopenharmony_ci	u32 fw_model;
19062306a36Sopenharmony_ci	wait_queue_head_t fw_waitq;
19162306a36Sopenharmony_ci	struct device *fw_device;
19262306a36Sopenharmony_ci	const struct firmware *helper_fw;
19362306a36Sopenharmony_ci	const struct lbs_fw_table *fw_table;
19462306a36Sopenharmony_ci	const struct lbs_fw_table *fw_iter;
19562306a36Sopenharmony_ci	lbs_fw_cb fw_callback;
19662306a36Sopenharmony_ci};
19762306a36Sopenharmony_ci
19862306a36Sopenharmony_ciextern struct cmd_confirm_sleep confirm_sleep;
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_ci/* Check if there is an interface active. */
20162306a36Sopenharmony_cistatic inline int lbs_iface_active(struct lbs_private *priv)
20262306a36Sopenharmony_ci{
20362306a36Sopenharmony_ci	int r;
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_ci	r = netif_running(priv->dev);
20662306a36Sopenharmony_ci	if (priv->mesh_dev)
20762306a36Sopenharmony_ci		r |= netif_running(priv->mesh_dev);
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_ci	return r;
21062306a36Sopenharmony_ci}
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_ci#endif
213