18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci *  Copyright (C) 2002 Intersil Americas Inc.
48c2ecf20Sopenharmony_ci *  Copyright (C) 2003 Herbert Valerio Riedel <hvr@gnu.org>
58c2ecf20Sopenharmony_ci *  Copyright (C) 2003 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
68c2ecf20Sopenharmony_ci *  Copyright (C) 2003 Aurelien Alleaume <slts@free.fr>
78c2ecf20Sopenharmony_ci */
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci#ifndef _ISLPCI_DEV_H
108c2ecf20Sopenharmony_ci#define _ISLPCI_DEV_H
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#include <linux/irqreturn.h>
138c2ecf20Sopenharmony_ci#include <linux/netdevice.h>
148c2ecf20Sopenharmony_ci#include <linux/wireless.h>
158c2ecf20Sopenharmony_ci#include <net/iw_handler.h>
168c2ecf20Sopenharmony_ci#include <linux/list.h>
178c2ecf20Sopenharmony_ci#include <linux/mutex.h>
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_ci#include "isl_38xx.h"
208c2ecf20Sopenharmony_ci#include "isl_oid.h"
218c2ecf20Sopenharmony_ci#include "islpci_mgt.h"
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci/* some states might not be superflous and may be removed when
248c2ecf20Sopenharmony_ci   design is finalized (hvr) */
258c2ecf20Sopenharmony_citypedef enum {
268c2ecf20Sopenharmony_ci	PRV_STATE_OFF = 0,	/* this means hw_unavailable is != 0 */
278c2ecf20Sopenharmony_ci	PRV_STATE_PREBOOT,	/* we are in a pre-boot state (empty RAM) */
288c2ecf20Sopenharmony_ci	PRV_STATE_BOOT,		/* boot state (fw upload, run fw) */
298c2ecf20Sopenharmony_ci	PRV_STATE_POSTBOOT,	/* after boot state, need reset now */
308c2ecf20Sopenharmony_ci	PRV_STATE_PREINIT,	/* pre-init state */
318c2ecf20Sopenharmony_ci	PRV_STATE_INIT,		/* init state (restore MIB backup to device) */
328c2ecf20Sopenharmony_ci	PRV_STATE_READY,	/* driver&device are in operational state */
338c2ecf20Sopenharmony_ci	PRV_STATE_SLEEP		/* device in sleep mode */
348c2ecf20Sopenharmony_ci} islpci_state_t;
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci/* ACL using MAC address */
378c2ecf20Sopenharmony_cistruct mac_entry {
388c2ecf20Sopenharmony_ci   struct list_head _list;
398c2ecf20Sopenharmony_ci   char addr[ETH_ALEN];
408c2ecf20Sopenharmony_ci};
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_cistruct islpci_acl {
438c2ecf20Sopenharmony_ci   enum { MAC_POLICY_OPEN=0, MAC_POLICY_ACCEPT=1, MAC_POLICY_REJECT=2 } policy;
448c2ecf20Sopenharmony_ci   struct list_head mac_list;  /* a list of mac_entry */
458c2ecf20Sopenharmony_ci   int size;   /* size of queue */
468c2ecf20Sopenharmony_ci   struct mutex lock;   /* accessed in ioctls and trap_work */
478c2ecf20Sopenharmony_ci};
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_cistruct islpci_membuf {
508c2ecf20Sopenharmony_ci	int size;                   /* size of memory */
518c2ecf20Sopenharmony_ci	void *mem;                  /* address of memory as seen by CPU */
528c2ecf20Sopenharmony_ci	dma_addr_t pci_addr;        /* address of memory as seen by device */
538c2ecf20Sopenharmony_ci};
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci#define MAX_BSS_WPA_IE_COUNT 64
568c2ecf20Sopenharmony_ci#define MAX_WPA_IE_LEN 64
578c2ecf20Sopenharmony_cistruct islpci_bss_wpa_ie {
588c2ecf20Sopenharmony_ci	struct list_head list;
598c2ecf20Sopenharmony_ci	unsigned long last_update;
608c2ecf20Sopenharmony_ci	u8 bssid[ETH_ALEN];
618c2ecf20Sopenharmony_ci	u8 wpa_ie[MAX_WPA_IE_LEN];
628c2ecf20Sopenharmony_ci	size_t wpa_ie_len;
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ci};
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_citypedef struct {
678c2ecf20Sopenharmony_ci	spinlock_t slock;	/* generic spinlock; */
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci	u32 priv_oid;
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ci	/* our mib cache */
728c2ecf20Sopenharmony_ci	u32 iw_mode;
738c2ecf20Sopenharmony_ci        struct rw_semaphore mib_sem;
748c2ecf20Sopenharmony_ci	void **mib;
758c2ecf20Sopenharmony_ci	char nickname[IW_ESSID_MAX_SIZE+1];
768c2ecf20Sopenharmony_ci
778c2ecf20Sopenharmony_ci	/* Take care of the wireless stats */
788c2ecf20Sopenharmony_ci	struct work_struct stats_work;
798c2ecf20Sopenharmony_ci	struct mutex stats_lock;
808c2ecf20Sopenharmony_ci	/* remember when we last updated the stats */
818c2ecf20Sopenharmony_ci	unsigned long stats_timestamp;
828c2ecf20Sopenharmony_ci	/* The first is accessed under semaphore locking.
838c2ecf20Sopenharmony_ci	 * The second is the clean one we return to iwconfig.
848c2ecf20Sopenharmony_ci	 */
858c2ecf20Sopenharmony_ci	struct iw_statistics local_iwstatistics;
868c2ecf20Sopenharmony_ci	struct iw_statistics iwstatistics;
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_ci	struct iw_spy_data spy_data; /* iwspy support */
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_ci	struct iw_public_data wireless_data;
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ci	int monitor_type; /* ARPHRD_IEEE80211 or ARPHRD_IEEE80211_PRISM */
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_ci	struct islpci_acl acl;
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_ci	/* PCI bus allocation & configuration members */
978c2ecf20Sopenharmony_ci	struct pci_dev *pdev;	/* PCI structure information */
988c2ecf20Sopenharmony_ci	char firmware[33];
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_ci	void __iomem *device_base;	/* ioremapped device base address */
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ci	/* consistent DMA region */
1038c2ecf20Sopenharmony_ci	void *driver_mem_address;	/* base DMA address */
1048c2ecf20Sopenharmony_ci	dma_addr_t device_host_address;	/* base DMA address (bus address) */
1058c2ecf20Sopenharmony_ci	dma_addr_t device_psm_buffer;	/* host memory for PSM buffering (bus address) */
1068c2ecf20Sopenharmony_ci
1078c2ecf20Sopenharmony_ci	/* our network_device structure  */
1088c2ecf20Sopenharmony_ci	struct net_device *ndev;
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ci	/* device queue interface members */
1118c2ecf20Sopenharmony_ci	struct isl38xx_cb *control_block;	/* device control block
1128c2ecf20Sopenharmony_ci							   (== driver_mem_address!) */
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_ci	/* Each queue has three indexes:
1158c2ecf20Sopenharmony_ci	 *   free/index_mgmt/data_rx/tx (called index, see below),
1168c2ecf20Sopenharmony_ci	 *   driver_curr_frag, and device_curr_frag (in the control block)
1178c2ecf20Sopenharmony_ci	 * All indexes are ever-increasing, but interpreted modulo the
1188c2ecf20Sopenharmony_ci	 * device queue size when used.
1198c2ecf20Sopenharmony_ci	 *   index <= device_curr_frag <= driver_curr_frag  at all times
1208c2ecf20Sopenharmony_ci	 * For rx queues, [index, device_curr_frag) contains fragments
1218c2ecf20Sopenharmony_ci	 * that the interrupt processing needs to handle (owned by driver).
1228c2ecf20Sopenharmony_ci	 * [device_curr_frag, driver_curr_frag) is the free space in the
1238c2ecf20Sopenharmony_ci	 * rx queue, waiting for data (owned by device).  The driver
1248c2ecf20Sopenharmony_ci	 * increments driver_curr_frag to indicate to the device that more
1258c2ecf20Sopenharmony_ci	 * buffers are available.
1268c2ecf20Sopenharmony_ci	 * If device_curr_frag == driver_curr_frag, no more rx buffers are
1278c2ecf20Sopenharmony_ci	 * available, and the rx DMA engine of the device is halted.
1288c2ecf20Sopenharmony_ci	 * For tx queues, [index, device_curr_frag) contains fragments
1298c2ecf20Sopenharmony_ci	 * where tx is done; they need to be freed (owned by driver).
1308c2ecf20Sopenharmony_ci	 * [device_curr_frag, driver_curr_frag) contains the frames
1318c2ecf20Sopenharmony_ci	 * that are being transferred (owned by device).  The driver
1328c2ecf20Sopenharmony_ci	 * increments driver_curr_frag to indicate that more tx work
1338c2ecf20Sopenharmony_ci	 * needs to be done.
1348c2ecf20Sopenharmony_ci	 */
1358c2ecf20Sopenharmony_ci	u32 index_mgmt_rx;              /* real index mgmt rx queue */
1368c2ecf20Sopenharmony_ci	u32 index_mgmt_tx;              /* read index mgmt tx queue */
1378c2ecf20Sopenharmony_ci	u32 free_data_rx;	/* free pointer data rx queue */
1388c2ecf20Sopenharmony_ci	u32 free_data_tx;	/* free pointer data tx queue */
1398c2ecf20Sopenharmony_ci	u32 data_low_tx_full;	/* full detected flag */
1408c2ecf20Sopenharmony_ci
1418c2ecf20Sopenharmony_ci	/* frame memory buffers for the device queues */
1428c2ecf20Sopenharmony_ci	struct islpci_membuf mgmt_tx[ISL38XX_CB_MGMT_QSIZE];
1438c2ecf20Sopenharmony_ci	struct islpci_membuf mgmt_rx[ISL38XX_CB_MGMT_QSIZE];
1448c2ecf20Sopenharmony_ci	struct sk_buff *data_low_tx[ISL38XX_CB_TX_QSIZE];
1458c2ecf20Sopenharmony_ci	struct sk_buff *data_low_rx[ISL38XX_CB_RX_QSIZE];
1468c2ecf20Sopenharmony_ci	dma_addr_t pci_map_tx_address[ISL38XX_CB_TX_QSIZE];
1478c2ecf20Sopenharmony_ci	dma_addr_t pci_map_rx_address[ISL38XX_CB_RX_QSIZE];
1488c2ecf20Sopenharmony_ci
1498c2ecf20Sopenharmony_ci	/* wait for a reset interrupt */
1508c2ecf20Sopenharmony_ci	wait_queue_head_t reset_done;
1518c2ecf20Sopenharmony_ci
1528c2ecf20Sopenharmony_ci	/* used by islpci_mgt_transaction */
1538c2ecf20Sopenharmony_ci	struct mutex mgmt_lock; /* serialize access to mailbox and wqueue */
1548c2ecf20Sopenharmony_ci	struct islpci_mgmtframe *mgmt_received;	  /* mbox for incoming frame */
1558c2ecf20Sopenharmony_ci	wait_queue_head_t mgmt_wqueue;            /* waitqueue for mbox */
1568c2ecf20Sopenharmony_ci
1578c2ecf20Sopenharmony_ci	/* state machine */
1588c2ecf20Sopenharmony_ci	islpci_state_t state;
1598c2ecf20Sopenharmony_ci	int state_off;		/* enumeration of off-state, if 0 then
1608c2ecf20Sopenharmony_ci				 * we're not in any off-state */
1618c2ecf20Sopenharmony_ci
1628c2ecf20Sopenharmony_ci	/* WPA stuff */
1638c2ecf20Sopenharmony_ci	int wpa; /* WPA mode enabled */
1648c2ecf20Sopenharmony_ci	struct list_head bss_wpa_list;
1658c2ecf20Sopenharmony_ci	int num_bss_wpa;
1668c2ecf20Sopenharmony_ci	struct mutex wpa_lock;
1678c2ecf20Sopenharmony_ci	u8 wpa_ie[MAX_WPA_IE_LEN];
1688c2ecf20Sopenharmony_ci	size_t wpa_ie_len;
1698c2ecf20Sopenharmony_ci
1708c2ecf20Sopenharmony_ci	struct work_struct reset_task;
1718c2ecf20Sopenharmony_ci	int reset_task_pending;
1728c2ecf20Sopenharmony_ci} islpci_private;
1738c2ecf20Sopenharmony_ci
1748c2ecf20Sopenharmony_cistatic inline islpci_state_t
1758c2ecf20Sopenharmony_ciislpci_get_state(islpci_private *priv)
1768c2ecf20Sopenharmony_ci{
1778c2ecf20Sopenharmony_ci	/* lock */
1788c2ecf20Sopenharmony_ci	return priv->state;
1798c2ecf20Sopenharmony_ci	/* unlock */
1808c2ecf20Sopenharmony_ci}
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_ciislpci_state_t islpci_set_state(islpci_private *priv, islpci_state_t new_state);
1838c2ecf20Sopenharmony_ci
1848c2ecf20Sopenharmony_ci#define ISLPCI_TX_TIMEOUT               (2*HZ)
1858c2ecf20Sopenharmony_ci
1868c2ecf20Sopenharmony_ciirqreturn_t islpci_interrupt(int, void *);
1878c2ecf20Sopenharmony_ci
1888c2ecf20Sopenharmony_ciint prism54_post_setup(islpci_private *, int);
1898c2ecf20Sopenharmony_ciint islpci_reset(islpci_private *, int);
1908c2ecf20Sopenharmony_ci
1918c2ecf20Sopenharmony_cistatic inline void
1928c2ecf20Sopenharmony_ciislpci_trigger(islpci_private *priv)
1938c2ecf20Sopenharmony_ci{
1948c2ecf20Sopenharmony_ci	isl38xx_trigger_device(islpci_get_state(priv) == PRV_STATE_SLEEP,
1958c2ecf20Sopenharmony_ci			       priv->device_base);
1968c2ecf20Sopenharmony_ci}
1978c2ecf20Sopenharmony_ci
1988c2ecf20Sopenharmony_ciint islpci_free_memory(islpci_private *);
1998c2ecf20Sopenharmony_cistruct net_device *islpci_setup(struct pci_dev *);
2008c2ecf20Sopenharmony_ci
2018c2ecf20Sopenharmony_ci#define DRV_NAME	"prism54"
2028c2ecf20Sopenharmony_ci#define DRV_VERSION	"1.2"
2038c2ecf20Sopenharmony_ci
2048c2ecf20Sopenharmony_ci#endif				/* _ISLPCI_DEV_H */
205