hfa384x_usb.c

来自「Linux的无线局域网方案是一个Linux设备驱动程序和子系统 一揽子方案的用」· C语言 代码 · 共 2,513 行 · 第 1/5 页

C
2,513
字号
{	int		result = 0;	UINT8		*verbuf;	UINT32		dlbufaddr;	int		nburns;	UINT32		burnlen;	UINT32		burndaddr;	UINT16		burnlo;	UINT16		burnhi;	int		nwrites;	UINT8		*writebuf;	UINT16		writepage;	UINT16		writeoffset;	UINT32		writelen;	int		i;	int		j;	DBFENTER;	WLAN_LOG_DEBUG2(5,"daddr=0x%08lx len=%ld\n", daddr, len);	/* Check that we're in the flash download state */	if ( hw->dlstate != HFA384x_DLSTATE_FLASHENABLED ) {		return -EINVAL;	}	WLAN_LOG_INFO2("Download %ld bytes to flash @0x%06lx\n", len, daddr);	/* Convert to flat address for arithmetic */	/* NOTE: dlbuffer RID stores the address in AUX format */	dlbufaddr = HFA384x_ADDR_AUX_MKFLAT(			hw->bufinfo.page, hw->bufinfo.offset);	WLAN_LOG_DEBUG3(5,		"dlbuf.page=0x%04x dlbuf.offset=0x%04x dlbufaddr=0x%08lx\n",		hw->bufinfo.page, hw->bufinfo.offset, dlbufaddr);	verbuf = kmalloc(hw->bufinfo.len, GFP_ATOMIC);	if ( verbuf == NULL ) {		WLAN_LOG_ERROR0("Failed to allocate flash verify buffer\n");		return 1;	}#if 0WLAN_LOG_WARNING3("dlbuf@0x%06lx len=%d to=%d\n", dlbufaddr, hw->bufinfo.len, hw->dltimeout);#endif	/* Calculations to determine how many fills of the dlbuffer to do	 * and how many USB wmemreq's to do for each fill.  At this point	 * in time, the dlbuffer size and the wmemreq size are the same.	 * Therefore, nwrites should always be 1.  The extra complexity	 * here is a hedge against future changes.	 */	/* Figure out how many times to do the flash programming */	nburns = len / hw->bufinfo.len;	nburns += (len % hw->bufinfo.len) ? 1 : 0;	/* For each flash program cycle, how many USB wmemreq's are needed? */	nwrites = hw->bufinfo.len / HFA384x_USB_RWMEM_MAXLEN;	nwrites += (hw->bufinfo.len % HFA384x_USB_RWMEM_MAXLEN) ? 1 : 0;	/* For each burn */	for ( i = 0; i < nburns; i++) {		/* Get the dest address and len */		burnlen = (len - (hw->bufinfo.len * i)) > hw->bufinfo.len ?				hw->bufinfo.len : 				(len - (hw->bufinfo.len * i));		burndaddr = daddr + (hw->bufinfo.len * i);		burnlo = HFA384x_ADDR_CMD_MKOFF(burndaddr);		burnhi = HFA384x_ADDR_CMD_MKPAGE(burndaddr);		WLAN_LOG_INFO2("Writing %ld bytes to flash @0x%06lx\n", 			burnlen, burndaddr);		/* Set the download mode */		result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_NV, 				burnlo, burnhi, burnlen);		if ( result ) {			WLAN_LOG_ERROR4("download(NV,lo=%x,hi=%x,len=%lx) "				"cmd failed, result=%d. Aborting d/l\n",				burnlo, burnhi, burnlen, result);			goto exit_proc;		}		/* copy the data to the flash download buffer */		for ( j=0; j < nwrites; j++) {			writebuf = buf + 				(i*hw->bufinfo.len) + 				(j*HFA384x_USB_RWMEM_MAXLEN);						writepage = HFA384x_ADDR_CMD_MKPAGE(					dlbufaddr + 					(j*HFA384x_USB_RWMEM_MAXLEN));			writeoffset = HFA384x_ADDR_CMD_MKOFF(					dlbufaddr + 					(j*HFA384x_USB_RWMEM_MAXLEN));			writelen = burnlen-(j*HFA384x_USB_RWMEM_MAXLEN);			writelen = writelen  > HFA384x_USB_RWMEM_MAXLEN ?					HFA384x_USB_RWMEM_MAXLEN :					writelen;			result = hfa384x_dowmem( hw, DOWAIT,					writepage, 					writeoffset, 					writebuf, 					writelen, 					NULL, NULL);#if 0Comment out for debugging, assume the write was successful.			if (result) {				WLAN_LOG_ERROR1(__FUNCTION__					": Write to dl buffer failed, "					"result=0x%04x. Aborting.\n", 					result);				goto exit_proc;			}#endif		}		/* set the download 'write flash' mode */		result = hfa384x_cmd_download(hw, 				HFA384x_PROGMODE_NVWRITE, 				0,0,0);		if ( result ) {			WLAN_LOG_ERROR4(				"download(NVWRITE,lo=%x,hi=%x,len=%lx) "				"cmd failed, result=%d. Aborting d/l\n",				burnlo, burnhi, burnlen, result);			goto exit_proc;		}		/* TODO: We really should do a readback and compare. */	}exit_proc:	/* Leave the firmware in the 'post-prog' mode.  flashdl_disable will */	/*  actually disable programming mode.  Remember, that will cause the */	/*  the firmware to effectively reset itself. */		DBFEXIT;	return result;}/*----------------------------------------------------------------* hfa384x_drvr_getconfig** Performs the sequence necessary to read a config/info item.** Arguments:*	hw		device structure*	rid		config/info record id (host order)*	buf		host side record buffer.  Upon return it will*			contain the body portion of the record (minus the *			RID and len).*	len		buffer length (in bytes, should match record length)** Returns: *	0		success*	>0		f/w reported error - f/w status code*	<0		driver reported error*	-ENODATA 	length mismatch between argument and retrieved*			record.** Side effects:** Call context:*	process ----------------------------------------------------------------*/int hfa384x_drvr_getconfig(hfa384x_t *hw, UINT16 rid, void *buf, UINT16 len){	int 			result = 0;	DBFENTER;	result = hfa384x_dorrid(hw, DOWAIT, rid, buf, len, NULL, NULL);	DBFEXIT;	return result;}/*----------------------------------------------------------------* hfa384x_drvr_getconfig16** Performs the sequence necessary to read a 16 bit config/info item* and convert it to host order.** Arguments:*	hw		device structure*	rid		config/info record id (in host order)*	val		ptr to 16 bit buffer to receive value (in host order)** Returns: *	0		success*	>0		f/w reported error - f/w status code*	<0		driver reported error** Side effects:** Call context:*	process ----------------------------------------------------------------*/int hfa384x_drvr_getconfig16(hfa384x_t *hw, UINT16 rid, void *val){	int		result = 0;	DBFENTER;	result = hfa384x_drvr_getconfig(hw, rid, val, sizeof(UINT16));	if ( result == 0 ) {		*((UINT16*)val) = hfa384x2host_16(*((UINT16*)val));	}	DBFEXIT;	return result;}/*----------------------------------------------------------------* hfa384x_drvr_getconfig32** Performs the sequence necessary to read a 32 bit config/info item* and convert it to host order.** Arguments:*	hw		device structure*	rid		config/info record id (in host order)*	val		ptr to 32 bit buffer to receive value (in host order)** Returns: *	0		success*	>0		f/w reported error - f/w status code*	<0		driver reported error** Side effects:** Call context:*	process ----------------------------------------------------------------*/int hfa384x_drvr_getconfig32(hfa384x_t *hw, UINT16 rid, void *val){	int		result = 0;	DBFENTER;	result = hfa384x_drvr_getconfig(hw, rid, val, sizeof(UINT32));	if ( result == 0 ) {		*((UINT32*)val) = hfa384x2host_32(*((UINT32*)val));	}	DBFEXIT;	return result;}/*----------------------------------------------------------------* hfa384x_drvr_getconfig_async** Performs the sequence necessary to perform an async read of* of a config/info item.** Arguments:*	hw		device structure*	rid		config/info record id (host order)*	buf		host side record buffer.  Upon return it will*			contain the body portion of the record (minus the *			RID and len).*	len		buffer length (in bytes, should match record length)*	cbfn		caller supplied callback, called when the command *			is done (successful or not).*	cbfndata	pointer to some caller supplied data that will be*			passed in as an argument to the cbfn.** Returns: *	nothing		the cbfn gets a status argument identifying if*			any errors occur.* Side effects:*	Queues an hfa384x_usbcmd_t for subsequent execution.** Call context:*	Any----------------------------------------------------------------*/voidhfa384x_drvr_getconfig_async(	hfa384x_t		*hw, 	UINT16			rid, 	ctlx_usercb_t		usercb, 	void			*usercb_data){	DBFENTER;	hfa384x_dorrid(hw, DOASYNC, rid, NULL, 0, usercb, usercb_data);	DBFEXIT;	return;}/*----------------------------------------------------------------* hfa384x_drvr_handover** Sends a handover notification to the MAC.** Arguments:*	hw		device structure*	addr		address of station that's left** Returns: *	zero		success.*	-ERESTARTSYS	received signal while waiting for semaphore.*	-EIO		failed to write to bap, or failed in cmd.** Side effects:** Call context:*	process----------------------------------------------------------------*/int hfa384x_drvr_handover( hfa384x_t *hw, UINT8 *addr){        DBFENTER;	WLAN_LOG_WARNING0(__FUNCTION__": Not currently supported in USB!\n");	DBFEXIT;	return -EIO;}/*----------------------------------------------------------------* hfa384x_drvr_low_level** Write test commands to the card.  Some test commands don't make* sense without prior set-up.  For example, continous TX isn't very* useful until you set the channel.  That functionality should be* enforced at a higher level.** Arguments:*	hw		device structure*	test_mode	The test command code to use.*       test_param      A parameter needed for the test mode being used.** Returns: *	0		success*	>0		f/w reported error - f/w status code*	<0		driver reported error** Side effects:** Call context:*	process ----------------------------------------------------------------*/int hfa384x_drvr_low_level(hfa384x_t *hw, UINT32 command,			   UINT32 param0,			   UINT32 param1,			   UINT32 param2){#if 0	int		result = 0;	UINT16	cmd = (UINT16) command;	UINT16 p0 = (UINT16) param0;	UINT16 p1 = (UINT16) param1;	UINT16 p2 = (UINT16) param2;	DBFENTER;		/* Do i need a host2hfa... conversion ? */#if 0	printk(KERN_INFO "%#x %#x %#x %#x\n", cmd, p0, p1, p2);#endif	result = hfa384x_docmd_wait(hw, cmd, p0, p1, p2);	DBFEXIT;	return result;#endifreturn 0;}/*----------------------------------------------------------------* hfa384x_drvr_mmi_read** Read mmi registers.  mmi is intersil-speak for the baseband* processor registers.** Arguments:*       hw              device structure*       register        The test register to be accessed (must be even #).** Returns:*       0               success*       >0              f/w reported error - f/w status code*       <0              driver reported error** Side effects:** Call context:*       process----------------------------------------------------------------*/int hfa384x_drvr_mmi_read(hfa384x_t *hw, UINT32 addr){#if 0        int             result = 0;        UINT16  cmd_code = (UINT16) 0x30;        UINT16 param = (UINT16) addr;        DBFENTER;        /* Do i need a host2hfa... conversion ? */        result = hfa384x_docmd_wait(hw, cmd_code, param, 0, 0);        DBFEXIT;        return result;#endifreturn 0;}/*----------------------------------------------------------------* hfa384x_drvr_mmi_write** Read mmi registers.  mmi is intersil-speak for the baseband* processor registers.** Arguments:*       hw              device structure*       addr            The test register to be accessed (must be even #).*       data            The data value to write to the register.** Returns:*       0               success*       >0              f/w reported error - f/w status code*       <0              driver reported error** Side effects:** Call context:*       process----------------------------------------------------------------*/inthfa384x_drvr_mmi_write(hfa384x_t *hw, UINT32 addr, UINT32 data){#if 0        int             result = 0;        UINT16  cmd_code = (UINT16) 0x31;        UINT16 param0 = (UINT16) addr;        UINT16 param1 = (UINT16) data;        DBFENTER;        WLAN_LOG_DEBUG1(1,"mmi write : addr = 0x%08lx\n", addr);        WLAN_LOG_DEBUG1(1,"mmi write : data = 0x%08lx\n", data);        /* Do i need a host2hfa... conversion ? */        result = hfa384x_docmd_wait(hw, cmd_code, param0, param1, 0);        DBFEXIT;        return result;#endifreturn 0;}/*----------------------------------------------------------------* hfa384x_drvr_ramdl_disable** Ends the ram download state.** Arguments:*	hw		device structure** Returns: *	0		success*	>0		f/w reported error - f/w status code*	<0		driver reported error** Side effects:** Call context:*	process ----------------------------------------------------------------*/int hfa384x_drvr_ramdl_disable(hfa384x_t *hw){	DBFENTER;	/* Check that we're already in the download state */	if ( hw->dlstate != HFA384x_DLSTATE_RAMENABLED ) {		return -EINVAL;	}	WLAN_LOG_DEBUG0(3,"ramdl_disable()\n");	/* There isn't much we can do at this point, so I don't */	/*  bother  w/ the return value */	hfa384x_cmd_download(hw, HFA384x_PROGMODE_DISABLE, 0, 0 , 0);	hw->dlstate = HFA384x_DLSTATE_DISABLED;	DBFEXIT;	return 0;}/*----------------------------------------------------------------* hfa384x_drvr_ramdl_enable** Begins the ram download state.  Checks to see that we're not* already in a d

⌨️ 快捷键说明

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