Skip to content

Commit c4eacab

Browse files
govindsiKalle Valo
authored andcommitted
ath11k: configure copy engine msi address in CE srng
Fill msi base address and msi data to be programmed in CE srang. This is used by the srng to generate the msi interrupt. Needed for PCI support. Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1 Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.1.0.1-01238-QCAHKSWPL_SILICONZ-2 Signed-off-by: Govind Singh <[email protected]> Signed-off-by: Kalle Valo <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 654e959 commit c4eacab

File tree

4 files changed

+83
-0
lines changed

4 files changed

+83
-0
lines changed

drivers/net/wireless/ath/ath11k/ce.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include "dp_rx.h"
77
#include "debug.h"
8+
#include "hif.h"
89

910
static const struct ce_attr host_ce_config_wlan[] = {
1011
/* CE0: host->target HTC control and raw streams */
@@ -352,6 +353,31 @@ static void ath11k_ce_send_done_cb(struct ath11k_ce_pipe *pipe)
352353
}
353354
}
354355

356+
static void ath11k_ce_srng_msi_ring_params_setup(struct ath11k_base *ab, u32 ce_id,
357+
struct hal_srng_params *ring_params)
358+
{
359+
u32 msi_data_start;
360+
u32 msi_data_count;
361+
u32 msi_irq_start;
362+
u32 addr_lo;
363+
u32 addr_hi;
364+
int ret;
365+
366+
ret = ath11k_get_user_msi_vector(ab, "CE",
367+
&msi_data_count, &msi_data_start,
368+
&msi_irq_start);
369+
370+
if (ret)
371+
return;
372+
373+
ath11k_get_msi_address(ab, &addr_lo, &addr_hi);
374+
375+
ring_params->msi_addr = addr_lo;
376+
ring_params->msi_addr |= (dma_addr_t)(((uint64_t)addr_hi) << 32);
377+
ring_params->msi_data = (ce_id % msi_data_count) + msi_data_start;
378+
ring_params->flags |= HAL_SRNG_FLAGS_MSI_INTR;
379+
}
380+
355381
static int ath11k_ce_init_ring(struct ath11k_base *ab,
356382
struct ath11k_ce_ring *ce_ring,
357383
int ce_id, enum hal_ring_type type)
@@ -395,6 +421,10 @@ static int ath11k_ce_init_ring(struct ath11k_base *ab,
395421
ret, ce_id);
396422
return ret;
397423
}
424+
425+
if (!(CE_ATTR_DIS_INTR & host_ce_config_wlan[ce_id].flags))
426+
ath11k_ce_srng_msi_ring_params_setup(ab, ce_id, &params);
427+
398428
ce_ring->hal_ring_id = ret;
399429

400430
return 0;

drivers/net/wireless/ath/ath11k/hal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,8 @@ struct hal_srng_params {
458458
u32 flags;
459459
u32 max_buffer_len;
460460
u32 low_threshold;
461+
dma_addr_t msi_addr;
462+
u32 msi_data;
461463

462464
/* Add more params as needed */
463465
};

drivers/net/wireless/ath/ath11k/hif.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ struct ath11k_hif_ops {
1919
void (*power_down)(struct ath11k_base *sc);
2020
int (*map_service_to_pipe)(struct ath11k_base *sc, u16 service_id,
2121
u8 *ul_pipe, u8 *dl_pipe);
22+
int (*get_user_msi_vector)(struct ath11k_base *ab, char *user_name,
23+
int *num_vectors, u32 *user_base_data,
24+
u32 *base_vector);
25+
void (*get_msi_address)(struct ath11k_base *ab, u32 *msi_addr_lo,
26+
u32 *msi_addr_hi);
2227
};
2328

2429
static inline int ath11k_hif_start(struct ath11k_base *sc)
@@ -66,4 +71,25 @@ static inline int ath11k_hif_map_service_to_pipe(struct ath11k_base *sc, u16 ser
6671
{
6772
return sc->hif.ops->map_service_to_pipe(sc, service_id, ul_pipe, dl_pipe);
6873
}
74+
75+
static inline int ath11k_get_user_msi_vector(struct ath11k_base *ab, char *user_name,
76+
int *num_vectors, u32 *user_base_data,
77+
u32 *base_vector)
78+
{
79+
if (!ab->hif.ops->get_user_msi_vector)
80+
return -EOPNOTSUPP;
81+
82+
return ab->hif.ops->get_user_msi_vector(ab, user_name, num_vectors,
83+
user_base_data,
84+
base_vector);
85+
}
86+
87+
static inline void ath11k_get_msi_address(struct ath11k_base *ab, u32 *msi_addr_lo,
88+
u32 *msi_addr_hi)
89+
{
90+
if (!ab->hif.ops->get_msi_address)
91+
return;
92+
93+
ab->hif.ops->get_msi_address(ab, msi_addr_lo, msi_addr_hi);
94+
}
6995
#endif /* _HIF_H_ */

drivers/net/wireless/ath/ath11k/pci.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,18 @@ int ath11k_pci_get_msi_irq(struct device *dev, unsigned int vector)
339339
return pci_irq_vector(pci_dev, vector);
340340
}
341341

342+
static void ath11k_pci_get_msi_address(struct ath11k_base *ab, u32 *msi_addr_lo,
343+
u32 *msi_addr_hi)
344+
{
345+
struct pci_dev *pci_dev = to_pci_dev(ab->dev);
346+
347+
pci_read_config_dword(pci_dev, pci_dev->msi_cap + PCI_MSI_ADDRESS_LO,
348+
msi_addr_lo);
349+
350+
pci_read_config_dword(pci_dev, pci_dev->msi_cap + PCI_MSI_ADDRESS_HI,
351+
msi_addr_hi);
352+
}
353+
342354
int ath11k_pci_get_user_msi_assignment(struct ath11k_pci *ab_pci, char *user_name,
343355
int *num_vectors, u32 *user_base_data,
344356
u32 *base_vector)
@@ -366,6 +378,17 @@ int ath11k_pci_get_user_msi_assignment(struct ath11k_pci *ab_pci, char *user_nam
366378
return -EINVAL;
367379
}
368380

381+
static int ath11k_get_user_msi_assignment(struct ath11k_base *ab, char *user_name,
382+
int *num_vectors, u32 *user_base_data,
383+
u32 *base_vector)
384+
{
385+
struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
386+
387+
return ath11k_pci_get_user_msi_assignment(ab_pci, user_name,
388+
num_vectors, user_base_data,
389+
base_vector);
390+
}
391+
369392
static void ath11k_pci_free_irq(struct ath11k_base *ab)
370393
{
371394
int i, irq_idx;
@@ -634,6 +657,8 @@ static const struct ath11k_hif_ops ath11k_pci_hif_ops = {
634657
.write32 = ath11k_pci_write32,
635658
.power_down = ath11k_pci_power_down,
636659
.power_up = ath11k_pci_power_up,
660+
.get_msi_address = ath11k_pci_get_msi_address,
661+
.get_user_msi_vector = ath11k_get_user_msi_assignment,
637662
};
638663

639664
static int ath11k_pci_probe(struct pci_dev *pdev,

0 commit comments

Comments
 (0)