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