wlan-ap-Telecominfraproject/feeds/ipq807x/mac80211/patches/076-ath11k-add-hw-ops-to-support-multi-radio.patch
John Crispin 3affbc1cad QualComm/AX: add Hawkeye and Cypress support
This series is based on
* 2020-07-10 ipq6018-ilq-11-0_qca_oem-034672b0676c37b1f4519e5720e18e95fe6236ef

Add support for
* qsdk kernel/v4.4
* qsdk ethernet subsystem
* v5.7 ath11k backport + QualComm staging patches (wlan_ap_1.0)
* ath11k-firmware
* hostapd/iw/...

Feature support
* full boot, system detection
* sysupgrade to nand
* HE support via latest hostapd
* driver support for usb, crypto, hwmon, cpufreq, ...

Missing
* NSS/HW flow offloading - FW blob is not redistributable

Using the qsdk v4.4 is an intermediate solution while the vanilla is being
tested. Vanilla kernel is almost on feature par. Work has already started
to upstream the ethernet and switch drivers. Once complete the target will
be fully upstream.

Signed-off-by: John Crispin <john@phrozen.org>
2020-07-23 18:54:03 +02:00

236 lines
7.0 KiB
Diff

--- a/drivers/net/wireless/ath/ath11k/ahb.c
+++ b/drivers/net/wireless/ath/ath11k/ahb.c
@@ -777,26 +777,26 @@ static int ath11k_ahb_ext_irq_config(str
if (ath11k_reo_status_ring_mask[i] & BIT(j))
irq_grp->irqs[num_irq++] = reo2host_status;
- if (j < MAX_RADIOS) {
+ if (j < ab->hw_params.max_radios) {
if (ath11k_rxdma2host_ring_mask[i] & BIT(j)) {
irq_grp->irqs[num_irq++] =
rxdma2host_destination_ring_mac1
- - ath11k_core_get_hw_mac_id(ab, j);
+ - ab->hw_params.hw_ops->get_hw_mac_from_pdev_id(ab, j);
}
if (ath11k_host2rxdma_ring_mask[i] & BIT(j)) {
irq_grp->irqs[num_irq++] =
host2rxdma_host_buf_ring_mac1
- - ath11k_core_get_hw_mac_id(ab, j);
+ - ab->hw_params.hw_ops->get_hw_mac_from_pdev_id(ab, j);
}
if (rx_mon_status_ring_mask[i] & BIT(j)) {
irq_grp->irqs[num_irq++] =
ppdu_end_interrupts_mac1 -
- ath11k_core_get_hw_mac_id(ab, j);
+ ab->hw_params.hw_ops->get_hw_mac_from_pdev_id(ab, j);
irq_grp->irqs[num_irq++] =
rxdma2host_monitor_status_ring_mac1 -
- ath11k_core_get_hw_mac_id(ab, j);
+ ab->hw_params.hw_ops->get_hw_mac_from_pdev_id(ab, j);
}
}
}
@@ -954,18 +954,19 @@ static int ath11k_ahb_probe(struct platf
ath11k_ahb_init_qmi_ce_config(ab);
- ret = ath11k_ahb_config_irq(ab);
+ ret = ath11k_core_init(ab);
if (ret) {
- ath11k_err(ab, "failed to configure irq: %d\n", ret);
+ ath11k_err(ab, "failed to init core: %d\n", ret);
goto err_ce_free;
}
- ret = ath11k_core_init(ab);
+ ret = ath11k_ahb_config_irq(ab);
if (ret) {
- ath11k_err(ab, "failed to init core: %d\n", ret);
+ ath11k_err(ab, "failed to configure irq: %d\n", ret);
goto err_ce_free;
}
+
ath11k_ahb_fwreset_from_cold_boot(ab);
return 0;
--- a/drivers/net/wireless/ath/ath11k/core.c
+++ b/drivers/net/wireless/ath/ath11k/core.c
@@ -33,6 +33,9 @@ static const struct ath11k_hw_params ath
.cal_size = IPQ8074_MAX_CAL_DATA_SZ,
},
.spectral_fft_sz = 2,
+ .max_radios = 3,
+ .bdf_addr = 0x4B0C0000,
+ .hw_ops = &qca8074_ops,
},
{
.dev_id = ATH11K_HW_IPQ6018,
@@ -43,11 +46,15 @@ static const struct ath11k_hw_params ath
.cal_size = IPQ6018_MAX_CAL_DATA_SZ,
},
.spectral_fft_sz = 4,
+ .max_radios = 2,
+ .bdf_addr = 0x4ABC0000,
+ .hw_ops = &qca6018_ops,
},
};
/* Map from pdev index to hw mac index */
-u8 ath11k_core_get_hw_mac_id(struct ath11k_base *ab, int pdev_idx)
+static u8 ath11k_qca8074_hw_mac_from_pdev_id(struct ath11k_base *ab,
+ int pdev_idx)
{
switch (pdev_idx) {
case 0:
@@ -62,6 +69,20 @@ u8 ath11k_core_get_hw_mac_id(struct ath1
}
}
+static u8 ath11k_qca6018_hw_mac_from_pdev_id(struct ath11k_base *ab,
+ int pdev_idx)
+{
+ return pdev_idx;
+}
+
+const struct ath11k_hw_ops qca8074_ops = {
+ .get_hw_mac_from_pdev_id = ath11k_qca8074_hw_mac_from_pdev_id,
+};
+
+const struct ath11k_hw_ops qca6018_ops = {
+ .get_hw_mac_from_pdev_id = ath11k_qca6018_hw_mac_from_pdev_id,
+};
+
static int ath11k_core_create_board_name(struct ath11k_base *ab, char *name,
size_t name_len)
{
--- a/drivers/net/wireless/ath/ath11k/core.h
+++ b/drivers/net/wireless/ath/ath11k/core.h
@@ -897,7 +897,6 @@ int ath11k_config_qdss(struct ath11k_bas
void ath11k_core_free_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd);
void ath11k_core_halt(struct ath11k *ar);
-u8 ath11k_core_get_hw_mac_id(struct ath11k_base *ab, int pdev_idx);
static inline const char *ath11k_scan_state_str(enum ath11k_scan_state state)
{
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
@@ -4051,7 +4051,7 @@ int ath11k_dp_rx_process_wbm_err(struct
int total_num_buffs_reaped = 0;
int ret, i;
- for (i = 0; i < MAX_RADIOS; i++)
+ for (i = 0; i < ab->num_radios; i++)
__skb_queue_head_init(&msdu_list[i]);
srng = &ab->hal.srng_list[dp->rx_rel_ring.ring_id];
--- a/drivers/net/wireless/ath/ath11k/htc.c
+++ b/drivers/net/wireless/ath/ath11k/htc.c
@@ -748,7 +748,7 @@ int ath11k_htc_init(struct ath11k_base *
htc->wmi_ep_count = 3;
break;
default:
- htc->wmi_ep_count = 3;
+ htc->wmi_ep_count = ab->hw_params.max_radios;
break;
}
--- a/drivers/net/wireless/ath/ath11k/hw.h
+++ b/drivers/net/wireless/ath/ath11k/hw.h
@@ -104,17 +104,28 @@ enum ath11k_hw_rate_ofdm {
ATH11K_HW_RATE_OFDM_9M,
};
+struct ath11k_hw_ops {
+ u8 (*get_hw_mac_from_pdev_id)(struct ath11k_base *ab, int pdev_id);
+};
+
struct ath11k_hw_params {
const char *name;
u16 dev_id;
+ u8 max_radios;
+ u32 bdf_addr;
struct {
const char *dir;
size_t board_size;
size_t cal_size;
} fw;
u8 spectral_fft_sz;
+
+ const struct ath11k_hw_ops *hw_ops;
};
+extern const struct ath11k_hw_ops qca8074_ops;
+extern const struct ath11k_hw_ops qca6018_ops;
+
struct ath11k_fw_ie {
__le32 id;
__le32 len;
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -6810,7 +6810,7 @@ int ath11k_mac_allocate(struct ath11k_ba
ar->ab = ab;
ar->pdev = pdev;
ar->pdev_idx = i;
- ar->lmac_id = ath11k_core_get_hw_mac_id(ab, i);
+ ar->lmac_id = ab->hw_params.hw_ops->get_hw_mac_from_pdev_id(ab, i);
ar->wmi = &ab->wmi_ab.wmi[i];
/* FIXME wmi[0] is already initialized during attach,
--- a/drivers/net/wireless/ath/ath11k/reg.c
+++ b/drivers/net/wireless/ath/ath11k/reg.c
@@ -695,7 +695,7 @@ void ath11k_reg_free(struct ath11k_base
{
int i;
- for (i = 0; i < MAX_RADIOS; i++) {
+ for (i = 0; i < ab->hw_params.max_radios; i++) {
kfree(ab->default_regd[i]);
kfree(ab->new_regd[i]);
}
--- a/drivers/net/wireless/ath/ath11k/wmi.c
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
@@ -6975,7 +6975,7 @@ int ath11k_wmi_connect(struct ath11k_bas
u8 wmi_ep_count;
wmi_ep_count = ab->htc.wmi_ep_count;
- if (wmi_ep_count > MAX_RADIOS)
+ if (wmi_ep_count > ab->hw_params.max_radios)
return -1;
for (i = 0; i < wmi_ep_count; i++)
@@ -6997,7 +6997,7 @@ int ath11k_wmi_pdev_attach(struct ath11k
{
struct ath11k_pdev_wmi *wmi_handle;
- if (pdev_id >= MAX_RADIOS)
+ if (pdev_id >= ab->hw_params.max_radios)
return -EINVAL;
wmi_handle = &ab->wmi_ab.wmi[pdev_id];
--- a/drivers/net/wireless/ath/ath11k/qmi.c
+++ b/drivers/net/wireless/ath/ath11k/qmi.c
@@ -2020,8 +2020,8 @@ static int ath11k_qmi_alloc_target_mem_c
for (i = 0, idx = 0; i < ab->qmi.mem_seg_count; i++) {
switch (ab->qmi.target_mem[i].type) {
case BDF_MEM_REGION_TYPE:
- ab->qmi.target_mem[idx].paddr = ATH11K_QMI_BDF_ADDRESS;
- ab->qmi.target_mem[idx].vaddr = ATH11K_QMI_BDF_ADDRESS;
+ ab->qmi.target_mem[idx].paddr = ab->hw_params.bdf_addr;
+ ab->qmi.target_mem[idx].vaddr = ab->hw_params.bdf_addr;
ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;
ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;
idx++;
@@ -2210,7 +2210,7 @@ static int ath11k_qmi_load_bdf(struct at
return -ENOMEM;
memset(&resp, 0, sizeof(resp));
- bdf_addr = ioremap(ATH11K_QMI_BDF_ADDRESS, ATH11K_QMI_BDF_MAX_SIZE);
+ bdf_addr = ioremap(ab->hw_params.bdf_addr, ATH11K_QMI_BDF_MAX_SIZE);
if (!bdf_addr) {
ath11k_warn(ab, "qmi ioremap error for BDF\n");
ret = -EIO;