diff --git a/misc_cmds.c b/misc_cmds.c index a650eaf..ba6597d 100644 --- a/misc_cmds.c +++ b/misc_cmds.c @@ -278,7 +278,7 @@ static int set_fem_manuf(struct nl80211_state *state, struct nl_cb *cb, return 0; } -COMMAND(set, fem_manuf, "<0|1> []", 0, 0, CIB_NONE, set_fem_manuf, +COMMAND(set, fem_manuf, "<0|1|2|3> []", 0, 0, CIB_NONE, set_fem_manuf, "Set FEM manufacturer"); static int get_drv_info(struct nl80211_state *state, struct nl_cb *cb, diff --git a/nvs.c b/nvs.c index 849f0b5..edde530 100644 --- a/nvs.c +++ b/nvs.c @@ -114,11 +114,10 @@ int nvs_set_mac(char *nvsfile, char *mac) return 0; } - - int nvs_fill_radio_params(int fd, struct wl12xx_ini *ini, char *buf) { struct wl1271_nvs_ini gp; + int fem_idx; if (ini) { /* Reset local NVS Radio Params */ @@ -131,16 +130,37 @@ int nvs_fill_radio_params(int fd, struct wl12xx_ini *ini, char *buf) if (gp.general_params.dual_mode_select) gp.stat_radio_params_5 = ini->ini1271.stat_radio_params_5; - gp.dyn_radio_params_2[0].params = - ini->ini1271.dyn_radio_params_2[0].params; - gp.dyn_radio_params_2[1].params = - ini->ini1271.dyn_radio_params_2[1].params; - - if (gp.general_params.dual_mode_select) { - gp.dyn_radio_params_5[0].params = - ini->ini1271.dyn_radio_params_5[0].params; - gp.dyn_radio_params_5[1].params = - ini->ini1271.dyn_radio_params_5[1].params; + if (gp.general_params.tx_bip_fem_auto_detect) { + /* For backward compatibility we fill the first 2 FEM entries */ + gp.dyn_radio_params_2[0].params = + ini->ini1271.dyn_radio_params_2[0].params; + gp.dyn_radio_params_2[1].params = + ini->ini1271.dyn_radio_params_2[1].params; + + if (gp.general_params.dual_mode_select) { + gp.dyn_radio_params_5[0].params = + ini->ini1271.dyn_radio_params_5[0].params; + gp.dyn_radio_params_5[1].params = + ini->ini1271.dyn_radio_params_5[1].params; + } + } + else { + /* + * Translate to NVS FEM entry + * In case of fem manufacturer 1 (TQS) use FEM idx 1 to maintain + * backward compatibilty. For all other types use idx 0 + */ + fem_idx = WL12XX_FEM_TO_NVS_ENTRY( + gp.general_params.tx_bip_fem_manufacturer); + + gp.dyn_radio_params_2[fem_idx].params = + ini->ini1271.dyn_radio_params_2 + [gp.general_params.tx_bip_fem_manufacturer].params; + + if (gp.general_params.dual_mode_select) + gp.dyn_radio_params_5[fem_idx].params = + ini->ini1271.dyn_radio_params_5 + [gp.general_params.tx_bip_fem_manufacturer].params; } write(fd, (const void *)&gp, sizeof(gp)); @@ -155,6 +175,7 @@ int nvs_fill_radio_params(int fd, struct wl12xx_ini *ini, char *buf) static int nvs_fill_radio_params_128x(int fd, struct wl12xx_ini *ini, char *buf) { struct wl128x_nvs_ini gp; + int fem_idx; if (ini) { /* Reset local NVS Radio Params */ @@ -168,17 +189,37 @@ static int nvs_fill_radio_params_128x(int fd, struct wl12xx_ini *ini, char *buf) if (gp.general_params.dual_mode_select) gp.stat_radio_params_5 = ini->ini128x.stat_radio_params_5; - /* For backward compatibility we fill the first 2 FEM entries */ - gp.dyn_radio_params_2[0].params = - ini->ini128x.dyn_radio_params_2[0].params; - gp.dyn_radio_params_2[1].params = - ini->ini128x.dyn_radio_params_2[1].params; - - if (gp.general_params.dual_mode_select) { - gp.dyn_radio_params_5[0].params = - ini->ini128x.dyn_radio_params_5[0].params; - gp.dyn_radio_params_5[1].params = - ini->ini128x.dyn_radio_params_5[1].params; + if (gp.general_params.tx_bip_fem_auto_detect) { + /* For backward compatibility we fill the first 2 FEM entries */ + gp.dyn_radio_params_2[0].params = + ini->ini128x.dyn_radio_params_2[0].params; + gp.dyn_radio_params_2[1].params = + ini->ini128x.dyn_radio_params_2[1].params; + + if (gp.general_params.dual_mode_select) { + gp.dyn_radio_params_5[0].params = + ini->ini128x.dyn_radio_params_5[0].params; + gp.dyn_radio_params_5[1].params = + ini->ini128x.dyn_radio_params_5[1].params; + } + } + else { + /* + * Translate to NVS FEM entry + * In case of fem manufacturer 1 (TQS) use FEM idx 1 to maintain + * backward compatibilty. For all other types use idx 0 + */ + fem_idx = WL12XX_FEM_TO_NVS_ENTRY( + gp.general_params.tx_bip_fem_manufacturer); + + gp.dyn_radio_params_2[fem_idx].params = + ini->ini128x.dyn_radio_params_2 + [gp.general_params.tx_bip_fem_manufacturer].params; + + if (gp.general_params.dual_mode_select) + gp.dyn_radio_params_5[fem_idx].params = + ini->ini128x.dyn_radio_params_5 + [gp.general_params.tx_bip_fem_manufacturer].params; } write(fd, (const void *)&gp, sizeof(gp)); @@ -1135,9 +1176,9 @@ int get_fem_nr(int autodetect, int manuf, int *femcnt, int *femi) } else { *femcnt = 1; - if(manuf >= WL12XX_NVS_FEM_MODULE_COUNT) { + if(manuf >= WL1271_INI_FEM_MODULE_COUNT) { fprintf(stderr, "FEM index out of bounds (%d > %d)\n", manuf, - WL12XX_NVS_FEM_MODULE_COUNT); + WL1271_INI_FEM_MODULE_COUNT); return 1; } diff --git a/plt.c b/plt.c index c120ecf..01e7f91 100644 --- a/plt.c +++ b/plt.c @@ -1034,20 +1034,20 @@ static int plt_autocalibrate(struct nl80211_state *state, struct nl_cb *cb, goto out_removenvs; } - fems_parsed = cmn.fem0_bands + cmn.fem1_bands; + fems_parsed = cmn.fem0_bands + cmn.fem1_bands + cmn.fem2_bands + cmn.fem3_bands; /* Get nr bands from parsed ini */ single_dual = ini_get_dual_mode(&cmn); if (single_dual == 0) { - if (fems_parsed < 1 || fems_parsed > 2) { + if (fems_parsed < 1 || fems_parsed > 4) { fprintf(stderr, "Incorrect number of FEM sections %d for single mode\n", fems_parsed); return 1; } } else if (single_dual == 1) { - if (fems_parsed < 2 && fems_parsed > 4) { + if (fems_parsed < 2 && fems_parsed > 8) { fprintf(stderr, "Incorrect number of FEM sections %d for dual mode\n", fems_parsed); return 1; @@ -1060,8 +1060,15 @@ static int plt_autocalibrate(struct nl80211_state *state, struct nl_cb *cb, } /* I suppose you can have one FEM with 2.4 only and one in dual band - but it's more likely a mistake */ - if ((single_dual + 1) * (cmn.auto_fem + 1) != fems_parsed) { + but it's more likely a mistake. + + In normal situation we have: + ---------------------------- + Single Band Manual - 1 FEM + Dual Band Manual - 2 FEMs + Single Band Auto Fem - 4 FEMs + Dual Band Auto Fem - 8 FEMs */ + if ((single_dual + 1) * (cmn.auto_fem * 3 + 1) != fems_parsed) { printf("WARNING: %d FEMS for %d bands with autofem %s looks " "like a strange configuration\n", fems_parsed, single_dual + 1, @@ -1115,6 +1122,12 @@ static int plt_autocalibrate(struct nl80211_state *state, struct nl_cb *cb, if (cmn.fem1_bands) { printf("FEM1 has %d bands. ", cmn.fem1_bands); } + if (cmn.fem2_bands) { + printf("FEM2 has %d bands. ", cmn.fem2_bands); + } + if (cmn.fem3_bands) { + printf("FEM3 has %d bands. ", cmn.fem3_bands); + } printf("AutoFEM is %s. ", cmn.auto_fem ? "on" : "off");