software/drivers/sd8887/src/wlan/mlan/mlan_sdio.c
/**
 *  @brief This function sends data to the card in SDIO aggregated mode.
 *
 *  @param pmadapter A pointer to mlan_adapter structure
 *  @param mbuf      A pointer to the SDIO data/cmd buffer
 *  @param port	     current port for aggregation
 *  @param next_pkt_len Length of next packet used for multiport aggregation
 *  @return         MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
@brief This function sends data to the card in SDIO aggregated mode.
@brief This function sends data to the card in SDIO aggregated mode .
static mlan_status
wlan_host_to_card_mp_aggr(mlan_adapter *pmadapter, mlan_buffer *mbuf, t_u8 port,
			  t_u32 next_pkt_len)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	t_s32 f_send_aggr_buf = 0;
	t_s32 f_send_cur_buf = 0;
	t_s32 f_precopy_cur_buf = 0;
	t_s32 f_postcopy_cur_buf = 0;
	t_u8 aggr_sg = 0;
	t_u8 mp_aggr_pkt_limit = SDIO_MP_AGGR_DEF_PKT_LIMIT;
	ENTER();
	PRINTM(MIF_D, "host_2_card_mp_aggr: next_pkt_len: %d curr_port:%d\n",
	       next_pkt_len, port);
	if (!pmadapter->mpa_tx.enabled) {
		PRINTM(MINFO,
		       "host_2_card_mp_aggr: tx aggregation disabled !\n");
		f_send_cur_buf = 1;
		goto tx_curr_single;
	}
	if (next_pkt_len) {
		PRINTM(MINFO, "host_2_card_mp_aggr: More packets in Queue.\n");
		if (MP_TX_AGGR_IN_PROGRESS(pmadapter)) {
			if (MP_TX_AGGR_BUF_HAS_ROOM
			    (pmadapter, mbuf, mbuf->data_len)) {
				f_precopy_cur_buf = 1;
				if (!
				    (pmadapter->
				     mp_wr_bitmap & (1 << pmadapter->
						     curr_wr_port)) ||
				    !MP_TX_AGGR_BUF_HAS_ROOM(pmadapter, mbuf,
							     mbuf->data_len +
							     next_pkt_len)) {
					f_send_aggr_buf = 1;
				}
			} else {
				f_send_aggr_buf = 1;
				if (!
				    (pmadapter->
				     mp_wr_bitmap & (1 << pmadapter->
						     curr_wr_port))) {
					f_send_cur_buf = 1;
				} else {
					f_postcopy_cur_buf = 1;
				}
			}
		} else {
			if (MP_TX_AGGR_BUF_HAS_ROOM
			    (pmadapter, mbuf, mbuf->data_len) &&
			    (pmadapter->
			     mp_wr_bitmap & (1 << pmadapter->curr_wr_port)))
				f_precopy_cur_buf = 1;
			else
				f_send_cur_buf = 1;
		}
	} else {
		PRINTM(MINFO,
		       "host_2_card_mp_aggr: Last packet in Tx Queue.\n");
		if (MP_TX_AGGR_IN_PROGRESS(pmadapter)) {
			f_send_aggr_buf = 1;
			if (MP_TX_AGGR_BUF_HAS_ROOM
			    (pmadapter, mbuf, mbuf->data_len)) {
				f_precopy_cur_buf = 1;
			} else {
				f_send_cur_buf = 1;
			}
		} else {
			f_send_cur_buf = 1;
		}
		pmadapter->mpa_sent_last_pkt++;
	}
	if (f_precopy_cur_buf) {
		PRINTM(MINFO, "host_2_card_mp_aggr: Precopy current buffer\n");
		if (pmadapter->mpa_buf)
			memcpy(pmadapter, pmadapter->mpa_buf +
			       (pmadapter->last_mp_index * mp_aggr_pkt_limit +
				pmadapter->mpa_tx.pkt_cnt) *
			       MLAN_SDIO_BLOCK_SIZE,
			       mbuf->pbuf + mbuf->data_offset,
			       MLAN_SDIO_BLOCK_SIZE);
		if (!pmadapter->mpa_tx.buf) {
			MP_TX_AGGR_BUF_PUT_SG(pmadapter, mbuf, port);
			aggr_sg = MTRUE;
		} else {
			MP_TX_AGGR_BUF_PUT(pmadapter, mbuf, port);
		}
		if (MP_TX_AGGR_PKT_LIMIT_REACHED(pmadapter) ||
		    MP_TX_AGGR_PORT_LIMIT_REACHED(pmadapter)
			) {
			PRINTM(MIF_D,
			       "host_2_card_mp_aggr: Aggregation Pkt limit reached\n");
			f_send_aggr_buf = 1;
		}
	}
	if (f_send_aggr_buf)
		ret = wlan_send_mp_aggr_buf(pmadapter);
tx_curr_single:
	if (f_send_cur_buf) {
		PRINTM(MINFO, "host_2_card_mp_aggr: writing to port #%d\n",
		       port);
		ret = wlan_write_data_sync(pmadapter, mbuf,
					   pmadapter->ioport + port);
		if (!(pmadapter->mp_wr_bitmap & (1 << pmadapter->curr_wr_port)))
			pmadapter->mpa_sent_no_ports++;
		pmadapter->last_mp_wr_bitmap[pmadapter->last_mp_index] =
			pmadapter->mp_wr_bitmap;
		pmadapter->last_mp_wr_ports[pmadapter->last_mp_index] =
			pmadapter->ioport + port;
		pmadapter->last_mp_wr_len[pmadapter->last_mp_index] =
			mbuf->data_len;
		memset(pmadapter,
		       (t_u8 *)&pmadapter->last_mp_wr_info[pmadapter->
							   last_mp_index *
							   mp_aggr_pkt_limit],
		       0, sizeof(t_u16) * mp_aggr_pkt_limit);
		pmadapter->last_mp_wr_info[pmadapter->last_mp_index *
					   mp_aggr_pkt_limit] =
			*(t_u16 *)(mbuf->pbuf + mbuf->data_offset);
		pmadapter->last_curr_wr_port[pmadapter->last_mp_index] =
			pmadapter->curr_wr_port;
		if (pmadapter->mpa_buf)
			memcpy(pmadapter,
			       pmadapter->mpa_buf +
			       (pmadapter->last_mp_index * mp_aggr_pkt_limit *
				MLAN_SDIO_BLOCK_SIZE),
			       mbuf->pbuf + mbuf->data_offset,
			       MLAN_SDIO_BLOCK_SIZE);
		pmadapter->last_mp_index++;
		if (pmadapter->last_mp_index >= SDIO_MP_DBG_NUM)
			pmadapter->last_mp_index = 0;
		pmadapter->mpa_tx_count[0]++;
	}
	if (f_postcopy_cur_buf) {
		PRINTM(MINFO, "host_2_card_mp_aggr: Postcopy current buffer\n");
		if (pmadapter->mpa_buf)
			memcpy(pmadapter, pmadapter->mpa_buf +
			       (pmadapter->last_mp_index * mp_aggr_pkt_limit +
				pmadapter->mpa_tx.pkt_cnt) *
			       MLAN_SDIO_BLOCK_SIZE,
			       mbuf->pbuf + mbuf->data_offset,
			       MLAN_SDIO_BLOCK_SIZE);
		if (!pmadapter->mpa_tx.buf) {
			MP_TX_AGGR_BUF_PUT_SG(pmadapter, mbuf, port);
			aggr_sg = MTRUE;
		} else {
			MP_TX_AGGR_BUF_PUT(pmadapter, mbuf, port);
		}
	}
	if (aggr_sg)
		ret = MLAN_STATUS_PENDING;
	LEAVE();
	return ret;
}
static mlan_status wlan_host_to_card_mp_aggr ( mlan_adapter * pmadapter , mlan_buffer * mbuf , t_u8 port , t_u32 next_pkt_len ) { mlan_status ret = MLAN_STATUS_SUCCESS ; t_s32 f_send_aggr_buf = 0 ; t_s32 f_send_cur_buf = 0 ; t_s32 f_precopy_cur_buf = 0 ; t_s32 f_postcopy_cur_buf = 0 ; t_u8 aggr_sg = 0 ; t_u8 mp_aggr_pkt_limit = SDIO_MP_AGGR_DEF_PKT_LIMIT ; ENTER ( ) ; PRINTM ( MIF_D , " \n " , next_pkt_len , port ) ; if ( ! pmadapter -> mpa_tx . enabled ) { PRINTM ( MINFO , " \n " ) ; f_send_cur_buf = 1 ; goto tx_curr_single ; } if ( next_pkt_len ) { PRINTM ( MINFO , " \n " ) ; if ( MP_TX_AGGR_IN_PROGRESS ( pmadapter ) ) { if ( MP_TX_AGGR_BUF_HAS_ROOM ( pmadapter , mbuf , mbuf -> data_len ) ) { f_precopy_cur_buf = 1 ; if ( ! ( pmadapter -> mp_wr_bitmap & ( 1 << pmadapter -> curr_wr_port ) ) || ! MP_TX_AGGR_BUF_HAS_ROOM ( pmadapter , mbuf , mbuf -> data_len + next_pkt_len ) ) { f_send_aggr_buf = 1 ; } } else { f_send_aggr_buf = 1 ; if ( ! ( pmadapter -> mp_wr_bitmap & ( 1 << pmadapter -> curr_wr_port ) ) ) { f_send_cur_buf = 1 ; } else { f_postcopy_cur_buf = 1 ; } } } else { if ( MP_TX_AGGR_BUF_HAS_ROOM ( pmadapter , mbuf , mbuf -> data_len ) && ( pmadapter -> mp_wr_bitmap & ( 1 << pmadapter -> curr_wr_port ) ) ) f_precopy_cur_buf = 1 ; else f_send_cur_buf = 1 ; } } else { PRINTM ( MINFO , " \n " ) ; if ( MP_TX_AGGR_IN_PROGRESS ( pmadapter ) ) { f_send_aggr_buf = 1 ; if ( MP_TX_AGGR_BUF_HAS_ROOM ( pmadapter , mbuf , mbuf -> data_len ) ) { f_precopy_cur_buf = 1 ; } else { f_send_cur_buf = 1 ; } } else { f_send_cur_buf = 1 ; } pmadapter -> mpa_sent_last_pkt ++ ; } if ( f_precopy_cur_buf ) { PRINTM ( MINFO , " \n " ) ; if ( pmadapter -> mpa_buf ) memcpy ( pmadapter , pmadapter -> mpa_buf + ( pmadapter -> last_mp_index * mp_aggr_pkt_limit + pmadapter -> mpa_tx . pkt_cnt ) * MLAN_SDIO_BLOCK_SIZE , mbuf -> pbuf + mbuf -> data_offset , MLAN_SDIO_BLOCK_SIZE ) ; if ( ! pmadapter -> mpa_tx . buf ) { MP_TX_AGGR_BUF_PUT_SG ( pmadapter , mbuf , port ) ; aggr_sg = MTRUE ; } else { MP_TX_AGGR_BUF_PUT ( pmadapter , mbuf , port ) ; } if ( MP_TX_AGGR_PKT_LIMIT_REACHED ( pmadapter ) || MP_TX_AGGR_PORT_LIMIT_REACHED ( pmadapter ) ) { PRINTM ( MIF_D , " \n " ) ; f_send_aggr_buf = 1 ; } } if ( f_send_aggr_buf ) ret = wlan_send_mp_aggr_buf ( pmadapter ) ; tx_curr_single : if ( f_send_cur_buf ) { PRINTM ( MINFO , " \n " , port ) ; ret = wlan_write_data_sync ( pmadapter , mbuf , pmadapter -> ioport + port ) ; if ( ! ( pmadapter -> mp_wr_bitmap & ( 1 << pmadapter -> curr_wr_port ) ) ) pmadapter -> mpa_sent_no_ports ++ ; pmadapter -> last_mp_wr_bitmap [ pmadapter -> last_mp_index ] = pmadapter -> mp_wr_bitmap ; pmadapter -> last_mp_wr_ports [ pmadapter -> last_mp_index ] = pmadapter -> ioport + port ; pmadapter -> last_mp_wr_len [ pmadapter -> last_mp_index ] = mbuf -> data_len ; memset ( pmadapter , ( t_u8 * ) & pmadapter -> last_mp_wr_info [ pmadapter -> last_mp_index * mp_aggr_pkt_limit ] , 0 , sizeof ( t_u16 ) * mp_aggr_pkt_limit ) ; pmadapter -> last_mp_wr_info [ pmadapter -> last_mp_index * mp_aggr_pkt_limit ] = * ( t_u16 * ) ( mbuf -> pbuf + mbuf -> data_offset ) ; pmadapter -> last_curr_wr_port [ pmadapter -> last_mp_index ] = pmadapter -> curr_wr_port ; if ( pmadapter -> mpa_buf ) memcpy ( pmadapter , pmadapter -> mpa_buf + ( pmadapter -> last_mp_index * mp_aggr_pkt_limit * MLAN_SDIO_BLOCK_SIZE ) , mbuf -> pbuf + mbuf -> data_offset , MLAN_SDIO_BLOCK_SIZE ) ; pmadapter -> last_mp_index ++ ; if ( pmadapter -> last_mp_index >= SDIO_MP_DBG_NUM ) pmadapter -> last_mp_index = 0 ; pmadapter -> mpa_tx_count [ 0 ] ++ ; } if ( f_postcopy_cur_buf ) { PRINTM ( MINFO , " \n " ) ; if ( pmadapter -> mpa_buf ) memcpy ( pmadapter , pmadapter -> mpa_buf + ( pmadapter -> last_mp_index * mp_aggr_pkt_limit + pmadapter -> mpa_tx . pkt_cnt ) * MLAN_SDIO_BLOCK_SIZE , mbuf -> pbuf + mbuf -> data_offset , MLAN_SDIO_BLOCK_SIZE ) ; if ( ! pmadapter -> mpa_tx . buf ) { MP_TX_AGGR_BUF_PUT_SG ( pmadapter , mbuf , port ) ; aggr_sg = MTRUE ; } else { MP_TX_AGGR_BUF_PUT ( pmadapter , mbuf , port ) ; } } if ( aggr_sg ) ret = MLAN_STATUS_PENDING ; LEAVE ( ) ; return ret ; }
@brief This function sends data to the card in SDIO aggregated mode.
@brief This function sends data to the card in SDIO aggregated mode .
/* More pkt in TX queue */ /* No room in Aggr buf, send it */ /* Last pkt in TX queue */ /* some packs in Aggr buf already */ /* No room in Aggr buf, send it */ /* No more pkts allowed in Aggr buf, send it */ /* Always return PENDING in SG mode */