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: Kalle Valo <kvalo@qca.qualcomm.com>
This commit is contained in:
parent
d5d6805bf9
commit
eef254051f
|
@ -443,7 +443,7 @@ 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,
|
||||||
|
@ -576,7 +576,7 @@ 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,
|
||||||
|
|
|
@ -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,
|
||||||
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 {
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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,13 +529,13 @@ 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);
|
||||||
|
@ -554,7 +556,7 @@ 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);
|
||||||
|
@ -591,6 +593,8 @@ done:
|
||||||
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,
|
||||||
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,
|
||||||
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,13 +702,13 @@ 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);
|
||||||
|
@ -724,7 +730,7 @@ 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);
|
||||||
|
@ -760,6 +766,8 @@ done:
|
||||||
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 @@ err:
|
||||||
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)
|
||||||
|
|
||||||
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,
|
||||||
|
|
Loading…
Reference in New Issue