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