📄 orinoco.c
字号:
if (priv->has_sensitivity) { err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFSYSTEMSCALE, priv->ap_density); if (err) { printk(KERN_WARNING "%s: Error %d setting SYSTEMSCALE. " "Disabling sensitivity control\n", dev->name, err); priv->has_sensitivity = 0; } } /* Set RTS threshold */ err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD, priv->rts_thresh); if (err) { printk(KERN_ERR "%s: Error %d setting RTS threshold\n", dev->name, err); return err; } /* Set fragmentation threshold or MWO robustness */ if (priv->has_mwo) err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFMWOROBUST_AGERE, priv->mwo_robust); else err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFFRAGMENTATIONTHRESHOLD, priv->frag_thresh); if (err) { printk(KERN_ERR "%s: Error %d setting framentation\n", dev->name, err); return err; } /* Set bitrate */ err = __orinoco_hw_set_bitrate(priv); if (err) { printk(KERN_ERR "%s: Error %d setting bitrate\n", dev->name, err); return err; } /* Set power management */ if (priv->has_pm) { err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFPMENABLED, priv->pm_on); if (err) { printk(KERN_ERR "%s: Error %d setting up PM\n", dev->name, err); return err; } err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFMULTICASTRECEIVE, priv->pm_mcast); if (err) { printk(KERN_ERR "%s: Error %d setting up PM\n", dev->name, err); return err; } err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFMAXSLEEPDURATION, priv->pm_period); if (err) { printk(KERN_ERR "%s: Error %d setting up PM\n", dev->name, err); return err; } err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFPMHOLDOVERDURATION, priv->pm_timeout); if (err) { printk(KERN_ERR "%s: Error %d setting up PM\n", dev->name, err); return err; } } /* Set preamble - only for Symbol so far... */ if (priv->has_preamble) { err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFPREAMBLE_SYMBOL, priv->preamble); if (err) { printk(KERN_ERR "%s: Error %d setting preamble\n", dev->name, err); return err; } } /* Set up encryption */ if (priv->has_wep) { err = __orinoco_hw_setup_wep(priv); if (err) { printk(KERN_ERR "%s: Error %d activating WEP\n", dev->name, err); return err; } } /* Set promiscuity / multicast*/ priv->promiscuous = 0; priv->mc_count = 0; __orinoco_set_multicast_list(dev); /* FIXME: what about the xmit_lock */ return 0;}/* xyzzy */static int orinoco_reconfigure(struct net_device *dev){ struct orinoco_private *priv = dev->priv; struct hermes *hw = &priv->hw; unsigned long flags; int err = 0; if (priv->broken_disableport) { schedule_work(&priv->reset_work); return 0; } err = orinoco_lock(priv, &flags); if (err) return err; err = hermes_disable_port(hw, 0); if (err) { printk(KERN_WARNING "%s: Unable to disable port while reconfiguring card\n", dev->name); priv->broken_disableport = 1; goto out; } err = __orinoco_program_rids(dev); if (err) { printk(KERN_WARNING "%s: Unable to reconfigure card\n", dev->name); goto out; } err = hermes_enable_port(hw, 0); if (err) { printk(KERN_WARNING "%s: Unable to enable port while reconfiguring card\n", dev->name); goto out; } out: if (err) { printk(KERN_WARNING "%s: Resetting instead...\n", dev->name); schedule_work(&priv->reset_work); err = 0; } orinoco_unlock(priv, &flags); return err;}/* This must be called from user context, without locks held - use * schedule_work() */static void orinoco_reset(struct net_device *dev){ struct orinoco_private *priv = dev->priv; struct hermes *hw = &priv->hw; int err; unsigned long flags; err = orinoco_lock(priv, &flags); if (err) /* When the hardware becomes available again, whatever * detects that is responsible for re-initializing * it. So no need for anything further*/ return; netif_stop_queue(dev); /* Shut off interrupts. Depending on what state the hardware * is in, this might not work, but we'll try anyway */ hermes_set_irqmask(hw, 0); hermes_write_regn(hw, EVACK, 0xffff); priv->hw_unavailable++; priv->last_linkstatus = 0xffff; /* firmware will have to reassociate */ priv->connected = 0; orinoco_unlock(priv, &flags); if (priv->hard_reset) err = (*priv->hard_reset)(priv); if (err) { printk(KERN_ERR "%s: orinoco_reset: Error %d performing hard reset\n", dev->name, err); /* FIXME: shutdown of some sort */ return; } err = orinoco_reinit_firmware(dev); if (err) { printk(KERN_ERR "%s: orinoco_reset: Error %d re-initializing firmware\n", dev->name, err); return; } spin_lock_irq(&priv->lock); /* This has to be called from user context */ priv->hw_unavailable--; /* priv->open or priv->hw_unavailable might have changed while * we dropped the lock */ if (priv->open && (! priv->hw_unavailable)) { err = __orinoco_up(dev); if (err) { printk(KERN_ERR "%s: orinoco_reset: Error %d reenabling card\n", dev->name, err); } else dev->trans_start = jiffies; } spin_unlock_irq(&priv->lock); return;}/********************************************************************//* Internal helper functions *//********************************************************************/static inline voidset_port_type(struct orinoco_private *priv){ switch (priv->iw_mode) { case IW_MODE_INFRA: priv->port_type = 1; priv->createibss = 0; break; case IW_MODE_ADHOC: if (priv->prefer_port3) { priv->port_type = 3; priv->createibss = 0; } else { priv->port_type = priv->ibss_port; priv->createibss = 1; } break; default: printk(KERN_ERR "%s: Invalid priv->iw_mode in set_port_type()\n", priv->ndev->name); }}/* Does the frame have a SNAP header indicating it should be * de-encapsulated to Ethernet-II? */static inline intis_ethersnap(struct header_struct *hdr){ /* We de-encapsulate all packets which, a) have SNAP headers * (i.e. SSAP=DSAP=0xaa and CTRL=0x3 in the 802.2 LLC header * and where b) the OUI of the SNAP header is 00:00:00 or * 00:00:f8 - we need both because different APs appear to use * different OUIs for some reason */ return (memcmp(&hdr->dsap, &encaps_hdr, 5) == 0) && ( (hdr->oui[2] == 0x00) || (hdr->oui[2] == 0xf8) );}static voidorinoco_set_multicast_list(struct net_device *dev){ struct orinoco_private *priv = dev->priv; unsigned long flags; if (orinoco_lock(priv, &flags) != 0) { printk(KERN_DEBUG "%s: orinoco_set_multicast_list() " "called when hw_unavailable\n", dev->name); return; } __orinoco_set_multicast_list(dev); orinoco_unlock(priv, &flags);}/********************************************************************//* Hardware control functions *//********************************************************************/static int __orinoco_hw_set_bitrate(struct orinoco_private *priv){ hermes_t *hw = &priv->hw; int err = 0; if (priv->bitratemode >= BITRATE_TABLE_SIZE) { printk(KERN_ERR "%s: BUG: Invalid bitrate mode %d\n", priv->ndev->name, priv->bitratemode); return -EINVAL; } switch (priv->firmware_type) { case FIRMWARE_TYPE_AGERE: err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFTXRATECONTROL, bitrate_table[priv->bitratemode].agere_txratectrl); break; case FIRMWARE_TYPE_INTERSIL: case FIRMWARE_TYPE_SYMBOL: err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFTXRATECONTROL, bitrate_table[priv->bitratemode].intersil_txratectrl); break; default: BUG(); } return err;}static int __orinoco_hw_setup_wep(struct orinoco_private *priv){ hermes_t *hw = &priv->hw; int err = 0; int master_wep_flag; int auth_flag; switch (priv->firmware_type) { case FIRMWARE_TYPE_AGERE: /* Agere style WEP */ if (priv->wep_on) { err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFTXKEY_AGERE, priv->tx_key); if (err) return err; err = HERMES_WRITE_RECORD(hw, USER_BAP, HERMES_RID_CNFWEPKEYS_AGERE, &priv->keys); if (err) return err; } err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFWEPENABLED_AGERE, priv->wep_on); if (err) return err; break; case FIRMWARE_TYPE_INTERSIL: /* Intersil style WEP */ case FIRMWARE_TYPE_SYMBOL: /* Symbol style WEP */ master_wep_flag = 0; /* Off */ if (priv->wep_on) { int keylen; int i; /* Fudge around firmware weirdness */ keylen = le16_to_cpu(priv->keys[priv->tx_key].len); /* Write all 4 keys */ for(i = 0; i < ORINOCO_MAX_KEYS; i++) {/* int keylen = le16_to_cpu(priv->keys[i].len); */ if (keylen > LARGE_KEY_SIZE) { printk(KERN_ERR "%s: BUG: Key %d has oversize length %d.\n", priv->ndev->name, i, keylen); return -E2BIG; } err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFDEFAULTKEY0 + i, HERMES_BYTES_TO_RECLEN(keylen), priv->keys[i].data); if (err) return err; } /* Write the index of the key used in transmission */ err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFWEPDEFAULTKEYID, priv->tx_key); if (err) return err; if (priv->wep_restrict) { auth_flag = 2; master_wep_flag = 3; } else { /* Authentication is where Intersil and Symbol * firmware differ... */ auth_flag = 1; if (priv->firmware_type == FIRMWARE_TYPE_SYMBOL) master_wep_flag = 3; /* Symbol */ else master_wep_flag = 1; /* Intersil */ } err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFAUTHENTICATION, auth_flag); if (err) return err; } /* Master WEP setting : on/off */ err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFWEPFLAGS_INTERSIL, master_wep_flag); if (err) return err; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -