cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

hermes.h (16213B)


      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 */