diff options
Diffstat (limited to 'drivers/net/wireless/sd8797/mlan/mlan_sta_tx.c')
-rw-r--r-- | drivers/net/wireless/sd8797/mlan/mlan_sta_tx.c | 411 |
1 files changed, 210 insertions, 201 deletions
diff --git a/drivers/net/wireless/sd8797/mlan/mlan_sta_tx.c b/drivers/net/wireless/sd8797/mlan/mlan_sta_tx.c index 6191e4edeefc..64ecddc949e3 100644 --- a/drivers/net/wireless/sd8797/mlan/mlan_sta_tx.c +++ b/drivers/net/wireless/sd8797/mlan/mlan_sta_tx.c @@ -2,8 +2,8 @@ * * @brief This file contains the handling of data packet * transmission in MLAN module. - * - * Copyright (C) 2008-2011, Marvell International Ltd. + * + * Copyright (C) 2008-2011, Marvell International Ltd. * * This software file (the "File") is distributed by Marvell International * Ltd. under the terms of the GNU General Public License Version 2, June 1991 @@ -47,9 +47,9 @@ Change log: /******************************************************** Global functions ********************************************************/ -/** - * @brief This function fill the txpd for tx packet - * +/** + * @brief This function fill the txpd for tx packet + * * @param priv A pointer to mlan_private structure * @param pmbuf A pointer to the mlan_buffer for process * @@ -58,98 +58,105 @@ Change log: t_void * wlan_ops_sta_process_txpd(IN t_void * priv, IN pmlan_buffer pmbuf) { - mlan_private *pmpriv = (mlan_private *) priv; - pmlan_adapter pmadapter = pmpriv->adapter; - TxPD *plocal_tx_pd; - t_u8 *head_ptr = MNULL; - t_u32 pkt_type; - t_u32 tx_control; - - ENTER(); - - if (!pmbuf->data_len) { - PRINTM(MERROR, "STA Tx Error: Invalid packet length: %d\n", - pmbuf->data_len); - pmbuf->status_code = MLAN_ERROR_PKT_SIZE_INVALID; - goto done; - } - if (pmbuf->buf_type == MLAN_BUF_TYPE_RAW_DATA) { - memcpy(pmpriv->adapter, &pkt_type, pmbuf->pbuf + pmbuf->data_offset, - sizeof(pkt_type)); - memcpy(pmpriv->adapter, &tx_control, - pmbuf->pbuf + pmbuf->data_offset + sizeof(pkt_type), - sizeof(tx_control)); - pmbuf->data_offset += sizeof(pkt_type) + sizeof(tx_control); - pmbuf->data_len -= sizeof(pkt_type) + sizeof(tx_control); - } - - if (pmbuf->data_offset < (sizeof(TxPD) + INTF_HEADER_LEN + DMA_ALIGNMENT)) { - PRINTM(MERROR, "not enough space for TxPD: %d\n", pmbuf->data_len); - pmbuf->status_code = MLAN_ERROR_PKT_SIZE_INVALID; - goto done; - } - - /* head_ptr should be aligned */ - head_ptr = - pmbuf->pbuf + pmbuf->data_offset - sizeof(TxPD) - INTF_HEADER_LEN; - head_ptr = (t_u8 *) ((t_ptr) head_ptr & ~((t_ptr) (DMA_ALIGNMENT - 1))); - - plocal_tx_pd = (TxPD *) (head_ptr + INTF_HEADER_LEN); - memset(pmadapter, plocal_tx_pd, 0, sizeof(TxPD)); - /* Set the BSS number to TxPD */ - plocal_tx_pd->bss_num = GET_BSS_NUM(pmpriv); - plocal_tx_pd->bss_type = pmpriv->bss_type; - - plocal_tx_pd->tx_pkt_length = (t_u16) pmbuf->data_len; - - plocal_tx_pd->priority = (t_u8) pmbuf->priority; - plocal_tx_pd->pkt_delay_2ms = - wlan_wmm_compute_driver_packet_delay(pmpriv, pmbuf); - - if (plocal_tx_pd->priority < NELEMENTS(pmpriv->wmm.user_pri_pkt_tx_ctrl)) - /* - * Set the priority specific tx_control field, setting of 0 will - * cause the default value to be used later in this function - */ - plocal_tx_pd->tx_control - = pmpriv->wmm.user_pri_pkt_tx_ctrl[plocal_tx_pd->priority]; - if (pmadapter->pps_uapsd_mode) { - if (MTRUE == wlan_check_last_packet_indication(pmpriv)) { - pmadapter->tx_lock_flag = MTRUE; - plocal_tx_pd->flags = MRVDRV_TxPD_POWER_MGMT_LAST_PACKET; - } - } - - /* Offset of actual data */ - plocal_tx_pd->tx_pkt_offset = - (t_u16) ((t_ptr) pmbuf->pbuf + pmbuf->data_offset - - (t_ptr) plocal_tx_pd); - - if (!plocal_tx_pd->tx_control) { - /* TxCtrl set by user or default */ - plocal_tx_pd->tx_control = pmpriv->pkt_tx_ctrl; - } - - if (pmbuf->buf_type == MLAN_BUF_TYPE_RAW_DATA) { - plocal_tx_pd->tx_pkt_type = (t_u16) pkt_type; - plocal_tx_pd->tx_control = tx_control; - } - - endian_convert_TxPD(plocal_tx_pd); - - /* Adjust the data offset and length to include TxPD in pmbuf */ - pmbuf->data_len += pmbuf->data_offset; - pmbuf->data_offset = (t_u32) (head_ptr - pmbuf->pbuf); - pmbuf->data_len -= pmbuf->data_offset; - - done: - LEAVE(); - return head_ptr; + mlan_private *pmpriv = (mlan_private *) priv; + pmlan_adapter pmadapter = pmpriv->adapter; + TxPD *plocal_tx_pd; + t_u8 *head_ptr = MNULL; + t_u32 pkt_type; + t_u32 tx_control; + + ENTER(); + + if (!pmbuf->data_len) { + PRINTM(MERROR, "STA Tx Error: Invalid packet length: %d\n", + pmbuf->data_len); + pmbuf->status_code = MLAN_ERROR_PKT_SIZE_INVALID; + goto done; + } + if (pmbuf->buf_type == MLAN_BUF_TYPE_RAW_DATA) { + memcpy(pmpriv->adapter, &pkt_type, + pmbuf->pbuf + pmbuf->data_offset, sizeof(pkt_type)); + memcpy(pmpriv->adapter, &tx_control, + pmbuf->pbuf + pmbuf->data_offset + sizeof(pkt_type), + sizeof(tx_control)); + pmbuf->data_offset += sizeof(pkt_type) + sizeof(tx_control); + pmbuf->data_len -= sizeof(pkt_type) + sizeof(tx_control); + } + + if (pmbuf->data_offset < (sizeof(TxPD) + INTF_HEADER_LEN + + DMA_ALIGNMENT)) { + PRINTM(MERROR, "not enough space for TxPD: %d\n", + pmbuf->data_len); + pmbuf->status_code = MLAN_ERROR_PKT_SIZE_INVALID; + goto done; + } + + /* head_ptr should be aligned */ + head_ptr = + pmbuf->pbuf + pmbuf->data_offset - sizeof(TxPD) - + INTF_HEADER_LEN; + head_ptr = (t_u8 *) ((t_ptr) head_ptr & ~((t_ptr) (DMA_ALIGNMENT - 1))); + + plocal_tx_pd = (TxPD *) (head_ptr + INTF_HEADER_LEN); + memset(pmadapter, plocal_tx_pd, 0, sizeof(TxPD)); + /* Set the BSS number to TxPD */ + plocal_tx_pd->bss_num = GET_BSS_NUM(pmpriv); + plocal_tx_pd->bss_type = pmpriv->bss_type; + + plocal_tx_pd->tx_pkt_length = (t_u16) pmbuf->data_len; + + plocal_tx_pd->priority = (t_u8) pmbuf->priority; + plocal_tx_pd->pkt_delay_2ms = + wlan_wmm_compute_driver_packet_delay(pmpriv, pmbuf); + + if (plocal_tx_pd->priority < + NELEMENTS(pmpriv->wmm.user_pri_pkt_tx_ctrl)) + /* + * Set the priority specific tx_control field, setting of 0 will + * cause the default value to be used later in this function + */ + plocal_tx_pd->tx_control + = + pmpriv->wmm.user_pri_pkt_tx_ctrl[plocal_tx_pd-> + priority]; + if (pmadapter->pps_uapsd_mode) { + if (MTRUE == wlan_check_last_packet_indication(pmpriv)) { + pmadapter->tx_lock_flag = MTRUE; + plocal_tx_pd->flags = + MRVDRV_TxPD_POWER_MGMT_LAST_PACKET; + } + } + + /* Offset of actual data */ + plocal_tx_pd->tx_pkt_offset = + (t_u16) ((t_ptr) pmbuf->pbuf + pmbuf->data_offset - + (t_ptr) plocal_tx_pd); + + if (!plocal_tx_pd->tx_control) { + /* TxCtrl set by user or default */ + plocal_tx_pd->tx_control = pmpriv->pkt_tx_ctrl; + } + + if (pmbuf->buf_type == MLAN_BUF_TYPE_RAW_DATA) { + plocal_tx_pd->tx_pkt_type = (t_u16) pkt_type; + plocal_tx_pd->tx_control = tx_control; + } + + endian_convert_TxPD(plocal_tx_pd); + + /* Adjust the data offset and length to include TxPD in pmbuf */ + pmbuf->data_len += pmbuf->data_offset; + pmbuf->data_offset = (t_u32) (head_ptr - pmbuf->pbuf); + pmbuf->data_len -= pmbuf->data_offset; + +done: + LEAVE(); + return head_ptr; } -/** +/** * @brief This function tells firmware to send a NULL data packet. - * + * * @param priv A pointer to mlan_private structure * @param flags Transmit Pkt Flags * @@ -158,95 +165,96 @@ wlan_ops_sta_process_txpd(IN t_void * priv, IN pmlan_buffer pmbuf) mlan_status wlan_send_null_packet(pmlan_private priv, t_u8 flags) { - pmlan_adapter pmadapter = priv->adapter; - TxPD *ptx_pd; + pmlan_adapter pmadapter = priv->adapter; + TxPD *ptx_pd; /* sizeof(TxPD) + Interface specific header */ #define NULL_PACKET_HDR 256 - t_u32 data_len = NULL_PACKET_HDR; - pmlan_buffer pmbuf = MNULL; - t_u8 *ptr; - mlan_status ret = MLAN_STATUS_SUCCESS; + t_u32 data_len = NULL_PACKET_HDR; + pmlan_buffer pmbuf = MNULL; + t_u8 *ptr; + mlan_status ret = MLAN_STATUS_SUCCESS; #ifdef DEBUG_LEVEL1 - t_u32 sec, usec; + t_u32 sec, usec; #endif - ENTER(); - - if (pmadapter->surprise_removed == MTRUE) { - ret = MLAN_STATUS_FAILURE; - goto done; - } - - if (priv->media_connected == MFALSE) { - ret = MLAN_STATUS_FAILURE; - goto done; - } - - if (pmadapter->data_sent == MTRUE) { - ret = MLAN_STATUS_FAILURE; - goto done; - } - - pmbuf = wlan_alloc_mlan_buffer(pmadapter, data_len, 0, MOAL_MALLOC_BUFFER); - if (!pmbuf) { - ret = MLAN_STATUS_FAILURE; - goto done; - } - memset(pmadapter, pmbuf->pbuf, 0, data_len); - pmbuf->bss_index = priv->bss_index; - pmbuf->buf_type = MLAN_BUF_TYPE_DATA; - ptr = pmbuf->pbuf + pmbuf->data_offset; - pmbuf->data_len = sizeof(TxPD) + INTF_HEADER_LEN; - ptx_pd = (TxPD *) (ptr + INTF_HEADER_LEN); - ptx_pd->tx_control = priv->pkt_tx_ctrl; - ptx_pd->flags = flags; - ptx_pd->priority = WMM_HIGHEST_PRIORITY; - ptx_pd->tx_pkt_offset = sizeof(TxPD); - /* Set the BSS number to TxPD */ - ptx_pd->bss_num = GET_BSS_NUM(priv); - ptx_pd->bss_type = priv->bss_type; - - endian_convert_TxPD(ptx_pd); - - ret = wlan_sdio_host_to_card(pmadapter, MLAN_TYPE_DATA, pmbuf, MNULL); - - switch (ret) { - case MLAN_STATUS_RESOURCE: - wlan_free_mlan_buffer(pmadapter, pmbuf); - PRINTM(MERROR, "STA Tx Error: Failed to send NULL packet!\n"); - pmadapter->dbg.num_tx_host_to_card_failure++; - goto done; - case MLAN_STATUS_FAILURE: - pmadapter->data_sent = MFALSE; - wlan_free_mlan_buffer(pmadapter, pmbuf); - PRINTM(MERROR, "STA Tx Error: Failed to send NULL packet!\n"); - pmadapter->dbg.num_tx_host_to_card_failure++; - goto done; - case MLAN_STATUS_SUCCESS: - wlan_free_mlan_buffer(pmadapter, pmbuf); - PRINTM(MINFO, "STA Tx: Successfully send the NULL packet\n"); - pmadapter->tx_lock_flag = MTRUE; - break; - case MLAN_STATUS_PENDING: - pmadapter->data_sent = MFALSE; - pmadapter->tx_lock_flag = MTRUE; - break; - default: - break; - } - - PRINTM_GET_SYS_TIME(MDATA, &sec, &usec); - PRINTM_NETINTF(MDATA, priv); - PRINTM(MDATA, "%lu.%06lu : Null data => FW\n", sec, usec); - DBG_HEXDUMP(MDAT_D, "Null data", ptr, sizeof(TxPD) + INTF_HEADER_LEN); - done: - LEAVE(); - return ret; + ENTER(); + + if (pmadapter->surprise_removed == MTRUE) { + ret = MLAN_STATUS_FAILURE; + goto done; + } + + if (priv->media_connected == MFALSE) { + ret = MLAN_STATUS_FAILURE; + goto done; + } + + if (pmadapter->data_sent == MTRUE) { + ret = MLAN_STATUS_FAILURE; + goto done; + } + + pmbuf = wlan_alloc_mlan_buffer(pmadapter, data_len, 0, + MOAL_MALLOC_BUFFER); + if (!pmbuf) { + ret = MLAN_STATUS_FAILURE; + goto done; + } + memset(pmadapter, pmbuf->pbuf, 0, data_len); + pmbuf->bss_index = priv->bss_index; + pmbuf->buf_type = MLAN_BUF_TYPE_DATA; + ptr = pmbuf->pbuf + pmbuf->data_offset; + pmbuf->data_len = sizeof(TxPD) + INTF_HEADER_LEN; + ptx_pd = (TxPD *) (ptr + INTF_HEADER_LEN); + ptx_pd->tx_control = priv->pkt_tx_ctrl; + ptx_pd->flags = flags; + ptx_pd->priority = WMM_HIGHEST_PRIORITY; + ptx_pd->tx_pkt_offset = sizeof(TxPD); + /* Set the BSS number to TxPD */ + ptx_pd->bss_num = GET_BSS_NUM(priv); + ptx_pd->bss_type = priv->bss_type; + + endian_convert_TxPD(ptx_pd); + + ret = wlan_sdio_host_to_card(pmadapter, MLAN_TYPE_DATA, pmbuf, MNULL); + + switch (ret) { + case MLAN_STATUS_RESOURCE: + wlan_free_mlan_buffer(pmadapter, pmbuf); + PRINTM(MERROR, "STA Tx Error: Failed to send NULL packet!\n"); + pmadapter->dbg.num_tx_host_to_card_failure++; + goto done; + case MLAN_STATUS_FAILURE: + pmadapter->data_sent = MFALSE; + wlan_free_mlan_buffer(pmadapter, pmbuf); + PRINTM(MERROR, "STA Tx Error: Failed to send NULL packet!\n"); + pmadapter->dbg.num_tx_host_to_card_failure++; + goto done; + case MLAN_STATUS_SUCCESS: + wlan_free_mlan_buffer(pmadapter, pmbuf); + PRINTM(MINFO, "STA Tx: Successfully send the NULL packet\n"); + pmadapter->tx_lock_flag = MTRUE; + break; + case MLAN_STATUS_PENDING: + pmadapter->data_sent = MFALSE; + pmadapter->tx_lock_flag = MTRUE; + break; + default: + break; + } + + PRINTM_GET_SYS_TIME(MDATA, &sec, &usec); + PRINTM_NETINTF(MDATA, priv); + PRINTM(MDATA, "%lu.%06lu : Null data => FW\n", sec, usec); + DBG_HEXDUMP(MDAT_D, "Null data", ptr, sizeof(TxPD) + INTF_HEADER_LEN); +done: + LEAVE(); + return ret; } -/** +/** * @brief This function checks if we need to send last packet indication. - * + * * @param priv A pointer to mlan_private structure * * @return MTRUE or MFALSE @@ -254,30 +262,31 @@ wlan_send_null_packet(pmlan_private priv, t_u8 flags) t_u8 wlan_check_last_packet_indication(pmlan_private priv) { - pmlan_adapter pmadapter = priv->adapter; - t_u8 ret = MFALSE; - t_u8 prop_ps = MTRUE; - - ENTER(); - - if (!pmadapter->sleep_period.period) { - LEAVE(); - return ret; - } - if (wlan_bypass_tx_list_empty(pmadapter) && wlan_wmm_lists_empty(pmadapter)) { - if (((priv->curr_bss_params.wmm_uapsd_enabled == MTRUE) && - priv->wmm_qosinfo) || prop_ps) - - ret = MTRUE; - } - if (ret && !pmadapter->cmd_sent && !pmadapter->curr_cmd - && !IS_COMMAND_PENDING(pmadapter)) { - pmadapter->delay_null_pkt = MFALSE; - ret = MTRUE; - } else { - ret = MFALSE; - pmadapter->delay_null_pkt = MTRUE; - } - LEAVE(); - return ret; + pmlan_adapter pmadapter = priv->adapter; + t_u8 ret = MFALSE; + t_u8 prop_ps = MTRUE; + + ENTER(); + + if (!pmadapter->sleep_period.period) { + LEAVE(); + return ret; + } + if (wlan_bypass_tx_list_empty(pmadapter) && + wlan_wmm_lists_empty(pmadapter)) { + if (((priv->curr_bss_params.wmm_uapsd_enabled == MTRUE) && + priv->wmm_qosinfo) || prop_ps) + + ret = MTRUE; + } + if (ret && !pmadapter->cmd_sent && !pmadapter->curr_cmd + && !IS_COMMAND_PENDING(pmadapter)) { + pmadapter->delay_null_pkt = MFALSE; + ret = MTRUE; + } else { + ret = MFALSE; + pmadapter->delay_null_pkt = MTRUE; + } + LEAVE(); + return ret; } |