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

📄 at76c503.c

📁 无线网卡驱动程序 802.11b无线网卡可直接移植到2.6内核中去
💻 C
📖 第 1 页 / 共 5 页
字号:
	assert(ptr != NULL);	memset(&join, 0, sizeof(struct at76c503_join));	memcpy(join.bssid, ptr->bssid, ETH_ALEN);	memcpy(join.essid, ptr->ssid, ptr->ssid_len);	join.essid_size = ptr->ssid_len;	join.bss_type = (dev->iw_mode == IW_MODE_ADHOC ? 1 : 2);	join.channel = ptr->channel;	join.timeout = cpu_to_le16(2000);	dbg(DBG_PROGRESS, "%s join addr %s ssid %s type %d ch %d timeout %d",	    dev->netdev->name, mac2str(join.bssid), 	    join.essid, join.bss_type, join.channel, le16_to_cpu(join.timeout));	return set_card_command(dev->udev, CMD_JOIN,				(unsigned char*)&join,				sizeof(struct at76c503_join));} /* join_bss *//* the firmware download timeout (after remap) */void fw_dl_timeout(unsigned long par){	struct at76c503 *dev = (struct at76c503 *)par;	defer_kevent(dev, KEVENT_RESET_DEVICE);}/* the restart timer timed out */void restart_timeout(unsigned long par){	struct at76c503 *dev = (struct at76c503 *)par;	defer_kevent(dev, KEVENT_RESTART);}/* we got to check the bss_list for old entries */void bss_list_timeout(unsigned long par){	struct at76c503 *dev = (struct at76c503 *)par;	unsigned long flags;	struct list_head *lptr, *nptr;	struct bss_info *ptr;	spin_lock_irqsave(&dev->bss_list_spinlock, flags);	list_for_each_safe(lptr, nptr, &dev->bss_list) {		ptr = list_entry(lptr, struct bss_info, list);		if (ptr != dev->curr_bss && ptr != dev->new_bss &&		    time_after(jiffies, ptr->last_rx+BSS_LIST_TIMEOUT)) {			dbg(DBG_BSS_TABLE_RM,			    "%s: bss_list: removing old BSS %s ch %d",			    dev->netdev->name, mac2str(ptr->bssid), ptr->channel);			list_del(&ptr->list);			kfree(ptr);		}	}	spin_unlock_irqrestore(&dev->bss_list_spinlock, flags);	/* restart the timer */	mod_timer(&dev->bss_list_timer, jiffies+BSS_LIST_TIMEOUT);	}/* we got a timeout for a infrastructure mgmt packet */void mgmt_timeout(unsigned long par){	struct at76c503 *dev = (struct at76c503 *)par;	defer_kevent(dev, KEVENT_MGMT_TIMEOUT);}/* == PROC handle_mgmt_timeout_scan == *//* called in istate SCANNING on expiry of the mgmt_timer, when a scan was run before   (dev->scan_runs > 0) */void handle_mgmt_timeout_scan(struct at76c503 *dev){	u8 *cmd_status;	int ret;	struct mib_mdomain mdomain;	cmd_status = kmalloc(40, GFP_KERNEL);	if (cmd_status == NULL) {		err("%s: %s: cmd_status kmalloc returned NULL", 		    dev->netdev->name, __FUNCTION__);		return;	}		if ((ret=get_cmd_status(dev->udev, CMD_SCAN, cmd_status)) < 0) {		err("%s: %s: get_cmd_status failed with %d",		    dev->netdev->name, __FUNCTION__, ret);		cmd_status[5] = CMD_STATUS_IN_PROGRESS;	                /* INFO: Hope it was a one off error - if not, scanning 		   further down the line and stop this cycle */	}	dbg(DBG_PROGRESS, "%s %s:%d got cmd_status %d (istate %d, "	    "scan_runs %d)",	    dev->netdev->name, __FUNCTION__, __LINE__, cmd_status[5],	    dev->istate, dev->scan_runs);	if (cmd_status[5] == CMD_STATUS_COMPLETE) {		if (dev->istate == SCANNING) {			dump_bss_table(dev,0);			switch (dev->scan_runs) {			case 1:				assert(dev->international_roaming);				if ((ret=get_mib_mdomain(dev, &mdomain)) < 0) {					err("get_mib_mdomain returned %d", ret);				} else {					char obuf1[2*14+1], obuf2[2*14+1];										dbg(DBG_MIB, "%s: MIB MDOMAIN: channel_list %s "					    "tx_powerlevel %s",					    dev->netdev->name,					    hex2str(obuf1, mdomain.channel_list,						    (sizeof(obuf1)-1)/2,'\0'),					    hex2str(obuf2, mdomain.tx_powerlevel,						    (sizeof(obuf2)-1)/2,'\0'));				}				if ((ret = start_scan(dev, 0, 1)) < 0) {					err("%s: %s: start_scan (ANY) failed with %d", 					    dev->netdev->name, __FUNCTION__, ret);				}				dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer for %d ticks",				    __FUNCTION__, __LINE__, SCAN_POLL_INTERVAL);				mod_timer(&dev->mgmt_timer, jiffies + SCAN_POLL_INTERVAL);				break;			case 2:				if ((ret = start_scan(dev, 1, 1)) < 0) {					err("%s: %s: start_scan (SSID) failed with %d", 					    dev->netdev->name, __FUNCTION__, ret);				}				dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer for %d ticks",				    __FUNCTION__, __LINE__, SCAN_POLL_INTERVAL);				mod_timer(&dev->mgmt_timer, jiffies + SCAN_POLL_INTERVAL);				break;			case 3:				/* report the end of scan to user space */				iwevent_scan_complete(dev->netdev);				NEW_STATE(dev,JOINING);				assert(dev->curr_bss == NULL); /* done in free_bss_list, 								  find_bss will start with first bss */				/* call join_bss immediately after				   re-run of all other threads in kevent */				defer_kevent(dev,KEVENT_JOIN);				break;			default:				err("unexpected dev->scan_runs %d", dev->scan_runs);			} /* switch (dev->scan_runs)*/			dev->scan_runs++;		} else {			assert(dev->istate == MONITORING);			dbg(DBG_MONITOR_MODE, "%s: MONITOR MODE: restart scan",			    dev->netdev->name);			start_scan(dev, 0, 0);			dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer for %d ticks",			    __FUNCTION__, __LINE__, SCAN_POLL_INTERVAL);			mod_timer(&dev->mgmt_timer, jiffies + SCAN_POLL_INTERVAL);		}	} else { 		if ((cmd_status[5] != CMD_STATUS_IN_PROGRESS) &&		    (cmd_status[5] != CMD_STATUS_IDLE))			err("%s: %s: Bad scan status: %s", 			    dev->netdev->name, __FUNCTION__, 			    get_cmd_status_string(cmd_status[5]));		/* the first cmd status after scan start is always a IDLE ->		   start the timer to poll again until COMPLETED */		dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer for %d ticks",		    __FUNCTION__, __LINE__, SCAN_POLL_INTERVAL);		mod_timer(&dev->mgmt_timer, jiffies + SCAN_POLL_INTERVAL);	}	kfree(cmd_status);}/* the deferred procedure called from kevent() */void handle_mgmt_timeout(struct at76c503 *dev){	if ((dev->istate != SCANNING && dev->istate != MONITORING) || 	     (debug & DBG_MGMT_TIMER))		/* this is normal behaviour in states MONITORING, SCANNING ... */		dbg(DBG_PROGRESS, "%s: timeout, state %d", dev->netdev->name,		    dev->istate);	switch(dev->istate) {	case MONITORING:	case SCANNING: 		handle_mgmt_timeout_scan(dev);		break;	case JOINING:		assert(0);		break;	case CONNECTED: /* we haven't received the beacon of this BSS for 			   BEACON_TIMEOUT seconds */		info("%s: lost beacon bssid %s",		     dev->netdev->name, mac2str(dev->curr_bss->bssid));		/* jal: starting mgmt_timer in adhoc mode is questionable, 		   but I'll leave it here to track down another lockup problem */		if (dev->iw_mode != IW_MODE_ADHOC) {			netif_carrier_off(dev->netdev);			netif_stop_queue(dev->netdev);			iwevent_bss_disconnect(dev->netdev);			NEW_STATE(dev,SCANNING);			defer_kevent(dev,KEVENT_SCAN);		}		break;	case AUTHENTICATING:		if (dev->retries-- >= 0) {			auth_req(dev, dev->curr_bss, 1, NULL);			dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ",			    __FUNCTION__, __LINE__);			mod_timer(&dev->mgmt_timer, jiffies+HZ);		} else {			/* try to get next matching BSS */			NEW_STATE(dev,JOINING);			defer_kevent(dev,KEVENT_JOIN);		}		break;	case ASSOCIATING:		if (dev->retries-- >= 0) {			assoc_req(dev,dev->curr_bss);			dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ",			    __FUNCTION__, __LINE__);			mod_timer(&dev->mgmt_timer, jiffies+HZ);		} else {			/* jal: TODO: we may be authenticated to several			   BSS and may try to associate to the next of them here			   in the future ... */			/* try to get next matching BSS */			NEW_STATE(dev,JOINING);			defer_kevent(dev,KEVENT_JOIN);		}		break;	case REASSOCIATING:		if (dev->retries-- >= 0)			reassoc_req(dev, dev->curr_bss, dev->new_bss);		else {			/* we disassociate from the curr_bss and			   scan again ... */			NEW_STATE(dev,DISASSOCIATING);			dev->retries = DISASSOC_RETRIES;			disassoc_req(dev, dev->curr_bss);		}		dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ",		    __FUNCTION__, __LINE__);		mod_timer(&dev->mgmt_timer, jiffies+HZ);		break;	case DISASSOCIATING:		if (dev->retries-- >= 0) {			disassoc_req(dev, dev->curr_bss);			dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ",			    __FUNCTION__, __LINE__);			mod_timer(&dev->mgmt_timer,jiffies+HZ);		} else {			/* we scan again ... */			NEW_STATE(dev,SCANNING);			defer_kevent(dev,KEVENT_SCAN);		}		break;	case INIT:		break;	default:		assert(0);	} /* switch (dev->istate) */}/* handle_mgmt_timeout *//* calc. the padding from txbuf->wlength (which excludes the USB TX header)    guess this is needed to compensate a flaw in the AT76C503A USB part ... */static inlineint calc_padding(int wlen){	/* add the USB TX header */	wlen += AT76C503_TX_HDRLEN;	wlen = wlen % 64;	if (wlen < 50)		return 50 - wlen;	if (wlen >=61)		return 64 + 50 - wlen;	return 0;}/* send a management frame on bulk-out.   txbuf->wlength must be set (in LE format !) */staticint send_mgmt_bulk(struct at76c503 *dev, struct at76c503_tx_buffer *txbuf){	unsigned long flags;	int ret = 0;	int urb_status;	void *oldbuf = NULL;	netif_carrier_off(dev->netdev); /* disable running netdev watchdog */	netif_stop_queue(dev->netdev); /* stop tx data packets */	spin_lock_irqsave(&dev->mgmt_spinlock, flags);	if ((urb_status=dev->write_urb->status) == USB_ST_URB_PENDING) {		oldbuf=dev->next_mgmt_bulk; /* to kfree below */		dev->next_mgmt_bulk = txbuf;		txbuf = NULL;	}	spin_unlock_irqrestore(&dev->mgmt_spinlock, flags);	if (oldbuf) {		/* a data/mgmt tx is already pending in the URB -		   if this is no error in some situations we must		   implement a queue or silently modify the old msg */		err("%s: %s removed pending mgmt buffer %s",		    dev->netdev->name, __FUNCTION__,		    hex2str(dev->obuf, (u8 *)dev->next_mgmt_bulk,			    min((int)(sizeof(dev->obuf))/3, 64),' '));		kfree(dev->next_mgmt_bulk);	}	if (txbuf) {		txbuf->tx_rate = 0;//		txbuf->padding = 0;		txbuf->padding = 		   cpu_to_le16(calc_padding(le16_to_cpu(txbuf->wlength)));		if (dev->next_mgmt_bulk) {			err("%s: %s URB status %d, but mgmt is pending",			    dev->netdev->name, __FUNCTION__, urb_status);		}		dbg(DBG_TX_MGMT, "%s: tx mgmt: wlen %d tx_rate %d pad %d %s",		    dev->netdev->name, le16_to_cpu(txbuf->wlength),		    txbuf->tx_rate, le16_to_cpu(txbuf->padding),		    hex2str(dev->obuf, txbuf->packet,			    min((sizeof(dev->obuf)-1)/2,				(size_t)le16_to_cpu(txbuf->wlength)),'\0'));		/* txbuf was not consumed above -> send mgmt msg immediately */		memcpy(dev->bulk_out_buffer, txbuf,		       le16_to_cpu(txbuf->wlength) + AT76C503_TX_HDRLEN);		FILL_BULK_URB(dev->write_urb, dev->udev,			      usb_sndbulkpipe(dev->udev, 					      dev->bulk_out_endpointAddr),			      dev->bulk_out_buffer,			      le16_to_cpu(txbuf->wlength) + 			      le16_to_cpu(txbuf->padding) +			      AT76C503_TX_HDRLEN,			      (usb_complete_t)at76c503_write_bulk_callback, dev);		ret = submit_urb(dev->write_urb, GFP_ATOMIC);		if (ret) {			err("%s: %s error in tx submit urb: %d",			    dev->netdev->name, __FUNCTION__, ret);		}		kfree(txbuf);	} /* if (txbuf) */	return ret;} /* send_mgmt_bulk */staticint disassoc_req(struct at76c503 *dev, struct bss_info *bss){	struct at76c503_tx_buffer *tx_buffer;	struct ieee802_11_mgmt *mgmt;	struct ieee802_11_disassoc_frame *req;	assert(bss != NULL);	if (bss == NULL)		return -EFAULT;	tx_buffer = kmalloc(DISASSOC_FRAME_SIZE + MAX_PADDING_SIZE,			    GFP_ATOMIC);	if (!tx_buffer)		return -ENOMEM;	mgmt = (struct ieee802_11_mgmt *)&(tx_buffer->packet);	req  = (struct ieee802_11_disassoc_frame *)&(mgmt->data);	/* make wireless header */	mgmt->frame_ctl = cpu_to_le16(IEEE802_11_FTYPE_MGMT|IEEE802_11_STYPE_AUTH);	mgmt->duration_id = cpu_to_le16(0x8000);	memcpy(mgmt->addr1, bss->bssid, ETH_ALEN);	memcpy(mgmt->addr2, dev->netdev->dev_addr, ETH_ALEN);	memcpy(mgmt->addr3, bss->bssid, ETH_ALEN);	mgmt->seq_ctl = cpu_to_le16(0);	req->reason = 0;	/* init. at76c503 tx header */	tx_buffer->wlength = cpu_to_le16(DISASSOC_FRAME_SIZE -		AT76C503_TX_HDRLEN);		dbg(DBG_TX_MGMT, "%s: DisAssocReq bssid %s",	    dev->netdev->name, mac2str(mgmt->addr3));	/* either send immediately (if no data tx is pending	   or put it in pending list */	return send_mgmt_bulk(dev, tx_buffer); } /* disassoc_req *//* challenge is the challenge string (in TLV format)    we got with seq_nr 2 for shared secret authentication only and   send in seq_nr 3 WEP encrypted to prove we have the correct WEP key;   otherwise it is NULL */staticint auth_req(struct at76c503 *dev, struct bss_info *bss, int seq_nr, u8 *challenge){	struct at76c503_tx_buffer *tx_buffer;	struct ieee802_11_mgmt *mgmt;	struct ieee802_11_auth_frame *req;		int buf_len = (seq_nr != 3 ? AUTH_FRAME_SIZE : 		       AUTH_FRAME_SIZE + 1 + 1 + challenge[1]);	assert(bss != NULL);	assert(seq_nr != 3 || challenge != NULL);		tx_buffer = kmalloc(buf_len + MAX_PADDING_SIZE, GFP_ATOMIC);	if (!tx_buffer)		return -ENOMEM;	mgmt = (struct ieee802_11_mgmt *)&(tx_buffer->packet);	req  = (struct ieee802_11_auth_fr

⌨️ 快捷键说明

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