diff options
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 27 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 25 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c | 42 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h | 47 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 599 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h | 178 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c | 50 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h | 29 |
8 files changed, 984 insertions, 13 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index d777fae86988..a0b06a07cbde 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | |||
@@ -20,6 +20,10 @@ | |||
20 | #include <linux/types.h> | 20 | #include <linux/types.h> |
21 | #include <linux/pci_regs.h> | 21 | #include <linux/pci_regs.h> |
22 | 22 | ||
23 | #include <linux/ptp_clock_kernel.h> | ||
24 | #include <linux/net_tstamp.h> | ||
25 | #include <linux/clocksource.h> | ||
26 | |||
23 | /* compilation time flags */ | 27 | /* compilation time flags */ |
24 | 28 | ||
25 | /* define this to make the driver freeze on error to allow getting debug info | 29 | /* define this to make the driver freeze on error to allow getting debug info |
@@ -70,6 +74,7 @@ enum bnx2x_int_mode { | |||
70 | #define BNX2X_MSG_SP 0x0100000 /* was: NETIF_MSG_INTR */ | 74 | #define BNX2X_MSG_SP 0x0100000 /* was: NETIF_MSG_INTR */ |
71 | #define BNX2X_MSG_FP 0x0200000 /* was: NETIF_MSG_INTR */ | 75 | #define BNX2X_MSG_FP 0x0200000 /* was: NETIF_MSG_INTR */ |
72 | #define BNX2X_MSG_IOV 0x0800000 | 76 | #define BNX2X_MSG_IOV 0x0800000 |
77 | #define BNX2X_MSG_PTP 0x1000000 | ||
73 | #define BNX2X_MSG_IDLE 0x2000000 /* used for idle check*/ | 78 | #define BNX2X_MSG_IDLE 0x2000000 /* used for idle check*/ |
74 | #define BNX2X_MSG_ETHTOOL 0x4000000 | 79 | #define BNX2X_MSG_ETHTOOL 0x4000000 |
75 | #define BNX2X_MSG_DCB 0x8000000 | 80 | #define BNX2X_MSG_DCB 0x8000000 |
@@ -1591,6 +1596,8 @@ struct bnx2x { | |||
1591 | #define BC_SUPPORTS_RMMOD_CMD (1 << 24) | 1596 | #define BC_SUPPORTS_RMMOD_CMD (1 << 24) |
1592 | #define HAS_PHYS_PORT_ID (1 << 25) | 1597 | #define HAS_PHYS_PORT_ID (1 << 25) |
1593 | #define AER_ENABLED (1 << 26) | 1598 | #define AER_ENABLED (1 << 26) |
1599 | #define PTP_SUPPORTED (1 << 27) | ||
1600 | #define TX_TIMESTAMPING_EN (1 << 28) | ||
1594 | 1601 | ||
1595 | #define BP_NOMCP(bp) ((bp)->flags & NO_MCP_FLAG) | 1602 | #define BP_NOMCP(bp) ((bp)->flags & NO_MCP_FLAG) |
1596 | 1603 | ||
@@ -1933,6 +1940,19 @@ struct bnx2x { | |||
1933 | 1940 | ||
1934 | u8 phys_port_id[ETH_ALEN]; | 1941 | u8 phys_port_id[ETH_ALEN]; |
1935 | 1942 | ||
1943 | /* PTP related context */ | ||
1944 | struct ptp_clock *ptp_clock; | ||
1945 | struct ptp_clock_info ptp_clock_info; | ||
1946 | struct work_struct ptp_task; | ||
1947 | struct cyclecounter cyclecounter; | ||
1948 | struct timecounter timecounter; | ||
1949 | bool timecounter_init_done; | ||
1950 | struct sk_buff *ptp_tx_skb; | ||
1951 | unsigned long ptp_tx_start; | ||
1952 | bool hwtstamp_ioctl_called; | ||
1953 | u16 tx_type; | ||
1954 | u16 rx_filter; | ||
1955 | |||
1936 | struct bnx2x_link_report_data vf_link_vars; | 1956 | struct bnx2x_link_report_data vf_link_vars; |
1937 | }; | 1957 | }; |
1938 | 1958 | ||
@@ -2559,4 +2579,11 @@ void bnx2x_update_mng_version(struct bnx2x *bp); | |||
2559 | 2579 | ||
2560 | #define E1H_MAX_MF_SB_COUNT (HC_SB_MAX_SB_E1X/(E1HVN_MAX * PORT_MAX)) | 2580 | #define E1H_MAX_MF_SB_COUNT (HC_SB_MAX_SB_E1X/(E1HVN_MAX * PORT_MAX)) |
2561 | 2581 | ||
2582 | void bnx2x_init_ptp(struct bnx2x *bp); | ||
2583 | int bnx2x_configure_ptp_filters(struct bnx2x *bp); | ||
2584 | void bnx2x_set_rx_ts(struct bnx2x *bp, struct sk_buff *skb); | ||
2585 | |||
2586 | #define BNX2X_MAX_PHC_DRIFT 31000000 | ||
2587 | #define BNX2X_PTP_TX_TIMEOUT | ||
2588 | |||
2562 | #endif /* bnx2x.h */ | 2589 | #endif /* bnx2x.h */ |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index e35326cfd2c9..a1dd2e417a97 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | |||
@@ -1067,6 +1067,11 @@ reuse_rx: | |||
1067 | 1067 | ||
1068 | skb_record_rx_queue(skb, fp->rx_queue); | 1068 | skb_record_rx_queue(skb, fp->rx_queue); |
1069 | 1069 | ||
1070 | /* Check if this packet was timestamped */ | ||
1071 | if (unlikely(le16_to_cpu(cqe->fast_path_cqe.type_error_flags) & | ||
1072 | (1 << ETH_FAST_PATH_RX_CQE_PTP_PKT_SHIFT))) | ||
1073 | bnx2x_set_rx_ts(bp, skb); | ||
1074 | |||
1070 | if (le16_to_cpu(cqe_fp->pars_flags.flags) & | 1075 | if (le16_to_cpu(cqe_fp->pars_flags.flags) & |
1071 | PARSING_FLAGS_VLAN) | 1076 | PARSING_FLAGS_VLAN) |
1072 | __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), | 1077 | __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), |
@@ -2808,7 +2813,11 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) | |||
2808 | /* Initialize Rx filter. */ | 2813 | /* Initialize Rx filter. */ |
2809 | bnx2x_set_rx_mode_inner(bp); | 2814 | bnx2x_set_rx_mode_inner(bp); |
2810 | 2815 | ||
2811 | /* Start the Tx */ | 2816 | if (bp->flags & PTP_SUPPORTED) { |
2817 | bnx2x_init_ptp(bp); | ||
2818 | bnx2x_configure_ptp_filters(bp); | ||
2819 | } | ||
2820 | /* Start Tx */ | ||
2812 | switch (load_mode) { | 2821 | switch (load_mode) { |
2813 | case LOAD_NORMAL: | 2822 | case LOAD_NORMAL: |
2814 | /* Tx queue should be only re-enabled */ | 2823 | /* Tx queue should be only re-enabled */ |
@@ -3833,6 +3842,20 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3833 | 3842 | ||
3834 | tx_start_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_START_BD; | 3843 | tx_start_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_START_BD; |
3835 | 3844 | ||
3845 | if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { | ||
3846 | if (!(bp->flags & TX_TIMESTAMPING_EN)) { | ||
3847 | BNX2X_ERR("Tx timestamping was not enabled, this packet will not be timestamped\n"); | ||
3848 | } else if (bp->ptp_tx_skb) { | ||
3849 | BNX2X_ERR("The device supports only a single outstanding packet to timestamp, this packet will not be timestamped\n"); | ||
3850 | } else { | ||
3851 | skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; | ||
3852 | /* schedule check for Tx timestamp */ | ||
3853 | bp->ptp_tx_skb = skb_get(skb); | ||
3854 | bp->ptp_tx_start = jiffies; | ||
3855 | schedule_work(&bp->ptp_task); | ||
3856 | } | ||
3857 | } | ||
3858 | |||
3836 | /* header nbd: indirectly zero other flags! */ | 3859 | /* header nbd: indirectly zero other flags! */ |
3837 | tx_start_bd->general_data = 1 << ETH_TX_START_BD_HDR_NBDS_SHIFT; | 3860 | tx_start_bd->general_data = 1 << ETH_TX_START_BD_HDR_NBDS_SHIFT; |
3838 | 3861 | ||
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index 92fee842f954..0b173ed20ae9 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c | |||
@@ -3481,6 +3481,46 @@ static int bnx2x_set_channels(struct net_device *dev, | |||
3481 | return bnx2x_nic_load(bp, LOAD_NORMAL); | 3481 | return bnx2x_nic_load(bp, LOAD_NORMAL); |
3482 | } | 3482 | } |
3483 | 3483 | ||
3484 | static int bnx2x_get_ts_info(struct net_device *dev, | ||
3485 | struct ethtool_ts_info *info) | ||
3486 | { | ||
3487 | struct bnx2x *bp = netdev_priv(dev); | ||
3488 | |||
3489 | if (bp->flags & PTP_SUPPORTED) { | ||
3490 | info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE | | ||
3491 | SOF_TIMESTAMPING_RX_SOFTWARE | | ||
3492 | SOF_TIMESTAMPING_SOFTWARE | | ||
3493 | SOF_TIMESTAMPING_TX_HARDWARE | | ||
3494 | SOF_TIMESTAMPING_RX_HARDWARE | | ||
3495 | SOF_TIMESTAMPING_RAW_HARDWARE; | ||
3496 | |||
3497 | if (bp->ptp_clock) | ||
3498 | info->phc_index = ptp_clock_index(bp->ptp_clock); | ||
3499 | else | ||
3500 | info->phc_index = -1; | ||
3501 | |||
3502 | info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) | | ||
3503 | (1 << HWTSTAMP_FILTER_PTP_V1_L4_EVENT) | | ||
3504 | (1 << HWTSTAMP_FILTER_PTP_V1_L4_SYNC) | | ||
3505 | (1 << HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ) | | ||
3506 | (1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT) | | ||
3507 | (1 << HWTSTAMP_FILTER_PTP_V2_L4_SYNC) | | ||
3508 | (1 << HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ) | | ||
3509 | (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) | | ||
3510 | (1 << HWTSTAMP_FILTER_PTP_V2_L2_SYNC) | | ||
3511 | (1 << HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ) | | ||
3512 | (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) | | ||
3513 | (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) | | ||
3514 | (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ); | ||
3515 | |||
3516 | info->tx_types = (1 << HWTSTAMP_TX_OFF)|(1 << HWTSTAMP_TX_ON); | ||
3517 | |||
3518 | return 0; | ||
3519 | } | ||
3520 | |||
3521 | return ethtool_op_get_ts_info(dev, info); | ||
3522 | } | ||
3523 | |||
3484 | static const struct ethtool_ops bnx2x_ethtool_ops = { | 3524 | static const struct ethtool_ops bnx2x_ethtool_ops = { |
3485 | .get_settings = bnx2x_get_settings, | 3525 | .get_settings = bnx2x_get_settings, |
3486 | .set_settings = bnx2x_set_settings, | 3526 | .set_settings = bnx2x_set_settings, |
@@ -3522,7 +3562,7 @@ static const struct ethtool_ops bnx2x_ethtool_ops = { | |||
3522 | .get_module_eeprom = bnx2x_get_module_eeprom, | 3562 | .get_module_eeprom = bnx2x_get_module_eeprom, |
3523 | .get_eee = bnx2x_get_eee, | 3563 | .get_eee = bnx2x_get_eee, |
3524 | .set_eee = bnx2x_set_eee, | 3564 | .set_eee = bnx2x_set_eee, |
3525 | .get_ts_info = ethtool_op_get_ts_info, | 3565 | .get_ts_info = bnx2x_get_ts_info, |
3526 | }; | 3566 | }; |
3527 | 3567 | ||
3528 | static const struct ethtool_ops bnx2x_vf_ethtool_ops = { | 3568 | static const struct ethtool_ops bnx2x_vf_ethtool_ops = { |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h index 3b6cbd2deafb..7ea04537ecbf 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h | |||
@@ -3547,7 +3547,9 @@ struct client_init_rx_data { | |||
3547 | __le16 rx_cos_mask; | 3547 | __le16 rx_cos_mask; |
3548 | __le16 silent_vlan_value; | 3548 | __le16 silent_vlan_value; |
3549 | __le16 silent_vlan_mask; | 3549 | __le16 silent_vlan_mask; |
3550 | __le32 reserved6[2]; | 3550 | u8 handle_ptp_pkts_flg; |
3551 | u8 reserved6[3]; | ||
3552 | __le32 reserved7; | ||
3551 | }; | 3553 | }; |
3552 | 3554 | ||
3553 | /* | 3555 | /* |
@@ -3616,7 +3618,9 @@ struct client_update_ramrod_data { | |||
3616 | u8 refuse_outband_vlan_change_flg; | 3618 | u8 refuse_outband_vlan_change_flg; |
3617 | u8 tx_switching_flg; | 3619 | u8 tx_switching_flg; |
3618 | u8 tx_switching_change_flg; | 3620 | u8 tx_switching_change_flg; |
3619 | __le32 reserved1; | 3621 | u8 handle_ptp_pkts_flg; |
3622 | u8 handle_ptp_pkts_change_flg; | ||
3623 | __le16 reserved1; | ||
3620 | __le32 echo; | 3624 | __le32 echo; |
3621 | }; | 3625 | }; |
3622 | 3626 | ||
@@ -3850,8 +3854,10 @@ struct eth_fast_path_rx_cqe { | |||
3850 | #define ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG_SHIFT 4 | 3854 | #define ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG_SHIFT 4 |
3851 | #define ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG (0x1<<5) | 3855 | #define ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG (0x1<<5) |
3852 | #define ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG_SHIFT 5 | 3856 | #define ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG_SHIFT 5 |
3853 | #define ETH_FAST_PATH_RX_CQE_RESERVED0 (0x3<<6) | 3857 | #define ETH_FAST_PATH_RX_CQE_PTP_PKT (0x1<<6) |
3854 | #define ETH_FAST_PATH_RX_CQE_RESERVED0_SHIFT 6 | 3858 | #define ETH_FAST_PATH_RX_CQE_PTP_PKT_SHIFT 6 |
3859 | #define ETH_FAST_PATH_RX_CQE_RESERVED0 (0x1<<7) | ||
3860 | #define ETH_FAST_PATH_RX_CQE_RESERVED0_SHIFT 7 | ||
3855 | u8 status_flags; | 3861 | u8 status_flags; |
3856 | #define ETH_FAST_PATH_RX_CQE_RSS_HASH_TYPE (0x7<<0) | 3862 | #define ETH_FAST_PATH_RX_CQE_RSS_HASH_TYPE (0x7<<0) |
3857 | #define ETH_FAST_PATH_RX_CQE_RSS_HASH_TYPE_SHIFT 0 | 3863 | #define ETH_FAST_PATH_RX_CQE_RSS_HASH_TYPE_SHIFT 0 |
@@ -5658,6 +5664,16 @@ struct protocol_common_spe { | |||
5658 | union protocol_common_specific_data data; | 5664 | union protocol_common_specific_data data; |
5659 | }; | 5665 | }; |
5660 | 5666 | ||
5667 | /* The data for the Set Timesync Ramrod */ | ||
5668 | struct set_timesync_ramrod_data { | ||
5669 | u8 drift_adjust_cmd; | ||
5670 | u8 offset_cmd; | ||
5671 | u8 add_sub_drift_adjust_value; | ||
5672 | u8 drift_adjust_value; | ||
5673 | u32 drift_adjust_period; | ||
5674 | struct regpair offset_delta; | ||
5675 | }; | ||
5676 | |||
5661 | /* | 5677 | /* |
5662 | * The send queue element | 5678 | * The send queue element |
5663 | */ | 5679 | */ |
@@ -5780,6 +5796,29 @@ struct tstorm_vf_zone_data { | |||
5780 | struct regpair reserved; | 5796 | struct regpair reserved; |
5781 | }; | 5797 | }; |
5782 | 5798 | ||
5799 | /* Add or Subtract Value for Set Timesync Ramrod */ | ||
5800 | enum ts_add_sub_value { | ||
5801 | TS_SUB_VALUE, | ||
5802 | TS_ADD_VALUE, | ||
5803 | MAX_TS_ADD_SUB_VALUE | ||
5804 | }; | ||
5805 | |||
5806 | /* Drift-Adjust Commands for Set Timesync Ramrod */ | ||
5807 | enum ts_drift_adjust_cmd { | ||
5808 | TS_DRIFT_ADJUST_KEEP, | ||
5809 | TS_DRIFT_ADJUST_SET, | ||
5810 | TS_DRIFT_ADJUST_RESET, | ||
5811 | MAX_TS_DRIFT_ADJUST_CMD | ||
5812 | }; | ||
5813 | |||
5814 | /* Offset Commands for Set Timesync Ramrod */ | ||
5815 | enum ts_offset_cmd { | ||
5816 | TS_OFFSET_KEEP, | ||
5817 | TS_OFFSET_INC, | ||
5818 | TS_OFFSET_DEC, | ||
5819 | MAX_TS_OFFSET_CMD | ||
5820 | }; | ||
5821 | |||
5783 | /* Tunnel Mode */ | 5822 | /* Tunnel Mode */ |
5784 | enum tunnel_mode { | 5823 | enum tunnel_mode { |
5785 | TUNN_MODE_NONE, | 5824 | TUNN_MODE_NONE, |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index a154c7e1550c..566674cc69bc 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | |||
@@ -63,7 +63,6 @@ | |||
63 | #include "bnx2x_vfpf.h" | 63 | #include "bnx2x_vfpf.h" |
64 | #include "bnx2x_dcb.h" | 64 | #include "bnx2x_dcb.h" |
65 | #include "bnx2x_sp.h" | 65 | #include "bnx2x_sp.h" |
66 | |||
67 | #include <linux/firmware.h> | 66 | #include <linux/firmware.h> |
68 | #include "bnx2x_fw_file_hdr.h" | 67 | #include "bnx2x_fw_file_hdr.h" |
69 | /* FW files */ | 68 | /* FW files */ |
@@ -290,6 +289,8 @@ static int bnx2x_set_storm_rx_mode(struct bnx2x *bp); | |||
290 | * General service functions | 289 | * General service functions |
291 | ****************************************************************************/ | 290 | ****************************************************************************/ |
292 | 291 | ||
292 | static int bnx2x_hwtstamp_ioctl(struct bnx2x *bp, struct ifreq *ifr); | ||
293 | |||
293 | static void __storm_memset_dma_mapping(struct bnx2x *bp, | 294 | static void __storm_memset_dma_mapping(struct bnx2x *bp, |
294 | u32 addr, dma_addr_t mapping) | 295 | u32 addr, dma_addr_t mapping) |
295 | { | 296 | { |
@@ -523,6 +524,7 @@ int bnx2x_issue_dmae_with_comp(struct bnx2x *bp, struct dmae_command *dmae, | |||
523 | * as long as this code is called both from syscall context and | 524 | * as long as this code is called both from syscall context and |
524 | * from ndo_set_rx_mode() flow that may be called from BH. | 525 | * from ndo_set_rx_mode() flow that may be called from BH. |
525 | */ | 526 | */ |
527 | |||
526 | spin_lock_bh(&bp->dmae_lock); | 528 | spin_lock_bh(&bp->dmae_lock); |
527 | 529 | ||
528 | /* reset completion */ | 530 | /* reset completion */ |
@@ -551,7 +553,9 @@ int bnx2x_issue_dmae_with_comp(struct bnx2x *bp, struct dmae_command *dmae, | |||
551 | } | 553 | } |
552 | 554 | ||
553 | unlock: | 555 | unlock: |
556 | |||
554 | spin_unlock_bh(&bp->dmae_lock); | 557 | spin_unlock_bh(&bp->dmae_lock); |
558 | |||
555 | return rc; | 559 | return rc; |
556 | } | 560 | } |
557 | 561 | ||
@@ -5452,6 +5456,14 @@ static void bnx2x_eq_int(struct bnx2x *bp) | |||
5452 | break; | 5456 | break; |
5453 | 5457 | ||
5454 | goto next_spqe; | 5458 | goto next_spqe; |
5459 | |||
5460 | case EVENT_RING_OPCODE_SET_TIMESYNC: | ||
5461 | DP(BNX2X_MSG_SP | BNX2X_MSG_PTP, | ||
5462 | "got set_timesync ramrod completion\n"); | ||
5463 | if (f_obj->complete_cmd(bp, f_obj, | ||
5464 | BNX2X_F_CMD_SET_TIMESYNC)) | ||
5465 | break; | ||
5466 | goto next_spqe; | ||
5455 | } | 5467 | } |
5456 | 5468 | ||
5457 | switch (opcode | bp->state) { | 5469 | switch (opcode | bp->state) { |
@@ -9033,6 +9045,48 @@ static int bnx2x_func_wait_started(struct bnx2x *bp) | |||
9033 | return 0; | 9045 | return 0; |
9034 | } | 9046 | } |
9035 | 9047 | ||
9048 | static void bnx2x_disable_ptp(struct bnx2x *bp) | ||
9049 | { | ||
9050 | int port = BP_PORT(bp); | ||
9051 | |||
9052 | /* Disable sending PTP packets to host */ | ||
9053 | REG_WR(bp, port ? NIG_REG_P1_LLH_PTP_TO_HOST : | ||
9054 | NIG_REG_P0_LLH_PTP_TO_HOST, 0x0); | ||
9055 | |||
9056 | /* Reset PTP event detection rules */ | ||
9057 | REG_WR(bp, port ? NIG_REG_P1_LLH_PTP_PARAM_MASK : | ||
9058 | NIG_REG_P0_LLH_PTP_PARAM_MASK, 0x7FF); | ||
9059 | REG_WR(bp, port ? NIG_REG_P1_LLH_PTP_RULE_MASK : | ||
9060 | NIG_REG_P0_LLH_PTP_RULE_MASK, 0x3FFF); | ||
9061 | REG_WR(bp, port ? NIG_REG_P1_TLLH_PTP_PARAM_MASK : | ||
9062 | NIG_REG_P0_TLLH_PTP_PARAM_MASK, 0x7FF); | ||
9063 | REG_WR(bp, port ? NIG_REG_P1_TLLH_PTP_RULE_MASK : | ||
9064 | NIG_REG_P0_TLLH_PTP_RULE_MASK, 0x3FFF); | ||
9065 | |||
9066 | /* Disable the PTP feature */ | ||
9067 | REG_WR(bp, port ? NIG_REG_P1_PTP_EN : | ||
9068 | NIG_REG_P0_PTP_EN, 0x0); | ||
9069 | } | ||
9070 | |||
9071 | /* Called during unload, to stop PTP-related stuff */ | ||
9072 | void bnx2x_stop_ptp(struct bnx2x *bp) | ||
9073 | { | ||
9074 | /* Cancel PTP work queue. Should be done after the Tx queues are | ||
9075 | * drained to prevent additional scheduling. | ||
9076 | */ | ||
9077 | cancel_work_sync(&bp->ptp_task); | ||
9078 | |||
9079 | if (bp->ptp_tx_skb) { | ||
9080 | dev_kfree_skb_any(bp->ptp_tx_skb); | ||
9081 | bp->ptp_tx_skb = NULL; | ||
9082 | } | ||
9083 | |||
9084 | /* Disable PTP in HW */ | ||
9085 | bnx2x_disable_ptp(bp); | ||
9086 | |||
9087 | DP(BNX2X_MSG_PTP, "PTP stop ended successfully\n"); | ||
9088 | } | ||
9089 | |||
9036 | void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode, bool keep_link) | 9090 | void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode, bool keep_link) |
9037 | { | 9091 | { |
9038 | int port = BP_PORT(bp); | 9092 | int port = BP_PORT(bp); |
@@ -9151,6 +9205,13 @@ unload_error: | |||
9151 | #endif | 9205 | #endif |
9152 | } | 9206 | } |
9153 | 9207 | ||
9208 | /* stop_ptp should be after the Tx queues are drained to prevent | ||
9209 | * scheduling to the cancelled PTP work queue. It should also be after | ||
9210 | * function stop ramrod is sent, since as part of this ramrod FW access | ||
9211 | * PTP registers. | ||
9212 | */ | ||
9213 | bnx2x_stop_ptp(bp); | ||
9214 | |||
9154 | /* Disable HW interrupts, NAPI */ | 9215 | /* Disable HW interrupts, NAPI */ |
9155 | bnx2x_netif_stop(bp, 1); | 9216 | bnx2x_netif_stop(bp, 1); |
9156 | /* Delete all NAPI objects */ | 9217 | /* Delete all NAPI objects */ |
@@ -12023,6 +12084,9 @@ static int bnx2x_init_bp(struct bnx2x *bp) | |||
12023 | 12084 | ||
12024 | bp->dump_preset_idx = 1; | 12085 | bp->dump_preset_idx = 1; |
12025 | 12086 | ||
12087 | if (CHIP_IS_E3B0(bp)) | ||
12088 | bp->flags |= PTP_SUPPORTED; | ||
12089 | |||
12026 | return rc; | 12090 | return rc; |
12027 | } | 12091 | } |
12028 | 12092 | ||
@@ -12355,13 +12419,17 @@ static int bnx2x_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
12355 | struct bnx2x *bp = netdev_priv(dev); | 12419 | struct bnx2x *bp = netdev_priv(dev); |
12356 | struct mii_ioctl_data *mdio = if_mii(ifr); | 12420 | struct mii_ioctl_data *mdio = if_mii(ifr); |
12357 | 12421 | ||
12358 | DP(NETIF_MSG_LINK, "ioctl: phy id 0x%x, reg 0x%x, val_in 0x%x\n", | ||
12359 | mdio->phy_id, mdio->reg_num, mdio->val_in); | ||
12360 | |||
12361 | if (!netif_running(dev)) | 12422 | if (!netif_running(dev)) |
12362 | return -EAGAIN; | 12423 | return -EAGAIN; |
12363 | 12424 | ||
12364 | return mdio_mii_ioctl(&bp->mdio, mdio, cmd); | 12425 | switch (cmd) { |
12426 | case SIOCSHWTSTAMP: | ||
12427 | return bnx2x_hwtstamp_ioctl(bp, ifr); | ||
12428 | default: | ||
12429 | DP(NETIF_MSG_LINK, "ioctl: phy id 0x%x, reg 0x%x, val_in 0x%x\n", | ||
12430 | mdio->phy_id, mdio->reg_num, mdio->val_in); | ||
12431 | return mdio_mii_ioctl(&bp->mdio, mdio, cmd); | ||
12432 | } | ||
12365 | } | 12433 | } |
12366 | 12434 | ||
12367 | #ifdef CONFIG_NET_POLL_CONTROLLER | 12435 | #ifdef CONFIG_NET_POLL_CONTROLLER |
@@ -13005,6 +13073,191 @@ static int set_is_vf(int chip_id) | |||
13005 | } | 13073 | } |
13006 | } | 13074 | } |
13007 | 13075 | ||
13076 | /* nig_tsgen registers relative address */ | ||
13077 | #define tsgen_ctrl 0x0 | ||
13078 | #define tsgen_freecount 0x10 | ||
13079 | #define tsgen_synctime_t0 0x20 | ||
13080 | #define tsgen_offset_t0 0x28 | ||
13081 | #define tsgen_drift_t0 0x30 | ||
13082 | #define tsgen_synctime_t1 0x58 | ||
13083 | #define tsgen_offset_t1 0x60 | ||
13084 | #define tsgen_drift_t1 0x68 | ||
13085 | |||
13086 | /* FW workaround for setting drift */ | ||
13087 | static int bnx2x_send_update_drift_ramrod(struct bnx2x *bp, int drift_dir, | ||
13088 | int best_val, int best_period) | ||
13089 | { | ||
13090 | struct bnx2x_func_state_params func_params = {NULL}; | ||
13091 | struct bnx2x_func_set_timesync_params *set_timesync_params = | ||
13092 | &func_params.params.set_timesync; | ||
13093 | |||
13094 | /* Prepare parameters for function state transitions */ | ||
13095 | __set_bit(RAMROD_COMP_WAIT, &func_params.ramrod_flags); | ||
13096 | __set_bit(RAMROD_RETRY, &func_params.ramrod_flags); | ||
13097 | |||
13098 | func_params.f_obj = &bp->func_obj; | ||
13099 | func_params.cmd = BNX2X_F_CMD_SET_TIMESYNC; | ||
13100 | |||
13101 | /* Function parameters */ | ||
13102 | set_timesync_params->drift_adjust_cmd = TS_DRIFT_ADJUST_SET; | ||
13103 | set_timesync_params->offset_cmd = TS_OFFSET_KEEP; | ||
13104 | set_timesync_params->add_sub_drift_adjust_value = | ||
13105 | drift_dir ? TS_ADD_VALUE : TS_SUB_VALUE; | ||
13106 | set_timesync_params->drift_adjust_value = best_val; | ||
13107 | set_timesync_params->drift_adjust_period = best_period; | ||
13108 | |||
13109 | return bnx2x_func_state_change(bp, &func_params); | ||
13110 | } | ||
13111 | |||
13112 | static int bnx2x_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb) | ||
13113 | { | ||
13114 | struct bnx2x *bp = container_of(ptp, struct bnx2x, ptp_clock_info); | ||
13115 | int rc; | ||
13116 | int drift_dir = 1; | ||
13117 | int val, period, period1, period2, dif, dif1, dif2; | ||
13118 | int best_dif = BNX2X_MAX_PHC_DRIFT, best_period = 0, best_val = 0; | ||
13119 | |||
13120 | DP(BNX2X_MSG_PTP, "PTP adjfreq called, ppb = %d\n", ppb); | ||
13121 | |||
13122 | if (!netif_running(bp->dev)) { | ||
13123 | DP(BNX2X_MSG_PTP, | ||
13124 | "PTP adjfreq called while the interface is down\n"); | ||
13125 | return -EFAULT; | ||
13126 | } | ||
13127 | |||
13128 | if (ppb < 0) { | ||
13129 | ppb = -ppb; | ||
13130 | drift_dir = 0; | ||
13131 | } | ||
13132 | |||
13133 | if (ppb == 0) { | ||
13134 | best_val = 1; | ||
13135 | best_period = 0x1FFFFFF; | ||
13136 | } else if (ppb >= BNX2X_MAX_PHC_DRIFT) { | ||
13137 | best_val = 31; | ||
13138 | best_period = 1; | ||
13139 | } else { | ||
13140 | /* Changed not to allow val = 8, 16, 24 as these values | ||
13141 | * are not supported in workaround. | ||
13142 | */ | ||
13143 | for (val = 0; val <= 31; val++) { | ||
13144 | if ((val & 0x7) == 0) | ||
13145 | continue; | ||
13146 | period1 = val * 1000000 / ppb; | ||
13147 | period2 = period1 + 1; | ||
13148 | if (period1 != 0) | ||
13149 | dif1 = ppb - (val * 1000000 / period1); | ||
13150 | else | ||
13151 | dif1 = BNX2X_MAX_PHC_DRIFT; | ||
13152 | if (dif1 < 0) | ||
13153 | dif1 = -dif1; | ||
13154 | dif2 = ppb - (val * 1000000 / period2); | ||
13155 | if (dif2 < 0) | ||
13156 | dif2 = -dif2; | ||
13157 | dif = (dif1 < dif2) ? dif1 : dif2; | ||
13158 | period = (dif1 < dif2) ? period1 : period2; | ||
13159 | if (dif < best_dif) { | ||
13160 | best_dif = dif; | ||
13161 | best_val = val; | ||
13162 | best_period = period; | ||
13163 | } | ||
13164 | } | ||
13165 | } | ||
13166 | |||
13167 | rc = bnx2x_send_update_drift_ramrod(bp, drift_dir, best_val, | ||
13168 | best_period); | ||
13169 | if (rc) { | ||
13170 | BNX2X_ERR("Failed to set drift\n"); | ||
13171 | return -EFAULT; | ||
13172 | } | ||
13173 | |||
13174 | DP(BNX2X_MSG_PTP, "Configrued val = %d, period = %d\n", best_val, | ||
13175 | best_period); | ||
13176 | |||
13177 | return 0; | ||
13178 | } | ||
13179 | |||
13180 | static int bnx2x_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) | ||
13181 | { | ||
13182 | struct bnx2x *bp = container_of(ptp, struct bnx2x, ptp_clock_info); | ||
13183 | u64 now; | ||
13184 | |||
13185 | DP(BNX2X_MSG_PTP, "PTP adjtime called, delta = %llx\n", delta); | ||
13186 | |||
13187 | now = timecounter_read(&bp->timecounter); | ||
13188 | now += delta; | ||
13189 | /* Re-init the timecounter */ | ||
13190 | timecounter_init(&bp->timecounter, &bp->cyclecounter, now); | ||
13191 | |||
13192 | return 0; | ||
13193 | } | ||
13194 | |||
13195 | static int bnx2x_ptp_gettime(struct ptp_clock_info *ptp, struct timespec *ts) | ||
13196 | { | ||
13197 | struct bnx2x *bp = container_of(ptp, struct bnx2x, ptp_clock_info); | ||
13198 | u64 ns; | ||
13199 | u32 remainder; | ||
13200 | |||
13201 | ns = timecounter_read(&bp->timecounter); | ||
13202 | |||
13203 | DP(BNX2X_MSG_PTP, "PTP gettime called, ns = %llu\n", ns); | ||
13204 | |||
13205 | ts->tv_sec = div_u64_rem(ns, 1000000000ULL, &remainder); | ||
13206 | ts->tv_nsec = remainder; | ||
13207 | |||
13208 | return 0; | ||
13209 | } | ||
13210 | |||
13211 | static int bnx2x_ptp_settime(struct ptp_clock_info *ptp, | ||
13212 | const struct timespec *ts) | ||
13213 | { | ||
13214 | struct bnx2x *bp = container_of(ptp, struct bnx2x, ptp_clock_info); | ||
13215 | u64 ns; | ||
13216 | |||
13217 | ns = ts->tv_sec * 1000000000ULL; | ||
13218 | ns += ts->tv_nsec; | ||
13219 | |||
13220 | DP(BNX2X_MSG_PTP, "PTP settime called, ns = %llu\n", ns); | ||
13221 | |||
13222 | /* Re-init the timecounter */ | ||
13223 | timecounter_init(&bp->timecounter, &bp->cyclecounter, ns); | ||
13224 | |||
13225 | return 0; | ||
13226 | } | ||
13227 | |||
13228 | /* Enable (or disable) ancillary features of the phc subsystem */ | ||
13229 | static int bnx2x_ptp_enable(struct ptp_clock_info *ptp, | ||
13230 | struct ptp_clock_request *rq, int on) | ||
13231 | { | ||
13232 | struct bnx2x *bp = container_of(ptp, struct bnx2x, ptp_clock_info); | ||
13233 | |||
13234 | BNX2X_ERR("PHC ancillary features are not supported\n"); | ||
13235 | return -ENOTSUPP; | ||
13236 | } | ||
13237 | |||
13238 | void bnx2x_register_phc(struct bnx2x *bp) | ||
13239 | { | ||
13240 | /* Fill the ptp_clock_info struct and register PTP clock*/ | ||
13241 | bp->ptp_clock_info.owner = THIS_MODULE; | ||
13242 | snprintf(bp->ptp_clock_info.name, 16, "%s", bp->dev->name); | ||
13243 | bp->ptp_clock_info.max_adj = BNX2X_MAX_PHC_DRIFT; /* In PPB */ | ||
13244 | bp->ptp_clock_info.n_alarm = 0; | ||
13245 | bp->ptp_clock_info.n_ext_ts = 0; | ||
13246 | bp->ptp_clock_info.n_per_out = 0; | ||
13247 | bp->ptp_clock_info.pps = 0; | ||
13248 | bp->ptp_clock_info.adjfreq = bnx2x_ptp_adjfreq; | ||
13249 | bp->ptp_clock_info.adjtime = bnx2x_ptp_adjtime; | ||
13250 | bp->ptp_clock_info.gettime = bnx2x_ptp_gettime; | ||
13251 | bp->ptp_clock_info.settime = bnx2x_ptp_settime; | ||
13252 | bp->ptp_clock_info.enable = bnx2x_ptp_enable; | ||
13253 | |||
13254 | bp->ptp_clock = ptp_clock_register(&bp->ptp_clock_info, &bp->pdev->dev); | ||
13255 | if (IS_ERR(bp->ptp_clock)) { | ||
13256 | bp->ptp_clock = NULL; | ||
13257 | BNX2X_ERR("PTP clock registeration failed\n"); | ||
13258 | } | ||
13259 | } | ||
13260 | |||
13008 | static int bnx2x_init_one(struct pci_dev *pdev, | 13261 | static int bnx2x_init_one(struct pci_dev *pdev, |
13009 | const struct pci_device_id *ent) | 13262 | const struct pci_device_id *ent) |
13010 | { | 13263 | { |
@@ -13176,6 +13429,8 @@ static int bnx2x_init_one(struct pci_dev *pdev, | |||
13176 | "Unknown", | 13429 | "Unknown", |
13177 | dev->base_addr, bp->pdev->irq, dev->dev_addr); | 13430 | dev->base_addr, bp->pdev->irq, dev->dev_addr); |
13178 | 13431 | ||
13432 | bnx2x_register_phc(bp); | ||
13433 | |||
13179 | return 0; | 13434 | return 0; |
13180 | 13435 | ||
13181 | init_one_exit: | 13436 | init_one_exit: |
@@ -13202,6 +13457,11 @@ static void __bnx2x_remove(struct pci_dev *pdev, | |||
13202 | struct bnx2x *bp, | 13457 | struct bnx2x *bp, |
13203 | bool remove_netdev) | 13458 | bool remove_netdev) |
13204 | { | 13459 | { |
13460 | if (bp->ptp_clock) { | ||
13461 | ptp_clock_unregister(bp->ptp_clock); | ||
13462 | bp->ptp_clock = NULL; | ||
13463 | } | ||
13464 | |||
13205 | /* Delete storage MAC address */ | 13465 | /* Delete storage MAC address */ |
13206 | if (!NO_FCOE(bp)) { | 13466 | if (!NO_FCOE(bp)) { |
13207 | rtnl_lock(); | 13467 | rtnl_lock(); |
@@ -14177,3 +14437,332 @@ int bnx2x_pretend_func(struct bnx2x *bp, u16 pretend_func_val) | |||
14177 | REG_RD(bp, pretend_reg); | 14437 | REG_RD(bp, pretend_reg); |
14178 | return 0; | 14438 | return 0; |
14179 | } | 14439 | } |
14440 | |||
14441 | static void bnx2x_ptp_task(struct work_struct *work) | ||
14442 | { | ||
14443 | struct bnx2x *bp = container_of(work, struct bnx2x, ptp_task); | ||
14444 | int port = BP_PORT(bp); | ||
14445 | u32 val_seq; | ||
14446 | u64 timestamp, ns; | ||
14447 | struct skb_shared_hwtstamps shhwtstamps; | ||
14448 | |||
14449 | /* Read Tx timestamp registers */ | ||
14450 | val_seq = REG_RD(bp, port ? NIG_REG_P1_TLLH_PTP_BUF_SEQID : | ||
14451 | NIG_REG_P0_TLLH_PTP_BUF_SEQID); | ||
14452 | if (val_seq & 0x10000) { | ||
14453 | /* There is a valid timestamp value */ | ||
14454 | timestamp = REG_RD(bp, port ? NIG_REG_P1_TLLH_PTP_BUF_TS_MSB : | ||
14455 | NIG_REG_P0_TLLH_PTP_BUF_TS_MSB); | ||
14456 | timestamp <<= 32; | ||
14457 | timestamp |= REG_RD(bp, port ? NIG_REG_P1_TLLH_PTP_BUF_TS_LSB : | ||
14458 | NIG_REG_P0_TLLH_PTP_BUF_TS_LSB); | ||
14459 | /* Reset timestamp register to allow new timestamp */ | ||
14460 | REG_WR(bp, port ? NIG_REG_P1_TLLH_PTP_BUF_SEQID : | ||
14461 | NIG_REG_P0_TLLH_PTP_BUF_SEQID, 0x10000); | ||
14462 | ns = timecounter_cyc2time(&bp->timecounter, timestamp); | ||
14463 | |||
14464 | memset(&shhwtstamps, 0, sizeof(shhwtstamps)); | ||
14465 | shhwtstamps.hwtstamp = ns_to_ktime(ns); | ||
14466 | skb_tstamp_tx(bp->ptp_tx_skb, &shhwtstamps); | ||
14467 | dev_kfree_skb_any(bp->ptp_tx_skb); | ||
14468 | bp->ptp_tx_skb = NULL; | ||
14469 | |||
14470 | DP(BNX2X_MSG_PTP, "Tx timestamp, timestamp cycles = %llu, ns = %llu\n", | ||
14471 | timestamp, ns); | ||
14472 | } else { | ||
14473 | DP(BNX2X_MSG_PTP, "There is no valid Tx timestamp yet\n"); | ||
14474 | /* Reschedule to keep checking for a valid timestamp value */ | ||
14475 | schedule_work(&bp->ptp_task); | ||
14476 | } | ||
14477 | } | ||
14478 | |||
14479 | void bnx2x_set_rx_ts(struct bnx2x *bp, struct sk_buff *skb) | ||
14480 | { | ||
14481 | int port = BP_PORT(bp); | ||
14482 | u64 timestamp, ns; | ||
14483 | |||
14484 | timestamp = REG_RD(bp, port ? NIG_REG_P1_LLH_PTP_HOST_BUF_TS_MSB : | ||
14485 | NIG_REG_P0_LLH_PTP_HOST_BUF_TS_MSB); | ||
14486 | timestamp <<= 32; | ||
14487 | timestamp |= REG_RD(bp, port ? NIG_REG_P1_LLH_PTP_HOST_BUF_TS_LSB : | ||
14488 | NIG_REG_P0_LLH_PTP_HOST_BUF_TS_LSB); | ||
14489 | |||
14490 | /* Reset timestamp register to allow new timestamp */ | ||
14491 | REG_WR(bp, port ? NIG_REG_P1_LLH_PTP_HOST_BUF_SEQID : | ||
14492 | NIG_REG_P0_LLH_PTP_HOST_BUF_SEQID, 0x10000); | ||
14493 | |||
14494 | ns = timecounter_cyc2time(&bp->timecounter, timestamp); | ||
14495 | |||
14496 | skb_hwtstamps(skb)->hwtstamp = ns_to_ktime(ns); | ||
14497 | |||
14498 | DP(BNX2X_MSG_PTP, "Rx timestamp, timestamp cycles = %llu, ns = %llu\n", | ||
14499 | timestamp, ns); | ||
14500 | } | ||
14501 | |||
14502 | /* Read the PHC */ | ||
14503 | static cycle_t bnx2x_cyclecounter_read(const struct cyclecounter *cc) | ||
14504 | { | ||
14505 | struct bnx2x *bp = container_of(cc, struct bnx2x, cyclecounter); | ||
14506 | int port = BP_PORT(bp); | ||
14507 | u32 wb_data[2]; | ||
14508 | u64 phc_cycles; | ||
14509 | |||
14510 | REG_RD_DMAE(bp, port ? NIG_REG_TIMESYNC_GEN_REG + tsgen_synctime_t1 : | ||
14511 | NIG_REG_TIMESYNC_GEN_REG + tsgen_synctime_t0, wb_data, 2); | ||
14512 | phc_cycles = wb_data[1]; | ||
14513 | phc_cycles = (phc_cycles << 32) + wb_data[0]; | ||
14514 | |||
14515 | DP(BNX2X_MSG_PTP, "PHC read cycles = %llu\n", phc_cycles); | ||
14516 | |||
14517 | return phc_cycles; | ||
14518 | } | ||
14519 | |||
14520 | static void bnx2x_init_cyclecounter(struct bnx2x *bp) | ||
14521 | { | ||
14522 | memset(&bp->cyclecounter, 0, sizeof(bp->cyclecounter)); | ||
14523 | bp->cyclecounter.read = bnx2x_cyclecounter_read; | ||
14524 | bp->cyclecounter.mask = CLOCKSOURCE_MASK(64); | ||
14525 | bp->cyclecounter.shift = 1; | ||
14526 | bp->cyclecounter.mult = 1; | ||
14527 | } | ||
14528 | |||
14529 | static int bnx2x_send_reset_timesync_ramrod(struct bnx2x *bp) | ||
14530 | { | ||
14531 | struct bnx2x_func_state_params func_params = {NULL}; | ||
14532 | struct bnx2x_func_set_timesync_params *set_timesync_params = | ||
14533 | &func_params.params.set_timesync; | ||
14534 | |||
14535 | /* Prepare parameters for function state transitions */ | ||
14536 | __set_bit(RAMROD_COMP_WAIT, &func_params.ramrod_flags); | ||
14537 | __set_bit(RAMROD_RETRY, &func_params.ramrod_flags); | ||
14538 | |||
14539 | func_params.f_obj = &bp->func_obj; | ||
14540 | func_params.cmd = BNX2X_F_CMD_SET_TIMESYNC; | ||
14541 | |||
14542 | /* Function parameters */ | ||
14543 | set_timesync_params->drift_adjust_cmd = TS_DRIFT_ADJUST_RESET; | ||
14544 | set_timesync_params->offset_cmd = TS_OFFSET_KEEP; | ||
14545 | |||
14546 | return bnx2x_func_state_change(bp, &func_params); | ||
14547 | } | ||
14548 | |||
14549 | int bnx2x_enable_ptp_packets(struct bnx2x *bp) | ||
14550 | { | ||
14551 | struct bnx2x_queue_state_params q_params; | ||
14552 | int rc, i; | ||
14553 | |||
14554 | /* send queue update ramrod to enable PTP packets */ | ||
14555 | memset(&q_params, 0, sizeof(q_params)); | ||
14556 | __set_bit(RAMROD_COMP_WAIT, &q_params.ramrod_flags); | ||
14557 | q_params.cmd = BNX2X_Q_CMD_UPDATE; | ||
14558 | __set_bit(BNX2X_Q_UPDATE_PTP_PKTS_CHNG, | ||
14559 | &q_params.params.update.update_flags); | ||
14560 | __set_bit(BNX2X_Q_UPDATE_PTP_PKTS, | ||
14561 | &q_params.params.update.update_flags); | ||
14562 | |||
14563 | /* send the ramrod on all the queues of the PF */ | ||
14564 | for_each_eth_queue(bp, i) { | ||
14565 | struct bnx2x_fastpath *fp = &bp->fp[i]; | ||
14566 | |||
14567 | /* Set the appropriate Queue object */ | ||
14568 | q_params.q_obj = &bnx2x_sp_obj(bp, fp).q_obj; | ||
14569 | |||
14570 | /* Update the Queue state */ | ||
14571 | rc = bnx2x_queue_state_change(bp, &q_params); | ||
14572 | if (rc) { | ||
14573 | BNX2X_ERR("Failed to enable PTP packets\n"); | ||
14574 | return rc; | ||
14575 | } | ||
14576 | } | ||
14577 | |||
14578 | return 0; | ||
14579 | } | ||
14580 | |||
14581 | int bnx2x_configure_ptp_filters(struct bnx2x *bp) | ||
14582 | { | ||
14583 | int port = BP_PORT(bp); | ||
14584 | int rc; | ||
14585 | |||
14586 | if (!bp->hwtstamp_ioctl_called) | ||
14587 | return 0; | ||
14588 | |||
14589 | switch (bp->tx_type) { | ||
14590 | case HWTSTAMP_TX_ON: | ||
14591 | bp->flags |= TX_TIMESTAMPING_EN; | ||
14592 | REG_WR(bp, port ? NIG_REG_P1_TLLH_PTP_PARAM_MASK : | ||
14593 | NIG_REG_P0_TLLH_PTP_PARAM_MASK, 0x6AA); | ||
14594 | REG_WR(bp, port ? NIG_REG_P1_TLLH_PTP_RULE_MASK : | ||
14595 | NIG_REG_P0_TLLH_PTP_RULE_MASK, 0x3EEE); | ||
14596 | break; | ||
14597 | case HWTSTAMP_TX_ONESTEP_SYNC: | ||
14598 | BNX2X_ERR("One-step timestamping is not supported\n"); | ||
14599 | return -ERANGE; | ||
14600 | } | ||
14601 | |||
14602 | switch (bp->rx_filter) { | ||
14603 | case HWTSTAMP_FILTER_NONE: | ||
14604 | break; | ||
14605 | case HWTSTAMP_FILTER_ALL: | ||
14606 | case HWTSTAMP_FILTER_SOME: | ||
14607 | bp->rx_filter = HWTSTAMP_FILTER_NONE; | ||
14608 | break; | ||
14609 | case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: | ||
14610 | case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: | ||
14611 | case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: | ||
14612 | bp->rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT; | ||
14613 | /* Initialize PTP detection for UDP/IPv4 events */ | ||
14614 | REG_WR(bp, port ? NIG_REG_P1_LLH_PTP_PARAM_MASK : | ||
14615 | NIG_REG_P0_LLH_PTP_PARAM_MASK, 0x7EE); | ||
14616 | REG_WR(bp, port ? NIG_REG_P1_LLH_PTP_RULE_MASK : | ||
14617 | NIG_REG_P0_LLH_PTP_RULE_MASK, 0x3FFE); | ||
14618 | break; | ||
14619 | case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: | ||
14620 | case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: | ||
14621 | case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: | ||
14622 | bp->rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT; | ||
14623 | /* Initialize PTP detection for UDP/IPv4 or UDP/IPv6 events */ | ||
14624 | REG_WR(bp, port ? NIG_REG_P1_LLH_PTP_PARAM_MASK : | ||
14625 | NIG_REG_P0_LLH_PTP_PARAM_MASK, 0x7EA); | ||
14626 | REG_WR(bp, port ? NIG_REG_P1_LLH_PTP_RULE_MASK : | ||
14627 | NIG_REG_P0_LLH_PTP_RULE_MASK, 0x3FEE); | ||
14628 | break; | ||
14629 | case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: | ||
14630 | case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: | ||
14631 | case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: | ||
14632 | bp->rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT; | ||
14633 | /* Initialize PTP detection L2 events */ | ||
14634 | REG_WR(bp, port ? NIG_REG_P1_LLH_PTP_PARAM_MASK : | ||
14635 | NIG_REG_P0_LLH_PTP_PARAM_MASK, 0x6BF); | ||
14636 | REG_WR(bp, port ? NIG_REG_P1_LLH_PTP_RULE_MASK : | ||
14637 | NIG_REG_P0_LLH_PTP_RULE_MASK, 0x3EFF); | ||
14638 | |||
14639 | break; | ||
14640 | case HWTSTAMP_FILTER_PTP_V2_EVENT: | ||
14641 | case HWTSTAMP_FILTER_PTP_V2_SYNC: | ||
14642 | case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: | ||
14643 | bp->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; | ||
14644 | /* Initialize PTP detection L2, UDP/IPv4 or UDP/IPv6 events */ | ||
14645 | REG_WR(bp, port ? NIG_REG_P1_LLH_PTP_PARAM_MASK : | ||
14646 | NIG_REG_P0_LLH_PTP_PARAM_MASK, 0x6AA); | ||
14647 | REG_WR(bp, port ? NIG_REG_P1_LLH_PTP_RULE_MASK : | ||
14648 | NIG_REG_P0_LLH_PTP_RULE_MASK, 0x3EEE); | ||
14649 | break; | ||
14650 | } | ||
14651 | |||
14652 | /* Indicate to FW that this PF expects recorded PTP packets */ | ||
14653 | rc = bnx2x_enable_ptp_packets(bp); | ||
14654 | if (rc) | ||
14655 | return rc; | ||
14656 | |||
14657 | /* Enable sending PTP packets to host */ | ||
14658 | REG_WR(bp, port ? NIG_REG_P1_LLH_PTP_TO_HOST : | ||
14659 | NIG_REG_P0_LLH_PTP_TO_HOST, 0x1); | ||
14660 | |||
14661 | return 0; | ||
14662 | } | ||
14663 | |||
14664 | static int bnx2x_hwtstamp_ioctl(struct bnx2x *bp, struct ifreq *ifr) | ||
14665 | { | ||
14666 | struct hwtstamp_config config; | ||
14667 | int rc; | ||
14668 | |||
14669 | DP(BNX2X_MSG_PTP, "HWTSTAMP IOCTL called\n"); | ||
14670 | |||
14671 | if (copy_from_user(&config, ifr->ifr_data, sizeof(config))) | ||
14672 | return -EFAULT; | ||
14673 | |||
14674 | DP(BNX2X_MSG_PTP, "Requested tx_type: %d, requested rx_filters = %d\n", | ||
14675 | config.tx_type, config.rx_filter); | ||
14676 | |||
14677 | if (config.flags) { | ||
14678 | BNX2X_ERR("config.flags is reserved for future use\n"); | ||
14679 | return -EINVAL; | ||
14680 | } | ||
14681 | |||
14682 | bp->hwtstamp_ioctl_called = 1; | ||
14683 | bp->tx_type = config.tx_type; | ||
14684 | bp->rx_filter = config.rx_filter; | ||
14685 | |||
14686 | rc = bnx2x_configure_ptp_filters(bp); | ||
14687 | if (rc) | ||
14688 | return rc; | ||
14689 | |||
14690 | config.rx_filter = bp->rx_filter; | ||
14691 | |||
14692 | return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ? | ||
14693 | -EFAULT : 0; | ||
14694 | } | ||
14695 | |||
14696 | /* Configrues HW for PTP */ | ||
14697 | static int bnx2x_configure_ptp(struct bnx2x *bp) | ||
14698 | { | ||
14699 | int rc, port = BP_PORT(bp); | ||
14700 | u32 wb_data[2]; | ||
14701 | |||
14702 | /* Reset PTP event detection rules - will be configured in the IOCTL */ | ||
14703 | REG_WR(bp, port ? NIG_REG_P1_LLH_PTP_PARAM_MASK : | ||
14704 | NIG_REG_P0_LLH_PTP_PARAM_MASK, 0x7FF); | ||
14705 | REG_WR(bp, port ? NIG_REG_P1_LLH_PTP_RULE_MASK : | ||
14706 | NIG_REG_P0_LLH_PTP_RULE_MASK, 0x3FFF); | ||
14707 | REG_WR(bp, port ? NIG_REG_P1_TLLH_PTP_PARAM_MASK : | ||
14708 | NIG_REG_P0_TLLH_PTP_PARAM_MASK, 0x7FF); | ||
14709 | REG_WR(bp, port ? NIG_REG_P1_TLLH_PTP_RULE_MASK : | ||
14710 | NIG_REG_P0_TLLH_PTP_RULE_MASK, 0x3FFF); | ||
14711 | |||
14712 | /* Disable PTP packets to host - will be configured in the IOCTL*/ | ||
14713 | REG_WR(bp, port ? NIG_REG_P1_LLH_PTP_TO_HOST : | ||
14714 | NIG_REG_P0_LLH_PTP_TO_HOST, 0x0); | ||
14715 | |||
14716 | /* Enable the PTP feature */ | ||
14717 | REG_WR(bp, port ? NIG_REG_P1_PTP_EN : | ||
14718 | NIG_REG_P0_PTP_EN, 0x3F); | ||
14719 | |||
14720 | /* Enable the free-running counter */ | ||
14721 | wb_data[0] = 0; | ||
14722 | wb_data[1] = 0; | ||
14723 | REG_WR_DMAE(bp, NIG_REG_TIMESYNC_GEN_REG + tsgen_ctrl, wb_data, 2); | ||
14724 | |||
14725 | /* Reset drift register (offset register is not reset) */ | ||
14726 | rc = bnx2x_send_reset_timesync_ramrod(bp); | ||
14727 | if (rc) { | ||
14728 | BNX2X_ERR("Failed to reset PHC drift register\n"); | ||
14729 | return -EFAULT; | ||
14730 | } | ||
14731 | |||
14732 | /* Reset possibly old timestamps */ | ||
14733 | REG_WR(bp, port ? NIG_REG_P1_LLH_PTP_HOST_BUF_SEQID : | ||
14734 | NIG_REG_P0_LLH_PTP_HOST_BUF_SEQID, 0x10000); | ||
14735 | REG_WR(bp, port ? NIG_REG_P1_TLLH_PTP_BUF_SEQID : | ||
14736 | NIG_REG_P0_TLLH_PTP_BUF_SEQID, 0x10000); | ||
14737 | |||
14738 | return 0; | ||
14739 | } | ||
14740 | |||
14741 | /* Called during load, to initialize PTP-related stuff */ | ||
14742 | void bnx2x_init_ptp(struct bnx2x *bp) | ||
14743 | { | ||
14744 | int rc; | ||
14745 | |||
14746 | /* Configure PTP in HW */ | ||
14747 | rc = bnx2x_configure_ptp(bp); | ||
14748 | if (rc) { | ||
14749 | BNX2X_ERR("Stopping PTP initialization\n"); | ||
14750 | return; | ||
14751 | } | ||
14752 | |||
14753 | /* Init work queue for Tx timestamping */ | ||
14754 | INIT_WORK(&bp->ptp_task, bnx2x_ptp_task); | ||
14755 | |||
14756 | /* Init cyclecounter and timecounter. This is done only in the first | ||
14757 | * load. If done in every load, PTP application will fail when doing | ||
14758 | * unload / load (e.g. MTU change) while it is running. | ||
14759 | */ | ||
14760 | if (!bp->timecounter_init_done) { | ||
14761 | bnx2x_init_cyclecounter(bp); | ||
14762 | timecounter_init(&bp->timecounter, &bp->cyclecounter, | ||
14763 | ktime_to_ns(ktime_get_real())); | ||
14764 | bp->timecounter_init_done = 1; | ||
14765 | } | ||
14766 | |||
14767 | DP(BNX2X_MSG_PTP, "PTP initialization ended successfully\n"); | ||
14768 | } | ||
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h index 2beb5430b876..b0779d773343 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h | |||
@@ -2182,6 +2182,45 @@ | |||
2182 | #define NIG_REG_P0_HWPFC_ENABLE 0x18078 | 2182 | #define NIG_REG_P0_HWPFC_ENABLE 0x18078 |
2183 | #define NIG_REG_P0_LLH_FUNC_MEM2 0x18480 | 2183 | #define NIG_REG_P0_LLH_FUNC_MEM2 0x18480 |
2184 | #define NIG_REG_P0_LLH_FUNC_MEM2_ENABLE 0x18440 | 2184 | #define NIG_REG_P0_LLH_FUNC_MEM2_ENABLE 0x18440 |
2185 | /* [RW 17] Packet TimeSync information that is buffered in 1-deep FIFOs for | ||
2186 | * the host. Bits [15:0] return the sequence ID of the packet. Bit 16 | ||
2187 | * indicates the validity of the data in the buffer. Writing a 1 to bit 16 | ||
2188 | * will clear the buffer. | ||
2189 | */ | ||
2190 | #define NIG_REG_P0_LLH_PTP_HOST_BUF_SEQID 0x1875c | ||
2191 | /* [R 32] Packet TimeSync information that is buffered in 1-deep FIFOs for | ||
2192 | * the host. This location returns the lower 32 bits of timestamp value. | ||
2193 | */ | ||
2194 | #define NIG_REG_P0_LLH_PTP_HOST_BUF_TS_LSB 0x18754 | ||
2195 | /* [R 32] Packet TimeSync information that is buffered in 1-deep FIFOs for | ||
2196 | * the host. This location returns the upper 32 bits of timestamp value. | ||
2197 | */ | ||
2198 | #define NIG_REG_P0_LLH_PTP_HOST_BUF_TS_MSB 0x18758 | ||
2199 | /* [RW 11] Mask register for the various parameters used in determining PTP | ||
2200 | * packet presence. Set each bit to 1 to mask out the particular parameter. | ||
2201 | * 0-IPv4 DA 0 of 224.0.1.129. 1-IPv4 DA 1 of 224.0.0.107. 2-IPv6 DA 0 of | ||
2202 | * 0xFF0*:0:0:0:0:0:0:181. 3-IPv6 DA 1 of 0xFF02:0:0:0:0:0:0:6B. 4-UDP | ||
2203 | * destination port 0 of 319. 5-UDP destination port 1 of 320. 6-MAC | ||
2204 | * Ethertype 0 of 0x88F7. 7-configurable MAC Ethertype 1. 8-MAC DA 0 of | ||
2205 | * 0x01-1B-19-00-00-00. 9-MAC DA 1 of 0x01-80-C2-00-00-0E. 10-configurable | ||
2206 | * MAC DA 2. The reset default is set to mask out all parameters. | ||
2207 | */ | ||
2208 | #define NIG_REG_P0_LLH_PTP_PARAM_MASK 0x187a0 | ||
2209 | /* [RW 14] Mask regiser for the rules used in detecting PTP packets. Set | ||
2210 | * each bit to 1 to mask out that particular rule. 0-{IPv4 DA 0; UDP DP 0} . | ||
2211 | * 1-{IPv4 DA 0; UDP DP 1} . 2-{IPv4 DA 1; UDP DP 0} . 3-{IPv4 DA 1; UDP DP | ||
2212 | * 1} . 4-{IPv6 DA 0; UDP DP 0} . 5-{IPv6 DA 0; UDP DP 1} . 6-{IPv6 DA 1; | ||
2213 | * UDP DP 0} . 7-{IPv6 DA 1; UDP DP 1} . 8-{MAC DA 0; Ethertype 0} . 9-{MAC | ||
2214 | * DA 1; Ethertype 0} . 10-{MAC DA 0; Ethertype 1} . 11-{MAC DA 1; Ethertype | ||
2215 | * 1} . 12-{MAC DA 2; Ethertype 0} . 13-{MAC DA 2; Ethertype 1} . The reset | ||
2216 | * default is to mask out all of the rules. Note that rules 0-3 are for IPv4 | ||
2217 | * packets only and require that the packet is IPv4 for the rules to match. | ||
2218 | * Note that rules 4-7 are for IPv6 packets only and require that the packet | ||
2219 | * is IPv6 for the rules to match. | ||
2220 | */ | ||
2221 | #define NIG_REG_P0_LLH_PTP_RULE_MASK 0x187a4 | ||
2222 | /* [RW 1] Set to 1 to enable PTP packets to be forwarded to the host. */ | ||
2223 | #define NIG_REG_P0_LLH_PTP_TO_HOST 0x187ac | ||
2185 | /* [RW 1] Input enable for RX MAC interface. */ | 2224 | /* [RW 1] Input enable for RX MAC interface. */ |
2186 | #define NIG_REG_P0_MAC_IN_EN 0x185ac | 2225 | #define NIG_REG_P0_MAC_IN_EN 0x185ac |
2187 | /* [RW 1] Output enable for TX MAC interface */ | 2226 | /* [RW 1] Output enable for TX MAC interface */ |
@@ -2194,6 +2233,17 @@ | |||
2194 | * priority field is extracted from the outer-most VLAN in receive packet. | 2233 | * priority field is extracted from the outer-most VLAN in receive packet. |
2195 | * Only COS 0 and COS 1 are supported in E2. */ | 2234 | * Only COS 0 and COS 1 are supported in E2. */ |
2196 | #define NIG_REG_P0_PKT_PRIORITY_TO_COS 0x18054 | 2235 | #define NIG_REG_P0_PKT_PRIORITY_TO_COS 0x18054 |
2236 | /* [RW 6] Enable for TimeSync feature. Bits [2:0] are for RX side. Bits | ||
2237 | * [5:3] are for TX side. Bit 0 enables TimeSync on RX side. Bit 1 enables | ||
2238 | * V1 frame format in timesync event detection on RX side. Bit 2 enables V2 | ||
2239 | * frame format in timesync event detection on RX side. Bit 3 enables | ||
2240 | * TimeSync on TX side. Bit 4 enables V1 frame format in timesync event | ||
2241 | * detection on TX side. Bit 5 enables V2 frame format in timesync event | ||
2242 | * detection on TX side. Note that for HW to detect PTP packet and extract | ||
2243 | * data from the packet, at least one of the version bits of that traffic | ||
2244 | * direction has to be enabled. | ||
2245 | */ | ||
2246 | #define NIG_REG_P0_PTP_EN 0x18788 | ||
2197 | /* [RW 16] Bit-map indicating which SAFC/PFC priorities to map to COS 0. A | 2247 | /* [RW 16] Bit-map indicating which SAFC/PFC priorities to map to COS 0. A |
2198 | * priority is mapped to COS 0 when the corresponding mask bit is 1. More | 2248 | * priority is mapped to COS 0 when the corresponding mask bit is 1. More |
2199 | * than one bit may be set; allowing multiple priorities to be mapped to one | 2249 | * than one bit may be set; allowing multiple priorities to be mapped to one |
@@ -2300,7 +2350,46 @@ | |||
2300 | * Ethernet header. */ | 2350 | * Ethernet header. */ |
2301 | #define NIG_REG_P1_HDRS_AFTER_BASIC 0x1818c | 2351 | #define NIG_REG_P1_HDRS_AFTER_BASIC 0x1818c |
2302 | #define NIG_REG_P1_LLH_FUNC_MEM2 0x184c0 | 2352 | #define NIG_REG_P1_LLH_FUNC_MEM2 0x184c0 |
2303 | #define NIG_REG_P1_LLH_FUNC_MEM2_ENABLE 0x18460 | 2353 | #define NIG_REG_P1_LLH_FUNC_MEM2_ENABLE 0x18460a |
2354 | /* [RW 17] Packet TimeSync information that is buffered in 1-deep FIFOs for | ||
2355 | * the host. Bits [15:0] return the sequence ID of the packet. Bit 16 | ||
2356 | * indicates the validity of the data in the buffer. Writing a 1 to bit 16 | ||
2357 | * will clear the buffer. | ||
2358 | */ | ||
2359 | #define NIG_REG_P1_LLH_PTP_HOST_BUF_SEQID 0x18774 | ||
2360 | /* [R 32] Packet TimeSync information that is buffered in 1-deep FIFOs for | ||
2361 | * the host. This location returns the lower 32 bits of timestamp value. | ||
2362 | */ | ||
2363 | #define NIG_REG_P1_LLH_PTP_HOST_BUF_TS_LSB 0x1876c | ||
2364 | /* [R 32] Packet TimeSync information that is buffered in 1-deep FIFOs for | ||
2365 | * the host. This location returns the upper 32 bits of timestamp value. | ||
2366 | */ | ||
2367 | #define NIG_REG_P1_LLH_PTP_HOST_BUF_TS_MSB 0x18770 | ||
2368 | /* [RW 11] Mask register for the various parameters used in determining PTP | ||
2369 | * packet presence. Set each bit to 1 to mask out the particular parameter. | ||
2370 | * 0-IPv4 DA 0 of 224.0.1.129. 1-IPv4 DA 1 of 224.0.0.107. 2-IPv6 DA 0 of | ||
2371 | * 0xFF0*:0:0:0:0:0:0:181. 3-IPv6 DA 1 of 0xFF02:0:0:0:0:0:0:6B. 4-UDP | ||
2372 | * destination port 0 of 319. 5-UDP destination port 1 of 320. 6-MAC | ||
2373 | * Ethertype 0 of 0x88F7. 7-configurable MAC Ethertype 1. 8-MAC DA 0 of | ||
2374 | * 0x01-1B-19-00-00-00. 9-MAC DA 1 of 0x01-80-C2-00-00-0E. 10-configurable | ||
2375 | * MAC DA 2. The reset default is set to mask out all parameters. | ||
2376 | */ | ||
2377 | #define NIG_REG_P1_LLH_PTP_PARAM_MASK 0x187c8 | ||
2378 | /* [RW 14] Mask regiser for the rules used in detecting PTP packets. Set | ||
2379 | * each bit to 1 to mask out that particular rule. 0-{IPv4 DA 0; UDP DP 0} . | ||
2380 | * 1-{IPv4 DA 0; UDP DP 1} . 2-{IPv4 DA 1; UDP DP 0} . 3-{IPv4 DA 1; UDP DP | ||
2381 | * 1} . 4-{IPv6 DA 0; UDP DP 0} . 5-{IPv6 DA 0; UDP DP 1} . 6-{IPv6 DA 1; | ||
2382 | * UDP DP 0} . 7-{IPv6 DA 1; UDP DP 1} . 8-{MAC DA 0; Ethertype 0} . 9-{MAC | ||
2383 | * DA 1; Ethertype 0} . 10-{MAC DA 0; Ethertype 1} . 11-{MAC DA 1; Ethertype | ||
2384 | * 1} . 12-{MAC DA 2; Ethertype 0} . 13-{MAC DA 2; Ethertype 1} . The reset | ||
2385 | * default is to mask out all of the rules. Note that rules 0-3 are for IPv4 | ||
2386 | * packets only and require that the packet is IPv4 for the rules to match. | ||
2387 | * Note that rules 4-7 are for IPv6 packets only and require that the packet | ||
2388 | * is IPv6 for the rules to match. | ||
2389 | */ | ||
2390 | #define NIG_REG_P1_LLH_PTP_RULE_MASK 0x187cc | ||
2391 | /* [RW 1] Set to 1 to enable PTP packets to be forwarded to the host. */ | ||
2392 | #define NIG_REG_P1_LLH_PTP_TO_HOST 0x187d4 | ||
2304 | /* [RW 32] Specify the client number to be assigned to each priority of the | 2393 | /* [RW 32] Specify the client number to be assigned to each priority of the |
2305 | * strict priority arbiter. This register specifies bits 31:0 of the 36-bit | 2394 | * strict priority arbiter. This register specifies bits 31:0 of the 36-bit |
2306 | * value. Priority 0 is the highest priority. Bits [3:0] are for priority 0 | 2395 | * value. Priority 0 is the highest priority. Bits [3:0] are for priority 0 |
@@ -2342,6 +2431,17 @@ | |||
2342 | * priority field is extracted from the outer-most VLAN in receive packet. | 2431 | * priority field is extracted from the outer-most VLAN in receive packet. |
2343 | * Only COS 0 and COS 1 are supported in E2. */ | 2432 | * Only COS 0 and COS 1 are supported in E2. */ |
2344 | #define NIG_REG_P1_PKT_PRIORITY_TO_COS 0x181a8 | 2433 | #define NIG_REG_P1_PKT_PRIORITY_TO_COS 0x181a8 |
2434 | /* [RW 6] Enable for TimeSync feature. Bits [2:0] are for RX side. Bits | ||
2435 | * [5:3] are for TX side. Bit 0 enables TimeSync on RX side. Bit 1 enables | ||
2436 | * V1 frame format in timesync event detection on RX side. Bit 2 enables V2 | ||
2437 | * frame format in timesync event detection on RX side. Bit 3 enables | ||
2438 | * TimeSync on TX side. Bit 4 enables V1 frame format in timesync event | ||
2439 | * detection on TX side. Bit 5 enables V2 frame format in timesync event | ||
2440 | * detection on TX side. Note that for HW to detect PTP packet and extract | ||
2441 | * data from the packet, at least one of the version bits of that traffic | ||
2442 | * direction has to be enabled. | ||
2443 | */ | ||
2444 | #define NIG_REG_P1_PTP_EN 0x187b0 | ||
2345 | /* [RW 16] Bit-map indicating which SAFC/PFC priorities to map to COS 0. A | 2445 | /* [RW 16] Bit-map indicating which SAFC/PFC priorities to map to COS 0. A |
2346 | * priority is mapped to COS 0 when the corresponding mask bit is 1. More | 2446 | * priority is mapped to COS 0 when the corresponding mask bit is 1. More |
2347 | * than one bit may be set; allowing multiple priorities to be mapped to one | 2447 | * than one bit may be set; allowing multiple priorities to be mapped to one |
@@ -2361,6 +2461,78 @@ | |||
2361 | #define NIG_REG_P1_RX_MACFIFO_EMPTY 0x1858c | 2461 | #define NIG_REG_P1_RX_MACFIFO_EMPTY 0x1858c |
2362 | /* [R 1] TLLH FIFO is empty. */ | 2462 | /* [R 1] TLLH FIFO is empty. */ |
2363 | #define NIG_REG_P1_TLLH_FIFO_EMPTY 0x18338 | 2463 | #define NIG_REG_P1_TLLH_FIFO_EMPTY 0x18338 |
2464 | /* [RW 19] Packet TimeSync information that is buffered in 1-deep FIFOs for | ||
2465 | * TX side. Bits [15:0] reflect the sequence ID of the packet. Bit 16 | ||
2466 | * indicates the validity of the data in the buffer. Bit 17 indicates that | ||
2467 | * the sequence ID is valid and it is waiting for the TX timestamp value. | ||
2468 | * Bit 18 indicates whether the timestamp is from a SW request (value of 1) | ||
2469 | * or HW request (value of 0). Writing a 1 to bit 16 will clear the buffer. | ||
2470 | */ | ||
2471 | #define NIG_REG_P0_TLLH_PTP_BUF_SEQID 0x187e0 | ||
2472 | /* [R 32] Packet TimeSync information that is buffered in 1-deep FIFOs for | ||
2473 | * MCP. This location returns the lower 32 bits of timestamp value. | ||
2474 | */ | ||
2475 | #define NIG_REG_P0_TLLH_PTP_BUF_TS_LSB 0x187d8 | ||
2476 | /* [R 32] Packet TimeSync information that is buffered in 1-deep FIFOs for | ||
2477 | * MCP. This location returns the upper 32 bits of timestamp value. | ||
2478 | */ | ||
2479 | #define NIG_REG_P0_TLLH_PTP_BUF_TS_MSB 0x187dc | ||
2480 | /* [RW 11] Mask register for the various parameters used in determining PTP | ||
2481 | * packet presence. Set each bit to 1 to mask out the particular parameter. | ||
2482 | * 0-IPv4 DA 0 of 224.0.1.129. 1-IPv4 DA 1 of 224.0.0.107. 2-IPv6 DA 0 of | ||
2483 | * 0xFF0*:0:0:0:0:0:0:181. 3-IPv6 DA 1 of 0xFF02:0:0:0:0:0:0:6B. 4-UDP | ||
2484 | * destination port 0 of 319. 5-UDP destination port 1 of 320. 6-MAC | ||
2485 | * Ethertype 0 of 0x88F7. 7-configurable MAC Ethertype 1. 8-MAC DA 0 of | ||
2486 | * 0x01-1B-19-00-00-00. 9-MAC DA 1 of 0x01-80-C2-00-00-0E. 10-configurable | ||
2487 | * MAC DA 2. The reset default is set to mask out all parameters. | ||
2488 | */ | ||
2489 | #define NIG_REG_P0_TLLH_PTP_PARAM_MASK 0x187f0 | ||
2490 | /* [RW 14] Mask regiser for the rules used in detecting PTP packets. Set | ||
2491 | * each bit to 1 to mask out that particular rule. 0-{IPv4 DA 0; UDP DP 0} . | ||
2492 | * 1-{IPv4 DA 0; UDP DP 1} . 2-{IPv4 DA 1; UDP DP 0} . 3-{IPv4 DA 1; UDP DP | ||
2493 | * 1} . 4-{IPv6 DA 0; UDP DP 0} . 5-{IPv6 DA 0; UDP DP 1} . 6-{IPv6 DA 1; | ||
2494 | * UDP DP 0} . 7-{IPv6 DA 1; UDP DP 1} . 8-{MAC DA 0; Ethertype 0} . 9-{MAC | ||
2495 | * DA 1; Ethertype 0} . 10-{MAC DA 0; Ethertype 1} . 11-{MAC DA 1; Ethertype | ||
2496 | * 1} . 12-{MAC DA 2; Ethertype 0} . 13-{MAC DA 2; Ethertype 1} . The reset | ||
2497 | * default is to mask out all of the rules. | ||
2498 | */ | ||
2499 | #define NIG_REG_P0_TLLH_PTP_RULE_MASK 0x187f4 | ||
2500 | /* [RW 19] Packet TimeSync information that is buffered in 1-deep FIFOs for | ||
2501 | * TX side. Bits [15:0] reflect the sequence ID of the packet. Bit 16 | ||
2502 | * indicates the validity of the data in the buffer. Bit 17 indicates that | ||
2503 | * the sequence ID is valid and it is waiting for the TX timestamp value. | ||
2504 | * Bit 18 indicates whether the timestamp is from a SW request (value of 1) | ||
2505 | * or HW request (value of 0). Writing a 1 to bit 16 will clear the buffer. | ||
2506 | */ | ||
2507 | #define NIG_REG_P1_TLLH_PTP_BUF_SEQID 0x187ec | ||
2508 | /* [R 32] Packet TimeSync information that is buffered in 1-deep FIFOs for | ||
2509 | * MCP. This location returns the lower 32 bits of timestamp value. | ||
2510 | */ | ||
2511 | #define NIG_REG_P1_TLLH_PTP_BUF_TS_LSB 0x187e4 | ||
2512 | /* [R 32] Packet TimeSync information that is buffered in 1-deep FIFOs for | ||
2513 | * MCP. This location returns the upper 32 bits of timestamp value. | ||
2514 | */ | ||
2515 | #define NIG_REG_P1_TLLH_PTP_BUF_TS_MSB 0x187e8 | ||
2516 | /* [RW 11] Mask register for the various parameters used in determining PTP | ||
2517 | * packet presence. Set each bit to 1 to mask out the particular parameter. | ||
2518 | * 0-IPv4 DA 0 of 224.0.1.129. 1-IPv4 DA 1 of 224.0.0.107. 2-IPv6 DA 0 of | ||
2519 | * 0xFF0*:0:0:0:0:0:0:181. 3-IPv6 DA 1 of 0xFF02:0:0:0:0:0:0:6B. 4-UDP | ||
2520 | * destination port 0 of 319. 5-UDP destination port 1 of 320. 6-MAC | ||
2521 | * Ethertype 0 of 0x88F7. 7-configurable MAC Ethertype 1. 8-MAC DA 0 of | ||
2522 | * 0x01-1B-19-00-00-00. 9-MAC DA 1 of 0x01-80-C2-00-00-0E. 10-configurable | ||
2523 | * MAC DA 2. The reset default is set to mask out all parameters. | ||
2524 | */ | ||
2525 | #define NIG_REG_P1_TLLH_PTP_PARAM_MASK 0x187f8 | ||
2526 | /* [RW 14] Mask regiser for the rules used in detecting PTP packets. Set | ||
2527 | * each bit to 1 to mask out that particular rule. 0-{IPv4 DA 0; UDP DP 0} . | ||
2528 | * 1-{IPv4 DA 0; UDP DP 1} . 2-{IPv4 DA 1; UDP DP 0} . 3-{IPv4 DA 1; UDP DP | ||
2529 | * 1} . 4-{IPv6 DA 0; UDP DP 0} . 5-{IPv6 DA 0; UDP DP 1} . 6-{IPv6 DA 1; | ||
2530 | * UDP DP 0} . 7-{IPv6 DA 1; UDP DP 1} . 8-{MAC DA 0; Ethertype 0} . 9-{MAC | ||
2531 | * DA 1; Ethertype 0} . 10-{MAC DA 0; Ethertype 1} . 11-{MAC DA 1; Ethertype | ||
2532 | * 1} . 12-{MAC DA 2; Ethertype 0} . 13-{MAC DA 2; Ethertype 1} . The reset | ||
2533 | * default is to mask out all of the rules. | ||
2534 | */ | ||
2535 | #define NIG_REG_P1_TLLH_PTP_RULE_MASK 0x187fc | ||
2364 | /* [RW 32] Specify which of the credit registers the client is to be mapped | 2536 | /* [RW 32] Specify which of the credit registers the client is to be mapped |
2365 | * to. This register specifies bits 31:0 of the 36-bit value. Bits[3:0] are | 2537 | * to. This register specifies bits 31:0 of the 36-bit value. Bits[3:0] are |
2366 | * for client 0; bits [35:32] are for client 8. For clients that are not | 2538 | * for client 0; bits [35:32] are for client 8. For clients that are not |
@@ -2513,6 +2685,10 @@ | |||
2513 | swap is equal to SPIO pin that inputs from ifmux_serdes_swap. If 1 then | 2685 | swap is equal to SPIO pin that inputs from ifmux_serdes_swap. If 1 then |
2514 | ort swap is equal to ~nig_registers_port_swap.port_swap */ | 2686 | ort swap is equal to ~nig_registers_port_swap.port_swap */ |
2515 | #define NIG_REG_STRAP_OVERRIDE 0x10398 | 2687 | #define NIG_REG_STRAP_OVERRIDE 0x10398 |
2688 | /* [WB 64] Addresses for TimeSync related registers in the timesync | ||
2689 | * generator sub-module. | ||
2690 | */ | ||
2691 | #define NIG_REG_TIMESYNC_GEN_REG 0x18800 | ||
2516 | /* [RW 1] output enable for RX_XCM0 IF */ | 2692 | /* [RW 1] output enable for RX_XCM0 IF */ |
2517 | #define NIG_REG_XCM0_OUT_EN 0x100f0 | 2693 | #define NIG_REG_XCM0_OUT_EN 0x100f0 |
2518 | /* [RW 1] output enable for RX_XCM1 IF */ | 2694 | /* [RW 1] output enable for RX_XCM1 IF */ |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c index d825ef6a9139..798e97fb63f7 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c | |||
@@ -4725,6 +4725,12 @@ static void bnx2x_q_fill_update_data(struct bnx2x *bp, | |||
4725 | data->tx_switching_change_flg = | 4725 | data->tx_switching_change_flg = |
4726 | test_bit(BNX2X_Q_UPDATE_TX_SWITCHING_CHNG, | 4726 | test_bit(BNX2X_Q_UPDATE_TX_SWITCHING_CHNG, |
4727 | ¶ms->update_flags); | 4727 | ¶ms->update_flags); |
4728 | |||
4729 | /* PTP */ | ||
4730 | data->handle_ptp_pkts_flg = | ||
4731 | test_bit(BNX2X_Q_UPDATE_PTP_PKTS, ¶ms->update_flags); | ||
4732 | data->handle_ptp_pkts_change_flg = | ||
4733 | test_bit(BNX2X_Q_UPDATE_PTP_PKTS_CHNG, ¶ms->update_flags); | ||
4728 | } | 4734 | } |
4729 | 4735 | ||
4730 | static inline int bnx2x_q_send_update(struct bnx2x *bp, | 4736 | static inline int bnx2x_q_send_update(struct bnx2x *bp, |
@@ -5379,6 +5385,10 @@ static int bnx2x_func_chk_transition(struct bnx2x *bp, | |||
5379 | (!test_bit(BNX2X_F_CMD_STOP, &o->pending))) | 5385 | (!test_bit(BNX2X_F_CMD_STOP, &o->pending))) |
5380 | next_state = BNX2X_F_STATE_STARTED; | 5386 | next_state = BNX2X_F_STATE_STARTED; |
5381 | 5387 | ||
5388 | else if ((cmd == BNX2X_F_CMD_SET_TIMESYNC) && | ||
5389 | (!test_bit(BNX2X_F_CMD_STOP, &o->pending))) | ||
5390 | next_state = BNX2X_F_STATE_STARTED; | ||
5391 | |||
5382 | else if (cmd == BNX2X_F_CMD_TX_STOP) | 5392 | else if (cmd == BNX2X_F_CMD_TX_STOP) |
5383 | next_state = BNX2X_F_STATE_TX_STOPPED; | 5393 | next_state = BNX2X_F_STATE_TX_STOPPED; |
5384 | 5394 | ||
@@ -5388,6 +5398,10 @@ static int bnx2x_func_chk_transition(struct bnx2x *bp, | |||
5388 | (!test_bit(BNX2X_F_CMD_STOP, &o->pending))) | 5398 | (!test_bit(BNX2X_F_CMD_STOP, &o->pending))) |
5389 | next_state = BNX2X_F_STATE_TX_STOPPED; | 5399 | next_state = BNX2X_F_STATE_TX_STOPPED; |
5390 | 5400 | ||
5401 | else if ((cmd == BNX2X_F_CMD_SET_TIMESYNC) && | ||
5402 | (!test_bit(BNX2X_F_CMD_STOP, &o->pending))) | ||
5403 | next_state = BNX2X_F_STATE_TX_STOPPED; | ||
5404 | |||
5391 | else if (cmd == BNX2X_F_CMD_TX_START) | 5405 | else if (cmd == BNX2X_F_CMD_TX_START) |
5392 | next_state = BNX2X_F_STATE_STARTED; | 5406 | next_state = BNX2X_F_STATE_STARTED; |
5393 | 5407 | ||
@@ -5843,6 +5857,40 @@ static inline int bnx2x_func_send_tx_start(struct bnx2x *bp, | |||
5843 | U64_LO(data_mapping), NONE_CONNECTION_TYPE); | 5857 | U64_LO(data_mapping), NONE_CONNECTION_TYPE); |
5844 | } | 5858 | } |
5845 | 5859 | ||
5860 | static inline | ||
5861 | int bnx2x_func_send_set_timesync(struct bnx2x *bp, | ||
5862 | struct bnx2x_func_state_params *params) | ||
5863 | { | ||
5864 | struct bnx2x_func_sp_obj *o = params->f_obj; | ||
5865 | struct set_timesync_ramrod_data *rdata = | ||
5866 | (struct set_timesync_ramrod_data *)o->rdata; | ||
5867 | dma_addr_t data_mapping = o->rdata_mapping; | ||
5868 | struct bnx2x_func_set_timesync_params *set_timesync_params = | ||
5869 | ¶ms->params.set_timesync; | ||
5870 | |||
5871 | memset(rdata, 0, sizeof(*rdata)); | ||
5872 | |||
5873 | /* Fill the ramrod data with provided parameters */ | ||
5874 | rdata->drift_adjust_cmd = set_timesync_params->drift_adjust_cmd; | ||
5875 | rdata->offset_cmd = set_timesync_params->offset_cmd; | ||
5876 | rdata->add_sub_drift_adjust_value = | ||
5877 | set_timesync_params->add_sub_drift_adjust_value; | ||
5878 | rdata->drift_adjust_value = set_timesync_params->drift_adjust_value; | ||
5879 | rdata->drift_adjust_period = set_timesync_params->drift_adjust_period; | ||
5880 | rdata->offset_delta.lo = U64_LO(set_timesync_params->offset_delta); | ||
5881 | rdata->offset_delta.hi = U64_HI(set_timesync_params->offset_delta); | ||
5882 | |||
5883 | DP(BNX2X_MSG_SP, "Set timesync command params: drift_cmd = %d, offset_cmd = %d, add_sub_drift = %d, drift_val = %d, drift_period = %d, offset_lo = %d, offset_hi = %d\n", | ||
5884 | rdata->drift_adjust_cmd, rdata->offset_cmd, | ||
5885 | rdata->add_sub_drift_adjust_value, rdata->drift_adjust_value, | ||
5886 | rdata->drift_adjust_period, rdata->offset_delta.lo, | ||
5887 | rdata->offset_delta.hi); | ||
5888 | |||
5889 | return bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_TIMESYNC, 0, | ||
5890 | U64_HI(data_mapping), | ||
5891 | U64_LO(data_mapping), NONE_CONNECTION_TYPE); | ||
5892 | } | ||
5893 | |||
5846 | static int bnx2x_func_send_cmd(struct bnx2x *bp, | 5894 | static int bnx2x_func_send_cmd(struct bnx2x *bp, |
5847 | struct bnx2x_func_state_params *params) | 5895 | struct bnx2x_func_state_params *params) |
5848 | { | 5896 | { |
@@ -5865,6 +5913,8 @@ static int bnx2x_func_send_cmd(struct bnx2x *bp, | |||
5865 | return bnx2x_func_send_tx_start(bp, params); | 5913 | return bnx2x_func_send_tx_start(bp, params); |
5866 | case BNX2X_F_CMD_SWITCH_UPDATE: | 5914 | case BNX2X_F_CMD_SWITCH_UPDATE: |
5867 | return bnx2x_func_send_switch_update(bp, params); | 5915 | return bnx2x_func_send_switch_update(bp, params); |
5916 | case BNX2X_F_CMD_SET_TIMESYNC: | ||
5917 | return bnx2x_func_send_set_timesync(bp, params); | ||
5868 | default: | 5918 | default: |
5869 | BNX2X_ERR("Unknown command: %d\n", params->cmd); | 5919 | BNX2X_ERR("Unknown command: %d\n", params->cmd); |
5870 | return -EINVAL; | 5920 | return -EINVAL; |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h index 5ac247dd9834..21c8f6fb89e5 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h | |||
@@ -770,7 +770,9 @@ enum { | |||
770 | BNX2X_Q_UPDATE_SILENT_VLAN_REM_CHNG, | 770 | BNX2X_Q_UPDATE_SILENT_VLAN_REM_CHNG, |
771 | BNX2X_Q_UPDATE_SILENT_VLAN_REM, | 771 | BNX2X_Q_UPDATE_SILENT_VLAN_REM, |
772 | BNX2X_Q_UPDATE_TX_SWITCHING_CHNG, | 772 | BNX2X_Q_UPDATE_TX_SWITCHING_CHNG, |
773 | BNX2X_Q_UPDATE_TX_SWITCHING | 773 | BNX2X_Q_UPDATE_TX_SWITCHING, |
774 | BNX2X_Q_UPDATE_PTP_PKTS_CHNG, | ||
775 | BNX2X_Q_UPDATE_PTP_PKTS, | ||
774 | }; | 776 | }; |
775 | 777 | ||
776 | /* Allowed Queue states */ | 778 | /* Allowed Queue states */ |
@@ -853,6 +855,10 @@ enum bnx2x_q_type { | |||
853 | #define BNX2X_MULTI_TX_COS 3 /* Maximum possible */ | 855 | #define BNX2X_MULTI_TX_COS 3 /* Maximum possible */ |
854 | 856 | ||
855 | #define MAC_PAD (ALIGN(ETH_ALEN, sizeof(u32)) - ETH_ALEN) | 857 | #define MAC_PAD (ALIGN(ETH_ALEN, sizeof(u32)) - ETH_ALEN) |
858 | /* DMAE channel to be used by FW for timesync workaroun. A driver that sends | ||
859 | * timesync-related ramrods must not use this DMAE command ID. | ||
860 | */ | ||
861 | #define FW_DMAE_CMD_ID 6 | ||
856 | 862 | ||
857 | struct bnx2x_queue_init_params { | 863 | struct bnx2x_queue_init_params { |
858 | struct { | 864 | struct { |
@@ -1117,6 +1123,7 @@ enum bnx2x_func_cmd { | |||
1117 | BNX2X_F_CMD_TX_STOP, | 1123 | BNX2X_F_CMD_TX_STOP, |
1118 | BNX2X_F_CMD_TX_START, | 1124 | BNX2X_F_CMD_TX_START, |
1119 | BNX2X_F_CMD_SWITCH_UPDATE, | 1125 | BNX2X_F_CMD_SWITCH_UPDATE, |
1126 | BNX2X_F_CMD_SET_TIMESYNC, | ||
1120 | BNX2X_F_CMD_MAX, | 1127 | BNX2X_F_CMD_MAX, |
1121 | }; | 1128 | }; |
1122 | 1129 | ||
@@ -1191,6 +1198,7 @@ struct bnx2x_func_afex_viflists_params { | |||
1191 | u8 afex_vif_list_command; | 1198 | u8 afex_vif_list_command; |
1192 | u8 func_to_clear; | 1199 | u8 func_to_clear; |
1193 | }; | 1200 | }; |
1201 | |||
1194 | struct bnx2x_func_tx_start_params { | 1202 | struct bnx2x_func_tx_start_params { |
1195 | struct priority_cos traffic_type_to_priority_cos[MAX_TRAFFIC_TYPES]; | 1203 | struct priority_cos traffic_type_to_priority_cos[MAX_TRAFFIC_TYPES]; |
1196 | u8 dcb_enabled; | 1204 | u8 dcb_enabled; |
@@ -1198,6 +1206,24 @@ struct bnx2x_func_tx_start_params { | |||
1198 | u8 dont_add_pri_0_en; | 1206 | u8 dont_add_pri_0_en; |
1199 | }; | 1207 | }; |
1200 | 1208 | ||
1209 | struct bnx2x_func_set_timesync_params { | ||
1210 | /* Reset, set or keep the current drift value */ | ||
1211 | u8 drift_adjust_cmd; | ||
1212 | |||
1213 | /* Dec, inc or keep the current offset */ | ||
1214 | u8 offset_cmd; | ||
1215 | |||
1216 | /* Drift value direction */ | ||
1217 | u8 add_sub_drift_adjust_value; | ||
1218 | |||
1219 | /* Drift, period and offset values to be used according to the commands | ||
1220 | * above. | ||
1221 | */ | ||
1222 | u8 drift_adjust_value; | ||
1223 | u32 drift_adjust_period; | ||
1224 | u64 offset_delta; | ||
1225 | }; | ||
1226 | |||
1201 | struct bnx2x_func_state_params { | 1227 | struct bnx2x_func_state_params { |
1202 | struct bnx2x_func_sp_obj *f_obj; | 1228 | struct bnx2x_func_sp_obj *f_obj; |
1203 | 1229 | ||
@@ -1216,6 +1242,7 @@ struct bnx2x_func_state_params { | |||
1216 | struct bnx2x_func_afex_update_params afex_update; | 1242 | struct bnx2x_func_afex_update_params afex_update; |
1217 | struct bnx2x_func_afex_viflists_params afex_viflists; | 1243 | struct bnx2x_func_afex_viflists_params afex_viflists; |
1218 | struct bnx2x_func_tx_start_params tx_start; | 1244 | struct bnx2x_func_tx_start_params tx_start; |
1245 | struct bnx2x_func_set_timesync_params set_timesync; | ||
1219 | } params; | 1246 | } params; |
1220 | }; | 1247 | }; |
1221 | 1248 | ||