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

📄 at76c503.c

📁 无线网卡驱动程序 802.11b无线网卡可直接移植到2.6内核中去
💻 C
📖 第 1 页 / 共 5 页
字号:
#define KEVENT_NEW_BSS 2#define KEVENT_SET_PROMISC 3#define KEVENT_MGMT_TIMEOUT 4#define KEVENT_SCAN 5 #define KEVENT_JOIN 6#define KEVENT_STARTIBSS 7#define KEVENT_SUBMIT_RX 8#define KEVENT_RESTART 9 /* restart the device */#define KEVENT_ASSOC_DONE  10 /* execute the power save settings:			     listen interval, pm mode, assoc id */#define KEVENT_EXTERNAL_FW  11#define KEVENT_INTERNAL_FW  12#define KEVENT_RESET_DEVICE 13#define KEVENT_MONITOR      14static DECLARE_WAIT_QUEUE_HEAD(wait_queue);static u8 snapsig[] = {0xaa, 0xaa, 0x03};//#ifdef COLLAPSE_RFC1042/* RFC 1042 encapsulates Ethernet frames in 802.2 SNAP (0xaa, 0xaa, 0x03) with * a SNAP OID of 0 (0x00, 0x00, 0x00) */static u8 rfc1042sig[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};//#endif /* COLLAPSE_RFC1042 *//* local function prototypes */static void iwspy_update(struct at76c503 *dev, struct at76c503_rx_buffer *buf);static void at76c503_read_bulk_callback (struct urb *urb);static void at76c503_write_bulk_callback(struct urb *urb);static void defer_kevent (struct at76c503 *dev, int flag);static struct bss_info *find_matching_bss(struct at76c503 *dev,					  struct bss_info *curr);static int auth_req(struct at76c503 *dev, struct bss_info *bss, int seq_nr,		    u8 *challenge);static int disassoc_req(struct at76c503 *dev, struct bss_info *bss);static int assoc_req(struct at76c503 *dev, struct bss_info *bss);static int reassoc_req(struct at76c503 *dev, struct bss_info *curr,		       struct bss_info *new);static void dump_bss_table(struct at76c503 *dev, int force_output);static int submit_rx_urb(struct at76c503 *dev);static int startup_device(struct at76c503 *dev);#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8)static int update_usb_intf_descr(struct at76c503 *dev);#endifstatic int set_iroaming(struct at76c503 *dev, int onoff);static void set_monitor_mode(struct at76c503 *dev, int use_prism);/* disassemble the firmware image */static int at76c503_get_fw_info(u8 *fw_data, int fw_size,				u32 *board, u32 *version, char **str,				u8 **ext_fw, u32 *ext_fw_size,				u8 **int_fw, u32 *int_fw_size);/* second step of initialisation (after fw download) */static int init_new_device(struct at76c503 *dev);/* some abbrev. for wireless events */static inline void iwevent_scan_complete(struct net_device *dev){	union iwreq_data wrqu;	wrqu.data.length = 0;	wrqu.data.flags = 0;	wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);	dbg(DBG_WE_EVENTS, "%s: SIOCGIWSCAN sent", dev->name);}static inline void iwevent_bss_connect(struct net_device *dev, u8 *bssid){	union iwreq_data wrqu;	wrqu.data.length = 0;	wrqu.data.flags = 0;	memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN);	wrqu.ap_addr.sa_family = ARPHRD_ETHER;	wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);	dbg(DBG_WE_EVENTS, "%s: %s: SIOCGIWAP sent", dev->name, __FUNCTION__);}static inline void iwevent_bss_disconnect(struct net_device *dev){	union iwreq_data wrqu;	wrqu.data.length = 0;	wrqu.data.flags = 0;	memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);	wrqu.ap_addr.sa_family = ARPHRD_ETHER;	wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);	dbg(DBG_WE_EVENTS, "%s: %s: SIOCGIWAP sent", dev->name, __FUNCTION__);}/* hexdump len many bytes from buf into obuf, separated by delim,   add a trailing \0 into obuf */static char *hex2str(char *obuf, u8 *buf, int len, char delim){#define BIN2HEX(x) ((x) < 10 ? '0'+(x) : (x)+'A'-10)  char *ret = obuf;  while (len--) {    *obuf++ = BIN2HEX(*buf>>4);    *obuf++ = BIN2HEX(*buf&0xf);    if (delim != '\0')      *obuf++ = delim;    buf++;  }  if (delim != '\0' && obuf > ret)	  obuf--; // remove last inserted delimiter  *obuf = '\0';  return ret;}/* == PROC is_cloaked_ssid ==   returns != 0, if the given SSID is a cloaked one:   - length 0   - length > 0, all bytes are \0   - length == 1, SSID ' '*/static inline int is_cloaked_ssid(u8 *ssid, int length){	return (length == 0) || 		(length == 1 && *ssid == ' ') ||		(length > 0 && !memcmp(ssid,zeros,length));}static inline void free_bss_list(struct at76c503 *dev){	struct list_head *next, *ptr;	unsigned long flags;	spin_lock_irqsave(&dev->bss_list_spinlock, flags);	dev->curr_bss = dev->new_bss = NULL;	list_for_each_safe(ptr, next, &dev->bss_list) {		list_del(ptr);		kfree(list_entry(ptr, struct bss_info, list));	}	spin_unlock_irqrestore(&dev->bss_list_spinlock, flags);}static inline char *mac2str(u8 *mac){	static char str [6*3];  	sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x",		mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);	return str;}#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8)/* == PROC analyze_usb_config ==    This procedure analyzes the configuration after the   USB device got reset and find the start of the interface and the   two endpoint descriptors.   Returns < 0 if the descriptors seems to be wrong. */static int analyze_usb_config(u8 *cfgd, int cfgd_len,				int *intf_idx, int *ep0_idx, int *ep1_idx){	u8 *cfgd_start = cfgd;	u8 *cfgd_end = cfgd + cfgd_len; /* first byte after config descriptor */	int nr_intf=0, nr_ep=0; /* number of interface, number of endpoint descr.			       found */	assert(cfgd_len >= 2);	if (cfgd_len < 2)		return -1;	if (*(cfgd+1) != USB_DT_CONFIG) {		err("not a config descriptor");		return -2;	}	if (*cfgd != USB_DT_CONFIG_SIZE) {		err("invalid length for config descriptor: %d", *cfgd);		return -3;	}	/* scan the config descr */	while ((cfgd+1) < cfgd_end) {		switch (*(cfgd+1)) {		case USB_DT_INTERFACE:			nr_intf++;			if (nr_intf == 1)				*intf_idx = cfgd - cfgd_start;			break;		case USB_DT_ENDPOINT:			nr_ep++;			if (nr_ep == 1)				*ep0_idx = cfgd - cfgd_start;			else				if (nr_ep == 2)					*ep1_idx = cfgd - cfgd_start;			break;		default:			;		}		cfgd += *cfgd;	} /* while ((cfgd+1) < cfgd_end) */	if (nr_ep != 2 || nr_intf != 1) {		err("unexpected nr of intf (%d) or endpoints (%d)",		    nr_intf, nr_ep);		return -4;	}	return 0;} /* end of analyze_usb_config *//* == PROC update_usb_intf_descr ==   currently (2.6.0-test2) usb_reset_device() does not recognize that   the interface descr. are changed.   This procedure reads the configuration and does a limited parsing of   the interface and endpoint descriptors.   This is IMHO needed until usb_reset_device() is changed inside the   kernel's USB subsystem.   Copied from usb/core/config.c:usb_get_configuration()   THIS IS VERY UGLY CODE - DO NOT COPY IT ! */#define AT76C503A_USB_CONFDESCR_LEN 0x20/* the short configuration descriptor before reset *///#define AT76C503A_USB_SHORT_CONFDESCR_LEN 0x19static int update_usb_intf_descr(struct at76c503 *dev){	int intf0; /* begin of intf descriptor in configuration */ 	int ep0, ep1; /* begin of endpoint descriptors */	struct usb_device *udev = dev->udev;	struct usb_config_descriptor *cfg_desc;	int result = 0, size;	u8 *buffer;	struct usb_host_interface *ifp;	int i;	dbg(DBG_DEVSTART, "%s: ENTER", __FUNCTION__);	cfg_desc = (struct usb_config_descriptor *)		kmalloc(AT76C503A_USB_CONFDESCR_LEN, GFP_KERNEL);	if (!cfg_desc) {		err("cannot kmalloc config desc");		return -ENOMEM;	}	result = usb_get_descriptor(udev, USB_DT_CONFIG, 0,				    cfg_desc, AT76C503A_USB_CONFDESCR_LEN);	if (result < AT76C503A_USB_CONFDESCR_LEN) {		if (result < 0)			err("unable to get descriptor");		else {			err("config descriptor too short (expected >= %i, got %i)",			    AT76C503A_USB_CONFDESCR_LEN, result);			result = -EINVAL;		}		goto err;	}	/* now check the config descriptor */	le16_to_cpus(&cfg_desc->wTotalLength);	size = cfg_desc->wTotalLength;	buffer = (u8 *)cfg_desc;		if (cfg_desc->bNumInterfaces > 1) {		err("found %d interfaces", cfg_desc->bNumInterfaces);		result = - EINVAL;		goto err;	}	if ((result=analyze_usb_config(buffer, size, &intf0, &ep0, &ep1))) {		err("analyze_usb_config returned %d for config desc %s",		    result,		    hex2str(dev->obuf, (u8 *)cfg_desc, 			    min((int)(sizeof(dev->obuf)-1)/2,size), '\0'));		result=-EINVAL;		goto err;	}	/* we got the correct config descriptor - update the interface's endpoints */	ifp = &udev->actconfig->interface[0]->altsetting[0];	if (ifp->endpoint)		kfree(ifp->endpoint);	memcpy(&ifp->desc, buffer+intf0, USB_DT_INTERFACE_SIZE);	if (!(ifp->endpoint = kmalloc(2 * sizeof(struct usb_host_endpoint), 				      GFP_KERNEL))) {		result = -ENOMEM;		goto err;	}	memset(ifp->endpoint, 0, 2 * sizeof(struct usb_host_endpoint));	memcpy(&ifp->endpoint[0].desc, buffer+ep0, USB_DT_ENDPOINT_SIZE);	le16_to_cpus(&ifp->endpoint[0].desc.wMaxPacketSize);	memcpy(&ifp->endpoint[1].desc, buffer+ep1, USB_DT_ENDPOINT_SIZE);	le16_to_cpus(&ifp->endpoint[1].desc.wMaxPacketSize);	/* we must set the max packet for the new ep (see usb_set_maxpacket() ) */#define usb_endpoint_out(ep_dir)	(!((ep_dir) & USB_DIR_IN))	for(i=0; i < ifp->desc.bNumEndpoints; i++) {		struct usb_endpoint_descriptor	*d = &ifp->endpoint[i].desc;				int b = d->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;		if (usb_endpoint_out(d->bEndpointAddress)) {			if (d->wMaxPacketSize > udev->epmaxpacketout[b])				udev->epmaxpacketout[b] = d->wMaxPacketSize;		} else {			if (d->wMaxPacketSize > udev->epmaxpacketin[b])				udev->epmaxpacketin[b] = d->wMaxPacketSize;		}	}			     	dbg(DBG_DEVSTART, "%s: ifp %p num_altsetting %d "	    "endpoint addr x%x, x%x", __FUNCTION__,	    ifp, udev->actconfig->interface[0]->num_altsetting,	    ifp->endpoint[0].desc.bEndpointAddress,	    ifp->endpoint[1].desc.bEndpointAddress);	result = 0;err:	kfree(cfg_desc);	dbg(DBG_DEVSTART, "%s: EXIT with %d", __FUNCTION__, result);	return result;} /* update_usb_intf_descr */		#endif	/* #if  LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8) */int at76c503_remap(struct usb_device *udev){	int ret;	ret = usb_control_msg(udev, usb_sndctrlpipe(udev,0),			      0x0a, INTERFACE_VENDOR_REQUEST_OUT,			      0, 0,			      NULL, 0, HZ * USB_CTRL_GET_TIMEOUT);	if (ret < 0)		return ret;	return 0;}static int get_op_mode(struct usb_device *udev){	int ret;	u8 op_mode;	ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),			      0x33, INTERFACE_VENDOR_REQUEST_IN,			      0x01, 0,			      &op_mode, 1, HZ * USB_CTRL_GET_TIMEOUT);	if(ret < 0)		return ret;	return op_mode;}/* this loads a block of the second part of the firmware */static inlineint load_ext_fw_block(struct usb_device *udev,		      int i, unsigned char *buf, int bsize){	return usb_control_msg(udev, usb_sndctrlpipe(udev,0),			       0x0e, DEVICE_VENDOR_REQUEST_OUT,			       0x0802, i,			       buf, bsize, HZ * USB_CTRL_GET_TIMEOUT);}static inlineint get_hw_cfg_rfmd(struct usb_device *udev,	       unsigned char *buf, int buf_size){	return usb_control_msg(udev, usb_rcvctrlpipe(udev,0),			       0x33, INTERFACE_VENDOR_REQUEST_IN,			       ((0x0a << 8) | 0x02), 0,			       buf, buf_size, HZ * USB_CTRL_GET_TIMEOUT);}/* Intersil boards use a different "value" for GetHWConfig requests */static inlineint get_hw_cfg_intersil(struct usb_device *udev,	       unsigned char *buf, int buf_size){	return usb_control_msg(udev, usb_rcvctrlpipe(udev,0),			       0x33, INTERFACE_VENDOR_REQUEST_IN,			       ((0x09 << 8) | 0x02), 0,			       buf, buf_size, HZ * USB_CTRL_GET_TIMEOUT);}/* Get the hardware configuration for the adapter and place the appropriate * data in the appropriate fields of 'dev' (the GetHWConfig request and * interpretation of the result depends on the type of board we're dealing * with) */static int get_hw_config(struct at76c503 *dev){	int ret;	union {		struct hwcfg_intersil i;		struct hwcfg_rfmd     r3;		struct hwcfg_r505     r5;	} *hwcfg = kmalloc(sizeof(*hwcfg), GFP_KERNEL);	if (!hwcfg)		return -ENOMEM;	switch (dev->board_type) {	  case BOARDTYPE_503_INTERSIL_3861:	  case BOARDTYPE_503_INTERSIL_3863:		ret = get_hw_cfg_intersil(dev->udev, (unsigned char *)&hwcfg->i, sizeof(hwcfg->i));		if (ret < 0) break;		memcpy(dev->mac_addr, hwcfg->i.mac_addr, ETH_ALEN);		memcpy(dev->cr31_values, hwcfg->i.cr31_values, 14);		memcpy(dev->cr58_values, hwcfg->i.cr58_values, 14);		memcpy(dev->pidvid, hwcfg->i.pidvid, 4);		dev->regulatory_domain = hwcfg->i.regulatory_domain;		break;	  case BOARDTYPE_503_RFMD:	  case BOARDTYPE_503_RFMD_ACC:		ret = get_hw_cfg_rfmd(dev->udev, (unsigned char *)&hwcfg->r3, sizeof(hwcfg->r3));		if (ret < 0) break;		memcpy(dev->cr20_values, hwcfg->r3.cr20_values, 14);		memcpy(dev->cr21_values, hwcfg->r3.cr21_values, 14);		memcpy(dev->bb_cr, hwcfg->r3.bb_cr, 14);		memcpy(dev->pidvid, hwcfg->r3.pidvid, 4);		memcpy(dev->mac_addr, hwcfg->r3.mac_addr, ETH_ALEN);		dev->regulatory_domain = hwcfg->r3.regulatory_domain;		memcpy(dev->low_power_values, hwcfg->r3.low_power_values, 14);		memcpy(dev->normal_power_values, hwcfg->r3.normal_power_values, 14);		break;	  case BOARDTYPE_505_RFMD:	  case BOARDTYPE_505_RFMD_2958:	  case BOARDTYPE_505A_RFMD_2958:		ret = get_hw_cfg_rfmd(dev->udev, (unsigned char *)&hwcfg->r5, sizeof(hwcfg->r5));		if (ret < 0) break;		memcpy(dev->cr39_values, hwcfg->r5.cr39_values, 14);

⌨️ 快捷键说明

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