Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /* hermes.h
0003  *
0004  * Driver core for the "Hermes" wireless MAC controller, as used in
0005  * the Lucent Orinoco and Cabletron RoamAbout cards. It should also
0006  * work on the hfa3841 and hfa3842 MAC controller chips used in the
0007  * Prism I & II chipsets.
0008  *
0009  * This is not a complete driver, just low-level access routines for
0010  * the MAC controller itself.
0011  *
0012  * Based on the prism2 driver from Absolute Value Systems' linux-wlan
0013  * project, the Linux wvlan_cs driver, Lucent's HCF-Light
0014  * (wvlan_hcf.c) library, and the NetBSD wireless driver.
0015  *
0016  * Copyright (C) 2000, David Gibson, Linuxcare Australia.
0017  * (C) Copyright David Gibson, IBM Corp. 2001-2003.
0018  *
0019  * Portions taken from hfa384x.h.
0020  * Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
0021  */
0022 
0023 #ifndef _HERMES_H
0024 #define _HERMES_H
0025 
0026 /* Notes on locking:
0027  *
0028  * As a module of low level hardware access routines, there is no
0029  * locking. Users of this module should ensure that they serialize
0030  * access to the hermes structure, and to the hardware
0031 */
0032 
0033 #include <linux/if_ether.h>
0034 #include <linux/io.h>
0035 
0036 /*
0037  * Limits and constants
0038  */
0039 #define     HERMES_ALLOC_LEN_MIN        (4)
0040 #define     HERMES_ALLOC_LEN_MAX        (2400)
0041 #define     HERMES_LTV_LEN_MAX      (34)
0042 #define     HERMES_BAP_DATALEN_MAX      (4096)
0043 #define     HERMES_BAP_OFFSET_MAX       (4096)
0044 #define     HERMES_PORTID_MAX       (7)
0045 #define     HERMES_NUMPORTS_MAX     (HERMES_PORTID_MAX + 1)
0046 #define     HERMES_PDR_LEN_MAX      (260)   /* in bytes, from EK */
0047 #define     HERMES_PDA_RECS_MAX     (200)   /* a guess */
0048 #define     HERMES_PDA_LEN_MAX      (1024)  /* in bytes, from EK */
0049 #define     HERMES_SCANRESULT_MAX       (35)
0050 #define     HERMES_CHINFORESULT_MAX     (8)
0051 #define     HERMES_MAX_MULTICAST        (16)
0052 #define     HERMES_MAGIC            (0x7d1f)
0053 
0054 /*
0055  * Hermes register offsets
0056  */
0057 #define     HERMES_CMD          (0x00)
0058 #define     HERMES_PARAM0           (0x02)
0059 #define     HERMES_PARAM1           (0x04)
0060 #define     HERMES_PARAM2           (0x06)
0061 #define     HERMES_STATUS           (0x08)
0062 #define     HERMES_RESP0            (0x0A)
0063 #define     HERMES_RESP1            (0x0C)
0064 #define     HERMES_RESP2            (0x0E)
0065 #define     HERMES_INFOFID          (0x10)
0066 #define     HERMES_RXFID            (0x20)
0067 #define     HERMES_ALLOCFID         (0x22)
0068 #define     HERMES_TXCOMPLFID       (0x24)
0069 #define     HERMES_SELECT0          (0x18)
0070 #define     HERMES_OFFSET0          (0x1C)
0071 #define     HERMES_DATA0            (0x36)
0072 #define     HERMES_SELECT1          (0x1A)
0073 #define     HERMES_OFFSET1          (0x1E)
0074 #define     HERMES_DATA1            (0x38)
0075 #define     HERMES_EVSTAT           (0x30)
0076 #define     HERMES_INTEN            (0x32)
0077 #define     HERMES_EVACK            (0x34)
0078 #define     HERMES_CONTROL          (0x14)
0079 #define     HERMES_SWSUPPORT0       (0x28)
0080 #define     HERMES_SWSUPPORT1       (0x2A)
0081 #define     HERMES_SWSUPPORT2       (0x2C)
0082 #define     HERMES_AUXPAGE          (0x3A)
0083 #define     HERMES_AUXOFFSET        (0x3C)
0084 #define     HERMES_AUXDATA          (0x3E)
0085 
0086 /*
0087  * CMD register bitmasks
0088  */
0089 #define     HERMES_CMD_BUSY         (0x8000)
0090 #define     HERMES_CMD_AINFO        (0x7f00)
0091 #define     HERMES_CMD_MACPORT      (0x0700)
0092 #define     HERMES_CMD_RECL         (0x0100)
0093 #define     HERMES_CMD_WRITE        (0x0100)
0094 #define     HERMES_CMD_PROGMODE     (0x0300)
0095 #define     HERMES_CMD_CMDCODE      (0x003f)
0096 
0097 /*
0098  * STATUS register bitmasks
0099  */
0100 #define     HERMES_STATUS_RESULT        (0x7f00)
0101 #define     HERMES_STATUS_CMDCODE       (0x003f)
0102 
0103 /*
0104  * OFFSET register bitmasks
0105  */
0106 #define     HERMES_OFFSET_BUSY      (0x8000)
0107 #define     HERMES_OFFSET_ERR       (0x4000)
0108 #define     HERMES_OFFSET_DATAOFF       (0x0ffe)
0109 
0110 /*
0111  * Event register bitmasks (INTEN, EVSTAT, EVACK)
0112  */
0113 #define     HERMES_EV_TICK          (0x8000)
0114 #define     HERMES_EV_WTERR         (0x4000)
0115 #define     HERMES_EV_INFDROP       (0x2000)
0116 #define     HERMES_EV_INFO          (0x0080)
0117 #define     HERMES_EV_DTIM          (0x0020)
0118 #define     HERMES_EV_CMD           (0x0010)
0119 #define     HERMES_EV_ALLOC         (0x0008)
0120 #define     HERMES_EV_TXEXC         (0x0004)
0121 #define     HERMES_EV_TX            (0x0002)
0122 #define     HERMES_EV_RX            (0x0001)
0123 
0124 /*
0125  * Command codes
0126  */
0127 /*--- Controller Commands ----------------------------*/
0128 #define     HERMES_CMD_INIT         (0x0000)
0129 #define     HERMES_CMD_ENABLE       (0x0001)
0130 #define     HERMES_CMD_DISABLE      (0x0002)
0131 #define     HERMES_CMD_DIAG         (0x0003)
0132 
0133 /*--- Buffer Mgmt Commands ---------------------------*/
0134 #define     HERMES_CMD_ALLOC        (0x000A)
0135 #define     HERMES_CMD_TX           (0x000B)
0136 
0137 /*--- Regulate Commands ------------------------------*/
0138 #define     HERMES_CMD_NOTIFY       (0x0010)
0139 #define     HERMES_CMD_INQUIRE      (0x0011)
0140 
0141 /*--- Configure Commands -----------------------------*/
0142 #define     HERMES_CMD_ACCESS       (0x0021)
0143 #define     HERMES_CMD_DOWNLD       (0x0022)
0144 
0145 /*--- Serial I/O Commands ----------------------------*/
0146 #define     HERMES_CMD_READMIF      (0x0030)
0147 #define     HERMES_CMD_WRITEMIF     (0x0031)
0148 
0149 /*--- Debugging Commands -----------------------------*/
0150 #define     HERMES_CMD_TEST         (0x0038)
0151 
0152 
0153 /* Test command arguments */
0154 #define     HERMES_TEST_SET_CHANNEL     0x0800
0155 #define     HERMES_TEST_MONITOR     0x0b00
0156 #define     HERMES_TEST_STOP        0x0f00
0157 
0158 /* Authentication algorithms */
0159 #define     HERMES_AUTH_OPEN        1
0160 #define     HERMES_AUTH_SHARED_KEY      2
0161 
0162 /* WEP settings */
0163 #define     HERMES_WEP_PRIVACY_INVOKED  0x0001
0164 #define     HERMES_WEP_EXCL_UNENCRYPTED 0x0002
0165 #define     HERMES_WEP_HOST_ENCRYPT     0x0010
0166 #define     HERMES_WEP_HOST_DECRYPT     0x0080
0167 
0168 /* Symbol hostscan options */
0169 #define     HERMES_HOSTSCAN_SYMBOL_5SEC 0x0001
0170 #define     HERMES_HOSTSCAN_SYMBOL_ONCE 0x0002
0171 #define     HERMES_HOSTSCAN_SYMBOL_PASSIVE  0x0040
0172 #define     HERMES_HOSTSCAN_SYMBOL_BCAST    0x0080
0173 
0174 /*
0175  * Frame structures and constants
0176  */
0177 
0178 #define HERMES_DESCRIPTOR_OFFSET    0
0179 #define HERMES_802_11_OFFSET        (14)
0180 #define HERMES_802_3_OFFSET     (14 + 32)
0181 #define HERMES_802_2_OFFSET     (14 + 32 + 14)
0182 #define HERMES_TXCNTL2_OFFSET       (HERMES_802_3_OFFSET - 2)
0183 
0184 #define HERMES_RXSTAT_ERR       (0x0003)
0185 #define HERMES_RXSTAT_BADCRC        (0x0001)
0186 #define HERMES_RXSTAT_UNDECRYPTABLE (0x0002)
0187 #define HERMES_RXSTAT_MIC       (0x0010)    /* Frame contains MIC */
0188 #define HERMES_RXSTAT_MACPORT       (0x0700)
0189 #define HERMES_RXSTAT_PCF       (0x1000)    /* Frame was received in CF period */
0190 #define HERMES_RXSTAT_MIC_KEY_ID    (0x1800)    /* MIC key used */
0191 #define HERMES_RXSTAT_MSGTYPE       (0xE000)
0192 #define HERMES_RXSTAT_1042      (0x2000)    /* RFC-1042 frame */
0193 #define HERMES_RXSTAT_TUNNEL        (0x4000)    /* bridge-tunnel encoded frame */
0194 #define HERMES_RXSTAT_WMP       (0x6000)    /* Wavelan-II Management Protocol frame */
0195 
0196 /* Shift amount for key ID in RXSTAT and TXCTRL */
0197 #define HERMES_MIC_KEY_ID_SHIFT     11
0198 
0199 struct hermes_tx_descriptor {
0200     __le16 status;
0201     __le16 reserved1;
0202     __le16 reserved2;
0203     __le32 sw_support;
0204     u8 retry_count;
0205     u8 tx_rate;
0206     __le16 tx_control;
0207 } __packed;
0208 
0209 #define HERMES_TXSTAT_RETRYERR      (0x0001)
0210 #define HERMES_TXSTAT_AGEDERR       (0x0002)
0211 #define HERMES_TXSTAT_DISCON        (0x0004)
0212 #define HERMES_TXSTAT_FORMERR       (0x0008)
0213 
0214 #define HERMES_TXCTRL_TX_OK     (0x0002)    /* ?? interrupt on Tx complete */
0215 #define HERMES_TXCTRL_TX_EX     (0x0004)    /* ?? interrupt on Tx exception */
0216 #define HERMES_TXCTRL_802_11        (0x0008)    /* We supply 802.11 header */
0217 #define HERMES_TXCTRL_MIC       (0x0010)    /* 802.3 + TKIP */
0218 #define HERMES_TXCTRL_MIC_KEY_ID    (0x1800)    /* MIC Key ID mask */
0219 #define HERMES_TXCTRL_ALT_RTRY      (0x0020)
0220 
0221 /* Inquiry constants and data types */
0222 
0223 #define HERMES_INQ_TALLIES      (0xF100)
0224 #define HERMES_INQ_SCAN         (0xF101)
0225 #define HERMES_INQ_CHANNELINFO      (0xF102)
0226 #define HERMES_INQ_HOSTSCAN     (0xF103)
0227 #define HERMES_INQ_HOSTSCAN_SYMBOL  (0xF104)
0228 #define HERMES_INQ_LINKSTATUS       (0xF200)
0229 #define HERMES_INQ_SEC_STAT_AGERE   (0xF202)
0230 
0231 struct hermes_tallies_frame {
0232     __le16 TxUnicastFrames;
0233     __le16 TxMulticastFrames;
0234     __le16 TxFragments;
0235     __le16 TxUnicastOctets;
0236     __le16 TxMulticastOctets;
0237     __le16 TxDeferredTransmissions;
0238     __le16 TxSingleRetryFrames;
0239     __le16 TxMultipleRetryFrames;
0240     __le16 TxRetryLimitExceeded;
0241     __le16 TxDiscards;
0242     __le16 RxUnicastFrames;
0243     __le16 RxMulticastFrames;
0244     __le16 RxFragments;
0245     __le16 RxUnicastOctets;
0246     __le16 RxMulticastOctets;
0247     __le16 RxFCSErrors;
0248     __le16 RxDiscards_NoBuffer;
0249     __le16 TxDiscardsWrongSA;
0250     __le16 RxWEPUndecryptable;
0251     __le16 RxMsgInMsgFragments;
0252     __le16 RxMsgInBadMsgFragments;
0253     /* Those last are probably not available in very old firmwares */
0254     __le16 RxDiscards_WEPICVError;
0255     __le16 RxDiscards_WEPExcluded;
0256 } __packed;
0257 
0258 /* Grabbed from wlan-ng - Thanks Mark... - Jean II
0259  * This is the result of a scan inquiry command */
0260 /* Structure describing info about an Access Point */
0261 struct prism2_scan_apinfo {
0262     __le16 channel;     /* Channel where the AP sits */
0263     __le16 noise;       /* Noise level */
0264     __le16 level;       /* Signal level */
0265     u8 bssid[ETH_ALEN]; /* MAC address of the Access Point */
0266     __le16 beacon_interv;   /* Beacon interval */
0267     __le16 capabilities;    /* Capabilities */
0268     __le16 essid_len;   /* ESSID length */
0269     u8 essid[32];       /* ESSID of the network */
0270     u8 rates[10];       /* Bit rate supported */
0271     __le16 proberesp_rate;  /* Data rate of the response frame */
0272     __le16 atim;        /* ATIM window time, Kus (hostscan only) */
0273 } __packed;
0274 
0275 /* Same stuff for the Lucent/Agere card.
0276  * Thanks to h1kari <h1kari AT dachb0den.com> - Jean II */
0277 struct agere_scan_apinfo {
0278     __le16 channel;     /* Channel where the AP sits */
0279     __le16 noise;       /* Noise level */
0280     __le16 level;       /* Signal level */
0281     u8 bssid[ETH_ALEN]; /* MAC address of the Access Point */
0282     __le16 beacon_interv;   /* Beacon interval */
0283     __le16 capabilities;    /* Capabilities */
0284     /* bits: 0-ess, 1-ibss, 4-privacy [wep] */
0285     __le16 essid_len;   /* ESSID length */
0286     u8 essid[32];       /* ESSID of the network */
0287 } __packed;
0288 
0289 /* Moustafa: Scan structure for Symbol cards */
0290 struct symbol_scan_apinfo {
0291     u8 channel;     /* Channel where the AP sits */
0292     u8 unknown1;        /* 8 in 2.9x and 3.9x f/w, 0 otherwise */
0293     __le16 noise;       /* Noise level */
0294     __le16 level;       /* Signal level */
0295     u8 bssid[ETH_ALEN]; /* MAC address of the Access Point */
0296     __le16 beacon_interv;   /* Beacon interval */
0297     __le16 capabilities;    /* Capabilities */
0298     /* bits: 0-ess, 1-ibss, 4-privacy [wep] */
0299     __le16 essid_len;   /* ESSID length */
0300     u8 essid[32];       /* ESSID of the network */
0301     __le16 rates[5];    /* Bit rate supported */
0302     __le16 basic_rates; /* Basic rates bitmask */
0303     u8 unknown2[6];     /* Always FF:FF:FF:FF:00:00 */
0304     u8 unknown3[8];     /* Always 0, appeared in f/w 3.91-68 */
0305 } __packed;
0306 
0307 union hermes_scan_info {
0308     struct agere_scan_apinfo    a;
0309     struct prism2_scan_apinfo   p;
0310     struct symbol_scan_apinfo   s;
0311 };
0312 
0313 /* Extended scan struct for HERMES_INQ_CHANNELINFO.
0314  * wl_lkm calls this an ACS scan (Automatic Channel Select).
0315  * Keep out of union hermes_scan_info because it is much bigger than
0316  * the older scan structures. */
0317 struct agere_ext_scan_info {
0318     __le16  reserved0;
0319 
0320     u8  noise;
0321     u8  level;
0322     u8  rx_flow;
0323     u8  rate;
0324     __le16  reserved1[2];
0325 
0326     __le16  frame_control;
0327     __le16  dur_id;
0328     u8  addr1[ETH_ALEN];
0329     u8  addr2[ETH_ALEN];
0330     u8  bssid[ETH_ALEN];
0331     __le16  sequence;
0332     u8  addr4[ETH_ALEN];
0333 
0334     __le16  data_length;
0335 
0336     /* Next 3 fields do not get filled in. */
0337     u8  daddr[ETH_ALEN];
0338     u8  saddr[ETH_ALEN];
0339     __le16  len_type;
0340 
0341     __le64  timestamp;
0342     __le16  beacon_interval;
0343     __le16  capabilities;
0344     u8  data[];
0345 } __packed;
0346 
0347 #define HERMES_LINKSTATUS_NOT_CONNECTED   (0x0000)
0348 #define HERMES_LINKSTATUS_CONNECTED       (0x0001)
0349 #define HERMES_LINKSTATUS_DISCONNECTED    (0x0002)
0350 #define HERMES_LINKSTATUS_AP_CHANGE       (0x0003)
0351 #define HERMES_LINKSTATUS_AP_OUT_OF_RANGE (0x0004)
0352 #define HERMES_LINKSTATUS_AP_IN_RANGE     (0x0005)
0353 #define HERMES_LINKSTATUS_ASSOC_FAILED    (0x0006)
0354 
0355 struct hermes_linkstatus {
0356     __le16 linkstatus;         /* Link status */
0357 } __packed;
0358 
0359 struct hermes_response {
0360     u16 status, resp0, resp1, resp2;
0361 };
0362 
0363 /* "ID" structure - used for ESSID and station nickname */
0364 struct hermes_idstring {
0365     __le16 len;
0366     __le16 val[16];
0367 } __packed;
0368 
0369 struct hermes_multicast {
0370     u8 addr[HERMES_MAX_MULTICAST][ETH_ALEN];
0371 } __packed;
0372 
0373 /* Timeouts */
0374 #define HERMES_BAP_BUSY_TIMEOUT (10000) /* In iterations of ~1us */
0375 
0376 struct hermes;
0377 
0378 /* Functions to access hardware */
0379 struct hermes_ops {
0380     int (*init)(struct hermes *hw);
0381     int (*cmd_wait)(struct hermes *hw, u16 cmd, u16 parm0,
0382             struct hermes_response *resp);
0383     int (*init_cmd_wait)(struct hermes *hw, u16 cmd,
0384                  u16 parm0, u16 parm1, u16 parm2,
0385                  struct hermes_response *resp);
0386     int (*allocate)(struct hermes *hw, u16 size, u16 *fid);
0387     int (*read_ltv)(struct hermes *hw, int bap, u16 rid, unsigned buflen,
0388             u16 *length, void *buf);
0389     int (*read_ltv_pr)(struct hermes *hw, int bap, u16 rid,
0390                   unsigned buflen, u16 *length, void *buf);
0391     int (*write_ltv)(struct hermes *hw, int bap, u16 rid,
0392              u16 length, const void *value);
0393     int (*bap_pread)(struct hermes *hw, int bap, void *buf, int len,
0394              u16 id, u16 offset);
0395     int (*bap_pwrite)(struct hermes *hw, int bap, const void *buf,
0396               int len, u16 id, u16 offset);
0397     int (*read_pda)(struct hermes *hw, __le16 *pda,
0398             u32 pda_addr, u16 pda_len);
0399     int (*program_init)(struct hermes *hw, u32 entry_point);
0400     int (*program_end)(struct hermes *hw);
0401     int (*program)(struct hermes *hw, const char *buf,
0402                u32 addr, u32 len);
0403     void (*lock_irqsave)(spinlock_t *lock, unsigned long *flags);
0404     void (*unlock_irqrestore)(spinlock_t *lock, unsigned long *flags);
0405     void (*lock_irq)(spinlock_t *lock);
0406     void (*unlock_irq)(spinlock_t *lock);
0407 };
0408 
0409 /* Basic control structure */
0410 struct hermes {
0411     void __iomem *iobase;
0412     int reg_spacing;
0413 #define HERMES_16BIT_REGSPACING 0
0414 #define HERMES_32BIT_REGSPACING 1
0415     u16 inten; /* Which interrupts should be enabled? */
0416     bool eeprom_pda;
0417     const struct hermes_ops *ops;
0418     void *priv;
0419 };
0420 
0421 /* Register access convenience macros */
0422 #define hermes_read_reg(hw, off) \
0423     (ioread16((hw)->iobase + ((off) << (hw)->reg_spacing)))
0424 #define hermes_write_reg(hw, off, val) \
0425     (iowrite16((val), (hw)->iobase + ((off) << (hw)->reg_spacing)))
0426 #define hermes_read_regn(hw, name) hermes_read_reg((hw), HERMES_##name)
0427 #define hermes_write_regn(hw, name, val) \
0428     hermes_write_reg((hw), HERMES_##name, (val))
0429 
0430 /* Function prototypes */
0431 void hermes_struct_init(struct hermes *hw, void __iomem *address,
0432             int reg_spacing);
0433 
0434 /* Inline functions */
0435 
0436 static inline int hermes_present(struct hermes *hw)
0437 {
0438     return hermes_read_regn(hw, SWSUPPORT0) == HERMES_MAGIC;
0439 }
0440 
0441 static inline void hermes_set_irqmask(struct hermes *hw, u16 events)
0442 {
0443     hw->inten = events;
0444     hermes_write_regn(hw, INTEN, events);
0445 }
0446 
0447 static inline int hermes_enable_port(struct hermes *hw, int port)
0448 {
0449     return hw->ops->cmd_wait(hw, HERMES_CMD_ENABLE | (port << 8),
0450                  0, NULL);
0451 }
0452 
0453 static inline int hermes_disable_port(struct hermes *hw, int port)
0454 {
0455     return hw->ops->cmd_wait(hw, HERMES_CMD_DISABLE | (port << 8),
0456                  0, NULL);
0457 }
0458 
0459 /* Initiate an INQUIRE command (tallies or scan).  The result will come as an
0460  * information frame in __orinoco_ev_info() */
0461 static inline int hermes_inquire(struct hermes *hw, u16 rid)
0462 {
0463     return hw->ops->cmd_wait(hw, HERMES_CMD_INQUIRE, rid, NULL);
0464 }
0465 
0466 #define HERMES_BYTES_TO_RECLEN(n) ((((n) + 1) / 2) + 1)
0467 #define HERMES_RECLEN_TO_BYTES(n) (((n) - 1) * 2)
0468 
0469 /* Note that for the next two, the count is in 16-bit words, not bytes */
0470 static inline void hermes_read_words(struct hermes *hw, int off,
0471                      void *buf, unsigned count)
0472 {
0473     off = off << hw->reg_spacing;
0474     ioread16_rep(hw->iobase + off, buf, count);
0475 }
0476 
0477 static inline void hermes_write_bytes(struct hermes *hw, int off,
0478                       const char *buf, unsigned count)
0479 {
0480     off = off << hw->reg_spacing;
0481     iowrite16_rep(hw->iobase + off, buf, count >> 1);
0482     if (unlikely(count & 1))
0483         iowrite8(buf[count - 1], hw->iobase + off);
0484 }
0485 
0486 static inline void hermes_clear_words(struct hermes *hw, int off,
0487                       unsigned count)
0488 {
0489     unsigned i;
0490 
0491     off = off << hw->reg_spacing;
0492 
0493     for (i = 0; i < count; i++)
0494         iowrite16(0, hw->iobase + off);
0495 }
0496 
0497 #define HERMES_READ_RECORD(hw, bap, rid, buf) \
0498     (hw->ops->read_ltv((hw), (bap), (rid), sizeof(*buf), NULL, (buf)))
0499 #define HERMES_READ_RECORD_PR(hw, bap, rid, buf) \
0500     (hw->ops->read_ltv_pr((hw), (bap), (rid), sizeof(*buf), NULL, (buf)))
0501 #define HERMES_WRITE_RECORD(hw, bap, rid, buf) \
0502     (hw->ops->write_ltv((hw), (bap), (rid), \
0503                 HERMES_BYTES_TO_RECLEN(sizeof(*buf)), (buf)))
0504 
0505 static inline int hermes_read_wordrec(struct hermes *hw, int bap, u16 rid,
0506                       u16 *word)
0507 {
0508     __le16 rec;
0509     int err;
0510 
0511     err = HERMES_READ_RECORD(hw, bap, rid, &rec);
0512     *word = le16_to_cpu(rec);
0513     return err;
0514 }
0515 
0516 static inline int hermes_read_wordrec_pr(struct hermes *hw, int bap, u16 rid,
0517                      u16 *word)
0518 {
0519     __le16 rec;
0520     int err;
0521 
0522     err = HERMES_READ_RECORD_PR(hw, bap, rid, &rec);
0523     *word = le16_to_cpu(rec);
0524     return err;
0525 }
0526 
0527 static inline int hermes_write_wordrec(struct hermes *hw, int bap, u16 rid,
0528                        u16 word)
0529 {
0530     __le16 rec = cpu_to_le16(word);
0531     return HERMES_WRITE_RECORD(hw, bap, rid, &rec);
0532 }
0533 
0534 #endif  /* _HERMES_H */