diff options
author | David Kilroy <kilroyd@googlemail.com> | 2009-06-18 18:21:31 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-07-10 15:01:46 -0400 |
commit | 721aa2f75b00399074eb443fdf16d797b4504a36 (patch) | |
tree | da92487be47b18f853b37c54e22bb5f6d44c39ae /drivers/net/wireless/orinoco | |
parent | 6415f7df10573bf1ec42644f42bef565127114a1 (diff) |
orinoco: provide generic commit function
This allows changes to be commited from cfg80211 functions.
Signed-off-by: David Kilroy <kilroyd@googlemail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/orinoco')
-rw-r--r-- | drivers/net/wireless/orinoco/hw.c | 227 | ||||
-rw-r--r-- | drivers/net/wireless/orinoco/hw.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/orinoco/main.c | 297 | ||||
-rw-r--r-- | drivers/net/wireless/orinoco/main.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/orinoco/wext.c | 35 |
5 files changed, 294 insertions, 269 deletions
diff --git a/drivers/net/wireless/orinoco/hw.c b/drivers/net/wireless/orinoco/hw.c index eaa89d3866c9..56627d91aa70 100644 --- a/drivers/net/wireless/orinoco/hw.c +++ b/drivers/net/wireless/orinoco/hw.c | |||
@@ -406,6 +406,233 @@ void orinoco_get_ratemode_cfg(int ratemode, int *bitrate, int *automatic) | |||
406 | *automatic = bitrate_table[ratemode].automatic; | 406 | *automatic = bitrate_table[ratemode].automatic; |
407 | } | 407 | } |
408 | 408 | ||
409 | int orinoco_hw_program_rids(struct orinoco_private *priv) | ||
410 | { | ||
411 | struct net_device *dev = priv->ndev; | ||
412 | hermes_t *hw = &priv->hw; | ||
413 | int err; | ||
414 | struct hermes_idstring idbuf; | ||
415 | |||
416 | /* Set the MAC address */ | ||
417 | err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR, | ||
418 | HERMES_BYTES_TO_RECLEN(ETH_ALEN), dev->dev_addr); | ||
419 | if (err) { | ||
420 | printk(KERN_ERR "%s: Error %d setting MAC address\n", | ||
421 | dev->name, err); | ||
422 | return err; | ||
423 | } | ||
424 | |||
425 | /* Set up the link mode */ | ||
426 | err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFPORTTYPE, | ||
427 | priv->port_type); | ||
428 | if (err) { | ||
429 | printk(KERN_ERR "%s: Error %d setting port type\n", | ||
430 | dev->name, err); | ||
431 | return err; | ||
432 | } | ||
433 | /* Set the channel/frequency */ | ||
434 | if (priv->channel != 0 && priv->iw_mode != IW_MODE_INFRA) { | ||
435 | err = hermes_write_wordrec(hw, USER_BAP, | ||
436 | HERMES_RID_CNFOWNCHANNEL, | ||
437 | priv->channel); | ||
438 | if (err) { | ||
439 | printk(KERN_ERR "%s: Error %d setting channel %d\n", | ||
440 | dev->name, err, priv->channel); | ||
441 | return err; | ||
442 | } | ||
443 | } | ||
444 | |||
445 | if (priv->has_ibss) { | ||
446 | u16 createibss; | ||
447 | |||
448 | if ((strlen(priv->desired_essid) == 0) && (priv->createibss)) { | ||
449 | printk(KERN_WARNING "%s: This firmware requires an " | ||
450 | "ESSID in IBSS-Ad-Hoc mode.\n", dev->name); | ||
451 | /* With wvlan_cs, in this case, we would crash. | ||
452 | * hopefully, this driver will behave better... | ||
453 | * Jean II */ | ||
454 | createibss = 0; | ||
455 | } else { | ||
456 | createibss = priv->createibss; | ||
457 | } | ||
458 | |||
459 | err = hermes_write_wordrec(hw, USER_BAP, | ||
460 | HERMES_RID_CNFCREATEIBSS, | ||
461 | createibss); | ||
462 | if (err) { | ||
463 | printk(KERN_ERR "%s: Error %d setting CREATEIBSS\n", | ||
464 | dev->name, err); | ||
465 | return err; | ||
466 | } | ||
467 | } | ||
468 | |||
469 | /* Set the desired BSSID */ | ||
470 | err = __orinoco_hw_set_wap(priv); | ||
471 | if (err) { | ||
472 | printk(KERN_ERR "%s: Error %d setting AP address\n", | ||
473 | dev->name, err); | ||
474 | return err; | ||
475 | } | ||
476 | |||
477 | /* Set the desired ESSID */ | ||
478 | idbuf.len = cpu_to_le16(strlen(priv->desired_essid)); | ||
479 | memcpy(&idbuf.val, priv->desired_essid, sizeof(idbuf.val)); | ||
480 | /* WinXP wants partner to configure OWNSSID even in IBSS mode. (jimc) */ | ||
481 | err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNSSID, | ||
482 | HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2), | ||
483 | &idbuf); | ||
484 | if (err) { | ||
485 | printk(KERN_ERR "%s: Error %d setting OWNSSID\n", | ||
486 | dev->name, err); | ||
487 | return err; | ||
488 | } | ||
489 | err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFDESIREDSSID, | ||
490 | HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2), | ||
491 | &idbuf); | ||
492 | if (err) { | ||
493 | printk(KERN_ERR "%s: Error %d setting DESIREDSSID\n", | ||
494 | dev->name, err); | ||
495 | return err; | ||
496 | } | ||
497 | |||
498 | /* Set the station name */ | ||
499 | idbuf.len = cpu_to_le16(strlen(priv->nick)); | ||
500 | memcpy(&idbuf.val, priv->nick, sizeof(idbuf.val)); | ||
501 | err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME, | ||
502 | HERMES_BYTES_TO_RECLEN(strlen(priv->nick)+2), | ||
503 | &idbuf); | ||
504 | if (err) { | ||
505 | printk(KERN_ERR "%s: Error %d setting nickname\n", | ||
506 | dev->name, err); | ||
507 | return err; | ||
508 | } | ||
509 | |||
510 | /* Set AP density */ | ||
511 | if (priv->has_sensitivity) { | ||
512 | err = hermes_write_wordrec(hw, USER_BAP, | ||
513 | HERMES_RID_CNFSYSTEMSCALE, | ||
514 | priv->ap_density); | ||
515 | if (err) { | ||
516 | printk(KERN_WARNING "%s: Error %d setting SYSTEMSCALE. " | ||
517 | "Disabling sensitivity control\n", | ||
518 | dev->name, err); | ||
519 | |||
520 | priv->has_sensitivity = 0; | ||
521 | } | ||
522 | } | ||
523 | |||
524 | /* Set RTS threshold */ | ||
525 | err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD, | ||
526 | priv->rts_thresh); | ||
527 | if (err) { | ||
528 | printk(KERN_ERR "%s: Error %d setting RTS threshold\n", | ||
529 | dev->name, err); | ||
530 | return err; | ||
531 | } | ||
532 | |||
533 | /* Set fragmentation threshold or MWO robustness */ | ||
534 | if (priv->has_mwo) | ||
535 | err = hermes_write_wordrec(hw, USER_BAP, | ||
536 | HERMES_RID_CNFMWOROBUST_AGERE, | ||
537 | priv->mwo_robust); | ||
538 | else | ||
539 | err = hermes_write_wordrec(hw, USER_BAP, | ||
540 | HERMES_RID_CNFFRAGMENTATIONTHRESHOLD, | ||
541 | priv->frag_thresh); | ||
542 | if (err) { | ||
543 | printk(KERN_ERR "%s: Error %d setting fragmentation\n", | ||
544 | dev->name, err); | ||
545 | return err; | ||
546 | } | ||
547 | |||
548 | /* Set bitrate */ | ||
549 | err = __orinoco_hw_set_bitrate(priv); | ||
550 | if (err) { | ||
551 | printk(KERN_ERR "%s: Error %d setting bitrate\n", | ||
552 | dev->name, err); | ||
553 | return err; | ||
554 | } | ||
555 | |||
556 | /* Set power management */ | ||
557 | if (priv->has_pm) { | ||
558 | err = hermes_write_wordrec(hw, USER_BAP, | ||
559 | HERMES_RID_CNFPMENABLED, | ||
560 | priv->pm_on); | ||
561 | if (err) { | ||
562 | printk(KERN_ERR "%s: Error %d setting up PM\n", | ||
563 | dev->name, err); | ||
564 | return err; | ||
565 | } | ||
566 | |||
567 | err = hermes_write_wordrec(hw, USER_BAP, | ||
568 | HERMES_RID_CNFMULTICASTRECEIVE, | ||
569 | priv->pm_mcast); | ||
570 | if (err) { | ||
571 | printk(KERN_ERR "%s: Error %d setting up PM\n", | ||
572 | dev->name, err); | ||
573 | return err; | ||
574 | } | ||
575 | err = hermes_write_wordrec(hw, USER_BAP, | ||
576 | HERMES_RID_CNFMAXSLEEPDURATION, | ||
577 | priv->pm_period); | ||
578 | if (err) { | ||
579 | printk(KERN_ERR "%s: Error %d setting up PM\n", | ||
580 | dev->name, err); | ||
581 | return err; | ||
582 | } | ||
583 | err = hermes_write_wordrec(hw, USER_BAP, | ||
584 | HERMES_RID_CNFPMHOLDOVERDURATION, | ||
585 | priv->pm_timeout); | ||
586 | if (err) { | ||
587 | printk(KERN_ERR "%s: Error %d setting up PM\n", | ||
588 | dev->name, err); | ||
589 | return err; | ||
590 | } | ||
591 | } | ||
592 | |||
593 | /* Set preamble - only for Symbol so far... */ | ||
594 | if (priv->has_preamble) { | ||
595 | err = hermes_write_wordrec(hw, USER_BAP, | ||
596 | HERMES_RID_CNFPREAMBLE_SYMBOL, | ||
597 | priv->preamble); | ||
598 | if (err) { | ||
599 | printk(KERN_ERR "%s: Error %d setting preamble\n", | ||
600 | dev->name, err); | ||
601 | return err; | ||
602 | } | ||
603 | } | ||
604 | |||
605 | /* Set up encryption */ | ||
606 | if (priv->has_wep || priv->has_wpa) { | ||
607 | err = __orinoco_hw_setup_enc(priv); | ||
608 | if (err) { | ||
609 | printk(KERN_ERR "%s: Error %d activating encryption\n", | ||
610 | dev->name, err); | ||
611 | return err; | ||
612 | } | ||
613 | } | ||
614 | |||
615 | if (priv->iw_mode == IW_MODE_MONITOR) { | ||
616 | /* Enable monitor mode */ | ||
617 | dev->type = ARPHRD_IEEE80211; | ||
618 | err = hermes_docmd_wait(hw, HERMES_CMD_TEST | | ||
619 | HERMES_TEST_MONITOR, 0, NULL); | ||
620 | } else { | ||
621 | /* Disable monitor mode */ | ||
622 | dev->type = ARPHRD_ETHER; | ||
623 | err = hermes_docmd_wait(hw, HERMES_CMD_TEST | | ||
624 | HERMES_TEST_STOP, 0, NULL); | ||
625 | } | ||
626 | if (err) | ||
627 | return err; | ||
628 | |||
629 | /* Reset promiscuity / multicast*/ | ||
630 | priv->promiscuous = 0; | ||
631 | priv->mc_count = 0; | ||
632 | |||
633 | return 0; | ||
634 | } | ||
635 | |||
409 | /* Get tsc from the firmware */ | 636 | /* Get tsc from the firmware */ |
410 | int orinoco_hw_get_tkip_iv(struct orinoco_private *priv, int key, u8 *tsc) | 637 | int orinoco_hw_get_tkip_iv(struct orinoco_private *priv, int key, u8 *tsc) |
411 | { | 638 | { |
diff --git a/drivers/net/wireless/orinoco/hw.h b/drivers/net/wireless/orinoco/hw.h index 84c108cc0f52..210c2b1b7f97 100644 --- a/drivers/net/wireless/orinoco/hw.h +++ b/drivers/net/wireless/orinoco/hw.h | |||
@@ -29,6 +29,7 @@ int orinoco_hw_allocate_fid(struct orinoco_private *priv); | |||
29 | int orinoco_get_bitratemode(int bitrate, int automatic); | 29 | int orinoco_get_bitratemode(int bitrate, int automatic); |
30 | void orinoco_get_ratemode_cfg(int ratemode, int *bitrate, int *automatic); | 30 | void orinoco_get_ratemode_cfg(int ratemode, int *bitrate, int *automatic); |
31 | 31 | ||
32 | int orinoco_hw_program_rids(struct orinoco_private *priv); | ||
32 | int orinoco_hw_get_tkip_iv(struct orinoco_private *priv, int key, u8 *tsc); | 33 | int orinoco_hw_get_tkip_iv(struct orinoco_private *priv, int key, u8 *tsc); |
33 | int __orinoco_hw_set_bitrate(struct orinoco_private *priv); | 34 | int __orinoco_hw_set_bitrate(struct orinoco_private *priv); |
34 | int orinoco_hw_get_act_bitrate(struct orinoco_private *priv, int *bitrate); | 35 | int orinoco_hw_get_act_bitrate(struct orinoco_private *priv, int *bitrate); |
diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c index 0727b41a397e..dab6649ad0cb 100644 --- a/drivers/net/wireless/orinoco/main.c +++ b/drivers/net/wireless/orinoco/main.c | |||
@@ -210,9 +210,10 @@ struct orinoco_rx_data { | |||
210 | /* Function prototypes */ | 210 | /* Function prototypes */ |
211 | /********************************************************************/ | 211 | /********************************************************************/ |
212 | 212 | ||
213 | static void __orinoco_set_multicast_list(struct net_device *dev); | 213 | static int __orinoco_set_multicast_list(struct net_device *dev); |
214 | static int __orinoco_up(struct orinoco_private *priv); | 214 | static int __orinoco_up(struct orinoco_private *priv); |
215 | static int __orinoco_down(struct orinoco_private *priv); | 215 | static int __orinoco_down(struct orinoco_private *priv); |
216 | static int __orinoco_commit(struct orinoco_private *priv); | ||
216 | 217 | ||
217 | /********************************************************************/ | 218 | /********************************************************************/ |
218 | /* Internal helper functions */ | 219 | /* Internal helper functions */ |
@@ -1524,7 +1525,7 @@ static int __orinoco_up(struct orinoco_private *priv) | |||
1524 | 1525 | ||
1525 | netif_carrier_off(dev); /* just to make sure */ | 1526 | netif_carrier_off(dev); /* just to make sure */ |
1526 | 1527 | ||
1527 | err = __orinoco_program_rids(dev); | 1528 | err = __orinoco_commit(priv); |
1528 | if (err) { | 1529 | if (err) { |
1529 | printk(KERN_ERR "%s: Error %d configuring card\n", | 1530 | printk(KERN_ERR "%s: Error %d configuring card\n", |
1530 | dev->name, err); | 1531 | dev->name, err); |
@@ -1593,237 +1594,7 @@ static int orinoco_reinit_firmware(struct orinoco_private *priv) | |||
1593 | return err; | 1594 | return err; |
1594 | } | 1595 | } |
1595 | 1596 | ||
1596 | int __orinoco_program_rids(struct net_device *dev) | 1597 | static int |
1597 | { | ||
1598 | struct orinoco_private *priv = ndev_priv(dev); | ||
1599 | hermes_t *hw = &priv->hw; | ||
1600 | int err; | ||
1601 | struct hermes_idstring idbuf; | ||
1602 | |||
1603 | /* Set the MAC address */ | ||
1604 | err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR, | ||
1605 | HERMES_BYTES_TO_RECLEN(ETH_ALEN), dev->dev_addr); | ||
1606 | if (err) { | ||
1607 | printk(KERN_ERR "%s: Error %d setting MAC address\n", | ||
1608 | dev->name, err); | ||
1609 | return err; | ||
1610 | } | ||
1611 | |||
1612 | /* Set up the link mode */ | ||
1613 | err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFPORTTYPE, | ||
1614 | priv->port_type); | ||
1615 | if (err) { | ||
1616 | printk(KERN_ERR "%s: Error %d setting port type\n", | ||
1617 | dev->name, err); | ||
1618 | return err; | ||
1619 | } | ||
1620 | /* Set the channel/frequency */ | ||
1621 | if (priv->channel != 0 && priv->iw_mode != IW_MODE_INFRA) { | ||
1622 | err = hermes_write_wordrec(hw, USER_BAP, | ||
1623 | HERMES_RID_CNFOWNCHANNEL, | ||
1624 | priv->channel); | ||
1625 | if (err) { | ||
1626 | printk(KERN_ERR "%s: Error %d setting channel %d\n", | ||
1627 | dev->name, err, priv->channel); | ||
1628 | return err; | ||
1629 | } | ||
1630 | } | ||
1631 | |||
1632 | if (priv->has_ibss) { | ||
1633 | u16 createibss; | ||
1634 | |||
1635 | if ((strlen(priv->desired_essid) == 0) && (priv->createibss)) { | ||
1636 | printk(KERN_WARNING "%s: This firmware requires an " | ||
1637 | "ESSID in IBSS-Ad-Hoc mode.\n", dev->name); | ||
1638 | /* With wvlan_cs, in this case, we would crash. | ||
1639 | * hopefully, this driver will behave better... | ||
1640 | * Jean II */ | ||
1641 | createibss = 0; | ||
1642 | } else { | ||
1643 | createibss = priv->createibss; | ||
1644 | } | ||
1645 | |||
1646 | err = hermes_write_wordrec(hw, USER_BAP, | ||
1647 | HERMES_RID_CNFCREATEIBSS, | ||
1648 | createibss); | ||
1649 | if (err) { | ||
1650 | printk(KERN_ERR "%s: Error %d setting CREATEIBSS\n", | ||
1651 | dev->name, err); | ||
1652 | return err; | ||
1653 | } | ||
1654 | } | ||
1655 | |||
1656 | /* Set the desired BSSID */ | ||
1657 | err = __orinoco_hw_set_wap(priv); | ||
1658 | if (err) { | ||
1659 | printk(KERN_ERR "%s: Error %d setting AP address\n", | ||
1660 | dev->name, err); | ||
1661 | return err; | ||
1662 | } | ||
1663 | /* Set the desired ESSID */ | ||
1664 | idbuf.len = cpu_to_le16(strlen(priv->desired_essid)); | ||
1665 | memcpy(&idbuf.val, priv->desired_essid, sizeof(idbuf.val)); | ||
1666 | /* WinXP wants partner to configure OWNSSID even in IBSS mode. (jimc) */ | ||
1667 | err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNSSID, | ||
1668 | HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2), | ||
1669 | &idbuf); | ||
1670 | if (err) { | ||
1671 | printk(KERN_ERR "%s: Error %d setting OWNSSID\n", | ||
1672 | dev->name, err); | ||
1673 | return err; | ||
1674 | } | ||
1675 | err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFDESIREDSSID, | ||
1676 | HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2), | ||
1677 | &idbuf); | ||
1678 | if (err) { | ||
1679 | printk(KERN_ERR "%s: Error %d setting DESIREDSSID\n", | ||
1680 | dev->name, err); | ||
1681 | return err; | ||
1682 | } | ||
1683 | |||
1684 | /* Set the station name */ | ||
1685 | idbuf.len = cpu_to_le16(strlen(priv->nick)); | ||
1686 | memcpy(&idbuf.val, priv->nick, sizeof(idbuf.val)); | ||
1687 | err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME, | ||
1688 | HERMES_BYTES_TO_RECLEN(strlen(priv->nick)+2), | ||
1689 | &idbuf); | ||
1690 | if (err) { | ||
1691 | printk(KERN_ERR "%s: Error %d setting nickname\n", | ||
1692 | dev->name, err); | ||
1693 | return err; | ||
1694 | } | ||
1695 | |||
1696 | /* Set AP density */ | ||
1697 | if (priv->has_sensitivity) { | ||
1698 | err = hermes_write_wordrec(hw, USER_BAP, | ||
1699 | HERMES_RID_CNFSYSTEMSCALE, | ||
1700 | priv->ap_density); | ||
1701 | if (err) { | ||
1702 | printk(KERN_WARNING "%s: Error %d setting SYSTEMSCALE. " | ||
1703 | "Disabling sensitivity control\n", | ||
1704 | dev->name, err); | ||
1705 | |||
1706 | priv->has_sensitivity = 0; | ||
1707 | } | ||
1708 | } | ||
1709 | |||
1710 | /* Set RTS threshold */ | ||
1711 | err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD, | ||
1712 | priv->rts_thresh); | ||
1713 | if (err) { | ||
1714 | printk(KERN_ERR "%s: Error %d setting RTS threshold\n", | ||
1715 | dev->name, err); | ||
1716 | return err; | ||
1717 | } | ||
1718 | |||
1719 | /* Set fragmentation threshold or MWO robustness */ | ||
1720 | if (priv->has_mwo) | ||
1721 | err = hermes_write_wordrec(hw, USER_BAP, | ||
1722 | HERMES_RID_CNFMWOROBUST_AGERE, | ||
1723 | priv->mwo_robust); | ||
1724 | else | ||
1725 | err = hermes_write_wordrec(hw, USER_BAP, | ||
1726 | HERMES_RID_CNFFRAGMENTATIONTHRESHOLD, | ||
1727 | priv->frag_thresh); | ||
1728 | if (err) { | ||
1729 | printk(KERN_ERR "%s: Error %d setting fragmentation\n", | ||
1730 | dev->name, err); | ||
1731 | return err; | ||
1732 | } | ||
1733 | |||
1734 | /* Set bitrate */ | ||
1735 | err = __orinoco_hw_set_bitrate(priv); | ||
1736 | if (err) { | ||
1737 | printk(KERN_ERR "%s: Error %d setting bitrate\n", | ||
1738 | dev->name, err); | ||
1739 | return err; | ||
1740 | } | ||
1741 | |||
1742 | /* Set power management */ | ||
1743 | if (priv->has_pm) { | ||
1744 | err = hermes_write_wordrec(hw, USER_BAP, | ||
1745 | HERMES_RID_CNFPMENABLED, | ||
1746 | priv->pm_on); | ||
1747 | if (err) { | ||
1748 | printk(KERN_ERR "%s: Error %d setting up PM\n", | ||
1749 | dev->name, err); | ||
1750 | return err; | ||
1751 | } | ||
1752 | |||
1753 | err = hermes_write_wordrec(hw, USER_BAP, | ||
1754 | HERMES_RID_CNFMULTICASTRECEIVE, | ||
1755 | priv->pm_mcast); | ||
1756 | if (err) { | ||
1757 | printk(KERN_ERR "%s: Error %d setting up PM\n", | ||
1758 | dev->name, err); | ||
1759 | return err; | ||
1760 | } | ||
1761 | err = hermes_write_wordrec(hw, USER_BAP, | ||
1762 | HERMES_RID_CNFMAXSLEEPDURATION, | ||
1763 | priv->pm_period); | ||
1764 | if (err) { | ||
1765 | printk(KERN_ERR "%s: Error %d setting up PM\n", | ||
1766 | dev->name, err); | ||
1767 | return err; | ||
1768 | } | ||
1769 | err = hermes_write_wordrec(hw, USER_BAP, | ||
1770 | HERMES_RID_CNFPMHOLDOVERDURATION, | ||
1771 | priv->pm_timeout); | ||
1772 | if (err) { | ||
1773 | printk(KERN_ERR "%s: Error %d setting up PM\n", | ||
1774 | dev->name, err); | ||
1775 | return err; | ||
1776 | } | ||
1777 | } | ||
1778 | |||
1779 | /* Set preamble - only for Symbol so far... */ | ||
1780 | if (priv->has_preamble) { | ||
1781 | err = hermes_write_wordrec(hw, USER_BAP, | ||
1782 | HERMES_RID_CNFPREAMBLE_SYMBOL, | ||
1783 | priv->preamble); | ||
1784 | if (err) { | ||
1785 | printk(KERN_ERR "%s: Error %d setting preamble\n", | ||
1786 | dev->name, err); | ||
1787 | return err; | ||
1788 | } | ||
1789 | } | ||
1790 | |||
1791 | /* Set up encryption */ | ||
1792 | if (priv->has_wep || priv->has_wpa) { | ||
1793 | err = __orinoco_hw_setup_enc(priv); | ||
1794 | if (err) { | ||
1795 | printk(KERN_ERR "%s: Error %d activating encryption\n", | ||
1796 | dev->name, err); | ||
1797 | return err; | ||
1798 | } | ||
1799 | } | ||
1800 | |||
1801 | if (priv->iw_mode == IW_MODE_MONITOR) { | ||
1802 | /* Enable monitor mode */ | ||
1803 | dev->type = ARPHRD_IEEE80211; | ||
1804 | err = hermes_docmd_wait(hw, HERMES_CMD_TEST | | ||
1805 | HERMES_TEST_MONITOR, 0, NULL); | ||
1806 | } else { | ||
1807 | /* Disable monitor mode */ | ||
1808 | dev->type = ARPHRD_ETHER; | ||
1809 | err = hermes_docmd_wait(hw, HERMES_CMD_TEST | | ||
1810 | HERMES_TEST_STOP, 0, NULL); | ||
1811 | } | ||
1812 | if (err) | ||
1813 | return err; | ||
1814 | |||
1815 | /* Set promiscuity / multicast*/ | ||
1816 | priv->promiscuous = 0; | ||
1817 | priv->mc_count = 0; | ||
1818 | |||
1819 | /* FIXME: what about netif_tx_lock */ | ||
1820 | __orinoco_set_multicast_list(dev); | ||
1821 | |||
1822 | return 0; | ||
1823 | } | ||
1824 | |||
1825 | /* FIXME: return int? */ | ||
1826 | static void | ||
1827 | __orinoco_set_multicast_list(struct net_device *dev) | 1598 | __orinoco_set_multicast_list(struct net_device *dev) |
1828 | { | 1599 | { |
1829 | struct orinoco_private *priv = ndev_priv(dev); | 1600 | struct orinoco_private *priv = ndev_priv(dev); |
@@ -1843,6 +1614,8 @@ __orinoco_set_multicast_list(struct net_device *dev) | |||
1843 | 1614 | ||
1844 | err = __orinoco_hw_set_multicast_list(priv, dev->mc_list, mc_count, | 1615 | err = __orinoco_hw_set_multicast_list(priv, dev->mc_list, mc_count, |
1845 | promisc); | 1616 | promisc); |
1617 | |||
1618 | return err; | ||
1846 | } | 1619 | } |
1847 | 1620 | ||
1848 | /* This must be called from user context, without locks held - use | 1621 | /* This must be called from user context, without locks held - use |
@@ -1920,6 +1693,64 @@ void orinoco_reset(struct work_struct *work) | |||
1920 | printk(KERN_ERR "%s: Device has been disabled!\n", dev->name); | 1693 | printk(KERN_ERR "%s: Device has been disabled!\n", dev->name); |
1921 | } | 1694 | } |
1922 | 1695 | ||
1696 | static int __orinoco_commit(struct orinoco_private *priv) | ||
1697 | { | ||
1698 | struct net_device *dev = priv->ndev; | ||
1699 | int err = 0; | ||
1700 | |||
1701 | err = orinoco_hw_program_rids(priv); | ||
1702 | |||
1703 | /* FIXME: what about netif_tx_lock */ | ||
1704 | (void) __orinoco_set_multicast_list(dev); | ||
1705 | |||
1706 | return err; | ||
1707 | } | ||
1708 | |||
1709 | /* Ensures configuration changes are applied. May result in a reset. | ||
1710 | * The caller should hold priv->lock | ||
1711 | */ | ||
1712 | int orinoco_commit(struct orinoco_private *priv) | ||
1713 | { | ||
1714 | struct net_device *dev = priv->ndev; | ||
1715 | hermes_t *hw = &priv->hw; | ||
1716 | int err; | ||
1717 | |||
1718 | if (priv->broken_disableport) { | ||
1719 | schedule_work(&priv->reset_work); | ||
1720 | return 0; | ||
1721 | } | ||
1722 | |||
1723 | err = hermes_disable_port(hw, 0); | ||
1724 | if (err) { | ||
1725 | printk(KERN_WARNING "%s: Unable to disable port " | ||
1726 | "while reconfiguring card\n", dev->name); | ||
1727 | priv->broken_disableport = 1; | ||
1728 | goto out; | ||
1729 | } | ||
1730 | |||
1731 | err = __orinoco_commit(priv); | ||
1732 | if (err) { | ||
1733 | printk(KERN_WARNING "%s: Unable to reconfigure card\n", | ||
1734 | dev->name); | ||
1735 | goto out; | ||
1736 | } | ||
1737 | |||
1738 | err = hermes_enable_port(hw, 0); | ||
1739 | if (err) { | ||
1740 | printk(KERN_WARNING "%s: Unable to enable port while reconfiguring card\n", | ||
1741 | dev->name); | ||
1742 | goto out; | ||
1743 | } | ||
1744 | |||
1745 | out: | ||
1746 | if (err) { | ||
1747 | printk(KERN_WARNING "%s: Resetting instead...\n", dev->name); | ||
1748 | schedule_work(&priv->reset_work); | ||
1749 | err = 0; | ||
1750 | } | ||
1751 | return err; | ||
1752 | } | ||
1753 | |||
1923 | /********************************************************************/ | 1754 | /********************************************************************/ |
1924 | /* Interrupt handler */ | 1755 | /* Interrupt handler */ |
1925 | /********************************************************************/ | 1756 | /********************************************************************/ |
diff --git a/drivers/net/wireless/orinoco/main.h b/drivers/net/wireless/orinoco/main.h index af2bae4fe395..21ab36cd76c7 100644 --- a/drivers/net/wireless/orinoco/main.h +++ b/drivers/net/wireless/orinoco/main.h | |||
@@ -29,10 +29,9 @@ struct net_device; | |||
29 | struct work_struct; | 29 | struct work_struct; |
30 | 30 | ||
31 | void set_port_type(struct orinoco_private *priv); | 31 | void set_port_type(struct orinoco_private *priv); |
32 | int __orinoco_program_rids(struct net_device *dev); | 32 | int orinoco_commit(struct orinoco_private *priv); |
33 | void orinoco_reset(struct work_struct *work); | 33 | void orinoco_reset(struct work_struct *work); |
34 | 34 | ||
35 | |||
36 | /* Information element helpers - find a home for these... */ | 35 | /* Information element helpers - find a home for these... */ |
37 | static inline u8 *orinoco_get_ie(u8 *data, size_t len, | 36 | static inline u8 *orinoco_get_ie(u8 *data, size_t len, |
38 | enum ieee80211_eid eid) | 37 | enum ieee80211_eid eid) |
diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c index 74892e1d34ae..4c20b1d5c2a2 100644 --- a/drivers/net/wireless/orinoco/wext.c +++ b/drivers/net/wireless/orinoco/wext.c | |||
@@ -2163,49 +2163,16 @@ static int orinoco_ioctl_commit(struct net_device *dev, | |||
2163 | char *extra) | 2163 | char *extra) |
2164 | { | 2164 | { |
2165 | struct orinoco_private *priv = ndev_priv(dev); | 2165 | struct orinoco_private *priv = ndev_priv(dev); |
2166 | struct hermes *hw = &priv->hw; | ||
2167 | unsigned long flags; | 2166 | unsigned long flags; |
2168 | int err = 0; | 2167 | int err = 0; |
2169 | 2168 | ||
2170 | if (!priv->open) | 2169 | if (!priv->open) |
2171 | return 0; | 2170 | return 0; |
2172 | 2171 | ||
2173 | if (priv->broken_disableport) { | ||
2174 | orinoco_reset(&priv->reset_work); | ||
2175 | return 0; | ||
2176 | } | ||
2177 | |||
2178 | if (orinoco_lock(priv, &flags) != 0) | 2172 | if (orinoco_lock(priv, &flags) != 0) |
2179 | return err; | 2173 | return err; |
2180 | 2174 | ||
2181 | err = hermes_disable_port(hw, 0); | 2175 | err = orinoco_commit(priv); |
2182 | if (err) { | ||
2183 | printk(KERN_WARNING "%s: Unable to disable port " | ||
2184 | "while reconfiguring card\n", dev->name); | ||
2185 | priv->broken_disableport = 1; | ||
2186 | goto out; | ||
2187 | } | ||
2188 | |||
2189 | err = __orinoco_program_rids(dev); | ||
2190 | if (err) { | ||
2191 | printk(KERN_WARNING "%s: Unable to reconfigure card\n", | ||
2192 | dev->name); | ||
2193 | goto out; | ||
2194 | } | ||
2195 | |||
2196 | err = hermes_enable_port(hw, 0); | ||
2197 | if (err) { | ||
2198 | printk(KERN_WARNING "%s: Unable to enable port while reconfiguring card\n", | ||
2199 | dev->name); | ||
2200 | goto out; | ||
2201 | } | ||
2202 | |||
2203 | out: | ||
2204 | if (err) { | ||
2205 | printk(KERN_WARNING "%s: Resetting instead...\n", dev->name); | ||
2206 | schedule_work(&priv->reset_work); | ||
2207 | err = 0; | ||
2208 | } | ||
2209 | 2176 | ||
2210 | orinoco_unlock(priv, &flags); | 2177 | orinoco_unlock(priv, &flags); |
2211 | return err; | 2178 | return err; |