162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci#ifndef HOSTAP_WLAN_H
362306a36Sopenharmony_ci#define HOSTAP_WLAN_H
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#include <linux/interrupt.h>
662306a36Sopenharmony_ci#include <linux/wireless.h>
762306a36Sopenharmony_ci#include <linux/netdevice.h>
862306a36Sopenharmony_ci#include <linux/etherdevice.h>
962306a36Sopenharmony_ci#include <linux/mutex.h>
1062306a36Sopenharmony_ci#include <linux/refcount.h>
1162306a36Sopenharmony_ci#include <net/iw_handler.h>
1262306a36Sopenharmony_ci#include <net/ieee80211_radiotap.h>
1362306a36Sopenharmony_ci#include <net/lib80211.h>
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#include "hostap_config.h"
1662306a36Sopenharmony_ci#include "hostap_common.h"
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci#define MAX_PARM_DEVICES 8
1962306a36Sopenharmony_ci#define PARM_MIN_MAX "1-" __MODULE_STRING(MAX_PARM_DEVICES)
2062306a36Sopenharmony_ci#define DEF_INTS -1, -1, -1, -1, -1, -1, -1
2162306a36Sopenharmony_ci#define GET_INT_PARM(var,idx) var[var[idx] < 0 ? 0 : idx]
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci/* Specific skb->protocol value that indicates that the packet already contains
2562306a36Sopenharmony_ci * txdesc header.
2662306a36Sopenharmony_ci * FIX: This might need own value that would be allocated especially for Prism2
2762306a36Sopenharmony_ci * txdesc; ETH_P_CONTROL is commented as "Card specific control frames".
2862306a36Sopenharmony_ci * However, these skb's should have only minimal path in the kernel side since
2962306a36Sopenharmony_ci * prism2_send_mgmt() sends these with dev_queue_xmit() to prism2_tx(). */
3062306a36Sopenharmony_ci#define ETH_P_HOSTAP ETH_P_CONTROL
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci/* ARPHRD_IEEE80211_PRISM uses a bloated version of Prism2 RX frame header
3362306a36Sopenharmony_ci * (from linux-wlan-ng) */
3462306a36Sopenharmony_cistruct linux_wlan_ng_val {
3562306a36Sopenharmony_ci	u32 did;
3662306a36Sopenharmony_ci	u16 status, len;
3762306a36Sopenharmony_ci	u32 data;
3862306a36Sopenharmony_ci} __packed;
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_cistruct linux_wlan_ng_prism_hdr {
4162306a36Sopenharmony_ci	u32 msgcode, msglen;
4262306a36Sopenharmony_ci	char devname[16];
4362306a36Sopenharmony_ci	struct linux_wlan_ng_val hosttime, mactime, channel, rssi, sq, signal,
4462306a36Sopenharmony_ci		noise, rate, istx, frmlen;
4562306a36Sopenharmony_ci} __packed;
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_cistruct linux_wlan_ng_cap_hdr {
4862306a36Sopenharmony_ci	__be32 version;
4962306a36Sopenharmony_ci	__be32 length;
5062306a36Sopenharmony_ci	__be64 mactime;
5162306a36Sopenharmony_ci	__be64 hosttime;
5262306a36Sopenharmony_ci	__be32 phytype;
5362306a36Sopenharmony_ci	__be32 channel;
5462306a36Sopenharmony_ci	__be32 datarate;
5562306a36Sopenharmony_ci	__be32 antenna;
5662306a36Sopenharmony_ci	__be32 priority;
5762306a36Sopenharmony_ci	__be32 ssi_type;
5862306a36Sopenharmony_ci	__be32 ssi_signal;
5962306a36Sopenharmony_ci	__be32 ssi_noise;
6062306a36Sopenharmony_ci	__be32 preamble;
6162306a36Sopenharmony_ci	__be32 encoding;
6262306a36Sopenharmony_ci} __packed;
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_cistruct hostap_radiotap_rx {
6562306a36Sopenharmony_ci	struct ieee80211_radiotap_header hdr;
6662306a36Sopenharmony_ci	__le64 tsft;
6762306a36Sopenharmony_ci	u8 rate;
6862306a36Sopenharmony_ci	u8 padding;
6962306a36Sopenharmony_ci	__le16 chan_freq;
7062306a36Sopenharmony_ci	__le16 chan_flags;
7162306a36Sopenharmony_ci	s8 dbm_antsignal;
7262306a36Sopenharmony_ci	s8 dbm_antnoise;
7362306a36Sopenharmony_ci} __packed;
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci#define LWNG_CAP_DID_BASE   (4 | (1 << 6)) /* section 4, group 1 */
7662306a36Sopenharmony_ci#define LWNG_CAPHDR_VERSION 0x80211001
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_cistruct hfa384x_rx_frame {
7962306a36Sopenharmony_ci	/* HFA384X RX frame descriptor */
8062306a36Sopenharmony_ci	__le16 status; /* HFA384X_RX_STATUS_ flags */
8162306a36Sopenharmony_ci	__le32 time; /* timestamp, 1 microsecond resolution */
8262306a36Sopenharmony_ci	u8 silence; /* 27 .. 154; seems to be 0 */
8362306a36Sopenharmony_ci	u8 signal; /* 27 .. 154 */
8462306a36Sopenharmony_ci	u8 rate; /* 10, 20, 55, or 110 */
8562306a36Sopenharmony_ci	u8 rxflow;
8662306a36Sopenharmony_ci	__le32 reserved;
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci	/* 802.11 */
8962306a36Sopenharmony_ci	__le16 frame_control;
9062306a36Sopenharmony_ci	__le16 duration_id;
9162306a36Sopenharmony_ci	u8 addr1[ETH_ALEN];
9262306a36Sopenharmony_ci	u8 addr2[ETH_ALEN];
9362306a36Sopenharmony_ci	u8 addr3[ETH_ALEN];
9462306a36Sopenharmony_ci	__le16 seq_ctrl;
9562306a36Sopenharmony_ci	u8 addr4[ETH_ALEN];
9662306a36Sopenharmony_ci	__le16 data_len;
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ci	/* 802.3 */
9962306a36Sopenharmony_ci	u8 dst_addr[ETH_ALEN];
10062306a36Sopenharmony_ci	u8 src_addr[ETH_ALEN];
10162306a36Sopenharmony_ci	__be16 len;
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci	/* followed by frame data; max 2304 bytes */
10462306a36Sopenharmony_ci} __packed;
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_cistruct hfa384x_tx_frame {
10862306a36Sopenharmony_ci	/* HFA384X TX frame descriptor */
10962306a36Sopenharmony_ci	__le16 status; /* HFA384X_TX_STATUS_ flags */
11062306a36Sopenharmony_ci	__le16 reserved1;
11162306a36Sopenharmony_ci	__le16 reserved2;
11262306a36Sopenharmony_ci	__le32 sw_support;
11362306a36Sopenharmony_ci	u8 retry_count; /* not yet implemented */
11462306a36Sopenharmony_ci	u8 tx_rate; /* Host AP only; 0 = firmware, or 10, 20, 55, 110 */
11562306a36Sopenharmony_ci	__le16 tx_control; /* HFA384X_TX_CTRL_ flags */
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ci	/* 802.11 */
11862306a36Sopenharmony_ci	struct_group(header,
11962306a36Sopenharmony_ci		__le16 frame_control; /* parts not used */
12062306a36Sopenharmony_ci		__le16 duration_id;
12162306a36Sopenharmony_ci		u8 addr1[ETH_ALEN];
12262306a36Sopenharmony_ci		u8 addr2[ETH_ALEN]; /* filled by firmware */
12362306a36Sopenharmony_ci		u8 addr3[ETH_ALEN];
12462306a36Sopenharmony_ci		__le16 seq_ctrl; /* filled by firmware */
12562306a36Sopenharmony_ci	);
12662306a36Sopenharmony_ci	u8 addr4[ETH_ALEN];
12762306a36Sopenharmony_ci	__le16 data_len;
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci	/* 802.3 */
13062306a36Sopenharmony_ci	u8 dst_addr[ETH_ALEN];
13162306a36Sopenharmony_ci	u8 src_addr[ETH_ALEN];
13262306a36Sopenharmony_ci	__be16 len;
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_ci	/* followed by frame data; max 2304 bytes */
13562306a36Sopenharmony_ci} __packed;
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_cistruct hfa384x_rid_hdr
13962306a36Sopenharmony_ci{
14062306a36Sopenharmony_ci	__le16 len;
14162306a36Sopenharmony_ci	__le16 rid;
14262306a36Sopenharmony_ci} __packed;
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci
14562306a36Sopenharmony_ci/* Macro for converting signal levels (range 27 .. 154) to wireless ext
14662306a36Sopenharmony_ci * dBm value with some accuracy */
14762306a36Sopenharmony_ci#define HFA384X_LEVEL_TO_dBm(v) 0x100 + (v) * 100 / 255 - 100
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_ci#define HFA384X_LEVEL_TO_dBm_sign(v) (v) * 100 / 255 - 100
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_cistruct hfa384x_scan_request {
15262306a36Sopenharmony_ci	__le16 channel_list;
15362306a36Sopenharmony_ci	__le16 txrate; /* HFA384X_RATES_* */
15462306a36Sopenharmony_ci} __packed;
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_cistruct hfa384x_hostscan_request {
15762306a36Sopenharmony_ci	__le16 channel_list;
15862306a36Sopenharmony_ci	__le16 txrate;
15962306a36Sopenharmony_ci	__le16 target_ssid_len;
16062306a36Sopenharmony_ci	u8 target_ssid[32];
16162306a36Sopenharmony_ci} __packed;
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_cistruct hfa384x_join_request {
16462306a36Sopenharmony_ci	u8 bssid[ETH_ALEN];
16562306a36Sopenharmony_ci	__le16 channel;
16662306a36Sopenharmony_ci} __packed;
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_cistruct hfa384x_info_frame {
16962306a36Sopenharmony_ci	__le16 len;
17062306a36Sopenharmony_ci	__le16 type;
17162306a36Sopenharmony_ci} __packed;
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_cistruct hfa384x_comm_tallies {
17462306a36Sopenharmony_ci	__le16 tx_unicast_frames;
17562306a36Sopenharmony_ci	__le16 tx_multicast_frames;
17662306a36Sopenharmony_ci	__le16 tx_fragments;
17762306a36Sopenharmony_ci	__le16 tx_unicast_octets;
17862306a36Sopenharmony_ci	__le16 tx_multicast_octets;
17962306a36Sopenharmony_ci	__le16 tx_deferred_transmissions;
18062306a36Sopenharmony_ci	__le16 tx_single_retry_frames;
18162306a36Sopenharmony_ci	__le16 tx_multiple_retry_frames;
18262306a36Sopenharmony_ci	__le16 tx_retry_limit_exceeded;
18362306a36Sopenharmony_ci	__le16 tx_discards;
18462306a36Sopenharmony_ci	__le16 rx_unicast_frames;
18562306a36Sopenharmony_ci	__le16 rx_multicast_frames;
18662306a36Sopenharmony_ci	__le16 rx_fragments;
18762306a36Sopenharmony_ci	__le16 rx_unicast_octets;
18862306a36Sopenharmony_ci	__le16 rx_multicast_octets;
18962306a36Sopenharmony_ci	__le16 rx_fcs_errors;
19062306a36Sopenharmony_ci	__le16 rx_discards_no_buffer;
19162306a36Sopenharmony_ci	__le16 tx_discards_wrong_sa;
19262306a36Sopenharmony_ci	__le16 rx_discards_wep_undecryptable;
19362306a36Sopenharmony_ci	__le16 rx_message_in_msg_fragments;
19462306a36Sopenharmony_ci	__le16 rx_message_in_bad_msg_fragments;
19562306a36Sopenharmony_ci} __packed;
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_cistruct hfa384x_comm_tallies32 {
19862306a36Sopenharmony_ci	__le32 tx_unicast_frames;
19962306a36Sopenharmony_ci	__le32 tx_multicast_frames;
20062306a36Sopenharmony_ci	__le32 tx_fragments;
20162306a36Sopenharmony_ci	__le32 tx_unicast_octets;
20262306a36Sopenharmony_ci	__le32 tx_multicast_octets;
20362306a36Sopenharmony_ci	__le32 tx_deferred_transmissions;
20462306a36Sopenharmony_ci	__le32 tx_single_retry_frames;
20562306a36Sopenharmony_ci	__le32 tx_multiple_retry_frames;
20662306a36Sopenharmony_ci	__le32 tx_retry_limit_exceeded;
20762306a36Sopenharmony_ci	__le32 tx_discards;
20862306a36Sopenharmony_ci	__le32 rx_unicast_frames;
20962306a36Sopenharmony_ci	__le32 rx_multicast_frames;
21062306a36Sopenharmony_ci	__le32 rx_fragments;
21162306a36Sopenharmony_ci	__le32 rx_unicast_octets;
21262306a36Sopenharmony_ci	__le32 rx_multicast_octets;
21362306a36Sopenharmony_ci	__le32 rx_fcs_errors;
21462306a36Sopenharmony_ci	__le32 rx_discards_no_buffer;
21562306a36Sopenharmony_ci	__le32 tx_discards_wrong_sa;
21662306a36Sopenharmony_ci	__le32 rx_discards_wep_undecryptable;
21762306a36Sopenharmony_ci	__le32 rx_message_in_msg_fragments;
21862306a36Sopenharmony_ci	__le32 rx_message_in_bad_msg_fragments;
21962306a36Sopenharmony_ci} __packed;
22062306a36Sopenharmony_ci
22162306a36Sopenharmony_cistruct hfa384x_scan_result_hdr {
22262306a36Sopenharmony_ci	__le16 reserved;
22362306a36Sopenharmony_ci	__le16 scan_reason;
22462306a36Sopenharmony_ci#define HFA384X_SCAN_IN_PROGRESS 0 /* no results available yet */
22562306a36Sopenharmony_ci#define HFA384X_SCAN_HOST_INITIATED 1
22662306a36Sopenharmony_ci#define HFA384X_SCAN_FIRMWARE_INITIATED 2
22762306a36Sopenharmony_ci#define HFA384X_SCAN_INQUIRY_FROM_HOST 3
22862306a36Sopenharmony_ci} __packed;
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_ci#define HFA384X_SCAN_MAX_RESULTS 32
23162306a36Sopenharmony_ci
23262306a36Sopenharmony_cistruct hfa384x_scan_result {
23362306a36Sopenharmony_ci	__le16 chid;
23462306a36Sopenharmony_ci	__le16 anl;
23562306a36Sopenharmony_ci	__le16 sl;
23662306a36Sopenharmony_ci	u8 bssid[ETH_ALEN];
23762306a36Sopenharmony_ci	__le16 beacon_interval;
23862306a36Sopenharmony_ci	__le16 capability;
23962306a36Sopenharmony_ci	__le16 ssid_len;
24062306a36Sopenharmony_ci	u8 ssid[32];
24162306a36Sopenharmony_ci	u8 sup_rates[10];
24262306a36Sopenharmony_ci	__le16 rate;
24362306a36Sopenharmony_ci} __packed;
24462306a36Sopenharmony_ci
24562306a36Sopenharmony_cistruct hfa384x_hostscan_result {
24662306a36Sopenharmony_ci	__le16 chid;
24762306a36Sopenharmony_ci	__le16 anl;
24862306a36Sopenharmony_ci	__le16 sl;
24962306a36Sopenharmony_ci	u8 bssid[ETH_ALEN];
25062306a36Sopenharmony_ci	__le16 beacon_interval;
25162306a36Sopenharmony_ci	__le16 capability;
25262306a36Sopenharmony_ci	__le16 ssid_len;
25362306a36Sopenharmony_ci	u8 ssid[32];
25462306a36Sopenharmony_ci	u8 sup_rates[10];
25562306a36Sopenharmony_ci	__le16 rate;
25662306a36Sopenharmony_ci	__le16 atim;
25762306a36Sopenharmony_ci} __packed;
25862306a36Sopenharmony_ci
25962306a36Sopenharmony_cistruct comm_tallies_sums {
26062306a36Sopenharmony_ci	unsigned int tx_unicast_frames;
26162306a36Sopenharmony_ci	unsigned int tx_multicast_frames;
26262306a36Sopenharmony_ci	unsigned int tx_fragments;
26362306a36Sopenharmony_ci	unsigned int tx_unicast_octets;
26462306a36Sopenharmony_ci	unsigned int tx_multicast_octets;
26562306a36Sopenharmony_ci	unsigned int tx_deferred_transmissions;
26662306a36Sopenharmony_ci	unsigned int tx_single_retry_frames;
26762306a36Sopenharmony_ci	unsigned int tx_multiple_retry_frames;
26862306a36Sopenharmony_ci	unsigned int tx_retry_limit_exceeded;
26962306a36Sopenharmony_ci	unsigned int tx_discards;
27062306a36Sopenharmony_ci	unsigned int rx_unicast_frames;
27162306a36Sopenharmony_ci	unsigned int rx_multicast_frames;
27262306a36Sopenharmony_ci	unsigned int rx_fragments;
27362306a36Sopenharmony_ci	unsigned int rx_unicast_octets;
27462306a36Sopenharmony_ci	unsigned int rx_multicast_octets;
27562306a36Sopenharmony_ci	unsigned int rx_fcs_errors;
27662306a36Sopenharmony_ci	unsigned int rx_discards_no_buffer;
27762306a36Sopenharmony_ci	unsigned int tx_discards_wrong_sa;
27862306a36Sopenharmony_ci	unsigned int rx_discards_wep_undecryptable;
27962306a36Sopenharmony_ci	unsigned int rx_message_in_msg_fragments;
28062306a36Sopenharmony_ci	unsigned int rx_message_in_bad_msg_fragments;
28162306a36Sopenharmony_ci};
28262306a36Sopenharmony_ci
28362306a36Sopenharmony_ci
28462306a36Sopenharmony_cistruct hfa384x_regs {
28562306a36Sopenharmony_ci	u16 cmd;
28662306a36Sopenharmony_ci	u16 evstat;
28762306a36Sopenharmony_ci	u16 offset0;
28862306a36Sopenharmony_ci	u16 offset1;
28962306a36Sopenharmony_ci	u16 swsupport0;
29062306a36Sopenharmony_ci};
29162306a36Sopenharmony_ci
29262306a36Sopenharmony_ci
29362306a36Sopenharmony_ci#if defined(PRISM2_PCCARD) || defined(PRISM2_PLX)
29462306a36Sopenharmony_ci/* I/O ports for HFA384X Controller access */
29562306a36Sopenharmony_ci#define HFA384X_CMD_OFF 0x00
29662306a36Sopenharmony_ci#define HFA384X_PARAM0_OFF 0x02
29762306a36Sopenharmony_ci#define HFA384X_PARAM1_OFF 0x04
29862306a36Sopenharmony_ci#define HFA384X_PARAM2_OFF 0x06
29962306a36Sopenharmony_ci#define HFA384X_STATUS_OFF 0x08
30062306a36Sopenharmony_ci#define HFA384X_RESP0_OFF 0x0A
30162306a36Sopenharmony_ci#define HFA384X_RESP1_OFF 0x0C
30262306a36Sopenharmony_ci#define HFA384X_RESP2_OFF 0x0E
30362306a36Sopenharmony_ci#define HFA384X_INFOFID_OFF 0x10
30462306a36Sopenharmony_ci#define HFA384X_CONTROL_OFF 0x14
30562306a36Sopenharmony_ci#define HFA384X_SELECT0_OFF 0x18
30662306a36Sopenharmony_ci#define HFA384X_SELECT1_OFF 0x1A
30762306a36Sopenharmony_ci#define HFA384X_OFFSET0_OFF 0x1C
30862306a36Sopenharmony_ci#define HFA384X_OFFSET1_OFF 0x1E
30962306a36Sopenharmony_ci#define HFA384X_RXFID_OFF 0x20
31062306a36Sopenharmony_ci#define HFA384X_ALLOCFID_OFF 0x22
31162306a36Sopenharmony_ci#define HFA384X_TXCOMPLFID_OFF 0x24
31262306a36Sopenharmony_ci#define HFA384X_SWSUPPORT0_OFF 0x28
31362306a36Sopenharmony_ci#define HFA384X_SWSUPPORT1_OFF 0x2A
31462306a36Sopenharmony_ci#define HFA384X_SWSUPPORT2_OFF 0x2C
31562306a36Sopenharmony_ci#define HFA384X_EVSTAT_OFF 0x30
31662306a36Sopenharmony_ci#define HFA384X_INTEN_OFF 0x32
31762306a36Sopenharmony_ci#define HFA384X_EVACK_OFF 0x34
31862306a36Sopenharmony_ci#define HFA384X_DATA0_OFF 0x36
31962306a36Sopenharmony_ci#define HFA384X_DATA1_OFF 0x38
32062306a36Sopenharmony_ci#define HFA384X_AUXPAGE_OFF 0x3A
32162306a36Sopenharmony_ci#define HFA384X_AUXOFFSET_OFF 0x3C
32262306a36Sopenharmony_ci#define HFA384X_AUXDATA_OFF 0x3E
32362306a36Sopenharmony_ci#endif /* PRISM2_PCCARD || PRISM2_PLX */
32462306a36Sopenharmony_ci
32562306a36Sopenharmony_ci#ifdef PRISM2_PCI
32662306a36Sopenharmony_ci/* Memory addresses for ISL3874 controller access */
32762306a36Sopenharmony_ci#define HFA384X_CMD_OFF 0x00
32862306a36Sopenharmony_ci#define HFA384X_PARAM0_OFF 0x04
32962306a36Sopenharmony_ci#define HFA384X_PARAM1_OFF 0x08
33062306a36Sopenharmony_ci#define HFA384X_PARAM2_OFF 0x0C
33162306a36Sopenharmony_ci#define HFA384X_STATUS_OFF 0x10
33262306a36Sopenharmony_ci#define HFA384X_RESP0_OFF 0x14
33362306a36Sopenharmony_ci#define HFA384X_RESP1_OFF 0x18
33462306a36Sopenharmony_ci#define HFA384X_RESP2_OFF 0x1C
33562306a36Sopenharmony_ci#define HFA384X_INFOFID_OFF 0x20
33662306a36Sopenharmony_ci#define HFA384X_CONTROL_OFF 0x28
33762306a36Sopenharmony_ci#define HFA384X_SELECT0_OFF 0x30
33862306a36Sopenharmony_ci#define HFA384X_SELECT1_OFF 0x34
33962306a36Sopenharmony_ci#define HFA384X_OFFSET0_OFF 0x38
34062306a36Sopenharmony_ci#define HFA384X_OFFSET1_OFF 0x3C
34162306a36Sopenharmony_ci#define HFA384X_RXFID_OFF 0x40
34262306a36Sopenharmony_ci#define HFA384X_ALLOCFID_OFF 0x44
34362306a36Sopenharmony_ci#define HFA384X_TXCOMPLFID_OFF 0x48
34462306a36Sopenharmony_ci#define HFA384X_PCICOR_OFF 0x4C
34562306a36Sopenharmony_ci#define HFA384X_SWSUPPORT0_OFF 0x50
34662306a36Sopenharmony_ci#define HFA384X_SWSUPPORT1_OFF 0x54
34762306a36Sopenharmony_ci#define HFA384X_SWSUPPORT2_OFF 0x58
34862306a36Sopenharmony_ci#define HFA384X_PCIHCR_OFF 0x5C
34962306a36Sopenharmony_ci#define HFA384X_EVSTAT_OFF 0x60
35062306a36Sopenharmony_ci#define HFA384X_INTEN_OFF 0x64
35162306a36Sopenharmony_ci#define HFA384X_EVACK_OFF 0x68
35262306a36Sopenharmony_ci#define HFA384X_DATA0_OFF 0x6C
35362306a36Sopenharmony_ci#define HFA384X_DATA1_OFF 0x70
35462306a36Sopenharmony_ci#define HFA384X_AUXPAGE_OFF 0x74
35562306a36Sopenharmony_ci#define HFA384X_AUXOFFSET_OFF 0x78
35662306a36Sopenharmony_ci#define HFA384X_AUXDATA_OFF 0x7C
35762306a36Sopenharmony_ci#define HFA384X_PCI_M0_ADDRH_OFF 0x80
35862306a36Sopenharmony_ci#define HFA384X_PCI_M0_ADDRL_OFF 0x84
35962306a36Sopenharmony_ci#define HFA384X_PCI_M0_LEN_OFF 0x88
36062306a36Sopenharmony_ci#define HFA384X_PCI_M0_CTL_OFF 0x8C
36162306a36Sopenharmony_ci#define HFA384X_PCI_STATUS_OFF 0x98
36262306a36Sopenharmony_ci#define HFA384X_PCI_M1_ADDRH_OFF 0xA0
36362306a36Sopenharmony_ci#define HFA384X_PCI_M1_ADDRL_OFF 0xA4
36462306a36Sopenharmony_ci#define HFA384X_PCI_M1_LEN_OFF 0xA8
36562306a36Sopenharmony_ci#define HFA384X_PCI_M1_CTL_OFF 0xAC
36662306a36Sopenharmony_ci
36762306a36Sopenharmony_ci/* PCI bus master control bits (these are undocumented; based on guessing and
36862306a36Sopenharmony_ci * experimenting..) */
36962306a36Sopenharmony_ci#define HFA384X_PCI_CTL_FROM_BAP (BIT(5) | BIT(1) | BIT(0))
37062306a36Sopenharmony_ci#define HFA384X_PCI_CTL_TO_BAP (BIT(5) | BIT(0))
37162306a36Sopenharmony_ci
37262306a36Sopenharmony_ci#endif /* PRISM2_PCI */
37362306a36Sopenharmony_ci
37462306a36Sopenharmony_ci
37562306a36Sopenharmony_ci/* Command codes for CMD reg. */
37662306a36Sopenharmony_ci#define HFA384X_CMDCODE_INIT 0x00
37762306a36Sopenharmony_ci#define HFA384X_CMDCODE_ENABLE 0x01
37862306a36Sopenharmony_ci#define HFA384X_CMDCODE_DISABLE 0x02
37962306a36Sopenharmony_ci#define HFA384X_CMDCODE_ALLOC 0x0A
38062306a36Sopenharmony_ci#define HFA384X_CMDCODE_TRANSMIT 0x0B
38162306a36Sopenharmony_ci#define HFA384X_CMDCODE_INQUIRE 0x11
38262306a36Sopenharmony_ci#define HFA384X_CMDCODE_ACCESS 0x21
38362306a36Sopenharmony_ci#define HFA384X_CMDCODE_ACCESS_WRITE (0x21 | BIT(8))
38462306a36Sopenharmony_ci#define HFA384X_CMDCODE_DOWNLOAD 0x22
38562306a36Sopenharmony_ci#define HFA384X_CMDCODE_READMIF 0x30
38662306a36Sopenharmony_ci#define HFA384X_CMDCODE_WRITEMIF 0x31
38762306a36Sopenharmony_ci#define HFA384X_CMDCODE_TEST 0x38
38862306a36Sopenharmony_ci
38962306a36Sopenharmony_ci#define HFA384X_CMDCODE_MASK 0x3F
39062306a36Sopenharmony_ci
39162306a36Sopenharmony_ci/* Test mode operations */
39262306a36Sopenharmony_ci#define HFA384X_TEST_CHANGE_CHANNEL 0x08
39362306a36Sopenharmony_ci#define HFA384X_TEST_MONITOR 0x0B
39462306a36Sopenharmony_ci#define HFA384X_TEST_STOP 0x0F
39562306a36Sopenharmony_ci#define HFA384X_TEST_CFG_BITS 0x15
39662306a36Sopenharmony_ci#define HFA384X_TEST_CFG_BIT_ALC BIT(3)
39762306a36Sopenharmony_ci
39862306a36Sopenharmony_ci#define HFA384X_CMD_BUSY BIT(15)
39962306a36Sopenharmony_ci
40062306a36Sopenharmony_ci#define HFA384X_CMD_TX_RECLAIM BIT(8)
40162306a36Sopenharmony_ci
40262306a36Sopenharmony_ci#define HFA384X_OFFSET_ERR BIT(14)
40362306a36Sopenharmony_ci#define HFA384X_OFFSET_BUSY BIT(15)
40462306a36Sopenharmony_ci
40562306a36Sopenharmony_ci
40662306a36Sopenharmony_ci/* ProgMode for download command */
40762306a36Sopenharmony_ci#define HFA384X_PROGMODE_DISABLE 0
40862306a36Sopenharmony_ci#define HFA384X_PROGMODE_ENABLE_VOLATILE 1
40962306a36Sopenharmony_ci#define HFA384X_PROGMODE_ENABLE_NON_VOLATILE 2
41062306a36Sopenharmony_ci#define HFA384X_PROGMODE_PROGRAM_NON_VOLATILE 3
41162306a36Sopenharmony_ci
41262306a36Sopenharmony_ci#define HFA384X_AUX_MAGIC0 0xfe01
41362306a36Sopenharmony_ci#define HFA384X_AUX_MAGIC1 0xdc23
41462306a36Sopenharmony_ci#define HFA384X_AUX_MAGIC2 0xba45
41562306a36Sopenharmony_ci
41662306a36Sopenharmony_ci#define HFA384X_AUX_PORT_DISABLED 0
41762306a36Sopenharmony_ci#define HFA384X_AUX_PORT_DISABLE BIT(14)
41862306a36Sopenharmony_ci#define HFA384X_AUX_PORT_ENABLE BIT(15)
41962306a36Sopenharmony_ci#define HFA384X_AUX_PORT_ENABLED (BIT(14) | BIT(15))
42062306a36Sopenharmony_ci#define HFA384X_AUX_PORT_MASK (BIT(14) | BIT(15))
42162306a36Sopenharmony_ci
42262306a36Sopenharmony_ci#define PRISM2_PDA_SIZE 1024
42362306a36Sopenharmony_ci
42462306a36Sopenharmony_ci
42562306a36Sopenharmony_ci/* Events; EvStat, Interrupt mask (IntEn), and acknowledge bits (EvAck) */
42662306a36Sopenharmony_ci#define HFA384X_EV_TICK BIT(15)
42762306a36Sopenharmony_ci#define HFA384X_EV_WTERR BIT(14)
42862306a36Sopenharmony_ci#define HFA384X_EV_INFDROP BIT(13)
42962306a36Sopenharmony_ci#ifdef PRISM2_PCI
43062306a36Sopenharmony_ci#define HFA384X_EV_PCI_M1 BIT(9)
43162306a36Sopenharmony_ci#define HFA384X_EV_PCI_M0 BIT(8)
43262306a36Sopenharmony_ci#endif /* PRISM2_PCI */
43362306a36Sopenharmony_ci#define HFA384X_EV_INFO BIT(7)
43462306a36Sopenharmony_ci#define HFA384X_EV_DTIM BIT(5)
43562306a36Sopenharmony_ci#define HFA384X_EV_CMD BIT(4)
43662306a36Sopenharmony_ci#define HFA384X_EV_ALLOC BIT(3)
43762306a36Sopenharmony_ci#define HFA384X_EV_TXEXC BIT(2)
43862306a36Sopenharmony_ci#define HFA384X_EV_TX BIT(1)
43962306a36Sopenharmony_ci#define HFA384X_EV_RX BIT(0)
44062306a36Sopenharmony_ci
44162306a36Sopenharmony_ci
44262306a36Sopenharmony_ci/* HFA384X Information frames */
44362306a36Sopenharmony_ci#define HFA384X_INFO_HANDOVERADDR 0xF000 /* AP f/w ? */
44462306a36Sopenharmony_ci#define HFA384X_INFO_HANDOVERDEAUTHADDR 0xF001 /* AP f/w 1.3.7 */
44562306a36Sopenharmony_ci#define HFA384X_INFO_COMMTALLIES 0xF100
44662306a36Sopenharmony_ci#define HFA384X_INFO_SCANRESULTS 0xF101
44762306a36Sopenharmony_ci#define HFA384X_INFO_CHANNELINFORESULTS 0xF102 /* AP f/w only */
44862306a36Sopenharmony_ci#define HFA384X_INFO_HOSTSCANRESULTS 0xF103
44962306a36Sopenharmony_ci#define HFA384X_INFO_LINKSTATUS 0xF200
45062306a36Sopenharmony_ci#define HFA384X_INFO_ASSOCSTATUS 0xF201 /* ? */
45162306a36Sopenharmony_ci#define HFA384X_INFO_AUTHREQ 0xF202 /* ? */
45262306a36Sopenharmony_ci#define HFA384X_INFO_PSUSERCNT 0xF203 /* ? */
45362306a36Sopenharmony_ci#define HFA384X_INFO_KEYIDCHANGED 0xF204 /* ? */
45462306a36Sopenharmony_ci
45562306a36Sopenharmony_cienum { HFA384X_LINKSTATUS_CONNECTED = 1,
45662306a36Sopenharmony_ci       HFA384X_LINKSTATUS_DISCONNECTED = 2,
45762306a36Sopenharmony_ci       HFA384X_LINKSTATUS_AP_CHANGE = 3,
45862306a36Sopenharmony_ci       HFA384X_LINKSTATUS_AP_OUT_OF_RANGE = 4,
45962306a36Sopenharmony_ci       HFA384X_LINKSTATUS_AP_IN_RANGE = 5,
46062306a36Sopenharmony_ci       HFA384X_LINKSTATUS_ASSOC_FAILED = 6 };
46162306a36Sopenharmony_ci
46262306a36Sopenharmony_cienum { HFA384X_PORTTYPE_BSS = 1, HFA384X_PORTTYPE_WDS = 2,
46362306a36Sopenharmony_ci       HFA384X_PORTTYPE_PSEUDO_IBSS = 3, HFA384X_PORTTYPE_IBSS = 0,
46462306a36Sopenharmony_ci       HFA384X_PORTTYPE_HOSTAP = 6 };
46562306a36Sopenharmony_ci
46662306a36Sopenharmony_ci#define HFA384X_RATES_1MBPS BIT(0)
46762306a36Sopenharmony_ci#define HFA384X_RATES_2MBPS BIT(1)
46862306a36Sopenharmony_ci#define HFA384X_RATES_5MBPS BIT(2)
46962306a36Sopenharmony_ci#define HFA384X_RATES_11MBPS BIT(3)
47062306a36Sopenharmony_ci
47162306a36Sopenharmony_ci#define HFA384X_ROAMING_FIRMWARE 1
47262306a36Sopenharmony_ci#define HFA384X_ROAMING_HOST 2
47362306a36Sopenharmony_ci#define HFA384X_ROAMING_DISABLED 3
47462306a36Sopenharmony_ci
47562306a36Sopenharmony_ci#define HFA384X_WEPFLAGS_PRIVACYINVOKED BIT(0)
47662306a36Sopenharmony_ci#define HFA384X_WEPFLAGS_EXCLUDEUNENCRYPTED BIT(1)
47762306a36Sopenharmony_ci#define HFA384X_WEPFLAGS_HOSTENCRYPT BIT(4)
47862306a36Sopenharmony_ci#define HFA384X_WEPFLAGS_HOSTDECRYPT BIT(7)
47962306a36Sopenharmony_ci
48062306a36Sopenharmony_ci#define HFA384X_RX_STATUS_MSGTYPE (BIT(15) | BIT(14) | BIT(13))
48162306a36Sopenharmony_ci#define HFA384X_RX_STATUS_PCF BIT(12)
48262306a36Sopenharmony_ci#define HFA384X_RX_STATUS_MACPORT (BIT(10) | BIT(9) | BIT(8))
48362306a36Sopenharmony_ci#define HFA384X_RX_STATUS_UNDECR BIT(1)
48462306a36Sopenharmony_ci#define HFA384X_RX_STATUS_FCSERR BIT(0)
48562306a36Sopenharmony_ci
48662306a36Sopenharmony_ci#define HFA384X_RX_STATUS_GET_MSGTYPE(s) \
48762306a36Sopenharmony_ci(((s) & HFA384X_RX_STATUS_MSGTYPE) >> 13)
48862306a36Sopenharmony_ci#define HFA384X_RX_STATUS_GET_MACPORT(s) \
48962306a36Sopenharmony_ci(((s) & HFA384X_RX_STATUS_MACPORT) >> 8)
49062306a36Sopenharmony_ci
49162306a36Sopenharmony_cienum { HFA384X_RX_MSGTYPE_NORMAL = 0, HFA384X_RX_MSGTYPE_RFC1042 = 1,
49262306a36Sopenharmony_ci       HFA384X_RX_MSGTYPE_BRIDGETUNNEL = 2, HFA384X_RX_MSGTYPE_MGMT = 4 };
49362306a36Sopenharmony_ci
49462306a36Sopenharmony_ci
49562306a36Sopenharmony_ci#define HFA384X_TX_CTRL_ALT_RTRY BIT(5)
49662306a36Sopenharmony_ci#define HFA384X_TX_CTRL_802_11 BIT(3)
49762306a36Sopenharmony_ci#define HFA384X_TX_CTRL_802_3 0
49862306a36Sopenharmony_ci#define HFA384X_TX_CTRL_TX_EX BIT(2)
49962306a36Sopenharmony_ci#define HFA384X_TX_CTRL_TX_OK BIT(1)
50062306a36Sopenharmony_ci
50162306a36Sopenharmony_ci#define HFA384X_TX_STATUS_RETRYERR BIT(0)
50262306a36Sopenharmony_ci#define HFA384X_TX_STATUS_AGEDERR BIT(1)
50362306a36Sopenharmony_ci#define HFA384X_TX_STATUS_DISCON BIT(2)
50462306a36Sopenharmony_ci#define HFA384X_TX_STATUS_FORMERR BIT(3)
50562306a36Sopenharmony_ci
50662306a36Sopenharmony_ci/* HFA3861/3863 (BBP) Control Registers */
50762306a36Sopenharmony_ci#define HFA386X_CR_TX_CONFIGURE 0x12 /* CR9 */
50862306a36Sopenharmony_ci#define HFA386X_CR_RX_CONFIGURE 0x14 /* CR10 */
50962306a36Sopenharmony_ci#define HFA386X_CR_A_D_TEST_MODES2 0x1A /* CR13 */
51062306a36Sopenharmony_ci#define HFA386X_CR_MANUAL_TX_POWER 0x3E /* CR31 */
51162306a36Sopenharmony_ci#define HFA386X_CR_MEASURED_TX_POWER 0x74 /* CR58 */
51262306a36Sopenharmony_ci
51362306a36Sopenharmony_ci
51462306a36Sopenharmony_ci#ifdef __KERNEL__
51562306a36Sopenharmony_ci
51662306a36Sopenharmony_ci#define PRISM2_TXFID_COUNT 8
51762306a36Sopenharmony_ci#define PRISM2_DATA_MAXLEN 2304
51862306a36Sopenharmony_ci#define PRISM2_TXFID_LEN (PRISM2_DATA_MAXLEN + sizeof(struct hfa384x_tx_frame))
51962306a36Sopenharmony_ci#define PRISM2_TXFID_EMPTY 0xffff
52062306a36Sopenharmony_ci#define PRISM2_TXFID_RESERVED 0xfffe
52162306a36Sopenharmony_ci#define PRISM2_DUMMY_FID 0xffff
52262306a36Sopenharmony_ci#define MAX_SSID_LEN 32
52362306a36Sopenharmony_ci#define MAX_NAME_LEN 32 /* this is assumed to be equal to MAX_SSID_LEN */
52462306a36Sopenharmony_ci
52562306a36Sopenharmony_ci#define PRISM2_DUMP_RX_HDR BIT(0)
52662306a36Sopenharmony_ci#define PRISM2_DUMP_TX_HDR BIT(1)
52762306a36Sopenharmony_ci#define PRISM2_DUMP_TXEXC_HDR BIT(2)
52862306a36Sopenharmony_ci
52962306a36Sopenharmony_cistruct hostap_tx_callback_info {
53062306a36Sopenharmony_ci	u16 idx;
53162306a36Sopenharmony_ci	void (*func)(struct sk_buff *, int ok, void *);
53262306a36Sopenharmony_ci	void *data;
53362306a36Sopenharmony_ci	struct hostap_tx_callback_info *next;
53462306a36Sopenharmony_ci};
53562306a36Sopenharmony_ci
53662306a36Sopenharmony_ci
53762306a36Sopenharmony_ci/* IEEE 802.11 requires that STA supports concurrent reception of at least
53862306a36Sopenharmony_ci * three fragmented frames. This define can be increased to support more
53962306a36Sopenharmony_ci * concurrent frames, but it should be noted that each entry can consume about
54062306a36Sopenharmony_ci * 2 kB of RAM and increasing cache size will slow down frame reassembly. */
54162306a36Sopenharmony_ci#define PRISM2_FRAG_CACHE_LEN 4
54262306a36Sopenharmony_ci
54362306a36Sopenharmony_cistruct prism2_frag_entry {
54462306a36Sopenharmony_ci	unsigned long first_frag_time;
54562306a36Sopenharmony_ci	unsigned int seq;
54662306a36Sopenharmony_ci	unsigned int last_frag;
54762306a36Sopenharmony_ci	struct sk_buff *skb;
54862306a36Sopenharmony_ci	u8 src_addr[ETH_ALEN];
54962306a36Sopenharmony_ci	u8 dst_addr[ETH_ALEN];
55062306a36Sopenharmony_ci};
55162306a36Sopenharmony_ci
55262306a36Sopenharmony_ci
55362306a36Sopenharmony_cistruct hostap_cmd_queue {
55462306a36Sopenharmony_ci	struct list_head list;
55562306a36Sopenharmony_ci	wait_queue_head_t compl;
55662306a36Sopenharmony_ci	volatile enum { CMD_SLEEP, CMD_CALLBACK, CMD_COMPLETED } type;
55762306a36Sopenharmony_ci	void (*callback)(struct net_device *dev, long context, u16 resp0,
55862306a36Sopenharmony_ci			 u16 res);
55962306a36Sopenharmony_ci	long context;
56062306a36Sopenharmony_ci	u16 cmd, param0, param1;
56162306a36Sopenharmony_ci	u16 resp0, res;
56262306a36Sopenharmony_ci	volatile int issued, issuing;
56362306a36Sopenharmony_ci
56462306a36Sopenharmony_ci	refcount_t usecnt;
56562306a36Sopenharmony_ci	int del_req;
56662306a36Sopenharmony_ci};
56762306a36Sopenharmony_ci
56862306a36Sopenharmony_ci/* options for hw_shutdown */
56962306a36Sopenharmony_ci#define HOSTAP_HW_NO_DISABLE BIT(0)
57062306a36Sopenharmony_ci#define HOSTAP_HW_ENABLE_CMDCOMPL BIT(1)
57162306a36Sopenharmony_ci
57262306a36Sopenharmony_citypedef struct local_info local_info_t;
57362306a36Sopenharmony_ci
57462306a36Sopenharmony_cistruct prism2_helper_functions {
57562306a36Sopenharmony_ci	/* these functions are defined in hardware model specific files
57662306a36Sopenharmony_ci	 * (hostap_{cs,plx,pci}.c */
57762306a36Sopenharmony_ci	int (*card_present)(local_info_t *local);
57862306a36Sopenharmony_ci	void (*cor_sreset)(local_info_t *local);
57962306a36Sopenharmony_ci	void (*genesis_reset)(local_info_t *local, int hcr);
58062306a36Sopenharmony_ci
58162306a36Sopenharmony_ci	/* the following functions are from hostap_hw.c, but they may have some
58262306a36Sopenharmony_ci	 * hardware model specific code */
58362306a36Sopenharmony_ci
58462306a36Sopenharmony_ci	/* FIX: low-level commands like cmd might disappear at some point to
58562306a36Sopenharmony_ci	 * make it easier to change them if needed (e.g., cmd would be replaced
58662306a36Sopenharmony_ci	 * with write_mif/read_mif/testcmd/inquire); at least get_rid and
58762306a36Sopenharmony_ci	 * set_rid might move to hostap_{cs,plx,pci}.c */
58862306a36Sopenharmony_ci	int (*cmd)(struct net_device *dev, u16 cmd, u16 param0, u16 *param1,
58962306a36Sopenharmony_ci		   u16 *resp0);
59062306a36Sopenharmony_ci	void (*read_regs)(struct net_device *dev, struct hfa384x_regs *regs);
59162306a36Sopenharmony_ci	int (*get_rid)(struct net_device *dev, u16 rid, void *buf, int len,
59262306a36Sopenharmony_ci		       int exact_len);
59362306a36Sopenharmony_ci	int (*set_rid)(struct net_device *dev, u16 rid, void *buf, int len);
59462306a36Sopenharmony_ci	int (*hw_enable)(struct net_device *dev, int initial);
59562306a36Sopenharmony_ci	int (*hw_config)(struct net_device *dev, int initial);
59662306a36Sopenharmony_ci	void (*hw_reset)(struct net_device *dev);
59762306a36Sopenharmony_ci	void (*hw_shutdown)(struct net_device *dev, int no_disable);
59862306a36Sopenharmony_ci	int (*reset_port)(struct net_device *dev);
59962306a36Sopenharmony_ci	void (*schedule_reset)(local_info_t *local);
60062306a36Sopenharmony_ci	int (*download)(local_info_t *local,
60162306a36Sopenharmony_ci			struct prism2_download_param *param);
60262306a36Sopenharmony_ci	int (*tx)(struct sk_buff *skb, struct net_device *dev);
60362306a36Sopenharmony_ci	int (*set_tim)(struct net_device *dev, int aid, int set);
60462306a36Sopenharmony_ci	const struct proc_ops *read_aux_proc_ops;
60562306a36Sopenharmony_ci
60662306a36Sopenharmony_ci	int need_tx_headroom; /* number of bytes of headroom needed before
60762306a36Sopenharmony_ci			       * IEEE 802.11 header */
60862306a36Sopenharmony_ci	enum { HOSTAP_HW_PCCARD, HOSTAP_HW_PLX, HOSTAP_HW_PCI } hw_type;
60962306a36Sopenharmony_ci};
61062306a36Sopenharmony_ci
61162306a36Sopenharmony_ci
61262306a36Sopenharmony_cistruct prism2_download_data {
61362306a36Sopenharmony_ci	u32 dl_cmd;
61462306a36Sopenharmony_ci	u32 start_addr;
61562306a36Sopenharmony_ci	u32 num_areas;
61662306a36Sopenharmony_ci	struct prism2_download_data_area {
61762306a36Sopenharmony_ci		u32 addr; /* wlan card address */
61862306a36Sopenharmony_ci		u32 len;
61962306a36Sopenharmony_ci		u8 *data; /* allocated data */
62062306a36Sopenharmony_ci	} data[];
62162306a36Sopenharmony_ci};
62262306a36Sopenharmony_ci
62362306a36Sopenharmony_ci
62462306a36Sopenharmony_ci#define HOSTAP_MAX_BSS_COUNT 64
62562306a36Sopenharmony_ci#define MAX_WPA_IE_LEN 64
62662306a36Sopenharmony_ci
62762306a36Sopenharmony_cistruct hostap_bss_info {
62862306a36Sopenharmony_ci	struct list_head list;
62962306a36Sopenharmony_ci	unsigned long last_update;
63062306a36Sopenharmony_ci	unsigned int count;
63162306a36Sopenharmony_ci	u8 bssid[ETH_ALEN];
63262306a36Sopenharmony_ci	u16 capab_info;
63362306a36Sopenharmony_ci	u8 ssid[32];
63462306a36Sopenharmony_ci	size_t ssid_len;
63562306a36Sopenharmony_ci	u8 wpa_ie[MAX_WPA_IE_LEN];
63662306a36Sopenharmony_ci	size_t wpa_ie_len;
63762306a36Sopenharmony_ci	u8 rsn_ie[MAX_WPA_IE_LEN];
63862306a36Sopenharmony_ci	size_t rsn_ie_len;
63962306a36Sopenharmony_ci	int chan;
64062306a36Sopenharmony_ci	int included;
64162306a36Sopenharmony_ci};
64262306a36Sopenharmony_ci
64362306a36Sopenharmony_ci
64462306a36Sopenharmony_ci/* Per radio private Host AP data - shared by all net devices interfaces used
64562306a36Sopenharmony_ci * by each radio (wlan#, wlan#ap, wlan#sta, WDS).
64662306a36Sopenharmony_ci * ((struct hostap_interface *) netdev_priv(dev))->local points to this
64762306a36Sopenharmony_ci * structure. */
64862306a36Sopenharmony_cistruct local_info {
64962306a36Sopenharmony_ci	struct module *hw_module;
65062306a36Sopenharmony_ci	int card_idx;
65162306a36Sopenharmony_ci	int dev_enabled;
65262306a36Sopenharmony_ci	int master_dev_auto_open; /* was master device opened automatically */
65362306a36Sopenharmony_ci	int num_dev_open; /* number of open devices */
65462306a36Sopenharmony_ci	struct net_device *dev; /* master radio device */
65562306a36Sopenharmony_ci	struct net_device *ddev; /* main data device */
65662306a36Sopenharmony_ci	struct list_head hostap_interfaces; /* Host AP interface list (contains
65762306a36Sopenharmony_ci					     * struct hostap_interface entries)
65862306a36Sopenharmony_ci					     */
65962306a36Sopenharmony_ci	rwlock_t iface_lock; /* hostap_interfaces read lock; use write lock
66062306a36Sopenharmony_ci			      * when removing entries from the list.
66162306a36Sopenharmony_ci			      * TX and RX paths can use read lock. */
66262306a36Sopenharmony_ci	spinlock_t cmdlock, baplock, lock, irq_init_lock;
66362306a36Sopenharmony_ci	struct mutex rid_bap_mtx;
66462306a36Sopenharmony_ci	u16 infofid; /* MAC buffer id for info frame */
66562306a36Sopenharmony_ci	/* txfid, intransmitfid, next_txtid, and next_alloc are protected by
66662306a36Sopenharmony_ci	 * txfidlock */
66762306a36Sopenharmony_ci	spinlock_t txfidlock;
66862306a36Sopenharmony_ci	int txfid_len; /* length of allocated TX buffers */
66962306a36Sopenharmony_ci	u16 txfid[PRISM2_TXFID_COUNT]; /* buffer IDs for TX frames */
67062306a36Sopenharmony_ci	/* buffer IDs for intransmit frames or PRISM2_TXFID_EMPTY if
67162306a36Sopenharmony_ci	 * corresponding txfid is free for next TX frame */
67262306a36Sopenharmony_ci	u16 intransmitfid[PRISM2_TXFID_COUNT];
67362306a36Sopenharmony_ci	int next_txfid; /* index to the next txfid to be checked for
67462306a36Sopenharmony_ci			 * availability */
67562306a36Sopenharmony_ci	int next_alloc; /* index to the next intransmitfid to be checked for
67662306a36Sopenharmony_ci			 * allocation events */
67762306a36Sopenharmony_ci
67862306a36Sopenharmony_ci	/* bitfield for atomic bitops */
67962306a36Sopenharmony_ci#define HOSTAP_BITS_TRANSMIT 0
68062306a36Sopenharmony_ci#define HOSTAP_BITS_BAP_TASKLET 1
68162306a36Sopenharmony_ci#define HOSTAP_BITS_BAP_TASKLET2 2
68262306a36Sopenharmony_ci	unsigned long bits;
68362306a36Sopenharmony_ci
68462306a36Sopenharmony_ci	struct ap_data *ap;
68562306a36Sopenharmony_ci
68662306a36Sopenharmony_ci	char essid[MAX_SSID_LEN + 1];
68762306a36Sopenharmony_ci	char name[MAX_NAME_LEN + 1];
68862306a36Sopenharmony_ci	int name_set;
68962306a36Sopenharmony_ci	u16 channel_mask; /* mask of allowed channels */
69062306a36Sopenharmony_ci	u16 scan_channel_mask; /* mask of channels to be scanned */
69162306a36Sopenharmony_ci	struct comm_tallies_sums comm_tallies;
69262306a36Sopenharmony_ci	struct proc_dir_entry *proc;
69362306a36Sopenharmony_ci	int iw_mode; /* operating mode (IW_MODE_*) */
69462306a36Sopenharmony_ci	int pseudo_adhoc; /* 0: IW_MODE_ADHOC is real 802.11 compliant IBSS
69562306a36Sopenharmony_ci			   * 1: IW_MODE_ADHOC is "pseudo IBSS" */
69662306a36Sopenharmony_ci	char bssid[ETH_ALEN];
69762306a36Sopenharmony_ci	int channel;
69862306a36Sopenharmony_ci	int beacon_int;
69962306a36Sopenharmony_ci	int dtim_period;
70062306a36Sopenharmony_ci	int mtu;
70162306a36Sopenharmony_ci	int frame_dump; /* dump RX/TX frame headers, PRISM2_DUMP_ flags */
70262306a36Sopenharmony_ci	int fw_tx_rate_control;
70362306a36Sopenharmony_ci	u16 tx_rate_control;
70462306a36Sopenharmony_ci	u16 basic_rates;
70562306a36Sopenharmony_ci	int hw_resetting;
70662306a36Sopenharmony_ci	int hw_ready;
70762306a36Sopenharmony_ci	int hw_reset_tries; /* how many times reset has been tried */
70862306a36Sopenharmony_ci	int hw_downloading;
70962306a36Sopenharmony_ci	int shutdown;
71062306a36Sopenharmony_ci	int pri_only;
71162306a36Sopenharmony_ci	int no_pri; /* no PRI f/w present */
71262306a36Sopenharmony_ci	int sram_type; /* 8 = x8 SRAM, 16 = x16 SRAM, -1 = unknown */
71362306a36Sopenharmony_ci
71462306a36Sopenharmony_ci	enum {
71562306a36Sopenharmony_ci		PRISM2_TXPOWER_AUTO = 0, PRISM2_TXPOWER_OFF,
71662306a36Sopenharmony_ci		PRISM2_TXPOWER_FIXED, PRISM2_TXPOWER_UNKNOWN
71762306a36Sopenharmony_ci	} txpower_type;
71862306a36Sopenharmony_ci	int txpower; /* if txpower_type == PRISM2_TXPOWER_FIXED */
71962306a36Sopenharmony_ci
72062306a36Sopenharmony_ci	/* command queue for hfa384x_cmd(); protected with cmdlock */
72162306a36Sopenharmony_ci	struct list_head cmd_queue;
72262306a36Sopenharmony_ci	/* max_len for cmd_queue; in addition, cmd_callback can use two
72362306a36Sopenharmony_ci	 * additional entries to prevent sleeping commands from stopping
72462306a36Sopenharmony_ci	 * transmits */
72562306a36Sopenharmony_ci#define HOSTAP_CMD_QUEUE_MAX_LEN 16
72662306a36Sopenharmony_ci	int cmd_queue_len; /* number of entries in cmd_queue */
72762306a36Sopenharmony_ci
72862306a36Sopenharmony_ci	/* if card timeout is detected in interrupt context, reset_queue is
72962306a36Sopenharmony_ci	 * used to schedule card reseting to be done in user context */
73062306a36Sopenharmony_ci	struct work_struct reset_queue;
73162306a36Sopenharmony_ci
73262306a36Sopenharmony_ci	/* For scheduling a change of the promiscuous mode RID */
73362306a36Sopenharmony_ci	int is_promisc;
73462306a36Sopenharmony_ci	struct work_struct set_multicast_list_queue;
73562306a36Sopenharmony_ci
73662306a36Sopenharmony_ci	struct work_struct set_tim_queue;
73762306a36Sopenharmony_ci	struct list_head set_tim_list;
73862306a36Sopenharmony_ci	spinlock_t set_tim_lock;
73962306a36Sopenharmony_ci
74062306a36Sopenharmony_ci	int wds_max_connections;
74162306a36Sopenharmony_ci	int wds_connections;
74262306a36Sopenharmony_ci#define HOSTAP_WDS_BROADCAST_RA BIT(0)
74362306a36Sopenharmony_ci#define HOSTAP_WDS_AP_CLIENT BIT(1)
74462306a36Sopenharmony_ci#define HOSTAP_WDS_STANDARD_FRAME BIT(2)
74562306a36Sopenharmony_ci	u32 wds_type;
74662306a36Sopenharmony_ci	u16 tx_control; /* flags to be used in TX description */
74762306a36Sopenharmony_ci	int manual_retry_count; /* -1 = use f/w default; otherwise retry count
74862306a36Sopenharmony_ci				 * to be used with all frames */
74962306a36Sopenharmony_ci
75062306a36Sopenharmony_ci	struct iw_statistics wstats;
75162306a36Sopenharmony_ci	unsigned long scan_timestamp; /* Time started to scan */
75262306a36Sopenharmony_ci	enum {
75362306a36Sopenharmony_ci		PRISM2_MONITOR_80211 = 0, PRISM2_MONITOR_PRISM = 1,
75462306a36Sopenharmony_ci		PRISM2_MONITOR_CAPHDR = 2, PRISM2_MONITOR_RADIOTAP = 3
75562306a36Sopenharmony_ci	} monitor_type;
75662306a36Sopenharmony_ci	int monitor_allow_fcserr;
75762306a36Sopenharmony_ci
75862306a36Sopenharmony_ci	int hostapd; /* whether user space daemon, hostapd, is used for AP
75962306a36Sopenharmony_ci		      * management */
76062306a36Sopenharmony_ci	int hostapd_sta; /* whether hostapd is used with an extra STA interface
76162306a36Sopenharmony_ci			  */
76262306a36Sopenharmony_ci	struct net_device *apdev;
76362306a36Sopenharmony_ci	struct net_device_stats apdevstats;
76462306a36Sopenharmony_ci
76562306a36Sopenharmony_ci	char assoc_ap_addr[ETH_ALEN];
76662306a36Sopenharmony_ci	struct net_device *stadev;
76762306a36Sopenharmony_ci	struct net_device_stats stadevstats;
76862306a36Sopenharmony_ci
76962306a36Sopenharmony_ci#define WEP_KEYS 4
77062306a36Sopenharmony_ci#define WEP_KEY_LEN 13
77162306a36Sopenharmony_ci	struct lib80211_crypt_info crypt_info;
77262306a36Sopenharmony_ci
77362306a36Sopenharmony_ci	int open_wep; /* allow unencrypted frames */
77462306a36Sopenharmony_ci	int host_encrypt;
77562306a36Sopenharmony_ci	int host_decrypt;
77662306a36Sopenharmony_ci	int privacy_invoked; /* force privacy invoked flag even if no keys are
77762306a36Sopenharmony_ci			      * configured */
77862306a36Sopenharmony_ci	int fw_encrypt_ok; /* whether firmware-based WEP encrypt is working
77962306a36Sopenharmony_ci			    * in Host AP mode (STA f/w 1.4.9 or newer) */
78062306a36Sopenharmony_ci	int bcrx_sta_key; /* use individual keys to override default keys even
78162306a36Sopenharmony_ci			   * with RX of broad/multicast frames */
78262306a36Sopenharmony_ci
78362306a36Sopenharmony_ci	struct prism2_frag_entry frag_cache[PRISM2_FRAG_CACHE_LEN];
78462306a36Sopenharmony_ci	unsigned int frag_next_idx;
78562306a36Sopenharmony_ci
78662306a36Sopenharmony_ci	int ieee_802_1x; /* is IEEE 802.1X used */
78762306a36Sopenharmony_ci
78862306a36Sopenharmony_ci	int antsel_tx, antsel_rx;
78962306a36Sopenharmony_ci	int rts_threshold; /* dot11RTSThreshold */
79062306a36Sopenharmony_ci	int fragm_threshold; /* dot11FragmentationThreshold */
79162306a36Sopenharmony_ci	int auth_algs; /* PRISM2_AUTH_ flags */
79262306a36Sopenharmony_ci
79362306a36Sopenharmony_ci	int enh_sec; /* cnfEnhSecurity options (broadcast SSID hide/ignore) */
79462306a36Sopenharmony_ci	int tallies32; /* 32-bit tallies in use */
79562306a36Sopenharmony_ci
79662306a36Sopenharmony_ci	struct prism2_helper_functions *func;
79762306a36Sopenharmony_ci
79862306a36Sopenharmony_ci	u8 *pda;
79962306a36Sopenharmony_ci	int fw_ap;
80062306a36Sopenharmony_ci#define PRISM2_FW_VER(major, minor, variant) \
80162306a36Sopenharmony_ci(((major) << 16) | ((minor) << 8) | variant)
80262306a36Sopenharmony_ci	u32 sta_fw_ver;
80362306a36Sopenharmony_ci
80462306a36Sopenharmony_ci	/* Tasklets for handling hardware IRQ related operations outside hw IRQ
80562306a36Sopenharmony_ci	 * handler */
80662306a36Sopenharmony_ci	struct tasklet_struct bap_tasklet;
80762306a36Sopenharmony_ci
80862306a36Sopenharmony_ci	struct tasklet_struct info_tasklet;
80962306a36Sopenharmony_ci	struct sk_buff_head info_list; /* info frames as skb's for
81062306a36Sopenharmony_ci					* info_tasklet */
81162306a36Sopenharmony_ci
81262306a36Sopenharmony_ci	struct hostap_tx_callback_info *tx_callback; /* registered TX callbacks
81362306a36Sopenharmony_ci						      */
81462306a36Sopenharmony_ci
81562306a36Sopenharmony_ci	struct tasklet_struct rx_tasklet;
81662306a36Sopenharmony_ci	struct sk_buff_head rx_list;
81762306a36Sopenharmony_ci
81862306a36Sopenharmony_ci	struct tasklet_struct sta_tx_exc_tasklet;
81962306a36Sopenharmony_ci	struct sk_buff_head sta_tx_exc_list;
82062306a36Sopenharmony_ci
82162306a36Sopenharmony_ci	int host_roaming;
82262306a36Sopenharmony_ci	unsigned long last_join_time; /* time of last JoinRequest */
82362306a36Sopenharmony_ci	struct hfa384x_hostscan_result *last_scan_results;
82462306a36Sopenharmony_ci	int last_scan_results_count;
82562306a36Sopenharmony_ci	enum { PRISM2_SCAN, PRISM2_HOSTSCAN } last_scan_type;
82662306a36Sopenharmony_ci	struct work_struct info_queue;
82762306a36Sopenharmony_ci	unsigned long pending_info; /* bit field of pending info_queue items */
82862306a36Sopenharmony_ci#define PRISM2_INFO_PENDING_LINKSTATUS 0
82962306a36Sopenharmony_ci#define PRISM2_INFO_PENDING_SCANRESULTS 1
83062306a36Sopenharmony_ci	int prev_link_status; /* previous received LinkStatus info */
83162306a36Sopenharmony_ci	int prev_linkstatus_connected;
83262306a36Sopenharmony_ci	u8 preferred_ap[ETH_ALEN]; /* use this AP if possible */
83362306a36Sopenharmony_ci
83462306a36Sopenharmony_ci#ifdef PRISM2_CALLBACK
83562306a36Sopenharmony_ci	void *callback_data; /* Can be used in callbacks; e.g., allocate
83662306a36Sopenharmony_ci			      * on enable event and free on disable event.
83762306a36Sopenharmony_ci			      * Host AP driver code does not touch this. */
83862306a36Sopenharmony_ci#endif /* PRISM2_CALLBACK */
83962306a36Sopenharmony_ci
84062306a36Sopenharmony_ci	wait_queue_head_t hostscan_wq;
84162306a36Sopenharmony_ci
84262306a36Sopenharmony_ci	/* Passive scan in Host AP mode */
84362306a36Sopenharmony_ci	struct timer_list passive_scan_timer;
84462306a36Sopenharmony_ci	int passive_scan_interval; /* in seconds, 0 = disabled */
84562306a36Sopenharmony_ci	int passive_scan_channel;
84662306a36Sopenharmony_ci	enum { PASSIVE_SCAN_WAIT, PASSIVE_SCAN_LISTEN } passive_scan_state;
84762306a36Sopenharmony_ci
84862306a36Sopenharmony_ci	struct timer_list tick_timer;
84962306a36Sopenharmony_ci	unsigned long last_tick_timer;
85062306a36Sopenharmony_ci	unsigned int sw_tick_stuck;
85162306a36Sopenharmony_ci
85262306a36Sopenharmony_ci	/* commsQuality / dBmCommsQuality data from periodic polling; only
85362306a36Sopenharmony_ci	 * valid for Managed and Ad-hoc modes */
85462306a36Sopenharmony_ci	unsigned long last_comms_qual_update;
85562306a36Sopenharmony_ci	int comms_qual; /* in some odd unit.. */
85662306a36Sopenharmony_ci	int avg_signal; /* in dB (note: negative) */
85762306a36Sopenharmony_ci	int avg_noise; /* in dB (note: negative) */
85862306a36Sopenharmony_ci	struct work_struct comms_qual_update;
85962306a36Sopenharmony_ci
86062306a36Sopenharmony_ci	/* RSSI to dBm adjustment (for RX descriptor fields) */
86162306a36Sopenharmony_ci	int rssi_to_dBm; /* subtract from RSSI to get approximate dBm value */
86262306a36Sopenharmony_ci
86362306a36Sopenharmony_ci	/* BSS list / protected by local->lock */
86462306a36Sopenharmony_ci	struct list_head bss_list;
86562306a36Sopenharmony_ci	int num_bss_info;
86662306a36Sopenharmony_ci	int wpa; /* WPA support enabled */
86762306a36Sopenharmony_ci	int tkip_countermeasures;
86862306a36Sopenharmony_ci	int drop_unencrypted;
86962306a36Sopenharmony_ci	/* Generic IEEE 802.11 info element to be added to
87062306a36Sopenharmony_ci	 * ProbeResp/Beacon/(Re)AssocReq */
87162306a36Sopenharmony_ci	u8 *generic_elem;
87262306a36Sopenharmony_ci	size_t generic_elem_len;
87362306a36Sopenharmony_ci
87462306a36Sopenharmony_ci#ifdef PRISM2_DOWNLOAD_SUPPORT
87562306a36Sopenharmony_ci	/* Persistent volatile download data */
87662306a36Sopenharmony_ci	struct prism2_download_data *dl_pri;
87762306a36Sopenharmony_ci	struct prism2_download_data *dl_sec;
87862306a36Sopenharmony_ci#endif /* PRISM2_DOWNLOAD_SUPPORT */
87962306a36Sopenharmony_ci
88062306a36Sopenharmony_ci#ifdef PRISM2_IO_DEBUG
88162306a36Sopenharmony_ci#define PRISM2_IO_DEBUG_SIZE 10000
88262306a36Sopenharmony_ci	u32 io_debug[PRISM2_IO_DEBUG_SIZE];
88362306a36Sopenharmony_ci	int io_debug_head;
88462306a36Sopenharmony_ci	int io_debug_enabled;
88562306a36Sopenharmony_ci#endif /* PRISM2_IO_DEBUG */
88662306a36Sopenharmony_ci
88762306a36Sopenharmony_ci	/* Pointer to hardware model specific (cs,pci,plx) private data. */
88862306a36Sopenharmony_ci	void *hw_priv;
88962306a36Sopenharmony_ci};
89062306a36Sopenharmony_ci
89162306a36Sopenharmony_ci
89262306a36Sopenharmony_ci/* Per interface private Host AP data
89362306a36Sopenharmony_ci * Allocated for each net device that Host AP uses (wlan#, wlan#ap, wlan#sta,
89462306a36Sopenharmony_ci * WDS) and netdev_priv(dev) points to this structure. */
89562306a36Sopenharmony_cistruct hostap_interface {
89662306a36Sopenharmony_ci	struct list_head list; /* list entry in Host AP interface list */
89762306a36Sopenharmony_ci	struct net_device *dev; /* pointer to this device */
89862306a36Sopenharmony_ci	struct local_info *local; /* pointer to shared private data */
89962306a36Sopenharmony_ci	struct net_device_stats stats;
90062306a36Sopenharmony_ci	struct iw_spy_data spy_data; /* iwspy support */
90162306a36Sopenharmony_ci	struct iw_public_data wireless_data;
90262306a36Sopenharmony_ci
90362306a36Sopenharmony_ci	enum {
90462306a36Sopenharmony_ci		HOSTAP_INTERFACE_MASTER,
90562306a36Sopenharmony_ci		HOSTAP_INTERFACE_MAIN,
90662306a36Sopenharmony_ci		HOSTAP_INTERFACE_AP,
90762306a36Sopenharmony_ci		HOSTAP_INTERFACE_STA,
90862306a36Sopenharmony_ci		HOSTAP_INTERFACE_WDS,
90962306a36Sopenharmony_ci	} type;
91062306a36Sopenharmony_ci
91162306a36Sopenharmony_ci	union {
91262306a36Sopenharmony_ci		struct hostap_interface_wds {
91362306a36Sopenharmony_ci			u8 remote_addr[ETH_ALEN];
91462306a36Sopenharmony_ci		} wds;
91562306a36Sopenharmony_ci	} u;
91662306a36Sopenharmony_ci};
91762306a36Sopenharmony_ci
91862306a36Sopenharmony_ci
91962306a36Sopenharmony_ci#define HOSTAP_SKB_TX_DATA_MAGIC 0xf08a36a2
92062306a36Sopenharmony_ci
92162306a36Sopenharmony_ci/*
92262306a36Sopenharmony_ci * TX meta data - stored in skb->cb buffer, so this must not be increased over
92362306a36Sopenharmony_ci * the 48-byte limit.
92462306a36Sopenharmony_ci * THE PADDING THIS STARTS WITH IS A HORRIBLE HACK THAT SHOULD NOT LIVE
92562306a36Sopenharmony_ci * TO SEE THE DAY.
92662306a36Sopenharmony_ci */
92762306a36Sopenharmony_cistruct hostap_skb_tx_data {
92862306a36Sopenharmony_ci	unsigned int __padding_for_default_qdiscs;
92962306a36Sopenharmony_ci	u32 magic; /* HOSTAP_SKB_TX_DATA_MAGIC */
93062306a36Sopenharmony_ci	u8 rate; /* transmit rate */
93162306a36Sopenharmony_ci#define HOSTAP_TX_FLAGS_WDS BIT(0)
93262306a36Sopenharmony_ci#define HOSTAP_TX_FLAGS_BUFFERED_FRAME BIT(1)
93362306a36Sopenharmony_ci#define HOSTAP_TX_FLAGS_ADD_MOREDATA BIT(2)
93462306a36Sopenharmony_ci	u8 flags; /* HOSTAP_TX_FLAGS_* */
93562306a36Sopenharmony_ci	u16 tx_cb_idx;
93662306a36Sopenharmony_ci	struct hostap_interface *iface;
93762306a36Sopenharmony_ci	unsigned long jiffies; /* queueing timestamp */
93862306a36Sopenharmony_ci	unsigned short ethertype;
93962306a36Sopenharmony_ci};
94062306a36Sopenharmony_ci
94162306a36Sopenharmony_ci
94262306a36Sopenharmony_ci#ifndef PRISM2_NO_DEBUG
94362306a36Sopenharmony_ci
94462306a36Sopenharmony_ci#define DEBUG_FID BIT(0)
94562306a36Sopenharmony_ci#define DEBUG_PS BIT(1)
94662306a36Sopenharmony_ci#define DEBUG_FLOW BIT(2)
94762306a36Sopenharmony_ci#define DEBUG_AP BIT(3)
94862306a36Sopenharmony_ci#define DEBUG_HW BIT(4)
94962306a36Sopenharmony_ci#define DEBUG_EXTRA BIT(5)
95062306a36Sopenharmony_ci#define DEBUG_EXTRA2 BIT(6)
95162306a36Sopenharmony_ci#define DEBUG_PS2 BIT(7)
95262306a36Sopenharmony_ci#define DEBUG_MASK (DEBUG_PS | DEBUG_AP | DEBUG_HW | DEBUG_EXTRA)
95362306a36Sopenharmony_ci#define PDEBUG(n, args...) \
95462306a36Sopenharmony_cido { if ((n) & DEBUG_MASK) printk(KERN_DEBUG args); } while (0)
95562306a36Sopenharmony_ci#define PDEBUG2(n, args...) \
95662306a36Sopenharmony_cido { if ((n) & DEBUG_MASK) printk(args); } while (0)
95762306a36Sopenharmony_ci
95862306a36Sopenharmony_ci#else /* PRISM2_NO_DEBUG */
95962306a36Sopenharmony_ci
96062306a36Sopenharmony_ci#define PDEBUG(n, args...)
96162306a36Sopenharmony_ci#define PDEBUG2(n, args...)
96262306a36Sopenharmony_ci
96362306a36Sopenharmony_ci#endif /* PRISM2_NO_DEBUG */
96462306a36Sopenharmony_ci
96562306a36Sopenharmony_cienum { BAP0 = 0, BAP1 = 1 };
96662306a36Sopenharmony_ci
96762306a36Sopenharmony_ci#define PRISM2_IO_DEBUG_CMD_INB 0
96862306a36Sopenharmony_ci#define PRISM2_IO_DEBUG_CMD_INW 1
96962306a36Sopenharmony_ci#define PRISM2_IO_DEBUG_CMD_INSW 2
97062306a36Sopenharmony_ci#define PRISM2_IO_DEBUG_CMD_OUTB 3
97162306a36Sopenharmony_ci#define PRISM2_IO_DEBUG_CMD_OUTW 4
97262306a36Sopenharmony_ci#define PRISM2_IO_DEBUG_CMD_OUTSW 5
97362306a36Sopenharmony_ci#define PRISM2_IO_DEBUG_CMD_ERROR 6
97462306a36Sopenharmony_ci#define PRISM2_IO_DEBUG_CMD_INTERRUPT 7
97562306a36Sopenharmony_ci
97662306a36Sopenharmony_ci#ifdef PRISM2_IO_DEBUG
97762306a36Sopenharmony_ci
97862306a36Sopenharmony_ci#define PRISM2_IO_DEBUG_ENTRY(cmd, reg, value) \
97962306a36Sopenharmony_ci(((cmd) << 24) | ((reg) << 16) | value)
98062306a36Sopenharmony_ci
98162306a36Sopenharmony_cistatic inline void prism2_io_debug_add(struct net_device *dev, int cmd,
98262306a36Sopenharmony_ci				       int reg, int value)
98362306a36Sopenharmony_ci{
98462306a36Sopenharmony_ci	struct hostap_interface *iface = netdev_priv(dev);
98562306a36Sopenharmony_ci	local_info_t *local = iface->local;
98662306a36Sopenharmony_ci
98762306a36Sopenharmony_ci	if (!local->io_debug_enabled)
98862306a36Sopenharmony_ci		return;
98962306a36Sopenharmony_ci
99062306a36Sopenharmony_ci	local->io_debug[local->io_debug_head] =	jiffies & 0xffffffff;
99162306a36Sopenharmony_ci	if (++local->io_debug_head >= PRISM2_IO_DEBUG_SIZE)
99262306a36Sopenharmony_ci		local->io_debug_head = 0;
99362306a36Sopenharmony_ci	local->io_debug[local->io_debug_head] =
99462306a36Sopenharmony_ci		PRISM2_IO_DEBUG_ENTRY(cmd, reg, value);
99562306a36Sopenharmony_ci	if (++local->io_debug_head >= PRISM2_IO_DEBUG_SIZE)
99662306a36Sopenharmony_ci		local->io_debug_head = 0;
99762306a36Sopenharmony_ci}
99862306a36Sopenharmony_ci
99962306a36Sopenharmony_ci
100062306a36Sopenharmony_cistatic inline void prism2_io_debug_error(struct net_device *dev, int err)
100162306a36Sopenharmony_ci{
100262306a36Sopenharmony_ci	struct hostap_interface *iface = netdev_priv(dev);
100362306a36Sopenharmony_ci	local_info_t *local = iface->local;
100462306a36Sopenharmony_ci	unsigned long flags;
100562306a36Sopenharmony_ci
100662306a36Sopenharmony_ci	if (!local->io_debug_enabled)
100762306a36Sopenharmony_ci		return;
100862306a36Sopenharmony_ci
100962306a36Sopenharmony_ci	spin_lock_irqsave(&local->lock, flags);
101062306a36Sopenharmony_ci	prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_ERROR, 0, err);
101162306a36Sopenharmony_ci	if (local->io_debug_enabled == 1) {
101262306a36Sopenharmony_ci		local->io_debug_enabled = 0;
101362306a36Sopenharmony_ci		printk(KERN_DEBUG "%s: I/O debug stopped\n", dev->name);
101462306a36Sopenharmony_ci	}
101562306a36Sopenharmony_ci	spin_unlock_irqrestore(&local->lock, flags);
101662306a36Sopenharmony_ci}
101762306a36Sopenharmony_ci
101862306a36Sopenharmony_ci#else /* PRISM2_IO_DEBUG */
101962306a36Sopenharmony_ci
102062306a36Sopenharmony_cistatic inline void prism2_io_debug_add(struct net_device *dev, int cmd,
102162306a36Sopenharmony_ci				       int reg, int value)
102262306a36Sopenharmony_ci{
102362306a36Sopenharmony_ci}
102462306a36Sopenharmony_ci
102562306a36Sopenharmony_cistatic inline void prism2_io_debug_error(struct net_device *dev, int err)
102662306a36Sopenharmony_ci{
102762306a36Sopenharmony_ci}
102862306a36Sopenharmony_ci
102962306a36Sopenharmony_ci#endif /* PRISM2_IO_DEBUG */
103062306a36Sopenharmony_ci
103162306a36Sopenharmony_ci
103262306a36Sopenharmony_ci#ifdef PRISM2_CALLBACK
103362306a36Sopenharmony_cienum {
103462306a36Sopenharmony_ci	/* Called when card is enabled */
103562306a36Sopenharmony_ci	PRISM2_CALLBACK_ENABLE,
103662306a36Sopenharmony_ci
103762306a36Sopenharmony_ci	/* Called when card is disabled */
103862306a36Sopenharmony_ci	PRISM2_CALLBACK_DISABLE,
103962306a36Sopenharmony_ci
104062306a36Sopenharmony_ci	/* Called when RX/TX starts/ends */
104162306a36Sopenharmony_ci	PRISM2_CALLBACK_RX_START, PRISM2_CALLBACK_RX_END,
104262306a36Sopenharmony_ci	PRISM2_CALLBACK_TX_START, PRISM2_CALLBACK_TX_END
104362306a36Sopenharmony_ci};
104462306a36Sopenharmony_civoid prism2_callback(local_info_t *local, int event);
104562306a36Sopenharmony_ci#else /* PRISM2_CALLBACK */
104662306a36Sopenharmony_ci#define prism2_callback(d, e) do { } while (0)
104762306a36Sopenharmony_ci#endif /* PRISM2_CALLBACK */
104862306a36Sopenharmony_ci
104962306a36Sopenharmony_ci#endif /* __KERNEL__ */
105062306a36Sopenharmony_ci
105162306a36Sopenharmony_ci#endif /* HOSTAP_WLAN_H */
1052