Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions aq_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,9 @@ static netdev_tx_t aq_ndev_start_xmit(struct sk_buff *skb, struct net_device *nd
#if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)
if (unlikely(aq_utils_obj_test(&aq_nic->flags, AQ_NIC_PTP_DPATH_UP))) {
/* Hardware adds the Timestamp for PTPv2 802.AS1
* and PTPv2 IPv4 UDP.
* We have to push even general 320 port messages to the ptp
* and PTPv2 IPv4 UDP. Opposed to what is needed,
* it timestamps both event and general messages. That is why
* we have to push even port 320 (general) messages to the ptp
* queue explicitly. This is a limitation of current firmware
* and hardware PTP design of the chip. Otherwise ptp stream
* will fail to sync
Expand Down
1 change: 1 addition & 0 deletions aq_nic.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ struct aq_nic_cfg_s {
#define AQ_NIC_FLAG_ERR_HW 0x80000000U

#define AQ_NIC_QUIRK_BAD_PTP BIT(0)
#define AQ_NIC_QUIRK_NEED_PTP_FLIP BIT(1)

#ifdef PCI_DEBUG
#define AQ_NIC_PCI_RESOURCE_BUSY 0x00800000U
Expand Down
59 changes: 46 additions & 13 deletions aq_ptp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1075,15 +1075,32 @@ void aq_ptp_tx_hwtstamp(struct aq_nic_s *aq_nic, u64 timestamp)
netdev_err(aq_nic->ndev, "have timestamp but tx_queues empty\n");
return;
}

timestamp += atomic_read(&aq_ptp->offset_egress);
aq_ptp_convert_to_hwtstamp(aq_ptp, &hwtstamp, timestamp);
skb_tstamp_tx(skb, &hwtstamp);
// Only report the HW timestamp if it was requested. Otherwise,
// SW timestamping would be broken.
if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) {
timestamp += atomic_read(&aq_ptp->offset_egress);
aq_ptp_convert_to_hwtstamp(aq_ptp, &hwtstamp, timestamp);
skb_tstamp_tx(skb, &hwtstamp);
}
dev_kfree_skb_any(skb);

aq_ptp_tx_timeout_update(aq_ptp);
}

static void aq_ptp_enable_ptp(struct aq_ptp_s *aq_ptp, int enable)
{
struct aq_nic_s *aq_nic = aq_ptp->aq_nic;
if (aq_ptp->a1_ptp) {
mutex_lock(&aq_nic->fwreq_mutex);
aq_nic->aq_fw_ops->enable_ptp(aq_nic->aq_hw, enable);
mutex_unlock(&aq_nic->fwreq_mutex);
}

if (aq_ptp->a2_ptp)
aq_nic->aq_hw_ops->enable_ptp(aq_nic->aq_hw,
aq_ptp->ptp_clock_sel, enable);
}

static int aq_ptp_dpath_enable(struct aq_ptp_s *aq_ptp,
int enable_flags, u16 rx_queue)
{
Expand All @@ -1099,6 +1116,10 @@ static int aq_ptp_dpath_enable(struct aq_ptp_s *aq_ptp,
"%sable ptp filters: %x.\n",
enable_flags ? "En" : "Dis", enable_flags);

// Some NICs need to flip the bit twice to actually start/stop PTP
if (aq_nic->aq_nic_cfg.aq_hw_caps->quirks & AQ_NIC_QUIRK_NEED_PTP_FLIP)
aq_ptp_enable_ptp(aq_ptp, enable_flags ? 0 : 1);

if (enable_flags) {
if (enable_flags & (AQ_HW_PTP_L4_ENABLE)) {
if (aq_ptp->a1_ptp) {
Expand Down Expand Up @@ -1260,6 +1281,11 @@ static int aq_ptp_dpath_enable(struct aq_ptp_s *aq_ptp,
"Set L2 filter complete. Location: %d\n",
aq_ptp->eth_type_filter.location);
}

if (!err) {
aq_ptp_enable_ptp(aq_ptp, 1);
netdev_info(aq_nic->ndev, "PTP filters enabled.\n");
}
} else {
/* PTP disabled, clear all UDP/L2 filters */
for (i = 0; i < PTP_UDP_FILTERS_CNT; i++) {
Expand All @@ -1273,6 +1299,9 @@ static int aq_ptp_dpath_enable(struct aq_ptp_s *aq_ptp,
if (!err && hw_ops->hw_filter_l2_clear)
err = hw_ops->hw_filter_l2_clear(aq_nic->aq_hw,
&aq_ptp->eth_type_filter);

aq_ptp_enable_ptp(aq_ptp, 0);
netdev_info(aq_nic->ndev, "PTP filters disabled.\n");
}

return err;
Expand Down Expand Up @@ -1345,6 +1374,13 @@ int aq_ptp_hwtstamp_config_set(struct aq_ptp_s *aq_ptp,
return -ERANGE;
}

if (ptp_en_flags != AQ_HW_PTP_DISABLE &&
!aq_utils_obj_test(&aq_nic->aq_hw->flags, AQ_HW_PTP_AVAILABLE)) {
config->rx_filter = HWTSTAMP_FILTER_NONE;
netdev_err(aq_nic->ndev, "PTP timestamping requested but not supported.\n");
return -EOPNOTSUPP;
}

if (aq_ptp->hwtstamp_config.rx_filter != config->rx_filter)
err = aq_ptp_dpath_enable(aq_ptp,
ptp_en_flags,
Expand Down Expand Up @@ -1537,7 +1573,10 @@ int aq_ptp_xmit(struct aq_nic_s *aq_nic, struct sk_buff *skb)
ring->size);
return NETDEV_TX_BUSY;
}
skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
// SKBTX_IN_PROGRESS would report SW timestamp reporting in case only
// SW timestamps are requested.
if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
aq_ptp_tx_timeout_start(aq_ptp);

skb_tx_timestamp(skb);
Expand Down Expand Up @@ -2013,7 +2052,7 @@ void aq_ptp_clock_init(struct aq_nic_s *aq_nic, enum aq_ptp_state state)
}
}

if (!aq_ptp->a1_ptp && state != AQ_PTP_FIRST_INIT) {
if (state != AQ_PTP_FIRST_INIT) {
int ptp_en_flags =
aq_ptp_parse_rx_filters(state == AQ_PTP_LINK_UP ?
aq_ptp->hwtstamp_config.rx_filter :
Expand Down Expand Up @@ -2138,13 +2177,7 @@ int aq_ptp_init(struct aq_nic_s *aq_nic, unsigned int idx_ptp_vec, unsigned int
/* enable ptp counter */
aq_ptp->ptp_clock_sel = ATL_TSG_CLOCK_SEL_0; //mbox.info.caps_ex.;
aq_utils_obj_set(&aq_nic->aq_hw->flags, AQ_HW_PTP_AVAILABLE);
if (a1_ptp) {
mutex_lock(&aq_nic->fwreq_mutex);
aq_nic->aq_fw_ops->enable_ptp(aq_nic->aq_hw, 1);
mutex_unlock(&aq_nic->fwreq_mutex);
}
if (a2_ptp)
aq_nic->aq_hw_ops->enable_ptp(aq_nic->aq_hw, aq_ptp->ptp_clock_sel, 1);
aq_ptp_enable_ptp(aq_ptp, 1);

INIT_DELAYED_WORK(&aq_ptp->poll_sync, &aq_ptp_poll_sync_work_cb);

Expand Down
4 changes: 4 additions & 0 deletions hw_atl/hw_atl_a0.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ const struct aq_hw_caps_s hw_atl_a0_caps_aqc100 = {
AQ_NIC_RATE_2G5 |
AQ_NIC_RATE_1G |
AQ_NIC_RATE_100M,
.quirks = AQ_NIC_QUIRK_NEED_PTP_FLIP,
};

const struct aq_hw_caps_s hw_atl_a0_caps_aqc107 = {
Expand All @@ -64,6 +65,7 @@ const struct aq_hw_caps_s hw_atl_a0_caps_aqc107 = {
AQ_NIC_RATE_2G5 |
AQ_NIC_RATE_1G |
AQ_NIC_RATE_100M,
.quirks = AQ_NIC_QUIRK_NEED_PTP_FLIP,
};

const struct aq_hw_caps_s hw_atl_a0_caps_aqc108 = {
Expand All @@ -73,6 +75,7 @@ const struct aq_hw_caps_s hw_atl_a0_caps_aqc108 = {
AQ_NIC_RATE_2G5 |
AQ_NIC_RATE_1G |
AQ_NIC_RATE_100M,
.quirks = AQ_NIC_QUIRK_NEED_PTP_FLIP,
};

const struct aq_hw_caps_s hw_atl_a0_caps_aqc109 = {
Expand All @@ -81,6 +84,7 @@ const struct aq_hw_caps_s hw_atl_a0_caps_aqc109 = {
.link_speed_msk = AQ_NIC_RATE_2G5 |
AQ_NIC_RATE_1G |
AQ_NIC_RATE_100M,
.quirks = AQ_NIC_QUIRK_NEED_PTP_FLIP,
};

static int hw_atl_a0_hw_reset(struct aq_hw_s *self)
Expand Down
8 changes: 6 additions & 2 deletions hw_atl/hw_atl_b0.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ const struct aq_hw_caps_s hw_atl_b0_caps_aqc100 = {
AQ_NIC_RATE_2G5 |
AQ_NIC_RATE_1G |
AQ_NIC_RATE_100M,
.quirks = AQ_NIC_QUIRK_NEED_PTP_FLIP,
.fw_image_name = AQ_FW_AQC100X,
};

Expand All @@ -80,6 +81,7 @@ const struct aq_hw_caps_s hw_atl_b0_caps_aqc107 = {
AQ_NIC_RATE_2G5 |
AQ_NIC_RATE_1G |
AQ_NIC_RATE_100M,
.quirks = AQ_NIC_QUIRK_NEED_PTP_FLIP,
.fw_image_name = AQ_FW_AQC10XX,
};

Expand All @@ -90,6 +92,7 @@ const struct aq_hw_caps_s hw_atl_b0_caps_aqc108 = {
AQ_NIC_RATE_2G5 |
AQ_NIC_RATE_1G |
AQ_NIC_RATE_100M,
.quirks = AQ_NIC_QUIRK_NEED_PTP_FLIP,
.fw_image_name = AQ_FW_AQC10XX,
};

Expand All @@ -99,6 +102,7 @@ const struct aq_hw_caps_s hw_atl_b0_caps_aqc109 = {
.link_speed_msk = AQ_NIC_RATE_2G5 |
AQ_NIC_RATE_1G |
AQ_NIC_RATE_100M,
.quirks = AQ_NIC_QUIRK_NEED_PTP_FLIP,
.fw_image_name = AQ_FW_AQC10XX,
};

Expand All @@ -109,7 +113,7 @@ const struct aq_hw_caps_s hw_atl_b0_caps_aqc111 = {
AQ_NIC_RATE_2G5 |
AQ_NIC_RATE_1G |
AQ_NIC_RATE_100M,
.quirks = AQ_NIC_QUIRK_BAD_PTP,
.quirks = AQ_NIC_QUIRK_BAD_PTP | AQ_NIC_QUIRK_NEED_PTP_FLIP,
.fw_image_name = AQ_FW_AQC11XX,
};

Expand All @@ -119,7 +123,7 @@ const struct aq_hw_caps_s hw_atl_b0_caps_aqc112 = {
.link_speed_msk = AQ_NIC_RATE_2G5 |
AQ_NIC_RATE_1G |
AQ_NIC_RATE_100M,
.quirks = AQ_NIC_QUIRK_BAD_PTP,
.quirks = AQ_NIC_QUIRK_BAD_PTP | AQ_NIC_QUIRK_NEED_PTP_FLIP,
.fw_image_name = AQ_FW_AQC11XX,
};

Expand Down