Back to home page

OSCL-LXR

 
 

    


0001 /* hermes.c
0002  *
0003  * Driver core for the "Hermes" wireless MAC controller, as used in
0004  * the Lucent Orinoco and Cabletron RoamAbout cards. It should also
0005  * work on the hfa3841 and hfa3842 MAC controller chips used in the
0006  * Prism II chipsets.
0007  *
0008  * This is not a complete driver, just low-level access routines for
0009  * the MAC controller itself.
0010  *
0011  * Based on the prism2 driver from Absolute Value Systems' linux-wlan
0012  * project, the Linux wvlan_cs driver, Lucent's HCF-Light
0013  * (wvlan_hcf.c) library, and the NetBSD wireless driver (in no
0014  * particular order).
0015  *
0016  * Copyright (C) 2000, David Gibson, Linuxcare Australia.
0017  * (C) Copyright David Gibson, IBM Corp. 2001-2003.
0018  *
0019  * The contents of this file are subject to the Mozilla Public License
0020  * Version 1.1 (the "License"); you may not use this file except in
0021  * compliance with the License. You may obtain a copy of the License
0022  * at http://www.mozilla.org/MPL/
0023  *
0024  * Software distributed under the License is distributed on an "AS IS"
0025  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
0026  * the License for the specific language governing rights and
0027  * limitations under the License.
0028  *
0029  * Alternatively, the contents of this file may be used under the
0030  * terms of the GNU General Public License version 2 (the "GPL"), in
0031  * which case the provisions of the GPL are applicable instead of the
0032  * above.  If you wish to allow the use of your version of this file
0033  * only under the terms of the GPL and not to allow others to use your
0034  * version of this file under the MPL, indicate your decision by
0035  * deleting the provisions above and replace them with the notice and
0036  * other provisions required by the GPL.  If you do not delete the
0037  * provisions above, a recipient may use your version of this file
0038  * under either the MPL or the GPL.
0039  */
0040 
0041 #include <linux/module.h>
0042 #include <linux/kernel.h>
0043 #include <linux/delay.h>
0044 
0045 #include "hermes.h"
0046 
0047 /* These are maximum timeouts. Most often, card wil react much faster */
0048 #define CMD_BUSY_TIMEOUT (100) /* In iterations of ~1us */
0049 #define CMD_INIT_TIMEOUT (50000) /* in iterations of ~10us */
0050 #define CMD_COMPL_TIMEOUT (20000) /* in iterations of ~10us */
0051 #define ALLOC_COMPL_TIMEOUT (1000) /* in iterations of ~10us */
0052 
0053 /*
0054  * AUX port access.  To unlock the AUX port write the access keys to the
0055  * PARAM0-2 registers, then write HERMES_AUX_ENABLE to the HERMES_CONTROL
0056  * register.  Then read it and make sure it's HERMES_AUX_ENABLED.
0057  */
0058 #define HERMES_AUX_ENABLE   0x8000  /* Enable auxiliary port access */
0059 #define HERMES_AUX_DISABLE  0x4000  /* Disable to auxiliary port access */
0060 #define HERMES_AUX_ENABLED  0xC000  /* Auxiliary port is open */
0061 #define HERMES_AUX_DISABLED 0x0000  /* Auxiliary port is closed */
0062 
0063 #define HERMES_AUX_PW0  0xFE01
0064 #define HERMES_AUX_PW1  0xDC23
0065 #define HERMES_AUX_PW2  0xBA45
0066 
0067 /* HERMES_CMD_DOWNLD */
0068 #define HERMES_PROGRAM_DISABLE             (0x0000 | HERMES_CMD_DOWNLD)
0069 #define HERMES_PROGRAM_ENABLE_VOLATILE     (0x0100 | HERMES_CMD_DOWNLD)
0070 #define HERMES_PROGRAM_ENABLE_NON_VOLATILE (0x0200 | HERMES_CMD_DOWNLD)
0071 #define HERMES_PROGRAM_NON_VOLATILE        (0x0300 | HERMES_CMD_DOWNLD)
0072 
0073 /*
0074  * Debugging helpers
0075  */
0076 
0077 #define DMSG(stuff...) do {printk(KERN_DEBUG "hermes @ %p: " , hw->iobase); \
0078             printk(stuff); } while (0)
0079 
0080 #undef HERMES_DEBUG
0081 #ifdef HERMES_DEBUG
0082 
0083 #define DEBUG(lvl, stuff...) if ((lvl) <= HERMES_DEBUG) DMSG(stuff)
0084 
0085 #else /* ! HERMES_DEBUG */
0086 
0087 #define DEBUG(lvl, stuff...) do { } while (0)
0088 
0089 #endif /* ! HERMES_DEBUG */
0090 
0091 static const struct hermes_ops hermes_ops_local;
0092 
0093 /*
0094  * Internal functions
0095  */
0096 
0097 /* Issue a command to the chip. Waiting for it to complete is the caller's
0098    problem.
0099 
0100    Returns -EBUSY if the command register is busy, 0 on success.
0101 
0102    Callable from any context.
0103 */
0104 static int hermes_issue_cmd(struct hermes *hw, u16 cmd, u16 param0,
0105                 u16 param1, u16 param2)
0106 {
0107     int k = CMD_BUSY_TIMEOUT;
0108     u16 reg;
0109 
0110     /* First wait for the command register to unbusy */
0111     reg = hermes_read_regn(hw, CMD);
0112     while ((reg & HERMES_CMD_BUSY) && k) {
0113         k--;
0114         udelay(1);
0115         reg = hermes_read_regn(hw, CMD);
0116     }
0117     if (reg & HERMES_CMD_BUSY)
0118         return -EBUSY;
0119 
0120     hermes_write_regn(hw, PARAM2, param2);
0121     hermes_write_regn(hw, PARAM1, param1);
0122     hermes_write_regn(hw, PARAM0, param0);
0123     hermes_write_regn(hw, CMD, cmd);
0124 
0125     return 0;
0126 }
0127 
0128 /*
0129  * Function definitions
0130  */
0131 
0132 /* For doing cmds that wipe the magic constant in SWSUPPORT0 */
0133 static int hermes_doicmd_wait(struct hermes *hw, u16 cmd,
0134                   u16 parm0, u16 parm1, u16 parm2,
0135                   struct hermes_response *resp)
0136 {
0137     int err = 0;
0138     int k;
0139     u16 status, reg;
0140 
0141     err = hermes_issue_cmd(hw, cmd, parm0, parm1, parm2);
0142     if (err)
0143         return err;
0144 
0145     reg = hermes_read_regn(hw, EVSTAT);
0146     k = CMD_INIT_TIMEOUT;
0147     while ((!(reg & HERMES_EV_CMD)) && k) {
0148         k--;
0149         udelay(10);
0150         reg = hermes_read_regn(hw, EVSTAT);
0151     }
0152 
0153     hermes_write_regn(hw, SWSUPPORT0, HERMES_MAGIC);
0154 
0155     if (!hermes_present(hw)) {
0156         DEBUG(0, "hermes @ 0x%x: Card removed during reset.\n",
0157                hw->iobase);
0158         err = -ENODEV;
0159         goto out;
0160     }
0161 
0162     if (!(reg & HERMES_EV_CMD)) {
0163         printk(KERN_ERR "hermes @ %p: "
0164                "Timeout waiting for card to reset (reg=0x%04x)!\n",
0165                hw->iobase, reg);
0166         err = -ETIMEDOUT;
0167         goto out;
0168     }
0169 
0170     status = hermes_read_regn(hw, STATUS);
0171     if (resp) {
0172         resp->status = status;
0173         resp->resp0 = hermes_read_regn(hw, RESP0);
0174         resp->resp1 = hermes_read_regn(hw, RESP1);
0175         resp->resp2 = hermes_read_regn(hw, RESP2);
0176     }
0177 
0178     hermes_write_regn(hw, EVACK, HERMES_EV_CMD);
0179 
0180     if (status & HERMES_STATUS_RESULT)
0181         err = -EIO;
0182 out:
0183     return err;
0184 }
0185 
0186 void hermes_struct_init(struct hermes *hw, void __iomem *address,
0187             int reg_spacing)
0188 {
0189     hw->iobase = address;
0190     hw->reg_spacing = reg_spacing;
0191     hw->inten = 0x0;
0192     hw->eeprom_pda = false;
0193     hw->ops = &hermes_ops_local;
0194 }
0195 EXPORT_SYMBOL(hermes_struct_init);
0196 
0197 static int hermes_init(struct hermes *hw)
0198 {
0199     u16 reg;
0200     int err = 0;
0201     int k;
0202 
0203     /* We don't want to be interrupted while resetting the chipset */
0204     hw->inten = 0x0;
0205     hermes_write_regn(hw, INTEN, 0);
0206     hermes_write_regn(hw, EVACK, 0xffff);
0207 
0208     /* Normally it's a "can't happen" for the command register to
0209        be busy when we go to issue a command because we are
0210        serializing all commands.  However we want to have some
0211        chance of resetting the card even if it gets into a stupid
0212        state, so we actually wait to see if the command register
0213        will unbusy itself here. */
0214     k = CMD_BUSY_TIMEOUT;
0215     reg = hermes_read_regn(hw, CMD);
0216     while (k && (reg & HERMES_CMD_BUSY)) {
0217         if (reg == 0xffff) /* Special case - the card has probably been
0218                       removed, so don't wait for the timeout */
0219             return -ENODEV;
0220 
0221         k--;
0222         udelay(1);
0223         reg = hermes_read_regn(hw, CMD);
0224     }
0225 
0226     /* No need to explicitly handle the timeout - if we've timed
0227        out hermes_issue_cmd() will probably return -EBUSY below */
0228 
0229     /* According to the documentation, EVSTAT may contain
0230        obsolete event occurrence information.  We have to acknowledge
0231        it by writing EVACK. */
0232     reg = hermes_read_regn(hw, EVSTAT);
0233     hermes_write_regn(hw, EVACK, reg);
0234 
0235     /* We don't use hermes_docmd_wait here, because the reset wipes
0236        the magic constant in SWSUPPORT0 away, and it gets confused */
0237     err = hermes_doicmd_wait(hw, HERMES_CMD_INIT, 0, 0, 0, NULL);
0238 
0239     return err;
0240 }
0241 
0242 /* Issue a command to the chip, and (busy!) wait for it to
0243  * complete.
0244  *
0245  * Returns:
0246  *     < 0 on internal error
0247  *       0 on success
0248  *     > 0 on error returned by the firmware
0249  *
0250  * Callable from any context, but locking is your problem. */
0251 static int hermes_docmd_wait(struct hermes *hw, u16 cmd, u16 parm0,
0252                  struct hermes_response *resp)
0253 {
0254     int err;
0255     int k;
0256     u16 reg;
0257     u16 status;
0258 
0259     err = hermes_issue_cmd(hw, cmd, parm0, 0, 0);
0260     if (err) {
0261         if (!hermes_present(hw)) {
0262             if (net_ratelimit())
0263                 printk(KERN_WARNING "hermes @ %p: "
0264                        "Card removed while issuing command "
0265                        "0x%04x.\n", hw->iobase, cmd);
0266             err = -ENODEV;
0267         } else
0268             if (net_ratelimit())
0269                 printk(KERN_ERR "hermes @ %p: "
0270                        "Error %d issuing command 0x%04x.\n",
0271                        hw->iobase, err, cmd);
0272         goto out;
0273     }
0274 
0275     reg = hermes_read_regn(hw, EVSTAT);
0276     k = CMD_COMPL_TIMEOUT;
0277     while ((!(reg & HERMES_EV_CMD)) && k) {
0278         k--;
0279         udelay(10);
0280         reg = hermes_read_regn(hw, EVSTAT);
0281     }
0282 
0283     if (!hermes_present(hw)) {
0284         printk(KERN_WARNING "hermes @ %p: Card removed "
0285                "while waiting for command 0x%04x completion.\n",
0286                hw->iobase, cmd);
0287         err = -ENODEV;
0288         goto out;
0289     }
0290 
0291     if (!(reg & HERMES_EV_CMD)) {
0292         printk(KERN_ERR "hermes @ %p: Timeout waiting for "
0293                "command 0x%04x completion.\n", hw->iobase, cmd);
0294         err = -ETIMEDOUT;
0295         goto out;
0296     }
0297 
0298     status = hermes_read_regn(hw, STATUS);
0299     if (resp) {
0300         resp->status = status;
0301         resp->resp0 = hermes_read_regn(hw, RESP0);
0302         resp->resp1 = hermes_read_regn(hw, RESP1);
0303         resp->resp2 = hermes_read_regn(hw, RESP2);
0304     }
0305 
0306     hermes_write_regn(hw, EVACK, HERMES_EV_CMD);
0307 
0308     if (status & HERMES_STATUS_RESULT)
0309         err = -EIO;
0310 
0311  out:
0312     return err;
0313 }
0314 
0315 static int hermes_allocate(struct hermes *hw, u16 size, u16 *fid)
0316 {
0317     int err = 0;
0318     int k;
0319     u16 reg;
0320 
0321     if ((size < HERMES_ALLOC_LEN_MIN) || (size > HERMES_ALLOC_LEN_MAX))
0322         return -EINVAL;
0323 
0324     err = hermes_docmd_wait(hw, HERMES_CMD_ALLOC, size, NULL);
0325     if (err)
0326         return err;
0327 
0328     reg = hermes_read_regn(hw, EVSTAT);
0329     k = ALLOC_COMPL_TIMEOUT;
0330     while ((!(reg & HERMES_EV_ALLOC)) && k) {
0331         k--;
0332         udelay(10);
0333         reg = hermes_read_regn(hw, EVSTAT);
0334     }
0335 
0336     if (!hermes_present(hw)) {
0337         printk(KERN_WARNING "hermes @ %p: "
0338                "Card removed waiting for frame allocation.\n",
0339                hw->iobase);
0340         return -ENODEV;
0341     }
0342 
0343     if (!(reg & HERMES_EV_ALLOC)) {
0344         printk(KERN_ERR "hermes @ %p: "
0345                "Timeout waiting for frame allocation\n",
0346                hw->iobase);
0347         return -ETIMEDOUT;
0348     }
0349 
0350     *fid = hermes_read_regn(hw, ALLOCFID);
0351     hermes_write_regn(hw, EVACK, HERMES_EV_ALLOC);
0352 
0353     return 0;
0354 }
0355 
0356 /* Set up a BAP to read a particular chunk of data from card's internal buffer.
0357  *
0358  * Returns:
0359  *     < 0 on internal failure (errno)
0360  *       0 on success
0361  *     > 0 on error
0362  * from firmware
0363  *
0364  * Callable from any context */
0365 static int hermes_bap_seek(struct hermes *hw, int bap, u16 id, u16 offset)
0366 {
0367     int sreg = bap ? HERMES_SELECT1 : HERMES_SELECT0;
0368     int oreg = bap ? HERMES_OFFSET1 : HERMES_OFFSET0;
0369     int k;
0370     u16 reg;
0371 
0372     /* Paranoia.. */
0373     if ((offset > HERMES_BAP_OFFSET_MAX) || (offset % 2))
0374         return -EINVAL;
0375 
0376     k = HERMES_BAP_BUSY_TIMEOUT;
0377     reg = hermes_read_reg(hw, oreg);
0378     while ((reg & HERMES_OFFSET_BUSY) && k) {
0379         k--;
0380         udelay(1);
0381         reg = hermes_read_reg(hw, oreg);
0382     }
0383 
0384     if (reg & HERMES_OFFSET_BUSY)
0385         return -ETIMEDOUT;
0386 
0387     /* Now we actually set up the transfer */
0388     hermes_write_reg(hw, sreg, id);
0389     hermes_write_reg(hw, oreg, offset);
0390 
0391     /* Wait for the BAP to be ready */
0392     k = HERMES_BAP_BUSY_TIMEOUT;
0393     reg = hermes_read_reg(hw, oreg);
0394     while ((reg & (HERMES_OFFSET_BUSY | HERMES_OFFSET_ERR)) && k) {
0395         k--;
0396         udelay(1);
0397         reg = hermes_read_reg(hw, oreg);
0398     }
0399 
0400     if (reg != offset) {
0401         printk(KERN_ERR "hermes @ %p: BAP%d offset %s: "
0402                "reg=0x%x id=0x%x offset=0x%x\n", hw->iobase, bap,
0403                (reg & HERMES_OFFSET_BUSY) ? "timeout" : "error",
0404                reg, id, offset);
0405 
0406         if (reg & HERMES_OFFSET_BUSY)
0407             return -ETIMEDOUT;
0408 
0409         return -EIO;        /* error or wrong offset */
0410     }
0411 
0412     return 0;
0413 }
0414 
0415 /* Read a block of data from the chip's buffer, via the
0416  * BAP. Synchronization/serialization is the caller's problem.  len
0417  * must be even.
0418  *
0419  * Returns:
0420  *     < 0 on internal failure (errno)
0421  *       0 on success
0422  *     > 0 on error from firmware
0423  */
0424 static int hermes_bap_pread(struct hermes *hw, int bap, void *buf, int len,
0425                 u16 id, u16 offset)
0426 {
0427     int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
0428     int err = 0;
0429 
0430     if ((len < 0) || (len % 2))
0431         return -EINVAL;
0432 
0433     err = hermes_bap_seek(hw, bap, id, offset);
0434     if (err)
0435         goto out;
0436 
0437     /* Actually do the transfer */
0438     hermes_read_words(hw, dreg, buf, len / 2);
0439 
0440  out:
0441     return err;
0442 }
0443 
0444 /* Write a block of data to the chip's buffer, via the
0445  * BAP. Synchronization/serialization is the caller's problem.
0446  *
0447  * Returns:
0448  *     < 0 on internal failure (errno)
0449  *       0 on success
0450  *     > 0 on error from firmware
0451  */
0452 static int hermes_bap_pwrite(struct hermes *hw, int bap, const void *buf,
0453                  int len, u16 id, u16 offset)
0454 {
0455     int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
0456     int err = 0;
0457 
0458     if (len < 0)
0459         return -EINVAL;
0460 
0461     err = hermes_bap_seek(hw, bap, id, offset);
0462     if (err)
0463         goto out;
0464 
0465     /* Actually do the transfer */
0466     hermes_write_bytes(hw, dreg, buf, len);
0467 
0468  out:
0469     return err;
0470 }
0471 
0472 /* Read a Length-Type-Value record from the card.
0473  *
0474  * If length is NULL, we ignore the length read from the card, and
0475  * read the entire buffer regardless. This is useful because some of
0476  * the configuration records appear to have incorrect lengths in
0477  * practice.
0478  *
0479  * Callable from user or bh context.  */
0480 static int hermes_read_ltv(struct hermes *hw, int bap, u16 rid,
0481                unsigned bufsize, u16 *length, void *buf)
0482 {
0483     int err = 0;
0484     int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
0485     u16 rlength, rtype;
0486     unsigned nwords;
0487 
0488     if (bufsize % 2)
0489         return -EINVAL;
0490 
0491     err = hermes_docmd_wait(hw, HERMES_CMD_ACCESS, rid, NULL);
0492     if (err)
0493         return err;
0494 
0495     err = hermes_bap_seek(hw, bap, rid, 0);
0496     if (err)
0497         return err;
0498 
0499     rlength = hermes_read_reg(hw, dreg);
0500 
0501     if (!rlength)
0502         return -ENODATA;
0503 
0504     rtype = hermes_read_reg(hw, dreg);
0505 
0506     if (length)
0507         *length = rlength;
0508 
0509     if (rtype != rid)
0510         printk(KERN_WARNING "hermes @ %p: %s(): "
0511                "rid (0x%04x) does not match type (0x%04x)\n",
0512                hw->iobase, __func__, rid, rtype);
0513     if (HERMES_RECLEN_TO_BYTES(rlength) > bufsize)
0514         printk(KERN_WARNING "hermes @ %p: "
0515                "Truncating LTV record from %d to %d bytes. "
0516                "(rid=0x%04x, len=0x%04x)\n", hw->iobase,
0517                HERMES_RECLEN_TO_BYTES(rlength), bufsize, rid, rlength);
0518 
0519     nwords = min((unsigned)rlength - 1, bufsize / 2);
0520     hermes_read_words(hw, dreg, buf, nwords);
0521 
0522     return 0;
0523 }
0524 
0525 static int hermes_write_ltv(struct hermes *hw, int bap, u16 rid,
0526                 u16 length, const void *value)
0527 {
0528     int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
0529     int err = 0;
0530     unsigned count;
0531 
0532     if (length == 0)
0533         return -EINVAL;
0534 
0535     err = hermes_bap_seek(hw, bap, rid, 0);
0536     if (err)
0537         return err;
0538 
0539     hermes_write_reg(hw, dreg, length);
0540     hermes_write_reg(hw, dreg, rid);
0541 
0542     count = length - 1;
0543 
0544     hermes_write_bytes(hw, dreg, value, count << 1);
0545 
0546     err = hermes_docmd_wait(hw, HERMES_CMD_ACCESS | HERMES_CMD_WRITE,
0547                 rid, NULL);
0548 
0549     return err;
0550 }
0551 
0552 /*** Hermes AUX control ***/
0553 
0554 static inline void
0555 hermes_aux_setaddr(struct hermes *hw, u32 addr)
0556 {
0557     hermes_write_reg(hw, HERMES_AUXPAGE, (u16) (addr >> 7));
0558     hermes_write_reg(hw, HERMES_AUXOFFSET, (u16) (addr & 0x7F));
0559 }
0560 
0561 static inline int
0562 hermes_aux_control(struct hermes *hw, int enabled)
0563 {
0564     int desired_state = enabled ? HERMES_AUX_ENABLED : HERMES_AUX_DISABLED;
0565     int action = enabled ? HERMES_AUX_ENABLE : HERMES_AUX_DISABLE;
0566     int i;
0567 
0568     /* Already open? */
0569     if (hermes_read_reg(hw, HERMES_CONTROL) == desired_state)
0570         return 0;
0571 
0572     hermes_write_reg(hw, HERMES_PARAM0, HERMES_AUX_PW0);
0573     hermes_write_reg(hw, HERMES_PARAM1, HERMES_AUX_PW1);
0574     hermes_write_reg(hw, HERMES_PARAM2, HERMES_AUX_PW2);
0575     hermes_write_reg(hw, HERMES_CONTROL, action);
0576 
0577     for (i = 0; i < 20; i++) {
0578         udelay(10);
0579         if (hermes_read_reg(hw, HERMES_CONTROL) ==
0580             desired_state)
0581             return 0;
0582     }
0583 
0584     return -EBUSY;
0585 }
0586 
0587 /*** Hermes programming ***/
0588 
0589 /* About to start programming data (Hermes I)
0590  * offset is the entry point
0591  *
0592  * Spectrum_cs' Symbol fw does not require this
0593  * wl_lkm Agere fw does
0594  * Don't know about intersil
0595  */
0596 static int hermesi_program_init(struct hermes *hw, u32 offset)
0597 {
0598     int err;
0599 
0600     /* Disable interrupts?*/
0601     /*hw->inten = 0x0;*/
0602     /*hermes_write_regn(hw, INTEN, 0);*/
0603     /*hermes_set_irqmask(hw, 0);*/
0604 
0605     /* Acknowledge any outstanding command */
0606     hermes_write_regn(hw, EVACK, 0xFFFF);
0607 
0608     /* Using init_cmd_wait rather than cmd_wait */
0609     err = hw->ops->init_cmd_wait(hw,
0610                      0x0100 | HERMES_CMD_INIT,
0611                      0, 0, 0, NULL);
0612     if (err)
0613         return err;
0614 
0615     err = hw->ops->init_cmd_wait(hw,
0616                      0x0000 | HERMES_CMD_INIT,
0617                      0, 0, 0, NULL);
0618     if (err)
0619         return err;
0620 
0621     err = hermes_aux_control(hw, 1);
0622     pr_debug("AUX enable returned %d\n", err);
0623 
0624     if (err)
0625         return err;
0626 
0627     pr_debug("Enabling volatile, EP 0x%08x\n", offset);
0628     err = hw->ops->init_cmd_wait(hw,
0629                      HERMES_PROGRAM_ENABLE_VOLATILE,
0630                      offset & 0xFFFFu,
0631                      offset >> 16,
0632                      0,
0633                      NULL);
0634     pr_debug("PROGRAM_ENABLE returned %d\n", err);
0635 
0636     return err;
0637 }
0638 
0639 /* Done programming data (Hermes I)
0640  *
0641  * Spectrum_cs' Symbol fw does not require this
0642  * wl_lkm Agere fw does
0643  * Don't know about intersil
0644  */
0645 static int hermesi_program_end(struct hermes *hw)
0646 {
0647     struct hermes_response resp;
0648     int rc = 0;
0649     int err;
0650 
0651     rc = hw->ops->cmd_wait(hw, HERMES_PROGRAM_DISABLE, 0, &resp);
0652 
0653     pr_debug("PROGRAM_DISABLE returned %d, "
0654          "r0 0x%04x, r1 0x%04x, r2 0x%04x\n",
0655          rc, resp.resp0, resp.resp1, resp.resp2);
0656 
0657     if ((rc == 0) &&
0658         ((resp.status & HERMES_STATUS_CMDCODE) != HERMES_CMD_DOWNLD))
0659         rc = -EIO;
0660 
0661     err = hermes_aux_control(hw, 0);
0662     pr_debug("AUX disable returned %d\n", err);
0663 
0664     /* Acknowledge any outstanding command */
0665     hermes_write_regn(hw, EVACK, 0xFFFF);
0666 
0667     /* Reinitialise, ignoring return */
0668     (void) hw->ops->init_cmd_wait(hw, 0x0000 | HERMES_CMD_INIT,
0669                       0, 0, 0, NULL);
0670 
0671     return rc ? rc : err;
0672 }
0673 
0674 static int hermes_program_bytes(struct hermes *hw, const char *data,
0675                 u32 addr, u32 len)
0676 {
0677     /* wl lkm splits the programming into chunks of 2000 bytes.
0678      * This restriction appears to come from USB. The PCMCIA
0679      * adapters can program the whole lot in one go */
0680     hermes_aux_setaddr(hw, addr);
0681     hermes_write_bytes(hw, HERMES_AUXDATA, data, len);
0682     return 0;
0683 }
0684 
0685 /* Read PDA from the adapter */
0686 static int hermes_read_pda(struct hermes *hw, __le16 *pda, u32 pda_addr,
0687                u16 pda_len)
0688 {
0689     int ret;
0690     u16 pda_size;
0691     u16 data_len = pda_len;
0692     __le16 *data = pda;
0693 
0694     if (hw->eeprom_pda) {
0695         /* PDA of spectrum symbol is in eeprom */
0696 
0697         /* Issue command to read EEPROM */
0698         ret = hw->ops->cmd_wait(hw, HERMES_CMD_READMIF, 0, NULL);
0699         if (ret)
0700             return ret;
0701     } else {
0702         /* wl_lkm does not include PDA size in the PDA area.
0703          * We will pad the information into pda, so other routines
0704          * don't have to be modified */
0705         pda[0] = cpu_to_le16(pda_len - 2);
0706             /* Includes CFG_PROD_DATA but not itself */
0707         pda[1] = cpu_to_le16(0x0800); /* CFG_PROD_DATA */
0708         data_len = pda_len - 4;
0709         data = pda + 2;
0710     }
0711 
0712     /* Open auxiliary port */
0713     ret = hermes_aux_control(hw, 1);
0714     pr_debug("AUX enable returned %d\n", ret);
0715     if (ret)
0716         return ret;
0717 
0718     /* Read PDA */
0719     hermes_aux_setaddr(hw, pda_addr);
0720     hermes_read_words(hw, HERMES_AUXDATA, data, data_len / 2);
0721 
0722     /* Close aux port */
0723     ret = hermes_aux_control(hw, 0);
0724     pr_debug("AUX disable returned %d\n", ret);
0725 
0726     /* Check PDA length */
0727     pda_size = le16_to_cpu(pda[0]);
0728     pr_debug("Actual PDA length %d, Max allowed %d\n",
0729          pda_size, pda_len);
0730     if (pda_size > pda_len)
0731         return -EINVAL;
0732 
0733     return 0;
0734 }
0735 
0736 static void hermes_lock_irqsave(spinlock_t *lock,
0737                 unsigned long *flags) __acquires(lock)
0738 {
0739     spin_lock_irqsave(lock, *flags);
0740 }
0741 
0742 static void hermes_unlock_irqrestore(spinlock_t *lock,
0743                      unsigned long *flags) __releases(lock)
0744 {
0745     spin_unlock_irqrestore(lock, *flags);
0746 }
0747 
0748 static void hermes_lock_irq(spinlock_t *lock) __acquires(lock)
0749 {
0750     spin_lock_irq(lock);
0751 }
0752 
0753 static void hermes_unlock_irq(spinlock_t *lock) __releases(lock)
0754 {
0755     spin_unlock_irq(lock);
0756 }
0757 
0758 /* Hermes operations for local buses */
0759 static const struct hermes_ops hermes_ops_local = {
0760     .init = hermes_init,
0761     .cmd_wait = hermes_docmd_wait,
0762     .init_cmd_wait = hermes_doicmd_wait,
0763     .allocate = hermes_allocate,
0764     .read_ltv = hermes_read_ltv,
0765     .read_ltv_pr = hermes_read_ltv,
0766     .write_ltv = hermes_write_ltv,
0767     .bap_pread = hermes_bap_pread,
0768     .bap_pwrite = hermes_bap_pwrite,
0769     .read_pda = hermes_read_pda,
0770     .program_init = hermesi_program_init,
0771     .program_end = hermesi_program_end,
0772     .program = hermes_program_bytes,
0773     .lock_irqsave = hermes_lock_irqsave,
0774     .unlock_irqrestore = hermes_unlock_irqrestore,
0775     .lock_irq = hermes_lock_irq,
0776     .unlock_irq = hermes_unlock_irq,
0777 };