hfa384x_usb.c

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

C
2,513
字号
* Returns: *	0		success*	-ETIMEDOUT	timed out waiting for register ready or*			command completion*	>0		command indicated error, Status and Resp0-2 are*			in hw structure.** Side effects:*	* Call context:*	interrupt (wait==0)*	process (wait==0 || wait==1)----------------------------------------------------------------*/inthfa384x_dormem(	hfa384x_t *hw, 	UINT	wait,	UINT16	page,	UINT16	offset,	void	*data,	UINT	len,	ctlx_usercb_t usercb,	void	*usercb_data){	int			result = 0;	hfa384x_usbctlx_t	*ctlx;		DBFENTER;	ctlx = kmalloc(sizeof(*ctlx), GFP_ATOMIC);	if ( ctlx == NULL ) {		result = -ENOMEM;		goto done;	}	memset(ctlx, 0, sizeof(*ctlx));	ctlx->state = HFA384x_USBCTLX_START;	/* Initialize the command */	ctlx->outbuf.rmemreq.type =    host2hfa384x_16(HFA384x_USB_RMEMREQ);	ctlx->outbuf.rmemreq.frmlen =  host2hfa384x_16(					sizeof(ctlx->outbuf.rmemreq.offset) +					sizeof(ctlx->outbuf.rmemreq.page) +					len);	ctlx->outbuf.rmemreq.offset =	host2hfa384x_16(offset);	ctlx->outbuf.rmemreq.page =	host2hfa384x_16(page);	WLAN_LOG_DEBUG4(4,		"type=0x%04x frmlen=%d offset=0x%04x page=0x%04x\n",		ctlx->outbuf.rmemreq.type,		ctlx->outbuf.rmemreq.frmlen,		ctlx->outbuf.rmemreq.offset,		ctlx->outbuf.rmemreq.page);	WLAN_LOG_DEBUG1(4,"pktsize=%d\n", 		ROUNDUP64(sizeof(ctlx->outbuf.rmemreq)));	/* Fill the out packet */	FILL_BULK_URB( &(ctlx->outurb), hw->usb,		usb_sndbulkpipe(hw->usb, 2),		&(ctlx->outbuf), ROUNDUP64(sizeof(ctlx->outbuf.rmemreq)),		hfa384x_usbout_callback, hw->usbcontext);	ctlx->outurb.transfer_flags |= USB_ASYNC_UNLINK;	if ( wait ) {		hfa384x_usbctlx_submit_wait(hw, ctlx);	} else {		hfa384x_usbctlx_submit_async(hw, ctlx, usercb, usercb_data);		goto done;	}	/* All of the following is skipped for async calls */	/* On reawakening, check the ctlx status */	switch(ctlx->state) { 	case HFA384x_USBCTLX_COMPLETE:		WLAN_LOG_DEBUG1(4,"rmemresp:len=%d\n",			ctlx->inbuf.rmemresp.frmlen);		memcpy(data, ctlx->inbuf.rmemresp.data, len);		result = 0;		break;	case HFA384x_USBCTLX_REQSUBMIT_FAIL:		WLAN_LOG_WARNING0(__FUNCTION__":ctlx failure=REQSUBMIT_FAIL\n");		result = -EIO;		break;	case HFA384x_USBCTLX_REQ_TIMEOUT:		WLAN_LOG_WARNING0(__FUNCTION__":ctlx failure=REQ_TIMEOUT\n");		result = -EIO;		break;	case HFA384x_USBCTLX_REQ_FAILED:		WLAN_LOG_WARNING0(__FUNCTION__":ctlx failure=REQ_FAILED\n");		result = -EIO;		break;	case HFA384x_USBCTLX_RESP_TIMEOUT:		WLAN_LOG_WARNING0(__FUNCTION__":ctlx failure=RESP_TIMEOUT\n");		result = -EIO;		break;	default:		/* The ctlx is still running and probably still in the queue 		 * We were probably awakened by a signal.  Return an error  		 * and DO NOT free the ctlx.  Let the ctlx finish and it will		 * just be leaked.  At least we won't crash that way.		 * TODO: we need a ctlx_cancel function 		 */		result = -ERESTARTSYS;		goto done;		break;	}	kfree(ctlx);done:	DBFEXIT;	return result;}	/*----------------------------------------------------------------* hfa384x_dowmem** Constructs a writemem CTLX and issues it.** NOTE: Any changes to the 'post-submit' code in this function *       need to be carried over to hfa384x_cbwmem() since the handling*       is virtually identical.** Arguments:*	hw		device structure*	wait		1=wait for completion, 0=async*	page		MAC address space page (CMD format)*	offset		MAC address space offset*	data		Ptr to data buffer containing write data*	len		Length of the data to read (max == 2048)*	usercb		user callback for async calls, NULL for wait==1 calls*	usercb_data	user supplied data pointer for async calls, NULL** Returns: *	0		success*	-ETIMEDOUT	timed out waiting for register ready or*			command completion*	>0		command indicated error, Status and Resp0-2 are*			in hw structure.** Side effects:*	* Call context:*	interrupt (wait==0)*	process (wait==0 || wait==1)----------------------------------------------------------------*/inthfa384x_dowmem(	hfa384x_t *hw, 	UINT	wait,	UINT16	page,	UINT16	offset,	void	*data,	UINT	len,	ctlx_usercb_t usercb,	void	*usercb_data){	int			result = 0;	hfa384x_usbctlx_t	*ctlx;		DBFENTER;	WLAN_LOG_DEBUG3(5, "page=0x%04x offset=0x%04x len=%d\n",		page,offset,len);	ctlx = kmalloc(sizeof(*ctlx), GFP_ATOMIC);	if ( ctlx == NULL ) {		result = -ENOMEM;		goto done;	}	memset(ctlx, 0, sizeof(*ctlx));	ctlx->state = HFA384x_USBCTLX_START;	/* Initialize the command */	ctlx->outbuf.wmemreq.type =   host2hfa384x_16(HFA384x_USB_WMEMREQ);	ctlx->outbuf.wmemreq.frmlen = host2hfa384x_16(					sizeof(ctlx->outbuf.wmemreq.offset) +					sizeof(ctlx->outbuf.wmemreq.page) +					len);	ctlx->outbuf.wmemreq.offset = host2hfa384x_16(offset);	ctlx->outbuf.wmemreq.page =   host2hfa384x_16(page);	memcpy(ctlx->outbuf.wmemreq.data, data, len);	/* Fill the out packet */	FILL_BULK_URB( &(ctlx->outurb), hw->usb,		usb_sndbulkpipe(hw->usb, 2),		&(ctlx->outbuf), 		ROUNDUP64( sizeof(ctlx->outbuf.wmemreq.type) +			sizeof(ctlx->outbuf.wmemreq.frmlen) +			sizeof(ctlx->outbuf.wmemreq.offset) +			sizeof(ctlx->outbuf.wmemreq.page) +			len),		hfa384x_usbout_callback, 		hw->usbcontext);	ctlx->outurb.transfer_flags |= USB_ASYNC_UNLINK;	if ( wait ) {		hfa384x_usbctlx_submit_wait(hw, ctlx);	} else {		hfa384x_usbctlx_submit_async(hw, ctlx, usercb, usercb_data);		goto done;	}	/* All of the following is skipped for async calls */	/* On reawakening, check the ctlx status */	switch(ctlx->state) { 	case HFA384x_USBCTLX_COMPLETE:		result = hfa384x2host_16(ctlx->inbuf.wmemresp.status);		hw->status = hfa384x2host_16(ctlx->inbuf.wmemresp.status);		hw->resp0 = hfa384x2host_16(ctlx->inbuf.wmemresp.resp0);		hw->resp1 = hfa384x2host_16(ctlx->inbuf.wmemresp.resp1);		hw->resp2 = hfa384x2host_16(ctlx->inbuf.wmemresp.resp2);		break;	case HFA384x_USBCTLX_REQSUBMIT_FAIL:		WLAN_LOG_WARNING0(__FUNCTION__":ctlx failure=REQSUBMIT_FAIL\n");		result = -EIO;		break;	case HFA384x_USBCTLX_REQ_TIMEOUT:		WLAN_LOG_WARNING0(__FUNCTION__":ctlx failure=REQ_TIMEOUT\n");		result = -EIO;		break;	case HFA384x_USBCTLX_REQ_FAILED:		WLAN_LOG_WARNING0(__FUNCTION__":ctlx failure=REQ_FAILED\n");		result = -EIO;		break;	case HFA384x_USBCTLX_RESP_TIMEOUT:		WLAN_LOG_WARNING0(__FUNCTION__":ctlx failure=RESP_TIMEOUT\n");		result = -EIO;		break;	default:		/* The ctlx is still running and probably still in the queue 		 * We were probably awakened by a signal.  Return an error  		 * and DO NOT free the ctlx.  Let the ctlx finish and it will		 * just be leaked.  At least we won't crash that way.		 * TODO: we need a ctlx_cancel function 		 */		result = -ERESTARTSYS;		goto done;		break;	}	kfree(ctlx);done:	DBFEXIT;	return result;}	/*----------------------------------------------------------------* hfa384x_drvr_commtallies** Send a commtallies inquiry to the MAC.  Note that this is an async* call that will result in an info frame arriving sometime later.** Arguments:*	hw		device structure** Returns: *	zero		success.** Side effects:** Call context:*	process----------------------------------------------------------------*/int hfa384x_drvr_commtallies( hfa384x_t *hw ){	DBFENTER;	hfa384x_docmd(hw, 		DOASYNC, 		HFA384x_CMDCODE_INQ,		HFA384x_IT_COMMTALLIES,		0,0, NULL, NULL);		DBFEXIT;	return 0;}/*----------------------------------------------------------------* hfa384x_drvr_disable** Issues the disable command to stop communications on one of * the MACs 'ports'.  Only macport 0 is valid  for stations.* APs may also disable macports 1-6.  Only ports that have been* previously enabled may be disabled.** Arguments:*	hw		device structure*	macport		MAC port number (host order)** Returns: *	0		success*	>0		f/w reported failure - f/w status code*	<0		driver reported error (timeout|bad arg)** Side effects:** Call context:*	process ----------------------------------------------------------------*/int hfa384x_drvr_disable(hfa384x_t *hw, UINT16 macport){	int	result = 0;	DBFENTER;	if ((!hw->isap && macport != 0) || 	    (hw->isap && !(macport <= HFA384x_PORTID_MAX)) ||	    !(hw->port_enabled[macport]) ){		result = -EINVAL;	} else {		result = hfa384x_cmd_disable(hw, macport);		if ( result == 0 ) {			hw->port_enabled[macport] = 0;		}	}	DBFEXIT;	return result;}/*----------------------------------------------------------------* hfa384x_drvr_enable** Issues the enable command to enable communications on one of * the MACs 'ports'.  Only macport 0 is valid  for stations.* APs may also enable macports 1-6.  Only ports that are currently* disabled may be enabled.** Arguments:*	hw		device structure*	macport		MAC port number** Returns: *	0		success*	>0		f/w reported failure - f/w status code*	<0		driver reported error (timeout|bad arg)** Side effects:** Call context:*	process ----------------------------------------------------------------*/int hfa384x_drvr_enable(hfa384x_t *hw, UINT16 macport){	int	result = 0;	DBFENTER;	if ((!hw->isap && macport != 0) || 	    (hw->isap && !(macport <= HFA384x_PORTID_MAX)) ||	    (hw->port_enabled[macport]) ){		result = -EINVAL;	} else {		result = hfa384x_cmd_enable(hw, macport);		if ( result == 0 ) {			hw->port_enabled[macport] = 1;		}	}	DBFEXIT;	return result;}/*----------------------------------------------------------------* hfa384x_drvr_flashdl_enable** Begins the flash download state.  Checks to see that we're not* already in a download state and that a port isn't enabled.* Sets the download state and retrieves the flash download* buffer location, buffer size, and timeout length.** 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_flashdl_enable(hfa384x_t *hw){	int		result = 0;	int		i;	DBFENTER;	/* Check that a port isn't active */	for ( i = 0; i < HFA384x_PORTID_MAX; i++) {		if ( hw->port_enabled[i] ) {			WLAN_LOG_DEBUG0(1,"called when port enabled.\n");			return -EINVAL; 		}	}	/* Check that we're not already in a download state */	if ( hw->dlstate != HFA384x_DLSTATE_DISABLED ) {		return -EINVAL;	}	/* Retrieve the buffer loc&size and timeout */	if ( (result = hfa384x_drvr_getconfig(hw, HFA384x_RID_DOWNLOADBUFFER, 				&(hw->bufinfo), sizeof(hw->bufinfo))) ) {		return result;	}	hw->bufinfo.page = hfa384x2host_16(hw->bufinfo.page);	hw->bufinfo.offset = hfa384x2host_16(hw->bufinfo.offset);	hw->bufinfo.len = hfa384x2host_16(hw->bufinfo.len);	if ( (result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_MAXLOADTIME, 				&(hw->dltimeout))) ) {		return result;	}	hw->dltimeout = hfa384x2host_16(hw->dltimeout);#if 0WLAN_LOG_DEBUG0(1,"flashdl_enable\n");hw->dlstate = HFA384x_DLSTATE_FLASHENABLED;#endif	hw->dlstate = HFA384x_DLSTATE_FLASHENABLED;	DBFEXIT;	return result;}/*----------------------------------------------------------------* hfa384x_drvr_flashdl_disable** Ends the flash download state.  Note that this will cause the MAC* firmware to restart.** 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_flashdl_disable(hfa384x_t *hw){	DBFENTER;	/* Check that we're already in the download state */	if ( hw->dlstate != HFA384x_DLSTATE_FLASHENABLED ) {		return -EINVAL;	}#if 0WLAN_LOG_DEBUG0(1,"flashdl_enable\n");hw->dlstate = HFA384x_DLSTATE_DISABLED;#endif	return 0;	/* 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_flashdl_write** Performs a FLASH download of a chunk of data. First checks to see* that we're in the FLASH download state, then sets the download* mode, uses the aux functions to 1) copy the data to the flash* buffer, 2) sets the download 'write flash' mode, 3) readback and * compare.  Lather rinse, repeat as many times an necessary to get* all the given data into flash.  * When all data has been written using this function (possibly * repeatedly), call drvr_flashdl_disable() to end the download state* and restart the MAC.** Arguments:*	hw		device structure*	daddr		Card address to write to. (host order)*	buf		Ptr to data to write.*	len		Length of data (host order).** Returns: *	0		success*	>0		f/w reported error - f/w status code*	<0		driver reported error** Side effects:** Call context:*	process ----------------------------------------------------------------*/inthfa384x_drvr_flashdl_write(	hfa384x_t	*hw, 	UINT32		daddr, 	void		*buf, 	UINT32		len)

⌨️ 快捷键说明

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