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

📄 hostap_download.c

📁 IEEE 802.11a/b/g linux2.4/2.6 驱动程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
static int prism2_download_genesis(local_info_t *local,				   struct prism2_download_data *param){	struct net_device *dev = local->dev;	int ram16 = 0, i;	int ret = 0;	if (local->hw_downloading) {		printk(KERN_WARNING "%s: Already downloading - aborting new "		       "request\n", dev->name);		return -EBUSY;	}	if (!local->func->genesis_reset || !local->func->cor_sreset) {		printk(KERN_INFO "%s: Genesis mode downloading not supported "		       "with this hwmodel\n", dev->name);		return -EOPNOTSUPP;	}	local->hw_downloading = 1;	if (prism2_enable_aux_port(dev, 1)) {		printk(KERN_DEBUG "%s: failed to enable AUX port\n",		       dev->name);		ret = -EIO;		goto out;	}	if (local->sram_type == -1) {		/* 0x1F for x8 SRAM or 0x0F for x16 SRAM */		if (prism2_enable_genesis(local, 0x1f) == 0) {			ram16 = 0;			PDEBUG(DEBUG_EXTRA2, "%s: Genesis mode OK using x8 "			       "SRAM\n", dev->name);		} else if (prism2_enable_genesis(local, 0x0f) == 0) {			ram16 = 1;			PDEBUG(DEBUG_EXTRA2, "%s: Genesis mode OK using x16 "			       "SRAM\n", dev->name);		} else {			printk(KERN_DEBUG "%s: Could not initiate genesis "			       "mode\n", dev->name);			ret = -EIO;			goto out;		}	} else {		if (prism2_enable_genesis(local, local->sram_type == 8 ?					  0x1f : 0x0f)) {			printk(KERN_DEBUG "%s: Failed to set Genesis "			       "mode (sram_type=%d)\n", dev->name,			       local->sram_type);			ret = -EIO;			goto out;		}		ram16 = local->sram_type != 8;	}	for (i = 0; i < param->num_areas; i++) {		PDEBUG(DEBUG_EXTRA2, "%s: Writing %d bytes at 0x%08x\n",		       dev->name, param->data[i].len, param->data[i].addr);		if (hfa384x_to_aux(dev, param->data[i].addr,				   param->data[i].len, param->data[i].data)) {			printk(KERN_WARNING "%s: RAM download at 0x%08x "			       "(len=%d) failed\n", dev->name,			       param->data[i].addr, param->data[i].len);			ret = -EIO;			goto out;		}	}	PDEBUG(DEBUG_EXTRA2, "Disable genesis mode\n");	local->func->genesis_reset(local, ram16 ? 0x07 : 0x17);	if (prism2_enable_aux_port(dev, 0)) {		printk(KERN_DEBUG "%s: Failed to disable AUX port\n",		       dev->name);	}	mdelay(5);	local->hw_downloading = 0;	PDEBUG(DEBUG_EXTRA2, "Trying to initialize card\n");	/* Make sure the INIT command does not generate a command completion	 * event by disabling interrupts. */	hfa384x_disable_interrupts(dev);	if (prism2_hw_init(dev, 1)) {		printk(KERN_DEBUG "%s: Initialization after genesis mode "		       "download failed\n", dev->name);		ret = -EIO;		goto out;	}	PDEBUG(DEBUG_EXTRA2, "Card initialized - running PRI only\n");	if (prism2_hw_init2(dev, 1)) {		printk(KERN_DEBUG "%s: Initialization(2) after genesis mode "		       "download failed\n", dev->name);		ret = -EIO;		goto out;	} out:	local->hw_downloading = 0;	return ret;}#ifdef PRISM2_NON_VOLATILE_DOWNLOAD/* Note! Non-volatile downloading functionality has not yet been tested * thoroughly and it may corrupt flash image and effectively kill the card that * is being updated. You have been warned. */static inline int prism2_download_block(struct net_device *dev,					u32 addr, u8 *data,					u32 bufaddr, int rest_len){	u16 param0, param1;	int block_len;	block_len = rest_len < 4096 ? rest_len : 4096;	param0 = addr & 0xffff;	param1 = addr >> 16;	HFA384X_OUTW(block_len, HFA384X_PARAM2_OFF);	HFA384X_OUTW(param1, HFA384X_PARAM1_OFF);	if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD |			     (HFA384X_PROGMODE_ENABLE_NON_VOLATILE << 8),			     param0)) {		printk(KERN_WARNING "%s: Flash download command execution "		       "failed\n", dev->name);		return -1;	}	if (hfa384x_to_aux(dev, bufaddr, block_len, data)) {		printk(KERN_WARNING "%s: flash download at 0x%08x "		       "(len=%d) failed\n", dev->name, addr, block_len);		return -1;	}	HFA384X_OUTW(0, HFA384X_PARAM2_OFF);	HFA384X_OUTW(0, HFA384X_PARAM1_OFF);	if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD |			     (HFA384X_PROGMODE_PROGRAM_NON_VOLATILE << 8),			     0)) {		printk(KERN_WARNING "%s: Flash write command execution "		       "failed\n", dev->name);		return -1;	}	return block_len;}static int prism2_download_nonvolatile(local_info_t *local,				       struct prism2_download_data *dl){	struct net_device *dev = local->dev;	int ret = 0, i;	struct {		u16 page;		u16 offset;		u16 len;	} dlbuffer;	u32 bufaddr;	if (local->hw_downloading) {		printk(KERN_WARNING "%s: Already downloading - aborting new "		       "request\n", dev->name);		return -1;	}	ret = local->func->get_rid(dev, HFA384X_RID_DOWNLOADBUFFER,				   &dlbuffer, 6, 0);	if (ret < 0) {		printk(KERN_WARNING "%s: Could not read download buffer "		       "parameters\n", dev->name);		goto out;	}	dlbuffer.page = le16_to_cpu(dlbuffer.page);	dlbuffer.offset = le16_to_cpu(dlbuffer.offset);	dlbuffer.len = le16_to_cpu(dlbuffer.len);	printk(KERN_DEBUG "Download buffer: %d bytes at 0x%04x:0x%04x\n",	       dlbuffer.len, dlbuffer.page, dlbuffer.offset);	bufaddr = (dlbuffer.page << 7) + dlbuffer.offset;	local->hw_downloading = 1;	if (!local->pri_only) {		prism2_hw_shutdown(dev, 0);		if (prism2_hw_init(dev, 0)) {			printk(KERN_WARNING "%s: Could not initialize card for"			       " download\n", dev->name);			ret = -1;			goto out;		}	}	hfa384x_disable_interrupts(dev);	if (prism2_enable_aux_port(dev, 1)) {		printk(KERN_WARNING "%s: Could not enable AUX port\n",		       dev->name);		ret = -1;		goto out;	}	printk(KERN_DEBUG "%s: starting flash download\n", dev->name);	for (i = 0; i < dl->num_areas; i++) {		int rest_len = dl->data[i].len;		int data_off = 0;		while (rest_len > 0) {			int block_len;			block_len = prism2_download_block(				dev, dl->data[i].addr + data_off,				dl->data[i].data + data_off, bufaddr,				rest_len);			if (block_len < 0) {				ret = -1;				goto out;			}			rest_len -= block_len;			data_off += block_len;		}	}	HFA384X_OUTW(0, HFA384X_PARAM1_OFF);	HFA384X_OUTW(0, HFA384X_PARAM2_OFF);	if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD |				(HFA384X_PROGMODE_DISABLE << 8), 0)) {		printk(KERN_WARNING "%s: Download command execution failed\n",		       dev->name);		ret = -1;		goto out;	}	if (prism2_enable_aux_port(dev, 0)) {		printk(KERN_DEBUG "%s: Disabling AUX port failed\n",		       dev->name);		/* continue anyway.. restart should have taken care of this */	}	mdelay(5);	local->func->hw_reset(dev);	local->hw_downloading = 0;	if (prism2_hw_config(dev, 2)) {		printk(KERN_WARNING "%s: Card configuration after flash "		       "download failed\n", dev->name);		ret = -1;	} else {		printk(KERN_INFO "%s: Card initialized successfully after "		       "flash download\n", dev->name);	} out:	local->hw_downloading = 0;	return ret;}#endif /* PRISM2_NON_VOLATILE_DOWNLOAD */static void prism2_download_free_data(struct prism2_download_data *dl){	int i;	if (dl == NULL)		return;	for (i = 0; i < dl->num_areas; i++)		kfree(dl->data[i].data);	kfree(dl);}static int prism2_download(local_info_t *local,			   struct prism2_download_param *param){	int ret = 0;	int i;	u32 total_len = 0;	struct prism2_download_data *dl = NULL;	printk(KERN_DEBUG "prism2_download: dl_cmd=%d start_addr=0x%08x "	       "num_areas=%d\n",	       param->dl_cmd, param->start_addr, param->num_areas);	if (param->num_areas > 100) {		ret = -EINVAL;		goto out;	}	dl = kmalloc(sizeof(*dl) + param->num_areas *		     sizeof(struct prism2_download_data_area), GFP_KERNEL);	if (dl == NULL) {		ret = -ENOMEM;		goto out;	}	memset(dl, 0, sizeof(*dl) + param->num_areas *	       sizeof(struct prism2_download_data_area));	dl->dl_cmd = param->dl_cmd;	dl->start_addr = param->start_addr;	dl->num_areas = param->num_areas;	for (i = 0; i < param->num_areas; i++) {		PDEBUG(DEBUG_EXTRA2,		       "  area %d: addr=0x%08x len=%d ptr=0x%p\n",		       i, param->data[i].addr, param->data[i].len,		       param->data[i].ptr);		dl->data[i].addr = param->data[i].addr;		dl->data[i].len = param->data[i].len;		total_len += param->data[i].len;		if (param->data[i].len > PRISM2_MAX_DOWNLOAD_AREA_LEN ||		    total_len > PRISM2_MAX_DOWNLOAD_LEN) {			ret = -E2BIG;			goto out;		}		dl->data[i].data = kmalloc(dl->data[i].len, GFP_KERNEL);		if (dl->data[i].data == NULL) {			ret = -ENOMEM;			goto out;		}		if (copy_from_user(dl->data[i].data, param->data[i].ptr,				   param->data[i].len)) {			ret = -EFAULT;			goto out;		}	}	switch (param->dl_cmd) {	case PRISM2_DOWNLOAD_VOLATILE:	case PRISM2_DOWNLOAD_VOLATILE_PERSISTENT:		ret = prism2_download_volatile(local, dl);		break;	case PRISM2_DOWNLOAD_VOLATILE_GENESIS:	case PRISM2_DOWNLOAD_VOLATILE_GENESIS_PERSISTENT:		ret = prism2_download_genesis(local, dl);		break;	case PRISM2_DOWNLOAD_NON_VOLATILE:#ifdef PRISM2_NON_VOLATILE_DOWNLOAD		ret = prism2_download_nonvolatile(local, dl);#else /* PRISM2_NON_VOLATILE_DOWNLOAD */		printk(KERN_INFO "%s: non-volatile downloading not enabled\n",		       local->dev->name);		ret = -EOPNOTSUPP;#endif /* PRISM2_NON_VOLATILE_DOWNLOAD */		break;	default:		printk(KERN_DEBUG "%s: unsupported download command %d\n",		       local->dev->name, param->dl_cmd);		ret = -EINVAL;		break;	}; out:	if (ret == 0 && dl &&	    param->dl_cmd == PRISM2_DOWNLOAD_VOLATILE_GENESIS_PERSISTENT) {		prism2_download_free_data(local->dl_pri);		local->dl_pri = dl;	} else if (ret == 0 && dl &&		   param->dl_cmd == PRISM2_DOWNLOAD_VOLATILE_PERSISTENT) {		prism2_download_free_data(local->dl_sec);		local->dl_sec = dl;	} else		prism2_download_free_data(dl);	return ret;}

⌨️ 快捷键说明

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