/***************************************** * H2C Msg format : * 0x1DF - 0x1D0 *| 31 - 8 | 7-5 4 - 0 | *| h2c_msg |Class_ID CMD_ID | * * Extend 0x1FF - 0x1F0 *|31 - 0 | *|ext_msg| ******************************************/ static void _rtl8821au_fill_h2c_cmd(struct rtl_priv *rtlpriv, u8 element_id, u32 cmd_len, u8 *cmdbuffer) { struct rtl_hal *rtlhal = rtl_hal(rtlpriv); uint8_t bcmd_down = _FALSE; int32_t retry_cnts = 100; uint8_t h2c_box_num; uint32_t msgbox_addr; uint32_t msgbox_ex_addr; uint8_t cmd_idx, ext_cmd_len; uint32_t h2c_cmd = 0; uint32_t h2c_cmd_ex = 0; int _unused; _unused = mutex_lock_interruptible(&(rtl_usbdev(rtlpriv)->h2c_fwcmd_mutex)); if (!cmdbuffer) { goto exit; } if (cmd_len > RTL8812_MAX_CMD_LEN) { goto exit; } if (rtlpriv->bSurpriseRemoved == _TRUE) goto exit; /* pay attention to if race condition happened in H2C cmd setting. */ do { h2c_box_num = rtlhal->last_hmeboxnum; if (!_is_fw_read_cmd_down(rtlpriv, h2c_box_num)) { RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, " fw read cmd failed...\n"); goto exit; } *(uint8_t *)(&h2c_cmd) = element_id; if (cmd_len <= 3) { memcpy((uint8_t *)(&h2c_cmd)+1, cmdbuffer, cmd_len); } else { memcpy((uint8_t *)(&h2c_cmd)+1, cmdbuffer, 3); ext_cmd_len = cmd_len-3; memcpy((uint8_t *)(&h2c_cmd_ex), cmdbuffer+3, ext_cmd_len); /* Write Ext command */ msgbox_ex_addr = REG_HMEBOX_EXT0_8812 + (h2c_box_num * RTL8812_EX_MESSAGE_BOX_SIZE); #ifdef CONFIG_H2C_EF for (cmd_idx = 0; cmd_idx < ext_cmd_len; cmd_idx++) { rtl_write_byte(rtlpriv, msgbox_ex_addr+cmd_idx, *((uint8_t *)(&h2c_cmd_ex)+cmd_idx)); } #else h2c_cmd_ex = le32_to_cpu(h2c_cmd_ex); rtl_write_dword(rtlpriv, msgbox_ex_addr, h2c_cmd_ex); #endif } /* Write command */ msgbox_addr = REG_HMEBOX_0 + (h2c_box_num * RTL8812_MESSAGE_BOX_SIZE); #ifdef CONFIG_H2C_EF for (cmd_idx = 0; cmd_idx < RTL8812_MESSAGE_BOX_SIZE; cmd_idx++) { rtl_write_byte(rtlpriv, msgbox_addr+cmd_idx, *((uint8_t *)(&h2c_cmd)+cmd_idx)); } #else h2c_cmd = le32_to_cpu(h2c_cmd); rtl_write_dword(rtlpriv, msgbox_addr, h2c_cmd); #endif bcmd_down = _TRUE; /* * DBG_8192C("MSG_BOX:%d,CmdLen(%d), reg:0x%x =>h2c_cmd:0x%x, reg:0x%x =>h2c_cmd_ex:0x%x ..\n" * ,pHalData->LastHMEBoxNum ,CmdLen,msgbox_addr,h2c_cmd,msgbox_ex_addr,h2c_cmd_ex); */ rtlhal->last_hmeboxnum = (h2c_box_num+1) % RTL8812_MAX_H2C_BOX_NUMS; } while ((!bcmd_down) && (retry_cnts--)); exit: mutex_unlock(&(rtl_usbdev(rtlpriv)->h2c_fwcmd_mutex)); }
/***************************************** * H2C Msg format : * 0x1DF - 0x1D0 *| 31 - 8 | 7-5 4 - 0 | *| h2c_msg |Class_ID CMD_ID | * * Extend 0x1FF - 0x1F0 *|31 - 0 | *|ext_msg| ******************************************/ static s32 FillH2CCmd_88E(PADAPTER padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer) { struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); u8 h2c_box_num; u32 msgbox_addr; u32 msgbox_ex_addr; u8 cmd_idx,ext_cmd_len; u32 h2c_cmd = 0; u32 h2c_cmd_ex = 0; s32 ret = _FAIL; _func_enter_; padapter = GET_PRIMARY_ADAPTER(padapter); pHalData = GET_HAL_DATA(padapter); if(padapter->bFWReady == _FALSE) { DBG_8192C("FillH2CCmd_88E(): return H2C cmd because fw is not ready\n"); return ret; } _enter_critical_mutex(&(dvobj->h2c_fwcmd_mutex), NULL); if (!pCmdBuffer) { goto exit; } if (CmdLen > RTL88E_MAX_CMD_LEN) { goto exit; } if (padapter->bSurpriseRemoved == _TRUE) goto exit; //pay attention to if race condition happened in H2C cmd setting. do{ h2c_box_num = pHalData->LastHMEBoxNum; if(!_is_fw_read_cmd_down(padapter, h2c_box_num)){ DBG_8192C(" fw read cmd failed...\n"); goto exit; } *(u8*)(&h2c_cmd) = ElementID; if(CmdLen<=3) { _rtw_memcpy((u8*)(&h2c_cmd)+1, pCmdBuffer, CmdLen ); } else{ _rtw_memcpy((u8*)(&h2c_cmd)+1, pCmdBuffer,3); ext_cmd_len = CmdLen-3; _rtw_memcpy((u8*)(&h2c_cmd_ex), pCmdBuffer+3,ext_cmd_len ); //Write Ext command msgbox_ex_addr = REG_HMEBOX_EXT_0 + (h2c_box_num *RTL88E_EX_MESSAGE_BOX_SIZE); #ifdef CONFIG_H2C_EF for(cmd_idx=0;cmd_idx<ext_cmd_len;cmd_idx++ ){ rtw_write8(padapter,msgbox_ex_addr+cmd_idx,*((u8*)(&h2c_cmd_ex)+cmd_idx)); } #else h2c_cmd_ex = le32_to_cpu( h2c_cmd_ex ); rtw_write32(padapter, msgbox_ex_addr, h2c_cmd_ex); #endif } // Write command msgbox_addr =REG_HMEBOX_0 + (h2c_box_num *RTL88E_MESSAGE_BOX_SIZE); #ifdef CONFIG_H2C_EF for(cmd_idx=0;cmd_idx<RTL88E_MESSAGE_BOX_SIZE;cmd_idx++ ){ rtw_write8(padapter,msgbox_addr+cmd_idx,*((u8*)(&h2c_cmd)+cmd_idx)); } #else h2c_cmd = le32_to_cpu( h2c_cmd ); rtw_write32(padapter,msgbox_addr, h2c_cmd); #endif // DBG_8192C("MSG_BOX:%d,CmdLen(%d), reg:0x%x =>h2c_cmd:0x%x, reg:0x%x =>h2c_cmd_ex:0x%x ..\n" // ,pHalData->LastHMEBoxNum ,CmdLen,msgbox_addr,h2c_cmd,msgbox_ex_addr,h2c_cmd_ex); pHalData->LastHMEBoxNum = (h2c_box_num+1) % RTL88E_MAX_H2C_BOX_NUMS; }while(0); ret = _SUCCESS; exit: _exit_critical_mutex(&(dvobj->h2c_fwcmd_mutex), NULL); _func_exit_; return ret; }
/***************************************** * H2C Msg format : *| 31 - 8 |7 | 6 - 0 | *| h2c_msg |Ext_bit |CMD_ID | * ******************************************/ int FillH2CCmd(struct rtw_adapter *padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer) { u8 bcmd_down = false; s32 retry_cnts = 100; u8 h2c_box_num; u32 msgbox_addr; u32 msgbox_ex_addr; struct hal_data_8723a *pHalData; u32 h2c_cmd = 0; u16 h2c_cmd_ex = 0; int ret = _FAIL; padapter = GET_PRIMARY_ADAPTER(padapter); pHalData = GET_HAL_DATA(padapter); mutex_lock(&adapter_to_dvobj(padapter)->h2c_fwcmd_mutex); if (!pCmdBuffer) goto exit; if (CmdLen > RTL92C_MAX_CMD_LEN) goto exit; if (padapter->bSurpriseRemoved == true) goto exit; /* pay attention to if race condition happened in H2C cmd setting. */ do { h2c_box_num = pHalData->LastHMEBoxNum; if (!_is_fw_read_cmd_down(padapter, h2c_box_num)) { DBG_8723A(" fw read cmd failed...\n"); goto exit; } if (CmdLen <= 3) { memcpy((u8 *)(&h2c_cmd)+1, pCmdBuffer, CmdLen); } else { memcpy((u8 *)(&h2c_cmd_ex), pCmdBuffer, EX_MESSAGE_BOX_SIZE); memcpy((u8 *)(&h2c_cmd)+1, pCmdBuffer+2, (CmdLen-EX_MESSAGE_BOX_SIZE)); *(u8 *)(&h2c_cmd) |= BIT(7); } *(u8 *)(&h2c_cmd) |= ElementID; if (h2c_cmd & BIT(7)) { msgbox_ex_addr = REG_HMEBOX_EXT_0 + (h2c_box_num * EX_MESSAGE_BOX_SIZE); h2c_cmd_ex = le16_to_cpu(h2c_cmd_ex); rtl8723au_write16(padapter, msgbox_ex_addr, h2c_cmd_ex); } msgbox_addr = REG_HMEBOX_0 + (h2c_box_num * MESSAGE_BOX_SIZE); h2c_cmd = le32_to_cpu(h2c_cmd); rtl8723au_write32(padapter, msgbox_addr, h2c_cmd); bcmd_down = true; pHalData->LastHMEBoxNum = (h2c_box_num+1) % RTL92C_MAX_H2C_BOX_NUMS; } while ((!bcmd_down) && (retry_cnts--)); ret = _SUCCESS; exit: mutex_unlock(&adapter_to_dvobj(padapter)->h2c_fwcmd_mutex); return ret; }