/****************************************************************************** * * Copyright(c) 2019 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * *****************************************************************************/ #define _HAL_BTC_DBG_CMD_C_ #include "../hal_headers_le.h" #include "hal_btc.h" #include "halbtc_fw.h" #include "halbtc_fwdef.h" #include "halbtc_action.h" #include "halbtc_def.h" #ifdef CONFIG_BTCOEX #define BTC_CNSL(max_buff_len, used_len, buff_addr, remain_len, fmt, ...)\ do { \ u32 *used_len_tmp = &(used_len); \ if (*used_len_tmp < max_buff_len) \ *used_len_tmp += _os_snprintf(buff_addr, remain_len, fmt, ##__VA_ARGS__);\ } while (0) struct halbtc_cmd_info { char name[16]; u8 id; }; enum HALBTC_CMD_ID { HALBTC_HELP, HALBTC_SHOW, HALBTC_READ_BT, HALBTC_WRITE_BT, HALBTC_SET_COEX, HALBTC_UPDATE_POLICY, HALBTC_TDMA, HALBTC_SLOT, HALBTC_SIG_GDBG_EN, HALBTC_SGPIO_MAP, HALBTC_TRACE_STEP, HALBTC_WL_TX_POWER, HALBTC_WL_RX_LNA, HALBTC_BT_AFH_MAP, HALBTC_BT_TX_POWER, HALBTC_BT_RX_LNA, HALBTC_BT_IGNO_WLAN, HALBTC_SET_GNT_WL, HALBTC_SET_GNT_BT, HALBTC_SET_BT_PSD, HALBTC_GET_WL_NHM_DBM, HALBTC_SET_WL_TX1SS, HALBTC_DBG }; struct halbtc_cmd_info halbtc_cmd_i[] = { {"-h", HALBTC_HELP}, {"show", HALBTC_SHOW}, {"rb", HALBTC_READ_BT}, {"wb", HALBTC_WRITE_BT}, {"mode", HALBTC_SET_COEX}, {"update", HALBTC_UPDATE_POLICY}, {"tdma", HALBTC_TDMA}, {"slot", HALBTC_SLOT}, {"sig", HALBTC_SIG_GDBG_EN}, {"gpio", HALBTC_SGPIO_MAP}, {"wpwr", HALBTC_WL_TX_POWER}, {"wlna", HALBTC_WL_RX_LNA}, {"afh", HALBTC_BT_AFH_MAP}, {"bpwr", HALBTC_BT_TX_POWER}, {"blna", HALBTC_BT_RX_LNA}, {"igwl", HALBTC_BT_IGNO_WLAN}, {"gwl", HALBTC_SET_GNT_WL}, {"gbt", HALBTC_SET_GNT_BT}, {"bpsd", HALBTC_SET_BT_PSD}, {"wnhm", HALBTC_GET_WL_NHM_DBM}, {"wtx1ss", HALBTC_SET_WL_TX1SS}, {"dbg", HALBTC_DBG} }; static void _cmd_rb(struct btc_t *btc, u32 *used, char input[][MAX_ARGV], u32 input_num, char *output, u32 out_len) { u32 i = 0, type = 0, addr = 0; if (input_num < 3) goto help; _os_sscanf(input[1], "%d", &type); _os_sscanf(input[2], "%x", &addr); if (type > 4) goto help; btc->dbg.rb_done = false; btc->dbg.rb_val = 0xffffffff; _read_bt_reg(btc, (u8)(type), (u16)addr); for (i = 0; i < 50; i++) { if (!btc->dbg.rb_done) hal_mdelay(btc->hal, 10); else goto exit; } exit: if (!btc->dbg.rb_done) { BTC_CNSL(out_len, *used, output + *used, out_len - *used, " timeout !! \n"); } else { BTC_CNSL(out_len, *used, output + *used, out_len - *used, " rb %d(0x%x), val = 0x%x !! \n", type, addr, btc->dbg.rb_val); } return; help: BTC_CNSL(out_len, *used, output + *used, out_len - *used, " rb \n"); return; } static void _show_cx_info(struct btc_t *btc, u32 *used, char input[][MAX_ARGV], u32 input_num, char *output, u32 out_len) { struct btc_dm *dm = &btc->dm; struct btc_bt_info *bt = &btc->cx.bt; struct btc_wl_info *wl = &btc->cx.wl; struct rtw_hal_com_t *h = btc->hal; u32 ver_main = 0, ver_sub = 0, ver_hotfix = 0, id_branch = 0; if (!(dm->coex_info_map & BTC_COEX_INFO_CX)) return; dm->cnt_notify[BTC_NCNT_SHOW_COEX_INFO]++; BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r========== [BTC COEX INFO (%s)] ==========", id_to_str(BTC_STR_CHIPID, (u32)btc->chip->chip_id)); ver_main = (coex_ver & bMASKB3) >> 24; ver_sub = (coex_ver & bMASKB2) >> 16; ver_hotfix = (coex_ver & bMASKB1) >> 8; id_branch = coex_ver & bMASKB0; BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r %-15s : Coex:%d.%d.%d(branch:%d), ", "[coex_version]", ver_main, ver_sub, ver_hotfix, id_branch); ver_main = (wl->ver_info.fw_coex & bMASKB3) >> 24; ver_sub = (wl->ver_info.fw_coex & bMASKB2) >> 16; ver_hotfix = (wl->ver_info.fw_coex & bMASKB1) >> 8; id_branch = wl->ver_info.fw_coex & bMASKB0; BTC_CNSL(out_len, *used, output + *used, out_len - *used, "WL_FW_coex:%d.%d.%d(branch:%d)", ver_main, ver_sub, ver_hotfix, id_branch); ver_main = (btc->chip->wlcx_desired & bMASKB3) >> 24; ver_sub = (btc->chip->wlcx_desired & bMASKB2) >> 16; ver_hotfix = (btc->chip->wlcx_desired & bMASKB1) >> 8; BTC_CNSL(out_len, *used, output + *used, out_len - *used, "(%s, desired:%d.%d.%d), ", (wl->ver_info.fw_coex >= btc->chip->wlcx_desired ? "Match" : "Mis-Match"), ver_main, ver_sub, ver_hotfix); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "BT_FW_coex:%d(%s, desired:%d)", bt->ver_info.fw_coex, (bt->ver_info.fw_coex >= btc->chip->btcx_desired ? "Match" : "Mis-Match"), btc->chip->btcx_desired); if (bt->enable.now && bt->ver_info.fw == 0) hal_btc_fw_en_rpt(btc, RPT_EN_BT_VER_INFO, 1); else hal_btc_fw_en_rpt(btc, RPT_EN_BT_VER_INFO, 0); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r %-15s : WL_FW:%d.%d.%d.%d, BT_FW:0x%x(%s)", "[sub_module]", (wl->ver_info.fw & bMASKB3) >> 24, (wl->ver_info.fw & bMASKB2) >> 16, (wl->ver_info.fw & bMASKB1) >> 8, (wl->ver_info.fw & bMASKB0), bt->ver_info.fw, (bt->run_patch_code ? "patch" : "ROM")); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r %-15s : kt_ver:%x, rfe_type:0x%x, hw_id:0x%x, ant_iso:%d, ant_pg:%d, %s", "[hw_info]", btc->mdinfo.kt_ver, btc->mdinfo.rfe_type, ((btc->phl->id.id & 0xff00) >> 8), btc->mdinfo.ant.isolation, btc->mdinfo.ant.num, (btc->mdinfo.ant.num > 1? "" : (btc->mdinfo.ant.single_pos? "1Ant_Pos:S1, " : "1Ant_Pos:S0, "))); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "3rd_coex:%d, dbcc:%d, tx_num:%d, rx_num:%d", btc->cx.other.type, h->dbcc_en, h->rfpath_tx_num, h->rfpath_rx_num); } static void _show_wl_role_info(struct btc_t *btc, u32 *used, char input[][MAX_ARGV], u32 input_num, char *output, u32 out_len) { struct btc_wl_link_info *plink = NULL; struct btc_wl_info *wl = &btc->cx.wl; struct btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info; struct btc_traffic t; u8 i; if (btc->hal->dbcc_en) { BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r %-15s : PHY0_band(op:%d/scan:%d/real:%d), ", "[dbcc_info]", wl_dinfo->op_band[HW_PHY_0], wl_dinfo->scan_band[HW_PHY_0], wl_dinfo->real_band[HW_PHY_0]); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "PHY1_band(op:%d/scan:%d/real:%d)", wl_dinfo->op_band[HW_PHY_1], wl_dinfo->scan_band[HW_PHY_1], wl_dinfo->real_band[HW_PHY_1]); } for (i = 0; i < MAX_WIFI_ROLE_NUMBER; i++) { plink = &btc->cx.wl.link_info[i]; if (!plink->active) continue; BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r [port_%d] : role=%s(phy-%d), connect=%s(client_cnt=%d), mode=%s, ch=(ct:%d/pr:%d), bw=%s", plink->pid, id_to_str(BTC_STR_ROLE, (u32)plink->role), plink->phy, id_to_str(BTC_STR_MSTATE, (u32)plink->connected), plink->client_cnt-1, id_to_str(BTC_STR_WLMODE, (u32)plink->mode), plink->chdef.center_ch, plink->chdef.chan, id_to_str(BTC_STR_WLBW, (u32)plink->chdef.bw)); if (plink->connected == MLME_NO_LINK) continue; BTC_CNSL(out_len, *used, output + *used, out_len - *used, ", mac_id=%d, noa(%d)=%d.%03dms", plink->mac_id, plink->noa, plink->noa_duration/1000, plink->noa_duration%1000); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r [port_%d] : rssi=-%ddBm(%d), busy=%d, dir=%s, ", plink->pid, 110-plink->stat.rssi, plink->stat.rssi, plink->busy, (plink->dir == TRAFFIC_UL ? "UL" : "DL")); t = plink->stat.traffic; BTC_CNSL(out_len, *used, output + *used, out_len - *used, "tx[rate:%s/busy_level:%d/sts:0x%x/1ss:%s], ", id_to_str(BTC_STR_RATE, (u32)t.tx_rate), t.tx_lvl, t.tx_sts, (t.tx_1ss_limit ? "Y" : "N")); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "rx[rate:%s/busy_level:%d/sts:0x%x/drop:%d]", id_to_str(BTC_STR_RATE, (u32)t.rx_rate), t.rx_lvl, t.rx_sts, plink->rx_rate_drop_cnt); } } static void _show_wl_info(struct btc_t *btc, u32 *used, char input[][MAX_ARGV], u32 input_num, char *output, u32 out_len) { struct btc_cx *cx = &btc->cx; struct btc_wl_info *wl = &cx->wl; struct btc_wl_role_info *wl_rinfo = &wl->role_info; if (!(btc->dm.coex_info_map & BTC_COEX_INFO_WL)) return; BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r========== [WL Status] =========="); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r %-15s : link_mode:%s, mrole:%s, ", "[status]", id_to_str(BTC_STR_WLLINK, (u32)wl_rinfo->link_mode), id_to_str(BTC_STR_MROLE, wl_rinfo->mrole_type)); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "rf_off:%s, power_save:%d, init_ok:%s, nhm:%d(status=%d, ratio:%d)", (wl->status.map.rf_off? "Y" : "N"), wl->status.map.lps, (wl->status.map.init_ok? "Y" : "N"), wl->nhm.pwr, wl->nhm.current_status, wl->nhm.ratio); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r %-15s : scan:%s(band:%d/phy_map:0x%x), connecting:%s, roam:%s, 4way:%s", "[scan]", (wl->status.map.scan? "Y" : "N"), wl->scan_info.band[HW_PHY_0], wl->scan_info.phy_map, (wl->status.map.connecting? "Y" : "N"), (wl->status.map.roaming? "Y" : "N"), (wl->status.map._4way? "Y" : "N")); _show_wl_role_info(btc, used, input, input_num, output, out_len); } static void _show_dm_step(struct btc_t *btc, u32 *used, char input[][MAX_ARGV], u32 input_num, char *output, u32 out_len) { struct btc_dm *dm = &btc->dm; u32 n_begin = 0, n_end = 0, i = 0, cnt = 0; u32 step_cnt = dm->dm_step.cnt; if (step_cnt == 0) return; if (step_cnt <= BTC_DM_MAXSTEP) n_begin = 1; else n_begin = step_cnt - BTC_DM_MAXSTEP + 1; n_end = step_cnt; if (n_begin > n_end) return; for (i = n_begin; i <= n_end; i++) { if (cnt % 6 == 0) BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r %-15s : ", "[dm_steps]"); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "-> %s", dm->dm_step.step[(i-1) % BTC_DM_MAXSTEP]); cnt++; } } static void _show_bt_profile_info(struct btc_t *btc, u32 *used, char input[][MAX_ARGV], u32 input_num, char *output, u32 out_len) { struct btc_bt_link_info *bt_linfo = &btc->cx.bt.link_info; struct btc_bt_hfp_desc hfp = bt_linfo->hfp_desc; struct btc_bt_hid_desc hid = bt_linfo->hid_desc; struct btc_bt_a2dp_desc a2dp = bt_linfo->a2dp_desc; struct btc_bt_pan_desc pan = bt_linfo->pan_desc; if (hfp.exist) { BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r %-15s : type:%s, sut_pwr:%d, golden-rx:%d", "[HFP]", (hfp.type == 0? "SCO" : "eSCO"), bt_linfo->sut_pwr_level[0], bt_linfo->golden_rx_shift[0]); } if (hid.exist) { BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r %-15s : type:%s%s%s%s%s pair-cnt:%d, sut_pwr:%d, golden-rx:%d", "[HID]", (hid.type == BTC_HID_218? "2/18," : ""), (hid.type & BTC_HID_418? "4/18," : ""), (hid.type & BTC_HID_BLE? "BLE," : ""), (hid.type & BTC_HID_RCU? "RCU," : ""), (hid.type & BTC_HID_RCU_VOICE? "RCU-Voice," : ""), hid.pair_cnt, bt_linfo->sut_pwr_level[1], bt_linfo->golden_rx_shift[1]); } if (a2dp.exist) { BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r %-15s : type:%s, bit-pool:%d, flush-time:%d, ", "[A2DP]", (a2dp.type == BTC_A2DP_LEGACY ? "Legacy" : "TWS"), a2dp.bitpool, a2dp.flush_time); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "vid:0x%x, Dev-name:0x%x, sut_pwr:%d, golden-rx:%d", a2dp.vendor_id, a2dp.device_name, bt_linfo->sut_pwr_level[2], bt_linfo->golden_rx_shift[2]); } if (pan.exist) { BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r %-15s : sut_pwr:%d, golden-rx:%d", "[PAN]", bt_linfo->sut_pwr_level[3], bt_linfo->golden_rx_shift[3]); } } static void _show_bt_info(struct btc_t *btc, u32 *used, char input[][MAX_ARGV], u32 input_num, char *output, u32 out_len) { struct btc_cx *cx = &btc->cx; struct btc_bt_info *bt = &cx->bt; struct btc_wl_info *wl = &cx->wl; struct btc_module *module = &btc->mdinfo; struct btc_bt_link_info *bt_linfo = &bt->link_info; u8 *afh = bt_linfo->afh_map; if (!(btc->dm.coex_info_map & BTC_COEX_INFO_BT)) return; BTC_CNSL(out_len, *used, output + *used, out_len - *used, "%s", "\n\r========== [BT Status] =========="); /*bt->btg_type = (bt->ver_info.fw & BIT(28) ? BTC_BT_BTG: BTC_BT_ALONE);*/ BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r %-15s : enable:%s, btg:%s%s, connect:%s, ", "[status]", (bt->enable.now? "Y" : "N"), (bt->btg_type? "Y" : "N"), (bt->enable.now && (bt->btg_type != module->bt_pos)? "(efuse-mismatch!!)" : ""), (bt_linfo->status.map.connect? "Y" : "N")); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "igno_wl:%s, mailbox_avl:%s, rfk_state:0x%x", (bt->igno_wl? "Y" : "N"), (bt->mbx_avl? "Y" : "N"), bt->rfk_info.val); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r %-15s : profile:%s%s%s%s%s ", "[profile]", ((bt_linfo->profile_cnt.now == 0) ? "None," : ""), (bt_linfo->hfp_desc.exist? "HFP," : ""), (bt_linfo->hid_desc.exist? "HID," : ""), (bt_linfo->a2dp_desc.exist? (bt_linfo->a2dp_desc.sink ? "A2DP_sink," :"A2DP,") : ""), (bt_linfo->pan_desc.exist? "PAN," : "")); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "multi-link:%s, role:%s, ble-connect:%s, CQDDR:%s, A2DP_active:%s, PAN_active:%s", (bt_linfo->multi_link.now? "Y" : "N"), (bt_linfo->slave_role ? "Slave" : "Master"), (bt_linfo->status.map.ble_connect? "Y" : "N"), (bt_linfo->cqddr? "Y" : "N"), (bt_linfo->a2dp_desc.active? "Y" : "N"), (bt_linfo->pan_desc.active? "Y" : "N")); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r %-15s : rssi:%ddBm, tx_rate:%dM, %s%s%s%s", "[link]", bt_linfo->rssi-100, (bt_linfo->tx_3M? 3 : 2), (bt->pag? " paging!!" : ""), (bt->inq? " inquirying!!" : ""), (bt_linfo->status.map.acl_busy? " acl_busy!!" : ""), (bt_linfo->status.map.mesh_busy? " mesh_busy!!" : "")); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "%s afh_map[%02x%02x_%02x%02x_%02x%02x_%02x%02x_%02x%02x], ", (bt_linfo->relink.now? " ReLink!!" : ""), afh[0], afh[1], afh[2], afh[3], afh[4], afh[5], afh[6], afh[7], afh[8], afh[9]); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "wl_ch_map[en:%d/ch:%d/bw:%d]", wl->afh_info.en, wl->afh_info.ch, wl->afh_info.bw); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r %-15s : retry:%d, relink:%d, rate_chg:%d, reinit:%d, reenable:%d, ", "[stat_cnt]", cx->cnt_bt[BTC_BCNT_RETRY], cx->cnt_bt[BTC_BCNT_RELINK], cx->cnt_bt[BTC_BCNT_RATECHG], cx->cnt_bt[BTC_BCNT_REINIT], cx->cnt_bt[BTC_BCNT_REENABLE]); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "role-switch:%d, afh:%d, inq_page:%d(inq:%d/page:%d), igno_wl:%d", cx->cnt_bt[BTC_BCNT_ROLESW], cx->cnt_bt[BTC_BCNT_AFH], cx->cnt_bt[BTC_BCNT_INQPAG], cx->cnt_bt[BTC_BCNT_INQ], cx->cnt_bt[BTC_BCNT_PAGE], cx->cnt_bt[BTC_BCNT_IGNOWL]); _show_bt_profile_info(btc, used, input, input_num, output, out_len); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r %-15s : raw_data[%02x %02x %02x %02x %02x %02x] (type:%s/cnt:%d/same:%d)", "[bt_info]", bt->raw_info[2], bt->raw_info[3], bt->raw_info[4], bt->raw_info[5], bt->raw_info[6], bt->raw_info[7], (bt->raw_info[0] == BTC_BTINFO_AUTO ? "auto" : "reply"), cx->cnt_bt[BTC_BCNT_INFOUPDATE], cx->cnt_bt[BTC_BCNT_INFOSAME]); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r %-15s : Hi-rx = %d, Hi-tx = %d, Lo-rx = %d, Lo-tx = %d (bt_polut_wl_tx = %d)", "[trx_req_cnt]", cx->cnt_bt[BTC_BCNT_HIPRI_RX], cx->cnt_bt[BTC_BCNT_HIPRI_TX], cx->cnt_bt[BTC_BCNT_LOPRI_RX], cx->cnt_bt[BTC_BCNT_LOPRI_TX], cx->cnt_bt[BTC_BCNT_POLUT]); } static void _show_fbtc_tdma(struct btc_t *btc, u32 *used, char input[][MAX_ARGV], u32 input_num, char *output, u32 out_len) { struct btf_fwinfo *pfwinfo = &btc->fwinfo; struct btc_rpt_cmn_info *pcinfo = NULL; struct fbtc_tdma *t = NULL; pcinfo = &pfwinfo->rpt_fbtc_tdma.cinfo; if (!pcinfo->valid) return; t = &pfwinfo->rpt_fbtc_tdma.finfo.tdma; BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r %-15s : ", "[tdma_policy]"); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "type:%s, rx_flow_ctrl:%d, tx_flow_ctrl:%d, ", id_to_str(BTC_STR_TDMA, (u32)t->type), t->rxflctrl, t->txflctrl); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "wl_toggle_n:%d, leak_n:%d, ext_ctrl:%d, null_role:0x%x, ", t->wtgle_n, t->leak_n, t->ext_ctrl, t->rxflctrl_role); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "policy_type:%s", id_to_str(BTC_STR_POLICY, (u32)btc->policy_type)); } static void _show_dm_info(struct btc_t *btc, u32 *used, char input[][MAX_ARGV], u32 input_num, char *output, u32 out_len) { struct btc_module *module = &btc->mdinfo; struct btc_dm *dm = &btc->dm; struct btc_wl_info *wl = &btc->cx.wl; struct btc_bt_info *bt = &btc->cx.bt; if (!(dm->coex_info_map & BTC_COEX_INFO_DM)) return; BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r========== [Mechanism Status %s] ==========", (btc->ctrl.manual? "(Manual)":"(Auto)")); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r %-15s : type:%s, reason:%s(), action:%s(), ant_path:%s, run_cnt:%d", "[status]", (module->ant.type == BTC_ANT_SHARED ? "shared" : "dedicated"), dm->run_reason, dm->run_action, id_to_str(BTC_STR_ANTPATH, dm->set_ant_path & 0xff), dm->cnt_dm[BTC_DCNT_RUN]); _show_fbtc_tdma(btc, used, input, input_num, output, out_len); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r %-15s : wl_only:%d, bt_only:%d, igno_bt:%d, free_run:%d, wl_ps_ctrl:%d, ", "[dm_flag]", dm->wl_only, dm->bt_only, btc->ctrl.igno_bt, dm->freerun, btc->hal->btc_ctrl.lps); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "leak_ap:%d, fw_offload:%s%s, error_map:0x%x", dm->leak_ap, (BTC_CX_FW_OFFLOAD? "Y" : "N"), (dm->error.map.offload_mismatch? "(Mis-Match!!)" : ""), dm->error.val); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r %-15s : wl_tx_limit[en:%d/max_t:%dus/max_retry:%d/1ss:%d], bt_slot_req:%d-TU, bt_scan_rx_low_pri:%d", "[dm_drv_ctrl]", dm->wl_tx_limit.en, dm->wl_tx_limit.tx_time, dm->wl_tx_limit.tx_retry, dm->wl_tx_limit.tx_1ss, btc->bt_req_len, bt->scan_rx_low_pri); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r %-15s : wl[rssi_lvl:%d/para_lvl:%d/tx_pwr:%d/rx_lvl:%d/_btg_rx:%d/stb_chg:%d] ", "[dm_rf_ctrl]", wl->rssi_level, dm->trx_para_level, dm->rf_trx_para.wl_tx_power, dm->rf_trx_para.wl_rx_gain, dm->wl_btg_rx, dm->wl_stb_chg); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "bt[tx_pwr_dec:%d/rx_lna:%d(%s-tbl)]", dm->rf_trx_para.bt_tx_power, dm->rf_trx_para.bt_rx_gain, (bt->hi_lna_rx? "Hi" : "Ori")); _show_dm_step(btc, used, input, input_num, output, out_len); } static void _show_mreg(struct btc_t *btc, u32 *used, char input[][MAX_ARGV], u32 input_num, char *output, u32 out_len) { struct btf_fwinfo *pfwinfo = &btc->fwinfo; struct btc_rpt_cmn_info *pcinfo = NULL; struct fbtc_mreg_val *pmreg = NULL; struct fbtc_gpio_dbg *gdbg = NULL; struct rtw_hal_com_t *h = btc->hal; struct btc_cx *cx = &btc->cx; struct btc_wl_info *wl = &btc->cx.wl; struct btc_bt_info *bt = &btc->cx.bt; struct btc_gnt_ctrl gnt[2] = {0}; u8 i = 0, type = 0, cnt = 0; u32 val, offset; if (!(btc->dm.coex_info_map & BTC_COEX_INFO_MREG)) return; BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r========== [HW Status] =========="); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r %-15s : WL->BT:0x%08x(cnt:%d), BT->WL:0x%08x(total:%d, bt_update:%d)", "[scoreboard]", wl->scbd, cx->cnt_wl[BTC_WCNT_SCBDUPDATE], bt->scbd, cx->cnt_bt[BTC_BCNT_SCBDREAD], cx->cnt_bt[BTC_BCNT_SCBDUPDATE]); /* To avoid I/O if WL LPS or power-off */ if (wl->status.map.lps != BTC_LPS_RF_OFF && !wl->status.map.rf_off) { rtw_hal_mac_get_grant(h, (u8*)gnt); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r %-15s : pta_owner:%s, pta_req_mac:MAC%d, phy-0[gnt_wl:%s-%d/gnt_bt:%s-%d/polut_type:%s]", "[gnt_status]", (_read_cx_ctrl(btc) == BTC_CTRL_BY_WL? "WL" : "BT"), wl->pta_req_mac, (gnt[0].gnt_wl_sw_en? "SW" : "HW"), gnt[0].gnt_wl, (gnt[0].gnt_bt_sw_en? "SW" : "HW"), gnt[0].gnt_bt, id_to_str(BTC_STR_POLUT, wl->bt_polut_type[HW_PHY_0])); if (h->dbcc_en) BTC_CNSL(out_len, *used, output + *used, out_len - *used, " ,phy-1[gnt_wl:%s-%d/gnt_bt:%s-%d/polut_type:%s]", (gnt[1].gnt_wl_sw_en? "SW" : "HW"), gnt[1].gnt_wl, (gnt[1].gnt_bt_sw_en? "SW" : "HW"), gnt[1].gnt_bt, id_to_str(BTC_STR_POLUT, wl->bt_polut_type[HW_PHY_1])); } pcinfo = &pfwinfo->rpt_fbtc_mregval.cinfo; if (!pcinfo->valid) return; pmreg = &pfwinfo->rpt_fbtc_mregval.finfo; for (i = 0; i < pmreg->reg_num; i++) { type = (u8)btc->chip->mon_reg[i].type; offset = btc->chip->mon_reg[i].offset; val = pmreg->mreg_val[i]; if (cnt % 6 == 0) BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r %-15s : %s_0x%x=0x%x", "[reg]", id_to_str(BTC_STR_REG, (u32)type), offset, val); else BTC_CNSL(out_len, *used, output + *used, out_len - *used, ", %s_0x%x=0x%x", id_to_str(BTC_STR_REG, (u32)type), offset, val); cnt++; } pcinfo = &pfwinfo->rpt_fbtc_gpio_dbg.cinfo; if (!pcinfo->valid) return; gdbg = &pfwinfo->rpt_fbtc_gpio_dbg.finfo; if (!gdbg->en_map) return; BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r %-15s : enable_map:0x%08x", "[gpio_dbg]", gdbg->en_map); for (i = 0; i < BTC_DBG_MAX1; i++) { if (!(gdbg->en_map & BIT(i))) continue; BTC_CNSL(out_len, *used, output + *used, out_len - *used, ", %s->GPIO%d", id_to_str(BTC_STR_GDBG, (u32)i), gdbg->gpio_map[i]); } } static void _show_summary(struct btc_t *btc, u32 *used, char input[][MAX_ARGV], u32 input_num, char *output, u32 out_len) { struct btf_fwinfo *pfwinfo = &btc->fwinfo; struct btc_rpt_cmn_info *pcinfo = NULL; struct fbtc_rpt_ctrl *prptctrl = NULL; struct btc_cx *cx = &btc->cx; struct btc_dm *dm = &btc->dm; struct btc_wl_info *wl = &cx->wl; u32 cnt_sum = 0, *cnt = btc->dm.cnt_notify; u8 i; if (!(dm->coex_info_map & BTC_COEX_INFO_SUMMARY)) return; BTC_CNSL(out_len, *used, output + *used, out_len - *used, "%s", "\n\r========== [Statistics] =========="); pcinfo = &pfwinfo->rpt_ctrl.cinfo; if (pcinfo->valid && wl->status.map.lps != BTC_LPS_RF_OFF && !wl->status.map.rf_off) { prptctrl = &pfwinfo->rpt_ctrl.finfo; BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d, len:%d, max:%d), ", "[summary]", pfwinfo->cnt_h2c, pfwinfo->cnt_h2c_fail, prptctrl->rpt_info.cnt_h2c, pfwinfo->cnt_c2h, prptctrl->rpt_info.cnt_c2h, prptctrl->rpt_info.len_c2h, RTW_PHL_BTC_FWINFO_BUF); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x", pfwinfo->event[BTF_EVNT_RPT], prptctrl->rpt_info.cnt, prptctrl->rpt_info.en); if (dm->error.map.wl_fw_hang) BTC_CNSL(out_len, *used, output + *used, out_len - *used, " (WL FW Hang!!)"); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r %-15s : send_ok:%d, send_fail:%d, recv:%d, ", "[mailbox]", prptctrl->bt_mbx_info.cnt_send_ok, prptctrl->bt_mbx_info.cnt_send_fail, prptctrl->bt_mbx_info.cnt_recv); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "A2DP_empty:%d(stop:%d/tx:%d/ack:%d/nack:%d)", prptctrl->bt_mbx_info.a2dp.cnt_empty, prptctrl->bt_mbx_info.a2dp.cnt_flowctrl, prptctrl->bt_mbx_info.a2dp.cnt_tx, prptctrl->bt_mbx_info.a2dp.cnt_ack, prptctrl->bt_mbx_info.a2dp.cnt_nack); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r %-15s : wl_rfk[req:%d/go:%d/reject:%d/timeout:%d]", "[RFK]", cx->cnt_wl[BTC_WCNT_RFK_REQ], cx->cnt_wl[BTC_WCNT_RFK_GO], cx->cnt_wl[BTC_WCNT_RFK_REJECT], cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT]); BTC_CNSL(out_len, *used, output + *used, out_len - *used, ", bt_rfk[req:%d/go:%d/reject:%d/timeout:%d/fail:%d]", prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_REQ], prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_GO], prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_REJECT], prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_TIMEOUT], prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_FAIL]); } else { BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d", "[summary]", pfwinfo->cnt_h2c, pfwinfo->cnt_h2c_fail, pfwinfo->cnt_c2h); BTC_CNSL(out_len, *used, output + *used, out_len - *used, " WL FW rpt error!!(valid=%d, lps=%d, rf_off=%d)", pcinfo->valid, wl->status.map.lps, wl->status.map.rf_off); } for (i = 0; i < BTC_NCNT_MAX; i++) cnt_sum += dm->cnt_notify[i]; BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ", "[notify_cnt]", cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO], cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d", cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE], cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK], cnt[BTC_NCNT_WL_STA]); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, special_pkt=%d, ", "[notify_cnt]", cnt[BTC_NCNT_SCAN_START], cnt[BTC_NCNT_SCAN_FINISH], cnt[BTC_NCNT_SWITCH_BAND], cnt[BTC_NCNT_SPECIAL_PACKET]); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "timer=%d, control=%d, customerize=%d, hub_msg=%d", cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CONTROL], cnt[BTC_NCNT_CUSTOMERIZE], btc->hubmsg_cnt); } static void _show_error(struct btc_t *btc, u32 *used, char input[][MAX_ARGV], u32 input_num, char *output, u32 out_len) { struct btf_fwinfo *pfwinfo = &btc->fwinfo; struct fbtc_cysta *pcysta = NULL; pcysta = &pfwinfo->rpt_fbtc_cysta.finfo; if (pfwinfo->event[BTF_EVNT_BUF_OVERFLOW] == 0 && pcysta->except_cnt == 0 && !pfwinfo->len_mismch && !pfwinfo->fver_mismch) return; BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r %-15s : ", "[error]"); if (pfwinfo->event[BTF_EVNT_BUF_OVERFLOW]) { BTC_CNSL(out_len, *used, output + *used, out_len - *used, "overflow-cnt: %d, ", pfwinfo->event[BTF_EVNT_BUF_OVERFLOW]); } if (pfwinfo->len_mismch) { BTC_CNSL(out_len, *used, output + *used, out_len - *used, "len-mismatch: 0x%x, ", pfwinfo->len_mismch); } if (pfwinfo->fver_mismch) { BTC_CNSL(out_len, *used, output + *used, out_len - *used, "fver-mismatch: 0x%x, ", pfwinfo->fver_mismch); } /* cycle statistics exceptions */ if (pcysta->except_map || pcysta->except_cnt) { BTC_CNSL(out_len, *used, output + *used, out_len - *used, "exception-type: 0x%x, exception-cnt = %d", pcysta->except_map, pcysta->except_cnt); } } static void _show_fbtc_slots(struct btc_t *btc, u32 *used, char input[][MAX_ARGV], u32 input_num, char *output, u32 out_len) { struct btc_dm *dm = &btc->dm; struct fbtc_slot s; u8 i = 0; for (i = 0; i < CXST_MAX; i++) { s = dm->slot_now[i]; if (i % 5 == 0) BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r %-15s : %s[%d/0x%x/%d]", "[slot_list]", id_to_str(BTC_STR_SLOT, (u32)i), s.dur, s.cxtbl, s.cxtype); else BTC_CNSL(out_len, *used, output + *used, out_len - *used, ", %s[%d/0x%x/%d]", id_to_str(BTC_STR_SLOT, (u32)i), s.dur, s.cxtbl, s.cxtype); } } static void _show_fbtc_cysta(struct btc_t *btc, u32 *used, char input[][MAX_ARGV], u32 input_num, char *output, u32 out_len) { struct btf_fwinfo *pfwinfo = &btc->fwinfo; struct btc_dm *dm = &btc->dm; struct btc_bt_a2dp_desc *a2dp = &btc->cx.bt.link_info.a2dp_desc; struct btc_rpt_cmn_info *pcinfo = NULL; struct fbtc_cysta *pcysta = NULL; u8 i, cnt = 0, slot_pair, divide_cnt = 12; u16 cycle, c_begin, c_end, s_id; pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo; if (!pcinfo->valid) return; pcysta = &pfwinfo->rpt_fbtc_cysta.finfo; BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r %-15s : bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]", "[slot_cnt]", pcysta->bcn_cnt[CXBCN_ALL], pcysta->bcn_cnt[CXBCN_ALL_OK], pcysta->bcn_cnt[CXBCN_BT_SLOT], pcysta->bcn_cnt[CXBCN_BT_OK]); for (i = 0; i < CXST_MAX; i++) { if (!pcysta->slot_cnt[i]) continue; BTC_CNSL(out_len, *used, output + *used, out_len - *used, ", %s:%d", id_to_str(BTC_STR_SLOT, (u32)i), pcysta->slot_cnt[i]); } if (dm->tdma_now.rxflctrl) { BTC_CNSL(out_len, *used, output + *used, out_len - *used, ", leak_rx:%d", pcysta->leak_slot.cnt_rximr); } if (pcysta->collision_cnt) { BTC_CNSL(out_len, *used, output + *used, out_len - *used, ", collision:%d", pcysta->collision_cnt); } if (pcysta->skip_cnt) { BTC_CNSL(out_len, *used, output + *used, out_len - *used, ", skip:%d", pcysta->skip_cnt); } BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r %-15s : cycle:%d, avg_t[wl:%d/bt:%d/lk:%d.%03d]", "[cycle_time]", pcysta->cycles, pcysta->cycle_time.tavg[CXT_WL], pcysta->cycle_time.tavg[CXT_BT], pcysta->leak_slot.tavg/1000, pcysta->leak_slot.tavg%1000); BTC_CNSL(out_len, *used, output + *used, out_len - *used, ", max_t[wl:%d/bt:%d/lk:%d.%03d]", pcysta->cycle_time.tmax[CXT_WL], pcysta->cycle_time.tmax[CXT_BT], pcysta->leak_slot.tamx/1000, pcysta->leak_slot.tamx%1000); BTC_CNSL(out_len, *used, output + *used, out_len - *used, ", maxdiff_t[wl:%d/bt:%d]", pcysta->cycle_time.tmaxdiff[CXT_WL], pcysta->cycle_time.tmaxdiff[CXT_BT]); if (a2dp->exist) { BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r %-15s : a2dp_ept:%d, a2dp_late:%d", "[a2dp_t_sta]", pcysta->a2dp_ept.cnt, pcysta->a2dp_ept.cnt_timeout); BTC_CNSL(out_len, *used, output + *used, out_len - *used, ", avg_t:%d, max_t:%d", pcysta->a2dp_ept.tavg, pcysta->a2dp_ept.tmax); } if (pcysta->cycles <= 1) return; /* 1 cycle = 1 wl-slot + 1 bt-slot */ slot_pair = BTC_CYCLE_SLOT_MAX/2; if (pcysta->cycles <= slot_pair) c_begin = 1; else c_begin = pcysta->cycles - slot_pair + 1; c_end = pcysta->cycles; if (a2dp->exist) divide_cnt = 3; else divide_cnt = 12; if (c_begin > c_end) return; for (cycle = c_begin; cycle <= c_end; cycle++) { cnt++; s_id = ((cycle-1) % slot_pair)*2; if (cnt % divide_cnt == 1) BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r %-15s : ", "[cycleT_ermtan]"); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "->b%d", pcysta->slot_step_time[s_id]); #if 1 if (a2dp->exist) BTC_CNSL(out_len, *used, output + *used, out_len - *used, "(%d/%d/%dM/%d/%d/%d)", pcysta->a2dp_trx[s_id].empty_cnt, pcysta->a2dp_trx[s_id].retry_cnt, (pcysta->a2dp_trx[s_id].tx_rate ? 3:2), pcysta->a2dp_trx[s_id].tx_cnt, pcysta->a2dp_trx[s_id].ack_cnt, pcysta->a2dp_trx[s_id].nack_cnt); #endif BTC_CNSL(out_len, *used, output + *used, out_len - *used, "->w%d", pcysta->slot_step_time[s_id+1]); #if 1 if (a2dp->exist) BTC_CNSL(out_len, *used, output + *used, out_len - *used, "(%d/%d/%dM/%d/%d/%d)", pcysta->a2dp_trx[s_id+1].empty_cnt, pcysta->a2dp_trx[s_id+1].retry_cnt, (pcysta->a2dp_trx[s_id+1].tx_rate ? 3:2), pcysta->a2dp_trx[s_id+1].tx_cnt, pcysta->a2dp_trx[s_id+1].ack_cnt, pcysta->a2dp_trx[s_id+1].nack_cnt); #endif } } static void _show_fbtc_nullsta(struct btc_t *btc, u32 *used, char input[][MAX_ARGV], u32 input_num, char *output, u32 out_len) { struct btf_fwinfo *pfwinfo = &btc->fwinfo; struct btc_rpt_cmn_info *pcinfo = NULL; struct fbtc_cynullsta *ns = NULL; u8 i = 0; if (!btc->dm.tdma_now.rxflctrl) return; pcinfo = &pfwinfo->rpt_fbtc_nullsta.cinfo; if (!pcinfo->valid) return; ns = &pfwinfo->rpt_fbtc_nullsta.finfo; for (i = CXNULL_STATE_0; i <= CXNULL_STATE_1; i++) { BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r %-15s : ", "[null_status]"); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "null-%d", i); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "[Tx:%d/", ns->result[i][CXNULL_TX]); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "ok:%d/", ns->result[i][CXNULL_OK]); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "late:%d/", ns->result[i][CXNULL_LATE]); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "fail:%d/", ns->result[i][CXNULL_FAIL]); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "retry:%d/", ns->result[i][CXNULL_RETRY]); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "avg_t:%d.%03d/", ns->tavg[i]/1000, ns->tavg[i]%1000); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "max_t:%d.%03d]", ns->tmax[i]/1000, ns->tmax[i]%1000); } } static void _show_fbtc_step(struct btc_t *btc, u32 *used, char input[][MAX_ARGV], u32 input_num, char *output, u32 out_len) { struct btf_fwinfo *pfwinfo = &btc->fwinfo; struct btc_rpt_cmn_info *pcinfo = NULL; struct fbtc_steps *pstep = NULL; u8 type, val; u16 diff_t; u32 i, cnt = 0, n_begin = 0, n_end = 0, array_idx = 0; PHL_INFO("[BTC], %s(), rpt_en_map=0x%x\n", __func__, pfwinfo->rpt_en_map); if ((pfwinfo->rpt_en_map & RPT_EN_FW_STEP_INFO) == 0) return; pcinfo = &pfwinfo->rpt_fbtc_step.cinfo; if (!pcinfo->valid) return; pstep = &pfwinfo->rpt_fbtc_step.finfo; if (pcinfo->req_fver != pstep->fver || !pstep->cnt) return; if (pstep->cnt <= FCXDEF_STEP) n_begin = 1; else n_begin = pstep->cnt - FCXDEF_STEP + 1; n_end = pstep->cnt; if (n_begin > n_end) return; /* restore step info by using ring instead of FIFO */ for (i = n_begin; i <= n_end; i++) { array_idx = (i - 1) % FCXDEF_STEP; type = pstep->step[array_idx].type; val = pstep->step[array_idx].val; diff_t = pstep->step[array_idx].difft; if (type == CXSTEP_NONE || type >= CXSTEP_MAX) continue; if (cnt % 10 == 0) BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n\r %-15s : ", "[fw_steps]"); BTC_CNSL(out_len, *used, output + *used, out_len - *used, "-> %s(%d)", (type == CXSTEP_SLOT? id_to_str(BTC_STR_SLOT, (u32)val) : id_to_str(BTC_STR_EVENT, (u32)val)), diff_t); cnt++; } } static void _show_fw_dm_msg(struct btc_t *btc, u32 *used, char input[][MAX_ARGV], u32 input_num, char *output, u32 out_len) { if (!(btc->dm.coex_info_map & BTC_COEX_INFO_DM)) return; _show_error(btc, used, input, input_num, output, out_len); _show_fbtc_slots(btc, used, input, input_num, output, out_len); _show_fbtc_cysta(btc, used, input, input_num, output, out_len); _show_fbtc_nullsta(btc, used, input, input_num, output, out_len); _show_fbtc_step(btc, used, input, input_num, output, out_len); } static void _cmd_show(struct btc_t *btc, u32 *used, char input[][MAX_ARGV], u32 input_num, char *output, u32 out_len) { u32 show_map = 0xff; if (input_num > 1) _os_sscanf(input[1], "%x", &show_map); btc->dm.coex_info_map = show_map & 0xff; _show_cx_info(btc, used, input, input_num, output, out_len); _show_wl_info(btc, used, input, input_num, output, out_len); _show_bt_info(btc, used, input, input_num, output, out_len); _show_dm_info(btc, used, input, input_num, output, out_len); _show_fw_dm_msg(btc, used, input, input_num, output, out_len); _show_mreg(btc, used, input, input_num, output, out_len); _show_summary(btc, used, input, input_num, output, out_len); } static void _cmd_dbg(struct btc_t *btc, u32 *used, char input[][MAX_ARGV], u32 input_num, char *output, u32 out_len) { struct btc_ops *ops = btc->ops; u8 buf[8] = {0}; u32 len, n; u32 val = 0, type = 0, i; if ((input_num < 3) || (input_num > 10)) goto help; len = input_num - 1; _os_sscanf(input[1], "%d", &type); BTC_CNSL(out_len, *used, output + *used, out_len - *used, " test type=%d", type); buf[0] = (u8)(type & 0xff); for (n = 2; n <= len; n++) { _os_sscanf(input[n], "%x", &val); buf[n-1] = (u8)(val & 0xff); BTC_CNSL(out_len, *used, output + *used, out_len - *used, " para%d=0x%x", n-1, buf[n-1]); } BTC_CNSL(out_len, *used, output + *used, out_len - *used, " \n"); switch (type) { case 0: /* H2C-C2H loopback */ ops->fw_cmd(btc, BTFC_SET, SET_H2C_TEST, buf, (u16)len); btc->dbg.rb_done = false; btc->dbg.rb_val = 0xff; for (i = 0; i < 50; i++) { if (!btc->dbg.rb_done) { hal_mdelay(btc->hal, 10); } else { BTC_CNSL(out_len, *used, output + *used, out_len - *used, " H2C-C2H loopback data = 0x%x !!\n", btc->dbg.rb_val); return; } } BTC_CNSL(out_len, *used, output + *used, out_len - *used, " timeout !!\n"); break; case 1: /* H2C-mailbox */ ops->fw_cmd(btc, BTFC_SET, SET_H2C_TEST, buf, (u16)len); break; case 2: /* bt slot request */ btc->bt_req_len = (u32)buf[1]; hal_btc_send_event(btc, (u8*)&btc->bt_req_len, 4, BTC_HMSG_SET_BT_REQ_SLOT); break; case 3: /* fw_step debug */ if (buf[1] > 0) hal_btc_fw_en_rpt(btc, RPT_EN_FW_STEP_INFO, 1); else hal_btc_fw_en_rpt(btc, RPT_EN_FW_STEP_INFO, 0); break; } return; help: BTC_CNSL(out_len, *used, output + *used, out_len - *used, " dbg ... \n"); BTC_CNSL(out_len, *used, output + *used, out_len - *used, " dbg = 0: H2C-C2H loopback \n"); BTC_CNSL(out_len, *used, output + *used, out_len - *used, " dbg = 1: H2C-mailbox \n"); BTC_CNSL(out_len, *used, output + *used, out_len - *used, " dbg = 2: slot request for P2P+BT coex \n"); BTC_CNSL(out_len, *used, output + *used, out_len - *used, " dbg = 3: enable fw_step debug \n"); return; } static void _cmd_wb(struct btc_t *btc, u32 *used, char input[][MAX_ARGV], u32 input_num, char *output, u32 out_len) { u32 type = 0, addr = 0, val = 0; if (input_num < 4) goto help; _os_sscanf(input[1], "%d", &type); _os_sscanf(input[2], "%x", &addr); _os_sscanf(input[3], "%x", &val); if (type > 4) goto help; _write_bt_reg(btc, (u8)type, (u16)addr, val); BTC_CNSL(out_len, *used, output + *used, out_len - *used, " wb type=%d, addr=0x%x, val=0x%x !! \n", type, addr, val); return; help: BTC_CNSL(out_len, *used, output + *used, out_len - *used, " wb \n"); return; } static void _cmd_set_coex(struct btc_t *btc, u32 *used, char input[][MAX_ARGV], u32 input_num, char *output, u32 out_len) { u32 mode = 0; if (input_num < 2) goto help; _os_sscanf(input[1], "%d", &mode); switch(mode) { case 0: /* original */ btc->ctrl.manual = 0; btc->ctrl.always_freerun = 0; btc->dm.wl_only = 0; btc->dm.bt_only = 0; _set_init_info(btc); hal_btc_fw_set_drv_info(btc, CXDRVINFO_INIT); hal_btc_fw_set_drv_info(btc, CXDRVINFO_CTRL); _run_coex(btc, __func__); BTC_CNSL(out_len, *used, output + *used, out_len - *used, " recovery original coex mechanism !! \n"); break; case 1: /* freeze */ btc->ctrl.manual = 1; hal_btc_fw_set_drv_info(btc, CXDRVINFO_CTRL); _run_coex(btc, __func__); BTC_CNSL(out_len, *used, output + *used, out_len - *used, " freeze coex mechanism !! \n"); break; case 2: /* fix freerun */ btc->ctrl.always_freerun = 1; hal_btc_fw_set_drv_info(btc, CXDRVINFO_CTRL); _run_coex(btc, __func__); BTC_CNSL(out_len, *used, output + *used, out_len - *used, " freerun coex mechanism !! \n"); break; case 3: /* fix wl only */ btc->dm.wl_only = 1; _set_init_info(btc); hal_btc_fw_set_drv_info(btc, CXDRVINFO_INIT); _run_coex(btc, __func__); BTC_CNSL(out_len, *used, output + *used, out_len - *used, " always WL-only coex mechanism!! \n"); break; case 4: /* fix bt only */ btc->dm.bt_only = 1; _set_init_info(btc); hal_btc_fw_set_drv_info(btc, CXDRVINFO_INIT); _run_coex(btc, __func__); BTC_CNSL(out_len, *used, output + *used, out_len - *used, " always BT-only coex mechanism!! \n"); break; } return; help: BTC_CNSL(out_len, *used, output + *used, out_len - *used, " mode \n"); return; } static void _cmd_update_policy(struct btc_t *btc, u32 *used, char input[][MAX_ARGV], u32 input_num, char *output, u32 out_len) { hal_btc_fw_set_policy(btc, FC_EXEC, (u16)BTC_CXP_MANUAL<<8, __func__); BTC_CNSL(out_len, *used, output + *used, out_len - *used, " Update tdma/slot policy !! \n"); } static void _cmd_tdma(struct btc_t *btc, u32 *used, char input[][MAX_ARGV], u32 input_num, char *output, u32 out_len) { u32 para1 = 0, para2 = 0; u8 buf[8] = {0}; if (input_num < 3) goto help; _os_sscanf(input[1], "%x", ¶1); _os_sscanf(input[2], "%x", ¶2); buf[0] = (u8)((para1 & bMASKB3) >> 24); buf[1] = (u8)((para1 & bMASKB2) >> 16); buf[2] = (u8)((para1 & bMASKB1) >> 8); buf[3] = (u8)(para1 & bMASKB0); buf[4] = (u8)((para2 & bMASKB3) >> 24); buf[5] = (u8)((para2 & bMASKB2) >> 16); buf[6] = (u8)((para2 & bMASKB1) >> 8); buf[7] = (u8)(para2 & bMASKB0); if (!hal_btc_fw_set_1tdma(btc, (u16)sizeof(struct fbtc_tdma), buf)) goto help; BTC_CNSL(out_len, *used, output + *used, out_len - *used, " set tdma parameters1 type=%s, rxflctrl=0x%x, txflctrl=%d, wtgle_n=%d\n", id_to_str(BTC_STR_TDMA, (u32)buf[0]), buf[1], buf[2], buf[3]); BTC_CNSL(out_len, *used, output + *used, out_len - *used, " set tdma parameters2 leak_n=%d, ext_ctrl=%x, rxflctrl_role=0x%x\n", buf[4], buf[5], buf[6]); return; help: BTC_CNSL(out_len, *used, output + *used, out_len - *used, " tdma \n"); BTC_CNSL(out_len, *used, output + *used, out_len - *used, " bit[31:24]-> type --- 0:off, 1:fix, 2:auto, 3:auto2\n"); BTC_CNSL(out_len, *used, output + *used, out_len - *used, " bit[23:19]-> rx_flow_ctrl --- send rx flow ctrl every n*w2b-slot\n"); BTC_CNSL(out_len, *used, output + *used, out_len - *used, " bit[18:16]-> rx_flow_ctrl_type --- type 0:off, 1:null, 2:Qos-null, 3:cts\n"); BTC_CNSL(out_len, *used, output + *used, out_len - *used, " bit[15:8] -> tx_flow_ctrl --- 0:off, 1:on\n"); BTC_CNSL(out_len, *used, output + *used, out_len - *used, " bit[7:0] -> wtgle_n --- toggle coex table every n*w1-slot\n"); BTC_CNSL(out_len, *used, output + *used, out_len - *used, " bit[31:24]-> leak_n --- enter leak slot every n*w2b-slot\n"); BTC_CNSL(out_len, *used, output + *used, out_len - *used, " bit[23:16]-> ext_ctrl --- 0:off, 1:bcn-early_protect only 2:ext\n"); BTC_CNSL(out_len, *used, output + *used, out_len - *used, " bit[15:8] -> resevrd\n"); BTC_CNSL(out_len, *used, output + *used, out_len - *used, " bit[7:0] -> resevrd\n"); return; } static void _cmd_slot(struct btc_t *btc, u32 *used, char input[][MAX_ARGV], u32 input_num, char *output, u32 out_len) { u32 sid = 0, dur = 0, cx_tbl = 0, cx_type = 0, i; u32 *tmp32 = NULL; u8 buf[9] = {0}; if (input_num < 5) goto help; _os_sscanf(input[1], "%d", &sid); _os_sscanf(input[2], "%d", &dur); _os_sscanf(input[3], "%x", &cx_tbl); _os_sscanf(input[4], "%d", &cx_type); buf[0] = (u8) sid; buf[1] = (u8)(dur & bMASKB0); buf[2] = (u8)((dur & bMASKB1) >> 8); tmp32 = (u32 *)&buf[3]; *tmp32 = cx_tbl; buf[7] = (u8)(cx_type & bMASKB0); buf[8] = (u8)((cx_type & bMASKB1) >> 8); if (!hal_btc_fw_set_1slot(btc, (u16)sizeof(struct fbtc_slot)+1, buf)) goto help; BTC_CNSL(out_len, *used, output + *used, out_len - *used, " set slot parameters: slot:%s, duration:%d, table:%08x, type=%s!!\n", id_to_str(BTC_STR_SLOT, sid), dur, cx_tbl, (cx_type? "iso" : "mix")); return; help: BTC_CNSL(out_len, *used, output + *used, out_len - *used, " slot \n"); BTC_CNSL(out_len, *used, output + *used, out_len - *used, " \n"); for (i = 0; i < CXST_MAX; i++) { if ((i+1) % 5 == 1) BTC_CNSL(out_len, *used, output + *used, out_len - *used, " %d: %s", i, id_to_str(BTC_STR_SLOT, i)); else BTC_CNSL(out_len, *used, output + *used, out_len - *used, ", %d: %s", i, id_to_str(BTC_STR_SLOT, i)); if (((i+1) % 5 == 0) || (i == CXST_MAX - 1)) BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n"); } BTC_CNSL(out_len, *used, output + *used, out_len - *used, " unit: ms\n"); BTC_CNSL(out_len, *used, output + *used, out_len - *used, " 32bits coex table\n"); BTC_CNSL(out_len, *used, output + *used, out_len - *used, " BT packet at WL slot 0: allowed, 1: isolated\n"); return; } static void _cmd_sig_gdbg_en(struct btc_t *btc, u32 *used, char input[][MAX_ARGV], u32 input_num, char *output, u32 out_len) { u32 map = 0, i; if (input_num < 2) goto help; _os_sscanf(input[1], "%x", &map); hal_btc_fw_set_gpio_dbg(btc, CXDGPIO_EN_MAP, map); BTC_CNSL(out_len, *used, output + *used, out_len - *used, " signal to gpio debug map = 0x%08x!!\n", map); return; help: BTC_CNSL(out_len, *used, output + *used, out_len - *used, " sig \n"); for (i = 0; i < BTC_DBG_MAX1; i++) { if ((i+1) % 8 == 1) BTC_CNSL(out_len, *used, output + *used, out_len - *used, " %d: %s", i, id_to_str(BTC_STR_GDBG, i)); else BTC_CNSL(out_len, *used, output + *used, out_len - *used, ", %d: %s", i, id_to_str(BTC_STR_GDBG, i)); if (((i+1) % 8 == 0) || (i == BTC_DBG_MAX1 - 1)) BTC_CNSL(out_len, *used, output + *used, out_len - *used, "\n"); } return; } static void _cmd_sgpio_map(struct btc_t *btc, u32 *used, char input[][MAX_ARGV], u32 input_num, char *output, u32 out_len) { u32 sig = 0, gpio = 0; if (input_num < 3) goto help; _os_sscanf(input[1], "%d", &sig); _os_sscanf(input[2], "%d", &gpio); if ((sig > 31) || (gpio > 7)) goto help; hal_btc_fw_set_gpio_dbg(btc, CXDGPIO_MUX_MAP, ((gpio << 8) + sig)); BTC_CNSL(out_len, *used, output + *used, out_len - *used, " signal-%s -> gpio-%d\n", id_to_str(BTC_STR_GDBG, sig), gpio); return; help: BTC_CNSL(out_len, *used, output + *used, out_len - *used, " gpio \n"); return; } static void _cmd_wl_tx_power(struct btc_t *btc, u32 *used, char input[][MAX_ARGV], u32 input_num, char *output, u32 out_len) { u32 pwr = 0; u8 is_negative = 0; if (input_num < 2) goto help; _os_sscanf(input[1], "%d", &pwr); if (pwr & BIT(31)) { pwr = ~pwr + 1; is_negative = 1; } pwr = pwr & bMASKB0; if ((pwr != 255) && (pwr > 20)) goto help; if (is_negative) pwr |= BIT(7); _set_wl_tx_power(btc, pwr); if (pwr == 0xff) BTC_CNSL(out_len, *used, output + *used, out_len - *used, " set wl tx power level to original!!\n"); else if (is_negative) BTC_CNSL(out_len, *used, output + *used, out_len - *used, " set wl tx power level = -%d dBm!!\n", pwr & 0x7f); else BTC_CNSL(out_len, *used, output + *used, out_len - *used, " set wl tx power level = +%d dBm!!\n", pwr & 0x7f); return; help: BTC_CNSL(out_len, *used, output + *used, out_len - *used, " wpwr original tx power\n"); return; } static void _cmd_wl_rx_lna(struct btc_t *btc, u32 *used, char input[][MAX_ARGV], u32 input_num, char *output, u32 out_len) { u32 lna = 0; if (input_num < 2) goto help; _os_sscanf(input[1], "%d", &lna); _set_wl_rx_gain(btc, lna); BTC_CNSL(out_len, *used, output + *used, out_len - *used, " set wl rx level = %d!!\n", lna); return; help: BTC_CNSL(out_len, *used, output + *used, out_len - *used, " wlna \n"); return; } static void _cmd_bt_afh_map(struct btc_t *btc, u32 *used, char input[][MAX_ARGV], u32 input_num, char *output, u32 out_len) { u32 en = 0, ch = 0, bw = 0; if (input_num < 4) goto help; _os_sscanf(input[1], "%d", &en); _os_sscanf(input[2], "%d", &ch); _os_sscanf(input[3], "%d", &bw); btc->cx.wl.afh_info.en = (u8)en; btc->cx.wl.afh_info.ch = (u8)ch; btc->cx.wl.afh_info.bw = (u8)bw; hal_btc_fw_set_bt(btc, SET_BT_WL_CH_INFO, 3, (u8*)&btc->cx.wl.afh_info); BTC_CNSL(out_len, *used, output + *used, out_len - *used, " set bt afh map: en=%d, ch=%d, map=%d!!\n", en, ch, bw); return; help: BTC_CNSL(out_len, *used, output + *used, out_len - *used, " afh \n"); return; } static void _cmd_bt_tx_power(struct btc_t *btc, u32 *used, char input[][MAX_ARGV], u32 input_num, char *output, u32 out_len) { u32 pwr = 0; if (input_num < 2) goto help; _os_sscanf(input[1], "%d", &pwr); _set_bt_tx_power(btc, pwr); BTC_CNSL(out_len, *used, output + *used, out_len - *used, " decrease bt tx power level = %d!!\n", pwr); return; help: BTC_CNSL(out_len, *used, output + *used, out_len - *used, " bpwr \n"); return; } static void _cmd_bt_rx_lna(struct btc_t *btc, u32 *used, char input[][MAX_ARGV], u32 input_num, char *output, u32 out_len) { u32 lna = 0; if (input_num < 2) goto help; _os_sscanf(input[1], "%d", &lna); if (lna > 7) goto help; _set_bt_rx_gain(btc, lna); BTC_CNSL(out_len, *used, output + *used, out_len - *used, " set bt rx lna constrain level = %d!!\n", lna); return; help: BTC_CNSL(out_len, *used, output + *used, out_len - *used, " blna \n"); return; } static void _cmd_bt_igno_wlan(struct btc_t *btc, u32 *used, char input[][MAX_ARGV], u32 input_num, char *output, u32 out_len) { u32 igno = 0; if (input_num < 2) goto help; _os_sscanf(input[1], "%d", &igno); igno = igno & BIT(0); _set_bt_ignore_wlan_act(btc, (u8)igno); BTC_CNSL(out_len, *used, output + *used, out_len - *used, " set bt ignore wlan = %d!!\n", igno); return; help: BTC_CNSL(out_len, *used, output + *used, out_len - *used, " igwl <0: don't ignore wlan, 1: ignore wlan > \n"); return; } static void _cmd_set_gnt_wl(struct btc_t *btc, u32 *used, char input[][MAX_ARGV], u32 input_num, char *output, u32 out_len) { u32 gwl = 0, phy_map = BTC_PHY_ALL; if ((input_num != 2) && (input_num != 3)) goto help; _os_sscanf(input[1], "%d", &gwl); if (input_num == 3) { _os_sscanf(input[2], "%d", &phy_map); phy_map = (phy_map == 0? BTC_PHY_0 : BTC_PHY_1); } switch(gwl) { case 0: _set_gnt_wl(btc, (u8)phy_map, BTC_GNT_SW_LO); BTC_CNSL(out_len, *used, output + *used, out_len - *used, " set gnt_wl = SW-0 (phy_map=0x%x)\n", phy_map); break; case 1: _set_gnt_wl(btc, (u8)phy_map, BTC_GNT_SW_HI); BTC_CNSL(out_len, *used, output + *used, out_len - *used, " set gnt_wl = SW-1 (phy_map=0x%x)\n", phy_map); break; case 2: _set_gnt_wl(btc, (u8)phy_map, BTC_GNT_HW); BTC_CNSL(out_len, *used, output + *used, out_len - *used, " set gnt_wl = HW-PTA ctrl (phy_map=0x%x)\n", phy_map); break; } return; help: BTC_CNSL(out_len, *used, output + *used, out_len - *used, " gwl <0:SW_0, 1:SW_1, 2:HW_PTA> <0:PHY-0, 1:PHY-1, none:All> \n"); return; } static void _cmd_set_gnt_bt(struct btc_t *btc, u32 *used, char input[][MAX_ARGV], u32 input_num, char *output, u32 out_len) { u32 gbt = 0, phy_map = BTC_PHY_ALL; if ((input_num != 2) && (input_num != 3)) goto help; _os_sscanf(input[1], "%d", &gbt); if (input_num == 3) { _os_sscanf(input[2], "%d", &phy_map); phy_map = (phy_map == 0? BTC_PHY_0 : BTC_PHY_1); } switch(gbt) { case 0: _set_gnt_bt(btc, (u8)phy_map, BTC_GNT_SW_LO); BTC_CNSL(out_len, *used, output + *used, out_len - *used, " set gnt_bt = SW-0 (phy_map=0x%x)\n", phy_map); break; case 1: _set_gnt_bt(btc, (u8)phy_map, BTC_GNT_SW_HI); BTC_CNSL(out_len, *used, output + *used, out_len - *used, " set gnt_bt = SW-1 (phy_map=0x%x)\n", phy_map); break; case 2: _set_gnt_bt(btc, (u8)phy_map, BTC_GNT_HW); BTC_CNSL(out_len, *used, output + *used, out_len - *used, " set gnt_bt = HW-PTA ctrl (phy_map=0x%x)\n", phy_map); break; } return; help: BTC_CNSL(out_len, *used, output + *used, out_len - *used, " gbt <0:SW_0, 1:SW_1, 2:HW_PTA> <0:PHY-0, 1:PHY-1, none:All> \n"); return; } static void _cmd_set_bt_psd(struct btc_t *btc, u32 *used, char input[][MAX_ARGV], u32 input_num, char *output, u32 out_len) { u32 idx = 0, type = 0; if (input_num < 3) goto help; _os_sscanf(input[1], "%d", &idx); _os_sscanf(input[2], "%d", &type); _set_bt_psd_report(btc, (u8)idx, (u8)type); return; help: BTC_CNSL(out_len, *used, output + *used, out_len - *used, " bpsd \n"); return; } void _get_wl_nhm_dbm(struct btc_t *btc) { struct btc_wl_info *wl = &btc->cx.wl; struct btc_wl_nhm *wl_nhm = &wl->nhm; u8 set_result = false; s8 bw_att_db = 13; s8 nhm_pwr_dbm = 0; s8 pwr = 0; s8 cur_pwr = 0; u16 save_index = 0; bool new_data_flag = false; struct watchdog_nhm_report nhm_rpt = {0}; if (wl->afh_info.bw < CHANNEL_WIDTH_5) { if (wl->afh_info.bw != CHANNEL_WIDTH_80_80) { bw_att_db = 13 + 3 * (s8)(wl->afh_info.bw - CHANNEL_WIDTH_20); } else { bw_att_db = 13 + 3 * 3; } } rtw_hal_bb_nhm_mntr_result(btc->hal, &nhm_rpt, HW_PHY_0); set_result = nhm_rpt.ccx_rpt_result; if (set_result) { nhm_pwr_dbm = nhm_rpt.nhm_pwr_dbm; wl_nhm->instant_wl_nhm_dbm = nhm_pwr_dbm; if (wl_nhm->start_flag == false) { wl_nhm->start_flag = true; pwr = nhm_pwr_dbm - bw_att_db; new_data_flag = true; } else { pwr = wl_nhm->pwr; if (wl_nhm->last_ccx_rpt_stamp != nhm_rpt.ccx_rpt_stamp) { new_data_flag = true; wl_nhm->current_status = 1; // new data } else { wl_nhm->current_status = 2; //duplicated data } } if (new_data_flag) { wl_nhm->last_ccx_rpt_stamp = nhm_rpt.ccx_rpt_stamp; cur_pwr = nhm_pwr_dbm - bw_att_db; wl_nhm->instant_wl_nhm_per_mhz = cur_pwr; wl_nhm->valid_record_times += 1; if (wl_nhm->valid_record_times == 0) { wl_nhm->valid_record_times = 16; } save_index = (wl_nhm->valid_record_times + 16 - 1) % 16; wl_nhm->ratio = nhm_rpt.nhm_ratio; if (cur_pwr < pwr) { pwr = cur_pwr; wl_nhm->refresh = true; } else { pwr = (pwr >> 1) + (cur_pwr >> 1); wl_nhm->refresh = false; } wl_nhm->pwr = pwr; wl_nhm->record_pwr[(save_index & 0xF)] = pwr; wl_nhm->record_ratio[(save_index & 0xF)] = nhm_rpt.nhm_ratio; } } } static void _cmd_get_wl_nhm_dbm(struct btc_t *btc, u32 *used, char input[][MAX_ARGV], u32 input_num, char *output, u32 out_len) { struct btc_wl_info *wl = &btc->cx.wl; struct btc_wl_nhm *wl_nhm = &wl->nhm; u16 start_index = 0; u16 stop_index = 0; u16 i; u32 show_record_num = 16; if (input_num >= 3) goto help; _get_wl_nhm_dbm(btc); _os_sscanf(input[1], "%d", &show_record_num); if (show_record_num >= 16) show_record_num = 16; else if (show_record_num == 0) show_record_num = 1; if (wl_nhm->valid_record_times > 0) { if (wl_nhm->current_status == 0) { BTC_CNSL(out_len, *used, output + *used, out_len - *used, "wl nhm failed this time\n"); } BTC_CNSL(out_len, *used, output + *used, out_len - *used, "nhm_psd = %d dBm/MHz, nhm_ratio = %d, status = %d, " "valid_record_times = %d\n", wl_nhm->pwr, wl_nhm->ratio, wl_nhm->current_status, wl_nhm->valid_record_times); stop_index = wl_nhm->valid_record_times; if (wl_nhm->valid_record_times > (u16)show_record_num) { start_index = wl_nhm->valid_record_times - (u16)show_record_num; } for (i = start_index; i < stop_index; i++) { if (i == start_index) { BTC_CNSL(out_len, *used, output + *used, out_len - *used, "record_pwr(old->new) = %4d", wl_nhm->record_pwr[(i + 16) & 0xF]); } else if (i == (stop_index - 1)) { BTC_CNSL(out_len, *used, output + *used, out_len - *used, ", %4d dBm/MHz\n", wl_nhm->record_pwr[(i + 16) & 0xF]); } else { BTC_CNSL(out_len, *used, output + *used, out_len - *used, ", %4d", wl_nhm->record_pwr[(i + 16) & 0xF]); } } for (i = start_index; i < stop_index; i++) { if (i == start_index) { BTC_CNSL(out_len, *used, output + *used, out_len - *used, "record_ratio(old->new) = %4d", wl_nhm->record_ratio[(i + 16) & 0xF]); } else if (i == (stop_index - 1)) { BTC_CNSL(out_len, *used, output + *used, out_len - *used, ", %4d percent\n", wl_nhm->record_ratio[(i + 16) & 0xF]); } else { BTC_CNSL(out_len, *used, output + *used, out_len - *used, ", %4d", wl_nhm->record_ratio[(i + 16) & 0xF]); } } } else { BTC_CNSL(out_len, *used, output + *used, out_len - *used, "wl nhm not ready\n"); } return; help: BTC_CNSL(out_len, *used, output + *used, out_len - *used, " wnhm \n"); return; } u8 _btc_set_wl_tx_1ss(struct btc_t *btc, u8 port_id, bool enable) { struct rtw_hal_com_t *h = btc->hal; enum rtw_hal_status set_reult; set_reult = rtw_hal_btc_cfg_tx_1ss(h, btc->phl, port_id, enable); if (set_reult != RTW_HAL_STATUS_SUCCESS) return 1; return 0; } static void _cmd_set_wl_tx_1ss(struct btc_t *btc, u32 *used, char input[][MAX_ARGV], u32 input_num, char *output, u32 out_len) { u32 port_id = 0xFFFFFFFF; u8 j; u8 set_reult; bool enable = false; u32 enable_input; if (input_num < 2) goto help; _os_sscanf(input[1], "%d", &enable_input); if (input_num >= 3) _os_sscanf(input[2], "%d", &port_id); enable = enable_input == 1 ? true : false; if (port_id == 0xFFFFFFFF) { for( j = 0; j < MAX_WIFI_ROLE_NUMBER; j++) { set_reult = _btc_set_wl_tx_1ss(btc, j, enable); if (set_reult == 1) BTC_CNSL(out_len, *used, output + *used, out_len - *used, "port %d set 1ss to %d fail\n", j, enable); } } else if (port_id < MAX_WIFI_ROLE_NUMBER) { set_reult = _btc_set_wl_tx_1ss(btc, (u8)(port_id & 0xFF), enable); if (set_reult == 1) BTC_CNSL(out_len, *used, output + *used, out_len - *used, "port %d set 1ss to %d fail\n", port_id, enable); } else { BTC_CNSL(out_len, *used, output + *used, out_len - *used, "port %d is invalid\n", port_id); } return ; help: BTC_CNSL(out_len, *used, output + *used, out_len - *used, " wtx1ss \n"); return; } void halbtc_cmd_parser(struct btc_t *btc, char input[][MAX_ARGV], u32 input_num, char *output, u32 out_len) { u32 used = 0; u8 id = 0; u32 i; u32 array_size = sizeof(halbtc_cmd_i) / sizeof(struct halbtc_cmd_info); BTC_CNSL(out_len, used, output + used, out_len - used, "\n"); /* Parsing Cmd ID */ if (input_num) { for (i = 0; i < array_size; i++) { if (_os_strcmp(halbtc_cmd_i[i].name, input[0]) == 0) { id = halbtc_cmd_i[i].id; break; } } } switch (id) { case HALBTC_DBG: _cmd_dbg(btc, &used, input, input_num, output, out_len); break; case HALBTC_SHOW: _cmd_show(btc, &used, input, input_num, output, out_len); break; case HALBTC_WRITE_BT: _cmd_wb(btc, &used, input, input_num, output, out_len); break; case HALBTC_READ_BT: _cmd_rb(btc, &used, input, input_num, output, out_len); break; case HALBTC_SET_COEX: _cmd_set_coex(btc, &used, input, input_num, output, out_len); break; case HALBTC_UPDATE_POLICY: _cmd_update_policy(btc, &used, input, input_num, output, out_len); break; case HALBTC_TDMA: _cmd_tdma(btc, &used, input, input_num, output, out_len); break; case HALBTC_SLOT: _cmd_slot(btc, &used, input, input_num, output, out_len); break; case HALBTC_SIG_GDBG_EN: _cmd_sig_gdbg_en(btc, &used, input, input_num, output, out_len); break; case HALBTC_SGPIO_MAP: _cmd_sgpio_map(btc, &used, input, input_num, output, out_len); break; case HALBTC_WL_TX_POWER: _cmd_wl_tx_power(btc, &used, input, input_num, output, out_len); break; case HALBTC_WL_RX_LNA: _cmd_wl_rx_lna(btc, &used, input, input_num, output, out_len); break; case HALBTC_BT_AFH_MAP: _cmd_bt_afh_map(btc, &used, input, input_num, output, out_len); break; case HALBTC_BT_TX_POWER: _cmd_bt_tx_power(btc, &used, input, input_num, output, out_len); break; case HALBTC_BT_RX_LNA: _cmd_bt_rx_lna(btc, &used, input, input_num, output, out_len); break; case HALBTC_BT_IGNO_WLAN: _cmd_bt_igno_wlan(btc, &used, input, input_num, output, out_len); break; case HALBTC_SET_GNT_WL: _cmd_set_gnt_wl(btc, &used, input, input_num, output, out_len); break; case HALBTC_SET_GNT_BT: _cmd_set_gnt_bt(btc, &used, input, input_num, output, out_len); break; case HALBTC_SET_BT_PSD: _cmd_set_bt_psd(btc, &used, input, input_num, output, out_len); break; case HALBTC_GET_WL_NHM_DBM: _cmd_get_wl_nhm_dbm(btc, &used, input, input_num, output, out_len); break; case HALBTC_SET_WL_TX1SS: _cmd_set_wl_tx_1ss(btc, &used, input, input_num, output, out_len); break; default: BTC_CNSL(out_len, used, output + used, out_len - used, "command not supported !!\n"); /* fall through */ case HALBTC_HELP: BTC_CNSL(out_len, used, output + used, out_len - used, "BTC cmd ==>\n"); for (i = 0; i < array_size - 1; i++) BTC_CNSL(out_len, used, output + used, out_len - used, " %s\n", halbtc_cmd_i[i + 1].name); break; } } s32 halbtc_cmd(struct btc_t *btc, char *input, char *output, u32 out_len) { char *token; u32 argc = 0; char argv[MAX_ARGC][MAX_ARGV]; do { token = _os_strsep(&input, ", "); if (token) { if (_os_strlen((u8 *)token) <= MAX_ARGV) _os_strcpy(argv[argc], token); argc++; } else { break; } } while (argc < MAX_ARGC); #if 0 if (argc == 1) argv[0][_os_strlen((u8 *)argv[0]) - 1] = '\0'; #endif halbtc_cmd_parser(btc, argv, argc, output, out_len); return 0; } #endif