Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v2.6.17-rc4 969 lines 27 kB view raw
1/* 2 * Driver for 802.11b cards using RAM-loadable Symbol firmware, such as 3 * Symbol Wireless Networker LA4100, CompactFlash cards by Socket 4 * Communications and Intel PRO/Wireless 2011B. 5 * 6 * The driver implements Symbol firmware download. The rest is handled 7 * in hermes.c and orinoco.c. 8 * 9 * Utilities for downloading the Symbol firmware are available at 10 * http://sourceforge.net/projects/orinoco/ 11 * 12 * Copyright (C) 2002-2005 Pavel Roskin <proski@gnu.org> 13 * Portions based on orinoco_cs.c: 14 * Copyright (C) David Gibson, Linuxcare Australia 15 * Portions based on Spectrum24tDnld.c from original spectrum24 driver: 16 * Copyright (C) Symbol Technologies. 17 * 18 * See copyright notice in file orinoco.c. 19 */ 20 21#define DRIVER_NAME "spectrum_cs" 22#define PFX DRIVER_NAME ": " 23 24#include <linux/config.h> 25#include <linux/module.h> 26#include <linux/kernel.h> 27#include <linux/init.h> 28#include <linux/delay.h> 29#include <linux/firmware.h> 30#include <pcmcia/cs_types.h> 31#include <pcmcia/cs.h> 32#include <pcmcia/cistpl.h> 33#include <pcmcia/cisreg.h> 34#include <pcmcia/ds.h> 35 36#include "orinoco.h" 37 38static unsigned char *primsym; 39static unsigned char *secsym; 40static const char primary_fw_name[] = "symbol_sp24t_prim_fw"; 41static const char secondary_fw_name[] = "symbol_sp24t_sec_fw"; 42 43/********************************************************************/ 44/* Module stuff */ 45/********************************************************************/ 46 47MODULE_AUTHOR("Pavel Roskin <proski@gnu.org>"); 48MODULE_DESCRIPTION("Driver for Symbol Spectrum24 Trilogy cards with firmware downloader"); 49MODULE_LICENSE("Dual MPL/GPL"); 50 51/* Module parameters */ 52 53/* Some D-Link cards have buggy CIS. They do work at 5v properly, but 54 * don't have any CIS entry for it. This workaround it... */ 55static int ignore_cis_vcc; /* = 0 */ 56module_param(ignore_cis_vcc, int, 0); 57MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket"); 58 59/********************************************************************/ 60/* Data structures */ 61/********************************************************************/ 62 63/* PCMCIA specific device information (goes in the card field of 64 * struct orinoco_private */ 65struct orinoco_pccard { 66 struct pcmcia_device *p_dev; 67 dev_node_t node; 68}; 69 70/********************************************************************/ 71/* Function prototypes */ 72/********************************************************************/ 73 74static int spectrum_cs_config(struct pcmcia_device *link); 75static void spectrum_cs_release(struct pcmcia_device *link); 76 77/********************************************************************/ 78/* Firmware downloader */ 79/********************************************************************/ 80 81/* Position of PDA in the adapter memory */ 82#define EEPROM_ADDR 0x3000 83#define EEPROM_LEN 0x200 84#define PDA_OFFSET 0x100 85 86#define PDA_ADDR (EEPROM_ADDR + PDA_OFFSET) 87#define PDA_WORDS ((EEPROM_LEN - PDA_OFFSET) / 2) 88 89/* Constants for the CISREG_CCSR register */ 90#define HCR_RUN 0x07 /* run firmware after reset */ 91#define HCR_IDLE 0x0E /* don't run firmware after reset */ 92#define HCR_MEM16 0x10 /* memory width bit, should be preserved */ 93 94/* 95 * AUX port access. To unlock the AUX port write the access keys to the 96 * PARAM0-2 registers, then write HERMES_AUX_ENABLE to the HERMES_CONTROL 97 * register. Then read it and make sure it's HERMES_AUX_ENABLED. 98 */ 99#define HERMES_AUX_ENABLE 0x8000 /* Enable auxiliary port access */ 100#define HERMES_AUX_DISABLE 0x4000 /* Disable to auxiliary port access */ 101#define HERMES_AUX_ENABLED 0xC000 /* Auxiliary port is open */ 102 103#define HERMES_AUX_PW0 0xFE01 104#define HERMES_AUX_PW1 0xDC23 105#define HERMES_AUX_PW2 0xBA45 106 107/* End markers */ 108#define PDI_END 0x00000000 /* End of PDA */ 109#define BLOCK_END 0xFFFFFFFF /* Last image block */ 110#define TEXT_END 0x1A /* End of text header */ 111 112/* 113 * The following structures have little-endian fields denoted by 114 * the leading underscore. Don't access them directly - use inline 115 * functions defined below. 116 */ 117 118/* 119 * The binary image to be downloaded consists of series of data blocks. 120 * Each block has the following structure. 121 */ 122struct dblock { 123 __le32 _addr; /* adapter address where to write the block */ 124 __le16 _len; /* length of the data only, in bytes */ 125 char data[0]; /* data to be written */ 126} __attribute__ ((packed)); 127 128/* 129 * Plug Data References are located in in the image after the last data 130 * block. They refer to areas in the adapter memory where the plug data 131 * items with matching ID should be written. 132 */ 133struct pdr { 134 __le32 _id; /* record ID */ 135 __le32 _addr; /* adapter address where to write the data */ 136 __le32 _len; /* expected length of the data, in bytes */ 137 char next[0]; /* next PDR starts here */ 138} __attribute__ ((packed)); 139 140 141/* 142 * Plug Data Items are located in the EEPROM read from the adapter by 143 * primary firmware. They refer to the device-specific data that should 144 * be plugged into the secondary firmware. 145 */ 146struct pdi { 147 __le16 _len; /* length of ID and data, in words */ 148 __le16 _id; /* record ID */ 149 char data[0]; /* plug data */ 150} __attribute__ ((packed)); 151 152 153/* Functions for access to little-endian data */ 154static inline u32 155dblock_addr(const struct dblock *blk) 156{ 157 return le32_to_cpu(blk->_addr); 158} 159 160static inline u32 161dblock_len(const struct dblock *blk) 162{ 163 return le16_to_cpu(blk->_len); 164} 165 166static inline u32 167pdr_id(const struct pdr *pdr) 168{ 169 return le32_to_cpu(pdr->_id); 170} 171 172static inline u32 173pdr_addr(const struct pdr *pdr) 174{ 175 return le32_to_cpu(pdr->_addr); 176} 177 178static inline u32 179pdr_len(const struct pdr *pdr) 180{ 181 return le32_to_cpu(pdr->_len); 182} 183 184static inline u32 185pdi_id(const struct pdi *pdi) 186{ 187 return le16_to_cpu(pdi->_id); 188} 189 190/* Return length of the data only, in bytes */ 191static inline u32 192pdi_len(const struct pdi *pdi) 193{ 194 return 2 * (le16_to_cpu(pdi->_len) - 1); 195} 196 197 198/* Set address of the auxiliary port */ 199static inline void 200spectrum_aux_setaddr(hermes_t *hw, u32 addr) 201{ 202 hermes_write_reg(hw, HERMES_AUXPAGE, (u16) (addr >> 7)); 203 hermes_write_reg(hw, HERMES_AUXOFFSET, (u16) (addr & 0x7F)); 204} 205 206 207/* Open access to the auxiliary port */ 208static int 209spectrum_aux_open(hermes_t *hw) 210{ 211 int i; 212 213 /* Already open? */ 214 if (hermes_read_reg(hw, HERMES_CONTROL) == HERMES_AUX_ENABLED) 215 return 0; 216 217 hermes_write_reg(hw, HERMES_PARAM0, HERMES_AUX_PW0); 218 hermes_write_reg(hw, HERMES_PARAM1, HERMES_AUX_PW1); 219 hermes_write_reg(hw, HERMES_PARAM2, HERMES_AUX_PW2); 220 hermes_write_reg(hw, HERMES_CONTROL, HERMES_AUX_ENABLE); 221 222 for (i = 0; i < 20; i++) { 223 udelay(10); 224 if (hermes_read_reg(hw, HERMES_CONTROL) == 225 HERMES_AUX_ENABLED) 226 return 0; 227 } 228 229 return -EBUSY; 230} 231 232 233#define CS_CHECK(fn, ret) \ 234 do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) 235 236/* 237 * Reset the card using configuration registers COR and CCSR. 238 * If IDLE is 1, stop the firmware, so that it can be safely rewritten. 239 */ 240static int 241spectrum_reset(struct pcmcia_device *link, int idle) 242{ 243 int last_ret, last_fn; 244 conf_reg_t reg; 245 u_int save_cor; 246 247 /* Doing it if hardware is gone is guaranteed crash */ 248 if (pcmcia_dev_present(link)) 249 return -ENODEV; 250 251 /* Save original COR value */ 252 reg.Function = 0; 253 reg.Action = CS_READ; 254 reg.Offset = CISREG_COR; 255 CS_CHECK(AccessConfigurationRegister, 256 pcmcia_access_configuration_register(link, &reg)); 257 save_cor = reg.Value; 258 259 /* Soft-Reset card */ 260 reg.Action = CS_WRITE; 261 reg.Offset = CISREG_COR; 262 reg.Value = (save_cor | COR_SOFT_RESET); 263 CS_CHECK(AccessConfigurationRegister, 264 pcmcia_access_configuration_register(link, &reg)); 265 udelay(1000); 266 267 /* Read CCSR */ 268 reg.Action = CS_READ; 269 reg.Offset = CISREG_CCSR; 270 CS_CHECK(AccessConfigurationRegister, 271 pcmcia_access_configuration_register(link, &reg)); 272 273 /* 274 * Start or stop the firmware. Memory width bit should be 275 * preserved from the value we've just read. 276 */ 277 reg.Action = CS_WRITE; 278 reg.Offset = CISREG_CCSR; 279 reg.Value = (idle ? HCR_IDLE : HCR_RUN) | (reg.Value & HCR_MEM16); 280 CS_CHECK(AccessConfigurationRegister, 281 pcmcia_access_configuration_register(link, &reg)); 282 udelay(1000); 283 284 /* Restore original COR configuration index */ 285 reg.Action = CS_WRITE; 286 reg.Offset = CISREG_COR; 287 reg.Value = (save_cor & ~COR_SOFT_RESET); 288 CS_CHECK(AccessConfigurationRegister, 289 pcmcia_access_configuration_register(link, &reg)); 290 udelay(1000); 291 return 0; 292 293 cs_failed: 294 cs_error(link, last_fn, last_ret); 295 return -ENODEV; 296} 297 298 299/* 300 * Scan PDR for the record with the specified RECORD_ID. 301 * If it's not found, return NULL. 302 */ 303static struct pdr * 304spectrum_find_pdr(struct pdr *first_pdr, u32 record_id) 305{ 306 struct pdr *pdr = first_pdr; 307 308 while (pdr_id(pdr) != PDI_END) { 309 /* 310 * PDR area is currently not terminated by PDI_END. 311 * It's followed by CRC records, which have the type 312 * field where PDR has length. The type can be 0 or 1. 313 */ 314 if (pdr_len(pdr) < 2) 315 return NULL; 316 317 /* If the record ID matches, we are done */ 318 if (pdr_id(pdr) == record_id) 319 return pdr; 320 321 pdr = (struct pdr *) pdr->next; 322 } 323 return NULL; 324} 325 326 327/* Process one Plug Data Item - find corresponding PDR and plug it */ 328static int 329spectrum_plug_pdi(hermes_t *hw, struct pdr *first_pdr, struct pdi *pdi) 330{ 331 struct pdr *pdr; 332 333 /* Find the PDI corresponding to this PDR */ 334 pdr = spectrum_find_pdr(first_pdr, pdi_id(pdi)); 335 336 /* No match is found, safe to ignore */ 337 if (!pdr) 338 return 0; 339 340 /* Lengths of the data in PDI and PDR must match */ 341 if (pdi_len(pdi) != pdr_len(pdr)) 342 return -EINVAL; 343 344 /* do the actual plugging */ 345 spectrum_aux_setaddr(hw, pdr_addr(pdr)); 346 hermes_write_words(hw, HERMES_AUXDATA, pdi->data, 347 pdi_len(pdi) / 2); 348 349 return 0; 350} 351 352 353/* Read PDA from the adapter */ 354static int 355spectrum_read_pda(hermes_t *hw, __le16 *pda, int pda_len) 356{ 357 int ret; 358 int pda_size; 359 360 /* Issue command to read EEPROM */ 361 ret = hermes_docmd_wait(hw, HERMES_CMD_READMIF, 0, NULL); 362 if (ret) 363 return ret; 364 365 /* Open auxiliary port */ 366 ret = spectrum_aux_open(hw); 367 if (ret) 368 return ret; 369 370 /* read PDA from EEPROM */ 371 spectrum_aux_setaddr(hw, PDA_ADDR); 372 hermes_read_words(hw, HERMES_AUXDATA, pda, pda_len / 2); 373 374 /* Check PDA length */ 375 pda_size = le16_to_cpu(pda[0]); 376 if (pda_size > pda_len) 377 return -EINVAL; 378 379 return 0; 380} 381 382 383/* Parse PDA and write the records into the adapter */ 384static int 385spectrum_apply_pda(hermes_t *hw, const struct dblock *first_block, 386 __le16 *pda) 387{ 388 int ret; 389 struct pdi *pdi; 390 struct pdr *first_pdr; 391 const struct dblock *blk = first_block; 392 393 /* Skip all blocks to locate Plug Data References */ 394 while (dblock_addr(blk) != BLOCK_END) 395 blk = (struct dblock *) &blk->data[dblock_len(blk)]; 396 397 first_pdr = (struct pdr *) blk; 398 399 /* Go through every PDI and plug them into the adapter */ 400 pdi = (struct pdi *) (pda + 2); 401 while (pdi_id(pdi) != PDI_END) { 402 ret = spectrum_plug_pdi(hw, first_pdr, pdi); 403 if (ret) 404 return ret; 405 406 /* Increment to the next PDI */ 407 pdi = (struct pdi *) &pdi->data[pdi_len(pdi)]; 408 } 409 return 0; 410} 411 412 413/* Load firmware blocks into the adapter */ 414static int 415spectrum_load_blocks(hermes_t *hw, const struct dblock *first_block) 416{ 417 const struct dblock *blk; 418 u32 blkaddr; 419 u32 blklen; 420 421 blk = first_block; 422 blkaddr = dblock_addr(blk); 423 blklen = dblock_len(blk); 424 425 while (dblock_addr(blk) != BLOCK_END) { 426 spectrum_aux_setaddr(hw, blkaddr); 427 hermes_write_words(hw, HERMES_AUXDATA, blk->data, 428 blklen / 2); 429 430 blk = (struct dblock *) &blk->data[blklen]; 431 blkaddr = dblock_addr(blk); 432 blklen = dblock_len(blk); 433 } 434 return 0; 435} 436 437 438/* 439 * Process a firmware image - stop the card, load the firmware, reset 440 * the card and make sure it responds. For the secondary firmware take 441 * care of the PDA - read it and then write it on top of the firmware. 442 */ 443static int 444spectrum_dl_image(hermes_t *hw, struct pcmcia_device *link, 445 const unsigned char *image) 446{ 447 int ret; 448 const unsigned char *ptr; 449 const struct dblock *first_block; 450 451 /* Plug Data Area (PDA) */ 452 __le16 pda[PDA_WORDS]; 453 454 /* Binary block begins after the 0x1A marker */ 455 ptr = image; 456 while (*ptr++ != TEXT_END); 457 first_block = (const struct dblock *) ptr; 458 459 /* Read the PDA */ 460 if (image != primsym) { 461 ret = spectrum_read_pda(hw, pda, sizeof(pda)); 462 if (ret) 463 return ret; 464 } 465 466 /* Stop the firmware, so that it can be safely rewritten */ 467 ret = spectrum_reset(link, 1); 468 if (ret) 469 return ret; 470 471 /* Program the adapter with new firmware */ 472 ret = spectrum_load_blocks(hw, first_block); 473 if (ret) 474 return ret; 475 476 /* Write the PDA to the adapter */ 477 if (image != primsym) { 478 ret = spectrum_apply_pda(hw, first_block, pda); 479 if (ret) 480 return ret; 481 } 482 483 /* Run the firmware */ 484 ret = spectrum_reset(link, 0); 485 if (ret) 486 return ret; 487 488 /* Reset hermes chip and make sure it responds */ 489 ret = hermes_init(hw); 490 491 /* hermes_reset() should return 0 with the secondary firmware */ 492 if (image != primsym && ret != 0) 493 return -ENODEV; 494 495 /* And this should work with any firmware */ 496 if (!hermes_present(hw)) 497 return -ENODEV; 498 499 return 0; 500} 501 502 503/* 504 * Download the firmware into the card, this also does a PCMCIA soft 505 * reset on the card, to make sure it's in a sane state. 506 */ 507static int 508spectrum_dl_firmware(hermes_t *hw, struct pcmcia_device *link) 509{ 510 int ret; 511 const struct firmware *fw_entry; 512 513 if (request_firmware(&fw_entry, primary_fw_name, 514 &handle_to_dev(link)) == 0) { 515 primsym = fw_entry->data; 516 } else { 517 printk(KERN_ERR PFX "Cannot find firmware: %s\n", 518 primary_fw_name); 519 return -ENOENT; 520 } 521 522 if (request_firmware(&fw_entry, secondary_fw_name, 523 &handle_to_dev(link)) == 0) { 524 secsym = fw_entry->data; 525 } else { 526 printk(KERN_ERR PFX "Cannot find firmware: %s\n", 527 secondary_fw_name); 528 return -ENOENT; 529 } 530 531 /* Load primary firmware */ 532 ret = spectrum_dl_image(hw, link, primsym); 533 if (ret) { 534 printk(KERN_ERR PFX "Primary firmware download failed\n"); 535 return ret; 536 } 537 538 /* Load secondary firmware */ 539 ret = spectrum_dl_image(hw, link, secsym); 540 541 if (ret) { 542 printk(KERN_ERR PFX "Secondary firmware download failed\n"); 543 } 544 545 return ret; 546} 547 548/********************************************************************/ 549/* Device methods */ 550/********************************************************************/ 551 552static int 553spectrum_cs_hard_reset(struct orinoco_private *priv) 554{ 555 struct orinoco_pccard *card = priv->card; 556 struct pcmcia_device *link = card->p_dev; 557 int err; 558 559 if (!hermes_present(&priv->hw)) { 560 /* The firmware needs to be reloaded */ 561 if (spectrum_dl_firmware(&priv->hw, link) != 0) { 562 printk(KERN_ERR PFX "Firmware download failed\n"); 563 err = -ENODEV; 564 } 565 } else { 566 /* Soft reset using COR and HCR */ 567 spectrum_reset(link, 0); 568 } 569 570 return 0; 571} 572 573/********************************************************************/ 574/* PCMCIA stuff */ 575/********************************************************************/ 576 577/* 578 * This creates an "instance" of the driver, allocating local data 579 * structures for one device. The device is registered with Card 580 * Services. 581 * 582 * The dev_link structure is initialized, but we don't actually 583 * configure the card at this point -- we wait until we receive a card 584 * insertion event. */ 585static int 586spectrum_cs_probe(struct pcmcia_device *link) 587{ 588 struct net_device *dev; 589 struct orinoco_private *priv; 590 struct orinoco_pccard *card; 591 592 dev = alloc_orinocodev(sizeof(*card), spectrum_cs_hard_reset); 593 if (! dev) 594 return -ENOMEM; 595 priv = netdev_priv(dev); 596 card = priv->card; 597 598 /* Link both structures together */ 599 card->p_dev = link; 600 link->priv = dev; 601 602 /* Interrupt setup */ 603 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; 604 link->irq.IRQInfo1 = IRQ_LEVEL_ID; 605 link->irq.Handler = orinoco_interrupt; 606 link->irq.Instance = dev; 607 608 /* General socket configuration defaults can go here. In this 609 * client, we assume very little, and rely on the CIS for 610 * almost everything. In most clients, many details (i.e., 611 * number, sizes, and attributes of IO windows) are fixed by 612 * the nature of the device, and can be hard-wired here. */ 613 link->conf.Attributes = 0; 614 link->conf.IntType = INT_MEMORY_AND_IO; 615 616 return spectrum_cs_config(link); 617} /* spectrum_cs_attach */ 618 619/* 620 * This deletes a driver "instance". The device is de-registered with 621 * Card Services. If it has been released, all local data structures 622 * are freed. Otherwise, the structures will be freed when the device 623 * is released. 624 */ 625static void spectrum_cs_detach(struct pcmcia_device *link) 626{ 627 struct net_device *dev = link->priv; 628 629 spectrum_cs_release(link); 630 631 DEBUG(0, PFX "detach: link=%p link->dev_node=%p\n", link, link->dev_node); 632 if (link->dev_node) { 633 DEBUG(0, PFX "About to unregister net device %p\n", 634 dev); 635 unregister_netdev(dev); 636 } 637 free_orinocodev(dev); 638} /* spectrum_cs_detach */ 639 640/* 641 * spectrum_cs_config() is scheduled to run after a CARD_INSERTION 642 * event is received, to configure the PCMCIA socket, and to make the 643 * device available to the system. 644 */ 645 646static int 647spectrum_cs_config(struct pcmcia_device *link) 648{ 649 struct net_device *dev = link->priv; 650 struct orinoco_private *priv = netdev_priv(dev); 651 struct orinoco_pccard *card = priv->card; 652 hermes_t *hw = &priv->hw; 653 int last_fn, last_ret; 654 u_char buf[64]; 655 config_info_t conf; 656 cisinfo_t info; 657 tuple_t tuple; 658 cisparse_t parse; 659 void __iomem *mem; 660 661 CS_CHECK(ValidateCIS, pcmcia_validate_cis(link, &info)); 662 663 /* 664 * This reads the card's CONFIG tuple to find its 665 * configuration registers. 666 */ 667 tuple.DesiredTuple = CISTPL_CONFIG; 668 tuple.Attributes = 0; 669 tuple.TupleData = buf; 670 tuple.TupleDataMax = sizeof(buf); 671 tuple.TupleOffset = 0; 672 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); 673 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); 674 CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); 675 link->conf.ConfigBase = parse.config.base; 676 link->conf.Present = parse.config.rmask[0]; 677 678 /* Look up the current Vcc */ 679 CS_CHECK(GetConfigurationInfo, 680 pcmcia_get_configuration_info(link, &conf)); 681 682 /* 683 * In this loop, we scan the CIS for configuration table 684 * entries, each of which describes a valid card 685 * configuration, including voltage, IO window, memory window, 686 * and interrupt settings. 687 * 688 * We make no assumptions about the card to be configured: we 689 * use just the information available in the CIS. In an ideal 690 * world, this would work for any PCMCIA card, but it requires 691 * a complete and accurate CIS. In practice, a driver usually 692 * "knows" most of these things without consulting the CIS, 693 * and most client drivers will only use the CIS to fill in 694 * implementation-defined details. 695 */ 696 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; 697 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); 698 while (1) { 699 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); 700 cistpl_cftable_entry_t dflt = { .index = 0 }; 701 702 if ( (pcmcia_get_tuple_data(link, &tuple) != 0) 703 || (pcmcia_parse_tuple(link, &tuple, &parse) != 0)) 704 goto next_entry; 705 706 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) 707 dflt = *cfg; 708 if (cfg->index == 0) 709 goto next_entry; 710 link->conf.ConfigIndex = cfg->index; 711 712 /* Does this card need audio output? */ 713 if (cfg->flags & CISTPL_CFTABLE_AUDIO) { 714 link->conf.Attributes |= CONF_ENABLE_SPKR; 715 link->conf.Status = CCSR_AUDIO_ENA; 716 } 717 718 /* Use power settings for Vcc and Vpp if present */ 719 /* Note that the CIS values need to be rescaled */ 720 if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) { 721 if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) { 722 DEBUG(2, "spectrum_cs_config: Vcc mismatch (conf.Vcc = %d, CIS = %d)\n", conf.Vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000); 723 if (!ignore_cis_vcc) 724 goto next_entry; 725 } 726 } else if (dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) { 727 if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM] / 10000) { 728 DEBUG(2, "spectrum_cs_config: Vcc mismatch (conf.Vcc = %d, CIS = %d)\n", conf.Vcc, dflt.vcc.param[CISTPL_POWER_VNOM] / 10000); 729 if(!ignore_cis_vcc) 730 goto next_entry; 731 } 732 } 733 734 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) 735 link->conf.Vpp = 736 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; 737 else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) 738 link->conf.Vpp = 739 dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; 740 741 /* Do we need to allocate an interrupt? */ 742 link->conf.Attributes |= CONF_ENABLE_IRQ; 743 744 /* IO window settings */ 745 link->io.NumPorts1 = link->io.NumPorts2 = 0; 746 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { 747 cistpl_io_t *io = 748 (cfg->io.nwin) ? &cfg->io : &dflt.io; 749 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; 750 if (!(io->flags & CISTPL_IO_8BIT)) 751 link->io.Attributes1 = 752 IO_DATA_PATH_WIDTH_16; 753 if (!(io->flags & CISTPL_IO_16BIT)) 754 link->io.Attributes1 = 755 IO_DATA_PATH_WIDTH_8; 756 link->io.IOAddrLines = 757 io->flags & CISTPL_IO_LINES_MASK; 758 link->io.BasePort1 = io->win[0].base; 759 link->io.NumPorts1 = io->win[0].len; 760 if (io->nwin > 1) { 761 link->io.Attributes2 = 762 link->io.Attributes1; 763 link->io.BasePort2 = io->win[1].base; 764 link->io.NumPorts2 = io->win[1].len; 765 } 766 767 /* This reserves IO space but doesn't actually enable it */ 768 if (pcmcia_request_io(link, &link->io) != 0) 769 goto next_entry; 770 } 771 772 773 /* If we got this far, we're cool! */ 774 775 break; 776 777 next_entry: 778 pcmcia_disable_device(link); 779 last_ret = pcmcia_get_next_tuple(link, &tuple); 780 if (last_ret == CS_NO_MORE_ITEMS) { 781 printk(KERN_ERR PFX "GetNextTuple(): No matching " 782 "CIS configuration. Maybe you need the " 783 "ignore_cis_vcc=1 parameter.\n"); 784 goto cs_failed; 785 } 786 } 787 788 /* 789 * Allocate an interrupt line. Note that this does not assign 790 * a handler to the interrupt, unless the 'Handler' member of 791 * the irq structure is initialized. 792 */ 793 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); 794 795 /* We initialize the hermes structure before completing PCMCIA 796 * configuration just in case the interrupt handler gets 797 * called. */ 798 mem = ioport_map(link->io.BasePort1, link->io.NumPorts1); 799 if (!mem) 800 goto cs_failed; 801 802 hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING); 803 804 /* 805 * This actually configures the PCMCIA socket -- setting up 806 * the I/O windows and the interrupt mapping, and putting the 807 * card and host interface into "Memory and IO" mode. 808 */ 809 CS_CHECK(RequestConfiguration, 810 pcmcia_request_configuration(link, &link->conf)); 811 812 /* Ok, we have the configuration, prepare to register the netdev */ 813 dev->base_addr = link->io.BasePort1; 814 dev->irq = link->irq.AssignedIRQ; 815 SET_MODULE_OWNER(dev); 816 card->node.major = card->node.minor = 0; 817 818 /* Reset card and download firmware */ 819 if (spectrum_cs_hard_reset(priv) != 0) { 820 goto failed; 821 } 822 823 SET_NETDEV_DEV(dev, &handle_to_dev(link)); 824 /* Tell the stack we exist */ 825 if (register_netdev(dev) != 0) { 826 printk(KERN_ERR PFX "register_netdev() failed\n"); 827 goto failed; 828 } 829 830 /* At this point, the dev_node_t structure(s) needs to be 831 * initialized and arranged in a linked list at link->dev_node. */ 832 strcpy(card->node.dev_name, dev->name); 833 link->dev_node = &card->node; /* link->dev_node being non-NULL is also 834 used to indicate that the 835 net_device has been registered */ 836 837 /* Finally, report what we've done */ 838 printk(KERN_DEBUG "%s: index 0x%02x: ", 839 dev->name, link->conf.ConfigIndex); 840 if (link->conf.Vpp) 841 printk(", Vpp %d.%d", link->conf.Vpp / 10, 842 link->conf.Vpp % 10); 843 printk(", irq %d", link->irq.AssignedIRQ); 844 if (link->io.NumPorts1) 845 printk(", io 0x%04x-0x%04x", link->io.BasePort1, 846 link->io.BasePort1 + link->io.NumPorts1 - 1); 847 if (link->io.NumPorts2) 848 printk(" & 0x%04x-0x%04x", link->io.BasePort2, 849 link->io.BasePort2 + link->io.NumPorts2 - 1); 850 printk("\n"); 851 852 return 0; 853 854 cs_failed: 855 cs_error(link, last_fn, last_ret); 856 857 failed: 858 spectrum_cs_release(link); 859 return -ENODEV; 860} /* spectrum_cs_config */ 861 862/* 863 * After a card is removed, spectrum_cs_release() will unregister the 864 * device, and release the PCMCIA configuration. If the device is 865 * still open, this will be postponed until it is closed. 866 */ 867static void 868spectrum_cs_release(struct pcmcia_device *link) 869{ 870 struct net_device *dev = link->priv; 871 struct orinoco_private *priv = netdev_priv(dev); 872 unsigned long flags; 873 874 /* We're committed to taking the device away now, so mark the 875 * hardware as unavailable */ 876 spin_lock_irqsave(&priv->lock, flags); 877 priv->hw_unavailable++; 878 spin_unlock_irqrestore(&priv->lock, flags); 879 880 pcmcia_disable_device(link); 881 if (priv->hw.iobase) 882 ioport_unmap(priv->hw.iobase); 883} /* spectrum_cs_release */ 884 885 886static int 887spectrum_cs_suspend(struct pcmcia_device *link) 888{ 889 struct net_device *dev = link->priv; 890 struct orinoco_private *priv = netdev_priv(dev); 891 unsigned long flags; 892 int err = 0; 893 894 /* Mark the device as stopped, to block IO until later */ 895 spin_lock_irqsave(&priv->lock, flags); 896 897 err = __orinoco_down(dev); 898 if (err) 899 printk(KERN_WARNING "%s: Error %d downing interface\n", 900 dev->name, err); 901 902 netif_device_detach(dev); 903 priv->hw_unavailable++; 904 905 spin_unlock_irqrestore(&priv->lock, flags); 906 907 return 0; 908} 909 910static int 911spectrum_cs_resume(struct pcmcia_device *link) 912{ 913 struct net_device *dev = link->priv; 914 struct orinoco_private *priv = netdev_priv(dev); 915 916 netif_device_attach(dev); 917 priv->hw_unavailable--; 918 schedule_work(&priv->reset_work); 919 920 return 0; 921} 922 923 924/********************************************************************/ 925/* Module initialization */ 926/********************************************************************/ 927 928/* Can't be declared "const" or the whole __initdata section will 929 * become const */ 930static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION 931 " (Pavel Roskin <proski@gnu.org>," 932 " David Gibson <hermes@gibson.dropbear.id.au>, et al)"; 933 934static struct pcmcia_device_id spectrum_cs_ids[] = { 935 PCMCIA_DEVICE_MANF_CARD(0x026c, 0x0001), /* Symbol Spectrum24 LA4100 */ 936 PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0001), /* Socket Communications CF */ 937 PCMCIA_DEVICE_PROD_ID12("Intel", "PRO/Wireless LAN PC Card", 0x816cc815, 0x6fbf459a), /* 2011B, not 2011 */ 938 PCMCIA_DEVICE_NULL, 939}; 940MODULE_DEVICE_TABLE(pcmcia, spectrum_cs_ids); 941 942static struct pcmcia_driver orinoco_driver = { 943 .owner = THIS_MODULE, 944 .drv = { 945 .name = DRIVER_NAME, 946 }, 947 .probe = spectrum_cs_probe, 948 .remove = spectrum_cs_detach, 949 .suspend = spectrum_cs_suspend, 950 .resume = spectrum_cs_resume, 951 .id_table = spectrum_cs_ids, 952}; 953 954static int __init 955init_spectrum_cs(void) 956{ 957 printk(KERN_DEBUG "%s\n", version); 958 959 return pcmcia_register_driver(&orinoco_driver); 960} 961 962static void __exit 963exit_spectrum_cs(void) 964{ 965 pcmcia_unregister_driver(&orinoco_driver); 966} 967 968module_init(init_spectrum_cs); 969module_exit(exit_spectrum_cs);