|
@@ -19,6 +19,7 @@
|
|
#include <linux/module.h>
|
|
#include <linux/module.h>
|
|
#include <linux/firmware.h>
|
|
#include <linux/firmware.h>
|
|
#include <linux/of.h>
|
|
#include <linux/of.h>
|
|
|
|
+#include <linux/property.h>
|
|
#include <linux/dmi.h>
|
|
#include <linux/dmi.h>
|
|
#include <linux/ctype.h>
|
|
#include <linux/ctype.h>
|
|
#include <asm/byteorder.h>
|
|
#include <asm/byteorder.h>
|
|
@@ -63,6 +64,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|
{
|
|
{
|
|
.id = QCA988X_HW_2_0_VERSION,
|
|
.id = QCA988X_HW_2_0_VERSION,
|
|
.dev_id = QCA988X_2_0_DEVICE_ID,
|
|
.dev_id = QCA988X_2_0_DEVICE_ID,
|
|
|
|
+ .bus = ATH10K_BUS_PCI,
|
|
.name = "qca988x hw2.0",
|
|
.name = "qca988x hw2.0",
|
|
.patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR,
|
|
.patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR,
|
|
.uart_pin = 7,
|
|
.uart_pin = 7,
|
|
@@ -84,7 +86,6 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|
.vht160_mcs_rx_highest = 0,
|
|
.vht160_mcs_rx_highest = 0,
|
|
.vht160_mcs_tx_highest = 0,
|
|
.vht160_mcs_tx_highest = 0,
|
|
.n_cipher_suites = 8,
|
|
.n_cipher_suites = 8,
|
|
- .num_peers = TARGET_TLV_NUM_PEERS,
|
|
|
|
.ast_skid_limit = 0x10,
|
|
.ast_skid_limit = 0x10,
|
|
.num_wds_entries = 0x20,
|
|
.num_wds_entries = 0x20,
|
|
.target_64bit = false,
|
|
.target_64bit = false,
|
|
@@ -92,6 +93,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|
.shadow_reg_support = false,
|
|
.shadow_reg_support = false,
|
|
.rri_on_ddr = false,
|
|
.rri_on_ddr = false,
|
|
.hw_filter_reset_required = true,
|
|
.hw_filter_reset_required = true,
|
|
|
|
+ .fw_diag_ce_download = false,
|
|
},
|
|
},
|
|
{
|
|
{
|
|
.id = QCA988X_HW_2_0_VERSION,
|
|
.id = QCA988X_HW_2_0_VERSION,
|
|
@@ -117,7 +119,6 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|
.vht160_mcs_rx_highest = 0,
|
|
.vht160_mcs_rx_highest = 0,
|
|
.vht160_mcs_tx_highest = 0,
|
|
.vht160_mcs_tx_highest = 0,
|
|
.n_cipher_suites = 8,
|
|
.n_cipher_suites = 8,
|
|
- .num_peers = TARGET_TLV_NUM_PEERS,
|
|
|
|
.ast_skid_limit = 0x10,
|
|
.ast_skid_limit = 0x10,
|
|
.num_wds_entries = 0x20,
|
|
.num_wds_entries = 0x20,
|
|
.target_64bit = false,
|
|
.target_64bit = false,
|
|
@@ -126,10 +127,12 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|
.shadow_reg_support = false,
|
|
.shadow_reg_support = false,
|
|
.rri_on_ddr = false,
|
|
.rri_on_ddr = false,
|
|
.hw_filter_reset_required = true,
|
|
.hw_filter_reset_required = true,
|
|
|
|
+ .fw_diag_ce_download = false,
|
|
},
|
|
},
|
|
{
|
|
{
|
|
.id = QCA9887_HW_1_0_VERSION,
|
|
.id = QCA9887_HW_1_0_VERSION,
|
|
.dev_id = QCA9887_1_0_DEVICE_ID,
|
|
.dev_id = QCA9887_1_0_DEVICE_ID,
|
|
|
|
+ .bus = ATH10K_BUS_PCI,
|
|
.name = "qca9887 hw1.0",
|
|
.name = "qca9887 hw1.0",
|
|
.patch_load_addr = QCA9887_HW_1_0_PATCH_LOAD_ADDR,
|
|
.patch_load_addr = QCA9887_HW_1_0_PATCH_LOAD_ADDR,
|
|
.uart_pin = 7,
|
|
.uart_pin = 7,
|
|
@@ -151,7 +154,6 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|
.vht160_mcs_rx_highest = 0,
|
|
.vht160_mcs_rx_highest = 0,
|
|
.vht160_mcs_tx_highest = 0,
|
|
.vht160_mcs_tx_highest = 0,
|
|
.n_cipher_suites = 8,
|
|
.n_cipher_suites = 8,
|
|
- .num_peers = TARGET_TLV_NUM_PEERS,
|
|
|
|
.ast_skid_limit = 0x10,
|
|
.ast_skid_limit = 0x10,
|
|
.num_wds_entries = 0x20,
|
|
.num_wds_entries = 0x20,
|
|
.target_64bit = false,
|
|
.target_64bit = false,
|
|
@@ -160,10 +162,12 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|
.shadow_reg_support = false,
|
|
.shadow_reg_support = false,
|
|
.rri_on_ddr = false,
|
|
.rri_on_ddr = false,
|
|
.hw_filter_reset_required = true,
|
|
.hw_filter_reset_required = true,
|
|
|
|
+ .fw_diag_ce_download = false,
|
|
},
|
|
},
|
|
{
|
|
{
|
|
.id = QCA6174_HW_2_1_VERSION,
|
|
.id = QCA6174_HW_2_1_VERSION,
|
|
.dev_id = QCA6164_2_1_DEVICE_ID,
|
|
.dev_id = QCA6164_2_1_DEVICE_ID,
|
|
|
|
+ .bus = ATH10K_BUS_PCI,
|
|
.name = "qca6164 hw2.1",
|
|
.name = "qca6164 hw2.1",
|
|
.patch_load_addr = QCA6174_HW_2_1_PATCH_LOAD_ADDR,
|
|
.patch_load_addr = QCA6174_HW_2_1_PATCH_LOAD_ADDR,
|
|
.uart_pin = 6,
|
|
.uart_pin = 6,
|
|
@@ -184,7 +188,6 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|
.vht160_mcs_rx_highest = 0,
|
|
.vht160_mcs_rx_highest = 0,
|
|
.vht160_mcs_tx_highest = 0,
|
|
.vht160_mcs_tx_highest = 0,
|
|
.n_cipher_suites = 8,
|
|
.n_cipher_suites = 8,
|
|
- .num_peers = TARGET_TLV_NUM_PEERS,
|
|
|
|
.ast_skid_limit = 0x10,
|
|
.ast_skid_limit = 0x10,
|
|
.num_wds_entries = 0x20,
|
|
.num_wds_entries = 0x20,
|
|
.target_64bit = false,
|
|
.target_64bit = false,
|
|
@@ -193,10 +196,12 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|
.shadow_reg_support = false,
|
|
.shadow_reg_support = false,
|
|
.rri_on_ddr = false,
|
|
.rri_on_ddr = false,
|
|
.hw_filter_reset_required = true,
|
|
.hw_filter_reset_required = true,
|
|
|
|
+ .fw_diag_ce_download = false,
|
|
},
|
|
},
|
|
{
|
|
{
|
|
.id = QCA6174_HW_2_1_VERSION,
|
|
.id = QCA6174_HW_2_1_VERSION,
|
|
.dev_id = QCA6174_2_1_DEVICE_ID,
|
|
.dev_id = QCA6174_2_1_DEVICE_ID,
|
|
|
|
+ .bus = ATH10K_BUS_PCI,
|
|
.name = "qca6174 hw2.1",
|
|
.name = "qca6174 hw2.1",
|
|
.patch_load_addr = QCA6174_HW_2_1_PATCH_LOAD_ADDR,
|
|
.patch_load_addr = QCA6174_HW_2_1_PATCH_LOAD_ADDR,
|
|
.uart_pin = 6,
|
|
.uart_pin = 6,
|
|
@@ -217,7 +222,6 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|
.vht160_mcs_rx_highest = 0,
|
|
.vht160_mcs_rx_highest = 0,
|
|
.vht160_mcs_tx_highest = 0,
|
|
.vht160_mcs_tx_highest = 0,
|
|
.n_cipher_suites = 8,
|
|
.n_cipher_suites = 8,
|
|
- .num_peers = TARGET_TLV_NUM_PEERS,
|
|
|
|
.ast_skid_limit = 0x10,
|
|
.ast_skid_limit = 0x10,
|
|
.num_wds_entries = 0x20,
|
|
.num_wds_entries = 0x20,
|
|
.target_64bit = false,
|
|
.target_64bit = false,
|
|
@@ -226,10 +230,12 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|
.shadow_reg_support = false,
|
|
.shadow_reg_support = false,
|
|
.rri_on_ddr = false,
|
|
.rri_on_ddr = false,
|
|
.hw_filter_reset_required = true,
|
|
.hw_filter_reset_required = true,
|
|
|
|
+ .fw_diag_ce_download = false,
|
|
},
|
|
},
|
|
{
|
|
{
|
|
.id = QCA6174_HW_3_0_VERSION,
|
|
.id = QCA6174_HW_3_0_VERSION,
|
|
.dev_id = QCA6174_2_1_DEVICE_ID,
|
|
.dev_id = QCA6174_2_1_DEVICE_ID,
|
|
|
|
+ .bus = ATH10K_BUS_PCI,
|
|
.name = "qca6174 hw3.0",
|
|
.name = "qca6174 hw3.0",
|
|
.patch_load_addr = QCA6174_HW_3_0_PATCH_LOAD_ADDR,
|
|
.patch_load_addr = QCA6174_HW_3_0_PATCH_LOAD_ADDR,
|
|
.uart_pin = 6,
|
|
.uart_pin = 6,
|
|
@@ -250,7 +256,6 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|
.vht160_mcs_rx_highest = 0,
|
|
.vht160_mcs_rx_highest = 0,
|
|
.vht160_mcs_tx_highest = 0,
|
|
.vht160_mcs_tx_highest = 0,
|
|
.n_cipher_suites = 8,
|
|
.n_cipher_suites = 8,
|
|
- .num_peers = TARGET_TLV_NUM_PEERS,
|
|
|
|
.ast_skid_limit = 0x10,
|
|
.ast_skid_limit = 0x10,
|
|
.num_wds_entries = 0x20,
|
|
.num_wds_entries = 0x20,
|
|
.target_64bit = false,
|
|
.target_64bit = false,
|
|
@@ -259,10 +264,12 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|
.shadow_reg_support = false,
|
|
.shadow_reg_support = false,
|
|
.rri_on_ddr = false,
|
|
.rri_on_ddr = false,
|
|
.hw_filter_reset_required = true,
|
|
.hw_filter_reset_required = true,
|
|
|
|
+ .fw_diag_ce_download = false,
|
|
},
|
|
},
|
|
{
|
|
{
|
|
.id = QCA6174_HW_3_2_VERSION,
|
|
.id = QCA6174_HW_3_2_VERSION,
|
|
.dev_id = QCA6174_2_1_DEVICE_ID,
|
|
.dev_id = QCA6174_2_1_DEVICE_ID,
|
|
|
|
+ .bus = ATH10K_BUS_PCI,
|
|
.name = "qca6174 hw3.2",
|
|
.name = "qca6174 hw3.2",
|
|
.patch_load_addr = QCA6174_HW_3_0_PATCH_LOAD_ADDR,
|
|
.patch_load_addr = QCA6174_HW_3_0_PATCH_LOAD_ADDR,
|
|
.uart_pin = 6,
|
|
.uart_pin = 6,
|
|
@@ -286,7 +293,6 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|
.vht160_mcs_rx_highest = 0,
|
|
.vht160_mcs_rx_highest = 0,
|
|
.vht160_mcs_tx_highest = 0,
|
|
.vht160_mcs_tx_highest = 0,
|
|
.n_cipher_suites = 8,
|
|
.n_cipher_suites = 8,
|
|
- .num_peers = TARGET_TLV_NUM_PEERS,
|
|
|
|
.ast_skid_limit = 0x10,
|
|
.ast_skid_limit = 0x10,
|
|
.num_wds_entries = 0x20,
|
|
.num_wds_entries = 0x20,
|
|
.target_64bit = false,
|
|
.target_64bit = false,
|
|
@@ -295,10 +301,12 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|
.shadow_reg_support = false,
|
|
.shadow_reg_support = false,
|
|
.rri_on_ddr = false,
|
|
.rri_on_ddr = false,
|
|
.hw_filter_reset_required = true,
|
|
.hw_filter_reset_required = true,
|
|
|
|
+ .fw_diag_ce_download = true,
|
|
},
|
|
},
|
|
{
|
|
{
|
|
.id = QCA99X0_HW_2_0_DEV_VERSION,
|
|
.id = QCA99X0_HW_2_0_DEV_VERSION,
|
|
.dev_id = QCA99X0_2_0_DEVICE_ID,
|
|
.dev_id = QCA99X0_2_0_DEVICE_ID,
|
|
|
|
+ .bus = ATH10K_BUS_PCI,
|
|
.name = "qca99x0 hw2.0",
|
|
.name = "qca99x0 hw2.0",
|
|
.patch_load_addr = QCA99X0_HW_2_0_PATCH_LOAD_ADDR,
|
|
.patch_load_addr = QCA99X0_HW_2_0_PATCH_LOAD_ADDR,
|
|
.uart_pin = 7,
|
|
.uart_pin = 7,
|
|
@@ -325,7 +333,6 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|
.vht160_mcs_rx_highest = 0,
|
|
.vht160_mcs_rx_highest = 0,
|
|
.vht160_mcs_tx_highest = 0,
|
|
.vht160_mcs_tx_highest = 0,
|
|
.n_cipher_suites = 11,
|
|
.n_cipher_suites = 11,
|
|
- .num_peers = TARGET_TLV_NUM_PEERS,
|
|
|
|
.ast_skid_limit = 0x10,
|
|
.ast_skid_limit = 0x10,
|
|
.num_wds_entries = 0x20,
|
|
.num_wds_entries = 0x20,
|
|
.target_64bit = false,
|
|
.target_64bit = false,
|
|
@@ -334,10 +341,12 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|
.shadow_reg_support = false,
|
|
.shadow_reg_support = false,
|
|
.rri_on_ddr = false,
|
|
.rri_on_ddr = false,
|
|
.hw_filter_reset_required = true,
|
|
.hw_filter_reset_required = true,
|
|
|
|
+ .fw_diag_ce_download = false,
|
|
},
|
|
},
|
|
{
|
|
{
|
|
.id = QCA9984_HW_1_0_DEV_VERSION,
|
|
.id = QCA9984_HW_1_0_DEV_VERSION,
|
|
.dev_id = QCA9984_1_0_DEVICE_ID,
|
|
.dev_id = QCA9984_1_0_DEVICE_ID,
|
|
|
|
+ .bus = ATH10K_BUS_PCI,
|
|
.name = "qca9984/qca9994 hw1.0",
|
|
.name = "qca9984/qca9994 hw1.0",
|
|
.patch_load_addr = QCA9984_HW_1_0_PATCH_LOAD_ADDR,
|
|
.patch_load_addr = QCA9984_HW_1_0_PATCH_LOAD_ADDR,
|
|
.uart_pin = 7,
|
|
.uart_pin = 7,
|
|
@@ -354,8 +363,10 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|
.fw = {
|
|
.fw = {
|
|
.dir = QCA9984_HW_1_0_FW_DIR,
|
|
.dir = QCA9984_HW_1_0_FW_DIR,
|
|
.board = QCA9984_HW_1_0_BOARD_DATA_FILE,
|
|
.board = QCA9984_HW_1_0_BOARD_DATA_FILE,
|
|
|
|
+ .eboard = QCA9984_HW_1_0_EBOARD_DATA_FILE,
|
|
.board_size = QCA99X0_BOARD_DATA_SZ,
|
|
.board_size = QCA99X0_BOARD_DATA_SZ,
|
|
.board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ,
|
|
.board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ,
|
|
|
|
+ .ext_board_size = QCA99X0_EXT_BOARD_DATA_SZ,
|
|
},
|
|
},
|
|
.sw_decrypt_mcast_mgmt = true,
|
|
.sw_decrypt_mcast_mgmt = true,
|
|
.hw_ops = &qca99x0_ops,
|
|
.hw_ops = &qca99x0_ops,
|
|
@@ -369,7 +380,6 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|
.vht160_mcs_rx_highest = 1560,
|
|
.vht160_mcs_rx_highest = 1560,
|
|
.vht160_mcs_tx_highest = 1560,
|
|
.vht160_mcs_tx_highest = 1560,
|
|
.n_cipher_suites = 11,
|
|
.n_cipher_suites = 11,
|
|
- .num_peers = TARGET_TLV_NUM_PEERS,
|
|
|
|
.ast_skid_limit = 0x10,
|
|
.ast_skid_limit = 0x10,
|
|
.num_wds_entries = 0x20,
|
|
.num_wds_entries = 0x20,
|
|
.target_64bit = false,
|
|
.target_64bit = false,
|
|
@@ -378,10 +388,12 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|
.shadow_reg_support = false,
|
|
.shadow_reg_support = false,
|
|
.rri_on_ddr = false,
|
|
.rri_on_ddr = false,
|
|
.hw_filter_reset_required = true,
|
|
.hw_filter_reset_required = true,
|
|
|
|
+ .fw_diag_ce_download = false,
|
|
},
|
|
},
|
|
{
|
|
{
|
|
.id = QCA9888_HW_2_0_DEV_VERSION,
|
|
.id = QCA9888_HW_2_0_DEV_VERSION,
|
|
.dev_id = QCA9888_2_0_DEVICE_ID,
|
|
.dev_id = QCA9888_2_0_DEVICE_ID,
|
|
|
|
+ .bus = ATH10K_BUS_PCI,
|
|
.name = "qca9888 hw2.0",
|
|
.name = "qca9888 hw2.0",
|
|
.patch_load_addr = QCA9888_HW_2_0_PATCH_LOAD_ADDR,
|
|
.patch_load_addr = QCA9888_HW_2_0_PATCH_LOAD_ADDR,
|
|
.uart_pin = 7,
|
|
.uart_pin = 7,
|
|
@@ -412,7 +424,6 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|
.vht160_mcs_rx_highest = 780,
|
|
.vht160_mcs_rx_highest = 780,
|
|
.vht160_mcs_tx_highest = 780,
|
|
.vht160_mcs_tx_highest = 780,
|
|
.n_cipher_suites = 11,
|
|
.n_cipher_suites = 11,
|
|
- .num_peers = TARGET_TLV_NUM_PEERS,
|
|
|
|
.ast_skid_limit = 0x10,
|
|
.ast_skid_limit = 0x10,
|
|
.num_wds_entries = 0x20,
|
|
.num_wds_entries = 0x20,
|
|
.target_64bit = false,
|
|
.target_64bit = false,
|
|
@@ -421,10 +432,12 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|
.shadow_reg_support = false,
|
|
.shadow_reg_support = false,
|
|
.rri_on_ddr = false,
|
|
.rri_on_ddr = false,
|
|
.hw_filter_reset_required = true,
|
|
.hw_filter_reset_required = true,
|
|
|
|
+ .fw_diag_ce_download = false,
|
|
},
|
|
},
|
|
{
|
|
{
|
|
.id = QCA9377_HW_1_0_DEV_VERSION,
|
|
.id = QCA9377_HW_1_0_DEV_VERSION,
|
|
.dev_id = QCA9377_1_0_DEVICE_ID,
|
|
.dev_id = QCA9377_1_0_DEVICE_ID,
|
|
|
|
+ .bus = ATH10K_BUS_PCI,
|
|
.name = "qca9377 hw1.0",
|
|
.name = "qca9377 hw1.0",
|
|
.patch_load_addr = QCA9377_HW_1_0_PATCH_LOAD_ADDR,
|
|
.patch_load_addr = QCA9377_HW_1_0_PATCH_LOAD_ADDR,
|
|
.uart_pin = 6,
|
|
.uart_pin = 6,
|
|
@@ -445,7 +458,6 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|
.vht160_mcs_rx_highest = 0,
|
|
.vht160_mcs_rx_highest = 0,
|
|
.vht160_mcs_tx_highest = 0,
|
|
.vht160_mcs_tx_highest = 0,
|
|
.n_cipher_suites = 8,
|
|
.n_cipher_suites = 8,
|
|
- .num_peers = TARGET_TLV_NUM_PEERS,
|
|
|
|
.ast_skid_limit = 0x10,
|
|
.ast_skid_limit = 0x10,
|
|
.num_wds_entries = 0x20,
|
|
.num_wds_entries = 0x20,
|
|
.target_64bit = false,
|
|
.target_64bit = false,
|
|
@@ -454,10 +466,12 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|
.shadow_reg_support = false,
|
|
.shadow_reg_support = false,
|
|
.rri_on_ddr = false,
|
|
.rri_on_ddr = false,
|
|
.hw_filter_reset_required = true,
|
|
.hw_filter_reset_required = true,
|
|
|
|
+ .fw_diag_ce_download = false,
|
|
},
|
|
},
|
|
{
|
|
{
|
|
.id = QCA9377_HW_1_1_DEV_VERSION,
|
|
.id = QCA9377_HW_1_1_DEV_VERSION,
|
|
.dev_id = QCA9377_1_0_DEVICE_ID,
|
|
.dev_id = QCA9377_1_0_DEVICE_ID,
|
|
|
|
+ .bus = ATH10K_BUS_PCI,
|
|
.name = "qca9377 hw1.1",
|
|
.name = "qca9377 hw1.1",
|
|
.patch_load_addr = QCA9377_HW_1_0_PATCH_LOAD_ADDR,
|
|
.patch_load_addr = QCA9377_HW_1_0_PATCH_LOAD_ADDR,
|
|
.uart_pin = 6,
|
|
.uart_pin = 6,
|
|
@@ -480,7 +494,6 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|
.vht160_mcs_rx_highest = 0,
|
|
.vht160_mcs_rx_highest = 0,
|
|
.vht160_mcs_tx_highest = 0,
|
|
.vht160_mcs_tx_highest = 0,
|
|
.n_cipher_suites = 8,
|
|
.n_cipher_suites = 8,
|
|
- .num_peers = TARGET_TLV_NUM_PEERS,
|
|
|
|
.ast_skid_limit = 0x10,
|
|
.ast_skid_limit = 0x10,
|
|
.num_wds_entries = 0x20,
|
|
.num_wds_entries = 0x20,
|
|
.target_64bit = false,
|
|
.target_64bit = false,
|
|
@@ -489,10 +502,12 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|
.shadow_reg_support = false,
|
|
.shadow_reg_support = false,
|
|
.rri_on_ddr = false,
|
|
.rri_on_ddr = false,
|
|
.hw_filter_reset_required = true,
|
|
.hw_filter_reset_required = true,
|
|
|
|
+ .fw_diag_ce_download = true,
|
|
},
|
|
},
|
|
{
|
|
{
|
|
.id = QCA4019_HW_1_0_DEV_VERSION,
|
|
.id = QCA4019_HW_1_0_DEV_VERSION,
|
|
.dev_id = 0,
|
|
.dev_id = 0,
|
|
|
|
+ .bus = ATH10K_BUS_AHB,
|
|
.name = "qca4019 hw1.0",
|
|
.name = "qca4019 hw1.0",
|
|
.patch_load_addr = QCA4019_HW_1_0_PATCH_LOAD_ADDR,
|
|
.patch_load_addr = QCA4019_HW_1_0_PATCH_LOAD_ADDR,
|
|
.uart_pin = 7,
|
|
.uart_pin = 7,
|
|
@@ -520,7 +535,6 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|
.vht160_mcs_rx_highest = 0,
|
|
.vht160_mcs_rx_highest = 0,
|
|
.vht160_mcs_tx_highest = 0,
|
|
.vht160_mcs_tx_highest = 0,
|
|
.n_cipher_suites = 11,
|
|
.n_cipher_suites = 11,
|
|
- .num_peers = TARGET_TLV_NUM_PEERS,
|
|
|
|
.ast_skid_limit = 0x10,
|
|
.ast_skid_limit = 0x10,
|
|
.num_wds_entries = 0x20,
|
|
.num_wds_entries = 0x20,
|
|
.target_64bit = false,
|
|
.target_64bit = false,
|
|
@@ -529,10 +543,12 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|
.shadow_reg_support = false,
|
|
.shadow_reg_support = false,
|
|
.rri_on_ddr = false,
|
|
.rri_on_ddr = false,
|
|
.hw_filter_reset_required = true,
|
|
.hw_filter_reset_required = true,
|
|
|
|
+ .fw_diag_ce_download = false,
|
|
},
|
|
},
|
|
{
|
|
{
|
|
.id = WCN3990_HW_1_0_DEV_VERSION,
|
|
.id = WCN3990_HW_1_0_DEV_VERSION,
|
|
.dev_id = 0,
|
|
.dev_id = 0,
|
|
|
|
+ .bus = ATH10K_BUS_PCI,
|
|
.name = "wcn3990 hw1.0",
|
|
.name = "wcn3990 hw1.0",
|
|
.continuous_frag_desc = true,
|
|
.continuous_frag_desc = true,
|
|
.tx_chain_mask = 0x7,
|
|
.tx_chain_mask = 0x7,
|
|
@@ -553,6 +569,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|
.shadow_reg_support = true,
|
|
.shadow_reg_support = true,
|
|
.rri_on_ddr = true,
|
|
.rri_on_ddr = true,
|
|
.hw_filter_reset_required = false,
|
|
.hw_filter_reset_required = false,
|
|
|
|
+ .fw_diag_ce_download = false,
|
|
},
|
|
},
|
|
};
|
|
};
|
|
|
|
|
|
@@ -776,153 +793,11 @@ static int ath10k_push_board_ext_data(struct ath10k *ar, const void *data,
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-static int ath10k_download_board_data(struct ath10k *ar, const void *data,
|
|
|
|
- size_t data_len)
|
|
|
|
-{
|
|
|
|
- u32 board_data_size = ar->hw_params.fw.board_size;
|
|
|
|
- u32 address;
|
|
|
|
- int ret;
|
|
|
|
-
|
|
|
|
- ret = ath10k_push_board_ext_data(ar, data, data_len);
|
|
|
|
- if (ret) {
|
|
|
|
- ath10k_err(ar, "could not push board ext data (%d)\n", ret);
|
|
|
|
- goto exit;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- ret = ath10k_bmi_read32(ar, hi_board_data, &address);
|
|
|
|
- if (ret) {
|
|
|
|
- ath10k_err(ar, "could not read board data addr (%d)\n", ret);
|
|
|
|
- goto exit;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- ret = ath10k_bmi_write_memory(ar, address, data,
|
|
|
|
- min_t(u32, board_data_size,
|
|
|
|
- data_len));
|
|
|
|
- if (ret) {
|
|
|
|
- ath10k_err(ar, "could not write board data (%d)\n", ret);
|
|
|
|
- goto exit;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- ret = ath10k_bmi_write32(ar, hi_board_data_initialized, 1);
|
|
|
|
- if (ret) {
|
|
|
|
- ath10k_err(ar, "could not write board data bit (%d)\n", ret);
|
|
|
|
- goto exit;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-exit:
|
|
|
|
- return ret;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static int ath10k_download_cal_file(struct ath10k *ar,
|
|
|
|
- const struct firmware *file)
|
|
|
|
-{
|
|
|
|
- int ret;
|
|
|
|
-
|
|
|
|
- if (!file)
|
|
|
|
- return -ENOENT;
|
|
|
|
-
|
|
|
|
- if (IS_ERR(file))
|
|
|
|
- return PTR_ERR(file);
|
|
|
|
-
|
|
|
|
- ret = ath10k_download_board_data(ar, file->data, file->size);
|
|
|
|
- if (ret) {
|
|
|
|
- ath10k_err(ar, "failed to download cal_file data: %d\n", ret);
|
|
|
|
- return ret;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot cal file downloaded\n");
|
|
|
|
-
|
|
|
|
- return 0;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static int ath10k_download_cal_dt(struct ath10k *ar, const char *dt_name)
|
|
|
|
-{
|
|
|
|
- struct device_node *node;
|
|
|
|
- int data_len;
|
|
|
|
- void *data;
|
|
|
|
- int ret;
|
|
|
|
-
|
|
|
|
- node = ar->dev->of_node;
|
|
|
|
- if (!node)
|
|
|
|
- /* Device Tree is optional, don't print any warnings if
|
|
|
|
- * there's no node for ath10k.
|
|
|
|
- */
|
|
|
|
- return -ENOENT;
|
|
|
|
-
|
|
|
|
- if (!of_get_property(node, dt_name, &data_len)) {
|
|
|
|
- /* The calibration data node is optional */
|
|
|
|
- return -ENOENT;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (data_len != ar->hw_params.cal_data_len) {
|
|
|
|
- ath10k_warn(ar, "invalid calibration data length in DT: %d\n",
|
|
|
|
- data_len);
|
|
|
|
- ret = -EMSGSIZE;
|
|
|
|
- goto out;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- data = kmalloc(data_len, GFP_KERNEL);
|
|
|
|
- if (!data) {
|
|
|
|
- ret = -ENOMEM;
|
|
|
|
- goto out;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- ret = of_property_read_u8_array(node, dt_name, data, data_len);
|
|
|
|
- if (ret) {
|
|
|
|
- ath10k_warn(ar, "failed to read calibration data from DT: %d\n",
|
|
|
|
- ret);
|
|
|
|
- goto out_free;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- ret = ath10k_download_board_data(ar, data, data_len);
|
|
|
|
- if (ret) {
|
|
|
|
- ath10k_warn(ar, "failed to download calibration data from Device Tree: %d\n",
|
|
|
|
- ret);
|
|
|
|
- goto out_free;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- ret = 0;
|
|
|
|
-
|
|
|
|
-out_free:
|
|
|
|
- kfree(data);
|
|
|
|
-
|
|
|
|
-out:
|
|
|
|
- return ret;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static int ath10k_download_cal_eeprom(struct ath10k *ar)
|
|
|
|
-{
|
|
|
|
- size_t data_len;
|
|
|
|
- void *data = NULL;
|
|
|
|
- int ret;
|
|
|
|
-
|
|
|
|
- ret = ath10k_hif_fetch_cal_eeprom(ar, &data, &data_len);
|
|
|
|
- if (ret) {
|
|
|
|
- if (ret != -EOPNOTSUPP)
|
|
|
|
- ath10k_warn(ar, "failed to read calibration data from EEPROM: %d\n",
|
|
|
|
- ret);
|
|
|
|
- goto out_free;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- ret = ath10k_download_board_data(ar, data, data_len);
|
|
|
|
- if (ret) {
|
|
|
|
- ath10k_warn(ar, "failed to download calibration data from EEPROM: %d\n",
|
|
|
|
- ret);
|
|
|
|
- goto out_free;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- ret = 0;
|
|
|
|
-
|
|
|
|
-out_free:
|
|
|
|
- kfree(data);
|
|
|
|
-
|
|
|
|
- return ret;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
static int ath10k_core_get_board_id_from_otp(struct ath10k *ar)
|
|
static int ath10k_core_get_board_id_from_otp(struct ath10k *ar)
|
|
{
|
|
{
|
|
u32 result, address;
|
|
u32 result, address;
|
|
u8 board_id, chip_id;
|
|
u8 board_id, chip_id;
|
|
|
|
+ bool ext_bid_support;
|
|
int ret, bmi_board_id_param;
|
|
int ret, bmi_board_id_param;
|
|
|
|
|
|
address = ar->hw_params.patch_load_addr;
|
|
address = ar->hw_params.patch_load_addr;
|
|
@@ -962,10 +837,13 @@ static int ath10k_core_get_board_id_from_otp(struct ath10k *ar)
|
|
|
|
|
|
board_id = MS(result, ATH10K_BMI_BOARD_ID_FROM_OTP);
|
|
board_id = MS(result, ATH10K_BMI_BOARD_ID_FROM_OTP);
|
|
chip_id = MS(result, ATH10K_BMI_CHIP_ID_FROM_OTP);
|
|
chip_id = MS(result, ATH10K_BMI_CHIP_ID_FROM_OTP);
|
|
|
|
+ ext_bid_support = (result & ATH10K_BMI_EXT_BOARD_ID_SUPPORT);
|
|
|
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
|
- "boot get otp board id result 0x%08x board_id %d chip_id %d\n",
|
|
|
|
- result, board_id, chip_id);
|
|
|
|
|
|
+ "boot get otp board id result 0x%08x board_id %d chip_id %d ext_bid_support %d\n",
|
|
|
|
+ result, board_id, chip_id, ext_bid_support);
|
|
|
|
+
|
|
|
|
+ ar->id.ext_bid_supported = ext_bid_support;
|
|
|
|
|
|
if ((result & ATH10K_BMI_BOARD_ID_STATUS_MASK) != 0 ||
|
|
if ((result & ATH10K_BMI_BOARD_ID_STATUS_MASK) != 0 ||
|
|
(board_id == 0)) {
|
|
(board_id == 0)) {
|
|
@@ -1069,64 +947,6 @@ static int ath10k_core_check_dt(struct ath10k *ar)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-static int ath10k_download_and_run_otp(struct ath10k *ar)
|
|
|
|
-{
|
|
|
|
- u32 result, address = ar->hw_params.patch_load_addr;
|
|
|
|
- u32 bmi_otp_exe_param = ar->hw_params.otp_exe_param;
|
|
|
|
- int ret;
|
|
|
|
-
|
|
|
|
- ret = ath10k_download_board_data(ar,
|
|
|
|
- ar->running_fw->board_data,
|
|
|
|
- ar->running_fw->board_len);
|
|
|
|
- if (ret) {
|
|
|
|
- ath10k_err(ar, "failed to download board data: %d\n", ret);
|
|
|
|
- return ret;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* OTP is optional */
|
|
|
|
-
|
|
|
|
- if (!ar->running_fw->fw_file.otp_data ||
|
|
|
|
- !ar->running_fw->fw_file.otp_len) {
|
|
|
|
- ath10k_warn(ar, "Not running otp, calibration will be incorrect (otp-data %pK otp_len %zd)!\n",
|
|
|
|
- ar->running_fw->fw_file.otp_data,
|
|
|
|
- ar->running_fw->fw_file.otp_len);
|
|
|
|
- return 0;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot upload otp to 0x%x len %zd\n",
|
|
|
|
- address, ar->running_fw->fw_file.otp_len);
|
|
|
|
-
|
|
|
|
- ret = ath10k_bmi_fast_download(ar, address,
|
|
|
|
- ar->running_fw->fw_file.otp_data,
|
|
|
|
- ar->running_fw->fw_file.otp_len);
|
|
|
|
- if (ret) {
|
|
|
|
- ath10k_err(ar, "could not write otp (%d)\n", ret);
|
|
|
|
- return ret;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* As of now pre-cal is valid for 10_4 variants */
|
|
|
|
- if (ar->cal_mode == ATH10K_PRE_CAL_MODE_DT ||
|
|
|
|
- ar->cal_mode == ATH10K_PRE_CAL_MODE_FILE)
|
|
|
|
- bmi_otp_exe_param = BMI_PARAM_FLASH_SECTION_ALL;
|
|
|
|
-
|
|
|
|
- ret = ath10k_bmi_execute(ar, address, bmi_otp_exe_param, &result);
|
|
|
|
- if (ret) {
|
|
|
|
- ath10k_err(ar, "could not execute otp (%d)\n", ret);
|
|
|
|
- return ret;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot otp execute result %d\n", result);
|
|
|
|
-
|
|
|
|
- if (!(skip_otp || test_bit(ATH10K_FW_FEATURE_IGNORE_OTP_RESULT,
|
|
|
|
- ar->running_fw->fw_file.fw_features)) &&
|
|
|
|
- result != 0) {
|
|
|
|
- ath10k_err(ar, "otp calibration failed: %d", result);
|
|
|
|
- return -EINVAL;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return 0;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
static int ath10k_download_fw(struct ath10k *ar)
|
|
static int ath10k_download_fw(struct ath10k *ar)
|
|
{
|
|
{
|
|
u32 address, data_len;
|
|
u32 address, data_len;
|
|
@@ -1149,14 +969,24 @@ static int ath10k_download_fw(struct ath10k *ar)
|
|
"boot uploading firmware image %pK len %d\n",
|
|
"boot uploading firmware image %pK len %d\n",
|
|
data, data_len);
|
|
data, data_len);
|
|
|
|
|
|
- ret = ath10k_bmi_fast_download(ar, address, data, data_len);
|
|
|
|
- if (ret) {
|
|
|
|
- ath10k_err(ar, "failed to download firmware: %d\n",
|
|
|
|
- ret);
|
|
|
|
- return ret;
|
|
|
|
|
|
+ /* Check if device supports to download firmware via
|
|
|
|
+ * diag copy engine. Downloading firmware via diag CE
|
|
|
|
+ * greatly reduces the time to download firmware.
|
|
|
|
+ */
|
|
|
|
+ if (ar->hw_params.fw_diag_ce_download) {
|
|
|
|
+ ret = ath10k_hw_diag_fast_download(ar, address,
|
|
|
|
+ data, data_len);
|
|
|
|
+ if (ret == 0)
|
|
|
|
+ /* firmware upload via diag ce was successful */
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ ath10k_warn(ar,
|
|
|
|
+ "failed to upload firmware via diag ce, trying BMI: %d",
|
|
|
|
+ ret);
|
|
}
|
|
}
|
|
|
|
|
|
- return ret;
|
|
|
|
|
|
+ return ath10k_bmi_fast_download(ar, address,
|
|
|
|
+ data, data_len);
|
|
}
|
|
}
|
|
|
|
|
|
static void ath10k_core_free_board_files(struct ath10k *ar)
|
|
static void ath10k_core_free_board_files(struct ath10k *ar)
|
|
@@ -1164,9 +994,15 @@ static void ath10k_core_free_board_files(struct ath10k *ar)
|
|
if (!IS_ERR(ar->normal_mode_fw.board))
|
|
if (!IS_ERR(ar->normal_mode_fw.board))
|
|
release_firmware(ar->normal_mode_fw.board);
|
|
release_firmware(ar->normal_mode_fw.board);
|
|
|
|
|
|
|
|
+ if (!IS_ERR(ar->normal_mode_fw.ext_board))
|
|
|
|
+ release_firmware(ar->normal_mode_fw.ext_board);
|
|
|
|
+
|
|
ar->normal_mode_fw.board = NULL;
|
|
ar->normal_mode_fw.board = NULL;
|
|
ar->normal_mode_fw.board_data = NULL;
|
|
ar->normal_mode_fw.board_data = NULL;
|
|
ar->normal_mode_fw.board_len = 0;
|
|
ar->normal_mode_fw.board_len = 0;
|
|
|
|
+ ar->normal_mode_fw.ext_board = NULL;
|
|
|
|
+ ar->normal_mode_fw.ext_board_data = NULL;
|
|
|
|
+ ar->normal_mode_fw.ext_board_len = 0;
|
|
}
|
|
}
|
|
|
|
|
|
static void ath10k_core_free_firmware_files(struct ath10k *ar)
|
|
static void ath10k_core_free_firmware_files(struct ath10k *ar)
|
|
@@ -1220,28 +1056,47 @@ success:
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-static int ath10k_core_fetch_board_data_api_1(struct ath10k *ar)
|
|
|
|
|
|
+static int ath10k_core_fetch_board_data_api_1(struct ath10k *ar, int bd_ie_type)
|
|
{
|
|
{
|
|
- if (!ar->hw_params.fw.board) {
|
|
|
|
- ath10k_err(ar, "failed to find board file fw entry\n");
|
|
|
|
- return -EINVAL;
|
|
|
|
- }
|
|
|
|
|
|
+ const struct firmware *fw;
|
|
|
|
|
|
- ar->normal_mode_fw.board = ath10k_fetch_fw_file(ar,
|
|
|
|
- ar->hw_params.fw.dir,
|
|
|
|
- ar->hw_params.fw.board);
|
|
|
|
- if (IS_ERR(ar->normal_mode_fw.board))
|
|
|
|
- return PTR_ERR(ar->normal_mode_fw.board);
|
|
|
|
|
|
+ if (bd_ie_type == ATH10K_BD_IE_BOARD) {
|
|
|
|
+ if (!ar->hw_params.fw.board) {
|
|
|
|
+ ath10k_err(ar, "failed to find board file fw entry\n");
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ }
|
|
|
|
|
|
- ar->normal_mode_fw.board_data = ar->normal_mode_fw.board->data;
|
|
|
|
- ar->normal_mode_fw.board_len = ar->normal_mode_fw.board->size;
|
|
|
|
|
|
+ ar->normal_mode_fw.board = ath10k_fetch_fw_file(ar,
|
|
|
|
+ ar->hw_params.fw.dir,
|
|
|
|
+ ar->hw_params.fw.board);
|
|
|
|
+ if (IS_ERR(ar->normal_mode_fw.board))
|
|
|
|
+ return PTR_ERR(ar->normal_mode_fw.board);
|
|
|
|
+
|
|
|
|
+ ar->normal_mode_fw.board_data = ar->normal_mode_fw.board->data;
|
|
|
|
+ ar->normal_mode_fw.board_len = ar->normal_mode_fw.board->size;
|
|
|
|
+ } else if (bd_ie_type == ATH10K_BD_IE_BOARD_EXT) {
|
|
|
|
+ if (!ar->hw_params.fw.eboard) {
|
|
|
|
+ ath10k_err(ar, "failed to find eboard file fw entry\n");
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ fw = ath10k_fetch_fw_file(ar, ar->hw_params.fw.dir,
|
|
|
|
+ ar->hw_params.fw.eboard);
|
|
|
|
+ ar->normal_mode_fw.ext_board = fw;
|
|
|
|
+ if (IS_ERR(ar->normal_mode_fw.ext_board))
|
|
|
|
+ return PTR_ERR(ar->normal_mode_fw.ext_board);
|
|
|
|
+
|
|
|
|
+ ar->normal_mode_fw.ext_board_data = ar->normal_mode_fw.ext_board->data;
|
|
|
|
+ ar->normal_mode_fw.ext_board_len = ar->normal_mode_fw.ext_board->size;
|
|
|
|
+ }
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
static int ath10k_core_parse_bd_ie_board(struct ath10k *ar,
|
|
static int ath10k_core_parse_bd_ie_board(struct ath10k *ar,
|
|
const void *buf, size_t buf_len,
|
|
const void *buf, size_t buf_len,
|
|
- const char *boardname)
|
|
|
|
|
|
+ const char *boardname,
|
|
|
|
+ int bd_ie_type)
|
|
{
|
|
{
|
|
const struct ath10k_fw_ie *hdr;
|
|
const struct ath10k_fw_ie *hdr;
|
|
bool name_match_found;
|
|
bool name_match_found;
|
|
@@ -1290,12 +1145,21 @@ static int ath10k_core_parse_bd_ie_board(struct ath10k *ar,
|
|
/* no match found */
|
|
/* no match found */
|
|
break;
|
|
break;
|
|
|
|
|
|
- ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
|
|
|
- "boot found board data for '%s'",
|
|
|
|
- boardname);
|
|
|
|
|
|
+ if (bd_ie_type == ATH10K_BD_IE_BOARD) {
|
|
|
|
+ ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
|
|
|
+ "boot found board data for '%s'",
|
|
|
|
+ boardname);
|
|
|
|
|
|
- ar->normal_mode_fw.board_data = board_ie_data;
|
|
|
|
- ar->normal_mode_fw.board_len = board_ie_len;
|
|
|
|
|
|
+ ar->normal_mode_fw.board_data = board_ie_data;
|
|
|
|
+ ar->normal_mode_fw.board_len = board_ie_len;
|
|
|
|
+ } else if (bd_ie_type == ATH10K_BD_IE_BOARD_EXT) {
|
|
|
|
+ ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
|
|
|
+ "boot found eboard data for '%s'",
|
|
|
|
+ boardname);
|
|
|
|
+
|
|
|
|
+ ar->normal_mode_fw.ext_board_data = board_ie_data;
|
|
|
|
+ ar->normal_mode_fw.ext_board_len = board_ie_len;
|
|
|
|
+ }
|
|
|
|
|
|
ret = 0;
|
|
ret = 0;
|
|
goto out;
|
|
goto out;
|
|
@@ -1345,7 +1209,18 @@ static int ath10k_core_search_bd(struct ath10k *ar,
|
|
switch (ie_id) {
|
|
switch (ie_id) {
|
|
case ATH10K_BD_IE_BOARD:
|
|
case ATH10K_BD_IE_BOARD:
|
|
ret = ath10k_core_parse_bd_ie_board(ar, data, ie_len,
|
|
ret = ath10k_core_parse_bd_ie_board(ar, data, ie_len,
|
|
- boardname);
|
|
|
|
|
|
+ boardname,
|
|
|
|
+ ATH10K_BD_IE_BOARD);
|
|
|
|
+ if (ret == -ENOENT)
|
|
|
|
+ /* no match found, continue */
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ /* either found or error, so stop searching */
|
|
|
|
+ goto out;
|
|
|
|
+ case ATH10K_BD_IE_BOARD_EXT:
|
|
|
|
+ ret = ath10k_core_parse_bd_ie_board(ar, data, ie_len,
|
|
|
|
+ boardname,
|
|
|
|
+ ATH10K_BD_IE_BOARD_EXT);
|
|
if (ret == -ENOENT)
|
|
if (ret == -ENOENT)
|
|
/* no match found, continue */
|
|
/* no match found, continue */
|
|
break;
|
|
break;
|
|
@@ -1375,9 +1250,11 @@ static int ath10k_core_fetch_board_data_api_n(struct ath10k *ar,
|
|
const u8 *data;
|
|
const u8 *data;
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
- ar->normal_mode_fw.board = ath10k_fetch_fw_file(ar,
|
|
|
|
- ar->hw_params.fw.dir,
|
|
|
|
- filename);
|
|
|
|
|
|
+ /* Skip if already fetched during board data download */
|
|
|
|
+ if (!ar->normal_mode_fw.board)
|
|
|
|
+ ar->normal_mode_fw.board = ath10k_fetch_fw_file(ar,
|
|
|
|
+ ar->hw_params.fw.dir,
|
|
|
|
+ filename);
|
|
if (IS_ERR(ar->normal_mode_fw.board))
|
|
if (IS_ERR(ar->normal_mode_fw.board))
|
|
return PTR_ERR(ar->normal_mode_fw.board);
|
|
return PTR_ERR(ar->normal_mode_fw.board);
|
|
|
|
|
|
@@ -1465,23 +1342,49 @@ out:
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-static int ath10k_core_fetch_board_file(struct ath10k *ar)
|
|
|
|
|
|
+static int ath10k_core_create_eboard_name(struct ath10k *ar, char *name,
|
|
|
|
+ size_t name_len)
|
|
|
|
+{
|
|
|
|
+ if (ar->id.bmi_ids_valid) {
|
|
|
|
+ scnprintf(name, name_len,
|
|
|
|
+ "bus=%s,bmi-chip-id=%d,bmi-eboard-id=%d",
|
|
|
|
+ ath10k_bus_str(ar->hif.bus),
|
|
|
|
+ ar->id.bmi_chip_id,
|
|
|
|
+ ar->id.bmi_eboard_id);
|
|
|
|
+
|
|
|
|
+ ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot using eboard name '%s'\n", name);
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ /* Fallback if returned board id is zero */
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int ath10k_core_fetch_board_file(struct ath10k *ar, int bd_ie_type)
|
|
{
|
|
{
|
|
char boardname[100], fallback_boardname[100];
|
|
char boardname[100], fallback_boardname[100];
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
- ret = ath10k_core_create_board_name(ar, boardname,
|
|
|
|
- sizeof(boardname), true);
|
|
|
|
- if (ret) {
|
|
|
|
- ath10k_err(ar, "failed to create board name: %d", ret);
|
|
|
|
- return ret;
|
|
|
|
- }
|
|
|
|
|
|
+ if (bd_ie_type == ATH10K_BD_IE_BOARD) {
|
|
|
|
+ ret = ath10k_core_create_board_name(ar, boardname,
|
|
|
|
+ sizeof(boardname), true);
|
|
|
|
+ if (ret) {
|
|
|
|
+ ath10k_err(ar, "failed to create board name: %d", ret);
|
|
|
|
+ return ret;
|
|
|
|
+ }
|
|
|
|
|
|
- ret = ath10k_core_create_board_name(ar, fallback_boardname,
|
|
|
|
- sizeof(boardname), false);
|
|
|
|
- if (ret) {
|
|
|
|
- ath10k_err(ar, "failed to create fallback board name: %d", ret);
|
|
|
|
- return ret;
|
|
|
|
|
|
+ ret = ath10k_core_create_board_name(ar, fallback_boardname,
|
|
|
|
+ sizeof(boardname), false);
|
|
|
|
+ if (ret) {
|
|
|
|
+ ath10k_err(ar, "failed to create fallback board name: %d", ret);
|
|
|
|
+ return ret;
|
|
|
|
+ }
|
|
|
|
+ } else if (bd_ie_type == ATH10K_BD_IE_BOARD_EXT) {
|
|
|
|
+ ret = ath10k_core_create_eboard_name(ar, boardname,
|
|
|
|
+ sizeof(boardname));
|
|
|
|
+ if (ret) {
|
|
|
|
+ ath10k_err(ar, "fallback to eboard.bin since board id 0");
|
|
|
|
+ goto fallback;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
ar->bd_api = 2;
|
|
ar->bd_api = 2;
|
|
@@ -1491,8 +1394,9 @@ static int ath10k_core_fetch_board_file(struct ath10k *ar)
|
|
if (!ret)
|
|
if (!ret)
|
|
goto success;
|
|
goto success;
|
|
|
|
|
|
|
|
+fallback:
|
|
ar->bd_api = 1;
|
|
ar->bd_api = 1;
|
|
- ret = ath10k_core_fetch_board_data_api_1(ar);
|
|
|
|
|
|
+ ret = ath10k_core_fetch_board_data_api_1(ar, bd_ie_type);
|
|
if (ret) {
|
|
if (ret) {
|
|
ath10k_err(ar, "failed to fetch board-2.bin or board.bin from %s\n",
|
|
ath10k_err(ar, "failed to fetch board-2.bin or board.bin from %s\n",
|
|
ar->hw_params.fw.dir);
|
|
ar->hw_params.fw.dir);
|
|
@@ -1504,6 +1408,291 @@ success:
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static int ath10k_core_get_ext_board_id_from_otp(struct ath10k *ar)
|
|
|
|
+{
|
|
|
|
+ u32 result, address;
|
|
|
|
+ u8 ext_board_id;
|
|
|
|
+ int ret;
|
|
|
|
+
|
|
|
|
+ address = ar->hw_params.patch_load_addr;
|
|
|
|
+
|
|
|
|
+ if (!ar->normal_mode_fw.fw_file.otp_data ||
|
|
|
|
+ !ar->normal_mode_fw.fw_file.otp_len) {
|
|
|
|
+ ath10k_warn(ar,
|
|
|
|
+ "failed to retrieve extended board id due to otp binary missing\n");
|
|
|
|
+ return -ENODATA;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
|
|
|
+ "boot upload otp to 0x%x len %zd for ext board id\n",
|
|
|
|
+ address, ar->normal_mode_fw.fw_file.otp_len);
|
|
|
|
+
|
|
|
|
+ ret = ath10k_bmi_fast_download(ar, address,
|
|
|
|
+ ar->normal_mode_fw.fw_file.otp_data,
|
|
|
|
+ ar->normal_mode_fw.fw_file.otp_len);
|
|
|
|
+ if (ret) {
|
|
|
|
+ ath10k_err(ar, "could not write otp for ext board id check: %d\n",
|
|
|
|
+ ret);
|
|
|
|
+ return ret;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ret = ath10k_bmi_execute(ar, address, BMI_PARAM_GET_EXT_BOARD_ID, &result);
|
|
|
|
+ if (ret) {
|
|
|
|
+ ath10k_err(ar, "could not execute otp for ext board id check: %d\n",
|
|
|
|
+ ret);
|
|
|
|
+ return ret;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!result) {
|
|
|
|
+ ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
|
|
|
+ "ext board id does not exist in otp, ignore it\n");
|
|
|
|
+ return -EOPNOTSUPP;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ext_board_id = result & ATH10K_BMI_EBOARD_ID_STATUS_MASK;
|
|
|
|
+
|
|
|
|
+ ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
|
|
|
+ "boot get otp ext board id result 0x%08x ext_board_id %d\n",
|
|
|
|
+ result, ext_board_id);
|
|
|
|
+
|
|
|
|
+ ar->id.bmi_eboard_id = ext_board_id;
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int ath10k_download_board_data(struct ath10k *ar, const void *data,
|
|
|
|
+ size_t data_len)
|
|
|
|
+{
|
|
|
|
+ u32 board_data_size = ar->hw_params.fw.board_size;
|
|
|
|
+ u32 eboard_data_size = ar->hw_params.fw.ext_board_size;
|
|
|
|
+ u32 board_address;
|
|
|
|
+ u32 ext_board_address;
|
|
|
|
+ int ret;
|
|
|
|
+
|
|
|
|
+ ret = ath10k_push_board_ext_data(ar, data, data_len);
|
|
|
|
+ if (ret) {
|
|
|
|
+ ath10k_err(ar, "could not push board ext data (%d)\n", ret);
|
|
|
|
+ goto exit;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ret = ath10k_bmi_read32(ar, hi_board_data, &board_address);
|
|
|
|
+ if (ret) {
|
|
|
|
+ ath10k_err(ar, "could not read board data addr (%d)\n", ret);
|
|
|
|
+ goto exit;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ret = ath10k_bmi_write_memory(ar, board_address, data,
|
|
|
|
+ min_t(u32, board_data_size,
|
|
|
|
+ data_len));
|
|
|
|
+ if (ret) {
|
|
|
|
+ ath10k_err(ar, "could not write board data (%d)\n", ret);
|
|
|
|
+ goto exit;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ret = ath10k_bmi_write32(ar, hi_board_data_initialized, 1);
|
|
|
|
+ if (ret) {
|
|
|
|
+ ath10k_err(ar, "could not write board data bit (%d)\n", ret);
|
|
|
|
+ goto exit;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!ar->id.ext_bid_supported)
|
|
|
|
+ goto exit;
|
|
|
|
+
|
|
|
|
+ /* Extended board data download */
|
|
|
|
+ ret = ath10k_core_get_ext_board_id_from_otp(ar);
|
|
|
|
+ if (ret == -EOPNOTSUPP) {
|
|
|
|
+ /* Not fetching ext_board_data if ext board id is 0 */
|
|
|
|
+ ath10k_dbg(ar, ATH10K_DBG_BOOT, "otp returned ext board id 0\n");
|
|
|
|
+ return 0;
|
|
|
|
+ } else if (ret) {
|
|
|
|
+ ath10k_err(ar, "failed to get extended board id: %d\n", ret);
|
|
|
|
+ goto exit;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ret = ath10k_core_fetch_board_file(ar, ATH10K_BD_IE_BOARD_EXT);
|
|
|
|
+ if (ret)
|
|
|
|
+ goto exit;
|
|
|
|
+
|
|
|
|
+ if (ar->normal_mode_fw.ext_board_data) {
|
|
|
|
+ ext_board_address = board_address + EXT_BOARD_ADDRESS_OFFSET;
|
|
|
|
+ ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
|
|
|
+ "boot writing ext board data to addr 0x%x",
|
|
|
|
+ ext_board_address);
|
|
|
|
+ ret = ath10k_bmi_write_memory(ar, ext_board_address,
|
|
|
|
+ ar->normal_mode_fw.ext_board_data,
|
|
|
|
+ min_t(u32, eboard_data_size, data_len));
|
|
|
|
+ if (ret)
|
|
|
|
+ ath10k_err(ar, "failed to write ext board data: %d\n", ret);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+exit:
|
|
|
|
+ return ret;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int ath10k_download_and_run_otp(struct ath10k *ar)
|
|
|
|
+{
|
|
|
|
+ u32 result, address = ar->hw_params.patch_load_addr;
|
|
|
|
+ u32 bmi_otp_exe_param = ar->hw_params.otp_exe_param;
|
|
|
|
+ int ret;
|
|
|
|
+
|
|
|
|
+ ret = ath10k_download_board_data(ar,
|
|
|
|
+ ar->running_fw->board_data,
|
|
|
|
+ ar->running_fw->board_len);
|
|
|
|
+ if (ret) {
|
|
|
|
+ ath10k_err(ar, "failed to download board data: %d\n", ret);
|
|
|
|
+ return ret;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* OTP is optional */
|
|
|
|
+
|
|
|
|
+ if (!ar->running_fw->fw_file.otp_data ||
|
|
|
|
+ !ar->running_fw->fw_file.otp_len) {
|
|
|
|
+ ath10k_warn(ar, "Not running otp, calibration will be incorrect (otp-data %pK otp_len %zd)!\n",
|
|
|
|
+ ar->running_fw->fw_file.otp_data,
|
|
|
|
+ ar->running_fw->fw_file.otp_len);
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot upload otp to 0x%x len %zd\n",
|
|
|
|
+ address, ar->running_fw->fw_file.otp_len);
|
|
|
|
+
|
|
|
|
+ ret = ath10k_bmi_fast_download(ar, address,
|
|
|
|
+ ar->running_fw->fw_file.otp_data,
|
|
|
|
+ ar->running_fw->fw_file.otp_len);
|
|
|
|
+ if (ret) {
|
|
|
|
+ ath10k_err(ar, "could not write otp (%d)\n", ret);
|
|
|
|
+ return ret;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* As of now pre-cal is valid for 10_4 variants */
|
|
|
|
+ if (ar->cal_mode == ATH10K_PRE_CAL_MODE_DT ||
|
|
|
|
+ ar->cal_mode == ATH10K_PRE_CAL_MODE_FILE)
|
|
|
|
+ bmi_otp_exe_param = BMI_PARAM_FLASH_SECTION_ALL;
|
|
|
|
+
|
|
|
|
+ ret = ath10k_bmi_execute(ar, address, bmi_otp_exe_param, &result);
|
|
|
|
+ if (ret) {
|
|
|
|
+ ath10k_err(ar, "could not execute otp (%d)\n", ret);
|
|
|
|
+ return ret;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot otp execute result %d\n", result);
|
|
|
|
+
|
|
|
|
+ if (!(skip_otp || test_bit(ATH10K_FW_FEATURE_IGNORE_OTP_RESULT,
|
|
|
|
+ ar->running_fw->fw_file.fw_features)) &&
|
|
|
|
+ result != 0) {
|
|
|
|
+ ath10k_err(ar, "otp calibration failed: %d", result);
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int ath10k_download_cal_file(struct ath10k *ar,
|
|
|
|
+ const struct firmware *file)
|
|
|
|
+{
|
|
|
|
+ int ret;
|
|
|
|
+
|
|
|
|
+ if (!file)
|
|
|
|
+ return -ENOENT;
|
|
|
|
+
|
|
|
|
+ if (IS_ERR(file))
|
|
|
|
+ return PTR_ERR(file);
|
|
|
|
+
|
|
|
|
+ ret = ath10k_download_board_data(ar, file->data, file->size);
|
|
|
|
+ if (ret) {
|
|
|
|
+ ath10k_err(ar, "failed to download cal_file data: %d\n", ret);
|
|
|
|
+ return ret;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot cal file downloaded\n");
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int ath10k_download_cal_dt(struct ath10k *ar, const char *dt_name)
|
|
|
|
+{
|
|
|
|
+ struct device_node *node;
|
|
|
|
+ int data_len;
|
|
|
|
+ void *data;
|
|
|
|
+ int ret;
|
|
|
|
+
|
|
|
|
+ node = ar->dev->of_node;
|
|
|
|
+ if (!node)
|
|
|
|
+ /* Device Tree is optional, don't print any warnings if
|
|
|
|
+ * there's no node for ath10k.
|
|
|
|
+ */
|
|
|
|
+ return -ENOENT;
|
|
|
|
+
|
|
|
|
+ if (!of_get_property(node, dt_name, &data_len)) {
|
|
|
|
+ /* The calibration data node is optional */
|
|
|
|
+ return -ENOENT;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (data_len != ar->hw_params.cal_data_len) {
|
|
|
|
+ ath10k_warn(ar, "invalid calibration data length in DT: %d\n",
|
|
|
|
+ data_len);
|
|
|
|
+ ret = -EMSGSIZE;
|
|
|
|
+ goto out;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ data = kmalloc(data_len, GFP_KERNEL);
|
|
|
|
+ if (!data) {
|
|
|
|
+ ret = -ENOMEM;
|
|
|
|
+ goto out;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ret = of_property_read_u8_array(node, dt_name, data, data_len);
|
|
|
|
+ if (ret) {
|
|
|
|
+ ath10k_warn(ar, "failed to read calibration data from DT: %d\n",
|
|
|
|
+ ret);
|
|
|
|
+ goto out_free;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ret = ath10k_download_board_data(ar, data, data_len);
|
|
|
|
+ if (ret) {
|
|
|
|
+ ath10k_warn(ar, "failed to download calibration data from Device Tree: %d\n",
|
|
|
|
+ ret);
|
|
|
|
+ goto out_free;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ret = 0;
|
|
|
|
+
|
|
|
|
+out_free:
|
|
|
|
+ kfree(data);
|
|
|
|
+
|
|
|
|
+out:
|
|
|
|
+ return ret;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int ath10k_download_cal_eeprom(struct ath10k *ar)
|
|
|
|
+{
|
|
|
|
+ size_t data_len;
|
|
|
|
+ void *data = NULL;
|
|
|
|
+ int ret;
|
|
|
|
+
|
|
|
|
+ ret = ath10k_hif_fetch_cal_eeprom(ar, &data, &data_len);
|
|
|
|
+ if (ret) {
|
|
|
|
+ if (ret != -EOPNOTSUPP)
|
|
|
|
+ ath10k_warn(ar, "failed to read calibration data from EEPROM: %d\n",
|
|
|
|
+ ret);
|
|
|
|
+ goto out_free;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ret = ath10k_download_board_data(ar, data, data_len);
|
|
|
|
+ if (ret) {
|
|
|
|
+ ath10k_warn(ar, "failed to download calibration data from EEPROM: %d\n",
|
|
|
|
+ ret);
|
|
|
|
+ goto out_free;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ret = 0;
|
|
|
|
+
|
|
|
|
+out_free:
|
|
|
|
+ kfree(data);
|
|
|
|
+
|
|
|
|
+ return ret;
|
|
|
|
+}
|
|
|
|
+
|
|
int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name,
|
|
int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name,
|
|
struct ath10k_fw_file *fw_file)
|
|
struct ath10k_fw_file *fw_file)
|
|
{
|
|
{
|
|
@@ -1896,7 +2085,8 @@ static int ath10k_init_hw_params(struct ath10k *ar)
|
|
for (i = 0; i < ARRAY_SIZE(ath10k_hw_params_list); i++) {
|
|
for (i = 0; i < ARRAY_SIZE(ath10k_hw_params_list); i++) {
|
|
hw_params = &ath10k_hw_params_list[i];
|
|
hw_params = &ath10k_hw_params_list[i];
|
|
|
|
|
|
- if (hw_params->id == ar->target_version &&
|
|
|
|
|
|
+ if (hw_params->bus == ar->hif.bus &&
|
|
|
|
+ hw_params->id == ar->target_version &&
|
|
hw_params->dev_id == ar->dev_id)
|
|
hw_params->dev_id == ar->dev_id)
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
@@ -1997,6 +2187,7 @@ static void ath10k_core_set_coverage_class_work(struct work_struct *work)
|
|
static int ath10k_core_init_firmware_features(struct ath10k *ar)
|
|
static int ath10k_core_init_firmware_features(struct ath10k *ar)
|
|
{
|
|
{
|
|
struct ath10k_fw_file *fw_file = &ar->normal_mode_fw.fw_file;
|
|
struct ath10k_fw_file *fw_file = &ar->normal_mode_fw.fw_file;
|
|
|
|
+ int max_num_peers;
|
|
|
|
|
|
if (test_bit(ATH10K_FW_FEATURE_WMI_10_2, fw_file->fw_features) &&
|
|
if (test_bit(ATH10K_FW_FEATURE_WMI_10_2, fw_file->fw_features) &&
|
|
!test_bit(ATH10K_FW_FEATURE_WMI_10X, fw_file->fw_features)) {
|
|
!test_bit(ATH10K_FW_FEATURE_WMI_10X, fw_file->fw_features)) {
|
|
@@ -2076,7 +2267,7 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar)
|
|
|
|
|
|
switch (fw_file->wmi_op_version) {
|
|
switch (fw_file->wmi_op_version) {
|
|
case ATH10K_FW_WMI_OP_VERSION_MAIN:
|
|
case ATH10K_FW_WMI_OP_VERSION_MAIN:
|
|
- ar->max_num_peers = TARGET_NUM_PEERS;
|
|
|
|
|
|
+ max_num_peers = TARGET_NUM_PEERS;
|
|
ar->max_num_stations = TARGET_NUM_STATIONS;
|
|
ar->max_num_stations = TARGET_NUM_STATIONS;
|
|
ar->max_num_vdevs = TARGET_NUM_VDEVS;
|
|
ar->max_num_vdevs = TARGET_NUM_VDEVS;
|
|
ar->htt.max_num_pending_tx = TARGET_NUM_MSDU_DESC;
|
|
ar->htt.max_num_pending_tx = TARGET_NUM_MSDU_DESC;
|
|
@@ -2088,10 +2279,10 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar)
|
|
case ATH10K_FW_WMI_OP_VERSION_10_2:
|
|
case ATH10K_FW_WMI_OP_VERSION_10_2:
|
|
case ATH10K_FW_WMI_OP_VERSION_10_2_4:
|
|
case ATH10K_FW_WMI_OP_VERSION_10_2_4:
|
|
if (ath10k_peer_stats_enabled(ar)) {
|
|
if (ath10k_peer_stats_enabled(ar)) {
|
|
- ar->max_num_peers = TARGET_10X_TX_STATS_NUM_PEERS;
|
|
|
|
|
|
+ max_num_peers = TARGET_10X_TX_STATS_NUM_PEERS;
|
|
ar->max_num_stations = TARGET_10X_TX_STATS_NUM_STATIONS;
|
|
ar->max_num_stations = TARGET_10X_TX_STATS_NUM_STATIONS;
|
|
} else {
|
|
} else {
|
|
- ar->max_num_peers = TARGET_10X_NUM_PEERS;
|
|
|
|
|
|
+ max_num_peers = TARGET_10X_NUM_PEERS;
|
|
ar->max_num_stations = TARGET_10X_NUM_STATIONS;
|
|
ar->max_num_stations = TARGET_10X_NUM_STATIONS;
|
|
}
|
|
}
|
|
ar->max_num_vdevs = TARGET_10X_NUM_VDEVS;
|
|
ar->max_num_vdevs = TARGET_10X_NUM_VDEVS;
|
|
@@ -2100,7 +2291,7 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar)
|
|
ar->max_spatial_stream = WMI_MAX_SPATIAL_STREAM;
|
|
ar->max_spatial_stream = WMI_MAX_SPATIAL_STREAM;
|
|
break;
|
|
break;
|
|
case ATH10K_FW_WMI_OP_VERSION_TLV:
|
|
case ATH10K_FW_WMI_OP_VERSION_TLV:
|
|
- ar->max_num_peers = TARGET_TLV_NUM_PEERS;
|
|
|
|
|
|
+ max_num_peers = TARGET_TLV_NUM_PEERS;
|
|
ar->max_num_stations = TARGET_TLV_NUM_STATIONS;
|
|
ar->max_num_stations = TARGET_TLV_NUM_STATIONS;
|
|
ar->max_num_vdevs = TARGET_TLV_NUM_VDEVS;
|
|
ar->max_num_vdevs = TARGET_TLV_NUM_VDEVS;
|
|
ar->max_num_tdls_vdevs = TARGET_TLV_NUM_TDLS_VDEVS;
|
|
ar->max_num_tdls_vdevs = TARGET_TLV_NUM_TDLS_VDEVS;
|
|
@@ -2112,7 +2303,7 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar)
|
|
ar->wmi.mgmt_max_num_pending_tx = TARGET_TLV_MGMT_NUM_MSDU_DESC;
|
|
ar->wmi.mgmt_max_num_pending_tx = TARGET_TLV_MGMT_NUM_MSDU_DESC;
|
|
break;
|
|
break;
|
|
case ATH10K_FW_WMI_OP_VERSION_10_4:
|
|
case ATH10K_FW_WMI_OP_VERSION_10_4:
|
|
- ar->max_num_peers = TARGET_10_4_NUM_PEERS;
|
|
|
|
|
|
+ max_num_peers = TARGET_10_4_NUM_PEERS;
|
|
ar->max_num_stations = TARGET_10_4_NUM_STATIONS;
|
|
ar->max_num_stations = TARGET_10_4_NUM_STATIONS;
|
|
ar->num_active_peers = TARGET_10_4_ACTIVE_PEERS;
|
|
ar->num_active_peers = TARGET_10_4_ACTIVE_PEERS;
|
|
ar->max_num_vdevs = TARGET_10_4_NUM_VDEVS;
|
|
ar->max_num_vdevs = TARGET_10_4_NUM_VDEVS;
|
|
@@ -2131,10 +2322,16 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar)
|
|
break;
|
|
break;
|
|
case ATH10K_FW_WMI_OP_VERSION_UNSET:
|
|
case ATH10K_FW_WMI_OP_VERSION_UNSET:
|
|
case ATH10K_FW_WMI_OP_VERSION_MAX:
|
|
case ATH10K_FW_WMI_OP_VERSION_MAX:
|
|
|
|
+ default:
|
|
WARN_ON(1);
|
|
WARN_ON(1);
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (ar->hw_params.num_peers)
|
|
|
|
+ ar->max_num_peers = ar->hw_params.num_peers;
|
|
|
|
+ else
|
|
|
|
+ ar->max_num_peers = max_num_peers;
|
|
|
|
+
|
|
/* Backwards compatibility for firmwares without
|
|
/* Backwards compatibility for firmwares without
|
|
* ATH10K_FW_IE_HTT_OP_VERSION.
|
|
* ATH10K_FW_IE_HTT_OP_VERSION.
|
|
*/
|
|
*/
|
|
@@ -2384,6 +2581,10 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
|
|
ar->wmi.svc_map))
|
|
ar->wmi.svc_map))
|
|
val |= WMI_10_4_TDLS_UAPSD_BUFFER_STA;
|
|
val |= WMI_10_4_TDLS_UAPSD_BUFFER_STA;
|
|
|
|
|
|
|
|
+ if (test_bit(WMI_SERVICE_TX_DATA_ACK_RSSI,
|
|
|
|
+ ar->wmi.svc_map))
|
|
|
|
+ val |= WMI_10_4_TX_DATA_ACK_RSSI;
|
|
|
|
+
|
|
status = ath10k_mac_ext_resource_config(ar, val);
|
|
status = ath10k_mac_ext_resource_config(ar, val);
|
|
if (status) {
|
|
if (status) {
|
|
ath10k_err(ar,
|
|
ath10k_err(ar,
|
|
@@ -2608,7 +2809,7 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
|
|
if (ret)
|
|
if (ret)
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT, "DT bdf variant name not set.\n");
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT, "DT bdf variant name not set.\n");
|
|
|
|
|
|
- ret = ath10k_core_fetch_board_file(ar);
|
|
|
|
|
|
+ ret = ath10k_core_fetch_board_file(ar, ATH10K_BD_IE_BOARD);
|
|
if (ret) {
|
|
if (ret) {
|
|
ath10k_err(ar, "failed to fetch board file: %d\n", ret);
|
|
ath10k_err(ar, "failed to fetch board file: %d\n", ret);
|
|
goto err_free_firmware_files;
|
|
goto err_free_firmware_files;
|
|
@@ -2617,6 +2818,8 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
|
|
ath10k_debug_print_board_info(ar);
|
|
ath10k_debug_print_board_info(ar);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ device_get_mac_address(ar->dev, ar->mac_addr, sizeof(ar->mac_addr));
|
|
|
|
+
|
|
ret = ath10k_core_init_firmware_features(ar);
|
|
ret = ath10k_core_init_firmware_features(ar);
|
|
if (ret) {
|
|
if (ret) {
|
|
ath10k_err(ar, "fatal problem with firmware features: %d\n",
|
|
ath10k_err(ar, "fatal problem with firmware features: %d\n",
|
|
@@ -2729,9 +2932,11 @@ err:
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
-int ath10k_core_register(struct ath10k *ar, u32 chip_id)
|
|
|
|
|
|
+int ath10k_core_register(struct ath10k *ar,
|
|
|
|
+ const struct ath10k_bus_params *bus_params)
|
|
{
|
|
{
|
|
- ar->chip_id = chip_id;
|
|
|
|
|
|
+ ar->chip_id = bus_params->chip_id;
|
|
|
|
+ ar->dev_type = bus_params->dev_type;
|
|
queue_work(ar->workqueue, &ar->register_work);
|
|
queue_work(ar->workqueue, &ar->register_work);
|
|
|
|
|
|
return 0;
|
|
return 0;
|