/** * @brief The main process * * @param pmlan_adapter A pointer to mlan_adapter structure * * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE */ mlan_status mlan_rx_process(IN t_void * pmlan_adapter) { mlan_status ret = MLAN_STATUS_SUCCESS; mlan_adapter *pmadapter = (mlan_adapter *) pmlan_adapter; pmlan_callbacks pcb; pmlan_buffer pmbuf; ENTER(); MASSERT(pmlan_adapter); pcb = &pmadapter->callbacks; pcb->moal_spin_lock(pmadapter->pmoal_handle, pmadapter->prx_proc_lock); if (pmadapter->mlan_rx_processing || pmadapter->rx_lock_flag) { pcb->moal_spin_unlock(pmadapter->pmoal_handle, pmadapter->prx_proc_lock); goto exit_rx_proc; } else { pmadapter->mlan_rx_processing = MTRUE; pcb->moal_spin_unlock(pmadapter->pmoal_handle, pmadapter->prx_proc_lock); } /* Check for Rx data */ while ((pmbuf = (pmlan_buffer) util_dequeue_list(pmadapter->pmoal_handle, &pmadapter->rx_data_queue, pmadapter->callbacks. moal_spin_lock, pmadapter->callbacks. moal_spin_unlock))) { util_scalar_decrement(pmadapter->pmoal_handle, &pmadapter->rx_pkts_queued, pmadapter->callbacks.moal_spin_lock, pmadapter->callbacks.moal_spin_unlock); if (pmadapter->delay_task_flag && (util_scalar_read (pmadapter->pmoal_handle, &pmadapter->rx_pkts_queued, pmadapter->callbacks.moal_spin_lock, pmadapter->callbacks.moal_spin_unlock) < LOW_RX_PENDING)) { PRINTM(MEVENT, "Run\n"); pmadapter->delay_task_flag = MFALSE; wlan_recv_event(wlan_get_priv (pmadapter, MLAN_BSS_ROLE_ANY), MLAN_EVENT_ID_DRV_DEFER_HANDLING, MNULL); } wlan_handle_rx_packet(pmadapter, pmbuf); } pcb->moal_spin_lock(pmadapter->pmoal_handle, pmadapter->prx_proc_lock); pmadapter->mlan_rx_processing = MFALSE; pcb->moal_spin_unlock(pmadapter->pmoal_handle, pmadapter->prx_proc_lock); exit_rx_proc: LEAVE(); return ret; }
/** * @brief This function decodes the rx packet & * calls corresponding handlers according to the packet type * * @param pmadapter A pointer to mlan_adapter structure * @param pmbuf A pointer to the SDIO data/cmd buffer * @param upld_typ Type of rx packet * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE */ mlan_status wlan_decode_rx_packet(mlan_adapter * pmadapter, mlan_buffer * pmbuf, t_u32 upld_typ) { t_u8 *cmdBuf; t_u32 event; switch (upld_typ) { case MLAN_TYPE_DATA: PRINTM(MINFO, "--- Rx: Data packet ---\n"); pmbuf->data_len = (pmadapter->upld_len - INTF_HEADER_LEN); pmbuf->data_offset += INTF_HEADER_LEN; wlan_handle_rx_packet(pmadapter, pmbuf); break; case MLAN_TYPE_CMD: PRINTM(MINFO, "--- Rx: Cmd Response ---\n"); DBG_HEXDUMP(MDAT_D, "Cmd RESP BUFFER", pmbuf->pbuf + pmbuf->data_offset, pmadapter->upld_len); /* take care of curr_cmd = NULL case */ if (!pmadapter->curr_cmd) { cmdBuf = pmadapter->upld_buf; if (pmadapter->ps_state == PS_STATE_SLEEP_CFM) { wlan_process_sleep_confirm_resp(pmadapter, pmbuf->pbuf + pmbuf->data_offset + INTF_HEADER_LEN, pmadapter->upld_len - INTF_HEADER_LEN); } pmadapter->upld_len -= INTF_HEADER_LEN; memcpy(pmadapter, cmdBuf, pmbuf->pbuf + pmbuf->data_offset + INTF_HEADER_LEN, MIN(MRVDRV_SIZE_OF_CMD_BUFFER, pmadapter->upld_len - INTF_HEADER_LEN)); wlan_free_mlan_buffer(pmadapter, pmbuf); } else { pmadapter->cmd_resp_received = MTRUE; pmadapter->upld_len -= INTF_HEADER_LEN; pmbuf->data_len -= INTF_HEADER_LEN; pmbuf->data_offset += INTF_HEADER_LEN; pmadapter->curr_cmd->respbuf = pmbuf; } break; case MLAN_TYPE_EVENT: PRINTM(MINFO, "--- Rx: Event ---\n"); event = *(t_u32 *) & pmbuf->pbuf[pmbuf->data_offset + INTF_HEADER_LEN]; pmadapter->event_cause = wlan_le32_to_cpu(event); if ((pmadapter->upld_len > MLAN_EVENT_HEADER_LEN) && ((pmadapter->upld_len - MLAN_EVENT_HEADER_LEN) < MAX_EVENT_SIZE)) { memcpy(pmadapter, pmadapter->event_body, pmbuf->pbuf + pmbuf->data_offset + MLAN_EVENT_HEADER_LEN, pmadapter->upld_len - MLAN_EVENT_HEADER_LEN); } /* event cause has been saved to adapter->event_cause */ pmadapter->event_received = MTRUE; pmbuf->data_len = pmadapter->upld_len; pmadapter->pmlan_buffer_event = pmbuf; /* remove SDIO header */ pmbuf->data_offset += INTF_HEADER_LEN; pmbuf->data_len -= INTF_HEADER_LEN; break; default: PRINTM(MERROR, "SDIO unknown upload type = 0x%x\n", upld_typ); wlan_free_mlan_buffer(pmadapter, pmbuf); break; } return MLAN_STATUS_SUCCESS; }