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

📄 hfa384x_usb.c

📁 这是基于hfa3841、hfa3842的无线网卡linux驱动程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
----------------------------------------------------------------*/static voidhfa384x_usb_defer(void *data){	hfa384x_t *hw = data;	struct net_device *netdev = hw->wlandev->netdev;	unsigned long flags;	/* Don't bother trying to reset anything if the plug	 * has been pulled ...	 */	spin_lock_irqsave(&hw->ctlxq.lock, flags);	if ( hw->usb_removed ) {		spin_unlock_irqrestore(&hw->ctlxq.lock, flags);		return;	}	spin_unlock_irqrestore(&hw->ctlxq.lock, flags);	/* Reception has stopped: try to reset the input pipe */	if (test_bit(WORK_RX_HALT, &hw->work_flags)) {		int ret;		usb_unlink_urb(&hw->rx_urb);  /* Cannot be holding spinlock! */		ret = usb_clear_halt(hw->usb,		                     usb_rcvbulkpipe(hw->usb, hw->endp_in));		if (ret != 0) {			printk(KERN_ERR			       "Failed to clear rx pipe for %s: err=%d\n",			       netdev->name, ret);		}		else {			printk(KERN_INFO "%s rx pipe reset complete.\n",			                 netdev->name);			clear_bit(WORK_RX_HALT, &hw->work_flags);			submit_rx_urb(hw, GFP_KERNEL);		}	}	/* Transmission has stopped: try to reset the output pipe */	if (test_bit(WORK_TX_HALT, &hw->work_flags)) {		int ret;		usb_unlink_urb(&hw->tx_urb);		ret = usb_clear_halt(hw->usb,		                     usb_sndbulkpipe(hw->usb, hw->endp_out));		if (ret != 0) {			printk(KERN_ERR			       "Failed to clear tx pipe for %s: err=%d\n",			       netdev->name, ret);		} else {			printk(KERN_INFO "%s tx pipe reset complete.\n",			                 netdev->name);			p80211netdev_wake_queue(hw->wlandev);			clear_bit(WORK_TX_HALT, &hw->work_flags);			/* Stopping the BULK-OUT pipe also blocked			 * us from sending any more CTLX URBs, so			 * we need to re-run our queue ...			 */			hfa384x_usbctlxq_run(&hw->ctlxq);		}	}}/*----------------------------------------------------------------* hfa384x_create** Sets up the hfa384x_t data structure for use.  Note this* does _not_ intialize the actual hardware, just the data structures* we use to keep track of its state.** Arguments:*	hw		device structure*	irq		device irq number*	iobase		i/o base address for register access*	membase		memory base address for register access** Returns: *	nothing** Side effects:** Call context:*	process ----------------------------------------------------------------*/voidhfa384x_create( hfa384x_t *hw, struct usb_device *usb){	DBFENTER;	memset(hw, 0, sizeof(hfa384x_t));	hw->usb = usb;	hw->endp_in = -1;	hw->endp_out = -1;	/* Set up the waitq */	init_waitqueue_head(&hw->cmdq);	/* Initialize the command queue */	spin_lock_init(&hw->ctlxq.lock);	INIT_LIST_HEAD(&hw->ctlxq.pending);	INIT_LIST_HEAD(&hw->ctlxq.active);	INIT_LIST_HEAD(&hw->ctlxq.finished);	/* Initialize the authentication queue */	skb_queue_head_init(&hw->authq);	INIT_WORK(&hw->link_bh, prism2sta_processing_defer, hw);	INIT_WORK(&hw->usb_work, hfa384x_usb_defer, hw);	usb_init_urb(&hw->rx_urb);	usb_init_urb(&hw->tx_urb);/* We need to make sure everything is set up to do USB transfers after this * function is complete. * Normally, Initialize will be called after this is set up. */	hw->link_status = HFA384x_LINK_NOTCONNECTED;	hw->state = HFA384x_STATE_INIT;	DBFEXIT;}/*----------------------------------------------------------------* hfa384x_destroy** Partner to hfa384x_create().  This function cleans up the hw* structure so that it can be freed by the caller using a simple* kfree.  Currently, this function is just a placeholder.  If, at some* point in the future, an hw in the 'shutdown' state requires a 'deep'* kfree, this is where it should be done.  Note that if this function* is called on a _running_ hw structure, the drvr_stop() function is* called.** Arguments:*	hw		device structure** Returns: *	nothing, this function is not allowed to fail.** Side effects:** Call context:*	process ----------------------------------------------------------------*/voidhfa384x_destroy( hfa384x_t *hw){	struct sk_buff *skb;	DBFENTER;	if ( hw->state == HFA384x_STATE_RUNNING ) {		hfa384x_drvr_stop(hw);	}	hw->state = HFA384x_STATE_PREINIT;			if (hw->scanresults) {		kfree(hw->scanresults);		hw->scanresults = NULL;	}	/* Now to clean out the auth queue */        while ( (skb = skb_dequeue(&hw->authq)) ) {                dev_kfree_skb(skb);        }			DBFEXIT;}/*----------------------------------------------------------------* hfa384x_cbcmd** Ctlx_complete handler for async CMD type control exchanges.* mark the hw struct as such.** Note: If the handling is changed here, it should probably be *       changed in docmd as well.** Arguments:*	hw		hw struct*	ctlx		complete CTLX** Returns: *	nothing** Side effects:** Call context:*	interrupt----------------------------------------------------------------*/voidhfa384x_cbcmd(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx){	DBFENTER;	if ( ctlx->usercb != NULL ) {		hfa384x_async_cmdresult_t	cmdresult;		CTLX_STATE			result;		memset(&cmdresult, 0, sizeof(cmdresult));		result = ctlx->state;		if (result == CTLX_COMPLETE) {			cmdresult.status = 				hfa384x2host_16(ctlx->inbuf.cmdresp.status);			cmdresult.resp0 = 				hfa384x2host_16(ctlx->inbuf.cmdresp.resp0);			cmdresult.resp1 = 				hfa384x2host_16(ctlx->inbuf.cmdresp.resp1);			cmdresult.resp2 = 				hfa384x2host_16(ctlx->inbuf.cmdresp.resp2);		}			ctlx->usercb(hw, result, &cmdresult, ctlx->usercb_data);	}	DBFEXIT;}/*----------------------------------------------------------------* hfa384x_cbrrid** CTLX completion handler for async RRID type control exchanges.* * Note: If the handling is changed here, it should probably be *       changed in dorrid as well.** Arguments:*	hw		hw struct*	ctlx		complete CTLX** Returns: *	nothing** Side effects:** Call context:*	interrupt----------------------------------------------------------------*/voidhfa384x_cbrrid(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx){	DBFENTER;	if ( ctlx->usercb != NULL ) {		hfa384x_async_rridresult_t	rridresult;		CTLX_STATE			result;		memset(&rridresult, 0, sizeof(rridresult));		result = ctlx->state;			if (result == CTLX_COMPLETE) {			rridresult.rid = 				hfa384x2host_16(ctlx->inbuf.rridresp.rid);			rridresult.riddata = ctlx->inbuf.rridresp.data;			rridresult.riddata_len = 			((hfa384x2host_16(ctlx->inbuf.rridresp.frmlen)-1)*2);		}		ctlx->usercb(hw, result, &rridresult, ctlx->usercb_data);	}	DBFEXIT;}/*----------------------------------------------------------------* hfa384x_cbwrid** CTLX completion handler for async WRID type control exchanges.** Note: If the handling is changed here, it should probably be *       changed in dowrid as well.** Arguments:*	hw		hw struct*	ctlx		complete CTLX** Returns: *	nothing** Side effects:** Call context:*	interrupt----------------------------------------------------------------*/voidhfa384x_cbwrid(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx){	DBFENTER;	if ( ctlx->usercb != NULL ) {		hfa384x_async_wridresult_t	wridresult;		CTLX_STATE			result;		memset(&wridresult, 0, sizeof(wridresult));		result = ctlx->state;		if (result == CTLX_COMPLETE) {			wridresult.status = 				hfa384x2host_16(ctlx->inbuf.wridresp.status);			wridresult.resp0 = 				hfa384x2host_16(ctlx->inbuf.wridresp.resp0);			wridresult.resp1 = 				hfa384x2host_16(ctlx->inbuf.wridresp.resp1);			wridresult.resp2 = 				hfa384x2host_16(ctlx->inbuf.wridresp.resp2);		}		ctlx->usercb(hw, result, &wridresult, ctlx->usercb_data);	}	DBFEXIT;}/*----------------------------------------------------------------* hfa384x_cbrmem** CTLX completion handler for async RMEM type control exchanges.** Note: If the handling is changed here, it should probably be *       changed in dormem as well.** Arguments:*	hw		hw struct*	ctlx		complete CTLX** Returns: *	nothing** Side effects:** Call context:*	interrupt----------------------------------------------------------------*/voidhfa384x_cbrmem(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx){	DBFENTER;	DBFEXIT;}/*----------------------------------------------------------------* hfa384x_cbwmem** CTLX completion handler for async WMEM type control exchanges.** Note: If the handling is changed here, it should probably be *       changed in dowmem as well.** Arguments:*	hw		hw struct*	ctlx		complete CTLX** Returns: *	nothing** Side effects:** Call context:*	interrupt----------------------------------------------------------------*/voidhfa384x_cbwmem(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx){	DBFENTER;	DBFEXIT;}/*----------------------------------------------------------------* hfa384x_cmd_initialize** Issues the initialize command and sets the hw->state based* on the result.** 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----------------------------------------------------------------*/inthfa384x_cmd_initialize(hfa384x_t *hw){	int	result = 0;	int	i;	hfa384x_metacmd_t cmd;	DBFENTER;	cmd.cmd = HFA384x_CMDCODE_INIT;	cmd.parm0 = 0;	cmd.parm1 = 0;	cmd.parm2 = 0;	result = hfa384x_docmd(hw, DOWAIT, &cmd, NULL, NULL);	WLAN_LOG_DEBUG(3,"cmdresp.init: "		"status=0x%04x, resp0=0x%04x, "		"resp1=0x%04x, resp2=0x%04x\n",		cmd.status, cmd.resp0, cmd.resp1, cmd.resp2);	if ( result == 0 ) {		for ( i = 0; i < HFA384x_NUMPORTS_MAX; i++) {			hw->port_enabled[i] = 0;		}	}	DBFEXIT;	return result;}/*----------------------------------------------------------------* hfa384x_cmd_disable** Issues the disable command to stop communications on one of * the MACs 'ports'.** 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_cmd_disable(hfa384x_t *hw, UINT16 macport){	int	result = 0;	hfa384x_metacmd_t cmd;	DBFENTER;	cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_DISABLE) |		  HFA384x_CMD_MACPORT_SET(macport);	cmd.parm0 = 0;	cmd.parm1 = 0;	cmd.parm2 = 0;	result = hfa384x_docmd(hw, DOWAIT, &cmd, NULL, NULL);	DBFEXIT;	return result;}/*----------------------------------------------------------------* hfa384x_cmd_enable** Issues the enable command to enable communications on one of * the MACs 'ports'.** 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_cmd_enable(hfa384x_t *hw, UINT16 macport){	int	result = 0;	hfa384x_metacmd_t cmd;	DBFENTER;	cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_ENABLE) |		  HFA384x_CMD_MACPORT_SET(macport);	cmd.parm0 = 0;	cmd.parm1 = 0;	cmd.parm2 = 0;	result = hfa384x_docmd(hw, DOWAIT, &cmd, NULL, NULL);	DBFEXIT;	return result;}/*----------------------------------------------------------------* hfa384x_cmd_notify** Sends an info frame to the firmware to alter the behavior* of the f/w asynch processes.  Can only be called when the MAC

⌨️ 快捷键说明

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