diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2012-09-14 17:31:33 +0100 |
---|---|---|
committer | Ben Hutchings <bhutchings@solarflare.com> | 2013-08-21 16:35:26 +0100 |
commit | c5bb0e9891ba1f7c871adc09d9ef727e1c0c1c1e (patch) | |
tree | 62bf62dbc591718aade11df087dbdb9bc3862b85 /drivers/net/ethernet/sfc/siena_sriov.c | |
parent | d0c2ee99e54c0fd76938236e863ad7d3992f044f (diff) | |
download | blackbird-op-linux-c5bb0e9891ba1f7c871adc09d9ef727e1c0c1c1e.tar.gz blackbird-op-linux-c5bb0e9891ba1f7c871adc09d9ef727e1c0c1c1e.zip |
sfc: Use proper macros to declare and access MCDI arrays
A few functions are using heap buffers; change them to use stack
buffers as we really don't need to resort to the heap for a 252
byte buffer in process context.
MC_CMD_MEMCPY is quite weird in that it can use inline data placed in
the request buffer after the array of records. Thus there are two
variable-length arrays and we can't use the normal accessors for
the second. So we have to use _MCDI_PTR() in efx_sriov_memcpy().
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Diffstat (limited to 'drivers/net/ethernet/sfc/siena_sriov.c')
-rw-r--r-- | drivers/net/ethernet/sfc/siena_sriov.c | 53 |
1 files changed, 25 insertions, 28 deletions
diff --git a/drivers/net/ethernet/sfc/siena_sriov.c b/drivers/net/ethernet/sfc/siena_sriov.c index c376e90c4c37..198044f80a05 100644 --- a/drivers/net/ethernet/sfc/siena_sriov.c +++ b/drivers/net/ethernet/sfc/siena_sriov.c @@ -240,25 +240,22 @@ static void efx_sriov_usrev(struct efx_nic *efx, bool enabled) static int efx_sriov_memcpy(struct efx_nic *efx, struct efx_memcpy_req *req, unsigned int count) { - u8 *inbuf, *record; - unsigned int used; + MCDI_DECLARE_BUF(inbuf, MCDI_CTL_SDU_LEN_MAX_V1); + MCDI_DECLARE_STRUCT_PTR(record); + unsigned int index, used; u32 from_rid, from_hi, from_lo; int rc; mb(); /* Finish writing source/reading dest before DMA starts */ - used = MC_CMD_MEMCPY_IN_LEN(count); - if (WARN_ON(used > MCDI_CTL_SDU_LEN_MAX_V1)) + if (WARN_ON(count > MC_CMD_MEMCPY_IN_RECORD_MAXNUM)) return -ENOBUFS; + used = MC_CMD_MEMCPY_IN_LEN(count); - /* Allocate room for the largest request */ - inbuf = kzalloc(MCDI_CTL_SDU_LEN_MAX_V1, GFP_KERNEL); - if (inbuf == NULL) - return -ENOMEM; - - record = inbuf; - MCDI_SET_DWORD(record, MEMCPY_IN_RECORD, count); - while (count-- > 0) { + for (index = 0; index < count; index++) { + record = MCDI_ARRAY_STRUCT_PTR(inbuf, MEMCPY_IN_RECORD, index); + MCDI_SET_DWORD(record, MEMCPY_RECORD_TYPEDEF_NUM_RECORDS, + count); MCDI_SET_DWORD(record, MEMCPY_RECORD_TYPEDEF_TO_RID, req->to_rid); MCDI_SET_DWORD(record, MEMCPY_RECORD_TYPEDEF_TO_ADDR_LO, @@ -279,7 +276,8 @@ static int efx_sriov_memcpy(struct efx_nic *efx, struct efx_memcpy_req *req, from_rid = MC_CMD_MEMCPY_RECORD_TYPEDEF_RID_INLINE; from_lo = used; from_hi = 0; - memcpy(inbuf + used, req->from_buf, req->length); + memcpy(_MCDI_PTR(inbuf, used), req->from_buf, + req->length); used += req->length; } @@ -292,13 +290,10 @@ static int efx_sriov_memcpy(struct efx_nic *efx, struct efx_memcpy_req *req, req->length); ++req; - record += MC_CMD_MEMCPY_IN_RECORD_LEN; } rc = efx_mcdi_rpc(efx, MC_CMD_MEMCPY, inbuf, used, NULL, 0, NULL); out: - kfree(inbuf); - mb(); /* Don't write source/read dest before DMA is complete */ return rc; @@ -685,16 +680,12 @@ static int efx_vfdi_fini_all_queues(struct efx_vf *vf) unsigned vf_offset = EFX_VI_BASE + vf->index * efx_vf_size(efx); unsigned timeout = HZ; unsigned index, rxqs_count; - __le32 *rxqs; + MCDI_DECLARE_BUF(inbuf, MC_CMD_FLUSH_RX_QUEUES_IN_LENMAX); int rc; BUILD_BUG_ON(VF_MAX_RX_QUEUES > MC_CMD_FLUSH_RX_QUEUES_IN_QID_OFST_MAXNUM); - rxqs = kmalloc(count * sizeof(*rxqs), GFP_KERNEL); - if (rxqs == NULL) - return VFDI_RC_ENOMEM; - rtnl_lock(); siena_prepare_flush(efx); rtnl_unlock(); @@ -709,14 +700,19 @@ static int efx_vfdi_fini_all_queues(struct efx_vf *vf) vf_offset + index); efx_writeo(efx, ®, FR_AZ_TX_FLUSH_DESCQ); } - if (test_bit(index, vf->rxq_mask)) - rxqs[rxqs_count++] = cpu_to_le32(vf_offset + index); + if (test_bit(index, vf->rxq_mask)) { + MCDI_SET_ARRAY_DWORD( + inbuf, FLUSH_RX_QUEUES_IN_QID_OFST, + rxqs_count, vf_offset + index); + rxqs_count++; + } } atomic_set(&vf->rxq_retry_count, 0); while (timeout && (vf->rxq_count || vf->txq_count)) { - rc = efx_mcdi_rpc(efx, MC_CMD_FLUSH_RX_QUEUES, (u8 *)rxqs, - rxqs_count * sizeof(*rxqs), NULL, 0, NULL); + rc = efx_mcdi_rpc(efx, MC_CMD_FLUSH_RX_QUEUES, inbuf, + MC_CMD_FLUSH_RX_QUEUES_IN_LEN(rxqs_count), + NULL, 0, NULL); WARN_ON(rc < 0); timeout = wait_event_timeout(vf->flush_waitq, @@ -726,8 +722,10 @@ static int efx_vfdi_fini_all_queues(struct efx_vf *vf) for (index = 0; index < count; ++index) { if (test_and_clear_bit(index, vf->rxq_retry_mask)) { atomic_dec(&vf->rxq_retry_count); - rxqs[rxqs_count++] = - cpu_to_le32(vf_offset + index); + MCDI_SET_ARRAY_DWORD( + inbuf, FLUSH_RX_QUEUES_IN_QID_OFST, + rxqs_count, vf_offset + index); + rxqs_count++; } } } @@ -750,7 +748,6 @@ static int efx_vfdi_fini_all_queues(struct efx_vf *vf) } efx_sriov_bufs(efx, vf->buftbl_base, NULL, EFX_VF_BUFTBL_PER_VI * efx_vf_size(efx)); - kfree(rxqs); efx_vfdi_flush_clear(vf); vf->evq0_count = 0; |