software/drivers/sd8887/src/wlan/mlan/mlan_sdio.c
/**
 *  @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
 *  @param lock_flag  flag for spin_lock.
 *  @return          MLAN_STATUS_SUCCESS
 */
@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
@param lock_flag  flag for spin_lock.
@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 @param lock_flag flag for spin_lock .
static mlan_status
wlan_decode_rx_packet(mlan_adapter *pmadapter, mlan_buffer *pmbuf,
		      t_u32 upld_typ, t_u8 lock_flag)
{
	t_u8 *cmd_buf;
	t_u32 event;
	ENTER();
	switch (upld_typ) {
	case MLAN_TYPE_SPA_DATA:
		PRINTM(MINFO, "--- Rx: SPA Data packet ---\n");
		pmbuf->data_len = pmadapter->upld_len;
		if (pmadapter->rx_work_flag) {
			pmbuf->buf_type = MLAN_BUF_TYPE_SPA_DATA;
			if (lock_flag)
				pmadapter->callbacks.moal_spin_lock(pmadapter->
								    pmoal_handle,
								    pmadapter->
								    rx_data_queue.
								    plock);
			util_enqueue_list_tail(pmadapter->pmoal_handle,
					       &pmadapter->rx_data_queue,
					       (pmlan_linked_list)pmbuf, MNULL,
					       MNULL);
			pmadapter->rx_pkts_queued++;
			if (lock_flag)
				pmadapter->callbacks.
					moal_spin_unlock(pmadapter->
							 pmoal_handle,
							 pmadapter->
							 rx_data_queue.plock);
		} else {
			wlan_decode_spa_buffer(pmadapter,
					       pmbuf->pbuf + pmbuf->data_offset,
					       pmbuf->data_len);
			wlan_free_mlan_buffer(pmadapter, pmbuf);
		}
		pmadapter->data_received = MTRUE;
		break;
	case MLAN_TYPE_DATA:
		PRINTM(MINFO, "--- Rx: Data packet ---\n");
		if (pmadapter->upld_len > pmbuf->data_len) {
			PRINTM(MERROR,
			       "SDIO: Drop packet upld_len=%d data_len=%d \n",
			       pmadapter->upld_len, pmbuf->data_len);
			wlan_free_mlan_buffer(pmadapter, pmbuf);
			break;
		}
		pmbuf->data_len = (pmadapter->upld_len - INTF_HEADER_LEN);
		pmbuf->data_offset += INTF_HEADER_LEN;
		if (pmadapter->rx_work_flag) {
			if (lock_flag)
				pmadapter->callbacks.moal_spin_lock(pmadapter->
								    pmoal_handle,
								    pmadapter->
								    rx_data_queue.
								    plock);
			util_enqueue_list_tail(pmadapter->pmoal_handle,
					       &pmadapter->rx_data_queue,
					       (pmlan_linked_list)pmbuf, MNULL,
					       MNULL);
			pmadapter->rx_pkts_queued++;
			if (lock_flag)
				pmadapter->callbacks.
					moal_spin_unlock(pmadapter->
							 pmoal_handle,
							 pmadapter->
							 rx_data_queue.plock);
		} else {
			wlan_handle_rx_packet(pmadapter, pmbuf);
		}
		pmadapter->data_received = MTRUE;
		break;
	case MLAN_TYPE_CMD:
		PRINTM(MINFO, "--- Rx: Cmd Response ---\n");
		if (!pmadapter->curr_cmd) {
			cmd_buf = 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, cmd_buf,
			       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 = pmadapter->upld_len;
			pmbuf->data_offset += INTF_HEADER_LEN;
			pmadapter->curr_cmd->respbuf = pmbuf;
			if (pmadapter->upld_len >= MRVDRV_SIZE_OF_CMD_BUFFER) {
				PRINTM(MERROR, "Invalid CmdResp len=%d\n",
				       pmadapter->upld_len);
				DBG_HEXDUMP(MERROR, "Invalid CmdResp",
					    pmbuf->pbuf + pmbuf->data_offset,
					    MAX_DATA_DUMP_LEN);
			}
		}
		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);
		}
		pmadapter->event_received = MTRUE;
		pmbuf->data_len = pmadapter->upld_len;
		pmadapter->pmlan_buffer_event = pmbuf;
		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;
	}
	LEAVE();
	return MLAN_STATUS_SUCCESS;
}
static mlan_status wlan_decode_rx_packet ( mlan_adapter * pmadapter , mlan_buffer * pmbuf , t_u32 upld_typ , t_u8 lock_flag ) { t_u8 * cmd_buf ; t_u32 event ; ENTER ( ) ; switch ( upld_typ ) { case MLAN_TYPE_SPA_DATA : PRINTM ( MINFO , " \n " ) ; pmbuf -> data_len = pmadapter -> upld_len ; if ( pmadapter -> rx_work_flag ) { pmbuf -> buf_type = MLAN_BUF_TYPE_SPA_DATA ; if ( lock_flag ) pmadapter -> callbacks . moal_spin_lock ( pmadapter -> pmoal_handle , pmadapter -> rx_data_queue . plock ) ; util_enqueue_list_tail ( pmadapter -> pmoal_handle , & pmadapter -> rx_data_queue , ( pmlan_linked_list ) pmbuf , MNULL , MNULL ) ; pmadapter -> rx_pkts_queued ++ ; if ( lock_flag ) pmadapter -> callbacks . moal_spin_unlock ( pmadapter -> pmoal_handle , pmadapter -> rx_data_queue . plock ) ; } else { wlan_decode_spa_buffer ( pmadapter , pmbuf -> pbuf + pmbuf -> data_offset , pmbuf -> data_len ) ; wlan_free_mlan_buffer ( pmadapter , pmbuf ) ; } pmadapter -> data_received = MTRUE ; break ; case MLAN_TYPE_DATA : PRINTM ( MINFO , " \n " ) ; if ( pmadapter -> upld_len > pmbuf -> data_len ) { PRINTM ( MERROR , " \n " , pmadapter -> upld_len , pmbuf -> data_len ) ; wlan_free_mlan_buffer ( pmadapter , pmbuf ) ; break ; } pmbuf -> data_len = ( pmadapter -> upld_len - INTF_HEADER_LEN ) ; pmbuf -> data_offset += INTF_HEADER_LEN ; if ( pmadapter -> rx_work_flag ) { if ( lock_flag ) pmadapter -> callbacks . moal_spin_lock ( pmadapter -> pmoal_handle , pmadapter -> rx_data_queue . plock ) ; util_enqueue_list_tail ( pmadapter -> pmoal_handle , & pmadapter -> rx_data_queue , ( pmlan_linked_list ) pmbuf , MNULL , MNULL ) ; pmadapter -> rx_pkts_queued ++ ; if ( lock_flag ) pmadapter -> callbacks . moal_spin_unlock ( pmadapter -> pmoal_handle , pmadapter -> rx_data_queue . plock ) ; } else { wlan_handle_rx_packet ( pmadapter , pmbuf ) ; } pmadapter -> data_received = MTRUE ; break ; case MLAN_TYPE_CMD : PRINTM ( MINFO , " \n " ) ; if ( ! pmadapter -> curr_cmd ) { cmd_buf = 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 , cmd_buf , 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 = pmadapter -> upld_len ; pmbuf -> data_offset += INTF_HEADER_LEN ; pmadapter -> curr_cmd -> respbuf = pmbuf ; if ( pmadapter -> upld_len >= MRVDRV_SIZE_OF_CMD_BUFFER ) { PRINTM ( MERROR , " \n " , pmadapter -> upld_len ) ; DBG_HEXDUMP ( MERROR , " " , pmbuf -> pbuf + pmbuf -> data_offset , MAX_DATA_DUMP_LEN ) ; } } break ; case MLAN_TYPE_EVENT : PRINTM ( MINFO , " \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 ) ; } pmadapter -> event_received = MTRUE ; pmbuf -> data_len = pmadapter -> upld_len ; pmadapter -> pmlan_buffer_event = pmbuf ; pmbuf -> data_offset += INTF_HEADER_LEN ; pmbuf -> data_len -= INTF_HEADER_LEN ; break ; default : PRINTM ( MERROR , " \n " , upld_typ ) ; wlan_free_mlan_buffer ( pmadapter , pmbuf ) ; break ; } LEAVE ( ) ; return MLAN_STATUS_SUCCESS ; }
@brief This function decodes the rx packet &
  calls corresponding handlers according to the packet type
@brief This function decodes the rx packet & calls corresponding handlers according to the packet type
/* take care of curr_cmd = NULL case */ /* event cause has been saved to adapter->event_cause */ /* remove SDIO header */