hermes.c (20027B)
1/* hermes.c 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 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 (in no 14 * particular order). 15 * 16 * Copyright (C) 2000, David Gibson, Linuxcare Australia. 17 * (C) Copyright David Gibson, IBM Corp. 2001-2003. 18 * 19 * The contents of this file are subject to the Mozilla Public License 20 * Version 1.1 (the "License"); you may not use this file except in 21 * compliance with the License. You may obtain a copy of the License 22 * at http://www.mozilla.org/MPL/ 23 * 24 * Software distributed under the License is distributed on an "AS IS" 25 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 26 * the License for the specific language governing rights and 27 * limitations under the License. 28 * 29 * Alternatively, the contents of this file may be used under the 30 * terms of the GNU General Public License version 2 (the "GPL"), in 31 * which case the provisions of the GPL are applicable instead of the 32 * above. If you wish to allow the use of your version of this file 33 * only under the terms of the GPL and not to allow others to use your 34 * version of this file under the MPL, indicate your decision by 35 * deleting the provisions above and replace them with the notice and 36 * other provisions required by the GPL. If you do not delete the 37 * provisions above, a recipient may use your version of this file 38 * under either the MPL or the GPL. 39 */ 40 41#include <linux/module.h> 42#include <linux/kernel.h> 43#include <linux/delay.h> 44 45#include "hermes.h" 46 47/* These are maximum timeouts. Most often, card wil react much faster */ 48#define CMD_BUSY_TIMEOUT (100) /* In iterations of ~1us */ 49#define CMD_INIT_TIMEOUT (50000) /* in iterations of ~10us */ 50#define CMD_COMPL_TIMEOUT (20000) /* in iterations of ~10us */ 51#define ALLOC_COMPL_TIMEOUT (1000) /* in iterations of ~10us */ 52 53/* 54 * AUX port access. To unlock the AUX port write the access keys to the 55 * PARAM0-2 registers, then write HERMES_AUX_ENABLE to the HERMES_CONTROL 56 * register. Then read it and make sure it's HERMES_AUX_ENABLED. 57 */ 58#define HERMES_AUX_ENABLE 0x8000 /* Enable auxiliary port access */ 59#define HERMES_AUX_DISABLE 0x4000 /* Disable to auxiliary port access */ 60#define HERMES_AUX_ENABLED 0xC000 /* Auxiliary port is open */ 61#define HERMES_AUX_DISABLED 0x0000 /* Auxiliary port is closed */ 62 63#define HERMES_AUX_PW0 0xFE01 64#define HERMES_AUX_PW1 0xDC23 65#define HERMES_AUX_PW2 0xBA45 66 67/* HERMES_CMD_DOWNLD */ 68#define HERMES_PROGRAM_DISABLE (0x0000 | HERMES_CMD_DOWNLD) 69#define HERMES_PROGRAM_ENABLE_VOLATILE (0x0100 | HERMES_CMD_DOWNLD) 70#define HERMES_PROGRAM_ENABLE_NON_VOLATILE (0x0200 | HERMES_CMD_DOWNLD) 71#define HERMES_PROGRAM_NON_VOLATILE (0x0300 | HERMES_CMD_DOWNLD) 72 73/* 74 * Debugging helpers 75 */ 76 77#define DMSG(stuff...) do {printk(KERN_DEBUG "hermes @ %p: " , hw->iobase); \ 78 printk(stuff); } while (0) 79 80#undef HERMES_DEBUG 81#ifdef HERMES_DEBUG 82 83#define DEBUG(lvl, stuff...) if ((lvl) <= HERMES_DEBUG) DMSG(stuff) 84 85#else /* ! HERMES_DEBUG */ 86 87#define DEBUG(lvl, stuff...) do { } while (0) 88 89#endif /* ! HERMES_DEBUG */ 90 91static const struct hermes_ops hermes_ops_local; 92 93/* 94 * Internal functions 95 */ 96 97/* Issue a command to the chip. Waiting for it to complete is the caller's 98 problem. 99 100 Returns -EBUSY if the command register is busy, 0 on success. 101 102 Callable from any context. 103*/ 104static int hermes_issue_cmd(struct hermes *hw, u16 cmd, u16 param0, 105 u16 param1, u16 param2) 106{ 107 int k = CMD_BUSY_TIMEOUT; 108 u16 reg; 109 110 /* First wait for the command register to unbusy */ 111 reg = hermes_read_regn(hw, CMD); 112 while ((reg & HERMES_CMD_BUSY) && k) { 113 k--; 114 udelay(1); 115 reg = hermes_read_regn(hw, CMD); 116 } 117 if (reg & HERMES_CMD_BUSY) 118 return -EBUSY; 119 120 hermes_write_regn(hw, PARAM2, param2); 121 hermes_write_regn(hw, PARAM1, param1); 122 hermes_write_regn(hw, PARAM0, param0); 123 hermes_write_regn(hw, CMD, cmd); 124 125 return 0; 126} 127 128/* 129 * Function definitions 130 */ 131 132/* For doing cmds that wipe the magic constant in SWSUPPORT0 */ 133static int hermes_doicmd_wait(struct hermes *hw, u16 cmd, 134 u16 parm0, u16 parm1, u16 parm2, 135 struct hermes_response *resp) 136{ 137 int err = 0; 138 int k; 139 u16 status, reg; 140 141 err = hermes_issue_cmd(hw, cmd, parm0, parm1, parm2); 142 if (err) 143 return err; 144 145 reg = hermes_read_regn(hw, EVSTAT); 146 k = CMD_INIT_TIMEOUT; 147 while ((!(reg & HERMES_EV_CMD)) && k) { 148 k--; 149 udelay(10); 150 reg = hermes_read_regn(hw, EVSTAT); 151 } 152 153 hermes_write_regn(hw, SWSUPPORT0, HERMES_MAGIC); 154 155 if (!hermes_present(hw)) { 156 DEBUG(0, "hermes @ 0x%x: Card removed during reset.\n", 157 hw->iobase); 158 err = -ENODEV; 159 goto out; 160 } 161 162 if (!(reg & HERMES_EV_CMD)) { 163 printk(KERN_ERR "hermes @ %p: " 164 "Timeout waiting for card to reset (reg=0x%04x)!\n", 165 hw->iobase, reg); 166 err = -ETIMEDOUT; 167 goto out; 168 } 169 170 status = hermes_read_regn(hw, STATUS); 171 if (resp) { 172 resp->status = status; 173 resp->resp0 = hermes_read_regn(hw, RESP0); 174 resp->resp1 = hermes_read_regn(hw, RESP1); 175 resp->resp2 = hermes_read_regn(hw, RESP2); 176 } 177 178 hermes_write_regn(hw, EVACK, HERMES_EV_CMD); 179 180 if (status & HERMES_STATUS_RESULT) 181 err = -EIO; 182out: 183 return err; 184} 185 186void hermes_struct_init(struct hermes *hw, void __iomem *address, 187 int reg_spacing) 188{ 189 hw->iobase = address; 190 hw->reg_spacing = reg_spacing; 191 hw->inten = 0x0; 192 hw->eeprom_pda = false; 193 hw->ops = &hermes_ops_local; 194} 195EXPORT_SYMBOL(hermes_struct_init); 196 197static int hermes_init(struct hermes *hw) 198{ 199 u16 reg; 200 int err = 0; 201 int k; 202 203 /* We don't want to be interrupted while resetting the chipset */ 204 hw->inten = 0x0; 205 hermes_write_regn(hw, INTEN, 0); 206 hermes_write_regn(hw, EVACK, 0xffff); 207 208 /* Normally it's a "can't happen" for the command register to 209 be busy when we go to issue a command because we are 210 serializing all commands. However we want to have some 211 chance of resetting the card even if it gets into a stupid 212 state, so we actually wait to see if the command register 213 will unbusy itself here. */ 214 k = CMD_BUSY_TIMEOUT; 215 reg = hermes_read_regn(hw, CMD); 216 while (k && (reg & HERMES_CMD_BUSY)) { 217 if (reg == 0xffff) /* Special case - the card has probably been 218 removed, so don't wait for the timeout */ 219 return -ENODEV; 220 221 k--; 222 udelay(1); 223 reg = hermes_read_regn(hw, CMD); 224 } 225 226 /* No need to explicitly handle the timeout - if we've timed 227 out hermes_issue_cmd() will probably return -EBUSY below */ 228 229 /* According to the documentation, EVSTAT may contain 230 obsolete event occurrence information. We have to acknowledge 231 it by writing EVACK. */ 232 reg = hermes_read_regn(hw, EVSTAT); 233 hermes_write_regn(hw, EVACK, reg); 234 235 /* We don't use hermes_docmd_wait here, because the reset wipes 236 the magic constant in SWSUPPORT0 away, and it gets confused */ 237 err = hermes_doicmd_wait(hw, HERMES_CMD_INIT, 0, 0, 0, NULL); 238 239 return err; 240} 241 242/* Issue a command to the chip, and (busy!) wait for it to 243 * complete. 244 * 245 * Returns: 246 * < 0 on internal error 247 * 0 on success 248 * > 0 on error returned by the firmware 249 * 250 * Callable from any context, but locking is your problem. */ 251static int hermes_docmd_wait(struct hermes *hw, u16 cmd, u16 parm0, 252 struct hermes_response *resp) 253{ 254 int err; 255 int k; 256 u16 reg; 257 u16 status; 258 259 err = hermes_issue_cmd(hw, cmd, parm0, 0, 0); 260 if (err) { 261 if (!hermes_present(hw)) { 262 if (net_ratelimit()) 263 printk(KERN_WARNING "hermes @ %p: " 264 "Card removed while issuing command " 265 "0x%04x.\n", hw->iobase, cmd); 266 err = -ENODEV; 267 } else 268 if (net_ratelimit()) 269 printk(KERN_ERR "hermes @ %p: " 270 "Error %d issuing command 0x%04x.\n", 271 hw->iobase, err, cmd); 272 goto out; 273 } 274 275 reg = hermes_read_regn(hw, EVSTAT); 276 k = CMD_COMPL_TIMEOUT; 277 while ((!(reg & HERMES_EV_CMD)) && k) { 278 k--; 279 udelay(10); 280 reg = hermes_read_regn(hw, EVSTAT); 281 } 282 283 if (!hermes_present(hw)) { 284 printk(KERN_WARNING "hermes @ %p: Card removed " 285 "while waiting for command 0x%04x completion.\n", 286 hw->iobase, cmd); 287 err = -ENODEV; 288 goto out; 289 } 290 291 if (!(reg & HERMES_EV_CMD)) { 292 printk(KERN_ERR "hermes @ %p: Timeout waiting for " 293 "command 0x%04x completion.\n", hw->iobase, cmd); 294 err = -ETIMEDOUT; 295 goto out; 296 } 297 298 status = hermes_read_regn(hw, STATUS); 299 if (resp) { 300 resp->status = status; 301 resp->resp0 = hermes_read_regn(hw, RESP0); 302 resp->resp1 = hermes_read_regn(hw, RESP1); 303 resp->resp2 = hermes_read_regn(hw, RESP2); 304 } 305 306 hermes_write_regn(hw, EVACK, HERMES_EV_CMD); 307 308 if (status & HERMES_STATUS_RESULT) 309 err = -EIO; 310 311 out: 312 return err; 313} 314 315static int hermes_allocate(struct hermes *hw, u16 size, u16 *fid) 316{ 317 int err = 0; 318 int k; 319 u16 reg; 320 321 if ((size < HERMES_ALLOC_LEN_MIN) || (size > HERMES_ALLOC_LEN_MAX)) 322 return -EINVAL; 323 324 err = hermes_docmd_wait(hw, HERMES_CMD_ALLOC, size, NULL); 325 if (err) 326 return err; 327 328 reg = hermes_read_regn(hw, EVSTAT); 329 k = ALLOC_COMPL_TIMEOUT; 330 while ((!(reg & HERMES_EV_ALLOC)) && k) { 331 k--; 332 udelay(10); 333 reg = hermes_read_regn(hw, EVSTAT); 334 } 335 336 if (!hermes_present(hw)) { 337 printk(KERN_WARNING "hermes @ %p: " 338 "Card removed waiting for frame allocation.\n", 339 hw->iobase); 340 return -ENODEV; 341 } 342 343 if (!(reg & HERMES_EV_ALLOC)) { 344 printk(KERN_ERR "hermes @ %p: " 345 "Timeout waiting for frame allocation\n", 346 hw->iobase); 347 return -ETIMEDOUT; 348 } 349 350 *fid = hermes_read_regn(hw, ALLOCFID); 351 hermes_write_regn(hw, EVACK, HERMES_EV_ALLOC); 352 353 return 0; 354} 355 356/* Set up a BAP to read a particular chunk of data from card's internal buffer. 357 * 358 * Returns: 359 * < 0 on internal failure (errno) 360 * 0 on success 361 * > 0 on error 362 * from firmware 363 * 364 * Callable from any context */ 365static int hermes_bap_seek(struct hermes *hw, int bap, u16 id, u16 offset) 366{ 367 int sreg = bap ? HERMES_SELECT1 : HERMES_SELECT0; 368 int oreg = bap ? HERMES_OFFSET1 : HERMES_OFFSET0; 369 int k; 370 u16 reg; 371 372 /* Paranoia.. */ 373 if ((offset > HERMES_BAP_OFFSET_MAX) || (offset % 2)) 374 return -EINVAL; 375 376 k = HERMES_BAP_BUSY_TIMEOUT; 377 reg = hermes_read_reg(hw, oreg); 378 while ((reg & HERMES_OFFSET_BUSY) && k) { 379 k--; 380 udelay(1); 381 reg = hermes_read_reg(hw, oreg); 382 } 383 384 if (reg & HERMES_OFFSET_BUSY) 385 return -ETIMEDOUT; 386 387 /* Now we actually set up the transfer */ 388 hermes_write_reg(hw, sreg, id); 389 hermes_write_reg(hw, oreg, offset); 390 391 /* Wait for the BAP to be ready */ 392 k = HERMES_BAP_BUSY_TIMEOUT; 393 reg = hermes_read_reg(hw, oreg); 394 while ((reg & (HERMES_OFFSET_BUSY | HERMES_OFFSET_ERR)) && k) { 395 k--; 396 udelay(1); 397 reg = hermes_read_reg(hw, oreg); 398 } 399 400 if (reg != offset) { 401 printk(KERN_ERR "hermes @ %p: BAP%d offset %s: " 402 "reg=0x%x id=0x%x offset=0x%x\n", hw->iobase, bap, 403 (reg & HERMES_OFFSET_BUSY) ? "timeout" : "error", 404 reg, id, offset); 405 406 if (reg & HERMES_OFFSET_BUSY) 407 return -ETIMEDOUT; 408 409 return -EIO; /* error or wrong offset */ 410 } 411 412 return 0; 413} 414 415/* Read a block of data from the chip's buffer, via the 416 * BAP. Synchronization/serialization is the caller's problem. len 417 * must be even. 418 * 419 * Returns: 420 * < 0 on internal failure (errno) 421 * 0 on success 422 * > 0 on error from firmware 423 */ 424static int hermes_bap_pread(struct hermes *hw, int bap, void *buf, int len, 425 u16 id, u16 offset) 426{ 427 int dreg = bap ? HERMES_DATA1 : HERMES_DATA0; 428 int err = 0; 429 430 if ((len < 0) || (len % 2)) 431 return -EINVAL; 432 433 err = hermes_bap_seek(hw, bap, id, offset); 434 if (err) 435 goto out; 436 437 /* Actually do the transfer */ 438 hermes_read_words(hw, dreg, buf, len / 2); 439 440 out: 441 return err; 442} 443 444/* Write a block of data to the chip's buffer, via the 445 * BAP. Synchronization/serialization is the caller's problem. 446 * 447 * Returns: 448 * < 0 on internal failure (errno) 449 * 0 on success 450 * > 0 on error from firmware 451 */ 452static int hermes_bap_pwrite(struct hermes *hw, int bap, const void *buf, 453 int len, u16 id, u16 offset) 454{ 455 int dreg = bap ? HERMES_DATA1 : HERMES_DATA0; 456 int err = 0; 457 458 if (len < 0) 459 return -EINVAL; 460 461 err = hermes_bap_seek(hw, bap, id, offset); 462 if (err) 463 goto out; 464 465 /* Actually do the transfer */ 466 hermes_write_bytes(hw, dreg, buf, len); 467 468 out: 469 return err; 470} 471 472/* Read a Length-Type-Value record from the card. 473 * 474 * If length is NULL, we ignore the length read from the card, and 475 * read the entire buffer regardless. This is useful because some of 476 * the configuration records appear to have incorrect lengths in 477 * practice. 478 * 479 * Callable from user or bh context. */ 480static int hermes_read_ltv(struct hermes *hw, int bap, u16 rid, 481 unsigned bufsize, u16 *length, void *buf) 482{ 483 int err = 0; 484 int dreg = bap ? HERMES_DATA1 : HERMES_DATA0; 485 u16 rlength, rtype; 486 unsigned nwords; 487 488 if (bufsize % 2) 489 return -EINVAL; 490 491 err = hermes_docmd_wait(hw, HERMES_CMD_ACCESS, rid, NULL); 492 if (err) 493 return err; 494 495 err = hermes_bap_seek(hw, bap, rid, 0); 496 if (err) 497 return err; 498 499 rlength = hermes_read_reg(hw, dreg); 500 501 if (!rlength) 502 return -ENODATA; 503 504 rtype = hermes_read_reg(hw, dreg); 505 506 if (length) 507 *length = rlength; 508 509 if (rtype != rid) 510 printk(KERN_WARNING "hermes @ %p: %s(): " 511 "rid (0x%04x) does not match type (0x%04x)\n", 512 hw->iobase, __func__, rid, rtype); 513 if (HERMES_RECLEN_TO_BYTES(rlength) > bufsize) 514 printk(KERN_WARNING "hermes @ %p: " 515 "Truncating LTV record from %d to %d bytes. " 516 "(rid=0x%04x, len=0x%04x)\n", hw->iobase, 517 HERMES_RECLEN_TO_BYTES(rlength), bufsize, rid, rlength); 518 519 nwords = min((unsigned)rlength - 1, bufsize / 2); 520 hermes_read_words(hw, dreg, buf, nwords); 521 522 return 0; 523} 524 525static int hermes_write_ltv(struct hermes *hw, int bap, u16 rid, 526 u16 length, const void *value) 527{ 528 int dreg = bap ? HERMES_DATA1 : HERMES_DATA0; 529 int err = 0; 530 unsigned count; 531 532 if (length == 0) 533 return -EINVAL; 534 535 err = hermes_bap_seek(hw, bap, rid, 0); 536 if (err) 537 return err; 538 539 hermes_write_reg(hw, dreg, length); 540 hermes_write_reg(hw, dreg, rid); 541 542 count = length - 1; 543 544 hermes_write_bytes(hw, dreg, value, count << 1); 545 546 err = hermes_docmd_wait(hw, HERMES_CMD_ACCESS | HERMES_CMD_WRITE, 547 rid, NULL); 548 549 return err; 550} 551 552/*** Hermes AUX control ***/ 553 554static inline void 555hermes_aux_setaddr(struct hermes *hw, u32 addr) 556{ 557 hermes_write_reg(hw, HERMES_AUXPAGE, (u16) (addr >> 7)); 558 hermes_write_reg(hw, HERMES_AUXOFFSET, (u16) (addr & 0x7F)); 559} 560 561static inline int 562hermes_aux_control(struct hermes *hw, int enabled) 563{ 564 int desired_state = enabled ? HERMES_AUX_ENABLED : HERMES_AUX_DISABLED; 565 int action = enabled ? HERMES_AUX_ENABLE : HERMES_AUX_DISABLE; 566 int i; 567 568 /* Already open? */ 569 if (hermes_read_reg(hw, HERMES_CONTROL) == desired_state) 570 return 0; 571 572 hermes_write_reg(hw, HERMES_PARAM0, HERMES_AUX_PW0); 573 hermes_write_reg(hw, HERMES_PARAM1, HERMES_AUX_PW1); 574 hermes_write_reg(hw, HERMES_PARAM2, HERMES_AUX_PW2); 575 hermes_write_reg(hw, HERMES_CONTROL, action); 576 577 for (i = 0; i < 20; i++) { 578 udelay(10); 579 if (hermes_read_reg(hw, HERMES_CONTROL) == 580 desired_state) 581 return 0; 582 } 583 584 return -EBUSY; 585} 586 587/*** Hermes programming ***/ 588 589/* About to start programming data (Hermes I) 590 * offset is the entry point 591 * 592 * Spectrum_cs' Symbol fw does not require this 593 * wl_lkm Agere fw does 594 * Don't know about intersil 595 */ 596static int hermesi_program_init(struct hermes *hw, u32 offset) 597{ 598 int err; 599 600 /* Disable interrupts?*/ 601 /*hw->inten = 0x0;*/ 602 /*hermes_write_regn(hw, INTEN, 0);*/ 603 /*hermes_set_irqmask(hw, 0);*/ 604 605 /* Acknowledge any outstanding command */ 606 hermes_write_regn(hw, EVACK, 0xFFFF); 607 608 /* Using init_cmd_wait rather than cmd_wait */ 609 err = hw->ops->init_cmd_wait(hw, 610 0x0100 | HERMES_CMD_INIT, 611 0, 0, 0, NULL); 612 if (err) 613 return err; 614 615 err = hw->ops->init_cmd_wait(hw, 616 0x0000 | HERMES_CMD_INIT, 617 0, 0, 0, NULL); 618 if (err) 619 return err; 620 621 err = hermes_aux_control(hw, 1); 622 pr_debug("AUX enable returned %d\n", err); 623 624 if (err) 625 return err; 626 627 pr_debug("Enabling volatile, EP 0x%08x\n", offset); 628 err = hw->ops->init_cmd_wait(hw, 629 HERMES_PROGRAM_ENABLE_VOLATILE, 630 offset & 0xFFFFu, 631 offset >> 16, 632 0, 633 NULL); 634 pr_debug("PROGRAM_ENABLE returned %d\n", err); 635 636 return err; 637} 638 639/* Done programming data (Hermes I) 640 * 641 * Spectrum_cs' Symbol fw does not require this 642 * wl_lkm Agere fw does 643 * Don't know about intersil 644 */ 645static int hermesi_program_end(struct hermes *hw) 646{ 647 struct hermes_response resp; 648 int rc = 0; 649 int err; 650 651 rc = hw->ops->cmd_wait(hw, HERMES_PROGRAM_DISABLE, 0, &resp); 652 653 pr_debug("PROGRAM_DISABLE returned %d, " 654 "r0 0x%04x, r1 0x%04x, r2 0x%04x\n", 655 rc, resp.resp0, resp.resp1, resp.resp2); 656 657 if ((rc == 0) && 658 ((resp.status & HERMES_STATUS_CMDCODE) != HERMES_CMD_DOWNLD)) 659 rc = -EIO; 660 661 err = hermes_aux_control(hw, 0); 662 pr_debug("AUX disable returned %d\n", err); 663 664 /* Acknowledge any outstanding command */ 665 hermes_write_regn(hw, EVACK, 0xFFFF); 666 667 /* Reinitialise, ignoring return */ 668 (void) hw->ops->init_cmd_wait(hw, 0x0000 | HERMES_CMD_INIT, 669 0, 0, 0, NULL); 670 671 return rc ? rc : err; 672} 673 674static int hermes_program_bytes(struct hermes *hw, const char *data, 675 u32 addr, u32 len) 676{ 677 /* wl lkm splits the programming into chunks of 2000 bytes. 678 * This restriction appears to come from USB. The PCMCIA 679 * adapters can program the whole lot in one go */ 680 hermes_aux_setaddr(hw, addr); 681 hermes_write_bytes(hw, HERMES_AUXDATA, data, len); 682 return 0; 683} 684 685/* Read PDA from the adapter */ 686static int hermes_read_pda(struct hermes *hw, __le16 *pda, u32 pda_addr, 687 u16 pda_len) 688{ 689 int ret; 690 u16 pda_size; 691 u16 data_len = pda_len; 692 __le16 *data = pda; 693 694 if (hw->eeprom_pda) { 695 /* PDA of spectrum symbol is in eeprom */ 696 697 /* Issue command to read EEPROM */ 698 ret = hw->ops->cmd_wait(hw, HERMES_CMD_READMIF, 0, NULL); 699 if (ret) 700 return ret; 701 } else { 702 /* wl_lkm does not include PDA size in the PDA area. 703 * We will pad the information into pda, so other routines 704 * don't have to be modified */ 705 pda[0] = cpu_to_le16(pda_len - 2); 706 /* Includes CFG_PROD_DATA but not itself */ 707 pda[1] = cpu_to_le16(0x0800); /* CFG_PROD_DATA */ 708 data_len = pda_len - 4; 709 data = pda + 2; 710 } 711 712 /* Open auxiliary port */ 713 ret = hermes_aux_control(hw, 1); 714 pr_debug("AUX enable returned %d\n", ret); 715 if (ret) 716 return ret; 717 718 /* Read PDA */ 719 hermes_aux_setaddr(hw, pda_addr); 720 hermes_read_words(hw, HERMES_AUXDATA, data, data_len / 2); 721 722 /* Close aux port */ 723 ret = hermes_aux_control(hw, 0); 724 pr_debug("AUX disable returned %d\n", ret); 725 726 /* Check PDA length */ 727 pda_size = le16_to_cpu(pda[0]); 728 pr_debug("Actual PDA length %d, Max allowed %d\n", 729 pda_size, pda_len); 730 if (pda_size > pda_len) 731 return -EINVAL; 732 733 return 0; 734} 735 736static void hermes_lock_irqsave(spinlock_t *lock, 737 unsigned long *flags) __acquires(lock) 738{ 739 spin_lock_irqsave(lock, *flags); 740} 741 742static void hermes_unlock_irqrestore(spinlock_t *lock, 743 unsigned long *flags) __releases(lock) 744{ 745 spin_unlock_irqrestore(lock, *flags); 746} 747 748static void hermes_lock_irq(spinlock_t *lock) __acquires(lock) 749{ 750 spin_lock_irq(lock); 751} 752 753static void hermes_unlock_irq(spinlock_t *lock) __releases(lock) 754{ 755 spin_unlock_irq(lock); 756} 757 758/* Hermes operations for local buses */ 759static const struct hermes_ops hermes_ops_local = { 760 .init = hermes_init, 761 .cmd_wait = hermes_docmd_wait, 762 .init_cmd_wait = hermes_doicmd_wait, 763 .allocate = hermes_allocate, 764 .read_ltv = hermes_read_ltv, 765 .read_ltv_pr = hermes_read_ltv, 766 .write_ltv = hermes_write_ltv, 767 .bap_pread = hermes_bap_pread, 768 .bap_pwrite = hermes_bap_pwrite, 769 .read_pda = hermes_read_pda, 770 .program_init = hermesi_program_init, 771 .program_end = hermesi_program_end, 772 .program = hermes_program_bytes, 773 .lock_irqsave = hermes_lock_irqsave, 774 .unlock_irqrestore = hermes_unlock_irqrestore, 775 .lock_irq = hermes_lock_irq, 776 .unlock_irq = hermes_unlock_irq, 777};