Skip to content

Commit 04a1839

Browse files
Egor Pomozovdavem330
authored andcommitted
net: aquantia: implement data PTP datapath
Here we do alloc/free IRQs for PTP rings. We also implement processing of PTP packets on TX and RX sides. Signed-off-by: Egor Pomozov <[email protected]> Co-developed-by: Sergey Samoilenko <[email protected]> Signed-off-by: Sergey Samoilenko <[email protected]> Co-developed-by: Dmitry Bezrukov <[email protected]> Signed-off-by: Dmitry Bezrukov <[email protected]> Signed-off-by: Igor Russkikh <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 61cc502 commit 04a1839

File tree

11 files changed

+738
-12
lines changed

11 files changed

+738
-12
lines changed

drivers/net/ethernet/aquantia/atlantic/aq_cfg.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* SPDX-License-Identifier: GPL-2.0-only */
22
/*
33
* aQuantia Corporation Network Driver
4-
* Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved
4+
* Copyright (C) 2014-2019 aQuantia Corporation. All rights reserved
55
*/
66

77
/* File aq_cfg.h: Definition of configuration parameters and constants. */
@@ -27,7 +27,7 @@
2727

2828
#define AQ_CFG_INTERRUPT_MODERATION_USEC_MAX (0x1FF * 2)
2929

30-
#define AQ_CFG_IRQ_MASK 0x1FFU
30+
#define AQ_CFG_IRQ_MASK 0x3FFU
3131

3232
#define AQ_CFG_VECS_MAX 8U
3333
#define AQ_CFG_TCS_MAX 8U

drivers/net/ethernet/aquantia/atlantic/aq_hw.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,12 @@ struct aq_hw_ops {
244244

245245
int (*hw_rx_tc_mode_get)(struct aq_hw_s *self, u32 *tc_mode);
246246

247+
int (*hw_ring_hwts_rx_fill)(struct aq_hw_s *self,
248+
struct aq_ring_s *aq_ring);
249+
250+
int (*hw_ring_hwts_rx_receive)(struct aq_hw_s *self,
251+
struct aq_ring_s *ring);
252+
247253
void (*hw_get_ptp_ts)(struct aq_hw_s *self, u64 *stamp);
248254

249255
int (*hw_adj_clock_freq)(struct aq_hw_s *self, s32 delta);
@@ -252,6 +258,12 @@ struct aq_hw_ops {
252258

253259
int (*hw_set_sys_clock)(struct aq_hw_s *self, u64 time, u64 ts);
254260

261+
u16 (*rx_extract_ts)(struct aq_hw_s *self, u8 *p, unsigned int len,
262+
u64 *timestamp);
263+
264+
int (*extract_hwts)(struct aq_hw_s *self, u8 *p, unsigned int len,
265+
u64 *timestamp);
266+
255267
int (*hw_set_fc)(struct aq_hw_s *self, u32 fc, u32 tc);
256268
};
257269

drivers/net/ethernet/aquantia/atlantic/aq_main.c

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// SPDX-License-Identifier: GPL-2.0-only
22
/*
33
* aQuantia Corporation Network Driver
4-
* Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved
4+
* Copyright (C) 2014-2019 aQuantia Corporation. All rights reserved
55
*/
66

77
/* File aq_main.c: Main file for aQuantia Linux driver. */
@@ -10,10 +10,13 @@
1010
#include "aq_nic.h"
1111
#include "aq_pci_func.h"
1212
#include "aq_ethtool.h"
13+
#include "aq_ptp.h"
1314
#include "aq_filters.h"
1415

1516
#include <linux/netdevice.h>
1617
#include <linux/module.h>
18+
#include <linux/ip.h>
19+
#include <linux/udp.h>
1720

1821
MODULE_LICENSE("GPL v2");
1922
MODULE_VERSION(AQ_CFG_DRV_VERSION);
@@ -93,6 +96,24 @@ static int aq_ndev_start_xmit(struct sk_buff *skb, struct net_device *ndev)
9396
{
9497
struct aq_nic_s *aq_nic = netdev_priv(ndev);
9598

99+
if (unlikely(aq_utils_obj_test(&aq_nic->flags, AQ_NIC_PTP_DPATH_UP))) {
100+
/* Hardware adds the Timestamp for PTPv2 802.AS1
101+
* and PTPv2 IPv4 UDP.
102+
* We have to push even general 320 port messages to the ptp
103+
* queue explicitly. This is a limitation of current firmware
104+
* and hardware PTP design of the chip. Otherwise ptp stream
105+
* will fail to sync
106+
*/
107+
if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) ||
108+
unlikely((ip_hdr(skb)->version == 4) &&
109+
(ip_hdr(skb)->protocol == IPPROTO_UDP) &&
110+
((udp_hdr(skb)->dest == htons(319)) ||
111+
(udp_hdr(skb)->dest == htons(320)))) ||
112+
unlikely(eth_hdr(skb)->h_proto == htons(ETH_P_1588)))
113+
return aq_ptp_xmit(aq_nic, skb);
114+
}
115+
116+
skb_tx_timestamp(skb);
96117
return aq_nic_xmit(aq_nic, skb);
97118
}
98119

drivers/net/ethernet/aquantia/atlantic/aq_nic.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,11 @@ static int aq_nic_update_link_status(struct aq_nic_s *self)
146146
self->aq_hw->aq_link_status.mbps);
147147
aq_nic_update_interrupt_moderation_settings(self);
148148

149-
if (self->aq_ptp)
149+
if (self->aq_ptp) {
150150
aq_ptp_clock_init(self);
151+
aq_ptp_tm_offset_set(self,
152+
self->aq_hw->aq_link_status.mbps);
153+
}
151154

152155
/* Driver has to update flow control settings on RX block
153156
* on any link event.
@@ -196,6 +199,8 @@ static void aq_nic_service_task(struct work_struct *work)
196199
service_task);
197200
int err;
198201

202+
aq_ptp_service_task(self);
203+
199204
if (aq_utils_obj_test(&self->flags, AQ_NIC_FLAGS_IS_NOT_READY))
200205
return;
201206

@@ -408,6 +413,10 @@ int aq_nic_start(struct aq_nic_s *self)
408413
goto err_exit;
409414
}
410415

416+
err = aq_ptp_irq_alloc(self);
417+
if (err < 0)
418+
goto err_exit;
419+
411420
if (self->aq_nic_cfg.link_irq_vec) {
412421
int irqvec = pci_irq_vector(self->pdev,
413422
self->aq_nic_cfg.link_irq_vec);
@@ -440,9 +449,8 @@ int aq_nic_start(struct aq_nic_s *self)
440449
return err;
441450
}
442451

443-
static unsigned int aq_nic_map_skb(struct aq_nic_s *self,
444-
struct sk_buff *skb,
445-
struct aq_ring_s *ring)
452+
unsigned int aq_nic_map_skb(struct aq_nic_s *self, struct sk_buff *skb,
453+
struct aq_ring_s *ring)
446454
{
447455
unsigned int ret = 0U;
448456
unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
@@ -973,6 +981,8 @@ int aq_nic_stop(struct aq_nic_s *self)
973981
else
974982
aq_pci_func_free_irqs(self);
975983

984+
aq_ptp_irq_free(self);
985+
976986
for (i = 0U, aq_vec = self->aq_vec[0];
977987
self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i])
978988
aq_vec_stop(aq_vec);

drivers/net/ethernet/aquantia/atlantic/aq_nic.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ struct aq_nic_cfg_s {
5454
#define AQ_NIC_FLAG_STOPPING 0x00000008U
5555
#define AQ_NIC_FLAG_RESETTING 0x00000010U
5656
#define AQ_NIC_FLAG_CLOSING 0x00000020U
57+
#define AQ_NIC_PTP_DPATH_UP 0x02000000U
5758
#define AQ_NIC_LINK_DOWN 0x04000000U
5859
#define AQ_NIC_FLAG_ERR_UNPLUG 0x40000000U
5960
#define AQ_NIC_FLAG_ERR_HW 0x80000000U
@@ -129,6 +130,8 @@ void aq_nic_cfg_start(struct aq_nic_s *self);
129130
int aq_nic_ndev_register(struct aq_nic_s *self);
130131
void aq_nic_ndev_free(struct aq_nic_s *self);
131132
int aq_nic_start(struct aq_nic_s *self);
133+
unsigned int aq_nic_map_skb(struct aq_nic_s *self, struct sk_buff *skb,
134+
struct aq_ring_s *ring);
132135
int aq_nic_xmit(struct aq_nic_s *self, struct sk_buff *skb);
133136
int aq_nic_get_regs(struct aq_nic_s *self, struct ethtool_regs *regs, void *p);
134137
int aq_nic_get_regs_count(struct aq_nic_s *self);

drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// SPDX-License-Identifier: GPL-2.0-only
22
/*
33
* aQuantia Corporation Network Driver
4-
* Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved
4+
* Copyright (C) 2014-2019 aQuantia Corporation. All rights reserved
55
*/
66

77
/* File aq_pci_func.c: Definition of PCI functions. */
@@ -269,6 +269,9 @@ static int aq_pci_probe(struct pci_dev *pdev,
269269
numvecs = min((u8)AQ_CFG_VECS_DEF,
270270
aq_nic_get_cfg(self)->aq_hw_caps->msix_irqs);
271271
numvecs = min(numvecs, num_online_cpus());
272+
/* Request IRQ vector for PTP */
273+
numvecs += 1;
274+
272275
numvecs += AQ_HW_SERVICE_IRQS;
273276
/*enable interrupts */
274277
#if !AQ_CFG_FORCE_LEGACY_INT

0 commit comments

Comments
 (0)