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

📄 at76c503.c

📁 这是atmel公司的无线网卡驱动, 基于linux的驱动源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	}	printk ("\n");}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);	if (ret < 0)		return ret;	return 0;}static inlineint 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);	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);}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);}/* 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);}/* 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_INTERSIL:		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_RFMD:		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_R505:		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);		memcpy(dev->bb_cr, hwcfg->r5.bb_cr, 14);		memcpy(dev->pidvid, hwcfg->r5.pidvid, 4);		memcpy(dev->mac_addr, hwcfg->r5.mac_addr, ETH_ALEN);		dev->regulatory_domain = hwcfg->r5.regulatory_domain;		memcpy(dev->cr15_values, hwcfg->r5.cr15_values, 14);		break;	  default:		err("Bad board type set (%d).  Unable to get hardware config.", dev->board_type);		ret = -EINVAL;	}	kfree(hwcfg);	if (ret < 0) {		err("Get HW Config failed (%d)", ret);	}	return ret;}/* == PROC getRegDomain == */struct reg_domain const *getRegDomain(u16 code){	static struct reg_domain const fd_tab[] = {		{0x10, "FCC (U.S)", 0x7ff}, /* ch 1-11 */		{0x20, "IC (Canada)", 0x7ff}, /* ch 1-11 */		{0x30, "ETSI (Europe - (Spain+France)", 0x1fff},  /* ch 1-13 */		{0x31, "Spain", 0x600},    /* ch 10,11 */		{0x32, "France", 0x1e00},  /* ch 10-13 */		{0x40, "MKK (Japan)", 0x2000},  /* ch 14 */		{0x41, "MKK1 (Japan)", 0x3fff},  /* ch 1-14 */		{0x50, "Israel", 0x3fc},  /* ch 3-9 */	};	static int const tab_len = sizeof(fd_tab) / sizeof(struct reg_domain);	/* use this if an unknown code comes in */	static struct reg_domain const unknown = 		{0, "<unknown>", 0xffffffff};  	int i;	for(i=0; i < tab_len; i++)		if (code == fd_tab[i].code)			break;  	return (i >= tab_len) ? &unknown : &fd_tab[i];} /* getFreqDomain */static inlineint get_mib(struct usb_device *udev,	    u16 mib, u8 *buf, int buf_size){	return usb_control_msg(udev, usb_rcvctrlpipe(udev,0),			       0x33, INTERFACE_VENDOR_REQUEST_IN,			       mib << 8, 0,			       buf, buf_size, HZ);}static inlineint get_cmd_status(struct usb_device *udev,		   u8 cmd, u8 *cmd_status){	return usb_control_msg(udev, usb_rcvctrlpipe(udev,0),			       0x22, INTERFACE_VENDOR_REQUEST_IN,			       cmd, 0,			       cmd_status, 40, HZ);}#define EXT_FW_BLOCK_SIZE 1024int at76c503_download_external_fw(struct usb_device *udev, u8 *buf, int size){	int i = 0, ret = 0;	u8 op_mode;	u8 *block;	if (size < 0) return -EINVAL;	if ((size > 0) && (buf == NULL)) return -EFAULT;	op_mode = get_op_mode(udev);	if (op_mode <= 0) {		err("Internal firmware not loaded (%d)", op_mode);		return -EPROTO;	} 	if (op_mode == OPMODE_NETCARD) {		/* don't need firmware downloaded, it's already ready to go */		return 0;	}	if (op_mode != OPMODE_NOFLASHNETCARD) {		dbg(DBG_DEVSTART, 		    "Unexpected operating mode (%d)."		    "Attempting to download firmware anyway.", op_mode);	}	block = kmalloc(EXT_FW_BLOCK_SIZE, GFP_KERNEL);	if (block == NULL) return -ENOMEM;	dbg(DBG_DEVSTART, "Downloading external firmware...");	while(size > 0){		int bsize = size > EXT_FW_BLOCK_SIZE ? EXT_FW_BLOCK_SIZE : size;		memcpy(block, buf, bsize);		dbg(DBG_DEVSTART,		    "ext fw, size left = %5d, bsize = %4d, i = %2d", size, bsize, i);		if((ret = load_ext_fw_block(udev, i, block, bsize)) < 0){			err("load_ext_fw_block failed: %d, i = %d", ret, i);			goto exit;		}		buf += bsize;		size -= bsize;		i++;	}	/* for fw >= 0.100, the device needs	   an extra empty block: */	if((ret = load_ext_fw_block(udev, i, block, 0)) < 0){		err("load_ext_fw_block failed: %d, i = %d", ret, i);		goto exit;	} exit:	kfree(block);	return ret;}staticint set_card_command(struct usb_device *udev, int cmd,		    unsigned char *buf, int buf_size){	int ret;	struct at76c503_command *cmd_buf =		(struct at76c503_command *)kmalloc(			sizeof(struct at76c503_command) + buf_size,			GFP_KERNEL);	if(cmd_buf){		cmd_buf->cmd = cmd;		cmd_buf->reserved = 0;		cmd_buf->size = cpu_to_le16(buf_size);		if(buf_size > 0)			memcpy(&(cmd_buf[1]), buf, buf_size);		ret = usb_control_msg(udev, usb_sndctrlpipe(udev,0),				      0x0e, DEVICE_VENDOR_REQUEST_OUT,				      0, 0,				      cmd_buf,				      sizeof(struct at76c503_command) + buf_size,				      HZ);		kfree(cmd_buf);		return ret;	}	return -ENOMEM;}/* TODO: should timeout */int wait_completion(struct at76c503 *dev, int cmd){	u8 *cmd_status = kmalloc(40, GFP_KERNEL);	struct net_device *netdev = dev->netdev;	int ret = 0;	do{		ret = get_cmd_status(dev->udev, cmd, cmd_status);		if(ret < 0){			err("%s: get_cmd_status failed: %d", netdev->name, ret);			break;		}		dbg(DBG_WAIT_COMPLETE, "%s: cmd %d,cmd_status[5] = %d",		    dev->netdev->name, cmd, cmd_status[5]);		if(cmd_status[5] == CMD_STATUS_IN_PROGRESS ||		   cmd_status[5] == CMD_STATUS_IDLE){			set_current_state(TASK_INTERRUPTIBLE);			schedule_timeout(HZ/10); // 100 ms		}else break;	}while(1);	if (ret >= 0)		/* if get_cmd_status did not fail, return the status		   retrieved */		ret = cmd_status[5];	kfree(cmd_status);	return ret;}staticint set_mib(struct at76c503 *dev, struct set_mib_buffer *buf){	struct usb_device *udev = dev->udev;	int ret;	struct at76c503_command *cmd_buf =		(struct at76c503_command *)kmalloc(			sizeof(struct at76c503_command) + buf->size + 4,			GFP_KERNEL);	if(cmd_buf){		cmd_buf->cmd = CMD_SET_MIB;		cmd_buf->reserved = 0;		cmd_buf->size = cpu_to_le16(buf->size + 4);		memcpy(&(cmd_buf[1]), buf, buf->size + 4);		ret = usb_control_msg(udev, usb_sndctrlpipe(udev,0),				      0x0e, DEVICE_VENDOR_REQUEST_OUT,				      0, 0,				      cmd_buf,				      sizeof(struct at76c503_command) + buf->size + 4,				      HZ);		if (ret >= 0)			if ((ret=wait_completion(dev, CMD_SET_MIB)) != 			    CMD_STATUS_COMPLETE) {				info("%s: set_mib: wait_completion failed with %d",				     dev->netdev->name, ret);				ret = -156; /* ??? */			}		kfree(cmd_buf);		return ret;	}	return -ENOMEM;}/* return < 0 on error, == 0 if no command sent, == 1 if cmd sent */staticint set_radio(struct at76c503 *dev, int on_off){	int ret;	if(dev->radio_on != on_off){		ret = set_card_command(dev->udev, CMD_RADIO, NULL, 0);		if(ret < 0){			err("%s: set_card_command(CMD_RADIO) failed: %d", dev->netdev->name, ret);		} else			ret = 1;		dev->radio_on = on_off;	} else		ret = 0;	return ret;}/* == PROC set_pm_mode ==   sets power save modi (PM_ACTIVE/PM_SAVE/PM_SMART_SAVE) */static int set_pm_mode(struct at76c503 *dev, u8 mode) __attribute__ ((unused));static int set_pm_mode(struct at76c503 *dev, u8 mode){	int ret = 0;	struct set_mib_buffer mib_buf;	memset(&mib_buf, 0, sizeof(struct set_mib_buffer));	mib_buf.type = MIB_MAC_MGMT;	mib_buf.size = 1;	mib_buf.index = POWER_MGMT_MODE_OFFSET;	mib_buf.data[0] = mode;	ret = set_mib(dev, &mib_buf);	if(ret < 0){		err("%s: set_mib (pm_mode) failed: %d", dev->netdev->name, ret);	}	return ret;}/* == PROC set_associd ==   sets the assoc id for power save mode */static int set_associd(struct at76c503 *dev, u16 id) __attribute__ ((unused));static int set_associd(struct at76c503 *dev, u16 id){	int ret = 0;	struct set_mib_buffer mib_buf;	memset(&mib_buf, 0, sizeof(struct set_mib_buffer));	mib_buf.type = MIB_MAC_MGMT;	mib_buf.size = 2;	mib_buf.index = STATION_ID_OFFSET;	mib_buf.data[0] = id & 0xff;	mib_buf.data[1] = id >> 8;	ret = set_mib(dev, &mib_buf);	if(ret < 0){		err("%s: set_mib (associd) failed: %d", dev->netdev->name, ret);	}	return ret;}/* == PROC set_listen_interval ==   sets the listen interval for power save mode.   really needed, as we have a similar parameter in the assocreq ??? */static int set_listen_interval(struct at76c503 *dev, u16 interval) __attribute__ ((unused));static int set_listen_interval(struct at76c503 *dev, u16 interval){	int ret = 0;	struct set_mib_buffer mib_buf;	memset(&mib_buf, 0, sizeof(struct set_mib_buffer));	mib_buf.type = MIB_MAC;	mib_buf.size = 2;	mib_buf.index = STATION_ID_OFFSET;	mib_buf.data[0] = interval & 0xff;	mib_buf.data[1] = interval >> 8;	ret = set_mib(dev, &mib_buf);	if(ret < 0){		err("%s: set_mib (listen_interval) failed: %d",		    dev->netdev->name, ret);	}	return ret;}staticint set_preamble(struct at76c503 *dev, u8 type){	int ret = 0;	struct set_mib_buffer mib_buf;	memset(&mib_buf, 0, sizeof(struct set_mib_buffer));	mib_buf.type = MIB_LOCAL;	mib_buf.size = 1;	mib_buf.index = PREAMBLE_TYPE_OFFSET;	mib_buf.data[0] = type;	ret = set_mib(dev, &mib_buf);	if(ret < 0){		err("%s: set_mib (preamble) failed: %d", dev->netdev->name, ret);	}	return ret;}staticint set_frag(struct at76c503 *dev, u16 size){	int ret = 0;	struct set_mib_buffer mib_buf;	memset(&mib_buf, 0, sizeof(struct set_mib_buffer));	mib_buf.type = MIB_MAC;	mib_buf.size = 2;	mib_buf.index = FRAGMENTATION_OFFSET;	*(u16*)mib_buf.data = cpu_to_le16(size);	ret = set_mib(dev, &mib_buf);	if(ret < 0){		err("%s: set_mib (frag threshold) failed: %d", dev->netdev->name, ret);	}	return ret;}static

⌨️ 快捷键说明

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