aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Cochran <richardcochran@gmail.com>2014-11-21 15:51:26 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2015-01-22 21:10:19 -0500
commit720db4ffd0846570c1ddc82e7bb661ab0a676fad (patch)
treeb9d28e75701f3fe3444916778517b66669682c35
parent00c65578b47bec3f92ce259d0c9d959ac54fff28 (diff)
igb: enable auxiliary PHC functions for the i210
The i210 device offers a number of special PTP Hardware Clock features on the Software Defined Pins (SDPs). This patch adds support for two of the possible functions, namely time stamping external events, and periodic output signals. The assignment of PHC functions to the four SDP can be freely chosen by the user. Signed-off-by: Richard Cochran <richardcochran@gmail.com> Tested-by: Aaron Brown <aaron.f.brown@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-rw-r--r--drivers/net/ethernet/intel/igb/igb.h9
-rw-r--r--drivers/net/ethernet/intel/igb/igb_main.c51
-rw-r--r--drivers/net/ethernet/intel/igb/igb_ptp.c222
3 files changed, 276 insertions, 6 deletions
diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h
index ee22da391474..c2bd4f98a837 100644
--- a/drivers/net/ethernet/intel/igb/igb.h
+++ b/drivers/net/ethernet/intel/igb/igb.h
@@ -343,6 +343,9 @@ struct hwmon_buff {
343 }; 343 };
344#endif 344#endif
345 345
346#define IGB_N_EXTTS 2
347#define IGB_N_PEROUT 2
348#define IGB_N_SDP 4
346#define IGB_RETA_SIZE 128 349#define IGB_RETA_SIZE 128
347 350
348/* board specific private data structure */ 351/* board specific private data structure */
@@ -439,6 +442,12 @@ struct igb_adapter {
439 u32 tx_hwtstamp_timeouts; 442 u32 tx_hwtstamp_timeouts;
440 u32 rx_hwtstamp_cleared; 443 u32 rx_hwtstamp_cleared;
441 444
445 struct ptp_pin_desc sdp_config[IGB_N_SDP];
446 struct {
447 struct timespec start;
448 struct timespec period;
449 } perout[IGB_N_PEROUT];
450
442 char fw_version[32]; 451 char fw_version[32];
443#ifdef CONFIG_IGB_HWMON 452#ifdef CONFIG_IGB_HWMON
444 struct hwmon_buff *igb_hwmon_buff; 453 struct hwmon_buff *igb_hwmon_buff;
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index e84416286dde..6e6544970b83 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -5388,7 +5388,8 @@ static void igb_tsync_interrupt(struct igb_adapter *adapter)
5388{ 5388{
5389 struct e1000_hw *hw = &adapter->hw; 5389 struct e1000_hw *hw = &adapter->hw;
5390 struct ptp_clock_event event; 5390 struct ptp_clock_event event;
5391 u32 ack = 0, tsicr = rd32(E1000_TSICR); 5391 struct timespec ts;
5392 u32 ack = 0, tsauxc, sec, nsec, tsicr = rd32(E1000_TSICR);
5392 5393
5393 if (tsicr & TSINTR_SYS_WRAP) { 5394 if (tsicr & TSINTR_SYS_WRAP) {
5394 event.type = PTP_CLOCK_PPS; 5395 event.type = PTP_CLOCK_PPS;
@@ -5405,6 +5406,54 @@ static void igb_tsync_interrupt(struct igb_adapter *adapter)
5405 ack |= E1000_TSICR_TXTS; 5406 ack |= E1000_TSICR_TXTS;
5406 } 5407 }
5407 5408
5409 if (tsicr & TSINTR_TT0) {
5410 spin_lock(&adapter->tmreg_lock);
5411 ts = timespec_add(adapter->perout[0].start,
5412 adapter->perout[0].period);
5413 wr32(E1000_TRGTTIML0, ts.tv_nsec);
5414 wr32(E1000_TRGTTIMH0, ts.tv_sec);
5415 tsauxc = rd32(E1000_TSAUXC);
5416 tsauxc |= TSAUXC_EN_TT0;
5417 wr32(E1000_TSAUXC, tsauxc);
5418 adapter->perout[0].start = ts;
5419 spin_unlock(&adapter->tmreg_lock);
5420 ack |= TSINTR_TT0;
5421 }
5422
5423 if (tsicr & TSINTR_TT1) {
5424 spin_lock(&adapter->tmreg_lock);
5425 ts = timespec_add(adapter->perout[1].start,
5426 adapter->perout[1].period);
5427 wr32(E1000_TRGTTIML1, ts.tv_nsec);
5428 wr32(E1000_TRGTTIMH1, ts.tv_sec);
5429 tsauxc = rd32(E1000_TSAUXC);
5430 tsauxc |= TSAUXC_EN_TT1;
5431 wr32(E1000_TSAUXC, tsauxc);
5432 adapter->perout[1].start = ts;
5433 spin_unlock(&adapter->tmreg_lock);
5434 ack |= TSINTR_TT1;
5435 }
5436
5437 if (tsicr & TSINTR_AUTT0) {
5438 nsec = rd32(E1000_AUXSTMPL0);
5439 sec = rd32(E1000_AUXSTMPH0);
5440 event.type = PTP_CLOCK_EXTTS;
5441 event.index = 0;
5442 event.timestamp = sec * 1000000000ULL + nsec;
5443 ptp_clock_event(adapter->ptp_clock, &event);
5444 ack |= TSINTR_AUTT0;
5445 }
5446
5447 if (tsicr & TSINTR_AUTT1) {
5448 nsec = rd32(E1000_AUXSTMPL1);
5449 sec = rd32(E1000_AUXSTMPH1);
5450 event.type = PTP_CLOCK_EXTTS;
5451 event.index = 1;
5452 event.timestamp = sec * 1000000000ULL + nsec;
5453 ptp_clock_event(adapter->ptp_clock, &event);
5454 ack |= TSINTR_AUTT1;
5455 }
5456
5408 /* acknowledge the interrupts */ 5457 /* acknowledge the interrupts */
5409 wr32(E1000_TSICR, ack); 5458 wr32(E1000_TSICR, ack);
5410} 5459}
diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c b/drivers/net/ethernet/intel/igb/igb_ptp.c
index 98c58d921228..d20fc8ed11f1 100644
--- a/drivers/net/ethernet/intel/igb/igb_ptp.c
+++ b/drivers/net/ethernet/intel/igb/igb_ptp.c
@@ -355,16 +355,204 @@ static int igb_ptp_settime_i210(struct ptp_clock_info *ptp,
355 return 0; 355 return 0;
356} 356}
357 357
358static void igb_pin_direction(int pin, int input, u32 *ctrl, u32 *ctrl_ext)
359{
360 u32 *ptr = pin < 2 ? ctrl : ctrl_ext;
361 u32 mask[IGB_N_SDP] = {
362 E1000_CTRL_SDP0_DIR,
363 E1000_CTRL_SDP1_DIR,
364 E1000_CTRL_EXT_SDP2_DIR,
365 E1000_CTRL_EXT_SDP3_DIR,
366 };
367
368 if (input)
369 *ptr &= ~mask[pin];
370 else
371 *ptr |= mask[pin];
372}
373
374static void igb_pin_extts(struct igb_adapter *igb, int chan, int pin)
375{
376 struct e1000_hw *hw = &igb->hw;
377 u32 aux0_sel_sdp[IGB_N_SDP] = {
378 AUX0_SEL_SDP0, AUX0_SEL_SDP1, AUX0_SEL_SDP2, AUX0_SEL_SDP3,
379 };
380 u32 aux1_sel_sdp[IGB_N_SDP] = {
381 AUX1_SEL_SDP0, AUX1_SEL_SDP1, AUX1_SEL_SDP2, AUX1_SEL_SDP3,
382 };
383 u32 ts_sdp_en[IGB_N_SDP] = {
384 TS_SDP0_EN, TS_SDP1_EN, TS_SDP2_EN, TS_SDP3_EN,
385 };
386 u32 ctrl, ctrl_ext, tssdp = 0;
387
388 ctrl = rd32(E1000_CTRL);
389 ctrl_ext = rd32(E1000_CTRL_EXT);
390 tssdp = rd32(E1000_TSSDP);
391
392 igb_pin_direction(pin, 1, &ctrl, &ctrl_ext);
393
394 /* Make sure this pin is not enabled as an output. */
395 tssdp &= ~ts_sdp_en[pin];
396
397 if (chan == 1) {
398 tssdp &= ~AUX1_SEL_SDP3;
399 tssdp |= aux1_sel_sdp[pin] | AUX1_TS_SDP_EN;
400 } else {
401 tssdp &= ~AUX0_SEL_SDP3;
402 tssdp |= aux0_sel_sdp[pin] | AUX0_TS_SDP_EN;
403 }
404
405 wr32(E1000_TSSDP, tssdp);
406 wr32(E1000_CTRL, ctrl);
407 wr32(E1000_CTRL_EXT, ctrl_ext);
408}
409
410static void igb_pin_perout(struct igb_adapter *igb, int chan, int pin)
411{
412 struct e1000_hw *hw = &igb->hw;
413 u32 aux0_sel_sdp[IGB_N_SDP] = {
414 AUX0_SEL_SDP0, AUX0_SEL_SDP1, AUX0_SEL_SDP2, AUX0_SEL_SDP3,
415 };
416 u32 aux1_sel_sdp[IGB_N_SDP] = {
417 AUX1_SEL_SDP0, AUX1_SEL_SDP1, AUX1_SEL_SDP2, AUX1_SEL_SDP3,
418 };
419 u32 ts_sdp_en[IGB_N_SDP] = {
420 TS_SDP0_EN, TS_SDP1_EN, TS_SDP2_EN, TS_SDP3_EN,
421 };
422 u32 ts_sdp_sel_tt0[IGB_N_SDP] = {
423 TS_SDP0_SEL_TT0, TS_SDP1_SEL_TT0,
424 TS_SDP2_SEL_TT0, TS_SDP3_SEL_TT0,
425 };
426 u32 ts_sdp_sel_tt1[IGB_N_SDP] = {
427 TS_SDP0_SEL_TT1, TS_SDP1_SEL_TT1,
428 TS_SDP2_SEL_TT1, TS_SDP3_SEL_TT1,
429 };
430 u32 ts_sdp_sel_clr[IGB_N_SDP] = {
431 TS_SDP0_SEL_FC1, TS_SDP1_SEL_FC1,
432 TS_SDP2_SEL_FC1, TS_SDP3_SEL_FC1,
433 };
434 u32 ctrl, ctrl_ext, tssdp = 0;
435
436 ctrl = rd32(E1000_CTRL);
437 ctrl_ext = rd32(E1000_CTRL_EXT);
438 tssdp = rd32(E1000_TSSDP);
439
440 igb_pin_direction(pin, 0, &ctrl, &ctrl_ext);
441
442 /* Make sure this pin is not enabled as an input. */
443 if ((tssdp & AUX0_SEL_SDP3) == aux0_sel_sdp[pin])
444 tssdp &= ~AUX0_TS_SDP_EN;
445
446 if ((tssdp & AUX1_SEL_SDP3) == aux1_sel_sdp[pin])
447 tssdp &= ~AUX1_TS_SDP_EN;
448
449 tssdp &= ~ts_sdp_sel_clr[pin];
450 if (chan == 1)
451 tssdp |= ts_sdp_sel_tt1[pin];
452 else
453 tssdp |= ts_sdp_sel_tt0[pin];
454
455 tssdp |= ts_sdp_en[pin];
456
457 wr32(E1000_TSSDP, tssdp);
458 wr32(E1000_CTRL, ctrl);
459 wr32(E1000_CTRL_EXT, ctrl_ext);
460}
461
358static int igb_ptp_feature_enable_i210(struct ptp_clock_info *ptp, 462static int igb_ptp_feature_enable_i210(struct ptp_clock_info *ptp,
359 struct ptp_clock_request *rq, int on) 463 struct ptp_clock_request *rq, int on)
360{ 464{
361 struct igb_adapter *igb = 465 struct igb_adapter *igb =
362 container_of(ptp, struct igb_adapter, ptp_caps); 466 container_of(ptp, struct igb_adapter, ptp_caps);
363 struct e1000_hw *hw = &igb->hw; 467 struct e1000_hw *hw = &igb->hw;
468 u32 tsauxc, tsim, tsauxc_mask, tsim_mask, trgttiml, trgttimh;
364 unsigned long flags; 469 unsigned long flags;
365 u32 tsim; 470 struct timespec ts;
471 int pin;
472 s64 ns;
366 473
367 switch (rq->type) { 474 switch (rq->type) {
475 case PTP_CLK_REQ_EXTTS:
476 if (on) {
477 pin = ptp_find_pin(igb->ptp_clock, PTP_PF_EXTTS,
478 rq->extts.index);
479 if (pin < 0)
480 return -EBUSY;
481 }
482 if (rq->extts.index == 1) {
483 tsauxc_mask = TSAUXC_EN_TS1;
484 tsim_mask = TSINTR_AUTT1;
485 } else {
486 tsauxc_mask = TSAUXC_EN_TS0;
487 tsim_mask = TSINTR_AUTT0;
488 }
489 spin_lock_irqsave(&igb->tmreg_lock, flags);
490 tsauxc = rd32(E1000_TSAUXC);
491 tsim = rd32(E1000_TSIM);
492 if (on) {
493 igb_pin_extts(igb, rq->extts.index, pin);
494 tsauxc |= tsauxc_mask;
495 tsim |= tsim_mask;
496 } else {
497 tsauxc &= ~tsauxc_mask;
498 tsim &= ~tsim_mask;
499 }
500 wr32(E1000_TSAUXC, tsauxc);
501 wr32(E1000_TSIM, tsim);
502 spin_unlock_irqrestore(&igb->tmreg_lock, flags);
503 return 0;
504
505 case PTP_CLK_REQ_PEROUT:
506 if (on) {
507 pin = ptp_find_pin(igb->ptp_clock, PTP_PF_PEROUT,
508 rq->perout.index);
509 if (pin < 0)
510 return -EBUSY;
511 }
512 ts.tv_sec = rq->perout.period.sec;
513 ts.tv_nsec = rq->perout.period.nsec;
514 ns = timespec_to_ns(&ts);
515 ns = ns >> 1;
516 if (on && ns < 500000LL) {
517 /* 2k interrupts per second is an awful lot. */
518 return -EINVAL;
519 }
520 ts = ns_to_timespec(ns);
521 if (rq->perout.index == 1) {
522 tsauxc_mask = TSAUXC_EN_TT1;
523 tsim_mask = TSINTR_TT1;
524 trgttiml = E1000_TRGTTIML1;
525 trgttimh = E1000_TRGTTIMH1;
526 } else {
527 tsauxc_mask = TSAUXC_EN_TT0;
528 tsim_mask = TSINTR_TT0;
529 trgttiml = E1000_TRGTTIML0;
530 trgttimh = E1000_TRGTTIMH0;
531 }
532 spin_lock_irqsave(&igb->tmreg_lock, flags);
533 tsauxc = rd32(E1000_TSAUXC);
534 tsim = rd32(E1000_TSIM);
535 if (on) {
536 int i = rq->perout.index;
537
538 igb_pin_perout(igb, i, pin);
539 igb->perout[i].start.tv_sec = rq->perout.start.sec;
540 igb->perout[i].start.tv_nsec = rq->perout.start.nsec;
541 igb->perout[i].period.tv_sec = ts.tv_sec;
542 igb->perout[i].period.tv_nsec = ts.tv_nsec;
543 wr32(trgttiml, rq->perout.start.sec);
544 wr32(trgttimh, rq->perout.start.nsec);
545 tsauxc |= tsauxc_mask;
546 tsim |= tsim_mask;
547 } else {
548 tsauxc &= ~tsauxc_mask;
549 tsim &= ~tsim_mask;
550 }
551 wr32(E1000_TSAUXC, tsauxc);
552 wr32(E1000_TSIM, tsim);
553 spin_unlock_irqrestore(&igb->tmreg_lock, flags);
554 return 0;
555
368 case PTP_CLK_REQ_PPS: 556 case PTP_CLK_REQ_PPS:
369 spin_lock_irqsave(&igb->tmreg_lock, flags); 557 spin_lock_irqsave(&igb->tmreg_lock, flags);
370 tsim = rd32(E1000_TSIM); 558 tsim = rd32(E1000_TSIM);
@@ -375,9 +563,6 @@ static int igb_ptp_feature_enable_i210(struct ptp_clock_info *ptp,
375 wr32(E1000_TSIM, tsim); 563 wr32(E1000_TSIM, tsim);
376 spin_unlock_irqrestore(&igb->tmreg_lock, flags); 564 spin_unlock_irqrestore(&igb->tmreg_lock, flags);
377 return 0; 565 return 0;
378
379 default:
380 break;
381 } 566 }
382 567
383 return -EOPNOTSUPP; 568 return -EOPNOTSUPP;
@@ -389,6 +574,20 @@ static int igb_ptp_feature_enable(struct ptp_clock_info *ptp,
389 return -EOPNOTSUPP; 574 return -EOPNOTSUPP;
390} 575}
391 576
577static int igb_ptp_verify_pin(struct ptp_clock_info *ptp, unsigned int pin,
578 enum ptp_pin_function func, unsigned int chan)
579{
580 switch (func) {
581 case PTP_PF_NONE:
582 case PTP_PF_EXTTS:
583 case PTP_PF_PEROUT:
584 break;
585 case PTP_PF_PHYSYNC:
586 return -1;
587 }
588 return 0;
589}
590
392/** 591/**
393 * igb_ptp_tx_work 592 * igb_ptp_tx_work
394 * @work: pointer to work struct 593 * @work: pointer to work struct
@@ -779,6 +978,7 @@ void igb_ptp_init(struct igb_adapter *adapter)
779{ 978{
780 struct e1000_hw *hw = &adapter->hw; 979 struct e1000_hw *hw = &adapter->hw;
781 struct net_device *netdev = adapter->netdev; 980 struct net_device *netdev = adapter->netdev;
981 int i;
782 982
783 switch (hw->mac.type) { 983 switch (hw->mac.type) {
784 case e1000_82576: 984 case e1000_82576:
@@ -821,16 +1021,27 @@ void igb_ptp_init(struct igb_adapter *adapter)
821 break; 1021 break;
822 case e1000_i210: 1022 case e1000_i210:
823 case e1000_i211: 1023 case e1000_i211:
1024 for (i = 0; i < IGB_N_SDP; i++) {
1025 struct ptp_pin_desc *ppd = &adapter->sdp_config[i];
1026
1027 snprintf(ppd->name, sizeof(ppd->name), "SDP%d", i);
1028 ppd->index = i;
1029 ppd->func = PTP_PF_NONE;
1030 }
824 snprintf(adapter->ptp_caps.name, 16, "%pm", netdev->dev_addr); 1031 snprintf(adapter->ptp_caps.name, 16, "%pm", netdev->dev_addr);
825 adapter->ptp_caps.owner = THIS_MODULE; 1032 adapter->ptp_caps.owner = THIS_MODULE;
826 adapter->ptp_caps.max_adj = 62499999; 1033 adapter->ptp_caps.max_adj = 62499999;
827 adapter->ptp_caps.n_ext_ts = 0; 1034 adapter->ptp_caps.n_ext_ts = IGB_N_EXTTS;
1035 adapter->ptp_caps.n_per_out = IGB_N_PEROUT;
1036 adapter->ptp_caps.n_pins = IGB_N_SDP;
828 adapter->ptp_caps.pps = 1; 1037 adapter->ptp_caps.pps = 1;
1038 adapter->ptp_caps.pin_config = adapter->sdp_config;
829 adapter->ptp_caps.adjfreq = igb_ptp_adjfreq_82580; 1039 adapter->ptp_caps.adjfreq = igb_ptp_adjfreq_82580;
830 adapter->ptp_caps.adjtime = igb_ptp_adjtime_i210; 1040 adapter->ptp_caps.adjtime = igb_ptp_adjtime_i210;
831 adapter->ptp_caps.gettime = igb_ptp_gettime_i210; 1041 adapter->ptp_caps.gettime = igb_ptp_gettime_i210;
832 adapter->ptp_caps.settime = igb_ptp_settime_i210; 1042 adapter->ptp_caps.settime = igb_ptp_settime_i210;
833 adapter->ptp_caps.enable = igb_ptp_feature_enable_i210; 1043 adapter->ptp_caps.enable = igb_ptp_feature_enable_i210;
1044 adapter->ptp_caps.verify = igb_ptp_verify_pin;
834 /* Enable the timer functions by clearing bit 31. */ 1045 /* Enable the timer functions by clearing bit 31. */
835 wr32(E1000_TSAUXC, 0x0); 1046 wr32(E1000_TSAUXC, 0x0);
836 break; 1047 break;
@@ -949,6 +1160,7 @@ void igb_ptp_reset(struct igb_adapter *adapter)
949 case e1000_i210: 1160 case e1000_i210:
950 case e1000_i211: 1161 case e1000_i211:
951 wr32(E1000_TSAUXC, 0x0); 1162 wr32(E1000_TSAUXC, 0x0);
1163 wr32(E1000_TSSDP, 0x0);
952 wr32(E1000_TSIM, TSYNC_INTERRUPTS); 1164 wr32(E1000_TSIM, TSYNC_INTERRUPTS);
953 wr32(E1000_IMS, E1000_IMS_TS); 1165 wr32(E1000_IMS, E1000_IMS_TS);
954 break; 1166 break;