static void mwifiex_cleanup_mpa_buf(struct mwifiex_adapter *adapter) { struct sdio_mmc_card *card = adapter->card; MP_TX_AGGR_BUF_RESET(card); MP_RX_AGGR_BUF_RESET(card); }
static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, u8 *payload, u32 pkt_len, u8 port, u32 next_pkt_len) { struct sdio_mmc_card *card = adapter->card; int ret = 0; s32 f_send_aggr_buf = 0; s32 f_send_cur_buf = 0; s32 f_precopy_cur_buf = 0; s32 f_postcopy_cur_buf = 0; if ((!card->mpa_tx.enabled) || (port == CTRL_PORT)) { dev_dbg(adapter->dev, "info: %s: tx aggregation disabled\n", __func__); f_send_cur_buf = 1; goto tx_curr_single; } if (next_pkt_len) { dev_dbg(adapter->dev, "info: %s: more packets in queue.\n", __func__); if (MP_TX_AGGR_IN_PROGRESS(card)) { if (!MP_TX_AGGR_PORT_LIMIT_REACHED(card) && MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len)) { f_precopy_cur_buf = 1; if (!(card->mp_wr_bitmap & (1 << card->curr_wr_port)) || !MP_TX_AGGR_BUF_HAS_ROOM( card, pkt_len + next_pkt_len)) f_send_aggr_buf = 1; } else { f_send_aggr_buf = 1; if (MP_TX_AGGR_PORT_LIMIT_REACHED(card) || !(card->mp_wr_bitmap & (1 << card->curr_wr_port))) f_send_cur_buf = 1; else f_postcopy_cur_buf = 1; } } else { if (MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len) && (card->mp_wr_bitmap & (1 << card->curr_wr_port))) f_precopy_cur_buf = 1; else f_send_cur_buf = 1; } } else { dev_dbg(adapter->dev, "info: %s: Last packet in Tx Queue.\n", __func__); if (MP_TX_AGGR_IN_PROGRESS(card)) { f_send_aggr_buf = 1; if (MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len)) f_precopy_cur_buf = 1; else f_send_cur_buf = 1; } else { f_send_cur_buf = 1; } } if (f_precopy_cur_buf) { dev_dbg(adapter->dev, "data: %s: precopy current buffer\n", __func__); MP_TX_AGGR_BUF_PUT(card, payload, pkt_len, port); if (MP_TX_AGGR_PKT_LIMIT_REACHED(card) || MP_TX_AGGR_PORT_LIMIT_REACHED(card)) f_send_aggr_buf = 1; } if (f_send_aggr_buf) { dev_dbg(adapter->dev, "data: %s: send aggr buffer: %d %d\n", __func__, card->mpa_tx.start_port, card->mpa_tx.ports); ret = mwifiex_write_data_to_card(adapter, card->mpa_tx.buf, card->mpa_tx.buf_len, (adapter->ioport | 0x1000 | (card->mpa_tx.ports << 4)) + card->mpa_tx.start_port); MP_TX_AGGR_BUF_RESET(card); } tx_curr_single: if (f_send_cur_buf) { dev_dbg(adapter->dev, "data: %s: send current buffer %d\n", __func__, port); ret = mwifiex_write_data_to_card(adapter, payload, pkt_len, adapter->ioport + port); } if (f_postcopy_cur_buf) { dev_dbg(adapter->dev, "data: %s: postcopy current buffer\n", __func__); MP_TX_AGGR_BUF_PUT(card, payload, pkt_len, port); } return ret; }
/** * @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 */ 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_u32 cmd53_port = 0; mlan_buffer mbuf_aggr; 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) { /* More pkt in TX queue */ PRINTM(MINFO, "host_2_card_mp_aggr: More packets in Queue.\n"); if (MP_TX_AGGR_IN_PROGRESS(pmadapter)) { if (!MP_TX_AGGR_PORT_LIMIT_REACHED(pmadapter) && 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 { /* No room in Aggr buf, send it */ f_send_aggr_buf = 1; if (MP_TX_AGGR_PORT_LIMIT_REACHED(pmadapter) || !(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 { /* Last pkt in TX queue */ PRINTM(MINFO, "host_2_card_mp_aggr: Last packet in Tx Queue.\n"); if (MP_TX_AGGR_IN_PROGRESS(pmadapter)) { /* some packs in Aggr buf already */ f_send_aggr_buf = 1; if (MP_TX_AGGR_BUF_HAS_ROOM (pmadapter, mbuf, mbuf->data_len)) { f_precopy_cur_buf = 1; } else { /* No room in Aggr buf, send it */ f_send_cur_buf = 1; } } else { f_send_cur_buf = 1; } } if (f_precopy_cur_buf) { PRINTM(MINFO, "host_2_card_mp_aggr: Precopy current buffer\n"); 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"); /* No more pkts allowed in Aggr buf, send it */ f_send_aggr_buf = 1; } } if (f_send_aggr_buf) { PRINTM(MINFO, "host_2_card_mp_aggr: Send aggregation buffer." "%d %d\n", pmadapter->mpa_tx.start_port, pmadapter->mpa_tx.ports); memset(pmadapter, &mbuf_aggr, 0, sizeof(mlan_buffer)); mbuf_aggr.pbuf = (t_u8 *) pmadapter->mpa_tx.buf; mbuf_aggr.data_len = pmadapter->mpa_tx.buf_len; cmd53_port = (pmadapter->ioport | SDIO_MPA_ADDR_BASE | (pmadapter->mpa_tx.ports << 4)) + pmadapter->mpa_tx.start_port; ret = wlan_write_data_sync(pmadapter, &mbuf_aggr, cmd53_port); MP_TX_AGGR_BUF_RESET(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 (f_postcopy_cur_buf) { PRINTM(MINFO, "host_2_card_mp_aggr: Postcopy current buffer\n"); MP_TX_AGGR_BUF_PUT(pmadapter, mbuf, port); } LEAVE(); return ret; }