diff -u orinoco-0.13e-snax/orinoco.c orinoco-0.13e-dragorn/orinoco.c --- orinoco-0.13e-snax/orinoco.c 2004-02-02 14:50:41.000000000 -0500 +++ orinoco-0.13e-dragorn/orinoco.c 2004-02-02 14:45:26.000000000 -0500 @@ -458,6 +458,7 @@ #endif static int suppress_linkstatus; /* = 0 */ +static int suppress_linkstatus_copy; /* = 0 */ MODULE_PARM(suppress_linkstatus, "i"); /********************************************************************/ @@ -728,6 +729,8 @@ hermes_t *hw = &priv->hw; int err; struct hermes_idstring idbuf; + int word; + hermes_response_t resp; /* Set the MAC address */ err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR, @@ -906,6 +909,27 @@ priv->mc_count = 0; __orinoco_set_multicast_list(dev); /* FIXME: what about the xmit_lock */ + /* + * Set the rfmon mode of the card, if we're in rfmon. Otherwise, the firmware + * starts sending out a flood of probe requests. We already reinited the firmware + * before. + * - Dragorn + */ + if (dev->type == ARPHRD_IEEE80211_PRISM || dev->type == ARPHRD_IEEE80211) { + word = HFA384x_PORTTYPE_IBSS; + err = hermes_write_wordrec(hw, USER_BAP, + HERMES_RID_CNF_PORTTYPE, word); + if (err) + return err; + + /* Enable monitor mode */ + word = HERMES_CMD_MONITOR | (HERMES_MONITOR_ENABLE << 8); + err = hermes_docmd_wait(hw, word, 0, &resp); + if (err) + return err; + } + + return 0; } @@ -926,6 +950,17 @@ if (err) return err; + /* + * If we are in rmfmon mode we need to treat this like going into rfmon again, + * so re-init the firmware like the rfmon function does. + * We'll also need to do some other rfmonish behavior in config_rids + * - Dragorn + */ + if (dev->type == ARPHRD_IEEE80211_PRISM || dev->type == ARPHRD_IEEE80211) { + hermes_set_irqmask(hw, 0); + hermes_init(hw); + hermes_set_irqmask(hw, ORINOCO_INTEN); + } err = hermes_disable_port(hw, 0); if (err) { @@ -2373,10 +2408,13 @@ return 1; } - if (! priv->connected) { + if (! priv->connected || dev->type == ARPHRD_IEEE80211_PRISM || + dev->type == ARPHRD_IEEE80211) { /* Oops, the firmware hasn't established a connection, silently drop the packet (this seems to be the safest approach). */ + /* Also silently drop the packet if we're in rfmon, because it won't do + * very good things to try to write to the BAP. - Dragorn */ stats->tx_errors++; orinoco_unlock(priv, &flags); dev_kfree_skb(skb); @@ -3665,15 +3703,16 @@ static int orinoco_wlansniff(struct net_device *dev, struct iwreq *wrq) { struct orinoco_private *priv = dev->priv; - - hermes_t *hw = &(priv->hw); + hermes_t *hw = &(priv->hw); hermes_response_t resp; - int result = 0; - uint16_t word; + int result = 0; + uint16_t word; int *parms = (int *) wrq->u.name; int enable = parms[0] > 0; unsigned long flags; + int noMonitor = dev->type != ARPHRD_IEEE80211_PRISM && + dev->type != ARPHRD_IEEE80211; orinoco_lock(priv, &flags); @@ -3681,10 +3720,11 @@ { case P80211ENUM_truth_false: /* Confirm that we're in monitor mode */ - if ( dev->type == ARPHRD_ETHER ) { + if ( noMonitor ) { result = -EFAULT; } /* Disable monitor mode */ + suppress_linkstatus = suppress_linkstatus_copy; word = HERMES_CMD_MONITOR | (HERMES_MONITOR_DISABLE << 8); result = hermes_docmd_wait(hw, word, 0, &resp); @@ -3720,81 +3760,76 @@ break; case P80211ENUM_truth_true: - /* Re-initialize the card before changing channel as advised at - * http://lists.samba.org/pipermail/wireless/2002-June/004491.html - * by Ian Goldberg. Implementation by Pat Swieskowski. - */ -// __orinoco_down(dev); - hermes_set_irqmask(hw, 0); - hermes_init(hw); -// _orinoco_up(dev); - hermes_set_irqmask(hw, ORINOCO_INTEN); -/* - __orinoco_stop_irqs(priv); - hermes_reset(hw); - __orinoco_start_irqs(priv, HERMES_EV_RX | HERMES_EV_ALLOC | - HERMES_EV_TX | HERMES_EV_TXEXC | - HERMES_EV_WTERR | HERMES_EV_INFO | - HERMES_EV_INFDROP); -*/ - /* Disable the port (if enabled), only check Port 0 */ - if ( hw->port_enabled[0] ) { - /* Save macport 0 state */ - result = hermes_read_wordrec(hw, USER_BAP, - HERMES_RID_CNF_PORTTYPE, - &(priv->presniff_port_type)); - if ( result ) break; - - /* Save the wepflags state */ - result = hermes_read_wordrec(hw, USER_BAP, - HERMES_RID_CNF_PRISM2_WEP_ON, - &(priv->presniff_wepflags)); - if ( result ) break; - result = hermes_disable_port(hw, 0); - if ( result ) break; - } - else { - priv->presniff_port_type = 0; - } - - /* Set the channel we wish to sniff */ - if (parms[1] > 0 && parms[1] < 15) { - word = parms[1]; - result = hermes_write_wordrec(hw, USER_BAP, - HERMES_RID_CNF_CHANNEL, word); - } else { - result = -EFAULT; - } - - if ( result ) break; - - /* Set the port type to pIbss */ - word = HFA384x_PORTTYPE_IBSS; - result = hermes_write_wordrec(hw, USER_BAP, - HERMES_RID_CNF_PORTTYPE, word); - if ( result ) break; - -/* - if ( (msg->keepwepflags.status == P80211ENUM_msgitem_status_data_ok) && - (msg->keepwepflags.data != P80211ENUM_truth_true)) { - // Set the wepflags for no decryption //Orinoco doesn't like this - word = HFA384x_WEPFLAGS_DISABLE_TXCRYPT | - HFA384x_WEPFLAGS_DISABLE_RXCRYPT; - result = hermes_write_wordrec(hw, USER_BAP, - HERMES_RID_CNF_PRISM2_WEP_ON, word); //won't work with the bits above - } - if ( result ) break; - -*/ - /* Enable the port */ - result = hermes_enable_port(hw, 0); - if ( result ) break; - - /* Enable monitor mode */ - word = HERMES_CMD_MONITOR | (HERMES_MONITOR_ENABLE << 8); - result = hermes_docmd_wait(hw, word, 0, &resp); - if ( result ) break; - + // Only do this if we're not in monitor mode already + if (noMonitor) { + /* Re-initialize the card before changing channel as advised at + * http://lists.samba.org/pipermail/wireless/2002-June/004491.html + * by Ian Goldberg. Implementation by Pat Swieskowski. + */ + // __orinoco_down(dev); + hermes_set_irqmask(hw, 0); + hermes_init(hw); + // _orinoco_up(dev); + hermes_set_irqmask(hw, ORINOCO_INTEN); + suppress_linkstatus = 1; + /* + __orinoco_stop_irqs(priv); + hermes_reset(hw); + __orinoco_start_irqs(priv, HERMES_EV_RX | HERMES_EV_ALLOC | + HERMES_EV_TX | HERMES_EV_TXEXC | + HERMES_EV_WTERR | HERMES_EV_INFO | + HERMES_EV_INFDROP); + */ + /* Disable the port (if enabled), only check Port 0 */ + if ( hw->port_enabled[0] ) { + /* Save macport 0 state */ + result = hermes_read_wordrec(hw, USER_BAP, + HERMES_RID_CNF_PORTTYPE, + &(priv->presniff_port_type)); + if ( result ) break; + + /* Save the wepflags state */ + result = hermes_read_wordrec(hw, USER_BAP, + HERMES_RID_CNF_PRISM2_WEP_ON, + &(priv->presniff_wepflags)); + if ( result ) break; + } + else { + priv->presniff_port_type = 0; + } + } + + // Disable the port + result = hermes_disable_port(hw, 0); + if ( result ) break; + + /* Set the channel we wish to sniff */ + if (parms[1] > 0 && parms[1] < 15) { + word = parms[1]; + result = hermes_write_wordrec(hw, USER_BAP, + HERMES_RID_CNF_CHANNEL, word); + } else { + result = -EFAULT; + } + + if ( result ) break; + + if (noMonitor) { + /* Set the port type to pIbss */ + word = HFA384x_PORTTYPE_IBSS; + result = hermes_write_wordrec(hw, USER_BAP, + HERMES_RID_CNF_PORTTYPE, word); + if ( result ) break; + + /* Enable monitor mode */ + word = HERMES_CMD_MONITOR | (HERMES_MONITOR_ENABLE << 8); + result = hermes_docmd_wait(hw, word, 0, &resp); + if ( result ) break; + } + + /* Enable the port */ + result = hermes_enable_port(hw, 0); + if ( result ) break; /* Set the driver state */ /* Do we want the prism2 header? */ if (parms[0] == 1) @@ -4610,6 +4645,7 @@ static int __init init_orinoco(void) { printk(KERN_DEBUG "%s\n", version); + suppress_linkstatus_copy = suppress_linkstatus; return 0; }