linux/drivers/net/wireless/intersil/orinoco/hermes.h
<<
>>
Prefs
   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 */
 535