Skip to content

Commit 4901e83

Browse files
mwolechanguy11
authored andcommitted
idpf: add Tx timestamp capabilities negotiation
Tx timestamp capabilities are negotiated for the uplink Vport. Driver receives information about the number of available Tx timestamp latches, the size of Tx timestamp value and the set of indexes used for Tx timestamping. Add function to get the Tx timestamp capabilities and parse the uplink vport flag. Reviewed-by: Alexander Lobakin <aleksander.lobakin@intel.com> Reviewed-by: Jacob Keller <jacob.e.keller@intel.com> Co-developed-by: Emil Tantilov <emil.s.tantilov@intel.com> Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com> Co-developed-by: Pavan Kumar Linga <pavan.kumar.linga@intel.com> Signed-off-by: Pavan Kumar Linga <pavan.kumar.linga@intel.com> Signed-off-by: Milena Olech <milena.olech@intel.com> Tested-by: Samuel Salin <Samuel.salin@intel.com> Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
1 parent d5dba8f commit 4901e83

File tree

6 files changed

+308
-4
lines changed

6 files changed

+308
-4
lines changed

drivers/net/ethernet/intel/idpf/idpf.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,7 @@ struct idpf_port_stats {
292292
* @port_stats: per port csum, header split, and other offload stats
293293
* @link_up: True if link is up
294294
* @sw_marker_wq: workqueue for marker packets
295+
* @tx_tstamp_caps: Capabilities negotiated for Tx timestamping
295296
*/
296297
struct idpf_vport {
297298
u16 num_txq;
@@ -336,6 +337,8 @@ struct idpf_vport {
336337
bool link_up;
337338

338339
wait_queue_head_t sw_marker_wq;
340+
341+
struct idpf_ptp_vport_tx_tstamp_caps *tx_tstamp_caps;
339342
};
340343

341344
/**
@@ -480,6 +483,13 @@ struct idpf_vport_config {
480483

481484
struct idpf_vc_xn_manager;
482485

486+
#define idpf_for_each_vport(adapter, iter) \
487+
for (struct idpf_vport **__##iter = &(adapter)->vports[0], \
488+
*iter = (adapter)->max_vports ? *__##iter : NULL; \
489+
iter; \
490+
iter = (++__##iter) < &(adapter)->vports[(adapter)->max_vports] ? \
491+
*__##iter : NULL)
492+
483493
/**
484494
* struct idpf_adapter - Device data struct generated on probe
485495
* @pdev: PCI device struct given on probe

drivers/net/ethernet/intel/idpf/idpf_ptp.c

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,13 @@ void idpf_ptp_get_features_access(const struct idpf_adapter *adapter)
5555
ptp->adj_dev_clk_time_access = idpf_ptp_get_access(adapter,
5656
direct,
5757
mailbox);
58+
59+
/* Tx timestamping */
60+
direct = VIRTCHNL2_CAP_PTP_TX_TSTAMPS;
61+
mailbox = VIRTCHNL2_CAP_PTP_TX_TSTAMPS_MB;
62+
ptp->tx_tstamp_access = idpf_ptp_get_access(adapter,
63+
direct,
64+
mailbox);
5865
}
5966

6067
/**
@@ -393,6 +400,57 @@ static int idpf_ptp_create_clock(const struct idpf_adapter *adapter)
393400
return 0;
394401
}
395402

403+
/**
404+
* idpf_ptp_release_vport_tstamp - Release the Tx timestamps trakcers for a
405+
* given vport.
406+
* @vport: Virtual port structure
407+
*
408+
* Remove the queues and delete lists that tracks Tx timestamp entries for a
409+
* given vport.
410+
*/
411+
static void idpf_ptp_release_vport_tstamp(struct idpf_vport *vport)
412+
{
413+
struct idpf_ptp_tx_tstamp *ptp_tx_tstamp, *tmp;
414+
struct list_head *head;
415+
416+
/* Remove list with free latches */
417+
spin_lock_bh(&vport->tx_tstamp_caps->latches_lock);
418+
419+
head = &vport->tx_tstamp_caps->latches_free;
420+
list_for_each_entry_safe(ptp_tx_tstamp, tmp, head, list_member) {
421+
list_del(&ptp_tx_tstamp->list_member);
422+
kfree(ptp_tx_tstamp);
423+
}
424+
425+
/* Remove list with latches in use */
426+
head = &vport->tx_tstamp_caps->latches_in_use;
427+
list_for_each_entry_safe(ptp_tx_tstamp, tmp, head, list_member) {
428+
list_del(&ptp_tx_tstamp->list_member);
429+
kfree(ptp_tx_tstamp);
430+
}
431+
432+
spin_unlock_bh(&vport->tx_tstamp_caps->latches_lock);
433+
434+
kfree(vport->tx_tstamp_caps);
435+
vport->tx_tstamp_caps = NULL;
436+
}
437+
438+
/**
439+
* idpf_ptp_release_tstamp - Release the Tx timestamps trackers
440+
* @adapter: Driver specific private structure
441+
*
442+
* Remove the queues and delete lists that tracks Tx timestamp entries.
443+
*/
444+
static void idpf_ptp_release_tstamp(struct idpf_adapter *adapter)
445+
{
446+
idpf_for_each_vport(adapter, vport) {
447+
if (!idpf_ptp_is_vport_tx_tstamp_ena(vport))
448+
continue;
449+
450+
idpf_ptp_release_vport_tstamp(vport);
451+
}
452+
}
453+
396454
/**
397455
* idpf_ptp_init - Initialize PTP hardware clock support
398456
* @adapter: Driver specific private structure
@@ -479,6 +537,9 @@ void idpf_ptp_release(struct idpf_adapter *adapter)
479537
if (!ptp)
480538
return;
481539

540+
if (ptp->tx_tstamp_access != IDPF_PTP_NONE)
541+
idpf_ptp_release_tstamp(adapter);
542+
482543
if (ptp->clock)
483544
ptp_clock_unregister(ptp->clock);
484545

drivers/net/ethernet/intel/idpf/idpf_ptp.h

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,68 @@ struct idpf_ptp_secondary_mbx {
8585
bool valid:1;
8686
};
8787

88+
/**
89+
* enum idpf_ptp_tx_tstamp_state - Tx timestamp states
90+
* @IDPF_PTP_FREE: Tx timestamp index free to use
91+
* @IDPF_PTP_REQUEST: Tx timestamp index set to the Tx descriptor
92+
* @IDPF_PTP_READ_VALUE: Tx timestamp value ready to be read
93+
*/
94+
enum idpf_ptp_tx_tstamp_state {
95+
IDPF_PTP_FREE,
96+
IDPF_PTP_REQUEST,
97+
IDPF_PTP_READ_VALUE,
98+
};
99+
100+
/**
101+
* struct idpf_ptp_tx_tstamp_status - Parameters to track Tx timestamp
102+
* @skb: the pointer to the SKB that received the completion tag
103+
* @state: the state of the Tx timestamp
104+
*/
105+
struct idpf_ptp_tx_tstamp_status {
106+
struct sk_buff *skb;
107+
enum idpf_ptp_tx_tstamp_state state;
108+
};
109+
110+
/**
111+
* struct idpf_ptp_tx_tstamp - Parameters for Tx timestamping
112+
* @list_member: the list member structure
113+
* @tx_latch_reg_offset_l: Tx tstamp latch low register offset
114+
* @tx_latch_reg_offset_h: Tx tstamp latch high register offset
115+
* @skb: the pointer to the SKB for this timestamp request
116+
* @tstamp: the Tx tstamp value
117+
* @idx: the index of the Tx tstamp
118+
*/
119+
struct idpf_ptp_tx_tstamp {
120+
struct list_head list_member;
121+
u32 tx_latch_reg_offset_l;
122+
u32 tx_latch_reg_offset_h;
123+
struct sk_buff *skb;
124+
u64 tstamp;
125+
u32 idx;
126+
};
127+
128+
/**
129+
* struct idpf_ptp_vport_tx_tstamp_caps - Tx timestamp capabilities
130+
* @vport_id: the vport id
131+
* @num_entries: the number of negotiated Tx timestamp entries
132+
* @tstamp_ns_lo_bit: first bit for nanosecond part of the timestamp
133+
* @latches_lock: the lock to the lists of free/used timestamp indexes
134+
* @status_lock: the lock to the status tracker
135+
* @latches_free: the list of the free Tx timestamps latches
136+
* @latches_in_use: the list of the used Tx timestamps latches
137+
* @tx_tstamp_status: Tx tstamp status tracker
138+
*/
139+
struct idpf_ptp_vport_tx_tstamp_caps {
140+
u32 vport_id;
141+
u16 num_entries;
142+
u16 tstamp_ns_lo_bit;
143+
spinlock_t latches_lock;
144+
spinlock_t status_lock;
145+
struct list_head latches_free;
146+
struct list_head latches_in_use;
147+
struct idpf_ptp_tx_tstamp_status tx_tstamp_status[];
148+
};
149+
88150
/**
89151
* struct idpf_ptp - PTP parameters
90152
* @info: structure defining PTP hardware capabilities
@@ -98,6 +160,7 @@ struct idpf_ptp_secondary_mbx {
98160
* @get_dev_clk_time_access: access type for getting the device clock time
99161
* @set_dev_clk_time_access: access type for setting the device clock time
100162
* @adj_dev_clk_time_access: access type for the adjusting the device clock
163+
* @tx_tstamp_access: access type for the Tx timestamp value read
101164
* @rsv: reserved bits
102165
* @secondary_mbx: parameters for using dedicated PTP mailbox
103166
* @read_dev_clk_lock: spinlock protecting access to the device clock read
@@ -115,7 +178,8 @@ struct idpf_ptp {
115178
enum idpf_ptp_access get_dev_clk_time_access:2;
116179
enum idpf_ptp_access set_dev_clk_time_access:2;
117180
enum idpf_ptp_access adj_dev_clk_time_access:2;
118-
u32 rsv:10;
181+
enum idpf_ptp_access tx_tstamp_access:2;
182+
u8 rsv;
119183
struct idpf_ptp_secondary_mbx secondary_mbx;
120184
spinlock_t read_dev_clk_lock;
121185
};
@@ -144,6 +208,27 @@ struct idpf_ptp_dev_timers {
144208
u64 dev_clk_time_ns;
145209
};
146210

211+
/**
212+
* idpf_ptp_is_vport_tx_tstamp_ena - Verify the Tx timestamping enablement for
213+
* a given vport.
214+
* @vport: Virtual port structure
215+
*
216+
* Tx timestamp capabilities are negotiated with the Control Plane only if the
217+
* device clock value can be read, Tx timestamp access type is different than
218+
* NONE, and the PTP clock for the adapter is created. When all those conditions
219+
* are satisfied, Tx timestamp feature is enabled and tx_tstamp_caps is
220+
* allocated and fulfilled.
221+
*
222+
* Return: true if the Tx timestamping is enabled, false otherwise.
223+
*/
224+
static inline bool idpf_ptp_is_vport_tx_tstamp_ena(struct idpf_vport *vport)
225+
{
226+
if (!vport->tx_tstamp_caps)
227+
return false;
228+
else
229+
return true;
230+
}
231+
147232
#if IS_ENABLED(CONFIG_PTP_1588_CLOCK)
148233
int idpf_ptp_init(struct idpf_adapter *adapter);
149234
void idpf_ptp_release(struct idpf_adapter *adapter);
@@ -154,6 +239,7 @@ int idpf_ptp_get_dev_clk_time(struct idpf_adapter *adapter,
154239
int idpf_ptp_set_dev_clk_time(struct idpf_adapter *adapter, u64 time);
155240
int idpf_ptp_adj_dev_clk_fine(struct idpf_adapter *adapter, u64 incval);
156241
int idpf_ptp_adj_dev_clk_time(struct idpf_adapter *adapter, s64 delta);
242+
int idpf_ptp_get_vport_tstamps_caps(struct idpf_vport *vport);
157243
#else /* CONFIG_PTP_1588_CLOCK */
158244
static inline int idpf_ptp_init(struct idpf_adapter *adapter)
159245
{
@@ -195,5 +281,10 @@ static inline int idpf_ptp_adj_dev_clk_time(struct idpf_adapter *adapter,
195281
return -EOPNOTSUPP;
196282
}
197283

284+
static inline int idpf_ptp_get_vport_tstamps_caps(struct idpf_vport *vport)
285+
{
286+
return -EOPNOTSUPP;
287+
}
288+
198289
#endif /* CONFIG_PTP_1588_CLOCK */
199290
#endif /* _IDPF_PTP_H */

drivers/net/ethernet/intel/idpf/idpf_virtchnl.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,8 @@ static bool idpf_ptp_is_mb_msg(u32 op)
169169
case VIRTCHNL2_OP_PTP_SET_DEV_CLK_TIME:
170170
case VIRTCHNL2_OP_PTP_ADJ_DEV_CLK_FINE:
171171
case VIRTCHNL2_OP_PTP_ADJ_DEV_CLK_TIME:
172+
case VIRTCHNL2_OP_PTP_GET_VPORT_TX_TSTAMP_CAPS:
173+
case VIRTCHNL2_OP_PTP_GET_VPORT_TX_TSTAMP:
172174
return true;
173175
default:
174176
return false;
@@ -3134,6 +3136,7 @@ void idpf_vport_init(struct idpf_vport *vport, struct idpf_vport_max_q *max_q)
31343136
u16 rx_itr[] = {2, 8, 32, 96, 128};
31353137
struct idpf_rss_data *rss_data;
31363138
u16 idx = vport->idx;
3139+
int err;
31373140

31383141
vport_config = adapter->vport_config[idx];
31393142
rss_data = &vport_config->user_config.rss_data;
@@ -3168,6 +3171,14 @@ void idpf_vport_init(struct idpf_vport *vport, struct idpf_vport_max_q *max_q)
31683171
idpf_vport_alloc_vec_indexes(vport);
31693172

31703173
vport->crc_enable = adapter->crc_enable;
3174+
3175+
if (!(vport_msg->vport_flags &
3176+
cpu_to_le16(VIRTCHNL2_VPORT_UPLINK_PORT)))
3177+
return;
3178+
3179+
err = idpf_ptp_get_vport_tstamps_caps(vport);
3180+
if (err)
3181+
pci_dbg(vport->adapter->pdev, "Tx timestamping not supported\n");
31713182
}
31723183

31733184
/**

0 commit comments

Comments
 (0)