Commit c5bb0e98 authored by Ben Hutchings's avatar Ben Hutchings

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: default avatarBen Hutchings <bhutchings@solarflare.com>
parent d0c2ee99
...@@ -668,7 +668,7 @@ int efx_mcdi_get_board_cfg(struct efx_nic *efx, u8 *mac_address, ...@@ -668,7 +668,7 @@ int efx_mcdi_get_board_cfg(struct efx_nic *efx, u8 *mac_address,
u16 *fw_subtype_list, u32 *capabilities) u16 *fw_subtype_list, u32 *capabilities)
{ {
MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_BOARD_CFG_OUT_LENMAX); MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_BOARD_CFG_OUT_LENMAX);
size_t outlen, offset, i; size_t outlen, i;
int port_num = efx_port_num(efx); int port_num = efx_port_num(efx);
int rc; int rc;
...@@ -684,22 +684,21 @@ int efx_mcdi_get_board_cfg(struct efx_nic *efx, u8 *mac_address, ...@@ -684,22 +684,21 @@ int efx_mcdi_get_board_cfg(struct efx_nic *efx, u8 *mac_address,
goto fail; goto fail;
} }
offset = (port_num)
? MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT1_OFST
: MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT0_OFST;
if (mac_address) if (mac_address)
memcpy(mac_address, outbuf + offset, ETH_ALEN); memcpy(mac_address,
port_num ?
MCDI_PTR(outbuf, GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT1) :
MCDI_PTR(outbuf, GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT0),
ETH_ALEN);
if (fw_subtype_list) { if (fw_subtype_list) {
/* Byte-swap and truncate or zero-pad as necessary */
offset = MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_OFST;
for (i = 0; for (i = 0;
i < MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_MAXNUM; i < MCDI_VAR_ARRAY_LEN(outlen,
i++) { GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST);
fw_subtype_list[i] = i++)
(offset + 2 <= outlen) ? fw_subtype_list[i] = MCDI_ARRAY_WORD(
le16_to_cpup((__le16 *)(outbuf + offset)) : 0; outbuf, GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST, i);
offset += 2; for (; i < MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_MAXNUM; i++)
} fw_subtype_list[i] = 0;
} }
if (capabilities) { if (capabilities) {
if (port_num) if (port_num)
...@@ -980,7 +979,7 @@ static int efx_mcdi_read_assertion(struct efx_nic *efx) ...@@ -980,7 +979,7 @@ static int efx_mcdi_read_assertion(struct efx_nic *efx)
{ {
MCDI_DECLARE_BUF(inbuf, MC_CMD_GET_ASSERTS_IN_LEN); MCDI_DECLARE_BUF(inbuf, MC_CMD_GET_ASSERTS_IN_LEN);
MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_ASSERTS_OUT_LEN); MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_ASSERTS_OUT_LEN);
unsigned int flags, index, ofst; unsigned int flags, index;
const char *reason; const char *reason;
size_t outlen; size_t outlen;
int retry; int retry;
...@@ -1022,12 +1021,13 @@ static int efx_mcdi_read_assertion(struct efx_nic *efx) ...@@ -1022,12 +1021,13 @@ static int efx_mcdi_read_assertion(struct efx_nic *efx)
MCDI_DWORD(outbuf, GET_ASSERTS_OUT_THREAD_OFFS)); MCDI_DWORD(outbuf, GET_ASSERTS_OUT_THREAD_OFFS));
/* Print out the registers */ /* Print out the registers */
ofst = MC_CMD_GET_ASSERTS_OUT_GP_REGS_OFFS_OFST; for (index = 0;
for (index = 1; index < 32; index++) { index < MC_CMD_GET_ASSERTS_OUT_GP_REGS_OFFS_NUM;
netif_err(efx, hw, efx->net_dev, "R%.2d (?): 0x%.8x\n", index, index++)
MCDI_DWORD2(outbuf, ofst)); netif_err(efx, hw, efx->net_dev, "R%.2d (?): 0x%.8x\n",
ofst += sizeof(efx_dword_t); 1 + index,
} MCDI_ARRAY_DWORD(outbuf, GET_ASSERTS_OUT_GP_REGS_OFFS,
index));
return 0; return 0;
} }
...@@ -1201,34 +1201,31 @@ int efx_mcdi_flush_rxqs(struct efx_nic *efx) ...@@ -1201,34 +1201,31 @@ int efx_mcdi_flush_rxqs(struct efx_nic *efx)
{ {
struct efx_channel *channel; struct efx_channel *channel;
struct efx_rx_queue *rx_queue; struct efx_rx_queue *rx_queue;
__le32 *qid; MCDI_DECLARE_BUF(inbuf,
MC_CMD_FLUSH_RX_QUEUES_IN_LEN(EFX_MAX_CHANNELS));
int rc, count; int rc, count;
BUILD_BUG_ON(EFX_MAX_CHANNELS > BUILD_BUG_ON(EFX_MAX_CHANNELS >
MC_CMD_FLUSH_RX_QUEUES_IN_QID_OFST_MAXNUM); MC_CMD_FLUSH_RX_QUEUES_IN_QID_OFST_MAXNUM);
qid = kmalloc(EFX_MAX_CHANNELS * sizeof(*qid), GFP_KERNEL);
if (qid == NULL)
return -ENOMEM;
count = 0; count = 0;
efx_for_each_channel(channel, efx) { efx_for_each_channel(channel, efx) {
efx_for_each_channel_rx_queue(rx_queue, channel) { efx_for_each_channel_rx_queue(rx_queue, channel) {
if (rx_queue->flush_pending) { if (rx_queue->flush_pending) {
rx_queue->flush_pending = false; rx_queue->flush_pending = false;
atomic_dec(&efx->rxq_flush_pending); atomic_dec(&efx->rxq_flush_pending);
qid[count++] = cpu_to_le32( MCDI_SET_ARRAY_DWORD(
efx_rx_queue_index(rx_queue)); inbuf, FLUSH_RX_QUEUES_IN_QID_OFST,
count, efx_rx_queue_index(rx_queue));
count++;
} }
} }
} }
rc = efx_mcdi_rpc(efx, MC_CMD_FLUSH_RX_QUEUES, (u8 *)qid, rc = efx_mcdi_rpc(efx, MC_CMD_FLUSH_RX_QUEUES, inbuf,
count * sizeof(*qid), NULL, 0, NULL); MC_CMD_FLUSH_RX_QUEUES_IN_LEN(count), NULL, 0, NULL);
WARN_ON(rc < 0); WARN_ON(rc < 0);
kfree(qid);
return rc; return rc;
} }
......
...@@ -94,9 +94,6 @@ extern void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev); ...@@ -94,9 +94,6 @@ extern void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev);
#define _MCDI_DWORD(_buf, _field) \ #define _MCDI_DWORD(_buf, _field) \
((efx_dword_t *)MCDI_PTR(_buf, _field)) ((efx_dword_t *)MCDI_PTR(_buf, _field))
#define MCDI_DWORD2(_buf, _ofst) \
EFX_DWORD_FIELD(*(efx_dword_t *)((u8 *)(_buf) + (_ofst)), EFX_DWORD_0)
#define MCDI_SET_DWORD(_buf, _field, _value) \ #define MCDI_SET_DWORD(_buf, _field, _value) \
EFX_POPULATE_DWORD_1(*_MCDI_DWORD(_buf, _field), EFX_DWORD_0, _value) EFX_POPULATE_DWORD_1(*_MCDI_DWORD(_buf, _field), EFX_DWORD_0, _value)
#define MCDI_DWORD(_buf, _field) \ #define MCDI_DWORD(_buf, _field) \
......
...@@ -17,7 +17,7 @@ int efx_mcdi_set_mac(struct efx_nic *efx) ...@@ -17,7 +17,7 @@ int efx_mcdi_set_mac(struct efx_nic *efx)
u32 reject, fcntl; u32 reject, fcntl;
MCDI_DECLARE_BUF(cmdbytes, MC_CMD_SET_MAC_IN_LEN); MCDI_DECLARE_BUF(cmdbytes, MC_CMD_SET_MAC_IN_LEN);
memcpy(cmdbytes + MC_CMD_SET_MAC_IN_ADDR_OFST, memcpy(MCDI_PTR(cmdbytes, SET_MAC_IN_ADDR),
efx->net_dev->dev_addr, ETH_ALEN); efx->net_dev->dev_addr, ETH_ALEN);
MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_MTU, MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_MTU,
......
...@@ -615,17 +615,15 @@ static int efx_mcdi_bist(struct efx_nic *efx, unsigned int bist_mode, ...@@ -615,17 +615,15 @@ static int efx_mcdi_bist(struct efx_nic *efx, unsigned int bist_mode,
unsigned int retry, i, count = 0; unsigned int retry, i, count = 0;
size_t outlen; size_t outlen;
u32 status; u32 status;
u8 *buf, *ptr; MCDI_DECLARE_BUF(inbuf, MC_CMD_START_BIST_IN_LEN);
MCDI_DECLARE_BUF(outbuf, MC_CMD_POLL_BIST_OUT_SFT9001_LEN);
u8 *ptr;
int rc; int rc;
buf = kzalloc(0x100, GFP_KERNEL);
if (buf == NULL)
return -ENOMEM;
BUILD_BUG_ON(MC_CMD_START_BIST_OUT_LEN != 0); BUILD_BUG_ON(MC_CMD_START_BIST_OUT_LEN != 0);
MCDI_SET_DWORD(buf, START_BIST_IN_TYPE, bist_mode); MCDI_SET_DWORD(inbuf, START_BIST_IN_TYPE, bist_mode);
rc = efx_mcdi_rpc(efx, MC_CMD_START_BIST, buf, MC_CMD_START_BIST_IN_LEN, rc = efx_mcdi_rpc(efx, MC_CMD_START_BIST,
NULL, 0, NULL); inbuf, MC_CMD_START_BIST_IN_LEN, NULL, 0, NULL);
if (rc) if (rc)
goto out; goto out;
...@@ -633,11 +631,11 @@ static int efx_mcdi_bist(struct efx_nic *efx, unsigned int bist_mode, ...@@ -633,11 +631,11 @@ static int efx_mcdi_bist(struct efx_nic *efx, unsigned int bist_mode,
for (retry = 0; retry < 100; ++retry) { for (retry = 0; retry < 100; ++retry) {
BUILD_BUG_ON(MC_CMD_POLL_BIST_IN_LEN != 0); BUILD_BUG_ON(MC_CMD_POLL_BIST_IN_LEN != 0);
rc = efx_mcdi_rpc(efx, MC_CMD_POLL_BIST, NULL, 0, rc = efx_mcdi_rpc(efx, MC_CMD_POLL_BIST, NULL, 0,
buf, 0x100, &outlen); outbuf, sizeof(outbuf), &outlen);
if (rc) if (rc)
goto out; goto out;
status = MCDI_DWORD(buf, POLL_BIST_OUT_RESULT); status = MCDI_DWORD(outbuf, POLL_BIST_OUT_RESULT);
if (status != MC_CMD_POLL_BIST_RUNNING) if (status != MC_CMD_POLL_BIST_RUNNING)
goto finished; goto finished;
...@@ -654,7 +652,7 @@ static int efx_mcdi_bist(struct efx_nic *efx, unsigned int bist_mode, ...@@ -654,7 +652,7 @@ static int efx_mcdi_bist(struct efx_nic *efx, unsigned int bist_mode,
if (efx->phy_type == PHY_TYPE_SFT9001B && if (efx->phy_type == PHY_TYPE_SFT9001B &&
(bist_mode == MC_CMD_PHY_BIST_CABLE_SHORT || (bist_mode == MC_CMD_PHY_BIST_CABLE_SHORT ||
bist_mode == MC_CMD_PHY_BIST_CABLE_LONG)) { bist_mode == MC_CMD_PHY_BIST_CABLE_LONG)) {
ptr = MCDI_PTR(buf, POLL_BIST_OUT_SFT9001_CABLE_LENGTH_A); ptr = MCDI_PTR(outbuf, POLL_BIST_OUT_SFT9001_CABLE_LENGTH_A);
if (status == MC_CMD_POLL_BIST_PASSED && if (status == MC_CMD_POLL_BIST_PASSED &&
outlen >= MC_CMD_POLL_BIST_OUT_SFT9001_LEN) { outlen >= MC_CMD_POLL_BIST_OUT_SFT9001_LEN) {
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
...@@ -668,8 +666,6 @@ static int efx_mcdi_bist(struct efx_nic *efx, unsigned int bist_mode, ...@@ -668,8 +666,6 @@ static int efx_mcdi_bist(struct efx_nic *efx, unsigned int bist_mode,
rc = count; rc = count;
out: out:
kfree(buf);
return rc; return rc;
} }
...@@ -785,8 +781,7 @@ static int efx_mcdi_phy_get_module_eeprom(struct efx_nic *efx, ...@@ -785,8 +781,7 @@ static int efx_mcdi_phy_get_module_eeprom(struct efx_nic *efx,
space_remaining : payload_len; space_remaining : payload_len;
memcpy(user_data, memcpy(user_data,
outbuf + page_off + MCDI_PTR(outbuf, GET_PHY_MEDIA_INFO_OUT_DATA) + page_off,
MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_OFST,
to_copy); to_copy);
space_remaining -= to_copy; space_remaining -= to_copy;
......
...@@ -294,8 +294,7 @@ struct efx_ptp_data { ...@@ -294,8 +294,7 @@ struct efx_ptp_data {
struct work_struct pps_work; struct work_struct pps_work;
struct workqueue_struct *pps_workwq; struct workqueue_struct *pps_workwq;
bool nic_ts_enabled; bool nic_ts_enabled;
u8 txbuf[ALIGN(MC_CMD_PTP_IN_TRANSMIT_LEN( MCDI_DECLARE_BUF(txbuf, MC_CMD_PTP_IN_TRANSMIT_LENMAX);
MC_CMD_PTP_IN_TRANSMIT_PACKET_MAXNUM), 4)];
struct efx_ptp_timeset struct efx_ptp_timeset
timeset[MC_CMD_PTP_OUT_SYNCHRONIZE_TIMESET_MAXNUM]; timeset[MC_CMD_PTP_OUT_SYNCHRONIZE_TIMESET_MAXNUM];
}; };
...@@ -396,7 +395,8 @@ static void efx_ptp_send_times(struct efx_nic *efx, ...@@ -396,7 +395,8 @@ static void efx_ptp_send_times(struct efx_nic *efx,
} }
/* Read a timeset from the MC's results and partial process. */ /* Read a timeset from the MC's results and partial process. */
static void efx_ptp_read_timeset(u8 *data, struct efx_ptp_timeset *timeset) static void efx_ptp_read_timeset(MCDI_DECLARE_STRUCT_PTR(data),
struct efx_ptp_timeset *timeset)
{ {
unsigned start_ns, end_ns; unsigned start_ns, end_ns;
...@@ -425,12 +425,14 @@ static void efx_ptp_read_timeset(u8 *data, struct efx_ptp_timeset *timeset) ...@@ -425,12 +425,14 @@ static void efx_ptp_read_timeset(u8 *data, struct efx_ptp_timeset *timeset)
* busy. A number of readings are taken so that, hopefully, at least one good * busy. A number of readings are taken so that, hopefully, at least one good
* synchronisation will be seen in the results. * synchronisation will be seen in the results.
*/ */
static int efx_ptp_process_times(struct efx_nic *efx, u8 *synch_buf, static int
size_t response_length, efx_ptp_process_times(struct efx_nic *efx, MCDI_DECLARE_STRUCT_PTR(synch_buf),
const struct pps_event_time *last_time) size_t response_length,
const struct pps_event_time *last_time)
{ {
unsigned number_readings = (response_length / unsigned number_readings =
MC_CMD_PTP_OUT_SYNCHRONIZE_TIMESET_LEN); MCDI_VAR_ARRAY_LEN(response_length,
PTP_OUT_SYNCHRONIZE_TIMESET);
unsigned i; unsigned i;
unsigned total; unsigned total;
unsigned ngood = 0; unsigned ngood = 0;
...@@ -447,8 +449,10 @@ static int efx_ptp_process_times(struct efx_nic *efx, u8 *synch_buf, ...@@ -447,8 +449,10 @@ static int efx_ptp_process_times(struct efx_nic *efx, u8 *synch_buf,
* appera to be erroneous. * appera to be erroneous.
*/ */
for (i = 0; i < number_readings; i++) { for (i = 0; i < number_readings; i++) {
efx_ptp_read_timeset(synch_buf, &ptp->timeset[i]); efx_ptp_read_timeset(
synch_buf += MC_CMD_PTP_OUT_SYNCHRONIZE_TIMESET_LEN; MCDI_ARRAY_STRUCT_PTR(synch_buf,
PTP_OUT_SYNCHRONIZE_TIMESET, i),
&ptp->timeset[i]);
} }
/* Find the last good host-MC synchronization result. The MC times /* Find the last good host-MC synchronization result. The MC times
...@@ -564,15 +568,15 @@ static int efx_ptp_synchronize(struct efx_nic *efx, unsigned int num_readings) ...@@ -564,15 +568,15 @@ static int efx_ptp_synchronize(struct efx_nic *efx, unsigned int num_readings)
/* Transmit a PTP packet, via the MCDI interface, to the wire. */ /* Transmit a PTP packet, via the MCDI interface, to the wire. */
static int efx_ptp_xmit_skb(struct efx_nic *efx, struct sk_buff *skb) static int efx_ptp_xmit_skb(struct efx_nic *efx, struct sk_buff *skb)
{ {
u8 *txbuf = efx->ptp_data->txbuf; struct efx_ptp_data *ptp_data = efx->ptp_data;
struct skb_shared_hwtstamps timestamps; struct skb_shared_hwtstamps timestamps;
int rc = -EIO; int rc = -EIO;
/* MCDI driver requires word aligned lengths */ /* MCDI driver requires word aligned lengths */
size_t len = ALIGN(MC_CMD_PTP_IN_TRANSMIT_LEN(skb->len), 4); size_t len = ALIGN(MC_CMD_PTP_IN_TRANSMIT_LEN(skb->len), 4);
MCDI_DECLARE_BUF(txtime, MC_CMD_PTP_OUT_TRANSMIT_LEN); MCDI_DECLARE_BUF(txtime, MC_CMD_PTP_OUT_TRANSMIT_LEN);
MCDI_SET_DWORD(txbuf, PTP_IN_OP, MC_CMD_PTP_OP_TRANSMIT); MCDI_SET_DWORD(ptp_data->txbuf, PTP_IN_OP, MC_CMD_PTP_OP_TRANSMIT);
MCDI_SET_DWORD(txbuf, PTP_IN_TRANSMIT_LENGTH, skb->len); MCDI_SET_DWORD(ptp_data->txbuf, PTP_IN_TRANSMIT_LENGTH, skb->len);
if (skb_shinfo(skb)->nr_frags != 0) { if (skb_shinfo(skb)->nr_frags != 0) {
rc = skb_linearize(skb); rc = skb_linearize(skb);
if (rc != 0) if (rc != 0)
...@@ -585,9 +589,10 @@ static int efx_ptp_xmit_skb(struct efx_nic *efx, struct sk_buff *skb) ...@@ -585,9 +589,10 @@ static int efx_ptp_xmit_skb(struct efx_nic *efx, struct sk_buff *skb)
goto fail; goto fail;
} }
skb_copy_from_linear_data(skb, skb_copy_from_linear_data(skb,
&txbuf[MC_CMD_PTP_IN_TRANSMIT_PACKET_OFST], MCDI_PTR(ptp_data->txbuf,
PTP_IN_TRANSMIT_PACKET),
len); len);
rc = efx_mcdi_rpc(efx, MC_CMD_PTP, txbuf, len, txtime, rc = efx_mcdi_rpc(efx, MC_CMD_PTP, ptp_data->txbuf, len, txtime,
sizeof(txtime), &len); sizeof(txtime), &len);
if (rc != 0) if (rc != 0)
goto fail; goto fail;
......
...@@ -240,25 +240,22 @@ static void efx_sriov_usrev(struct efx_nic *efx, bool enabled) ...@@ -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, static int efx_sriov_memcpy(struct efx_nic *efx, struct efx_memcpy_req *req,
unsigned int count) unsigned int count)
{ {
u8 *inbuf, *record; MCDI_DECLARE_BUF(inbuf, MCDI_CTL_SDU_LEN_MAX_V1);
unsigned int used; MCDI_DECLARE_STRUCT_PTR(record);
unsigned int index, used;
u32 from_rid, from_hi, from_lo; u32 from_rid, from_hi, from_lo;
int rc; int rc;
mb(); /* Finish writing source/reading dest before DMA starts */ mb(); /* Finish writing source/reading dest before DMA starts */
used = MC_CMD_MEMCPY_IN_LEN(count); if (WARN_ON(count > MC_CMD_MEMCPY_IN_RECORD_MAXNUM))
if (WARN_ON(used > MCDI_CTL_SDU_LEN_MAX_V1))
return -ENOBUFS; return -ENOBUFS;
used = MC_CMD_MEMCPY_IN_LEN(count);
/* Allocate room for the largest request */ for (index = 0; index < count; index++) {
inbuf = kzalloc(MCDI_CTL_SDU_LEN_MAX_V1, GFP_KERNEL); record = MCDI_ARRAY_STRUCT_PTR(inbuf, MEMCPY_IN_RECORD, index);
if (inbuf == NULL) MCDI_SET_DWORD(record, MEMCPY_RECORD_TYPEDEF_NUM_RECORDS,
return -ENOMEM; count);
record = inbuf;
MCDI_SET_DWORD(record, MEMCPY_IN_RECORD, count);
while (count-- > 0) {
MCDI_SET_DWORD(record, MEMCPY_RECORD_TYPEDEF_TO_RID, MCDI_SET_DWORD(record, MEMCPY_RECORD_TYPEDEF_TO_RID,
req->to_rid); req->to_rid);
MCDI_SET_DWORD(record, MEMCPY_RECORD_TYPEDEF_TO_ADDR_LO, 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, ...@@ -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_rid = MC_CMD_MEMCPY_RECORD_TYPEDEF_RID_INLINE;
from_lo = used; from_lo = used;
from_hi = 0; from_hi = 0;
memcpy(inbuf + used, req->from_buf, req->length); memcpy(_MCDI_PTR(inbuf, used), req->from_buf,
req->length);
used += req->length; used += req->length;
} }
...@@ -292,13 +290,10 @@ static int efx_sriov_memcpy(struct efx_nic *efx, struct efx_memcpy_req *req, ...@@ -292,13 +290,10 @@ static int efx_sriov_memcpy(struct efx_nic *efx, struct efx_memcpy_req *req,
req->length); req->length);
++req; ++req;
record += MC_CMD_MEMCPY_IN_RECORD_LEN;
} }
rc = efx_mcdi_rpc(efx, MC_CMD_MEMCPY, inbuf, used, NULL, 0, NULL); rc = efx_mcdi_rpc(efx, MC_CMD_MEMCPY, inbuf, used, NULL, 0, NULL);
out: out:
kfree(inbuf);
mb(); /* Don't write source/read dest before DMA is complete */ mb(); /* Don't write source/read dest before DMA is complete */
return rc; return rc;
...@@ -685,16 +680,12 @@ static int efx_vfdi_fini_all_queues(struct efx_vf *vf) ...@@ -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 vf_offset = EFX_VI_BASE + vf->index * efx_vf_size(efx);
unsigned timeout = HZ; unsigned timeout = HZ;
unsigned index, rxqs_count; unsigned index, rxqs_count;
__le32 *rxqs; MCDI_DECLARE_BUF(inbuf, MC_CMD_FLUSH_RX_QUEUES_IN_LENMAX);
int rc; int rc;
BUILD_BUG_ON(VF_MAX_RX_QUEUES > BUILD_BUG_ON(VF_MAX_RX_QUEUES >
MC_CMD_FLUSH_RX_QUEUES_IN_QID_OFST_MAXNUM); 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(); rtnl_lock();
siena_prepare_flush(efx); siena_prepare_flush(efx);
rtnl_unlock(); rtnl_unlock();
...@@ -709,14 +700,19 @@ static int efx_vfdi_fini_all_queues(struct efx_vf *vf) ...@@ -709,14 +700,19 @@ static int efx_vfdi_fini_all_queues(struct efx_vf *vf)
vf_offset + index); vf_offset + index);
efx_writeo(efx, &reg, FR_AZ_TX_FLUSH_DESCQ); efx_writeo(efx, &reg, FR_AZ_TX_FLUSH_DESCQ);
} }
if (test_bit(index, vf->rxq_mask)) if (test_bit(index, vf->rxq_mask)) {
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++;
}
} }
atomic_set(&vf->rxq_retry_count, 0); atomic_set(&vf->rxq_retry_count, 0);
while (timeout && (vf->rxq_count || vf->txq_count)) { while (timeout && (vf->rxq_count || vf->txq_count)) {
rc = efx_mcdi_rpc(efx, MC_CMD_FLUSH_RX_QUEUES, (u8 *)rxqs, rc = efx_mcdi_rpc(efx, MC_CMD_FLUSH_RX_QUEUES, inbuf,
rxqs_count * sizeof(*rxqs), NULL, 0, NULL); MC_CMD_FLUSH_RX_QUEUES_IN_LEN(rxqs_count),
NULL, 0, NULL);
WARN_ON(rc < 0); WARN_ON(rc < 0);
timeout = wait_event_timeout(vf->flush_waitq, timeout = wait_event_timeout(vf->flush_waitq,
...@@ -726,8 +722,10 @@ static int efx_vfdi_fini_all_queues(struct efx_vf *vf) ...@@ -726,8 +722,10 @@ static int efx_vfdi_fini_all_queues(struct efx_vf *vf)
for (index = 0; index < count; ++index) { for (index = 0; index < count; ++index) {
if (test_and_clear_bit(index, vf->rxq_retry_mask)) { if (test_and_clear_bit(index, vf->rxq_retry_mask)) {
atomic_dec(&vf->rxq_retry_count); atomic_dec(&vf->rxq_retry_count);
rxqs[rxqs_count++] = MCDI_SET_ARRAY_DWORD(
cpu_to_le32(vf_offset + index); 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) ...@@ -750,7 +748,6 @@ static int efx_vfdi_fini_all_queues(struct efx_vf *vf)
} }
efx_sriov_bufs(efx, vf->buftbl_base, NULL, efx_sriov_bufs(efx, vf->buftbl_base, NULL,
EFX_VF_BUFTBL_PER_VI * efx_vf_size(efx)); EFX_VF_BUFTBL_PER_VI * efx_vf_size(efx));
kfree(rxqs);
efx_vfdi_flush_clear(vf); efx_vfdi_flush_clear(vf);
vf->evq0_count = 0; vf->evq0_count = 0;
......
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