⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 orinoco.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,				char buf[IW_ESSID_MAX_SIZE+1]){	hermes_t *hw = &priv->hw;	int err = 0;	struct hermes_idstring essidbuf;	char *p = (char *)(&essidbuf.val);	int len;	unsigned long flags;	err = orinoco_lock(priv, &flags);	if (err)		return err;	if (strlen(priv->desired_essid) > 0) {		/* We read the desired SSID from the hardware rather		   than from priv->desired_essid, just in case the		   firmware is allowed to change it on us. I'm not		   sure about this */		/* My guess is that the OWNSSID should always be whatever		 * we set to the card, whereas CURRENT_SSID is the one that		 * may change... - Jean II */		u16 rid;		*active = 1;		rid = (priv->port_type == 3) ? HERMES_RID_CNFOWNSSID :			HERMES_RID_CNFDESIREDSSID;				err = hermes_read_ltv(hw, USER_BAP, rid, sizeof(essidbuf),				      NULL, &essidbuf);		if (err)			goto fail_unlock;	} else {		*active = 0;		err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTSSID,				      sizeof(essidbuf), NULL, &essidbuf);		if (err)			goto fail_unlock;	}	len = le16_to_cpu(essidbuf.len);	memset(buf, 0, IW_ESSID_MAX_SIZE+1);	memcpy(buf, p, len);	buf[len] = '\0'; fail_unlock:	orinoco_unlock(priv, &flags);	return err;       }static long orinoco_hw_get_freq(struct orinoco_private *priv){		hermes_t *hw = &priv->hw;	int err = 0;	u16 channel;	long freq = 0;	unsigned long flags;	err = orinoco_lock(priv, &flags);	if (err)		return err;		err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CURRENTCHANNEL, &channel);	if (err)		goto out;	/* Intersil firmware 1.3.5 returns 0 when the interface is down */	if (channel == 0) {		err = -EBUSY;		goto out;	}	if ( (channel < 1) || (channel > NUM_CHANNELS) ) {		printk(KERN_WARNING "%s: Channel out of range (%d)!\n",		       priv->ndev->name, channel);		err = -EBUSY;		goto out;	}	freq = channel_frequency[channel-1] * 100000; out:	orinoco_unlock(priv, &flags);	if (err > 0)		err = -EBUSY;	return err ? err : freq;}static int orinoco_hw_get_bitratelist(struct orinoco_private *priv,				      int *numrates, s32 *rates, int max){	hermes_t *hw = &priv->hw;	struct hermes_idstring list;	unsigned char *p = (unsigned char *)&list.val;	int err = 0;	int num;	int i;	unsigned long flags;	err = orinoco_lock(priv, &flags);	if (err)		return err;	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_SUPPORTEDDATARATES,			      sizeof(list), NULL, &list);	orinoco_unlock(priv, &flags);	if (err)		return err;		num = le16_to_cpu(list.len);	*numrates = num;	num = min(num, max);	for (i = 0; i < num; i++) {		rates[i] = (p[i] & 0x7f) * 500000; /* convert to bps */	}	return 0;}#if 0static void show_rx_frame(struct orinoco_rxframe_hdr *frame){	printk(KERN_DEBUG "RX descriptor:\n");	printk(KERN_DEBUG "  status      = 0x%04x\n", frame->desc.status);	printk(KERN_DEBUG "  time        = 0x%08x\n", frame->desc.time);	printk(KERN_DEBUG "  silence     = 0x%02x\n", frame->desc.silence);	printk(KERN_DEBUG "  signal      = 0x%02x\n", frame->desc.signal);	printk(KERN_DEBUG "  rate        = 0x%02x\n", frame->desc.rate);	printk(KERN_DEBUG "  rxflow      = 0x%02x\n", frame->desc.rxflow);	printk(KERN_DEBUG "  reserved    = 0x%08x\n", frame->desc.reserved);	printk(KERN_DEBUG "IEEE 802.11 header:\n");	printk(KERN_DEBUG "  frame_ctl   = 0x%04x\n",	       frame->p80211.frame_ctl);	printk(KERN_DEBUG "  duration_id = 0x%04x\n",	       frame->p80211.duration_id);	printk(KERN_DEBUG "  addr1       = %02x:%02x:%02x:%02x:%02x:%02x\n",	       frame->p80211.addr1[0], frame->p80211.addr1[1],	       frame->p80211.addr1[2], frame->p80211.addr1[3],	       frame->p80211.addr1[4], frame->p80211.addr1[5]);	printk(KERN_DEBUG "  addr2       = %02x:%02x:%02x:%02x:%02x:%02x\n",	       frame->p80211.addr2[0], frame->p80211.addr2[1],	       frame->p80211.addr2[2], frame->p80211.addr2[3],	       frame->p80211.addr2[4], frame->p80211.addr2[5]);	printk(KERN_DEBUG "  addr3       = %02x:%02x:%02x:%02x:%02x:%02x\n",	       frame->p80211.addr3[0], frame->p80211.addr3[1],	       frame->p80211.addr3[2], frame->p80211.addr3[3],	       frame->p80211.addr3[4], frame->p80211.addr3[5]);	printk(KERN_DEBUG "  seq_ctl     = 0x%04x\n",	       frame->p80211.seq_ctl);	printk(KERN_DEBUG "  addr4       = %02x:%02x:%02x:%02x:%02x:%02x\n",	       frame->p80211.addr4[0], frame->p80211.addr4[1],	       frame->p80211.addr4[2], frame->p80211.addr4[3],	       frame->p80211.addr4[4], frame->p80211.addr4[5]);	printk(KERN_DEBUG "  data_len    = 0x%04x\n",	       frame->p80211.data_len);	printk(KERN_DEBUG "IEEE 802.3 header:\n");	printk(KERN_DEBUG "  dest        = %02x:%02x:%02x:%02x:%02x:%02x\n",	       frame->p8023.h_dest[0], frame->p8023.h_dest[1],	       frame->p8023.h_dest[2], frame->p8023.h_dest[3],	       frame->p8023.h_dest[4], frame->p8023.h_dest[5]);	printk(KERN_DEBUG "  src         = %02x:%02x:%02x:%02x:%02x:%02x\n",	       frame->p8023.h_source[0], frame->p8023.h_source[1],	       frame->p8023.h_source[2], frame->p8023.h_source[3],	       frame->p8023.h_source[4], frame->p8023.h_source[5]);	printk(KERN_DEBUG "  len         = 0x%04x\n", frame->p8023.h_proto);	printk(KERN_DEBUG "IEEE 802.2 LLC/SNAP header:\n");	printk(KERN_DEBUG "  DSAP        = 0x%02x\n", frame->p8022.dsap);	printk(KERN_DEBUG "  SSAP        = 0x%02x\n", frame->p8022.ssap);	printk(KERN_DEBUG "  ctrl        = 0x%02x\n", frame->p8022.ctrl);	printk(KERN_DEBUG "  OUI         = %02x:%02x:%02x\n",	       frame->p8022.oui[0], frame->p8022.oui[1], frame->p8022.oui[2]);	printk(KERN_DEBUG "  ethertype  = 0x%04x\n", frame->ethertype);}#endif /* 0 *//* * Interrupt handler */irqreturn_t orinoco_interrupt(int irq, void *dev_id, struct pt_regs *regs){	struct net_device *dev = (struct net_device *)dev_id;	struct orinoco_private *priv = netdev_priv(dev);	hermes_t *hw = &priv->hw;	int count = MAX_IRQLOOPS_PER_IRQ;	u16 evstat, events;	/* These are used to detect a runaway interrupt situation */	/* If we get more than MAX_IRQLOOPS_PER_JIFFY iterations in a jiffy,	 * we panic and shut down the hardware */	static int last_irq_jiffy = 0; /* jiffies value the last time we were called */	static int loops_this_jiffy = 0;	unsigned long flags;	if (orinoco_lock(priv, &flags) != 0) {		/* If hw is unavailable - we don't know if the irq was		 * for us or not */		return IRQ_HANDLED;	}	evstat = hermes_read_regn(hw, EVSTAT);	events = evstat & hw->inten;	if (! events) {		orinoco_unlock(priv, &flags);		return IRQ_NONE;	}		if (jiffies != last_irq_jiffy)		loops_this_jiffy = 0;	last_irq_jiffy = jiffies;	while (events && count--) {		if (++loops_this_jiffy > MAX_IRQLOOPS_PER_JIFFY) {			printk(KERN_WARNING "%s: IRQ handler is looping too "			       "much! Resetting.\n", dev->name);			/* Disable interrupts for now */			hermes_set_irqmask(hw, 0);			schedule_work(&priv->reset_work);			break;		}		/* Check the card hasn't been removed */		if (! hermes_present(hw)) {			DEBUG(0, "orinoco_interrupt(): card removed\n");			break;		}		if (events & HERMES_EV_TICK)			__orinoco_ev_tick(dev, hw);		if (events & HERMES_EV_WTERR)			__orinoco_ev_wterr(dev, hw);		if (events & HERMES_EV_INFDROP)			__orinoco_ev_infdrop(dev, hw);		if (events & HERMES_EV_INFO)			__orinoco_ev_info(dev, hw);		if (events & HERMES_EV_RX)			__orinoco_ev_rx(dev, hw);		if (events & HERMES_EV_TXEXC)			__orinoco_ev_txexc(dev, hw);		if (events & HERMES_EV_TX)			__orinoco_ev_tx(dev, hw);		if (events & HERMES_EV_ALLOC)			__orinoco_ev_alloc(dev, hw);				hermes_write_regn(hw, EVACK, events);		evstat = hermes_read_regn(hw, EVSTAT);		events = evstat & hw->inten;	};	orinoco_unlock(priv, &flags);	return IRQ_HANDLED;}static void __orinoco_ev_tick(struct net_device *dev, hermes_t *hw){	printk(KERN_DEBUG "%s: TICK\n", dev->name);}static void __orinoco_ev_wterr(struct net_device *dev, hermes_t *hw){	/* This seems to happen a fair bit under load, but ignoring it	   seems to work fine...*/	printk(KERN_DEBUG "%s: MAC controller error (WTERR). Ignoring.\n",	       dev->name);}static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw){	if (net_ratelimit())		printk(KERN_WARNING "%s: Information frame lost.\n", dev->name);}static void print_linkstatus(struct net_device *dev, u16 status){	char * s;	if (suppress_linkstatus)		return;	switch (status) {	case HERMES_LINKSTATUS_NOT_CONNECTED:		s = "Not Connected";		break;	case HERMES_LINKSTATUS_CONNECTED:		s = "Connected";		break;	case HERMES_LINKSTATUS_DISCONNECTED:		s = "Disconnected";		break;	case HERMES_LINKSTATUS_AP_CHANGE:		s = "AP Changed";		break;	case HERMES_LINKSTATUS_AP_OUT_OF_RANGE:		s = "AP Out of Range";		break;	case HERMES_LINKSTATUS_AP_IN_RANGE:		s = "AP In Range";		break;	case HERMES_LINKSTATUS_ASSOC_FAILED:		s = "Association Failed";		break;	default:		s = "UNKNOWN";	}		printk(KERN_INFO "%s: New link status: %s (%04x)\n",	       dev->name, s, status);}static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw){	struct orinoco_private *priv = netdev_priv(dev);	u16 infofid;	struct {		u16 len;		u16 type;	} __attribute__ ((packed)) info;	int len, type;	int err;	/* This is an answer to an INQUIRE command that we did earlier,	 * or an information "event" generated by the card	 * The controller return to us a pseudo frame containing	 * the information in question - Jean II */	infofid = hermes_read_regn(hw, INFOFID);	/* Read the info frame header - don't try too hard */	err = hermes_bap_pread(hw, IRQ_BAP, &info, sizeof(info),			       infofid, 0);	if (err) {		printk(KERN_ERR "%s: error %d reading info frame. "		       "Frame dropped.\n", dev->name, err);		return;	}		len = HERMES_RECLEN_TO_BYTES(le16_to_cpu(info.len));	type = le16_to_cpu(info.type);	switch (type) {	case HERMES_INQ_TALLIES: {		struct hermes_tallies_frame tallies;		struct iw_statistics *wstats = &priv->wstats;				if (len > sizeof(tallies)) {			printk(KERN_WARNING "%s: Tallies frame too long (%d bytes)\n",			       dev->name, len);			len = sizeof(tallies);		}				/* Read directly the data (no seek) */		hermes_read_words(hw, HERMES_DATA1, (void *) &tallies,				  len / 2); /* FIXME: blech! */				/* Increment our various counters */		/* wstats->discard.nwid - no wrong BSSID stuff */		wstats->discard.code +=			le16_to_cpu(tallies.RxWEPUndecryptable);		if (len == sizeof(tallies))  			wstats->discard.code +=				le16_to_cpu(tallies.RxDiscards_WEPICVError) +				le16_to_cpu(tallies.RxDiscards_WEPExcluded);		wstats->discard.misc +=			le16_to_cpu(tallies.TxDiscardsWrongSA);#if WIRELESS_EXT > 11		wstats->discard.fragment +=			le16_to_cpu(tallies.RxMsgInBadMsgFragments);		wstats->discard.retries +=			le16_to_cpu(tallies.TxRetryLimitExceeded);		/* wstats->miss.beacon - no match */#endif /* WIRELESS_EXT > 11 */	}	break;	case HERMES_INQ_LINKSTATUS: {		struct hermes_linkstatus linkstatus;		u16 newstatus;				if (len != sizeof(linkstatus)) {			printk(KERN_WARNING "%s: Unexpected size for linkstatus frame (%d bytes)\n",			       dev->name, len);			break;		}		hermes_read_words(hw, HERMES_DATA1, (void *) &linkstatus,				  len / 2);		newstatus = le16_to_cpu(linkstatus.linkstatus);		if ( (newstatus == HERMES_LINKSTATUS_CONNECTED)		     || (newstatus == HERMES_LINKSTATUS_AP_CHANGE)		     || (newstatus == HERMES_LINKSTATUS_AP_IN_RANGE) )			priv->connected = 1;		else if ( (newstatus == HERMES_LINKSTATUS_NOT_CONNECTED)			  || (newstatus == HERMES_LINKSTATUS_DISCONNECTED)			  || (newstatus == HERMES_LINKSTATUS_AP_OUT_OF_RANGE)			  || (newstatus == HERMES_LINKSTATUS_ASSOC_FAILED) )			priv->connected = 0;		if (newstatus != priv->last_linkstatus)			print_linkstatus(dev, newstatus);		priv->last_linkstatus = newstatus;	}	break;	default:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -