| /* |
| * wl ltecx command module |
| * |
| * Broadcom Proprietary and Confidential. Copyright (C) 2017, |
| * All Rights Reserved. |
| * |
| * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom; |
| * the contents of this file may not be disclosed to third parties, copied |
| * or duplicated in any form, in whole or in part, without the prior |
| * written permission of Broadcom. |
| * |
| * |
| * <<Broadcom-WL-IPTag/Proprietary:>> |
| * |
| * $Id: wluc_ltecx.c 458728 2014-02-27 18:15:25Z $ |
| */ |
| |
| #ifdef WIN32 |
| #include <windows.h> |
| #endif |
| |
| #include <wlioctl.h> |
| |
| #if defined(DONGLEBUILD) |
| #include <typedefs.h> |
| #include <osl.h> |
| #endif |
| |
| /* Because IL_BIGENDIAN was removed there are few warnings that need |
| * to be fixed. Windows was not compiled earlier with IL_BIGENDIAN. |
| * Hence these warnings were not seen earlier. |
| * For now ignore the following warnings |
| */ |
| #ifdef WIN32 |
| #pragma warning(push) |
| #pragma warning(disable : 4244) |
| #pragma warning(disable : 4761) |
| #endif |
| |
| #include <bcmutils.h> |
| #include <bcmendian.h> |
| #include "wlu_common.h" |
| #include "wlu.h" |
| |
| /* LTE coex funcs */ |
| static cmd_func_t wl_wci2_config; |
| static cmd_func_t wl_mws_params; |
| static cmd_func_t wl_mws_wci2_msg; |
| static cmd_func_t wl_mws_frame_config; |
| static cmd_func_t wl_mws_antmap; |
| static cmd_func_t wl_mws_oclmap; |
| static cmd_func_t wl_mws_scanreq_bm; |
| |
| static cmd_t wl_ltecx_cmds[] = { |
| { "wci2_config", wl_wci2_config, WLC_GET_VAR, WLC_SET_VAR, |
| "Get/Set LTE coex MWS signaling config\n" |
| "\tUsage: wl wci2_config <rxassert_off> <rxassert_jit> <rxdeassert_off> <rxdeassert_jit> " |
| "<txassert_off> <txassert_jit> <txdeassert_off> <txdeassert_jit> " |
| "<patassert_off> <patassert_jit> <inactassert_off> <inactassert_jit> " |
| "<scanfreqassert_off> <scanfreqassert_jit> <priassert_off_req>"}, |
| { "mws_params", wl_mws_params, WLC_GET_VAR, WLC_SET_VAR, |
| "Get/Set LTE coex MWS channel params\n" |
| "\tUsage: wl mws_params <rx_center_freq> <tx_center_freq> " |
| "<rx_channel_bw> <tx_channel_bw> <channel_en> <channel_type>"}, |
| { "mws_debug_msg", wl_mws_wci2_msg, WLC_GET_VAR, WLC_SET_VAR, |
| "Get/Set LTE coex BT-SIG message\n" |
| "\tUsage: wl mws_debug_msg <Message> <Interval 20us-32000us> " |
| "<Repeats>"}, |
| { "mws_frame_config", wl_mws_frame_config, WLC_GET_VAR, WLC_SET_VAR, |
| "Get/Set LTE Frame configuration\n" |
| "\tUsage: wl mws_frame_config <mws_frame_dur> <mws_framesync_assert_offset>" |
| "<mws_framesync_assert_jitter> <mws_num_periods>" |
| "{<mws_period_dur[i]> <mws_period_type>[i]}"}, |
| { "mws_antenna_selection", wl_mws_antmap, WLC_GET_VAR, WLC_SET_VAR, |
| "Get/Set Antenna selection params\n" |
| "\tUsage: wl mws_antenna_selection <band-AntTx-combo1> <band-AntTx-combo2> " |
| "<band-AntTx-combo3> <band-AntTx-combo4>\n"}, |
| { "mws_ocl_override", wl_mws_oclmap, WLC_GET_VAR, WLC_SET_VAR, |
| "Get/Set OCL maps\n" |
| "\tUsage: wl mws_ocl_override <bitmap_2G> <bitmap_5G_lo> " |
| "<bitmap_5G_mid> <bitmap_5G_high>\n"}, |
| { "mws_scanreq_bm", wl_mws_scanreq_bm, WLC_GET_VAR, WLC_SET_VAR, |
| "\tusage: wl mws_scanreq_bm [idx 2.4G-bitmap 5G-bitmap-lo 5G-bitmap-mid 5G-bitmap-hi]\n" |
| "Set/Get the channel bitmaps corresponding to MWS (cellular) scan index <idx>"}, |
| { NULL, NULL, 0, 0, NULL } |
| }; |
| |
| static char *buf; |
| |
| /* module initialization */ |
| void |
| wluc_ltecx_module_init(void) |
| { |
| /* get the global buf */ |
| buf = wl_get_buf(); |
| |
| /* register ltecx commands */ |
| wl_module_cmds_register(wl_ltecx_cmds); |
| } |
| |
| static int |
| wl_wci2_config(void *wl, cmd_t *cmd, char **argv) |
| { |
| uint32 val; |
| char *endptr = NULL; |
| uint argc; |
| wci2_config_t wci2_config; |
| uint16 *configp = (uint16 *)&wci2_config; |
| int ret, i; |
| |
| UNUSED_PARAMETER(cmd); |
| |
| val = 0; |
| |
| /* eat command name */ |
| argv++; |
| /* arg count */ |
| for (argc = 0; argv[argc]; argc++); |
| |
| memset(&wci2_config, '\0', sizeof(wci2_config_t)); |
| |
| if (argc == 0) { |
| /* Get and print the values */ |
| ret = wlu_iovar_getbuf(wl, "wci2_config", &wci2_config, sizeof(wci2_config_t), |
| buf, WLC_IOCTL_SMLEN); |
| if (ret) |
| return ret; |
| |
| printf("rxassert_off %d rxassert_jit %d rxdeassert_off %d rxdeassert_jit %d " |
| "txassert_off %d txassert_jit %d txdeassert_off %d txdeassert_jit %d " |
| "patassert_off %d patassert_jit %d inactassert_off %d inactassert_jit %d " |
| "scanfreqassert_off %d scanfreqassert_jit %d priassert_off_req %d\n", |
| dtoh16(((uint16 *)buf)[0]), dtoh16(((uint16 *)buf)[1]), |
| dtoh16(((uint16 *)buf)[2]), dtoh16(((uint16 *)buf)[3]), |
| dtoh16(((uint16 *)buf)[4]), dtoh16(((uint16 *)buf)[5]), |
| dtoh16(((uint16 *)buf)[6]), dtoh16(((uint16 *)buf)[7]), |
| dtoh16(((uint16 *)buf)[8]), dtoh16(((uint16 *)buf)[9]), |
| dtoh16(((uint16 *)buf)[10]), dtoh16(((uint16 *)buf)[11]), |
| dtoh16(((uint16 *)buf)[12]), dtoh16(((uint16 *)buf)[13]), |
| dtoh16(((uint16 *)buf)[14])); |
| return 0; |
| } |
| |
| if (argc < 15) |
| goto usage; |
| |
| for (i = 0; i < 15; ++i) { |
| val = strtoul(argv[i], &endptr, 0); |
| if (*endptr != '\0') |
| goto usage; |
| configp[i] = htod16((uint16)val); |
| } |
| return wlu_iovar_setbuf(wl, "wci2_config", &wci2_config, sizeof(wci2_config_t), |
| buf, WLC_IOCTL_SMLEN); |
| |
| usage: |
| return BCME_USAGE_ERROR; |
| } |
| |
| static int |
| wl_mws_params(void *wl, cmd_t *cmd, char **argv) |
| { |
| uint32 val; |
| char *endptr = NULL; |
| uint argc; |
| mws_params_t mws_params; |
| uint16 *paramsp = (uint16 *)&mws_params; |
| int ret, i; |
| |
| UNUSED_PARAMETER(cmd); |
| |
| val = 0; |
| |
| /* eat command name */ |
| argv++; |
| |
| /* arg count */ |
| for (argc = 0; argv[argc]; argc++); |
| |
| memset(&mws_params, '\0', sizeof(mws_params_t)); |
| |
| if (argc == 0) { |
| /* Get and print the values */ |
| ret = wlu_iovar_getbuf(wl, "mws_params", &mws_params, sizeof(mws_params_t), |
| buf, WLC_IOCTL_SMLEN); |
| if (ret) |
| return ret; |
| |
| printf("rx_center_freq %d tx_center_freq %d rx_channel_bw %d tx_channel_bw %d " |
| "channel_en %d channel_type %d\n", |
| dtoh16(((uint16 *)buf)[0]), dtoh16(((uint16 *)buf)[1]), |
| dtoh16(((uint16 *)buf)[2]), dtoh16(((uint16 *)buf)[3]), buf[8], buf[9]); |
| return 0; |
| } |
| |
| if (argc < 6) |
| goto usage; |
| for (i = 0; i < 4; ++i) { |
| val = strtoul(argv[i], &endptr, 0); |
| if (*endptr != '\0') |
| goto usage; |
| paramsp[i] = htod16((uint16)val); |
| } |
| val = strtoul(argv[i], &endptr, 0); |
| if (*endptr != '\0') |
| goto usage; |
| mws_params.mws_channel_en = val; |
| ++i; |
| val = strtoul(argv[i], &endptr, 0); |
| if (*endptr != '\0') |
| goto usage; |
| mws_params.mws_channel_type = val; |
| |
| return wlu_iovar_setbuf(wl, "mws_params", &mws_params, sizeof(mws_params_t), |
| buf, WLC_IOCTL_SMLEN); |
| |
| usage: |
| return BCME_USAGE_ERROR; |
| } |
| |
| static int |
| wl_mws_wci2_msg(void *wl, cmd_t *cmd, char **argv) |
| { |
| uint32 val; |
| char *endptr = NULL; |
| uint argc; |
| mws_wci2_msg_t mws_wci2_msg; |
| uint16 *paramsp = (uint16 *)&mws_wci2_msg; |
| int ret, i = 0; |
| |
| UNUSED_PARAMETER(cmd); |
| |
| val = 0; |
| |
| /* eat command name */ |
| argv++; |
| |
| /* arg count */ |
| for (argc = 0; argv[argc]; argc++); |
| |
| memset(&mws_wci2_msg, '\0', sizeof(mws_wci2_msg_t)); |
| |
| if (argc == 0) { |
| /* Get and print the values */ |
| ret = wlu_iovar_getbuf(wl, "mws_debug_msg", &mws_wci2_msg, sizeof(mws_wci2_msg_t), |
| buf, WLC_IOCTL_SMLEN); |
| if (ret) |
| return ret; |
| |
| printf("Message %d Interval %d Repeats %d \n", |
| dtoh16(((uint16 *)buf)[0]), dtoh16(((uint16 *)buf)[1]), |
| dtoh16(((uint16 *)buf)[2])); |
| return 0; |
| } |
| |
| if (argc < 3) |
| goto usage; |
| |
| for (i = 0; i < 3; ++i) { |
| val = strtoul(argv[i], &endptr, 0); |
| if (*endptr != '\0') |
| goto usage; |
| paramsp[i] = htod16((uint16)val); |
| } |
| if ((paramsp[1] < 20) || (paramsp[1] > 32000)) |
| goto usage; |
| return wlu_iovar_setbuf(wl, "mws_debug_msg", &mws_wci2_msg, sizeof(mws_wci2_msg_t), |
| buf, WLC_IOCTL_SMLEN); |
| |
| usage: |
| return BCME_USAGE_ERROR; |
| } |
| |
| static int |
| wl_mws_frame_config(void *wl, cmd_t *cmd, char **argv) |
| { |
| uint32 val; |
| char *endptr = NULL; |
| uint argc; |
| mws_frame_config_t mws_frame_config; |
| uint16 *paramsp = (uint16 *)&mws_frame_config; |
| int ret, j = 3, k = 4, l = 20; |
| uint8 i = 0; |
| |
| UNUSED_PARAMETER(cmd); |
| |
| val = 0; |
| |
| /* eat command name */ |
| argv++; |
| |
| /* arg count */ |
| for (argc = 0; argv[argc]; argc++); |
| |
| memset(&mws_frame_config, '\0', sizeof(mws_frame_config_t)); |
| |
| if (argc == 0) { |
| /* Get and print the values */ |
| ret = wlu_iovar_getbuf(wl, "mws_frame_config", &mws_frame_config, |
| sizeof(mws_frame_config_t), buf, WLC_IOCTL_SMLEN); |
| if (ret) { |
| return ret; |
| } |
| printf("mws_frame_dur %d us mws_framesync_assert_offset %d " |
| "mws_framesync_assert_jitter %d mws_num_periods %d \n", |
| dtoh16(((uint16 *)buf)[0]), dtoh16(((uint16 *)buf)[1]), |
| dtoh16(((uint16 *)buf)[2]), buf[27]); |
| for (i = 0; i < buf[27]; i++) { |
| printf("mws_period_dur[%d] %d us mws_period_type[%d] %d\n", |
| i, dtoh16(((uint16 *)buf)[j]), i, buf[l]); |
| j++; |
| l++; |
| } |
| return 0; |
| } |
| |
| if (argc <= 4) |
| goto usage; |
| /* Loop to populate the first three elements of the structure */ |
| for (i = 0; i < 3; ++i) { |
| val = strtoul(argv[i], &endptr, 0); |
| if (*endptr != '\0') |
| goto usage; |
| paramsp[i] = htod16((uint16)val); |
| } |
| |
| val = strtoul(argv[3], &endptr, 0); |
| if (*endptr != '\0') |
| goto usage; |
| mws_frame_config.mws_num_periods = val; |
| |
| /* Error check for insufficient data entered */ |
| if ((uint8)argc != ((mws_frame_config.mws_num_periods * 2) + 4)) { |
| goto usage; |
| } |
| /* Loop to populate the arrays of size equal to mws_frame_config.mws_num_periods */ |
| for (i = 0; i < mws_frame_config.mws_num_periods; i++) |
| { |
| val = strtoul(argv[k], &endptr, 0); |
| if (*endptr != '\0') { |
| goto usage; |
| } |
| mws_frame_config.mws_period_dur[i] = val; |
| k++; |
| |
| val = strtoul(argv[k], &endptr, 0); |
| if (*endptr != '\0') { |
| goto usage; |
| } |
| mws_frame_config.mws_period_type[i] = val; |
| k++; |
| } |
| /* Set the values */ |
| return wlu_iovar_setbuf(wl, "mws_frame_config", &mws_frame_config, |
| sizeof(mws_frame_config_t), buf, WLC_IOCTL_SMLEN); |
| |
| usage: |
| return BCME_USAGE_ERROR; |
| } |
| |
| static int |
| wl_mws_antmap(void *wl, cmd_t *cmd, char **argv) |
| { |
| uint32 val; |
| char *endptr = NULL; |
| uint argc; |
| mws_ant_map_t mws_antmap; |
| uint16 *paramsp = (uint16 *)&mws_antmap; |
| int ret, i = 0, j = 0; |
| uint16 error_mask = 0xc000; |
| uint16 ant_set[4]; |
| UNUSED_PARAMETER(cmd); |
| val = 0; |
| /* eat command name */ |
| argv++; |
| /* arg count */ |
| for (argc = 0; argv[argc]; argc++); |
| memset(&mws_antmap, '\0', sizeof(mws_antmap)); |
| if (argc == 0) { |
| /* Get and print the values */ |
| ret = wlu_iovar_getbuf(wl, "mws_antenna_selection", |
| &mws_antmap, sizeof(mws_antmap), |
| buf, WLC_IOCTL_SMLEN); |
| if (ret) |
| return ret; |
| printf("band_ant_combo1 %x band_ant_combo2 %x " |
| "band_ant_combo3 %x band_ant_combo4 %x\n", |
| dtoh16(((uint16 *)buf)[0]), dtoh16(((uint16 *)buf)[1]), |
| dtoh16(((uint16 *)buf)[2]), dtoh16(((uint16 *)buf)[3])); |
| return 0; |
| } |
| if (argc < 4) |
| goto usage; |
| for (i = 0; i < 4; ++i) { |
| val = strtoul(argv[i], &endptr, 0); |
| if (*endptr != '\0') |
| goto usage; |
| paramsp[i] = htod16((uint16)val); |
| ant_set[i] = (paramsp[i] & error_mask) >> 14; |
| for (j = 0; j < i; ++j) { |
| if (ant_set[i] == ant_set[j]) { |
| printf("duplicate band ant_tx combiniation\n"); |
| goto usage; |
| } |
| } |
| } |
| return wlu_iovar_setbuf(wl, "mws_antenna_selection", paramsp, sizeof(mws_antmap), |
| buf, WLC_IOCTL_SMLEN); |
| usage: |
| return BCME_USAGE_ERROR; |
| } |
| |
| static int |
| wl_mws_oclmap(void *wl, cmd_t *cmd, char **argv) |
| { |
| uint32 val; |
| char *endptr = NULL; |
| uint argc; |
| wl_mws_ocl_override_t mws_oclmap; |
| uint16 *paramsp = (uint16 *)&mws_oclmap; |
| int ret, i = 0; |
| UNUSED_PARAMETER(cmd); |
| val = 0; |
| /* eat command name */ |
| argv++; |
| /* arg count */ |
| for (argc = 0; argv[argc]; argc++); |
| memset(&mws_oclmap, '\0', sizeof(mws_oclmap)); |
| if (argc == 0) { |
| /* Get and print the values */ |
| ret = wlu_iovar_getbuf(wl, "mws_ocl_override", |
| &mws_oclmap, sizeof(mws_oclmap), |
| buf, WLC_IOCTL_SMLEN); |
| if (ret) |
| return ret; |
| printf(" bitmap_2g %x bitmap_5g_lo %x " |
| "babitmap_5g_mid %x bitmap_5g_high %x\n", |
| dtoh16(((uint16 *)buf)[1]), dtoh16(((uint16 *)buf)[2]), |
| dtoh16(((uint16 *)buf)[3]), dtoh16(((uint16 *)buf)[4])); |
| return 0; |
| } |
| if (argc < 4) |
| goto usage; |
| paramsp[0] = WL_MWS_OCL_OVERRIDE_VERSION; |
| for (i = 0; i < 4; ++i) { |
| val = strtoul(argv[i], &endptr, 0); |
| if (*endptr != '\0') |
| goto usage; |
| paramsp[i+1] = htod16((uint16)val); |
| } |
| return wlu_iovar_setbuf(wl, "mws_ocl_override", paramsp, sizeof(mws_oclmap), |
| buf, WLC_IOCTL_SMLEN); |
| usage: |
| return BCME_USAGE_ERROR; |
| } |
| |
| static int |
| wl_mws_scanreq_bm(void *wl, cmd_t *cmd, char **argv) |
| { |
| mws_scanreq_params_t mws_scanreq_params; |
| uint16 *paramsp = (uint16 *)&mws_scanreq_params; |
| char *endptr = NULL; |
| uint32 val; |
| uint argc, i; |
| int err; |
| |
| UNUSED_PARAMETER(cmd); |
| |
| /* eat command name */ |
| argv++; |
| |
| /* arg count */ |
| for (argc = 0; argv[argc]; argc++); |
| |
| memset(&mws_scanreq_params, 0, sizeof(mws_scanreq_params_t)); |
| |
| if (argc == 0) { |
| goto usage; |
| } else if (argc == 1) { |
| val = strtoul(argv[0], &endptr, 0); |
| if (*endptr != '\0') |
| goto usage; |
| mws_scanreq_params.idx = htod16((uint16)val); |
| |
| if ((mws_scanreq_params.idx < 1) || (mws_scanreq_params.idx > 31)) { |
| printf("LTE Index should be in range 1-31\n"); |
| goto usage; |
| } |
| |
| err = wlu_iovar_getbuf(wl, cmd->name, &mws_scanreq_params, |
| sizeof(mws_scanreq_params_t), buf, WLC_IOCTL_SMLEN); |
| if (err < 0) |
| return err; |
| mws_scanreq_params = *(mws_scanreq_params_t *)buf; |
| printf("\n Current LTE Timesharing coex : \n" |
| "\t LTE channel index = %d\n \t 2G Channel = %d \n\t 5G low channel= %d\n" |
| "\t 5G Middle channel= %d\n\t 5G High channel= %d\n", |
| mws_scanreq_params.idx, mws_scanreq_params.bm_2g, mws_scanreq_params.bm_5g_lo, |
| mws_scanreq_params.bm_5g_mid, mws_scanreq_params.bm_5g_hi); |
| return 0; |
| } else if (argc > 1 && argc < 5) { |
| goto usage; |
| } |
| memset(&mws_scanreq_params, 0, sizeof(mws_scanreq_params_t)); |
| for (i = 0; i < 5; ++i) { |
| val = strtoul(argv[i], &endptr, 0); |
| if (*endptr != '\0') |
| goto usage; |
| paramsp[i] = htod16((uint16)val); |
| } |
| |
| return wlu_iovar_setbuf(wl, "mws_scanreq_bm", &mws_scanreq_params, |
| sizeof(mws_scanreq_params_t), buf, WLC_IOCTL_SMLEN); |
| usage: |
| return BCME_USAGE_ERROR; |
| } |