Skip to content

Commit 5a27503

Browse files
mwolechanguy11
authored andcommitted
idpf: add mailbox access to read PTP clock time
When the access to read PTP clock is specified as mailbox, the driver needs to send virtchnl message to perform PTP actions. Message is sent using idpf_mbq_opc_send_msg_to_peer_drv mailbox opcode, with the parameters received during PTP capabilities negotiation. Add functions to recognize PTP messages, move them to dedicated secondary mailbox, read the PTP clock time and cross timestamp using mailbox messages. Reviewed-by: Alexander Lobakin <aleksander.lobakin@intel.com> Reviewed-by: Willem de Bruijn <willemb@google.com> Reviewed-by: Jacob Keller <jacob.e.keller@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 5cb8805 commit 5a27503

File tree

5 files changed

+164
-0
lines changed

5 files changed

+164
-0
lines changed

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,9 +123,12 @@ struct idpf_ctlq_info {
123123
/**
124124
* enum idpf_mbx_opc - PF/VF mailbox commands
125125
* @idpf_mbq_opc_send_msg_to_cp: used by PF or VF to send a message to its CP
126+
* @idpf_mbq_opc_send_msg_to_peer_drv: used by PF or VF to send a message to
127+
* any peer driver
126128
*/
127129
enum idpf_mbx_opc {
128130
idpf_mbq_opc_send_msg_to_cp = 0x0801,
131+
idpf_mbq_opc_send_msg_to_peer_drv = 0x0804,
129132
};
130133

131134
/* API supported for control queue management */

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

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,37 @@ static u64 idpf_ptp_read_src_clk_reg_direct(struct idpf_adapter *adapter,
9292
return ((u64)hi << 32) | lo;
9393
}
9494

95+
/**
96+
* idpf_ptp_read_src_clk_reg_mailbox - Read the main timer value through mailbox
97+
* @adapter: Driver specific private structure
98+
* @sts: Optional parameter for holding a pair of system timestamps from
99+
* the system clock. Will be ignored when NULL is given.
100+
* @src_clk: Returned main timer value in nanoseconds unit
101+
*
102+
* Return: 0 on success, -errno otherwise.
103+
*/
104+
static int idpf_ptp_read_src_clk_reg_mailbox(struct idpf_adapter *adapter,
105+
struct ptp_system_timestamp *sts,
106+
u64 *src_clk)
107+
{
108+
struct idpf_ptp_dev_timers clk_time;
109+
int err;
110+
111+
/* Read the system timestamp pre PHC read */
112+
ptp_read_system_prets(sts);
113+
114+
err = idpf_ptp_get_dev_clk_time(adapter, &clk_time);
115+
if (err)
116+
return err;
117+
118+
/* Read the system timestamp post PHC read */
119+
ptp_read_system_postts(sts);
120+
121+
*src_clk = clk_time.dev_clk_time_ns;
122+
123+
return 0;
124+
}
125+
95126
/**
96127
* idpf_ptp_read_src_clk_reg - Read the main timer value
97128
* @adapter: Driver specific private structure
@@ -107,6 +138,8 @@ static int idpf_ptp_read_src_clk_reg(struct idpf_adapter *adapter, u64 *src_clk,
107138
switch (adapter->ptp->get_dev_clk_time_access) {
108139
case IDPF_PTP_NONE:
109140
return -EOPNOTSUPP;
141+
case IDPF_PTP_MAILBOX:
142+
return idpf_ptp_read_src_clk_reg_mailbox(adapter, sts, src_clk);
110143
case IDPF_PTP_DIRECT:
111144
*src_clk = idpf_ptp_read_src_clk_reg_direct(adapter, sts);
112145
break;

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

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,19 @@ enum idpf_ptp_access {
5252
IDPF_PTP_MAILBOX,
5353
};
5454

55+
/**
56+
* struct idpf_ptp_secondary_mbx - PTP secondary mailbox
57+
* @peer_mbx_q_id: PTP mailbox queue ID
58+
* @peer_id: Peer ID for PTP Device Control daemon
59+
* @valid: indicates whether secondary mailblox is supported by the Control
60+
* Plane
61+
*/
62+
struct idpf_ptp_secondary_mbx {
63+
u16 peer_mbx_q_id;
64+
u16 peer_id;
65+
bool valid:1;
66+
};
67+
5568
/**
5669
* struct idpf_ptp - PTP parameters
5770
* @info: structure defining PTP hardware capabilities
@@ -62,6 +75,7 @@ enum idpf_ptp_access {
6275
* @caps: PTP capabilities negotiated with the Control Plane
6376
* @get_dev_clk_time_access: access type for getting the device clock time
6477
* @rsv: reserved bits
78+
* @secondary_mbx: parameters for using dedicated PTP mailbox
6579
* @read_dev_clk_lock: spinlock protecting access to the device clock read
6680
* operation executed by the HW latch
6781
*/
@@ -74,6 +88,7 @@ struct idpf_ptp {
7488
u32 caps;
7589
enum idpf_ptp_access get_dev_clk_time_access:2;
7690
u32 rsv:30;
91+
struct idpf_ptp_secondary_mbx secondary_mbx;
7792
spinlock_t read_dev_clk_lock;
7893
};
7994

@@ -91,11 +106,23 @@ idpf_ptp_info_to_adapter(const struct ptp_clock_info *info)
91106
return ptp->adapter;
92107
}
93108

109+
/**
110+
* struct idpf_ptp_dev_timers - System time and device time values
111+
* @sys_time_ns: system time value expressed in nanoseconds
112+
* @dev_clk_time_ns: device clock time value expressed in nanoseconds
113+
*/
114+
struct idpf_ptp_dev_timers {
115+
u64 sys_time_ns;
116+
u64 dev_clk_time_ns;
117+
};
118+
94119
#if IS_ENABLED(CONFIG_PTP_1588_CLOCK)
95120
int idpf_ptp_init(struct idpf_adapter *adapter);
96121
void idpf_ptp_release(struct idpf_adapter *adapter);
97122
int idpf_ptp_get_caps(struct idpf_adapter *adapter);
98123
void idpf_ptp_get_features_access(const struct idpf_adapter *adapter);
124+
int idpf_ptp_get_dev_clk_time(struct idpf_adapter *adapter,
125+
struct idpf_ptp_dev_timers *dev_clk_time);
99126
#else /* CONFIG_PTP_1588_CLOCK */
100127
static inline int idpf_ptp_init(struct idpf_adapter *adapter)
101128
{
@@ -112,5 +139,12 @@ static inline int idpf_ptp_get_caps(struct idpf_adapter *adapter)
112139
static inline void
113140
idpf_ptp_get_features_access(const struct idpf_adapter *adapter) { }
114141

142+
static inline int
143+
idpf_ptp_get_dev_clk_time(struct idpf_adapter *adapter,
144+
struct idpf_ptp_dev_timers *dev_clk_time)
145+
{
146+
return -EOPNOTSUPP;
147+
}
148+
115149
#endif /* CONFIG_PTP_1588_CLOCK */
116150
#endif /* _IDPF_PTP_H */

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

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,50 @@ static int idpf_mb_clean(struct idpf_adapter *adapter)
154154
return err;
155155
}
156156

157+
#if IS_ENABLED(CONFIG_PTP_1588_CLOCK)
158+
/**
159+
* idpf_ptp_is_mb_msg - Check if the message is PTP-related
160+
* @op: virtchnl opcode
161+
*
162+
* Return: true if msg is PTP-related, false otherwise.
163+
*/
164+
static bool idpf_ptp_is_mb_msg(u32 op)
165+
{
166+
switch (op) {
167+
case VIRTCHNL2_OP_PTP_GET_DEV_CLK_TIME:
168+
case VIRTCHNL2_OP_PTP_GET_CROSS_TIME:
169+
return true;
170+
default:
171+
return false;
172+
}
173+
}
174+
175+
/**
176+
* idpf_prepare_ptp_mb_msg - Prepare PTP related message
177+
*
178+
* @adapter: Driver specific private structure
179+
* @op: virtchnl opcode
180+
* @ctlq_msg: Corresponding control queue message
181+
*/
182+
static void idpf_prepare_ptp_mb_msg(struct idpf_adapter *adapter, u32 op,
183+
struct idpf_ctlq_msg *ctlq_msg)
184+
{
185+
/* If the message is PTP-related and the secondary mailbox is available,
186+
* send the message through the secondary mailbox.
187+
*/
188+
if (!idpf_ptp_is_mb_msg(op) || !adapter->ptp->secondary_mbx.valid)
189+
return;
190+
191+
ctlq_msg->opcode = idpf_mbq_opc_send_msg_to_peer_drv;
192+
ctlq_msg->func_id = adapter->ptp->secondary_mbx.peer_mbx_q_id;
193+
ctlq_msg->host_id = adapter->ptp->secondary_mbx.peer_id;
194+
}
195+
#else /* !CONFIG_PTP_1588_CLOCK */
196+
static void idpf_prepare_ptp_mb_msg(struct idpf_adapter *adapter, u32 op,
197+
struct idpf_ctlq_msg *ctlq_msg)
198+
{ }
199+
#endif /* CONFIG_PTP_1588_CLOCK */
200+
157201
/**
158202
* idpf_send_mb_msg - Send message over mailbox
159203
* @adapter: Driver specific private structure
@@ -197,6 +241,9 @@ int idpf_send_mb_msg(struct idpf_adapter *adapter, u32 op,
197241

198242
ctlq_msg->opcode = idpf_mbq_opc_send_msg_to_cp;
199243
ctlq_msg->func_id = 0;
244+
245+
idpf_prepare_ptp_mb_msg(adapter, op, ctlq_msg);
246+
200247
ctlq_msg->data_len = msg_size;
201248
ctlq_msg->cookie.mbx.chnl_opcode = op;
202249
ctlq_msg->cookie.mbx.chnl_retval = 0;

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

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ int idpf_ptp_get_caps(struct idpf_adapter *adapter)
2929
.timeout_ms = IDPF_VC_XN_DEFAULT_TIMEOUT_MSEC,
3030
};
3131
struct virtchnl2_ptp_clk_reg_offsets clock_offsets;
32+
struct idpf_ptp_secondary_mbx *scnd_mbx;
3233
struct idpf_ptp *ptp = adapter->ptp;
3334
enum idpf_ptp_access access_type;
3435
u32 temp_offset;
@@ -50,6 +51,16 @@ int idpf_ptp_get_caps(struct idpf_adapter *adapter)
5051

5152
ptp->caps = le32_to_cpu(recv_ptp_caps_msg->caps);
5253

54+
scnd_mbx = &ptp->secondary_mbx;
55+
scnd_mbx->peer_mbx_q_id = le16_to_cpu(recv_ptp_caps_msg->peer_mbx_q_id);
56+
57+
/* if the ptp_mb_q_id holds invalid value (0xffff), the secondary
58+
* mailbox is not supported.
59+
*/
60+
scnd_mbx->valid = scnd_mbx->peer_mbx_q_id != 0xffff;
61+
if (scnd_mbx->valid)
62+
scnd_mbx->peer_id = recv_ptp_caps_msg->peer_id;
63+
5364
/* Determine the access type for the PTP features */
5465
idpf_ptp_get_features_access(adapter);
5566

@@ -76,3 +87,39 @@ int idpf_ptp_get_caps(struct idpf_adapter *adapter)
7687

7788
return 0;
7889
}
90+
91+
/**
92+
* idpf_ptp_get_dev_clk_time - Send virtchnl get device clk time message
93+
* @adapter: Driver specific private structure
94+
* @dev_clk_time: Pointer to the device clock structure where the value is set
95+
*
96+
* Send virtchnl get time message to get the time of the clock.
97+
*
98+
* Return: 0 on success, -errno otherwise.
99+
*/
100+
int idpf_ptp_get_dev_clk_time(struct idpf_adapter *adapter,
101+
struct idpf_ptp_dev_timers *dev_clk_time)
102+
{
103+
struct virtchnl2_ptp_get_dev_clk_time get_dev_clk_time_msg;
104+
struct idpf_vc_xn_params xn_params = {
105+
.vc_op = VIRTCHNL2_OP_PTP_GET_DEV_CLK_TIME,
106+
.send_buf.iov_base = &get_dev_clk_time_msg,
107+
.send_buf.iov_len = sizeof(get_dev_clk_time_msg),
108+
.recv_buf.iov_base = &get_dev_clk_time_msg,
109+
.recv_buf.iov_len = sizeof(get_dev_clk_time_msg),
110+
.timeout_ms = IDPF_VC_XN_DEFAULT_TIMEOUT_MSEC,
111+
};
112+
int reply_sz;
113+
u64 dev_time;
114+
115+
reply_sz = idpf_vc_xn_exec(adapter, &xn_params);
116+
if (reply_sz < 0)
117+
return reply_sz;
118+
if (reply_sz != sizeof(get_dev_clk_time_msg))
119+
return -EIO;
120+
121+
dev_time = le64_to_cpu(get_dev_clk_time_msg.dev_time_ns);
122+
dev_clk_time->dev_clk_time_ns = dev_time;
123+
124+
return 0;
125+
}

0 commit comments

Comments
 (0)