Commit eef25405 authored by Kalle Valo's avatar Kalle Valo

ath10k: add diag_read() to hif ops

diag_read() is used for reading from firmware memory via the diagnose window.
First user will be cal_data debugfs file.

To serialise diagnostic window access and make it safe to use while firmware is
running take ce_lock both in ath10k_pci_diag_write_mem() and
ath10k_pci_diag_read_mem(). Because of that all the CE calls had to be changed
to _nolock variants.
Signed-off-by: default avatarKalle Valo <kvalo@qca.qualcomm.com>
parent d5d6805b
...@@ -443,12 +443,12 @@ int ath10k_ce_rx_post_buf(struct ath10k_ce_pipe *pipe, void *ctx, u32 paddr) ...@@ -443,12 +443,12 @@ int ath10k_ce_rx_post_buf(struct ath10k_ce_pipe *pipe, void *ctx, u32 paddr)
* Guts of ath10k_ce_completed_recv_next. * Guts of ath10k_ce_completed_recv_next.
* The caller takes responsibility for any necessary locking. * The caller takes responsibility for any necessary locking.
*/ */
static int ath10k_ce_completed_recv_next_nolock(struct ath10k_ce_pipe *ce_state, int ath10k_ce_completed_recv_next_nolock(struct ath10k_ce_pipe *ce_state,
void **per_transfer_contextp, void **per_transfer_contextp,
u32 *bufferp, u32 *bufferp,
unsigned int *nbytesp, unsigned int *nbytesp,
unsigned int *transfer_idp, unsigned int *transfer_idp,
unsigned int *flagsp) unsigned int *flagsp)
{ {
struct ath10k_ce_ring *dest_ring = ce_state->dest_ring; struct ath10k_ce_ring *dest_ring = ce_state->dest_ring;
unsigned int nentries_mask = dest_ring->nentries_mask; unsigned int nentries_mask = dest_ring->nentries_mask;
...@@ -576,11 +576,11 @@ int ath10k_ce_revoke_recv_next(struct ath10k_ce_pipe *ce_state, ...@@ -576,11 +576,11 @@ int ath10k_ce_revoke_recv_next(struct ath10k_ce_pipe *ce_state,
* Guts of ath10k_ce_completed_send_next. * Guts of ath10k_ce_completed_send_next.
* The caller takes responsibility for any necessary locking. * The caller takes responsibility for any necessary locking.
*/ */
static int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state, int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state,
void **per_transfer_contextp, void **per_transfer_contextp,
u32 *bufferp, u32 *bufferp,
unsigned int *nbytesp, unsigned int *nbytesp,
unsigned int *transfer_idp) unsigned int *transfer_idp)
{ {
struct ath10k_ce_ring *src_ring = ce_state->src_ring; struct ath10k_ce_ring *src_ring = ce_state->src_ring;
u32 ctrl_addr = ce_state->ctrl_addr; u32 ctrl_addr = ce_state->ctrl_addr;
......
...@@ -192,6 +192,12 @@ int ath10k_ce_completed_send_next(struct ath10k_ce_pipe *ce_state, ...@@ -192,6 +192,12 @@ int ath10k_ce_completed_send_next(struct ath10k_ce_pipe *ce_state,
unsigned int *nbytesp, unsigned int *nbytesp,
unsigned int *transfer_idp); unsigned int *transfer_idp);
int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state,
void **per_transfer_contextp,
u32 *bufferp,
unsigned int *nbytesp,
unsigned int *transfer_idp);
/*==================CE Engine Initialization=======================*/ /*==================CE Engine Initialization=======================*/
int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id, int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id,
...@@ -213,6 +219,13 @@ int ath10k_ce_revoke_recv_next(struct ath10k_ce_pipe *ce_state, ...@@ -213,6 +219,13 @@ int ath10k_ce_revoke_recv_next(struct ath10k_ce_pipe *ce_state,
void **per_transfer_contextp, void **per_transfer_contextp,
u32 *bufferp); u32 *bufferp);
int ath10k_ce_completed_recv_next_nolock(struct ath10k_ce_pipe *ce_state,
void **per_transfer_contextp,
u32 *bufferp,
unsigned int *nbytesp,
unsigned int *transfer_idp,
unsigned int *flagsp);
/* /*
* Support clean shutdown by allowing the caller to cancel * Support clean shutdown by allowing the caller to cancel
* pending sends. Target DMA must be stopped before using * pending sends. Target DMA must be stopped before using
......
...@@ -43,6 +43,10 @@ struct ath10k_hif_ops { ...@@ -43,6 +43,10 @@ struct ath10k_hif_ops {
int (*tx_sg)(struct ath10k *ar, u8 pipe_id, int (*tx_sg)(struct ath10k *ar, u8 pipe_id,
struct ath10k_hif_sg_item *items, int n_items); struct ath10k_hif_sg_item *items, int n_items);
/* read firmware memory through the diagnose interface */
int (*diag_read)(struct ath10k *ar, u32 address, void *buf,
size_t buf_len);
/* /*
* API to handle HIF-specific BMI message exchanges, this API is * API to handle HIF-specific BMI message exchanges, this API is
* synchronous and only allowed to be called from a context that * synchronous and only allowed to be called from a context that
...@@ -98,6 +102,12 @@ static inline int ath10k_hif_tx_sg(struct ath10k *ar, u8 pipe_id, ...@@ -98,6 +102,12 @@ static inline int ath10k_hif_tx_sg(struct ath10k *ar, u8 pipe_id,
return ar->hif.ops->tx_sg(ar, pipe_id, items, n_items); return ar->hif.ops->tx_sg(ar, pipe_id, items, n_items);
} }
static inline int ath10k_hif_diag_read(struct ath10k *ar, u32 address, void *buf,
size_t buf_len)
{
return ar->hif.ops->diag_read(ar, address, buf, buf_len);
}
static inline int ath10k_hif_exchange_bmi_msg(struct ath10k *ar, static inline int ath10k_hif_exchange_bmi_msg(struct ath10k *ar,
void *request, u32 request_len, void *request, u32 request_len,
void *response, u32 *response_len) void *response, u32 *response_len)
......
...@@ -485,6 +485,8 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data, ...@@ -485,6 +485,8 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data,
void *data_buf = NULL; void *data_buf = NULL;
int i; int i;
spin_lock_bh(&ar_pci->ce_lock);
ce_diag = ar_pci->ce_diag; ce_diag = ar_pci->ce_diag;
/* /*
...@@ -511,7 +513,7 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data, ...@@ -511,7 +513,7 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data,
nbytes = min_t(unsigned int, remaining_bytes, nbytes = min_t(unsigned int, remaining_bytes,
DIAG_TRANSFER_LIMIT); DIAG_TRANSFER_LIMIT);
ret = ath10k_ce_rx_post_buf(ce_diag, NULL, ce_data); ret = __ath10k_ce_rx_post_buf(ce_diag, NULL, ce_data);
if (ret != 0) if (ret != 0)
goto done; goto done;
...@@ -527,15 +529,15 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data, ...@@ -527,15 +529,15 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data,
address = TARG_CPU_SPACE_TO_CE_SPACE(ar, ar_pci->mem, address = TARG_CPU_SPACE_TO_CE_SPACE(ar, ar_pci->mem,
address); address);
ret = ath10k_ce_send(ce_diag, NULL, (u32)address, nbytes, 0, ret = ath10k_ce_send_nolock(ce_diag, NULL, (u32)address, nbytes, 0,
0); 0);
if (ret) if (ret)
goto done; goto done;
i = 0; i = 0;
while (ath10k_ce_completed_send_next(ce_diag, NULL, &buf, while (ath10k_ce_completed_send_next_nolock(ce_diag, NULL, &buf,
&completed_nbytes, &completed_nbytes,
&id) != 0) { &id) != 0) {
mdelay(1); mdelay(1);
if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) { if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) {
ret = -EBUSY; ret = -EBUSY;
...@@ -554,9 +556,9 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data, ...@@ -554,9 +556,9 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data,
} }
i = 0; i = 0;
while (ath10k_ce_completed_recv_next(ce_diag, NULL, &buf, while (ath10k_ce_completed_recv_next_nolock(ce_diag, NULL, &buf,
&completed_nbytes, &completed_nbytes,
&id, &flags) != 0) { &id, &flags) != 0) {
mdelay(1); mdelay(1);
if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) { if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) {
...@@ -591,6 +593,8 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data, ...@@ -591,6 +593,8 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data,
dma_free_coherent(ar->dev, orig_nbytes, data_buf, dma_free_coherent(ar->dev, orig_nbytes, data_buf,
ce_data_base); ce_data_base);
spin_unlock_bh(&ar_pci->ce_lock);
return ret; return ret;
} }
...@@ -648,6 +652,8 @@ static int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address, ...@@ -648,6 +652,8 @@ static int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address,
dma_addr_t ce_data_base = 0; dma_addr_t ce_data_base = 0;
int i; int i;
spin_lock_bh(&ar_pci->ce_lock);
ce_diag = ar_pci->ce_diag; ce_diag = ar_pci->ce_diag;
/* /*
...@@ -688,7 +694,7 @@ static int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address, ...@@ -688,7 +694,7 @@ static int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address,
nbytes = min_t(int, remaining_bytes, DIAG_TRANSFER_LIMIT); nbytes = min_t(int, remaining_bytes, DIAG_TRANSFER_LIMIT);
/* Set up to receive directly into Target(!) address */ /* Set up to receive directly into Target(!) address */
ret = ath10k_ce_rx_post_buf(ce_diag, NULL, address); ret = __ath10k_ce_rx_post_buf(ce_diag, NULL, address);
if (ret != 0) if (ret != 0)
goto done; goto done;
...@@ -696,15 +702,15 @@ static int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address, ...@@ -696,15 +702,15 @@ static int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address,
* Request CE to send caller-supplied data that * Request CE to send caller-supplied data that
* was copied to bounce buffer to Target(!) address. * was copied to bounce buffer to Target(!) address.
*/ */
ret = ath10k_ce_send(ce_diag, NULL, (u32)ce_data, ret = ath10k_ce_send_nolock(ce_diag, NULL, (u32)ce_data,
nbytes, 0, 0); nbytes, 0, 0);
if (ret != 0) if (ret != 0)
goto done; goto done;
i = 0; i = 0;
while (ath10k_ce_completed_send_next(ce_diag, NULL, &buf, while (ath10k_ce_completed_send_next_nolock(ce_diag, NULL, &buf,
&completed_nbytes, &completed_nbytes,
&id) != 0) { &id) != 0) {
mdelay(1); mdelay(1);
if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) { if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) {
...@@ -724,9 +730,9 @@ static int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address, ...@@ -724,9 +730,9 @@ static int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address,
} }
i = 0; i = 0;
while (ath10k_ce_completed_recv_next(ce_diag, NULL, &buf, while (ath10k_ce_completed_recv_next_nolock(ce_diag, NULL, &buf,
&completed_nbytes, &completed_nbytes,
&id, &flags) != 0) { &id, &flags) != 0) {
mdelay(1); mdelay(1);
if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) { if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) {
...@@ -760,6 +766,8 @@ static int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address, ...@@ -760,6 +766,8 @@ static int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address,
ath10k_warn(ar, "failed to write diag value at 0x%x: %d\n", ath10k_warn(ar, "failed to write diag value at 0x%x: %d\n",
address, ret); address, ret);
spin_unlock_bh(&ar_pci->ce_lock);
return ret; return ret;
} }
...@@ -942,6 +950,12 @@ static int ath10k_pci_hif_tx_sg(struct ath10k *ar, u8 pipe_id, ...@@ -942,6 +950,12 @@ static int ath10k_pci_hif_tx_sg(struct ath10k *ar, u8 pipe_id,
return err; return err;
} }
static int ath10k_pci_hif_diag_read(struct ath10k *ar, u32 address, void *buf,
size_t buf_len)
{
return ath10k_pci_diag_read_mem(ar, address, buf, buf_len);
}
static u16 ath10k_pci_hif_get_free_queue_number(struct ath10k *ar, u8 pipe) static u16 ath10k_pci_hif_get_free_queue_number(struct ath10k *ar, u8 pipe)
{ {
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
...@@ -1927,6 +1941,7 @@ static int ath10k_pci_hif_resume(struct ath10k *ar) ...@@ -1927,6 +1941,7 @@ static int ath10k_pci_hif_resume(struct ath10k *ar)
static const struct ath10k_hif_ops ath10k_pci_hif_ops = { static const struct ath10k_hif_ops ath10k_pci_hif_ops = {
.tx_sg = ath10k_pci_hif_tx_sg, .tx_sg = ath10k_pci_hif_tx_sg,
.diag_read = ath10k_pci_hif_diag_read,
.exchange_bmi_msg = ath10k_pci_hif_exchange_bmi_msg, .exchange_bmi_msg = ath10k_pci_hif_exchange_bmi_msg,
.start = ath10k_pci_hif_start, .start = ath10k_pci_hif_start,
.stop = ath10k_pci_hif_stop, .stop = ath10k_pci_hif_stop,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment