1 // SPDX-License-Identifier: GPL-2.0 2 /****************************************************************************** 3 * 4 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. 5 * 6 ******************************************************************************/ 7 8 #include "odm_precomp.h" 9 10 static u32 edca_setting_DL_GMode[HT_IOT_PEER_MAX] = { 11 /*UNKNOWN, REALTEK_90, ALTEK_92SE BROADCOM, LINK ATHEROS, 12 *CISCO, MERU, MARVELL, 92U_AP, SELF_AP 13 */ 14 0x4322, 0xa44f, 0x5e4322, 0xa42b, 0x5e4322, 0x4322, 15 0xa42b, 0x5ea42b, 0xa44f, 0x5e4322, 0x5ea42b 16 }; 17 18 static u32 edca_setting_UL[HT_IOT_PEER_MAX] = { 19 /*UNKNOWN, REALTEK_90, REALTEK_92SE, BROADCOM, RALINK, ATHEROS, 20 *CISCO, MERU, MARVELL, 92U_AP, SELF_AP(DownLink/Tx) 21 */ 22 0x5e4322, 0xa44f, 0x5e4322, 0x5ea32b, 0x5ea422, 0x5ea322, 23 0x3ea430, 0x5ea42b, 0x5ea44f, 0x5e4322, 0x5e4322}; 24 25 static u32 edca_setting_DL[HT_IOT_PEER_MAX] = { 26 /*UNKNOWN, REALTEK_90, REALTEK_92SE, BROADCOM, RALINK, ATHEROS, 27 *CISCO, MERU, MARVELL, 92U_AP, SELF_AP(UpLink/Rx) 28 */ 29 0xa44f, 0x5ea44f, 0x5e4322, 0x5ea42b, 0xa44f, 0xa630, 30 0x5ea630, 0x5ea42b, 0xa44f, 0xa42b, 0xa42b}; 31 32 void ODM_EdcaTurboInit(void *pDM_VOID) 33 { 34 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 35 struct adapter *Adapter = pDM_Odm->Adapter; 36 37 pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = false; 38 pDM_Odm->DM_EDCA_Table.bIsCurRDLState = false; 39 Adapter->recvpriv.bIsAnyNonBEPkts = false; 40 } /* ODM_InitEdcaTurbo */ 41 42 void odm_EdcaTurboCheck(void *pDM_VOID) 43 { 44 /* In HW integration first stage, we provide 4 different handles to 45 * operate at the same time. In stage2/3, we need to prove universal 46 * interface and merge all HW dynamic mechanism. 47 */ 48 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 49 50 if (!(pDM_Odm->SupportAbility & ODM_MAC_EDCA_TURBO)) 51 return; 52 53 odm_EdcaTurboCheckCE(pDM_Odm); 54 } /* odm_CheckEdcaTurbo */ 55 56 void odm_EdcaTurboCheckCE(void *pDM_VOID) 57 { 58 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; 59 struct adapter *Adapter = pDM_Odm->Adapter; 60 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(Adapter); 61 struct recv_priv *precvpriv = &(Adapter->recvpriv); 62 struct registry_priv *pregpriv = &Adapter->registrypriv; 63 struct mlme_ext_priv *pmlmeext = &(Adapter->mlmeextpriv); 64 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 65 u32 EDCA_BE_UL = 0x5ea42b; 66 u32 EDCA_BE_DL = 0x5ea42b; 67 u32 iot_peer = 0; 68 u8 wirelessmode = 0xFF; /* invalid value */ 69 u32 trafficIndex; 70 u32 edca_param; 71 u64 cur_tx_bytes = 0; 72 u64 cur_rx_bytes = 0; 73 u8 bbtchange = false; 74 u8 biasonrx = false; 75 struct hal_com_data *pHalData = GET_HAL_DATA(Adapter); 76 77 if (!pDM_Odm->bLinked) { 78 precvpriv->bIsAnyNonBEPkts = false; 79 return; 80 } 81 82 if (pregpriv->wifi_spec == 1) { 83 precvpriv->bIsAnyNonBEPkts = false; 84 return; 85 } 86 87 if (pDM_Odm->pwirelessmode) 88 wirelessmode = *(pDM_Odm->pwirelessmode); 89 90 iot_peer = pmlmeinfo->assoc_AP_vendor; 91 92 if (iot_peer >= HT_IOT_PEER_MAX) { 93 precvpriv->bIsAnyNonBEPkts = false; 94 return; 95 } 96 97 /* Check if the status needs to be changed. */ 98 if ((bbtchange) || (!precvpriv->bIsAnyNonBEPkts)) { 99 cur_tx_bytes = pdvobjpriv->traffic_stat.cur_tx_bytes; 100 cur_rx_bytes = pdvobjpriv->traffic_stat.cur_rx_bytes; 101 102 /* traffic, TX or RX */ 103 if (biasonrx) { 104 if (cur_tx_bytes > (cur_rx_bytes << 2)) { 105 /* Uplink TP is present. */ 106 trafficIndex = UP_LINK; 107 } else { /* Balance TP is present. */ 108 trafficIndex = DOWN_LINK; 109 } 110 } else { 111 if (cur_rx_bytes > (cur_tx_bytes << 2)) { 112 /* Downlink TP is present. */ 113 trafficIndex = DOWN_LINK; 114 } else { /* Balance TP is present. */ 115 trafficIndex = UP_LINK; 116 } 117 } 118 119 /* 92D txop can't be set to 0x3e for cisco1250 */ 120 if ((iot_peer == HT_IOT_PEER_CISCO) && 121 (wirelessmode == ODM_WM_N24G)) { 122 EDCA_BE_DL = edca_setting_DL[iot_peer]; 123 EDCA_BE_UL = edca_setting_UL[iot_peer]; 124 } else if ((iot_peer == HT_IOT_PEER_CISCO) && 125 ((wirelessmode == ODM_WM_G) || 126 (wirelessmode == (ODM_WM_B | ODM_WM_G)) || 127 (wirelessmode == ODM_WM_B))) { 128 EDCA_BE_DL = edca_setting_DL_GMode[iot_peer]; 129 } else if ((iot_peer == HT_IOT_PEER_AIRGO) && 130 (wirelessmode == ODM_WM_G)) { 131 EDCA_BE_DL = 0xa630; 132 } else if (iot_peer == HT_IOT_PEER_MARVELL) { 133 EDCA_BE_DL = edca_setting_DL[iot_peer]; 134 EDCA_BE_UL = edca_setting_UL[iot_peer]; 135 } else if (iot_peer == HT_IOT_PEER_ATHEROS) { 136 /* Set DL EDCA for Atheros peer to 0x3ea42b. */ 137 EDCA_BE_DL = edca_setting_DL[iot_peer]; 138 } 139 140 if (trafficIndex == DOWN_LINK) 141 edca_param = EDCA_BE_DL; 142 else 143 edca_param = EDCA_BE_UL; 144 145 rtw_write32(Adapter, REG_EDCA_BE_PARAM, edca_param); 146 147 pDM_Odm->DM_EDCA_Table.prv_traffic_idx = trafficIndex; 148 149 pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = true; 150 } else { 151 /* Turn Off EDCA turbo here. */ 152 /* Restore original EDCA according to the declaration of AP. */ 153 if (pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA) { 154 rtw_write32(Adapter, REG_EDCA_BE_PARAM, pHalData->AcParam_BE); 155 pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = false; 156 } 157 } 158 } 159