aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/hostap/hostap_cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/hostap/hostap_cs.c')
-rw-r--r--drivers/net/wireless/hostap/hostap_cs.c237
1 files changed, 104 insertions, 133 deletions
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index 3b4e55cf33cd..633740277352 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -234,7 +234,7 @@ static void sandisk_set_iobase(local_info_t *local)
234 reg.Value = hw_priv->link->io.BasePort1 & 0x00ff; 234 reg.Value = hw_priv->link->io.BasePort1 & 0x00ff;
235 res = pcmcia_access_configuration_register(hw_priv->link, 235 res = pcmcia_access_configuration_register(hw_priv->link,
236 &reg); 236 &reg);
237 if (res != CS_SUCCESS) { 237 if (res != 0) {
238 printk(KERN_DEBUG "Prism3 SanDisk - failed to set I/O base 0 -" 238 printk(KERN_DEBUG "Prism3 SanDisk - failed to set I/O base 0 -"
239 " res=%d\n", res); 239 " res=%d\n", res);
240 } 240 }
@@ -246,7 +246,7 @@ static void sandisk_set_iobase(local_info_t *local)
246 reg.Value = (hw_priv->link->io.BasePort1 & 0xff00) >> 8; 246 reg.Value = (hw_priv->link->io.BasePort1 & 0xff00) >> 8;
247 res = pcmcia_access_configuration_register(hw_priv->link, 247 res = pcmcia_access_configuration_register(hw_priv->link,
248 &reg); 248 &reg);
249 if (res != CS_SUCCESS) { 249 if (res != 0) {
250 printk(KERN_DEBUG "Prism3 SanDisk - failed to set I/O base 1 -" 250 printk(KERN_DEBUG "Prism3 SanDisk - failed to set I/O base 1 -"
251 " res=%d\n", res); 251 " res=%d\n", res);
252 } 252 }
@@ -305,7 +305,7 @@ static int sandisk_enable_wireless(struct net_device *dev)
305 tuple.DesiredTuple = CISTPL_LONGLINK_MFC; 305 tuple.DesiredTuple = CISTPL_LONGLINK_MFC;
306 if (pcmcia_get_first_tuple(hw_priv->link, &tuple) || 306 if (pcmcia_get_first_tuple(hw_priv->link, &tuple) ||
307 pcmcia_get_tuple_data(hw_priv->link, &tuple) || 307 pcmcia_get_tuple_data(hw_priv->link, &tuple) ||
308 pcmcia_parse_tuple(hw_priv->link, &tuple, parse) || 308 pcmcia_parse_tuple(&tuple, parse) ||
309 parse->longlink_mfc.nfn < 2) { 309 parse->longlink_mfc.nfn < 2) {
310 /* No multi-function links found */ 310 /* No multi-function links found */
311 ret = -ENODEV; 311 ret = -ENODEV;
@@ -322,7 +322,7 @@ static int sandisk_enable_wireless(struct net_device *dev)
322 reg.Value = COR_SOFT_RESET; 322 reg.Value = COR_SOFT_RESET;
323 res = pcmcia_access_configuration_register(hw_priv->link, 323 res = pcmcia_access_configuration_register(hw_priv->link,
324 &reg); 324 &reg);
325 if (res != CS_SUCCESS) { 325 if (res != 0) {
326 printk(KERN_DEBUG "%s: SanDisk - COR sreset failed (%d)\n", 326 printk(KERN_DEBUG "%s: SanDisk - COR sreset failed (%d)\n",
327 dev->name, res); 327 dev->name, res);
328 goto done; 328 goto done;
@@ -339,7 +339,7 @@ static int sandisk_enable_wireless(struct net_device *dev)
339 reg.Value = COR_LEVEL_REQ | 0x8 | COR_ADDR_DECODE | COR_FUNC_ENA; 339 reg.Value = COR_LEVEL_REQ | 0x8 | COR_ADDR_DECODE | COR_FUNC_ENA;
340 res = pcmcia_access_configuration_register(hw_priv->link, 340 res = pcmcia_access_configuration_register(hw_priv->link,
341 &reg); 341 &reg);
342 if (res != CS_SUCCESS) { 342 if (res != 0) {
343 printk(KERN_DEBUG "%s: SanDisk - COR sreset failed (%d)\n", 343 printk(KERN_DEBUG "%s: SanDisk - COR sreset failed (%d)\n",
344 dev->name, res); 344 dev->name, res);
345 goto done; 345 goto done;
@@ -374,7 +374,7 @@ static void prism2_pccard_cor_sreset(local_info_t *local)
374 reg.Value = 0; 374 reg.Value = 0;
375 res = pcmcia_access_configuration_register(hw_priv->link, 375 res = pcmcia_access_configuration_register(hw_priv->link,
376 &reg); 376 &reg);
377 if (res != CS_SUCCESS) { 377 if (res != 0) {
378 printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 1 (%d)\n", 378 printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 1 (%d)\n",
379 res); 379 res);
380 return; 380 return;
@@ -386,7 +386,7 @@ static void prism2_pccard_cor_sreset(local_info_t *local)
386 reg.Value |= COR_SOFT_RESET; 386 reg.Value |= COR_SOFT_RESET;
387 res = pcmcia_access_configuration_register(hw_priv->link, 387 res = pcmcia_access_configuration_register(hw_priv->link,
388 &reg); 388 &reg);
389 if (res != CS_SUCCESS) { 389 if (res != 0) {
390 printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 2 (%d)\n", 390 printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 2 (%d)\n",
391 res); 391 res);
392 return; 392 return;
@@ -399,7 +399,7 @@ static void prism2_pccard_cor_sreset(local_info_t *local)
399 reg.Value |= COR_IREQ_ENA; 399 reg.Value |= COR_IREQ_ENA;
400 res = pcmcia_access_configuration_register(hw_priv->link, 400 res = pcmcia_access_configuration_register(hw_priv->link,
401 &reg); 401 &reg);
402 if (res != CS_SUCCESS) { 402 if (res != 0) {
403 printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 3 (%d)\n", 403 printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 3 (%d)\n",
404 res); 404 res);
405 return; 405 return;
@@ -433,7 +433,7 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr)
433 reg.Value = 0; 433 reg.Value = 0;
434 res = pcmcia_access_configuration_register(hw_priv->link, 434 res = pcmcia_access_configuration_register(hw_priv->link,
435 &reg); 435 &reg);
436 if (res != CS_SUCCESS) { 436 if (res != 0) {
437 printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 1 " 437 printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 1 "
438 "(%d)\n", res); 438 "(%d)\n", res);
439 return; 439 return;
@@ -446,7 +446,7 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr)
446 reg.Value |= COR_SOFT_RESET; 446 reg.Value |= COR_SOFT_RESET;
447 res = pcmcia_access_configuration_register(hw_priv->link, 447 res = pcmcia_access_configuration_register(hw_priv->link,
448 &reg); 448 &reg);
449 if (res != CS_SUCCESS) { 449 if (res != 0) {
450 printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 2 " 450 printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 2 "
451 "(%d)\n", res); 451 "(%d)\n", res);
452 return; 452 return;
@@ -460,7 +460,7 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr)
460 reg.Offset = CISREG_CCSR; 460 reg.Offset = CISREG_CCSR;
461 res = pcmcia_access_configuration_register(hw_priv->link, 461 res = pcmcia_access_configuration_register(hw_priv->link,
462 &reg); 462 &reg);
463 if (res != CS_SUCCESS) { 463 if (res != 0) {
464 printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 3 " 464 printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 3 "
465 "(%d)\n", res); 465 "(%d)\n", res);
466 return; 466 return;
@@ -472,7 +472,7 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr)
472 reg.Value = old_cor & ~COR_SOFT_RESET; 472 reg.Value = old_cor & ~COR_SOFT_RESET;
473 res = pcmcia_access_configuration_register(hw_priv->link, 473 res = pcmcia_access_configuration_register(hw_priv->link,
474 &reg); 474 &reg);
475 if (res != CS_SUCCESS) { 475 if (res != 0) {
476 printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 4 " 476 printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 4 "
477 "(%d)\n", res); 477 "(%d)\n", res);
478 return; 478 return;
@@ -532,145 +532,118 @@ static void prism2_detach(struct pcmcia_device *link)
532#define CS_CHECK(fn, ret) \ 532#define CS_CHECK(fn, ret) \
533do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) 533do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
534 534
535#define CFG_CHECK2(fn, retf) \
536do { int _ret = (retf); \
537if (_ret != 0) { \
538 PDEBUG(DEBUG_EXTRA, "CardServices(" #fn ") returned %d\n", _ret); \
539 cs_error(link, fn, _ret); \
540 goto next_entry; \
541} \
542} while (0)
543
544 535
545/* run after a CARD_INSERTION event is received to configure the PCMCIA 536/* run after a CARD_INSERTION event is received to configure the PCMCIA
546 * socket and make the device available to the system */ 537 * socket and make the device available to the system */
538
539static int prism2_config_check(struct pcmcia_device *p_dev,
540 cistpl_cftable_entry_t *cfg,
541 cistpl_cftable_entry_t *dflt,
542 unsigned int vcc,
543 void *priv_data)
544{
545 if (cfg->index == 0)
546 return -ENODEV;
547
548 PDEBUG(DEBUG_EXTRA, "Checking CFTABLE_ENTRY 0x%02X "
549 "(default 0x%02X)\n", cfg->index, dflt->index);
550
551 /* Does this card need audio output? */
552 if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
553 p_dev->conf.Attributes |= CONF_ENABLE_SPKR;
554 p_dev->conf.Status = CCSR_AUDIO_ENA;
555 }
556
557 /* Use power settings for Vcc and Vpp if present */
558 /* Note that the CIS values need to be rescaled */
559 if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
560 if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] /
561 10000 && !ignore_cis_vcc) {
562 PDEBUG(DEBUG_EXTRA, " Vcc mismatch - skipping"
563 " this entry\n");
564 return -ENODEV;
565 }
566 } else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) {
567 if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] /
568 10000 && !ignore_cis_vcc) {
569 PDEBUG(DEBUG_EXTRA, " Vcc (default) mismatch "
570 "- skipping this entry\n");
571 return -ENODEV;
572 }
573 }
574
575 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
576 p_dev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
577 else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM))
578 p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000;
579
580 /* Do we need to allocate an interrupt? */
581 if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
582 p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
583 else if (!(p_dev->conf.Attributes & CONF_ENABLE_IRQ)) {
584 /* At least Compaq WL200 does not have IRQInfo1 set,
585 * but it does not work without interrupts.. */
586 printk(KERN_WARNING "Config has no IRQ info, but trying to "
587 "enable IRQ anyway..\n");
588 p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
589 }
590
591 /* IO window settings */
592 PDEBUG(DEBUG_EXTRA, "IO window settings: cfg->io.nwin=%d "
593 "dflt->io.nwin=%d\n",
594 cfg->io.nwin, dflt->io.nwin);
595 p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
596 if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
597 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
598 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
599 PDEBUG(DEBUG_EXTRA, "io->flags = 0x%04X, "
600 "io.base=0x%04x, len=%d\n", io->flags,
601 io->win[0].base, io->win[0].len);
602 if (!(io->flags & CISTPL_IO_8BIT))
603 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
604 if (!(io->flags & CISTPL_IO_16BIT))
605 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
606 p_dev->io.IOAddrLines = io->flags &
607 CISTPL_IO_LINES_MASK;
608 p_dev->io.BasePort1 = io->win[0].base;
609 p_dev->io.NumPorts1 = io->win[0].len;
610 if (io->nwin > 1) {
611 p_dev->io.Attributes2 = p_dev->io.Attributes1;
612 p_dev->io.BasePort2 = io->win[1].base;
613 p_dev->io.NumPorts2 = io->win[1].len;
614 }
615 }
616
617 /* This reserves IO space but doesn't actually enable it */
618 return pcmcia_request_io(p_dev, &p_dev->io);
619}
620
547static int prism2_config(struct pcmcia_device *link) 621static int prism2_config(struct pcmcia_device *link)
548{ 622{
549 struct net_device *dev; 623 struct net_device *dev;
550 struct hostap_interface *iface; 624 struct hostap_interface *iface;
551 local_info_t *local; 625 local_info_t *local;
552 int ret = 1; 626 int ret = 1;
553 tuple_t tuple;
554 cisparse_t *parse;
555 int last_fn, last_ret; 627 int last_fn, last_ret;
556 u_char buf[64];
557 config_info_t conf;
558 cistpl_cftable_entry_t dflt = { 0 };
559 struct hostap_cs_priv *hw_priv; 628 struct hostap_cs_priv *hw_priv;
560 629
561 PDEBUG(DEBUG_FLOW, "prism2_config()\n"); 630 PDEBUG(DEBUG_FLOW, "prism2_config()\n");
562 631
563 parse = kmalloc(sizeof(cisparse_t), GFP_KERNEL);
564 hw_priv = kzalloc(sizeof(*hw_priv), GFP_KERNEL); 632 hw_priv = kzalloc(sizeof(*hw_priv), GFP_KERNEL);
565 if (parse == NULL || hw_priv == NULL) { 633 if (hw_priv == NULL) {
566 ret = -ENOMEM; 634 ret = -ENOMEM;
567 goto failed; 635 goto failed;
568 } 636 }
569 637
570 tuple.Attributes = 0;
571 tuple.TupleData = buf;
572 tuple.TupleDataMax = sizeof(buf);
573 tuple.TupleOffset = 0;
574
575 CS_CHECK(GetConfigurationInfo,
576 pcmcia_get_configuration_info(link, &conf));
577
578 /* Look for an appropriate configuration table entry in the CIS */ 638 /* Look for an appropriate configuration table entry in the CIS */
579 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; 639 last_ret = pcmcia_loop_config(link, prism2_config_check, NULL);
580 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); 640 if (last_ret) {
581 for (;;) { 641 if (!ignore_cis_vcc)
582 cistpl_cftable_entry_t *cfg = &(parse->cftable_entry); 642 printk(KERN_ERR "GetNextTuple(): No matching "
583 CFG_CHECK2(GetTupleData, 643 "CIS configuration. Maybe you need the "
584 pcmcia_get_tuple_data(link, &tuple)); 644 "ignore_cis_vcc=1 parameter.\n");
585 CFG_CHECK2(ParseTuple, 645 cs_error(link, RequestIO, last_ret);
586 pcmcia_parse_tuple(link, &tuple, parse)); 646 goto failed;
587
588 if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
589 dflt = *cfg;
590 if (cfg->index == 0)
591 goto next_entry;
592 link->conf.ConfigIndex = cfg->index;
593 PDEBUG(DEBUG_EXTRA, "Checking CFTABLE_ENTRY 0x%02X "
594 "(default 0x%02X)\n", cfg->index, dflt.index);
595
596 /* Does this card need audio output? */
597 if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
598 link->conf.Attributes |= CONF_ENABLE_SPKR;
599 link->conf.Status = CCSR_AUDIO_ENA;
600 }
601
602 /* Use power settings for Vcc and Vpp if present */
603 /* Note that the CIS values need to be rescaled */
604 if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
605 if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] /
606 10000 && !ignore_cis_vcc) {
607 PDEBUG(DEBUG_EXTRA, " Vcc mismatch - skipping"
608 " this entry\n");
609 goto next_entry;
610 }
611 } else if (dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
612 if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM] /
613 10000 && !ignore_cis_vcc) {
614 PDEBUG(DEBUG_EXTRA, " Vcc (default) mismatch "
615 "- skipping this entry\n");
616 goto next_entry;
617 }
618 }
619
620 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
621 link->conf.Vpp =
622 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
623 else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
624 link->conf.Vpp =
625 dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
626
627 /* Do we need to allocate an interrupt? */
628 if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
629 link->conf.Attributes |= CONF_ENABLE_IRQ;
630 else if (!(link->conf.Attributes & CONF_ENABLE_IRQ)) {
631 /* At least Compaq WL200 does not have IRQInfo1 set,
632 * but it does not work without interrupts.. */
633 printk("Config has no IRQ info, but trying to enable "
634 "IRQ anyway..\n");
635 link->conf.Attributes |= CONF_ENABLE_IRQ;
636 }
637
638 /* IO window settings */
639 PDEBUG(DEBUG_EXTRA, "IO window settings: cfg->io.nwin=%d "
640 "dflt.io.nwin=%d\n",
641 cfg->io.nwin, dflt.io.nwin);
642 link->io.NumPorts1 = link->io.NumPorts2 = 0;
643 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
644 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
645 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
646 PDEBUG(DEBUG_EXTRA, "io->flags = 0x%04X, "
647 "io.base=0x%04x, len=%d\n", io->flags,
648 io->win[0].base, io->win[0].len);
649 if (!(io->flags & CISTPL_IO_8BIT))
650 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
651 if (!(io->flags & CISTPL_IO_16BIT))
652 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
653 link->io.IOAddrLines = io->flags &
654 CISTPL_IO_LINES_MASK;
655 link->io.BasePort1 = io->win[0].base;
656 link->io.NumPorts1 = io->win[0].len;
657 if (io->nwin > 1) {
658 link->io.Attributes2 = link->io.Attributes1;
659 link->io.BasePort2 = io->win[1].base;
660 link->io.NumPorts2 = io->win[1].len;
661 }
662 }
663
664 /* This reserves IO space but doesn't actually enable it */
665 CFG_CHECK2(RequestIO,
666 pcmcia_request_io(link, &link->io));
667
668 /* This configuration table entry is OK */
669 break;
670
671 next_entry:
672 CS_CHECK(GetNextTuple,
673 pcmcia_get_next_tuple(link, &tuple));
674 } 647 }
675 648
676 /* Need to allocate net_device before requesting IRQ handler */ 649 /* Need to allocate net_device before requesting IRQ handler */
@@ -738,14 +711,12 @@ static int prism2_config(struct pcmcia_device *link)
738 if (ret == 0 && local->ddev) 711 if (ret == 0 && local->ddev)
739 strcpy(hw_priv->node.dev_name, local->ddev->name); 712 strcpy(hw_priv->node.dev_name, local->ddev->name);
740 } 713 }
741 kfree(parse);
742 return ret; 714 return ret;
743 715
744 cs_failed: 716 cs_failed:
745 cs_error(link, last_fn, last_ret); 717 cs_error(link, last_fn, last_ret);
746 718
747 failed: 719 failed:
748 kfree(parse);
749 kfree(hw_priv); 720 kfree(hw_priv);
750 prism2_release((u_long)link); 721 prism2_release((u_long)link);
751 return ret; 722 return ret;