diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2012-09-14 12:31:33 -0400 |
---|---|---|
committer | Ben Hutchings <bhutchings@solarflare.com> | 2013-08-21 11:35:26 -0400 |
commit | c5bb0e9891ba1f7c871adc09d9ef727e1c0c1c1e (patch) | |
tree | 62bf62dbc591718aade11df087dbdb9bc3862b85 /drivers/net/ethernet/sfc | |
parent | d0c2ee99e54c0fd76938236e863ad7d3992f044f (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.c | 61 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/mcdi.h | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/mcdi_mac.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/mcdi_phy.c | 25 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/ptp.c | 35 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/siena_sriov.c | 53 |
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 | ||
670 | out: | 668 | out: |
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. */ |
399 | static void efx_ptp_read_timeset(u8 *data, struct efx_ptp_timeset *timeset) | 398 | static 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 | */ |
428 | static int efx_ptp_process_times(struct efx_nic *efx, u8 *synch_buf, | 428 | static int |
429 | size_t response_length, | 429 | efx_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. */ |
565 | static int efx_ptp_xmit_skb(struct efx_nic *efx, struct sk_buff *skb) | 569 | static 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) | |||
240 | static int efx_sriov_memcpy(struct efx_nic *efx, struct efx_memcpy_req *req, | 240 | static 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); |
299 | out: | 296 | out: |
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, ®, FR_AZ_TX_FLUSH_DESCQ); | 701 | efx_writeo(efx, ®, 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; |