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

📄 orinoco.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
	printk(KERN_DEBUG "%s: Station name \"%s\"\n", dev->name, priv->nick);	/* Get allowed channels */	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CHANNELLIST,				  &priv->channel_mask);	if (err) {		printk(KERN_ERR "%s: failed to read channel list!\n",		       dev->name);		goto out;	}	/* Get initial AP density */	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFSYSTEMSCALE, &priv->ap_density);	if (err) {		printk(KERN_ERR "%s: failed to read AP density!\n", dev->name);		goto out;	}	/* Get initial RTS threshold */	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,				  &priv->rts_thresh);	if (err) {		printk(KERN_ERR "%s: failed to read RTS threshold!\n", dev->name);		goto out;	}	/* Get initial fragmentation settings */	if (priv->has_mwo)		err = hermes_read_wordrec(hw, USER_BAP,					  HERMES_RID_CNFMWOROBUST_AGERE,					  &priv->mwo_robust);	else		err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,					  &priv->frag_thresh);	if (err) {		printk(KERN_ERR "%s: failed to read fragmentation settings!\n", dev->name);		goto out;	}	/* Power management setup */	if (priv->has_pm) {		priv->pm_on = 0;		priv->pm_mcast = 1;		err = hermes_read_wordrec(hw, USER_BAP,					  HERMES_RID_CNFMAXSLEEPDURATION,					  &priv->pm_period);		if (err) {			printk(KERN_ERR "%s: failed to read power management period!\n",			       dev->name);			goto out;		}		err = hermes_read_wordrec(hw, USER_BAP,					  HERMES_RID_CNFPMHOLDOVERDURATION,					  &priv->pm_timeout);		if (err) {			printk(KERN_ERR "%s: failed to read power management timeout!\n",			       dev->name);			goto out;		}	}	/* Preamble setup */	if (priv->has_preamble) {		err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFPREAMBLE_SYMBOL,					  &priv->preamble);		if (err)			goto out;	}			/* Set up the default configuration */	priv->iw_mode = IW_MODE_INFRA;	/* By default use IEEE/IBSS ad-hoc mode if we have it */	priv->prefer_port3 = priv->has_port3 && (! priv->has_ibss);	set_port_type(priv);	priv->promiscuous = 0;	priv->wep_on = 0;	priv->tx_key = 0;	printk(KERN_DEBUG "%s: ready\n", dev->name); out:	orinoco_unlock(priv);	TRACE_EXIT("orinoco");	return err;}struct net_device_stats *orinoco_get_stats(struct net_device *dev){	struct orinoco_private *priv = (struct orinoco_private *)dev->priv;		return &priv->stats;}struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev){	struct orinoco_private *priv = (struct orinoco_private *)dev->priv;	hermes_t *hw = &priv->hw;	struct iw_statistics *wstats = &priv->wstats;	int err = 0;	if (! netif_device_present(dev))		return NULL; /* FIXME: We may be able to do better than this */	orinoco_lock(priv);	if (priv->iw_mode == IW_MODE_ADHOC) {		memset(&wstats->qual, 0, sizeof(wstats->qual));		/* If a spy address is defined, we report stats of the		 * first spy address - Jean II */		if (SPY_NUMBER(priv)) {			wstats->qual.qual = priv->spy_stat[0].qual;			wstats->qual.level = priv->spy_stat[0].level;			wstats->qual.noise = priv->spy_stat[0].noise;			wstats->qual.updated = priv->spy_stat[0].updated;		}	} else {		orinoco_commsqual_t cq;		err = HERMES_READ_RECORD(hw, USER_BAP,					 HERMES_RID_COMMSQUALITY, &cq);				DEBUG(3, "%s: Global stats = %X-%X-%X\n", dev->name,		      cq.qual, cq.signal, cq.noise);		wstats->qual.qual = (int)le16_to_cpu(cq.qual);		wstats->qual.level = (int)le16_to_cpu(cq.signal) - 0x95;		wstats->qual.noise = (int)le16_to_cpu(cq.noise) - 0x95;		wstats->qual.updated = 7;	}	/* We can't really wait for the tallies inquiry command to	 * complete, so we just use the previous results and trigger	 * a new tallies inquiry command for next time - Jean II */	/* FIXME: Hmm.. seems a bit ugly, I wonder if there's a way to	   do better - dgibson */	err = hermes_inquire(hw, HERMES_INQ_TALLIES);               	orinoco_unlock(priv);	if (err)		return NULL;			return wstats;}static inline void orinoco_spy_gather(struct net_device *dev, u_char *mac,				    int level, int noise){	struct orinoco_private *priv = (struct orinoco_private *)dev->priv;	int i;	/* Gather wireless spy statistics: for each packet, compare the	 * source address with out list, and if match, get the stats... */	for (i = 0; i < priv->spy_number; i++)		if (!memcmp(mac, priv->spy_address[i], ETH_ALEN)) {			priv->spy_stat[i].level = level - 0x95;			priv->spy_stat[i].noise = noise - 0x95;			priv->spy_stat[i].qual = level - noise;			priv->spy_stat[i].updated = 7;		}}voidorinoco_stat_gather( struct net_device *dev,		   struct sk_buff *skb,		   struct orinoco_rxframe_hdr *hdr){	struct orinoco_private *priv = (struct orinoco_private *)dev->priv;	/* Using spy support with lots of Rx packets, like in an	 * infrastructure (AP), will really slow down everything, because	 * the MAC address must be compared to each entry of the spy list.	 * If the user really asks for it (set some address in the	 * spy list), we do it, but he will pay the price.	 * Note that to get here, you need both WIRELESS_SPY	 * compiled in AND some addresses in the list !!!	 */	/* Note : gcc will optimise the whole section away if	 * WIRELESS_SPY is not defined... - Jean II */	if (SPY_NUMBER(priv)) {		orinoco_spy_gather(dev, skb->mac.raw + ETH_ALEN,				   hdr->desc.signal, hdr->desc.silence);	}}intorinoco_xmit(struct sk_buff *skb, struct net_device *dev){	struct orinoco_private *priv = (struct orinoco_private *)dev->priv;	struct net_device_stats *stats = &priv->stats;	hermes_t *hw = &priv->hw;	int err = 0;	u16 txfid = priv->txfid;	char *p;	struct ethhdr *eh;	int len, data_len, data_off;	struct orinoco_txframe_hdr hdr;	hermes_response_t resp;	if (! netif_running(dev)) {		printk(KERN_ERR "%s: Tx on stopped device!\n",		       dev->name);		return 1;	}		if (netif_queue_stopped(dev)) {		printk(KERN_ERR "%s: Tx while transmitter busy!\n", 		       dev->name);		return 1;	}		orinoco_lock(priv);	/* Length of the packet body */	/* FIXME: what if the skb is smaller than this? */	len = max_t(int,skb->len - ETH_HLEN, ETH_ZLEN);	eh = (struct ethhdr *)skb->data;	/* Build the IEEE 802.11 header */	memset(&hdr, 0, sizeof(hdr));	memcpy(hdr.p80211.addr1, eh->h_dest, ETH_ALEN);	memcpy(hdr.p80211.addr2, eh->h_source, ETH_ALEN);	hdr.p80211.frame_ctl = IEEE802_11_FTYPE_DATA;	/* Request an interrupt on Tx failures, but not sucesses (we           use the buffer reclaim allocation event instead */	hdr.desc.tx_control = cpu_to_le16(HERMES_TXCTRL_TX_EX | HERMES_TXCTRL_TX_OK);	/* Encapsulate Ethernet-II frames */	if (ntohs(eh->h_proto) > 1500) { /* Ethernet-II frame */		data_len = len;		data_off = sizeof(hdr);		p = skb->data + ETH_HLEN;		/* 802.11 header */		hdr.p80211.data_len = cpu_to_le16(data_len + ENCAPS_OVERHEAD);		/* 802.3 header */		memcpy(hdr.p8023.h_dest, eh->h_dest, ETH_ALEN);		memcpy(hdr.p8023.h_source, eh->h_source, ETH_ALEN);		hdr.p8023.h_proto = htons(data_len + ENCAPS_OVERHEAD);				/* 802.2 header */		memcpy(&hdr.p8022, &encaps_hdr, sizeof(encaps_hdr));					hdr.ethertype = eh->h_proto;		err  = hermes_bap_pwrite(hw, USER_BAP, &hdr, sizeof(hdr),					 txfid, 0);		if (err) {				printk(KERN_ERR "%s: Error %d writing packet header to BAP\n",				       dev->name, err);			stats->tx_errors++;			goto fail;		}	} else { /* IEEE 802.3 frame */		data_len = len + ETH_HLEN;		data_off = P8023_OFFSET;		p = skb->data;				/* 802.11 header */		hdr.p80211.data_len = cpu_to_le16(len);		err = hermes_bap_pwrite(hw, USER_BAP, &hdr, P8023_OFFSET,					txfid, 0);		if (err) {			printk(KERN_ERR			       "%s: Error %d writing packet header to BAP\n",			       dev->name, err);			stats->tx_errors++;			goto fail;		}	}	/* Round up for odd length packets */	err = hermes_bap_pwrite(hw, USER_BAP, p, RUP_EVEN(data_len), txfid, data_off);	if (err) {		printk(KERN_ERR "%s: Error %d writing packet header to BAP\n",		       dev->name, err);		stats->tx_errors++;		goto fail;	}	/* Finally, we actually initiate the send */	err = hermes_docmd_wait(hw, HERMES_CMD_TX | HERMES_CMD_RECL, txfid, &resp);	if (err) {		printk(KERN_ERR "%s: Error %d transmitting packet\n", dev->name, err);		stats->tx_errors++;		goto fail;	}	atomic_inc(&priv->queue_length);	dev->trans_start = jiffies;	stats->tx_bytes += data_off + data_len;	netif_stop_queue(dev);	orinoco_unlock(priv);	dev_kfree_skb(skb);	return 0; fail:	orinoco_unlock(priv);	return err;}voidorinoco_tx_timeout(struct net_device *dev){	struct orinoco_private *priv = (struct orinoco_private *)dev->priv;	struct net_device_stats *stats = &priv->stats;	int err = 0;	printk(KERN_WARNING "%s: Tx timeout! Resetting card.\n", dev->name);	stats->tx_errors++;	err = orinoco_reset(priv);	if (err)		printk(KERN_ERR "%s: Error %d resetting card on Tx timeout!\n",		       dev->name, err);	else {		dev->trans_start = jiffies;		netif_wake_queue(dev);	}}static int orinoco_ioctl_getiwrange(struct net_device *dev, struct iw_point *rrq){	struct orinoco_private *priv = dev->priv;	int err = 0;	int mode;	struct iw_range range;	int numrates;	int i, k;	TRACE_ENTER(dev->name);	err = verify_area(VERIFY_WRITE, rrq->pointer, sizeof(range));	if (err)		return err;	rrq->length = sizeof(range);	orinoco_lock(priv);	mode = priv->iw_mode;	orinoco_unlock(priv);	memset(&range, 0, sizeof(range));	/* Much of this shamelessly taken from wvlan_cs.c. No idea	 * what it all means -dgibson */#if WIRELESS_EXT > 10	range.we_version_compiled = WIRELESS_EXT;	range.we_version_source = 11;#endif /* WIRELESS_EXT > 10 */	range.min_nwid = range.max_nwid = 0; /* We don't use nwids */	/* Set available channels/frequencies */	range.num_channels = NUM_CHANNELS;	k = 0;	for (i = 0; i < NUM_CHANNELS; i++) {		if (priv->channel_mask & (1 << i)) {			range.freq[k].i = i + 1;			range.freq[k].m = channel_frequency[i] * 100000;			range.freq[k].e = 1;			k++;		}				if (k >= IW_MAX_FREQUENCIES)			break;	}	range.num_frequency = k;	range.sensitivity = 3;	if ((mode == IW_MODE_ADHOC) && (priv->spy_number == 0)){		/* Quality stats meaningless in ad-hoc mode */		range.max_qual.qual = 0;		range.max_qual.level = 0;		range.max_qual.noise = 0;#if WIRELESS_EXT > 11		range.avg_qual.qual = 0;		range.avg_qual.level = 0;		range.avg_qual.noise = 0;#endif /* WIRELESS_EXT > 11 */	} else {		range.max_qual.qual = 0x8b - 0x2f;		range.max_qual.level = 0x2f - 0x95 - 1;		range.max_qual.noise = 0x2f - 0x95 - 1;#if WIRELESS_EXT > 11		/* Need to get better values */		range.avg_qual.qual = 0x24;		range.avg_qual.level = 0xC2;		range.avg_qual.noise = 0x9E;#endif /* WIRELESS_EXT > 11 */	}	err = orinoco_hw_get_bitratelist(priv, &numrates,				       range.bitrate, IW_MAX_BITRATES);	if (err)		return err;	range.num_bitrates = numrates;		/* Set an indication of the max TCP throughput in bit/s that we can	 * expect using this interface. May be use for QoS stuff...	 * Jean II */	if(numrates > 2)		range.throughput = 5 * 1000 * 1000;	/* ~5 Mb/s */	else		range.throughput = 1.5 * 1000 * 1000;	/* ~1.5 Mb/s */	range.min_rts = 0;	range.max_rts = 2347;

⌨️ 快捷键说明

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