if (wl->nvs == NULL)
return -ENODEV;
- /*
- * FIXME: the LEGACY NVS image support (NVS's missing the 5GHz band
- * configurations) can be removed when those NVS files stop floating
- * around.
- */
- if (wl->nvs_len == sizeof(struct wl1271_nvs_file) ||
- wl->nvs_len == WL1271_INI_LEGACY_NVS_FILE_SIZE) {
- /* for now 11a is unsupported in AP mode */
- if (wl->bss_type != BSS_TYPE_AP_BSS &&
- wl->nvs->general_params.dual_mode_select)
- wl->enable_11a = true;
- }
+ if (wl->chip.id == CHIP_ID_1283_PG20) {
+ struct wl128x_nvs_file *nvs = (struct wl128x_nvs_file *)wl->nvs;
+
+ if (wl->nvs_len == sizeof(struct wl128x_nvs_file)) {
+ if (nvs->general_params.dual_mode_select)
+ wl->enable_11a = true;
+ } else {
+ wl1271_error("nvs size is not as expected: %zu != %zu",
+ wl->nvs_len,
+ sizeof(struct wl128x_nvs_file));
+ kfree(wl->nvs);
+ wl->nvs = NULL;
+ wl->nvs_len = 0;
+ return -EILSEQ;
+ }
- if (wl->nvs_len != sizeof(struct wl1271_nvs_file) &&
- (wl->nvs_len != WL1271_INI_LEGACY_NVS_FILE_SIZE ||
- wl->enable_11a)) {
- wl1271_error("nvs size is not as expected: %zu != %zu",
- wl->nvs_len, sizeof(struct wl1271_nvs_file));
- kfree(wl->nvs);
- wl->nvs = NULL;
- wl->nvs_len = 0;
- return -EILSEQ;
- }
+ /* only the first part of the NVS needs to be uploaded */
+ nvs_len = sizeof(nvs->nvs);
+ nvs_ptr = (u8 *)nvs->nvs;
- /* only the first part of the NVS needs to be uploaded */
- nvs_len = sizeof(wl->nvs->nvs);
- nvs_ptr = (u8 *)wl->nvs->nvs;
+ } else {
+ struct wl1271_nvs_file *nvs =
+ (struct wl1271_nvs_file *)wl->nvs;
+ /*
+ * FIXME: the LEGACY NVS image support (NVS's missing the 5GHz
+ * band configurations) can be removed when those NVS files stop
+ * floating around.
+ */
+ if (wl->nvs_len == sizeof(struct wl1271_nvs_file) ||
+ wl->nvs_len == WL1271_INI_LEGACY_NVS_FILE_SIZE) {
+ /* for now 11a is unsupported in AP mode */
+ if (wl->bss_type != BSS_TYPE_AP_BSS &&
+ nvs->general_params.dual_mode_select)
+ wl->enable_11a = true;
+ }
+
+ if (wl->nvs_len != sizeof(struct wl1271_nvs_file) &&
+ (wl->nvs_len != WL1271_INI_LEGACY_NVS_FILE_SIZE ||
+ wl->enable_11a)) {
+ wl1271_error("nvs size is not as expected: %zu != %zu",
+ wl->nvs_len, sizeof(struct wl1271_nvs_file));
+ kfree(wl->nvs);
+ wl->nvs = NULL;
+ wl->nvs_len = 0;
+ return -EILSEQ;
+ }
+
+ /* only the first part of the NVS needs to be uploaded */
+ nvs_len = sizeof(nvs->nvs);
+ nvs_ptr = (u8 *) nvs->nvs;
+ }
/* update current MAC address to NVS */
nvs_ptr[11] = wl->mac_addr[0];
/*
* We've reached the first zero length, the first NVS table
* is located at an aligned offset which is at least 7 bytes further.
+ * NOTE: The wl->nvs->nvs element must be first, in order to
+ * simplify the casting, we assume it is at the beginning of
+ * the wl->nvs structure.
*/
- nvs_ptr = (u8 *)wl->nvs->nvs +
- ALIGN(nvs_ptr - (u8 *)wl->nvs->nvs + 7, 4);
- nvs_len -= nvs_ptr - (u8 *)wl->nvs->nvs;
+ nvs_ptr = (u8 *)wl->nvs +
+ ALIGN(nvs_ptr - (u8 *)wl->nvs + 7, 4);
+ nvs_len -= nvs_ptr - (u8 *)wl->nvs;
/* Now we must set the partition correctly */
wl1271_set_partition(wl, &part_table[PART_WORK]);
int wl1271_cmd_radio_parms(struct wl1271 *wl)
{
+ struct wl1271_nvs_file *nvs = (struct wl1271_nvs_file *)wl->nvs;
struct wl1271_radio_parms_cmd *radio_parms;
- struct wl1271_ini_general_params *gp = &wl->nvs->general_params;
+ struct wl1271_ini_general_params *gp = &nvs->general_params;
int ret;
if (!wl->nvs)
radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM;
/* 2.4GHz parameters */
- memcpy(&radio_parms->static_params_2, &wl->nvs->stat_radio_params_2,
+ memcpy(&radio_parms->static_params_2, &nvs->stat_radio_params_2,
sizeof(struct wl1271_ini_band_params_2));
memcpy(&radio_parms->dyn_params_2,
- &wl->nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params,
+ &nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params,
sizeof(struct wl1271_ini_fem_params_2));
/* 5GHz parameters */
memcpy(&radio_parms->static_params_5,
- &wl->nvs->stat_radio_params_5,
+ &nvs->stat_radio_params_5,
sizeof(struct wl1271_ini_band_params_5));
memcpy(&radio_parms->dyn_params_5,
- &wl->nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params,
+ &nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params,
sizeof(struct wl1271_ini_fem_params_5));
wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ",
#define WL1271_INI_LEGACY_NVS_FILE_SIZE 800
struct wl1271_nvs_file {
- /* NVS section */
+ /* NVS section - must be first! */
u8 nvs[WL1271_INI_NVS_SECTION_SIZE];
/* INI section */
} __packed;
struct wl128x_nvs_file {
- /* NVS section */
+ /* NVS section - must be first! */
u8 nvs[WL1271_INI_NVS_SECTION_SIZE];
/* INI section */
break;
case BSS_TYPE_IBSS:
case BSS_TYPE_STA_BSS:
- fw_name = WL1271_FW_NAME;
+ if (wl->chip.id == CHIP_ID_1283_PG20)
+ fw_name = WL128X_FW_NAME;
+ else
+ fw_name = WL1271_FW_NAME;
break;
default:
wl1271_error("no compatible firmware for bss_type %d",
return ret;
}
- wl->nvs = kmemdup(fw->data, sizeof(struct wl1271_nvs_file), GFP_KERNEL);
+ wl->nvs = kmemdup(fw->data, fw->size, GFP_KERNEL);
if (!wl->nvs) {
wl1271_error("could not allocate memory for the nvs file");
ret = wl1271_fetch_nvs(wl);
if (ret == 0) {
- u8 *nvs_ptr = (u8 *)wl->nvs->nvs;
+ /* NOTE: The wl->nvs->nvs element must be first, in
+ * order to simplify the casting, we assume it is at
+ * the beginning of the wl->nvs structure.
+ */
+ u8 *nvs_ptr = (u8 *)wl->nvs;
wl->mac_addr[0] = nvs_ptr[11];
wl->mac_addr[1] = nvs_ptr[10];
const struct firmware *fw;
int ret;
- ret = request_firmware(&fw, WL1271_FW_NAME, wl1271_wl_to_dev(wl));
+ if (wl->chip.id == CHIP_ID_1283_PG20)
+ ret = request_firmware(&fw, WL128X_FW_NAME,
+ wl1271_wl_to_dev(wl));
+ else
+ ret = request_firmware(&fw, WL1271_FW_NAME,
+ wl1271_wl_to_dev(wl));
if (ret < 0) {
wl1271_error("could not get firmware: %d", ret);
return ret;
}
- wl->nvs = kmemdup(fw->data, sizeof(struct wl1271_nvs_file), GFP_KERNEL);
+ wl->nvs = kmemdup(fw->data, fw->size, GFP_KERNEL);
if (!wl->nvs) {
wl1271_error("could not allocate memory for the nvs file");
#include "wl12xx.h"
#include "acx.h"
+#include "reg.h"
#define WL1271_TM_MAX_DATA_LENGTH 1024
kfree(wl->nvs);
- if (len != sizeof(struct wl1271_nvs_file))
+ if ((wl->chip.id == CHIP_ID_1283_PG20) &&
+ (len != sizeof(struct wl128x_nvs_file)))
+ return -EINVAL;
+ else if (len != sizeof(struct wl1271_nvs_file))
return -EINVAL;
wl->nvs = kzalloc(len, GFP_KERNEL);
u8 *fw;
size_t fw_len;
u8 fw_bss_type;
- struct wl1271_nvs_file *nvs;
+ void *nvs;
size_t nvs_len;
s8 hw_pg_ver;