aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/sfc
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2012-09-14 12:31:33 -0400
committerBen Hutchings <bhutchings@solarflare.com>2013-08-21 11:35:26 -0400
commitc5bb0e9891ba1f7c871adc09d9ef727e1c0c1c1e (patch)
tree62bf62dbc591718aade11df087dbdb9bc3862b85 /drivers/net/ethernet/sfc
parentd0c2ee99e54c0fd76938236e863ad7d3992f044f (diff)
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')
-rw-r--r--drivers/net/ethernet/sfc/mcdi.c61
-rw-r--r--drivers/net/ethernet/sfc/mcdi.h3
-rw-r--r--drivers/net/ethernet/sfc/mcdi_mac.c2
-rw-r--r--drivers/net/ethernet/sfc/mcdi_phy.c25
-rw-r--r--drivers/net/ethernet/sfc/ptp.c35
-rw-r--r--drivers/net/ethernet/sfc/siena_sriov.c53
6 files changed, 85 insertions, 94 deletions
diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c
index d65b562af567..d6d1ff19c918 100644
--- a/drivers/net/ethernet/sfc/mcdi.c
+++ b/drivers/net/ethernet/sfc/mcdi.c
@@ -668,7 +668,7 @@ int efx_mcdi_get_board_cfg(struct efx_nic *efx, u8 *mac_address,
668 u16 *fw_subtype_list, u32 *capabilities) 668 u16 *fw_subtype_list, u32 *capabilities)
669{ 669{
670 MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_BOARD_CFG_OUT_LENMAX); 670 MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_BOARD_CFG_OUT_LENMAX);
671 size_t outlen, offset, i; 671 size_t outlen, i;
672 int port_num = efx_port_num(efx); 672 int port_num = efx_port_num(efx);
673 int rc; 673 int rc;
674 674
@@ -684,22 +684,21 @@ int efx_mcdi_get_board_cfg(struct efx_nic *efx, u8 *mac_address,
684 goto fail; 684 goto fail;
685 } 685 }
686 686
687 offset = (port_num)
688 ? MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT1_OFST
689 : MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT0_OFST;
690 if (mac_address) 687 if (mac_address)
691 memcpy(mac_address, outbuf + offset, ETH_ALEN); 688 memcpy(mac_address,
689 port_num ?
690 MCDI_PTR(outbuf, GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT1) :
691 MCDI_PTR(outbuf, GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT0),
692 ETH_ALEN);
692 if (fw_subtype_list) { 693 if (fw_subtype_list) {
693 /* Byte-swap and truncate or zero-pad as necessary */
694 offset = MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_OFST;
695 for (i = 0; 694 for (i = 0;
696 i < MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_MAXNUM; 695 i < MCDI_VAR_ARRAY_LEN(outlen,
697 i++) { 696 GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST);
698 fw_subtype_list[i] = 697 i++)
699 (offset + 2 <= outlen) ? 698 fw_subtype_list[i] = MCDI_ARRAY_WORD(
700 le16_to_cpup((__le16 *)(outbuf + offset)) : 0; 699 outbuf, GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST, i);
701 offset += 2; 700 for (; i < MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_MAXNUM; i++)
702 } 701 fw_subtype_list[i] = 0;
703 } 702 }
704 if (capabilities) { 703 if (capabilities) {
705 if (port_num) 704 if (port_num)
@@ -980,7 +979,7 @@ static int efx_mcdi_read_assertion(struct efx_nic *efx)
980{ 979{
981 MCDI_DECLARE_BUF(inbuf, MC_CMD_GET_ASSERTS_IN_LEN); 980 MCDI_DECLARE_BUF(inbuf, MC_CMD_GET_ASSERTS_IN_LEN);
982 MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_ASSERTS_OUT_LEN); 981 MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_ASSERTS_OUT_LEN);
983 unsigned int flags, index, ofst; 982 unsigned int flags, index;
984 const char *reason; 983 const char *reason;
985 size_t outlen; 984 size_t outlen;
986 int retry; 985 int retry;
@@ -1022,12 +1021,13 @@ static int efx_mcdi_read_assertion(struct efx_nic *efx)
1022 MCDI_DWORD(outbuf, GET_ASSERTS_OUT_THREAD_OFFS)); 1021 MCDI_DWORD(outbuf, GET_ASSERTS_OUT_THREAD_OFFS));
1023 1022
1024 /* Print out the registers */ 1023 /* Print out the registers */
1025 ofst = MC_CMD_GET_ASSERTS_OUT_GP_REGS_OFFS_OFST; 1024 for (index = 0;
1026 for (index = 1; index < 32; index++) { 1025 index < MC_CMD_GET_ASSERTS_OUT_GP_REGS_OFFS_NUM;
1027 netif_err(efx, hw, efx->net_dev, "R%.2d (?): 0x%.8x\n", index, 1026 index++)
1028 MCDI_DWORD2(outbuf, ofst)); 1027 netif_err(efx, hw, efx->net_dev, "R%.2d (?): 0x%.8x\n",
1029 ofst += sizeof(efx_dword_t); 1028 1 + index,
1030 } 1029 MCDI_ARRAY_DWORD(outbuf, GET_ASSERTS_OUT_GP_REGS_OFFS,
1030 index));
1031 1031
1032 return 0; 1032 return 0;
1033} 1033}
@@ -1201,34 +1201,31 @@ int efx_mcdi_flush_rxqs(struct efx_nic *efx)
1201{ 1201{
1202 struct efx_channel *channel; 1202 struct efx_channel *channel;
1203 struct efx_rx_queue *rx_queue; 1203 struct efx_rx_queue *rx_queue;
1204 __le32 *qid; 1204 MCDI_DECLARE_BUF(inbuf,
1205 MC_CMD_FLUSH_RX_QUEUES_IN_LEN(EFX_MAX_CHANNELS));
1205 int rc, count; 1206 int rc, count;
1206 1207
1207 BUILD_BUG_ON(EFX_MAX_CHANNELS > 1208 BUILD_BUG_ON(EFX_MAX_CHANNELS >
1208 MC_CMD_FLUSH_RX_QUEUES_IN_QID_OFST_MAXNUM); 1209 MC_CMD_FLUSH_RX_QUEUES_IN_QID_OFST_MAXNUM);
1209 1210
1210 qid = kmalloc(EFX_MAX_CHANNELS * sizeof(*qid), GFP_KERNEL);
1211 if (qid == NULL)
1212 return -ENOMEM;
1213
1214 count = 0; 1211 count = 0;
1215 efx_for_each_channel(channel, efx) { 1212 efx_for_each_channel(channel, efx) {
1216 efx_for_each_channel_rx_queue(rx_queue, channel) { 1213 efx_for_each_channel_rx_queue(rx_queue, channel) {
1217 if (rx_queue->flush_pending) { 1214 if (rx_queue->flush_pending) {
1218 rx_queue->flush_pending = false; 1215 rx_queue->flush_pending = false;
1219 atomic_dec(&efx->rxq_flush_pending); 1216 atomic_dec(&efx->rxq_flush_pending);
1220 qid[count++] = cpu_to_le32( 1217 MCDI_SET_ARRAY_DWORD(
1221 efx_rx_queue_index(rx_queue)); 1218 inbuf, FLUSH_RX_QUEUES_IN_QID_OFST,
1219 count, efx_rx_queue_index(rx_queue));
1220 count++;
1222 } 1221 }
1223 } 1222 }
1224 } 1223 }
1225 1224
1226 rc = efx_mcdi_rpc(efx, MC_CMD_FLUSH_RX_QUEUES, (u8 *)qid, 1225 rc = efx_mcdi_rpc(efx, MC_CMD_FLUSH_RX_QUEUES, inbuf,
1227 count * sizeof(*qid), NULL, 0, NULL); 1226 MC_CMD_FLUSH_RX_QUEUES_IN_LEN(count), NULL, 0, NULL);
1228 WARN_ON(rc < 0); 1227 WARN_ON(rc < 0);
1229 1228
1230 kfree(qid);
1231
1232 return rc; 1229 return rc;
1233} 1230}
1234 1231
diff --git a/drivers/net/ethernet/sfc/mcdi.h b/drivers/net/ethernet/sfc/mcdi.h
index 969ecc06560a..f8ab64f0efb1 100644
--- a/drivers/net/ethernet/sfc/mcdi.h
+++ b/drivers/net/ethernet/sfc/mcdi.h
@@ -94,9 +94,6 @@ extern void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev);
94#define _MCDI_DWORD(_buf, _field) \ 94#define _MCDI_DWORD(_buf, _field) \
95 ((efx_dword_t *)MCDI_PTR(_buf, _field)) 95 ((efx_dword_t *)MCDI_PTR(_buf, _field))
96 96
97#define MCDI_DWORD2(_buf, _ofst) \
98 EFX_DWORD_FIELD(*(efx_dword_t *)((u8 *)(_buf) + (_ofst)), EFX_DWORD_0)
99
100#define MCDI_SET_DWORD(_buf, _field, _value) \ 97#define MCDI_SET_DWORD(_buf, _field, _value) \
101 EFX_POPULATE_DWORD_1(*_MCDI_DWORD(_buf, _field), EFX_DWORD_0, _value) 98 EFX_POPULATE_DWORD_1(*_MCDI_DWORD(_buf, _field), EFX_DWORD_0, _value)
102#define MCDI_DWORD(_buf, _field) \ 99#define MCDI_DWORD(_buf, _field) \
diff --git a/drivers/net/ethernet/sfc/mcdi_mac.c b/drivers/net/ethernet/sfc/mcdi_mac.c
index fafdc8e292c5..cf16bf13b6f2 100644
--- a/drivers/net/ethernet/sfc/mcdi_mac.c
+++ b/drivers/net/ethernet/sfc/mcdi_mac.c
@@ -17,7 +17,7 @@ int efx_mcdi_set_mac(struct efx_nic *efx)
17 u32 reject, fcntl; 17 u32 reject, fcntl;
18 MCDI_DECLARE_BUF(cmdbytes, MC_CMD_SET_MAC_IN_LEN); 18 MCDI_DECLARE_BUF(cmdbytes, MC_CMD_SET_MAC_IN_LEN);
19 19
20 memcpy(cmdbytes + MC_CMD_SET_MAC_IN_ADDR_OFST, 20 memcpy(MCDI_PTR(cmdbytes, SET_MAC_IN_ADDR),
21 efx->net_dev->dev_addr, ETH_ALEN); 21 efx->net_dev->dev_addr, ETH_ALEN);
22 22
23 MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_MTU, 23 MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_MTU,
diff --git a/drivers/net/ethernet/sfc/mcdi_phy.c b/drivers/net/ethernet/sfc/mcdi_phy.c
index 37b6ed99c47c..86c0d21b84bc 100644
--- a/drivers/net/ethernet/sfc/mcdi_phy.c
+++ b/drivers/net/ethernet/sfc/mcdi_phy.c
@@ -615,17 +615,15 @@ static int efx_mcdi_bist(struct efx_nic *efx, unsigned int bist_mode,
615 unsigned int retry, i, count = 0; 615 unsigned int retry, i, count = 0;
616 size_t outlen; 616 size_t outlen;
617 u32 status; 617 u32 status;
618 u8 *buf, *ptr; 618 MCDI_DECLARE_BUF(inbuf, MC_CMD_START_BIST_IN_LEN);
619 MCDI_DECLARE_BUF(outbuf, MC_CMD_POLL_BIST_OUT_SFT9001_LEN);
620 u8 *ptr;
619 int rc; 621 int rc;
620 622
621 buf = kzalloc(0x100, GFP_KERNEL);
622 if (buf == NULL)
623 return -ENOMEM;
624
625 BUILD_BUG_ON(MC_CMD_START_BIST_OUT_LEN != 0); 623 BUILD_BUG_ON(MC_CMD_START_BIST_OUT_LEN != 0);
626 MCDI_SET_DWORD(buf, START_BIST_IN_TYPE, bist_mode); 624 MCDI_SET_DWORD(inbuf, START_BIST_IN_TYPE, bist_mode);
627 rc = efx_mcdi_rpc(efx, MC_CMD_START_BIST, buf, MC_CMD_START_BIST_IN_LEN, 625 rc = efx_mcdi_rpc(efx, MC_CMD_START_BIST,
628 NULL, 0, NULL); 626 inbuf, MC_CMD_START_BIST_IN_LEN, NULL, 0, NULL);
629 if (rc) 627 if (rc)
630 goto out; 628 goto out;
631 629
@@ -633,11 +631,11 @@ static int efx_mcdi_bist(struct efx_nic *efx, unsigned int bist_mode,
633 for (retry = 0; retry < 100; ++retry) { 631 for (retry = 0; retry < 100; ++retry) {
634 BUILD_BUG_ON(MC_CMD_POLL_BIST_IN_LEN != 0); 632 BUILD_BUG_ON(MC_CMD_POLL_BIST_IN_LEN != 0);
635 rc = efx_mcdi_rpc(efx, MC_CMD_POLL_BIST, NULL, 0, 633 rc = efx_mcdi_rpc(efx, MC_CMD_POLL_BIST, NULL, 0,
636 buf, 0x100, &outlen); 634 outbuf, sizeof(outbuf), &outlen);
637 if (rc) 635 if (rc)
638 goto out; 636 goto out;
639 637
640 status = MCDI_DWORD(buf, POLL_BIST_OUT_RESULT); 638 status = MCDI_DWORD(outbuf, POLL_BIST_OUT_RESULT);
641 if (status != MC_CMD_POLL_BIST_RUNNING) 639 if (status != MC_CMD_POLL_BIST_RUNNING)
642 goto finished; 640 goto finished;
643 641
@@ -654,7 +652,7 @@ finished:
654 if (efx->phy_type == PHY_TYPE_SFT9001B && 652 if (efx->phy_type == PHY_TYPE_SFT9001B &&
655 (bist_mode == MC_CMD_PHY_BIST_CABLE_SHORT || 653 (bist_mode == MC_CMD_PHY_BIST_CABLE_SHORT ||
656 bist_mode == MC_CMD_PHY_BIST_CABLE_LONG)) { 654 bist_mode == MC_CMD_PHY_BIST_CABLE_LONG)) {
657 ptr = MCDI_PTR(buf, POLL_BIST_OUT_SFT9001_CABLE_LENGTH_A); 655 ptr = MCDI_PTR(outbuf, POLL_BIST_OUT_SFT9001_CABLE_LENGTH_A);
658 if (status == MC_CMD_POLL_BIST_PASSED && 656 if (status == MC_CMD_POLL_BIST_PASSED &&
659 outlen >= MC_CMD_POLL_BIST_OUT_SFT9001_LEN) { 657 outlen >= MC_CMD_POLL_BIST_OUT_SFT9001_LEN) {
660 for (i = 0; i < 8; i++) { 658 for (i = 0; i < 8; i++) {
@@ -668,8 +666,6 @@ finished:
668 rc = count; 666 rc = count;
669 667
670out: 668out:
671 kfree(buf);
672
673 return rc; 669 return rc;
674} 670}
675 671
@@ -785,8 +781,7 @@ static int efx_mcdi_phy_get_module_eeprom(struct efx_nic *efx,
785 space_remaining : payload_len; 781 space_remaining : payload_len;
786 782
787 memcpy(user_data, 783 memcpy(user_data,
788 outbuf + page_off + 784 MCDI_PTR(outbuf, GET_PHY_MEDIA_INFO_OUT_DATA) + page_off,
789 MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_OFST,
790 to_copy); 785 to_copy);
791 786
792 space_remaining -= to_copy; 787 space_remaining -= to_copy;
diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c
index f79f6fb579a1..ec2cf4d7c9b7 100644
--- a/drivers/net/ethernet/sfc/ptp.c
+++ b/drivers/net/ethernet/sfc/ptp.c
@@ -294,8 +294,7 @@ struct efx_ptp_data {
294 struct work_struct pps_work; 294 struct work_struct pps_work;
295 struct workqueue_struct *pps_workwq; 295 struct workqueue_struct *pps_workwq;
296 bool nic_ts_enabled; 296 bool nic_ts_enabled;
297 u8 txbuf[ALIGN(MC_CMD_PTP_IN_TRANSMIT_LEN( 297 MCDI_DECLARE_BUF(txbuf, MC_CMD_PTP_IN_TRANSMIT_LENMAX);
298 MC_CMD_PTP_IN_TRANSMIT_PACKET_MAXNUM), 4)];
299 struct efx_ptp_timeset 298 struct efx_ptp_timeset
300 timeset[MC_CMD_PTP_OUT_SYNCHRONIZE_TIMESET_MAXNUM]; 299 timeset[MC_CMD_PTP_OUT_SYNCHRONIZE_TIMESET_MAXNUM];
301}; 300};
@@ -396,7 +395,8 @@ static void efx_ptp_send_times(struct efx_nic *efx,
396} 395}
397 396
398/* Read a timeset from the MC's results and partial process. */ 397/* Read a timeset from the MC's results and partial process. */
399static void efx_ptp_read_timeset(u8 *data, struct efx_ptp_timeset *timeset) 398static void efx_ptp_read_timeset(MCDI_DECLARE_STRUCT_PTR(data),
399 struct efx_ptp_timeset *timeset)
400{ 400{
401 unsigned start_ns, end_ns; 401 unsigned start_ns, end_ns;
402 402
@@ -425,12 +425,14 @@ static void efx_ptp_read_timeset(u8 *data, struct efx_ptp_timeset *timeset)
425 * busy. A number of readings are taken so that, hopefully, at least one good 425 * busy. A number of readings are taken so that, hopefully, at least one good
426 * synchronisation will be seen in the results. 426 * synchronisation will be seen in the results.
427 */ 427 */
428static int efx_ptp_process_times(struct efx_nic *efx, u8 *synch_buf, 428static int
429 size_t response_length, 429efx_ptp_process_times(struct efx_nic *efx, MCDI_DECLARE_STRUCT_PTR(synch_buf),
430 const struct pps_event_time *last_time) 430 size_t response_length,
431 const struct pps_event_time *last_time)
431{ 432{
432 unsigned number_readings = (response_length / 433 unsigned number_readings =
433 MC_CMD_PTP_OUT_SYNCHRONIZE_TIMESET_LEN); 434 MCDI_VAR_ARRAY_LEN(response_length,
435 PTP_OUT_SYNCHRONIZE_TIMESET);
434 unsigned i; 436 unsigned i;
435 unsigned total; 437 unsigned total;
436 unsigned ngood = 0; 438 unsigned ngood = 0;
@@ -447,8 +449,10 @@ static int efx_ptp_process_times(struct efx_nic *efx, u8 *synch_buf,
447 * appera to be erroneous. 449 * appera to be erroneous.
448 */ 450 */
449 for (i = 0; i < number_readings; i++) { 451 for (i = 0; i < number_readings; i++) {
450 efx_ptp_read_timeset(synch_buf, &ptp->timeset[i]); 452 efx_ptp_read_timeset(
451 synch_buf += MC_CMD_PTP_OUT_SYNCHRONIZE_TIMESET_LEN; 453 MCDI_ARRAY_STRUCT_PTR(synch_buf,
454 PTP_OUT_SYNCHRONIZE_TIMESET, i),
455 &ptp->timeset[i]);
452 } 456 }
453 457
454 /* Find the last good host-MC synchronization result. The MC times 458 /* 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/* Transmit a PTP packet, via the MCDI interface, to the wire. */ 568/* Transmit a PTP packet, via the MCDI interface, to the wire. */
565static int efx_ptp_xmit_skb(struct efx_nic *efx, struct sk_buff *skb) 569static int efx_ptp_xmit_skb(struct efx_nic *efx, struct sk_buff *skb)
566{ 570{
567 u8 *txbuf = efx->ptp_data->txbuf; 571 struct efx_ptp_data *ptp_data = efx->ptp_data;
568 struct skb_shared_hwtstamps timestamps; 572 struct skb_shared_hwtstamps timestamps;
569 int rc = -EIO; 573 int rc = -EIO;
570 /* MCDI driver requires word aligned lengths */ 574 /* MCDI driver requires word aligned lengths */
571 size_t len = ALIGN(MC_CMD_PTP_IN_TRANSMIT_LEN(skb->len), 4); 575 size_t len = ALIGN(MC_CMD_PTP_IN_TRANSMIT_LEN(skb->len), 4);
572 MCDI_DECLARE_BUF(txtime, MC_CMD_PTP_OUT_TRANSMIT_LEN); 576 MCDI_DECLARE_BUF(txtime, MC_CMD_PTP_OUT_TRANSMIT_LEN);
573 577
574 MCDI_SET_DWORD(txbuf, PTP_IN_OP, MC_CMD_PTP_OP_TRANSMIT); 578 MCDI_SET_DWORD(ptp_data->txbuf, PTP_IN_OP, MC_CMD_PTP_OP_TRANSMIT);
575 MCDI_SET_DWORD(txbuf, PTP_IN_TRANSMIT_LENGTH, skb->len); 579 MCDI_SET_DWORD(ptp_data->txbuf, PTP_IN_TRANSMIT_LENGTH, skb->len);
576 if (skb_shinfo(skb)->nr_frags != 0) { 580 if (skb_shinfo(skb)->nr_frags != 0) {
577 rc = skb_linearize(skb); 581 rc = skb_linearize(skb);
578 if (rc != 0) 582 if (rc != 0)
@@ -585,9 +589,10 @@ static int efx_ptp_xmit_skb(struct efx_nic *efx, struct sk_buff *skb)
585 goto fail; 589 goto fail;
586 } 590 }
587 skb_copy_from_linear_data(skb, 591 skb_copy_from_linear_data(skb,
588 &txbuf[MC_CMD_PTP_IN_TRANSMIT_PACKET_OFST], 592 MCDI_PTR(ptp_data->txbuf,
593 PTP_IN_TRANSMIT_PACKET),
589 len); 594 len);
590 rc = efx_mcdi_rpc(efx, MC_CMD_PTP, txbuf, len, txtime, 595 rc = efx_mcdi_rpc(efx, MC_CMD_PTP, ptp_data->txbuf, len, txtime,
591 sizeof(txtime), &len); 596 sizeof(txtime), &len);
592 if (rc != 0) 597 if (rc != 0)
593 goto fail; 598 goto fail;
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)
240static int efx_sriov_memcpy(struct efx_nic *efx, struct efx_memcpy_req *req, 240static int efx_sriov_memcpy(struct efx_nic *efx, struct efx_memcpy_req *req,
241 unsigned int count) 241 unsigned int count)
242{ 242{
243 u8 *inbuf, *record; 243 MCDI_DECLARE_BUF(inbuf, MCDI_CTL_SDU_LEN_MAX_V1);
244 unsigned int used; 244 MCDI_DECLARE_STRUCT_PTR(record);
245 unsigned int index, used;
245 u32 from_rid, from_hi, from_lo; 246 u32 from_rid, from_hi, from_lo;
246 int rc; 247 int rc;
247 248
248 mb(); /* Finish writing source/reading dest before DMA starts */ 249 mb(); /* Finish writing source/reading dest before DMA starts */
249 250
250 used = MC_CMD_MEMCPY_IN_LEN(count); 251 if (WARN_ON(count > MC_CMD_MEMCPY_IN_RECORD_MAXNUM))
251 if (WARN_ON(used > MCDI_CTL_SDU_LEN_MAX_V1))
252 return -ENOBUFS; 252 return -ENOBUFS;
253 used = MC_CMD_MEMCPY_IN_LEN(count);
253 254
254 /* Allocate room for the largest request */ 255 for (index = 0; index < count; index++) {
255 inbuf = kzalloc(MCDI_CTL_SDU_LEN_MAX_V1, GFP_KERNEL); 256 record = MCDI_ARRAY_STRUCT_PTR(inbuf, MEMCPY_IN_RECORD, index);
256 if (inbuf == NULL) 257 MCDI_SET_DWORD(record, MEMCPY_RECORD_TYPEDEF_NUM_RECORDS,
257 return -ENOMEM; 258 count);
258
259 record = inbuf;
260 MCDI_SET_DWORD(record, MEMCPY_IN_RECORD, count);
261 while (count-- > 0) {
262 MCDI_SET_DWORD(record, MEMCPY_RECORD_TYPEDEF_TO_RID, 259 MCDI_SET_DWORD(record, MEMCPY_RECORD_TYPEDEF_TO_RID,
263 req->to_rid); 260 req->to_rid);
264 MCDI_SET_DWORD(record, MEMCPY_RECORD_TYPEDEF_TO_ADDR_LO, 261 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 from_rid = MC_CMD_MEMCPY_RECORD_TYPEDEF_RID_INLINE; 276 from_rid = MC_CMD_MEMCPY_RECORD_TYPEDEF_RID_INLINE;
280 from_lo = used; 277 from_lo = used;
281 from_hi = 0; 278 from_hi = 0;
282 memcpy(inbuf + used, req->from_buf, req->length); 279 memcpy(_MCDI_PTR(inbuf, used), req->from_buf,
280 req->length);
283 used += req->length; 281 used += req->length;
284 } 282 }
285 283
@@ -292,13 +290,10 @@ static int efx_sriov_memcpy(struct efx_nic *efx, struct efx_memcpy_req *req,
292 req->length); 290 req->length);
293 291
294 ++req; 292 ++req;
295 record += MC_CMD_MEMCPY_IN_RECORD_LEN;
296 } 293 }
297 294
298 rc = efx_mcdi_rpc(efx, MC_CMD_MEMCPY, inbuf, used, NULL, 0, NULL); 295 rc = efx_mcdi_rpc(efx, MC_CMD_MEMCPY, inbuf, used, NULL, 0, NULL);
299out: 296out:
300 kfree(inbuf);
301
302 mb(); /* Don't write source/read dest before DMA is complete */ 297 mb(); /* Don't write source/read dest before DMA is complete */
303 298
304 return rc; 299 return rc;
@@ -685,16 +680,12 @@ static int efx_vfdi_fini_all_queues(struct efx_vf *vf)
685 unsigned vf_offset = EFX_VI_BASE + vf->index * efx_vf_size(efx); 680 unsigned vf_offset = EFX_VI_BASE + vf->index * efx_vf_size(efx);
686 unsigned timeout = HZ; 681 unsigned timeout = HZ;
687 unsigned index, rxqs_count; 682 unsigned index, rxqs_count;
688 __le32 *rxqs; 683 MCDI_DECLARE_BUF(inbuf, MC_CMD_FLUSH_RX_QUEUES_IN_LENMAX);
689 int rc; 684 int rc;
690 685
691 BUILD_BUG_ON(VF_MAX_RX_QUEUES > 686 BUILD_BUG_ON(VF_MAX_RX_QUEUES >
692 MC_CMD_FLUSH_RX_QUEUES_IN_QID_OFST_MAXNUM); 687 MC_CMD_FLUSH_RX_QUEUES_IN_QID_OFST_MAXNUM);
693 688
694 rxqs = kmalloc(count * sizeof(*rxqs), GFP_KERNEL);
695 if (rxqs == NULL)
696 return VFDI_RC_ENOMEM;
697
698 rtnl_lock(); 689 rtnl_lock();
699 siena_prepare_flush(efx); 690 siena_prepare_flush(efx);
700 rtnl_unlock(); 691 rtnl_unlock();
@@ -709,14 +700,19 @@ static int efx_vfdi_fini_all_queues(struct efx_vf *vf)
709 vf_offset + index); 700 vf_offset + index);
710 efx_writeo(efx, &reg, FR_AZ_TX_FLUSH_DESCQ); 701 efx_writeo(efx, &reg, FR_AZ_TX_FLUSH_DESCQ);
711 } 702 }
712 if (test_bit(index, vf->rxq_mask)) 703 if (test_bit(index, vf->rxq_mask)) {
713 rxqs[rxqs_count++] = cpu_to_le32(vf_offset + index); 704 MCDI_SET_ARRAY_DWORD(
705 inbuf, FLUSH_RX_QUEUES_IN_QID_OFST,
706 rxqs_count, vf_offset + index);
707 rxqs_count++;
708 }
714 } 709 }
715 710
716 atomic_set(&vf->rxq_retry_count, 0); 711 atomic_set(&vf->rxq_retry_count, 0);
717 while (timeout && (vf->rxq_count || vf->txq_count)) { 712 while (timeout && (vf->rxq_count || vf->txq_count)) {
718 rc = efx_mcdi_rpc(efx, MC_CMD_FLUSH_RX_QUEUES, (u8 *)rxqs, 713 rc = efx_mcdi_rpc(efx, MC_CMD_FLUSH_RX_QUEUES, inbuf,
719 rxqs_count * sizeof(*rxqs), NULL, 0, NULL); 714 MC_CMD_FLUSH_RX_QUEUES_IN_LEN(rxqs_count),
715 NULL, 0, NULL);
720 WARN_ON(rc < 0); 716 WARN_ON(rc < 0);
721 717
722 timeout = wait_event_timeout(vf->flush_waitq, 718 timeout = wait_event_timeout(vf->flush_waitq,
@@ -726,8 +722,10 @@ static int efx_vfdi_fini_all_queues(struct efx_vf *vf)
726 for (index = 0; index < count; ++index) { 722 for (index = 0; index < count; ++index) {
727 if (test_and_clear_bit(index, vf->rxq_retry_mask)) { 723 if (test_and_clear_bit(index, vf->rxq_retry_mask)) {
728 atomic_dec(&vf->rxq_retry_count); 724 atomic_dec(&vf->rxq_retry_count);
729 rxqs[rxqs_count++] = 725 MCDI_SET_ARRAY_DWORD(
730 cpu_to_le32(vf_offset + index); 726 inbuf, FLUSH_RX_QUEUES_IN_QID_OFST,
727 rxqs_count, vf_offset + index);
728 rxqs_count++;
731 } 729 }
732 } 730 }
733 } 731 }
@@ -750,7 +748,6 @@ static int efx_vfdi_fini_all_queues(struct efx_vf *vf)
750 } 748 }
751 efx_sriov_bufs(efx, vf->buftbl_base, NULL, 749 efx_sriov_bufs(efx, vf->buftbl_base, NULL,
752 EFX_VF_BUFTBL_PER_VI * efx_vf_size(efx)); 750 EFX_VF_BUFTBL_PER_VI * efx_vf_size(efx));
753 kfree(rxqs);
754 efx_vfdi_flush_clear(vf); 751 efx_vfdi_flush_clear(vf);
755 752
756 vf->evq0_count = 0; 753 vf->evq0_count = 0;