Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.9.4.
  1/* SPDX-License-Identifier: GPL-2.0-only */
  2/* hermes.h
  3 *
  4 * Driver core for the "Hermes" wireless MAC controller, as used in
  5 * the Lucent Orinoco and Cabletron RoamAbout cards. It should also
  6 * work on the hfa3841 and hfa3842 MAC controller chips used in the
  7 * Prism I & II chipsets.
  8 *
  9 * This is not a complete driver, just low-level access routines for
 10 * the MAC controller itself.
 11 *
 12 * Based on the prism2 driver from Absolute Value Systems' linux-wlan
 13 * project, the Linux wvlan_cs driver, Lucent's HCF-Light
 14 * (wvlan_hcf.c) library, and the NetBSD wireless driver.
 15 *
 16 * Copyright (C) 2000, David Gibson, Linuxcare Australia.
 17 * (C) Copyright David Gibson, IBM Corp. 2001-2003.
 18 *
 19 * Portions taken from hfa384x.h.
 20 * Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
 21 */
 22
 23#ifndef _HERMES_H
 24#define _HERMES_H
 25
 26/* Notes on locking:
 27 *
 28 * As a module of low level hardware access routines, there is no
 29 * locking. Users of this module should ensure that they serialize
 30 * access to the hermes structure, and to the hardware
 31*/
 32
 33#include <linux/if_ether.h>
 34#include <linux/io.h>
 35
 36/*
 37 * Limits and constants
 38 */
 39#define		HERMES_ALLOC_LEN_MIN		(4)
 40#define		HERMES_ALLOC_LEN_MAX		(2400)
 41#define		HERMES_LTV_LEN_MAX		(34)
 42#define		HERMES_BAP_DATALEN_MAX		(4096)
 43#define		HERMES_BAP_OFFSET_MAX		(4096)
 44#define		HERMES_PORTID_MAX		(7)
 45#define		HERMES_NUMPORTS_MAX		(HERMES_PORTID_MAX + 1)
 46#define		HERMES_PDR_LEN_MAX		(260)	/* in bytes, from EK */
 47#define		HERMES_PDA_RECS_MAX		(200)	/* a guess */
 48#define		HERMES_PDA_LEN_MAX		(1024)	/* in bytes, from EK */
 49#define		HERMES_SCANRESULT_MAX		(35)
 50#define		HERMES_CHINFORESULT_MAX		(8)
 51#define		HERMES_MAX_MULTICAST		(16)
 52#define		HERMES_MAGIC			(0x7d1f)
 53
 54/*
 55 * Hermes register offsets
 56 */
 57#define		HERMES_CMD			(0x00)
 58#define		HERMES_PARAM0			(0x02)
 59#define		HERMES_PARAM1			(0x04)
 60#define		HERMES_PARAM2			(0x06)
 61#define		HERMES_STATUS			(0x08)
 62#define		HERMES_RESP0			(0x0A)
 63#define		HERMES_RESP1			(0x0C)
 64#define		HERMES_RESP2			(0x0E)
 65#define		HERMES_INFOFID			(0x10)
 66#define		HERMES_RXFID			(0x20)
 67#define		HERMES_ALLOCFID			(0x22)
 68#define		HERMES_TXCOMPLFID		(0x24)
 69#define		HERMES_SELECT0			(0x18)
 70#define		HERMES_OFFSET0			(0x1C)
 71#define		HERMES_DATA0			(0x36)
 72#define		HERMES_SELECT1			(0x1A)
 73#define		HERMES_OFFSET1			(0x1E)
 74#define		HERMES_DATA1			(0x38)
 75#define		HERMES_EVSTAT			(0x30)
 76#define		HERMES_INTEN			(0x32)
 77#define		HERMES_EVACK			(0x34)
 78#define		HERMES_CONTROL			(0x14)
 79#define		HERMES_SWSUPPORT0		(0x28)
 80#define		HERMES_SWSUPPORT1		(0x2A)
 81#define		HERMES_SWSUPPORT2		(0x2C)
 82#define		HERMES_AUXPAGE			(0x3A)
 83#define		HERMES_AUXOFFSET		(0x3C)
 84#define		HERMES_AUXDATA			(0x3E)
 85
 86/*
 87 * CMD register bitmasks
 88 */
 89#define		HERMES_CMD_BUSY			(0x8000)
 90#define		HERMES_CMD_AINFO		(0x7f00)
 91#define		HERMES_CMD_MACPORT		(0x0700)
 92#define		HERMES_CMD_RECL			(0x0100)
 93#define		HERMES_CMD_WRITE		(0x0100)
 94#define		HERMES_CMD_PROGMODE		(0x0300)
 95#define		HERMES_CMD_CMDCODE		(0x003f)
 96
 97/*
 98 * STATUS register bitmasks
 99 */
100#define		HERMES_STATUS_RESULT		(0x7f00)
101#define		HERMES_STATUS_CMDCODE		(0x003f)
102
103/*
104 * OFFSET register bitmasks
105 */
106#define		HERMES_OFFSET_BUSY		(0x8000)
107#define		HERMES_OFFSET_ERR		(0x4000)
108#define		HERMES_OFFSET_DATAOFF		(0x0ffe)
109
110/*
111 * Event register bitmasks (INTEN, EVSTAT, EVACK)
112 */
113#define		HERMES_EV_TICK			(0x8000)
114#define		HERMES_EV_WTERR			(0x4000)
115#define		HERMES_EV_INFDROP		(0x2000)
116#define		HERMES_EV_INFO			(0x0080)
117#define		HERMES_EV_DTIM			(0x0020)
118#define		HERMES_EV_CMD			(0x0010)
119#define		HERMES_EV_ALLOC			(0x0008)
120#define		HERMES_EV_TXEXC			(0x0004)
121#define		HERMES_EV_TX			(0x0002)
122#define		HERMES_EV_RX			(0x0001)
123
124/*
125 * Command codes
126 */
127/*--- Controller Commands ----------------------------*/
128#define		HERMES_CMD_INIT			(0x0000)
129#define		HERMES_CMD_ENABLE		(0x0001)
130#define		HERMES_CMD_DISABLE		(0x0002)
131#define		HERMES_CMD_DIAG			(0x0003)
132
133/*--- Buffer Mgmt Commands ---------------------------*/
134#define		HERMES_CMD_ALLOC		(0x000A)
135#define		HERMES_CMD_TX			(0x000B)
136
137/*--- Regulate Commands ------------------------------*/
138#define		HERMES_CMD_NOTIFY		(0x0010)
139#define		HERMES_CMD_INQUIRE		(0x0011)
140
141/*--- Configure Commands -----------------------------*/
142#define		HERMES_CMD_ACCESS		(0x0021)
143#define		HERMES_CMD_DOWNLD		(0x0022)
144
145/*--- Serial I/O Commands ----------------------------*/
146#define		HERMES_CMD_READMIF		(0x0030)
147#define		HERMES_CMD_WRITEMIF		(0x0031)
148
149/*--- Debugging Commands -----------------------------*/
150#define		HERMES_CMD_TEST			(0x0038)
151
152
153/* Test command arguments */
154#define		HERMES_TEST_SET_CHANNEL		0x0800
155#define		HERMES_TEST_MONITOR		0x0b00
156#define		HERMES_TEST_STOP		0x0f00
157
158/* Authentication algorithms */
159#define		HERMES_AUTH_OPEN		1
160#define		HERMES_AUTH_SHARED_KEY		2
161
162/* WEP settings */
163#define		HERMES_WEP_PRIVACY_INVOKED	0x0001
164#define		HERMES_WEP_EXCL_UNENCRYPTED	0x0002
165#define		HERMES_WEP_HOST_ENCRYPT		0x0010
166#define		HERMES_WEP_HOST_DECRYPT		0x0080
167
168/* Symbol hostscan options */
169#define		HERMES_HOSTSCAN_SYMBOL_5SEC	0x0001
170#define		HERMES_HOSTSCAN_SYMBOL_ONCE	0x0002
171#define		HERMES_HOSTSCAN_SYMBOL_PASSIVE	0x0040
172#define		HERMES_HOSTSCAN_SYMBOL_BCAST	0x0080
173
174/*
175 * Frame structures and constants
176 */
177
178#define HERMES_DESCRIPTOR_OFFSET	0
179#define HERMES_802_11_OFFSET		(14)
180#define HERMES_802_3_OFFSET		(14 + 32)
181#define HERMES_802_2_OFFSET		(14 + 32 + 14)
182#define HERMES_TXCNTL2_OFFSET		(HERMES_802_3_OFFSET - 2)
183
184#define HERMES_RXSTAT_ERR		(0x0003)
185#define	HERMES_RXSTAT_BADCRC		(0x0001)
186#define	HERMES_RXSTAT_UNDECRYPTABLE	(0x0002)
187#define	HERMES_RXSTAT_MIC		(0x0010)	/* Frame contains MIC */
188#define	HERMES_RXSTAT_MACPORT		(0x0700)
189#define HERMES_RXSTAT_PCF		(0x1000)	/* Frame was received in CF period */
190#define	HERMES_RXSTAT_MIC_KEY_ID	(0x1800)	/* MIC key used */
191#define	HERMES_RXSTAT_MSGTYPE		(0xE000)
192#define	HERMES_RXSTAT_1042		(0x2000)	/* RFC-1042 frame */
193#define	HERMES_RXSTAT_TUNNEL		(0x4000)	/* bridge-tunnel encoded frame */
194#define	HERMES_RXSTAT_WMP		(0x6000)	/* Wavelan-II Management Protocol frame */
195
196/* Shift amount for key ID in RXSTAT and TXCTRL */
197#define	HERMES_MIC_KEY_ID_SHIFT		11
198
199struct hermes_tx_descriptor {
200	__le16 status;
201	__le16 reserved1;
202	__le16 reserved2;
203	__le32 sw_support;
204	u8 retry_count;
205	u8 tx_rate;
206	__le16 tx_control;
207} __packed;
208
209#define HERMES_TXSTAT_RETRYERR		(0x0001)
210#define HERMES_TXSTAT_AGEDERR		(0x0002)
211#define HERMES_TXSTAT_DISCON		(0x0004)
212#define HERMES_TXSTAT_FORMERR		(0x0008)
213
214#define HERMES_TXCTRL_TX_OK		(0x0002)	/* ?? interrupt on Tx complete */
215#define HERMES_TXCTRL_TX_EX		(0x0004)	/* ?? interrupt on Tx exception */
216#define HERMES_TXCTRL_802_11		(0x0008)	/* We supply 802.11 header */
217#define HERMES_TXCTRL_MIC		(0x0010)	/* 802.3 + TKIP */
218#define HERMES_TXCTRL_MIC_KEY_ID	(0x1800)	/* MIC Key ID mask */
219#define HERMES_TXCTRL_ALT_RTRY		(0x0020)
220
221/* Inquiry constants and data types */
222
223#define HERMES_INQ_TALLIES		(0xF100)
224#define HERMES_INQ_SCAN			(0xF101)
225#define HERMES_INQ_CHANNELINFO		(0xF102)
226#define HERMES_INQ_HOSTSCAN		(0xF103)
227#define HERMES_INQ_HOSTSCAN_SYMBOL	(0xF104)
228#define HERMES_INQ_LINKSTATUS		(0xF200)
229#define HERMES_INQ_SEC_STAT_AGERE	(0xF202)
230
231struct hermes_tallies_frame {
232	__le16 TxUnicastFrames;
233	__le16 TxMulticastFrames;
234	__le16 TxFragments;
235	__le16 TxUnicastOctets;
236	__le16 TxMulticastOctets;
237	__le16 TxDeferredTransmissions;
238	__le16 TxSingleRetryFrames;
239	__le16 TxMultipleRetryFrames;
240	__le16 TxRetryLimitExceeded;
241	__le16 TxDiscards;
242	__le16 RxUnicastFrames;
243	__le16 RxMulticastFrames;
244	__le16 RxFragments;
245	__le16 RxUnicastOctets;
246	__le16 RxMulticastOctets;
247	__le16 RxFCSErrors;
248	__le16 RxDiscards_NoBuffer;
249	__le16 TxDiscardsWrongSA;
250	__le16 RxWEPUndecryptable;
251	__le16 RxMsgInMsgFragments;
252	__le16 RxMsgInBadMsgFragments;
253	/* Those last are probably not available in very old firmwares */
254	__le16 RxDiscards_WEPICVError;
255	__le16 RxDiscards_WEPExcluded;
256} __packed;
257
258/* Grabbed from wlan-ng - Thanks Mark... - Jean II
259 * This is the result of a scan inquiry command */
260/* Structure describing info about an Access Point */
261struct prism2_scan_apinfo {
262	__le16 channel;		/* Channel where the AP sits */
263	__le16 noise;		/* Noise level */
264	__le16 level;		/* Signal level */
265	u8 bssid[ETH_ALEN];	/* MAC address of the Access Point */
266	__le16 beacon_interv;	/* Beacon interval */
267	__le16 capabilities;	/* Capabilities */
268	__le16 essid_len;	/* ESSID length */
269	u8 essid[32];		/* ESSID of the network */
270	u8 rates[10];		/* Bit rate supported */
271	__le16 proberesp_rate;	/* Data rate of the response frame */
272	__le16 atim;		/* ATIM window time, Kus (hostscan only) */
273} __packed;
274
275/* Same stuff for the Lucent/Agere card.
276 * Thanks to h1kari <h1kari AT dachb0den.com> - Jean II */
277struct agere_scan_apinfo {
278	__le16 channel;		/* Channel where the AP sits */
279	__le16 noise;		/* Noise level */
280	__le16 level;		/* Signal level */
281	u8 bssid[ETH_ALEN];	/* MAC address of the Access Point */
282	__le16 beacon_interv;	/* Beacon interval */
283	__le16 capabilities;	/* Capabilities */
284	/* bits: 0-ess, 1-ibss, 4-privacy [wep] */
285	__le16 essid_len;	/* ESSID length */
286	u8 essid[32];		/* ESSID of the network */
287} __packed;
288
289/* Moustafa: Scan structure for Symbol cards */
290struct symbol_scan_apinfo {
291	u8 channel;		/* Channel where the AP sits */
292	u8 unknown1;		/* 8 in 2.9x and 3.9x f/w, 0 otherwise */
293	__le16 noise;		/* Noise level */
294	__le16 level;		/* Signal level */
295	u8 bssid[ETH_ALEN];	/* MAC address of the Access Point */
296	__le16 beacon_interv;	/* Beacon interval */
297	__le16 capabilities;	/* Capabilities */
298	/* bits: 0-ess, 1-ibss, 4-privacy [wep] */
299	__le16 essid_len;	/* ESSID length */
300	u8 essid[32];		/* ESSID of the network */
301	__le16 rates[5];	/* Bit rate supported */
302	__le16 basic_rates;	/* Basic rates bitmask */
303	u8 unknown2[6];		/* Always FF:FF:FF:FF:00:00 */
304	u8 unknown3[8];		/* Always 0, appeared in f/w 3.91-68 */
305} __packed;
306
307union hermes_scan_info {
308	struct agere_scan_apinfo	a;
309	struct prism2_scan_apinfo	p;
310	struct symbol_scan_apinfo	s;
311};
312
313/* Extended scan struct for HERMES_INQ_CHANNELINFO.
314 * wl_lkm calls this an ACS scan (Automatic Channel Select).
315 * Keep out of union hermes_scan_info because it is much bigger than
316 * the older scan structures. */
317struct agere_ext_scan_info {
318	__le16	reserved0;
319
320	u8	noise;
321	u8	level;
322	u8	rx_flow;
323	u8	rate;
324	__le16	reserved1[2];
325
326	__le16	frame_control;
327	__le16	dur_id;
328	u8	addr1[ETH_ALEN];
329	u8	addr2[ETH_ALEN];
330	u8	bssid[ETH_ALEN];
331	__le16	sequence;
332	u8	addr4[ETH_ALEN];
333
334	__le16	data_length;
335
336	/* Next 3 fields do not get filled in. */
337	u8	daddr[ETH_ALEN];
338	u8	saddr[ETH_ALEN];
339	__le16	len_type;
340
341	__le64	timestamp;
342	__le16	beacon_interval;
343	__le16	capabilities;
344	u8	data[];
345} __packed;
346
347#define HERMES_LINKSTATUS_NOT_CONNECTED   (0x0000)
348#define HERMES_LINKSTATUS_CONNECTED       (0x0001)
349#define HERMES_LINKSTATUS_DISCONNECTED    (0x0002)
350#define HERMES_LINKSTATUS_AP_CHANGE       (0x0003)
351#define HERMES_LINKSTATUS_AP_OUT_OF_RANGE (0x0004)
352#define HERMES_LINKSTATUS_AP_IN_RANGE     (0x0005)
353#define HERMES_LINKSTATUS_ASSOC_FAILED    (0x0006)
354
355struct hermes_linkstatus {
356	__le16 linkstatus;         /* Link status */
357} __packed;
358
359struct hermes_response {
360	u16 status, resp0, resp1, resp2;
361};
362
363/* "ID" structure - used for ESSID and station nickname */
364struct hermes_idstring {
365	__le16 len;
366	__le16 val[16];
367} __packed;
368
369struct hermes_multicast {
370	u8 addr[HERMES_MAX_MULTICAST][ETH_ALEN];
371} __packed;
372
373/* Timeouts */
374#define HERMES_BAP_BUSY_TIMEOUT (10000) /* In iterations of ~1us */
375
376struct hermes;
377
378/* Functions to access hardware */
379struct hermes_ops {
380	int (*init)(struct hermes *hw);
381	int (*cmd_wait)(struct hermes *hw, u16 cmd, u16 parm0,
382			struct hermes_response *resp);
383	int (*init_cmd_wait)(struct hermes *hw, u16 cmd,
384			     u16 parm0, u16 parm1, u16 parm2,
385			     struct hermes_response *resp);
386	int (*allocate)(struct hermes *hw, u16 size, u16 *fid);
387	int (*read_ltv)(struct hermes *hw, int bap, u16 rid, unsigned buflen,
388			u16 *length, void *buf);
389	int (*read_ltv_pr)(struct hermes *hw, int bap, u16 rid,
390			      unsigned buflen, u16 *length, void *buf);
391	int (*write_ltv)(struct hermes *hw, int bap, u16 rid,
392			 u16 length, const void *value);
393	int (*bap_pread)(struct hermes *hw, int bap, void *buf, int len,
394			 u16 id, u16 offset);
395	int (*bap_pwrite)(struct hermes *hw, int bap, const void *buf,
396			  int len, u16 id, u16 offset);
397	int (*read_pda)(struct hermes *hw, __le16 *pda,
398			u32 pda_addr, u16 pda_len);
399	int (*program_init)(struct hermes *hw, u32 entry_point);
400	int (*program_end)(struct hermes *hw);
401	int (*program)(struct hermes *hw, const char *buf,
402		       u32 addr, u32 len);
403	void (*lock_irqsave)(spinlock_t *lock, unsigned long *flags);
404	void (*unlock_irqrestore)(spinlock_t *lock, unsigned long *flags);
405	void (*lock_irq)(spinlock_t *lock);
406	void (*unlock_irq)(spinlock_t *lock);
407};
408
409/* Basic control structure */
410struct hermes {
411	void __iomem *iobase;
412	int reg_spacing;
413#define HERMES_16BIT_REGSPACING	0
414#define HERMES_32BIT_REGSPACING	1
415	u16 inten; /* Which interrupts should be enabled? */
416	bool eeprom_pda;
417	const struct hermes_ops *ops;
418	void *priv;
419};
420
421/* Register access convenience macros */
422#define hermes_read_reg(hw, off) \
423	(ioread16((hw)->iobase + ((off) << (hw)->reg_spacing)))
424#define hermes_write_reg(hw, off, val) \
425	(iowrite16((val), (hw)->iobase + ((off) << (hw)->reg_spacing)))
426#define hermes_read_regn(hw, name) hermes_read_reg((hw), HERMES_##name)
427#define hermes_write_regn(hw, name, val) \
428	hermes_write_reg((hw), HERMES_##name, (val))
429
430/* Function prototypes */
431void hermes_struct_init(struct hermes *hw, void __iomem *address,
432			int reg_spacing);
433
434/* Inline functions */
435
436static inline int hermes_present(struct hermes *hw)
437{
438	return hermes_read_regn(hw, SWSUPPORT0) == HERMES_MAGIC;
439}
440
441static inline void hermes_set_irqmask(struct hermes *hw, u16 events)
442{
443	hw->inten = events;
444	hermes_write_regn(hw, INTEN, events);
445}
446
447static inline int hermes_enable_port(struct hermes *hw, int port)
448{
449	return hw->ops->cmd_wait(hw, HERMES_CMD_ENABLE | (port << 8),
450				 0, NULL);
451}
452
453static inline int hermes_disable_port(struct hermes *hw, int port)
454{
455	return hw->ops->cmd_wait(hw, HERMES_CMD_DISABLE | (port << 8),
456				 0, NULL);
457}
458
459/* Initiate an INQUIRE command (tallies or scan).  The result will come as an
460 * information frame in __orinoco_ev_info() */
461static inline int hermes_inquire(struct hermes *hw, u16 rid)
462{
463	return hw->ops->cmd_wait(hw, HERMES_CMD_INQUIRE, rid, NULL);
464}
465
466#define HERMES_BYTES_TO_RECLEN(n) ((((n) + 1) / 2) + 1)
467#define HERMES_RECLEN_TO_BYTES(n) (((n) - 1) * 2)
468
469/* Note that for the next two, the count is in 16-bit words, not bytes */
470static inline void hermes_read_words(struct hermes *hw, int off,
471				     void *buf, unsigned count)
472{
473	off = off << hw->reg_spacing;
474	ioread16_rep(hw->iobase + off, buf, count);
475}
476
477static inline void hermes_write_bytes(struct hermes *hw, int off,
478				      const char *buf, unsigned count)
479{
480	off = off << hw->reg_spacing;
481	iowrite16_rep(hw->iobase + off, buf, count >> 1);
482	if (unlikely(count & 1))
483		iowrite8(buf[count - 1], hw->iobase + off);
484}
485
486static inline void hermes_clear_words(struct hermes *hw, int off,
487				      unsigned count)
488{
489	unsigned i;
490
491	off = off << hw->reg_spacing;
492
493	for (i = 0; i < count; i++)
494		iowrite16(0, hw->iobase + off);
495}
496
497#define HERMES_READ_RECORD(hw, bap, rid, buf) \
498	(hw->ops->read_ltv((hw), (bap), (rid), sizeof(*buf), NULL, (buf)))
499#define HERMES_READ_RECORD_PR(hw, bap, rid, buf) \
500	(hw->ops->read_ltv_pr((hw), (bap), (rid), sizeof(*buf), NULL, (buf)))
501#define HERMES_WRITE_RECORD(hw, bap, rid, buf) \
502	(hw->ops->write_ltv((hw), (bap), (rid), \
503			    HERMES_BYTES_TO_RECLEN(sizeof(*buf)), (buf)))
504
505static inline int hermes_read_wordrec(struct hermes *hw, int bap, u16 rid,
506				      u16 *word)
507{
508	__le16 rec;
509	int err;
510
511	err = HERMES_READ_RECORD(hw, bap, rid, &rec);
512	*word = le16_to_cpu(rec);
513	return err;
514}
515
516static inline int hermes_read_wordrec_pr(struct hermes *hw, int bap, u16 rid,
517					 u16 *word)
518{
519	__le16 rec;
520	int err;
521
522	err = HERMES_READ_RECORD_PR(hw, bap, rid, &rec);
523	*word = le16_to_cpu(rec);
524	return err;
525}
526
527static inline int hermes_write_wordrec(struct hermes *hw, int bap, u16 rid,
528				       u16 word)
529{
530	__le16 rec = cpu_to_le16(word);
531	return HERMES_WRITE_RECORD(hw, bap, rid, &rec);
532}
533
534#endif  /* _HERMES_H */