software/drivers/sd8887/src/wlan/mlan/mlan_sdio.c
/**
 *  @brief This function receives data from the card in aggregate mode.
 *
 *  @param pmadapter A pointer to mlan_adapter structure
 *  @return          MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
@brief This function receives data from the card in aggregate mode.
@param pmadapter A pointer to mlan_adapter structure
@return          MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
@brief This function receives data from the card in aggregate mode . @param pmadapter A pointer to mlan_adapter structure @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
mlan_status
wlan_receive_mp_aggr_buf(mlan_adapter *pmadapter)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	pmlan_callbacks pcb = &pmadapter->callbacks;
	mlan_buffer mbuf_aggr;
	mlan_buffer *mbuf_deaggr;
	t_u32 pind = 0;
	t_u32 pkt_len, pkt_type = 0;
	t_u8 *curr_ptr;
	t_u32 cmd53_port = 0;
	t_u32 i = 0;
	t_u32 port_count = 0;
	PRINTM(MINFO, "do_rx_aggr: num of packets: %d\n",
	       pmadapter->mpa_rx.pkt_cnt);
	memset(pmadapter, &mbuf_aggr, 0, sizeof(mlan_buffer));
	if (pmadapter->mpa_rx.pkt_cnt == 1)
		return wlan_receive_single_packet(pmadapter);
	if (!pmadapter->mpa_rx.buf) {
		mbuf_aggr.data_len = pmadapter->mpa_rx.buf_len;
		mbuf_aggr.pnext = mbuf_aggr.pprev = &mbuf_aggr;
		mbuf_aggr.use_count = 0;
		for (pind = 0; pind < pmadapter->mpa_rx.pkt_cnt; pind++) {
			pmadapter->mpa_rx.mbuf_arr[pind]->data_len =
				pmadapter->mpa_rx.len_arr[pind];
			wlan_link_buf_to_aggr(&mbuf_aggr,
					      pmadapter->mpa_rx.mbuf_arr[pind]);
		}
	} else {
		mbuf_aggr.pbuf = (t_u8 *)pmadapter->mpa_rx.buf;
		mbuf_aggr.data_len = pmadapter->mpa_rx.buf_len;
	}
	port_count = bitcount(pmadapter->mpa_rx.ports) - 1;
	cmd53_port =
		(pmadapter->ioport | SDIO_MPA_ADDR_BASE | (port_count << 8))
		+ pmadapter->mpa_rx.start_port;
	do {
		ret = pcb->moal_read_data_sync(pmadapter->pmoal_handle,
					       &mbuf_aggr, cmd53_port, 0);
		if (ret != MLAN_STATUS_SUCCESS) {
			PRINTM(MERROR,
			       "wlan: sdio mp cmd53 read failed: %d ioport=0x%x retry=%d\n",
			       ret, cmd53_port, i);
			i++;
			if (MLAN_STATUS_SUCCESS !=
			    pcb->moal_write_reg(pmadapter->pmoal_handle,
						HOST_TO_CARD_EVENT_REG,
						HOST_TERM_CMD53)) {
				PRINTM(MERROR, "Set Term cmd53 failed\n");
			}
			if (i > MAX_WRITE_IOMEM_RETRY) {
				ret = MLAN_STATUS_FAILURE;
				goto done;
			}
		}
	} while (ret == MLAN_STATUS_FAILURE);
	if (!pmadapter->mpa_rx.buf && pmadapter->mpa_rx.pkt_cnt > 1) {
		for (pind = 0; pind < pmadapter->mpa_rx.pkt_cnt; pind++) {
			mbuf_deaggr = pmadapter->mpa_rx.mbuf_arr[pind];
			pkt_len =
				wlan_le16_to_cpu(*(t_u16 *)
						 (mbuf_deaggr->pbuf +
						  mbuf_deaggr->data_offset));
			pkt_type =
				wlan_le16_to_cpu(*(t_u16 *)
						 (mbuf_deaggr->pbuf +
						  mbuf_deaggr->data_offset +
						  2));
			pmadapter->upld_len = pkt_len;
			wlan_decode_rx_packet(pmadapter, mbuf_deaggr, pkt_type,
					      MTRUE);
		}
	} else {
		DBG_HEXDUMP(MIF_D, "SDIO MP-A Blk Rd", pmadapter->mpa_rx.buf,
			    MIN(pmadapter->mpa_rx.buf_len, MAX_DATA_DUMP_LEN));
		curr_ptr = pmadapter->mpa_rx.buf;
		for (pind = 0; pind < pmadapter->mpa_rx.pkt_cnt; pind++) {
			pkt_len = wlan_le16_to_cpu(*(t_u16 *)&curr_ptr[0]);
			pkt_type = wlan_le16_to_cpu(*(t_u16 *)&curr_ptr[2]);
			PRINTM(MINFO, "RX: [%d] pktlen: %d pkt_type: 0x%x\n",
			       pind, pkt_len, pkt_type);
			mbuf_deaggr = pmadapter->mpa_rx.mbuf_arr[pind];
			if ((pkt_type == MLAN_TYPE_DATA
			     || pkt_type == MLAN_TYPE_SPA_DATA) &&
			    (pkt_len <= pmadapter->mpa_rx.len_arr[pind])) {
				memcpy(pmadapter,
				       mbuf_deaggr->pbuf +
				       mbuf_deaggr->data_offset, curr_ptr,
				       pkt_len);
				pmadapter->upld_len = pkt_len;
				wlan_decode_rx_packet(pmadapter, mbuf_deaggr,
						      pkt_type, MTRUE);
			} else {
				PRINTM(MERROR,
				       "Wrong aggr packet: type=%d, len=%d, max_len=%d\n",
				       pkt_type, pkt_len,
				       pmadapter->mpa_rx.len_arr[pind]);
				wlan_free_mlan_buffer(pmadapter, mbuf_deaggr);
			}
			curr_ptr += pmadapter->mpa_rx.len_arr[pind];
		}
	}
	pmadapter->mpa_rx_count[pmadapter->mpa_rx.pkt_cnt - 1]++;
	MP_RX_AGGR_BUF_RESET(pmadapter);
done:
	return ret;
}
mlan_status wlan_receive_mp_aggr_buf ( mlan_adapter * pmadapter ) { mlan_status ret = MLAN_STATUS_SUCCESS ; pmlan_callbacks pcb = & pmadapter -> callbacks ; mlan_buffer mbuf_aggr ; mlan_buffer * mbuf_deaggr ; t_u32 pind = 0 ; t_u32 pkt_len , pkt_type = 0 ; t_u8 * curr_ptr ; t_u32 cmd53_port = 0 ; t_u32 i = 0 ; t_u32 port_count = 0 ; PRINTM ( MINFO , " \n " , pmadapter -> mpa_rx . pkt_cnt ) ; memset ( pmadapter , & mbuf_aggr , 0 , sizeof ( mlan_buffer ) ) ; if ( pmadapter -> mpa_rx . pkt_cnt == 1 ) return wlan_receive_single_packet ( pmadapter ) ; if ( ! pmadapter -> mpa_rx . buf ) { mbuf_aggr . data_len = pmadapter -> mpa_rx . buf_len ; mbuf_aggr . pnext = mbuf_aggr . pprev = & mbuf_aggr ; mbuf_aggr . use_count = 0 ; for ( pind = 0 ; pind < pmadapter -> mpa_rx . pkt_cnt ; pind ++ ) { pmadapter -> mpa_rx . mbuf_arr [ pind ] -> data_len = pmadapter -> mpa_rx . len_arr [ pind ] ; wlan_link_buf_to_aggr ( & mbuf_aggr , pmadapter -> mpa_rx . mbuf_arr [ pind ] ) ; } } else { mbuf_aggr . pbuf = ( t_u8 * ) pmadapter -> mpa_rx . buf ; mbuf_aggr . data_len = pmadapter -> mpa_rx . buf_len ; } port_count = bitcount ( pmadapter -> mpa_rx . ports ) - 1 ; cmd53_port = ( pmadapter -> ioport | SDIO_MPA_ADDR_BASE | ( port_count << 8 ) ) + pmadapter -> mpa_rx . start_port ; do { ret = pcb -> moal_read_data_sync ( pmadapter -> pmoal_handle , & mbuf_aggr , cmd53_port , 0 ) ; if ( ret != MLAN_STATUS_SUCCESS ) { PRINTM ( MERROR , " \n " , ret , cmd53_port , i ) ; i ++ ; if ( MLAN_STATUS_SUCCESS != pcb -> moal_write_reg ( pmadapter -> pmoal_handle , HOST_TO_CARD_EVENT_REG , HOST_TERM_CMD53 ) ) { PRINTM ( MERROR , " \n " ) ; } if ( i > MAX_WRITE_IOMEM_RETRY ) { ret = MLAN_STATUS_FAILURE ; goto done ; } } } while ( ret == MLAN_STATUS_FAILURE ) ; if ( ! pmadapter -> mpa_rx . buf && pmadapter -> mpa_rx . pkt_cnt > 1 ) { for ( pind = 0 ; pind < pmadapter -> mpa_rx . pkt_cnt ; pind ++ ) { mbuf_deaggr = pmadapter -> mpa_rx . mbuf_arr [ pind ] ; pkt_len = wlan_le16_to_cpu ( * ( t_u16 * ) ( mbuf_deaggr -> pbuf + mbuf_deaggr -> data_offset ) ) ; pkt_type = wlan_le16_to_cpu ( * ( t_u16 * ) ( mbuf_deaggr -> pbuf + mbuf_deaggr -> data_offset + 2 ) ) ; pmadapter -> upld_len = pkt_len ; wlan_decode_rx_packet ( pmadapter , mbuf_deaggr , pkt_type , MTRUE ) ; } } else { DBG_HEXDUMP ( MIF_D , " " , pmadapter -> mpa_rx . buf , MIN ( pmadapter -> mpa_rx . buf_len , MAX_DATA_DUMP_LEN ) ) ; curr_ptr = pmadapter -> mpa_rx . buf ; for ( pind = 0 ; pind < pmadapter -> mpa_rx . pkt_cnt ; pind ++ ) { pkt_len = wlan_le16_to_cpu ( * ( t_u16 * ) & curr_ptr [ 0 ] ) ; pkt_type = wlan_le16_to_cpu ( * ( t_u16 * ) & curr_ptr [ 2 ] ) ; PRINTM ( MINFO , " \n " , pind , pkt_len , pkt_type ) ; mbuf_deaggr = pmadapter -> mpa_rx . mbuf_arr [ pind ] ; if ( ( pkt_type == MLAN_TYPE_DATA || pkt_type == MLAN_TYPE_SPA_DATA ) && ( pkt_len <= pmadapter -> mpa_rx . len_arr [ pind ] ) ) { memcpy ( pmadapter , mbuf_deaggr -> pbuf + mbuf_deaggr -> data_offset , curr_ptr , pkt_len ) ; pmadapter -> upld_len = pkt_len ; wlan_decode_rx_packet ( pmadapter , mbuf_deaggr , pkt_type , MTRUE ) ; } else { PRINTM ( MERROR , " \n " , pkt_type , pkt_len , pmadapter -> mpa_rx . len_arr [ pind ] ) ; wlan_free_mlan_buffer ( pmadapter , mbuf_deaggr ) ; } curr_ptr += pmadapter -> mpa_rx . len_arr [ pind ] ; } } pmadapter -> mpa_rx_count [ pmadapter -> mpa_rx . pkt_cnt - 1 ] ++ ; MP_RX_AGGR_BUF_RESET ( pmadapter ) ; done : return ret ; }
@brief This function receives data from the card in aggregate mode.
@brief This function receives data from the card in aggregate mode .
/* do aggr RX now */ /* port_count = pmadapter->mpa_rx.pkt_cnt - 1; */ /* get curr PKT len & type */ /* copy pkt to deaggr buf */ /* Process de-aggr packet */