aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsudarsana.kalluru@cavium.com <sudarsana.kalluru@cavium.com>2017-05-02 04:11:03 -0400
committerDavid S. Miller <davem@davemloft.net>2017-05-02 15:33:01 -0400
commit8d3f87d8cd0a16c58ae7e4410938528866c1c0db (patch)
treee15e2590d068f35aea706abbcca6259d13433326
parent461eec12012c29b66525c270208d30be8f6da8e7 (diff)
qed*: Fix issues in the ptp filter config implementation.
PTP hardware filter configuration performed by the driver for a given user requested config is not correct for some of the PTP modes. Following changes are needed for PTP config-filter implementation. 1. NIG_REG_TX_PTP_EN register - Bits 0/1/2 respectively enables TimeSync/"V1 frame format support"/"V2 frame format support" on the TX side. Set the associated bits based on the user request. 2. ptp4l application fails to operate in Peer Delay mode. Following changes are needed to fix this, a. Driver should enable (set to 0) DA #1-related bits for IPv4, IPv6 and MAC destination addresses in these registers: NIG_REG_TX_LLH_PTP_RULE_MASK NIG_REG_LLH_PTP_RULE_MASK b. NIG_REG_LLH_PTP_PARAM_MASK/NIG_REG_TX_LLH_PTP_PARAM_MASK should be set to 0x0 in all modes. Signed-off-by: Sudarsana Reddy Kalluru <Sudarsana.Kalluru@cavium.com> Signed-off-by: Yuval Mintz <Yuval.Mintz@cavium.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_ptp.c84
-rw-r--r--drivers/net/ethernet/qlogic/qede/qede_ptp.c34
-rw-r--r--include/linux/qed/qed_eth_if.h23
3 files changed, 98 insertions, 43 deletions
diff --git a/drivers/net/ethernet/qlogic/qed/qed_ptp.c b/drivers/net/ethernet/qlogic/qed/qed_ptp.c
index 1871ebfdb793..434a164a76ed 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_ptp.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_ptp.c
@@ -188,39 +188,73 @@ static int qed_ptp_hw_read_cc(struct qed_dev *cdev, u64 *phc_cycles)
188} 188}
189 189
190/* Filter PTP protocol packets that need to be timestamped */ 190/* Filter PTP protocol packets that need to be timestamped */
191static int qed_ptp_hw_cfg_rx_filters(struct qed_dev *cdev, 191static int qed_ptp_hw_cfg_filters(struct qed_dev *cdev,
192 enum qed_ptp_filter_type type) 192 enum qed_ptp_filter_type rx_type,
193 enum qed_ptp_hwtstamp_tx_type tx_type)
193{ 194{
194 struct qed_hwfn *p_hwfn = QED_LEADING_HWFN(cdev); 195 struct qed_hwfn *p_hwfn = QED_LEADING_HWFN(cdev);
195 struct qed_ptt *p_ptt = p_hwfn->p_ptp_ptt; 196 struct qed_ptt *p_ptt = p_hwfn->p_ptp_ptt;
196 u32 rule_mask, parm_mask; 197 u32 rule_mask, enable_cfg = 0x0;
197 198
198 switch (type) { 199 switch (rx_type) {
199 case QED_PTP_FILTER_L2_IPV4_IPV6: 200 case QED_PTP_FILTER_NONE:
200 parm_mask = 0x6AA; 201 enable_cfg = 0x0;
201 rule_mask = 0x3EEE; 202 rule_mask = 0x3FFF;
202 break; 203 break;
203 case QED_PTP_FILTER_L2: 204 case QED_PTP_FILTER_ALL:
204 parm_mask = 0x6BF; 205 enable_cfg = 0x7;
205 rule_mask = 0x3EFF; 206 rule_mask = 0x3CAA;
206 break; 207 break;
207 case QED_PTP_FILTER_IPV4_IPV6: 208 case QED_PTP_FILTER_V1_L4_EVENT:
208 parm_mask = 0x7EA; 209 enable_cfg = 0x3;
209 rule_mask = 0x3FFE; 210 rule_mask = 0x3FFA;
210 break; 211 break;
211 case QED_PTP_FILTER_IPV4: 212 case QED_PTP_FILTER_V1_L4_GEN:
212 parm_mask = 0x7EE; 213 enable_cfg = 0x3;
213 rule_mask = 0x3FFE; 214 rule_mask = 0x3FFE;
214 break; 215 break;
216 case QED_PTP_FILTER_V2_L4_EVENT:
217 enable_cfg = 0x5;
218 rule_mask = 0x3FAA;
219 break;
220 case QED_PTP_FILTER_V2_L4_GEN:
221 enable_cfg = 0x5;
222 rule_mask = 0x3FEE;
223 break;
224 case QED_PTP_FILTER_V2_L2_EVENT:
225 enable_cfg = 0x5;
226 rule_mask = 0x3CFF;
227 break;
228 case QED_PTP_FILTER_V2_L2_GEN:
229 enable_cfg = 0x5;
230 rule_mask = 0x3EFF;
231 break;
232 case QED_PTP_FILTER_V2_EVENT:
233 enable_cfg = 0x5;
234 rule_mask = 0x3CAA;
235 break;
236 case QED_PTP_FILTER_V2_GEN:
237 enable_cfg = 0x5;
238 rule_mask = 0x3EEE;
239 break;
215 default: 240 default:
216 DP_INFO(p_hwfn, "Invalid PTP filter type %d\n", type); 241 DP_INFO(p_hwfn, "Invalid PTP filter type %d\n", rx_type);
217 return -EINVAL; 242 return -EINVAL;
218 } 243 }
219 244
220 qed_wr(p_hwfn, p_ptt, NIG_REG_LLH_PTP_PARAM_MASK, parm_mask); 245 qed_wr(p_hwfn, p_ptt, NIG_REG_LLH_PTP_PARAM_MASK, 0);
221 qed_wr(p_hwfn, p_ptt, NIG_REG_LLH_PTP_RULE_MASK, rule_mask); 246 qed_wr(p_hwfn, p_ptt, NIG_REG_LLH_PTP_RULE_MASK, rule_mask);
247 qed_wr(p_hwfn, p_ptt, NIG_REG_RX_PTP_EN, enable_cfg);
222 248
223 qed_wr(p_hwfn, p_ptt, NIG_REG_LLH_PTP_TO_HOST, 0x1); 249 if (tx_type == QED_PTP_HWTSTAMP_TX_OFF) {
250 qed_wr(p_hwfn, p_ptt, NIG_REG_TX_PTP_EN, 0x0);
251 qed_wr(p_hwfn, p_ptt, NIG_REG_TX_LLH_PTP_PARAM_MASK, 0x7FF);
252 qed_wr(p_hwfn, p_ptt, NIG_REG_TX_LLH_PTP_RULE_MASK, 0x3FFF);
253 } else {
254 qed_wr(p_hwfn, p_ptt, NIG_REG_TX_PTP_EN, enable_cfg);
255 qed_wr(p_hwfn, p_ptt, NIG_REG_TX_LLH_PTP_PARAM_MASK, 0);
256 qed_wr(p_hwfn, p_ptt, NIG_REG_TX_LLH_PTP_RULE_MASK, rule_mask);
257 }
224 258
225 /* Reset possibly old timestamps */ 259 /* Reset possibly old timestamps */
226 qed_wr(p_hwfn, p_ptt, NIG_REG_LLH_PTP_HOST_BUF_SEQID, 260 qed_wr(p_hwfn, p_ptt, NIG_REG_LLH_PTP_HOST_BUF_SEQID,
@@ -383,17 +417,6 @@ static int qed_ptp_hw_enable(struct qed_dev *cdev)
383 return 0; 417 return 0;
384} 418}
385 419
386static int qed_ptp_hw_hwtstamp_tx_on(struct qed_dev *cdev)
387{
388 struct qed_hwfn *p_hwfn = QED_LEADING_HWFN(cdev);
389 struct qed_ptt *p_ptt = p_hwfn->p_ptp_ptt;
390
391 qed_wr(p_hwfn, p_ptt, NIG_REG_TX_LLH_PTP_PARAM_MASK, 0x6AA);
392 qed_wr(p_hwfn, p_ptt, NIG_REG_TX_LLH_PTP_RULE_MASK, 0x3EEE);
393
394 return 0;
395}
396
397static int qed_ptp_hw_disable(struct qed_dev *cdev) 420static int qed_ptp_hw_disable(struct qed_dev *cdev)
398{ 421{
399 struct qed_hwfn *p_hwfn = QED_LEADING_HWFN(cdev); 422 struct qed_hwfn *p_hwfn = QED_LEADING_HWFN(cdev);
@@ -419,8 +442,7 @@ static int qed_ptp_hw_disable(struct qed_dev *cdev)
419} 442}
420 443
421const struct qed_eth_ptp_ops qed_ptp_ops_pass = { 444const struct qed_eth_ptp_ops qed_ptp_ops_pass = {
422 .hwtstamp_tx_on = qed_ptp_hw_hwtstamp_tx_on, 445 .cfg_filters = qed_ptp_hw_cfg_filters,
423 .cfg_rx_filters = qed_ptp_hw_cfg_rx_filters,
424 .read_rx_ts = qed_ptp_hw_read_rx_ts, 446 .read_rx_ts = qed_ptp_hw_read_rx_ts,
425 .read_tx_ts = qed_ptp_hw_read_tx_ts, 447 .read_tx_ts = qed_ptp_hw_read_tx_ts,
426 .read_cc = qed_ptp_hw_read_cc, 448 .read_cc = qed_ptp_hw_read_cc,
diff --git a/drivers/net/ethernet/qlogic/qede/qede_ptp.c b/drivers/net/ethernet/qlogic/qede/qede_ptp.c
index aa4b5e7bb8e1..24f06e2ef43e 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_ptp.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_ptp.c
@@ -209,6 +209,8 @@ static u64 qede_ptp_read_cc(const struct cyclecounter *cc)
209 209
210static int qede_ptp_cfg_filters(struct qede_dev *edev) 210static int qede_ptp_cfg_filters(struct qede_dev *edev)
211{ 211{
212 enum qed_ptp_hwtstamp_tx_type tx_type = QED_PTP_HWTSTAMP_TX_ON;
213 enum qed_ptp_filter_type rx_filter = QED_PTP_FILTER_NONE;
212 struct qede_ptp *ptp = edev->ptp; 214 struct qede_ptp *ptp = edev->ptp;
213 215
214 if (!ptp) 216 if (!ptp)
@@ -222,7 +224,12 @@ static int qede_ptp_cfg_filters(struct qede_dev *edev)
222 switch (ptp->tx_type) { 224 switch (ptp->tx_type) {
223 case HWTSTAMP_TX_ON: 225 case HWTSTAMP_TX_ON:
224 edev->flags |= QEDE_TX_TIMESTAMPING_EN; 226 edev->flags |= QEDE_TX_TIMESTAMPING_EN;
225 ptp->ops->hwtstamp_tx_on(edev->cdev); 227 tx_type = QED_PTP_HWTSTAMP_TX_ON;
228 break;
229
230 case HWTSTAMP_TX_OFF:
231 edev->flags &= ~QEDE_TX_TIMESTAMPING_EN;
232 tx_type = QED_PTP_HWTSTAMP_TX_OFF;
226 break; 233 break;
227 234
228 case HWTSTAMP_TX_ONESTEP_SYNC: 235 case HWTSTAMP_TX_ONESTEP_SYNC:
@@ -233,42 +240,57 @@ static int qede_ptp_cfg_filters(struct qede_dev *edev)
233 spin_lock_bh(&ptp->lock); 240 spin_lock_bh(&ptp->lock);
234 switch (ptp->rx_filter) { 241 switch (ptp->rx_filter) {
235 case HWTSTAMP_FILTER_NONE: 242 case HWTSTAMP_FILTER_NONE:
243 rx_filter = QED_PTP_FILTER_NONE;
236 break; 244 break;
237 case HWTSTAMP_FILTER_ALL: 245 case HWTSTAMP_FILTER_ALL:
238 case HWTSTAMP_FILTER_SOME: 246 case HWTSTAMP_FILTER_SOME:
239 ptp->rx_filter = HWTSTAMP_FILTER_NONE; 247 ptp->rx_filter = HWTSTAMP_FILTER_NONE;
248 rx_filter = QED_PTP_FILTER_ALL;
240 break; 249 break;
241 case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: 250 case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
251 ptp->rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT;
252 rx_filter = QED_PTP_FILTER_V1_L4_EVENT;
253 break;
242 case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: 254 case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
243 case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: 255 case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
244 ptp->rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT; 256 ptp->rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT;
245 /* Initialize PTP detection for UDP/IPv4 events */ 257 /* Initialize PTP detection for UDP/IPv4 events */
246 ptp->ops->cfg_rx_filters(edev->cdev, QED_PTP_FILTER_IPV4); 258 rx_filter = QED_PTP_FILTER_V1_L4_GEN;
247 break; 259 break;
248 case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: 260 case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
261 ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT;
262 rx_filter = QED_PTP_FILTER_V2_L4_EVENT;
263 break;
249 case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: 264 case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
250 case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: 265 case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
251 ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT; 266 ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT;
252 /* Initialize PTP detection for UDP/IPv4 or UDP/IPv6 events */ 267 /* Initialize PTP detection for UDP/IPv4 or UDP/IPv6 events */
253 ptp->ops->cfg_rx_filters(edev->cdev, QED_PTP_FILTER_IPV4_IPV6); 268 rx_filter = QED_PTP_FILTER_V2_L4_GEN;
254 break; 269 break;
255 case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: 270 case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
271 ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT;
272 rx_filter = QED_PTP_FILTER_V2_L2_EVENT;
273 break;
256 case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: 274 case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
257 case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: 275 case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
258 ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT; 276 ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT;
259 /* Initialize PTP detection L2 events */ 277 /* Initialize PTP detection L2 events */
260 ptp->ops->cfg_rx_filters(edev->cdev, QED_PTP_FILTER_L2); 278 rx_filter = QED_PTP_FILTER_V2_L2_GEN;
261 break; 279 break;
262 case HWTSTAMP_FILTER_PTP_V2_EVENT: 280 case HWTSTAMP_FILTER_PTP_V2_EVENT:
281 ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
282 rx_filter = QED_PTP_FILTER_V2_EVENT;
283 break;
263 case HWTSTAMP_FILTER_PTP_V2_SYNC: 284 case HWTSTAMP_FILTER_PTP_V2_SYNC:
264 case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: 285 case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
265 ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; 286 ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
266 /* Initialize PTP detection L2, UDP/IPv4 or UDP/IPv6 events */ 287 /* Initialize PTP detection L2, UDP/IPv4 or UDP/IPv6 events */
267 ptp->ops->cfg_rx_filters(edev->cdev, 288 rx_filter = QED_PTP_FILTER_V2_GEN;
268 QED_PTP_FILTER_L2_IPV4_IPV6);
269 break; 289 break;
270 } 290 }
271 291
292 ptp->ops->cfg_filters(edev->cdev, rx_filter, tx_type);
293
272 spin_unlock_bh(&ptp->lock); 294 spin_unlock_bh(&ptp->lock);
273 295
274 return 0; 296 return 0;
diff --git a/include/linux/qed/qed_eth_if.h b/include/linux/qed/qed_eth_if.h
index 15fa7c6e4c6f..d66d16a559e1 100644
--- a/include/linux/qed/qed_eth_if.h
+++ b/include/linux/qed/qed_eth_if.h
@@ -164,10 +164,21 @@ struct qed_eth_cb_ops {
164#define QED_MAX_PHC_DRIFT_PPB 291666666 164#define QED_MAX_PHC_DRIFT_PPB 291666666
165 165
166enum qed_ptp_filter_type { 166enum qed_ptp_filter_type {
167 QED_PTP_FILTER_L2, 167 QED_PTP_FILTER_NONE,
168 QED_PTP_FILTER_IPV4, 168 QED_PTP_FILTER_ALL,
169 QED_PTP_FILTER_IPV4_IPV6, 169 QED_PTP_FILTER_V1_L4_EVENT,
170 QED_PTP_FILTER_L2_IPV4_IPV6 170 QED_PTP_FILTER_V1_L4_GEN,
171 QED_PTP_FILTER_V2_L4_EVENT,
172 QED_PTP_FILTER_V2_L4_GEN,
173 QED_PTP_FILTER_V2_L2_EVENT,
174 QED_PTP_FILTER_V2_L2_GEN,
175 QED_PTP_FILTER_V2_EVENT,
176 QED_PTP_FILTER_V2_GEN
177};
178
179enum qed_ptp_hwtstamp_tx_type {
180 QED_PTP_HWTSTAMP_TX_OFF,
181 QED_PTP_HWTSTAMP_TX_ON,
171}; 182};
172 183
173#ifdef CONFIG_DCB 184#ifdef CONFIG_DCB
@@ -230,8 +241,8 @@ struct qed_eth_dcbnl_ops {
230#endif 241#endif
231 242
232struct qed_eth_ptp_ops { 243struct qed_eth_ptp_ops {
233 int (*hwtstamp_tx_on)(struct qed_dev *); 244 int (*cfg_filters)(struct qed_dev *, enum qed_ptp_filter_type,
234 int (*cfg_rx_filters)(struct qed_dev *, enum qed_ptp_filter_type); 245 enum qed_ptp_hwtstamp_tx_type);
235 int (*read_rx_ts)(struct qed_dev *, u64 *); 246 int (*read_rx_ts)(struct qed_dev *, u64 *);
236 int (*read_tx_ts)(struct qed_dev *, u64 *); 247 int (*read_tx_ts)(struct qed_dev *, u64 *);
237 int (*read_cc)(struct qed_dev *, u64 *); 248 int (*read_cc)(struct qed_dev *, u64 *);