📄 hfa384x_usb.c
字号:
----------------------------------------------------------------*/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 + -