📄 hfa384x.c
字号:
spin_unlock_bh(&hw->cmdlock); DBFEXIT; return result;}/*----------------------------------------------------------------* hfa384x_cmd_allocate** Issues the allocate command instructing the firmware to allocate* a 'frame structure buffer' in MAC controller RAM. This command* does not provide the result, it only initiates one of the f/w's* asynchronous processes to construct the buffer. When the * allocation is complete, it will be indicated via the Alloc* bit in the EvStat register and the FID identifying the allocated* space will be available from the AllocFID register. Some care* should be taken when waiting for the Alloc event. If a Tx or * Notify command w/ Reclaim has been previously executed, it's* possible the first Alloc event after execution of this command* will be for the reclaimed buffer and not the one you asked for.* This case must be handled in the Alloc event handler.** Arguments:* hw device structure* len allocation length, must be an even value* in the range [4-2400]. (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 thread ----------------------------------------------------------------*/int hfa384x_cmd_allocate(hfa384x_t *hw, UINT16 len){ int result = 0; hfa384x_metacmd_t cmd; DBFENTER; if ( (len % 2) || len < HFA384x_CMD_ALLOC_LEN_MIN || len > HFA384x_CMD_ALLOC_LEN_MAX ) { result = -EINVAL; } else { cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_ALLOC); cmd.parm0 = len; cmd.parm1 = 0; cmd.parm2 = 0; spin_lock_bh(&hw->cmdlock); result = hfa384x_docmd_wait(hw, &cmd); spin_unlock_bh(&hw->cmdlock); } DBFEXIT; return result;}/*----------------------------------------------------------------* hfa384x_cmd_transmit** Instructs the firmware to transmit a frame previously copied* to a given buffer. This function returns immediately, the Tx* results are available via the Tx or TxExc events (if the frame* control bits are set). The reclaim argument specifies if the * FID passed will be used by the f/w tx process or returned for* use w/ another transmit command. If reclaim is set, expect an * Alloc event signalling the availibility of the FID for reuse.** NOTE: hw->cmdlock MUST BE HELD before calling this function!** Arguments:* hw device structure* reclaim [0|1] indicates whether the given FID will* be handed back (via Alloc event) for reuse.* (host order)* qos [0-3] Value to put in the QoS field of the * tx command, identifies a queue to place the * outgoing frame in.* (host order)* fid FID of buffer containing the frame that was* previously copied to MAC memory via the bap.* (host order)** Returns: * 0 success* >0 f/w reported failure - f/w status code* <0 driver reported error (timeout|bad arg)** Side effects:* hw->resp0 will contain the FID being used by async tx* process. If reclaim==0, resp0 will be the same as the fid* argument. If reclaim==1, resp0 will be the different and* is the value to watch for in the Tx|TxExc to indicate completion* of the frame passed in fid.** Call context:* process thread ----------------------------------------------------------------*/int hfa384x_cmd_transmit(hfa384x_t *hw, UINT16 reclaim, UINT16 qos, UINT16 fid){ int result = 0; hfa384x_metacmd_t cmd; DBFENTER; cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_TX) | HFA384x_CMD_RECL_SET(reclaim) | HFA384x_CMD_QOS_SET(qos); cmd.parm0 = fid; cmd.parm1 = 0; cmd.parm2 = 0; result = hfa384x_docmd_wait(hw, &cmd); DBFEXIT; return result;}/*----------------------------------------------------------------* hfa384x_cmd_clearpersist** Instructs the firmware to clear the persistence bit in a given* FID. This has the effect of telling the firmware to drop the* persistent frame. The FID must be one that was previously used* to transmit a PRST frame.** Arguments:* hw device structure* fid FID of the persistent frame (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 thread ----------------------------------------------------------------*/int hfa384x_cmd_clearpersist(hfa384x_t *hw, UINT16 fid){ int result = 0; hfa384x_metacmd_t cmd; DBFENTER; cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_CLRPRST); cmd.parm0 = fid; cmd.parm1 = 0; cmd.parm2 = 0; spin_lock_bh(&hw->cmdlock); result = hfa384x_docmd_wait(hw, &cmd); spin_unlock_bh(&hw->cmdlock); 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* is in the enabled state.** Arguments:* hw device structure* reclaim [0|1] indicates whether the given FID will* be handed back (via Alloc event) for reuse.* (host order)* fid FID of buffer containing the frame that was* previously copied to MAC memory via the bap.* (host order)** Returns: * 0 success* >0 f/w reported failure - f/w status code* <0 driver reported error (timeout|bad arg)** Side effects:* hw->resp0 will contain the FID being used by async notify* process. If reclaim==0, resp0 will be the same as the fid* argument. If reclaim==1, resp0 will be the different.** Call context:* process thread ----------------------------------------------------------------*/int hfa384x_cmd_notify(hfa384x_t *hw, UINT16 reclaim, UINT16 fid, void *buf, UINT16 len){ int result = 0; hfa384x_metacmd_t cmd; DBFENTER; cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_NOTIFY) | HFA384x_CMD_RECL_SET(reclaim); cmd.parm0 = fid; cmd.parm1 = 0; cmd.parm2 = 0; spin_lock_bh(&hw->cmdlock); /* Copy the record to FID */ result = hfa384x_copy_to_bap(hw, HFA384x_BAP_PROC, hw->infofid, 0, buf, len); if ( result ) { WLAN_LOG_DEBUG(1, "copy_to_bap(%04x, 0, %d) failed, result=0x%x\n", hw->infofid, len, result); result = -EIO; goto failed; } result = hfa384x_docmd_wait(hw, &cmd); spin_unlock_bh(&hw->cmdlock); failed: spin_unlock_bh(&hw->cmdlock); DBFEXIT; return result;}/*----------------------------------------------------------------* hfa384x_cmd_inquiry** Requests an info frame from the firmware. The info frame will* be delivered asynchronously via the Info event.** Arguments:* hw device structure* fid FID of the info frame requested. (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 thread ----------------------------------------------------------------*/int hfa384x_cmd_inquiry(hfa384x_t *hw, UINT16 fid){ int result = 0; hfa384x_metacmd_t cmd; DBFENTER; cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_INQ); cmd.parm0 = fid; cmd.parm1 = 0; cmd.parm2 = 0; spin_lock_bh(&hw->cmdlock); result = hfa384x_docmd_wait(hw, &cmd); spin_unlock_bh(&hw->cmdlock); DBFEXIT; return result;}/*----------------------------------------------------------------* hfa384x_cmd_access** Requests that a given record be copied to/from the record * buffer. If we're writing from the record buffer, the contents* must previously have been written to the record buffer via the * bap. If we're reading into the record buffer, the record can* be read out of the record buffer after this call.** Arguments:* hw device structure* write [0|1] copy the record buffer to the given* configuration record. (host order)* rid RID of the record to read/write. (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 failure - f/w status code* <0 driver reported error (timeout|bad arg)** Side effects:** Call context:* process thread ----------------------------------------------------------------*/int hfa384x_cmd_access(hfa384x_t *hw, UINT16 write, UINT16 rid, void* buf, UINT16 len){ int result = 0; hfa384x_metacmd_t cmd; hfa384x_rec_t rec; DBFENTER;#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)) /* This should NOT be called in interrupt context! */ if (in_irq()) { WLAN_LOG_ERROR("Krap, in Interrupt context!");#ifdef WLAN_INCLUDE_DEBUG BUG();#endif }#endif spin_lock_bh(&hw->cmdlock); if (write) { rec.rid = host2hfa384x_16(rid); rec.reclen = host2hfa384x_16((len/2) + 1); /* note conversion to words, +1 for rid field */ /* write the record */ result = hfa384x_copy_to_bap4( hw, HFA384x_BAP_PROC, rid, 0, &rec, sizeof(rec), buf, len, NULL, 0, NULL, 0); if ( result ) { WLAN_LOG_DEBUG(3,"Failure writing record header+data\n"); goto fail; } } cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_ACCESS) | HFA384x_CMD_WRITE_SET(write); cmd.parm0 = rid; cmd.parm1 = 0; cmd.parm2 = 0; result = hfa384x_docmd_wait(hw, &cmd); if ( result ) { WLAN_LOG_ERROR("Call to hfa384x_docmd_wait failed (%d %d)\n", result, cmd.result.resp0); goto fail; } if (!write) { result = hfa384x_copy_from_bap( hw, HFA384x_BAP_PROC, rid, 0, &rec, sizeof(rec)); if ( result ) { WLAN_LOG_DEBUG(3,"Call to hfa384x_copy_from_bap failed\n"); goto fail; } /* Validate the record length */ if ( ((hfa384x2host_16(rec.reclen)-1)*2) != len ) { /* note body len calculation in bytes */ WLAN_LOG_DEBUG(1, "RID len mismatch, rid=0x%04x hlen=%d fwlen=%d\n", rid, len, (hfa384x2host_16(rec.reclen)-1)*2); result = -ENODATA; goto fail; } result = hfa384x_copy_from_bap( hw, HFA384x_BAP_PROC, rid, sizeof(rec), buf, len); } fail: spin_unlock_bh(&hw->cmdlock); DBFEXIT; return result;}/*----------------------------------------------------------------* hfa384x_cmd_monitor** Enables the 'monitor mode' of the MAC. Here's the description of* monitor mode that I've received thus far:** "The "monitor mode" of operation is that the MAC passes all * frames for which the PLCP checks are correct. All received * MPDUs are passed to the host with MAC Port = 7, with a * receive status of good, FCS error, or undecryptable. Passing * certain MPDUs is a violation of the 802.11 standard, but useful * for a debugging tool." Normal communication is not possible* while monitor mode is enabled.** Arguments:* hw device structure* enable a code (0x0b|0x0f) that enables/disables* monitor mode. (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 thread ----------------------------------------------------------------*/int hfa384x_cmd_monitor(hfa384x_t *hw, UINT16 enable){ int result = 0; hfa384x_metacmd_t cmd; DBFENTER; cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_MONITOR) | HFA384x_CMD_AINFO_SET(enable); cmd.parm0 = 0; cmd.parm1 = 0; cmd.parm2 = 0; spin_lock_bh(&hw->cmdlock); result = hfa384x_docmd_wait(hw, &cmd); spin_unlock_bh(&hw->cmdlock); DBFEXIT; return result;}/*----------------------------------------------------------------* hfa384x_cmd_download** Sets the controls for the MAC controller code/data download* process. The arguments set the mode and address associated * with a download. Note that the aux registers should be enabled* prior to setting one of the download enable modes.** Arguments:* hw device structure* mode 0 - Disable programming and begin code exec* 1 - Enable volatile mem programming* 2 - Enable non-volatile mem programming* 3 - Program non-volatile section from NV download* buffer. * (host order)* lowaddr * highaddr For mode 1, sets the high & low order bits of * the "destination address". This address will be* the execution start address when download is* subsequently disabled.* For mode 2, sets the high & low order bits of * the destination in NV ram.* For modes 0 & 3, should be zero. (host order)* NOTE: these address args are in CMD format* codelen Length of the data to write in mode 2, * zero otherwise. (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 thread ----------------------------------------------------------------*/int hfa384x_cmd_download(hfa384x_t *hw, UINT16 mode, UINT16 lowaddr, UINT16 highaddr, UINT16 codelen){ int result = 0; hfa384x_metacmd_t cmd; DBFENTER; cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_DOWNLD) | HFA384x_CMD_PROGMODE_SET(mode); cmd.parm0 = lowaddr; cmd.parm1 = highaddr; cmd.parm2 = codelen; spin_lock_bh(&hw->cmdlock); result = hfa384x_dl_docmd_wait(hw, &cmd); spin_unlock_bh(&hw->cmdlock); DBFEXIT; return result;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -