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

📄 hfa384x_usb.c

📁 这是基于hfa3841、hfa3842的无线网卡linux驱动程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
* Side effects:*	* Call context:*	interrupt (wait==0)*	process (wait==0 || wait==1)----------------------------------------------------------------*/static inthfa384x_dorrid(	hfa384x_t *hw, 	UINT	wait,	UINT16	rid,	void	*riddata,	UINT	riddatalen,	ctlx_usercb_t usercb,	void	*usercb_data){	int			result;	hfa384x_usbctlx_t	*ctlx;	UINT			maclen;		DBFENTER;	ctlx = kmalloc(sizeof(*ctlx), in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);	if ( ctlx == NULL ) {		result = -ENOMEM;		goto done;	}	hfa384x_usbctlx_init(ctlx, hw);	/* Initialize the command */	ctlx->outbuf.rridreq.type =   host2hfa384x_16(HFA384x_USB_RRIDREQ);	ctlx->outbuf.rridreq.frmlen = 		host2hfa384x_16(sizeof(ctlx->outbuf.rridreq.rid));	ctlx->outbuf.rridreq.rid =    host2hfa384x_16(rid);	/* Fill the out packet */	usb_fill_bulk_urb( &(ctlx->outurb), hw->usb,		usb_sndbulkpipe(hw->usb, hw->endp_out),		&(ctlx->outbuf), ROUNDUP64(sizeof(ctlx->outbuf.rridreq)),		hfa384x_ctlxout_callback, ctlx);	ctlx->outurb.transfer_flags |= USB_QUEUE_BULK;	/* Submit the CTLX */	if ( wait ) {		hfa384x_usbctlx_submit_wait(hw, ctlx);	} else if ( hfa384x_usbctlx_submit_async(	                              hw, ctlx, usercb, usercb_data) == 0 ) {		result = 0;		goto done;	}	/* All of the following is skipped for async calls */	/* On reawakening, check the ctlx status */	switch(ctlx->state) { 	case CTLX_COMPLETE:		/* The results are in ctlx->outbuf */		/* Validate the length, note body len calculation in bytes */		maclen = ((hfa384x2host_16(ctlx->inbuf.rridresp.frmlen)-1)*2);		if ( maclen != riddatalen ) {  			WLAN_LOG_WARNING(			"RID len mismatch, rid=0x%04x hlen=%d fwlen=%d\n",			rid, riddatalen, maclen);			result = -ENODATA;			break;		}		memcpy( riddata, ctlx->inbuf.rridresp.data, riddatalen);		result = 0;		break;	case CTLX_REQSUBMIT_FAIL:		WLAN_LOG_WARNING("ctlx failure=REQSUBMIT_FAIL\n");		result = -EIO;		break;	case CTLX_REQ_TIMEOUT:		WLAN_LOG_WARNING("ctlx failure=REQ_TIMEOUT\n");		result = -EIO;		break;	case CTLX_REQ_FAILED:		WLAN_LOG_WARNING("ctlx failure=REQ_FAILED\n");		result = -EIO;		break;	case CTLX_START:		result = -EIO;		break;	default:		result = -ERESTARTSYS;		break;	} /* switch */	complete(&ctlx->done);	kfree(ctlx);done:	DBFEXIT;	return result;}/*----------------------------------------------------------------* hfa384x_dowrid** Constructs a write rid CTLX and issues it.** NOTE: Any changes to the 'post-submit' code in this function *       need to be carried over to hfa384x_cbwrid() since the handling*       is virtually identical.** Arguments:*	hw		device structure*	wait		1=wait for completion, 0=async*	rid		RID code*	riddata		Data portion of RID formatted for MAC*	riddatalen	Length of the data portion in bytes*	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_dowrid(	hfa384x_t *hw, 	UINT	wait,	UINT16	rid,	void	*riddata,	UINT	riddatalen,	ctlx_usercb_t usercb,	void	*usercb_data){	int			result;	hfa384x_usbctlx_t	*ctlx;		DBFENTER;	ctlx = kmalloc(sizeof(*ctlx), in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);	if ( ctlx == NULL ) {		result = -ENOMEM;		goto done;	}	hfa384x_usbctlx_init(ctlx, hw);	/* Initialize the command */	ctlx->outbuf.wridreq.type =   host2hfa384x_16(HFA384x_USB_WRIDREQ);	ctlx->outbuf.wridreq.frmlen = host2hfa384x_16(					(sizeof(ctlx->outbuf.rridreq.rid) + 					riddatalen + 1) / 2);	ctlx->outbuf.wridreq.rid =    host2hfa384x_16(rid);	memcpy(ctlx->outbuf.wridreq.data, riddata, riddatalen);	/* Fill the out packet */	usb_fill_bulk_urb( &(ctlx->outurb), hw->usb,		usb_sndbulkpipe(hw->usb, hw->endp_out),		&(ctlx->outbuf), 		ROUNDUP64( sizeof(ctlx->outbuf.wridreq.type) +			sizeof(ctlx->outbuf.wridreq.frmlen) +			sizeof(ctlx->outbuf.wridreq.rid) +			riddatalen),		hfa384x_ctlxout_callback, 		ctlx);	ctlx->outurb.transfer_flags |= USB_QUEUE_BULK;	/* Submit the CTLX */	if ( wait ) {		hfa384x_usbctlx_submit_wait(hw, ctlx);	} else if ( hfa384x_usbctlx_submit_async(                                      hw, ctlx, usercb, usercb_data) == 0 ) {		result = 0;		goto done;	}	/* All of the following is skipped for async calls */	/* On reawakening, check the ctlx status */	switch(ctlx->state) { 	case CTLX_COMPLETE:		result = hfa384x2host_16(ctlx->inbuf.wridresp.status);		result &= HFA384x_STATUS_RESULT;/*		hw->status = hfa384x2host_16(ctlx->inbuf.wridresp.status);		hw->resp0 = hfa384x2host_16(ctlx->inbuf.wridresp.resp0);		hw->resp1 = hfa384x2host_16(ctlx->inbuf.wridresp.resp1);		hw->resp2 = hfa384x2host_16(ctlx->inbuf.wridresp.resp2);*/		break;	case CTLX_REQSUBMIT_FAIL:		WLAN_LOG_WARNING("ctlx failure=REQSUBMIT_FAIL\n");		result = -EIO;		break;	case CTLX_REQ_TIMEOUT:		WLAN_LOG_WARNING("ctlx failure=REQ_TIMEOUT\n");		result = -EIO;		break;	case CTLX_REQ_FAILED:		WLAN_LOG_WARNING("ctlx failure=REQ_FAILED\n");		result = -EIO;		break;	case CTLX_START:		result = -EIO;		break;	default:		result = -ERESTARTSYS;		break;	} /* switch */	complete(&ctlx->done);	kfree(ctlx);done:	DBFEXIT;	return result;}/*----------------------------------------------------------------* hfa384x_dormem** Constructs a readmem CTLX and issues it.** NOTE: Any changes to the 'post-submit' code in this function *       need to be carried over to hfa384x_cbrmem() 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 to receive read*	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_dormem(	hfa384x_t *hw, 	UINT	wait,	UINT16	page,	UINT16	offset,	void	*data,	UINT	len,	ctlx_usercb_t usercb,	void	*usercb_data){	int			result;	hfa384x_usbctlx_t	*ctlx;		DBFENTER;	ctlx = kmalloc(sizeof(*ctlx), in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);	if ( ctlx == NULL ) {		result = -ENOMEM;		goto done;	}	hfa384x_usbctlx_init(ctlx, hw);	/* 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_DEBUG(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_DEBUG(4,"pktsize=%d\n", 		ROUNDUP64(sizeof(ctlx->outbuf.rmemreq)));	/* Fill the out packet */	usb_fill_bulk_urb( &(ctlx->outurb), hw->usb,		usb_sndbulkpipe(hw->usb, hw->endp_out),		&(ctlx->outbuf), ROUNDUP64(sizeof(ctlx->outbuf.rmemreq)),		hfa384x_ctlxout_callback, ctlx);	ctlx->outurb.transfer_flags |= USB_QUEUE_BULK;	if ( wait ) {		hfa384x_usbctlx_submit_wait(hw, ctlx);	} else if ( hfa384x_usbctlx_submit_async(	                              hw, ctlx, usercb, usercb_data) == 0 ) {		result = 0;		goto done;	}	/* All of the following is skipped for async calls */	/* On reawakening, check the ctlx status */	switch(ctlx->state) { 	case CTLX_COMPLETE:		WLAN_LOG_DEBUG(4,"rmemresp:len=%d\n",			ctlx->inbuf.rmemresp.frmlen);		memcpy(data, ctlx->inbuf.rmemresp.data, len);		result = 0;		break;	case CTLX_REQSUBMIT_FAIL:		WLAN_LOG_WARNING("ctlx failure=REQSUBMIT_FAIL\n");		result = -EIO;		break;	case CTLX_REQ_TIMEOUT:		WLAN_LOG_WARNING("ctlx failure=REQ_TIMEOUT\n");		result = -EIO;		break;	case CTLX_REQ_FAILED:		WLAN_LOG_WARNING("ctlx failure=REQ_FAILED\n");		result = -EIO;		break;	case CTLX_START:		result = -EIO;		break;	default:		result = -ERESTARTSYS;		break;	} /* switch */	complete(&ctlx->done);	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;	hfa384x_usbctlx_t	*ctlx;		DBFENTER;	WLAN_LOG_DEBUG(5, "page=0x%04x offset=0x%04x len=%d\n",		page,offset,len);	ctlx = kmalloc(sizeof(*ctlx), in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);	if ( ctlx == NULL ) {		result = -ENOMEM;		goto done;	}	hfa384x_usbctlx_init(ctlx, hw);	/* 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 */	usb_fill_bulk_urb( &(ctlx->outurb), hw->usb,		usb_sndbulkpipe(hw->usb, hw->endp_out),		&(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_ctlxout_callback, 		ctlx);	ctlx->outurb.transfer_flags |= USB_QUEUE_BULK;	if ( wait ) {		hfa384x_usbctlx_submit_wait(hw, ctlx);	} else if ( hfa384x_usbctlx_submit_async(	                              hw, ctlx, usercb, usercb_data) == 0 ) {		result = 0;		goto done;	}	/* All of the following is skipped for async calls */	/* On reawakening, check the ctlx status */	switch(ctlx->state) { 	case CTLX_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 CTLX_REQSUBMIT_FAIL:		WLAN_LOG_WARNING("ctlx failure=REQSUBMIT_FAIL\n");		result = -EIO;		break;	case CTLX_REQ_TIMEOUT:		WLAN_LOG_WARNING("ctlx failure=REQ_TIMEOUT\n");		result = -EIO;		break;	case CTLX_REQ_FAILED:		WLAN_LOG_WARNING("ctlx failure=REQ_FAILED\n");		result = -EIO;		break;	case CTLX_START:		result = -EIO;		break;	default:		result = -ERESTARTSYS;		break;	} /* switch */	complete(&ctlx->done);	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 ){	hfa384x_metacmd_t cmd;	DBFENTER;	cmd.cmd = HFA384x_CMDCODE_INQ;	cmd.parm0 = HFA384x_IT_COMMTALLIES;	cmd.parm1 = 0;	cmd.parm2 = 0;	hfa384x_docmd(hw, DOASYNC, &cmd, 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.

⌨️ 快捷键说明

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