diff options
Diffstat (limited to 'drivers/net/ethernet/intel/igb')
-rw-r--r-- | drivers/net/ethernet/intel/igb/igb.h | 11 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/igb/igb_main.c | 157 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/igb/igb_ptp.c | 267 |
3 files changed, 367 insertions, 68 deletions
diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h index 82d891e183b1..c2bd4f98a837 100644 --- a/drivers/net/ethernet/intel/igb/igb.h +++ b/drivers/net/ethernet/intel/igb/igb.h | |||
@@ -29,7 +29,7 @@ | |||
29 | #include "e1000_mac.h" | 29 | #include "e1000_mac.h" |
30 | #include "e1000_82575.h" | 30 | #include "e1000_82575.h" |
31 | 31 | ||
32 | #include <linux/clocksource.h> | 32 | #include <linux/timecounter.h> |
33 | #include <linux/net_tstamp.h> | 33 | #include <linux/net_tstamp.h> |
34 | #include <linux/ptp_clock_kernel.h> | 34 | #include <linux/ptp_clock_kernel.h> |
35 | #include <linux/bitops.h> | 35 | #include <linux/bitops.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 ff59897a9463..f366b3b96d03 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c | |||
@@ -5035,9 +5035,9 @@ netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb, | |||
5035 | 5035 | ||
5036 | skb_tx_timestamp(skb); | 5036 | skb_tx_timestamp(skb); |
5037 | 5037 | ||
5038 | if (vlan_tx_tag_present(skb)) { | 5038 | if (skb_vlan_tag_present(skb)) { |
5039 | tx_flags |= IGB_TX_FLAGS_VLAN; | 5039 | tx_flags |= IGB_TX_FLAGS_VLAN; |
5040 | tx_flags |= (vlan_tx_tag_get(skb) << IGB_TX_FLAGS_VLAN_SHIFT); | 5040 | tx_flags |= (skb_vlan_tag_get(skb) << IGB_TX_FLAGS_VLAN_SHIFT); |
5041 | } | 5041 | } |
5042 | 5042 | ||
5043 | /* record initial flags and protocol */ | 5043 | /* record initial flags and protocol */ |
@@ -5384,6 +5384,80 @@ void igb_update_stats(struct igb_adapter *adapter, | |||
5384 | } | 5384 | } |
5385 | } | 5385 | } |
5386 | 5386 | ||
5387 | static void igb_tsync_interrupt(struct igb_adapter *adapter) | ||
5388 | { | ||
5389 | struct e1000_hw *hw = &adapter->hw; | ||
5390 | struct ptp_clock_event event; | ||
5391 | struct timespec ts; | ||
5392 | u32 ack = 0, tsauxc, sec, nsec, tsicr = rd32(E1000_TSICR); | ||
5393 | |||
5394 | if (tsicr & TSINTR_SYS_WRAP) { | ||
5395 | event.type = PTP_CLOCK_PPS; | ||
5396 | if (adapter->ptp_caps.pps) | ||
5397 | ptp_clock_event(adapter->ptp_clock, &event); | ||
5398 | else | ||
5399 | dev_err(&adapter->pdev->dev, "unexpected SYS WRAP"); | ||
5400 | ack |= TSINTR_SYS_WRAP; | ||
5401 | } | ||
5402 | |||
5403 | if (tsicr & E1000_TSICR_TXTS) { | ||
5404 | /* retrieve hardware timestamp */ | ||
5405 | schedule_work(&adapter->ptp_tx_work); | ||
5406 | ack |= E1000_TSICR_TXTS; | ||
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 | |||
5457 | /* acknowledge the interrupts */ | ||
5458 | wr32(E1000_TSICR, ack); | ||
5459 | } | ||
5460 | |||
5387 | static irqreturn_t igb_msix_other(int irq, void *data) | 5461 | static irqreturn_t igb_msix_other(int irq, void *data) |
5388 | { | 5462 | { |
5389 | struct igb_adapter *adapter = data; | 5463 | struct igb_adapter *adapter = data; |
@@ -5415,16 +5489,8 @@ static irqreturn_t igb_msix_other(int irq, void *data) | |||
5415 | mod_timer(&adapter->watchdog_timer, jiffies + 1); | 5489 | mod_timer(&adapter->watchdog_timer, jiffies + 1); |
5416 | } | 5490 | } |
5417 | 5491 | ||
5418 | if (icr & E1000_ICR_TS) { | 5492 | if (icr & E1000_ICR_TS) |
5419 | u32 tsicr = rd32(E1000_TSICR); | 5493 | igb_tsync_interrupt(adapter); |
5420 | |||
5421 | if (tsicr & E1000_TSICR_TXTS) { | ||
5422 | /* acknowledge the interrupt */ | ||
5423 | wr32(E1000_TSICR, E1000_TSICR_TXTS); | ||
5424 | /* retrieve hardware timestamp */ | ||
5425 | schedule_work(&adapter->ptp_tx_work); | ||
5426 | } | ||
5427 | } | ||
5428 | 5494 | ||
5429 | wr32(E1000_EIMS, adapter->eims_other); | 5495 | wr32(E1000_EIMS, adapter->eims_other); |
5430 | 5496 | ||
@@ -6011,8 +6077,12 @@ static void igb_vf_reset_msg(struct igb_adapter *adapter, u32 vf) | |||
6011 | adapter->vf_data[vf].flags |= IGB_VF_FLAG_CTS; | 6077 | adapter->vf_data[vf].flags |= IGB_VF_FLAG_CTS; |
6012 | 6078 | ||
6013 | /* reply to reset with ack and vf mac address */ | 6079 | /* reply to reset with ack and vf mac address */ |
6014 | msgbuf[0] = E1000_VF_RESET | E1000_VT_MSGTYPE_ACK; | 6080 | if (!is_zero_ether_addr(vf_mac)) { |
6015 | memcpy(addr, vf_mac, ETH_ALEN); | 6081 | msgbuf[0] = E1000_VF_RESET | E1000_VT_MSGTYPE_ACK; |
6082 | memcpy(addr, vf_mac, ETH_ALEN); | ||
6083 | } else { | ||
6084 | msgbuf[0] = E1000_VF_RESET | E1000_VT_MSGTYPE_NACK; | ||
6085 | } | ||
6016 | igb_write_mbx(hw, msgbuf, 3, vf); | 6086 | igb_write_mbx(hw, msgbuf, 3, vf); |
6017 | } | 6087 | } |
6018 | 6088 | ||
@@ -6203,16 +6273,8 @@ static irqreturn_t igb_intr_msi(int irq, void *data) | |||
6203 | mod_timer(&adapter->watchdog_timer, jiffies + 1); | 6273 | mod_timer(&adapter->watchdog_timer, jiffies + 1); |
6204 | } | 6274 | } |
6205 | 6275 | ||
6206 | if (icr & E1000_ICR_TS) { | 6276 | if (icr & E1000_ICR_TS) |
6207 | u32 tsicr = rd32(E1000_TSICR); | 6277 | igb_tsync_interrupt(adapter); |
6208 | |||
6209 | if (tsicr & E1000_TSICR_TXTS) { | ||
6210 | /* acknowledge the interrupt */ | ||
6211 | wr32(E1000_TSICR, E1000_TSICR_TXTS); | ||
6212 | /* retrieve hardware timestamp */ | ||
6213 | schedule_work(&adapter->ptp_tx_work); | ||
6214 | } | ||
6215 | } | ||
6216 | 6278 | ||
6217 | napi_schedule(&q_vector->napi); | 6279 | napi_schedule(&q_vector->napi); |
6218 | 6280 | ||
@@ -6257,16 +6319,8 @@ static irqreturn_t igb_intr(int irq, void *data) | |||
6257 | mod_timer(&adapter->watchdog_timer, jiffies + 1); | 6319 | mod_timer(&adapter->watchdog_timer, jiffies + 1); |
6258 | } | 6320 | } |
6259 | 6321 | ||
6260 | if (icr & E1000_ICR_TS) { | 6322 | if (icr & E1000_ICR_TS) |
6261 | u32 tsicr = rd32(E1000_TSICR); | 6323 | igb_tsync_interrupt(adapter); |
6262 | |||
6263 | if (tsicr & E1000_TSICR_TXTS) { | ||
6264 | /* acknowledge the interrupt */ | ||
6265 | wr32(E1000_TSICR, E1000_TSICR_TXTS); | ||
6266 | /* retrieve hardware timestamp */ | ||
6267 | schedule_work(&adapter->ptp_tx_work); | ||
6268 | } | ||
6269 | } | ||
6270 | 6324 | ||
6271 | napi_schedule(&q_vector->napi); | 6325 | napi_schedule(&q_vector->napi); |
6272 | 6326 | ||
@@ -6527,15 +6581,17 @@ static void igb_reuse_rx_page(struct igb_ring *rx_ring, | |||
6527 | DMA_FROM_DEVICE); | 6581 | DMA_FROM_DEVICE); |
6528 | } | 6582 | } |
6529 | 6583 | ||
6584 | static inline bool igb_page_is_reserved(struct page *page) | ||
6585 | { | ||
6586 | return (page_to_nid(page) != numa_mem_id()) || page->pfmemalloc; | ||
6587 | } | ||
6588 | |||
6530 | static bool igb_can_reuse_rx_page(struct igb_rx_buffer *rx_buffer, | 6589 | static bool igb_can_reuse_rx_page(struct igb_rx_buffer *rx_buffer, |
6531 | struct page *page, | 6590 | struct page *page, |
6532 | unsigned int truesize) | 6591 | unsigned int truesize) |
6533 | { | 6592 | { |
6534 | /* avoid re-using remote pages */ | 6593 | /* avoid re-using remote pages */ |
6535 | if (unlikely(page_to_nid(page) != numa_node_id())) | 6594 | if (unlikely(igb_page_is_reserved(page))) |
6536 | return false; | ||
6537 | |||
6538 | if (unlikely(page->pfmemalloc)) | ||
6539 | return false; | 6595 | return false; |
6540 | 6596 | ||
6541 | #if (PAGE_SIZE < 8192) | 6597 | #if (PAGE_SIZE < 8192) |
@@ -6545,22 +6601,19 @@ static bool igb_can_reuse_rx_page(struct igb_rx_buffer *rx_buffer, | |||
6545 | 6601 | ||
6546 | /* flip page offset to other buffer */ | 6602 | /* flip page offset to other buffer */ |
6547 | rx_buffer->page_offset ^= IGB_RX_BUFSZ; | 6603 | rx_buffer->page_offset ^= IGB_RX_BUFSZ; |
6548 | |||
6549 | /* Even if we own the page, we are not allowed to use atomic_set() | ||
6550 | * This would break get_page_unless_zero() users. | ||
6551 | */ | ||
6552 | atomic_inc(&page->_count); | ||
6553 | #else | 6604 | #else |
6554 | /* move offset up to the next cache line */ | 6605 | /* move offset up to the next cache line */ |
6555 | rx_buffer->page_offset += truesize; | 6606 | rx_buffer->page_offset += truesize; |
6556 | 6607 | ||
6557 | if (rx_buffer->page_offset > (PAGE_SIZE - IGB_RX_BUFSZ)) | 6608 | if (rx_buffer->page_offset > (PAGE_SIZE - IGB_RX_BUFSZ)) |
6558 | return false; | 6609 | return false; |
6559 | |||
6560 | /* bump ref count on page before it is given to the stack */ | ||
6561 | get_page(page); | ||
6562 | #endif | 6610 | #endif |
6563 | 6611 | ||
6612 | /* Even if we own the page, we are not allowed to use atomic_set() | ||
6613 | * This would break get_page_unless_zero() users. | ||
6614 | */ | ||
6615 | atomic_inc(&page->_count); | ||
6616 | |||
6564 | return true; | 6617 | return true; |
6565 | } | 6618 | } |
6566 | 6619 | ||
@@ -6603,13 +6656,12 @@ static bool igb_add_rx_frag(struct igb_ring *rx_ring, | |||
6603 | 6656 | ||
6604 | memcpy(__skb_put(skb, size), va, ALIGN(size, sizeof(long))); | 6657 | memcpy(__skb_put(skb, size), va, ALIGN(size, sizeof(long))); |
6605 | 6658 | ||
6606 | /* we can reuse buffer as-is, just make sure it is local */ | 6659 | /* page is not reserved, we can reuse buffer as-is */ |
6607 | if (likely((page_to_nid(page) == numa_node_id()) && | 6660 | if (likely(!igb_page_is_reserved(page))) |
6608 | !page->pfmemalloc)) | ||
6609 | return true; | 6661 | return true; |
6610 | 6662 | ||
6611 | /* this page cannot be reused so discard it */ | 6663 | /* this page cannot be reused so discard it */ |
6612 | put_page(page); | 6664 | __free_page(page); |
6613 | return false; | 6665 | return false; |
6614 | } | 6666 | } |
6615 | 6667 | ||
@@ -6627,7 +6679,6 @@ static struct sk_buff *igb_fetch_rx_buffer(struct igb_ring *rx_ring, | |||
6627 | struct page *page; | 6679 | struct page *page; |
6628 | 6680 | ||
6629 | rx_buffer = &rx_ring->rx_buffer_info[rx_ring->next_to_clean]; | 6681 | rx_buffer = &rx_ring->rx_buffer_info[rx_ring->next_to_clean]; |
6630 | |||
6631 | page = rx_buffer->page; | 6682 | page = rx_buffer->page; |
6632 | prefetchw(page); | 6683 | prefetchw(page); |
6633 | 6684 | ||
@@ -7042,8 +7093,8 @@ void igb_alloc_rx_buffers(struct igb_ring *rx_ring, u16 cleaned_count) | |||
7042 | i -= rx_ring->count; | 7093 | i -= rx_ring->count; |
7043 | } | 7094 | } |
7044 | 7095 | ||
7045 | /* clear the hdr_addr for the next_to_use descriptor */ | 7096 | /* clear the status bits for the next_to_use descriptor */ |
7046 | rx_desc->read.hdr_addr = 0; | 7097 | rx_desc->wb.upper.status_error = 0; |
7047 | 7098 | ||
7048 | cleaned_count--; | 7099 | cleaned_count--; |
7049 | } while (cleaned_count); | 7100 | } while (cleaned_count); |
diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c b/drivers/net/ethernet/intel/igb/igb_ptp.c index 794c139f0cc0..d20fc8ed11f1 100644 --- a/drivers/net/ethernet/intel/igb/igb_ptp.c +++ b/drivers/net/ethernet/intel/igb/igb_ptp.c | |||
@@ -256,14 +256,9 @@ static int igb_ptp_adjtime_82576(struct ptp_clock_info *ptp, s64 delta) | |||
256 | struct igb_adapter *igb = container_of(ptp, struct igb_adapter, | 256 | struct igb_adapter *igb = container_of(ptp, struct igb_adapter, |
257 | ptp_caps); | 257 | ptp_caps); |
258 | unsigned long flags; | 258 | unsigned long flags; |
259 | s64 now; | ||
260 | 259 | ||
261 | spin_lock_irqsave(&igb->tmreg_lock, flags); | 260 | spin_lock_irqsave(&igb->tmreg_lock, flags); |
262 | 261 | timecounter_adjtime(&igb->tc, delta); | |
263 | now = timecounter_read(&igb->tc); | ||
264 | now += delta; | ||
265 | timecounter_init(&igb->tc, &igb->cc, now); | ||
266 | |||
267 | spin_unlock_irqrestore(&igb->tmreg_lock, flags); | 262 | spin_unlock_irqrestore(&igb->tmreg_lock, flags); |
268 | 263 | ||
269 | return 0; | 264 | return 0; |
@@ -360,12 +355,239 @@ static int igb_ptp_settime_i210(struct ptp_clock_info *ptp, | |||
360 | return 0; | 355 | return 0; |
361 | } | 356 | } |
362 | 357 | ||
358 | static 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 | |||
374 | static 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 | |||
410 | static 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 | |||
462 | static int igb_ptp_feature_enable_i210(struct ptp_clock_info *ptp, | ||
463 | struct ptp_clock_request *rq, int on) | ||
464 | { | ||
465 | struct igb_adapter *igb = | ||
466 | container_of(ptp, struct igb_adapter, ptp_caps); | ||
467 | struct e1000_hw *hw = &igb->hw; | ||
468 | u32 tsauxc, tsim, tsauxc_mask, tsim_mask, trgttiml, trgttimh; | ||
469 | unsigned long flags; | ||
470 | struct timespec ts; | ||
471 | int pin; | ||
472 | s64 ns; | ||
473 | |||
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 | |||
556 | case PTP_CLK_REQ_PPS: | ||
557 | spin_lock_irqsave(&igb->tmreg_lock, flags); | ||
558 | tsim = rd32(E1000_TSIM); | ||
559 | if (on) | ||
560 | tsim |= TSINTR_SYS_WRAP; | ||
561 | else | ||
562 | tsim &= ~TSINTR_SYS_WRAP; | ||
563 | wr32(E1000_TSIM, tsim); | ||
564 | spin_unlock_irqrestore(&igb->tmreg_lock, flags); | ||
565 | return 0; | ||
566 | } | ||
567 | |||
568 | return -EOPNOTSUPP; | ||
569 | } | ||
570 | |||
363 | static int igb_ptp_feature_enable(struct ptp_clock_info *ptp, | 571 | static int igb_ptp_feature_enable(struct ptp_clock_info *ptp, |
364 | struct ptp_clock_request *rq, int on) | 572 | struct ptp_clock_request *rq, int on) |
365 | { | 573 | { |
366 | return -EOPNOTSUPP; | 574 | return -EOPNOTSUPP; |
367 | } | 575 | } |
368 | 576 | ||
577 | static 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 | |||
369 | /** | 591 | /** |
370 | * igb_ptp_tx_work | 592 | * igb_ptp_tx_work |
371 | * @work: pointer to work struct | 593 | * @work: pointer to work struct |
@@ -756,6 +978,7 @@ void igb_ptp_init(struct igb_adapter *adapter) | |||
756 | { | 978 | { |
757 | struct e1000_hw *hw = &adapter->hw; | 979 | struct e1000_hw *hw = &adapter->hw; |
758 | struct net_device *netdev = adapter->netdev; | 980 | struct net_device *netdev = adapter->netdev; |
981 | int i; | ||
759 | 982 | ||
760 | switch (hw->mac.type) { | 983 | switch (hw->mac.type) { |
761 | case e1000_82576: | 984 | case e1000_82576: |
@@ -770,7 +993,7 @@ void igb_ptp_init(struct igb_adapter *adapter) | |||
770 | adapter->ptp_caps.settime = igb_ptp_settime_82576; | 993 | adapter->ptp_caps.settime = igb_ptp_settime_82576; |
771 | adapter->ptp_caps.enable = igb_ptp_feature_enable; | 994 | adapter->ptp_caps.enable = igb_ptp_feature_enable; |
772 | adapter->cc.read = igb_ptp_read_82576; | 995 | adapter->cc.read = igb_ptp_read_82576; |
773 | adapter->cc.mask = CLOCKSOURCE_MASK(64); | 996 | adapter->cc.mask = CYCLECOUNTER_MASK(64); |
774 | adapter->cc.mult = 1; | 997 | adapter->cc.mult = 1; |
775 | adapter->cc.shift = IGB_82576_TSYNC_SHIFT; | 998 | adapter->cc.shift = IGB_82576_TSYNC_SHIFT; |
776 | /* Dial the nominal frequency. */ | 999 | /* Dial the nominal frequency. */ |
@@ -790,7 +1013,7 @@ void igb_ptp_init(struct igb_adapter *adapter) | |||
790 | adapter->ptp_caps.settime = igb_ptp_settime_82576; | 1013 | adapter->ptp_caps.settime = igb_ptp_settime_82576; |
791 | adapter->ptp_caps.enable = igb_ptp_feature_enable; | 1014 | adapter->ptp_caps.enable = igb_ptp_feature_enable; |
792 | adapter->cc.read = igb_ptp_read_82580; | 1015 | adapter->cc.read = igb_ptp_read_82580; |
793 | adapter->cc.mask = CLOCKSOURCE_MASK(IGB_NBITS_82580); | 1016 | adapter->cc.mask = CYCLECOUNTER_MASK(IGB_NBITS_82580); |
794 | adapter->cc.mult = 1; | 1017 | adapter->cc.mult = 1; |
795 | adapter->cc.shift = 0; | 1018 | adapter->cc.shift = 0; |
796 | /* Enable the timer functions by clearing bit 31. */ | 1019 | /* Enable the timer functions by clearing bit 31. */ |
@@ -798,16 +1021,27 @@ void igb_ptp_init(struct igb_adapter *adapter) | |||
798 | break; | 1021 | break; |
799 | case e1000_i210: | 1022 | case e1000_i210: |
800 | 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 | } | ||
801 | snprintf(adapter->ptp_caps.name, 16, "%pm", netdev->dev_addr); | 1031 | snprintf(adapter->ptp_caps.name, 16, "%pm", netdev->dev_addr); |
802 | adapter->ptp_caps.owner = THIS_MODULE; | 1032 | adapter->ptp_caps.owner = THIS_MODULE; |
803 | adapter->ptp_caps.max_adj = 62499999; | 1033 | adapter->ptp_caps.max_adj = 62499999; |
804 | adapter->ptp_caps.n_ext_ts = 0; | 1034 | adapter->ptp_caps.n_ext_ts = IGB_N_EXTTS; |
805 | adapter->ptp_caps.pps = 0; | 1035 | adapter->ptp_caps.n_per_out = IGB_N_PEROUT; |
1036 | adapter->ptp_caps.n_pins = IGB_N_SDP; | ||
1037 | adapter->ptp_caps.pps = 1; | ||
1038 | adapter->ptp_caps.pin_config = adapter->sdp_config; | ||
806 | adapter->ptp_caps.adjfreq = igb_ptp_adjfreq_82580; | 1039 | adapter->ptp_caps.adjfreq = igb_ptp_adjfreq_82580; |
807 | adapter->ptp_caps.adjtime = igb_ptp_adjtime_i210; | 1040 | adapter->ptp_caps.adjtime = igb_ptp_adjtime_i210; |
808 | adapter->ptp_caps.gettime = igb_ptp_gettime_i210; | 1041 | adapter->ptp_caps.gettime = igb_ptp_gettime_i210; |
809 | adapter->ptp_caps.settime = igb_ptp_settime_i210; | 1042 | adapter->ptp_caps.settime = igb_ptp_settime_i210; |
810 | adapter->ptp_caps.enable = igb_ptp_feature_enable; | 1043 | adapter->ptp_caps.enable = igb_ptp_feature_enable_i210; |
1044 | adapter->ptp_caps.verify = igb_ptp_verify_pin; | ||
811 | /* Enable the timer functions by clearing bit 31. */ | 1045 | /* Enable the timer functions by clearing bit 31. */ |
812 | wr32(E1000_TSAUXC, 0x0); | 1046 | wr32(E1000_TSAUXC, 0x0); |
813 | break; | 1047 | break; |
@@ -905,6 +1139,7 @@ void igb_ptp_stop(struct igb_adapter *adapter) | |||
905 | void igb_ptp_reset(struct igb_adapter *adapter) | 1139 | void igb_ptp_reset(struct igb_adapter *adapter) |
906 | { | 1140 | { |
907 | struct e1000_hw *hw = &adapter->hw; | 1141 | struct e1000_hw *hw = &adapter->hw; |
1142 | unsigned long flags; | ||
908 | 1143 | ||
909 | if (!(adapter->flags & IGB_FLAG_PTP)) | 1144 | if (!(adapter->flags & IGB_FLAG_PTP)) |
910 | return; | 1145 | return; |
@@ -912,6 +1147,8 @@ void igb_ptp_reset(struct igb_adapter *adapter) | |||
912 | /* reset the tstamp_config */ | 1147 | /* reset the tstamp_config */ |
913 | igb_ptp_set_timestamp_mode(adapter, &adapter->tstamp_config); | 1148 | igb_ptp_set_timestamp_mode(adapter, &adapter->tstamp_config); |
914 | 1149 | ||
1150 | spin_lock_irqsave(&adapter->tmreg_lock, flags); | ||
1151 | |||
915 | switch (adapter->hw.mac.type) { | 1152 | switch (adapter->hw.mac.type) { |
916 | case e1000_82576: | 1153 | case e1000_82576: |
917 | /* Dial the nominal frequency. */ | 1154 | /* Dial the nominal frequency. */ |
@@ -922,23 +1159,25 @@ void igb_ptp_reset(struct igb_adapter *adapter) | |||
922 | case e1000_i350: | 1159 | case e1000_i350: |
923 | case e1000_i210: | 1160 | case e1000_i210: |
924 | case e1000_i211: | 1161 | case e1000_i211: |
925 | /* Enable the timer functions and interrupts. */ | ||
926 | wr32(E1000_TSAUXC, 0x0); | 1162 | wr32(E1000_TSAUXC, 0x0); |
1163 | wr32(E1000_TSSDP, 0x0); | ||
927 | wr32(E1000_TSIM, TSYNC_INTERRUPTS); | 1164 | wr32(E1000_TSIM, TSYNC_INTERRUPTS); |
928 | wr32(E1000_IMS, E1000_IMS_TS); | 1165 | wr32(E1000_IMS, E1000_IMS_TS); |
929 | break; | 1166 | break; |
930 | default: | 1167 | default: |
931 | /* No work to do. */ | 1168 | /* No work to do. */ |
932 | return; | 1169 | goto out; |
933 | } | 1170 | } |
934 | 1171 | ||
935 | /* Re-initialize the timer. */ | 1172 | /* Re-initialize the timer. */ |
936 | if ((hw->mac.type == e1000_i210) || (hw->mac.type == e1000_i211)) { | 1173 | if ((hw->mac.type == e1000_i210) || (hw->mac.type == e1000_i211)) { |
937 | struct timespec ts = ktime_to_timespec(ktime_get_real()); | 1174 | struct timespec ts = ktime_to_timespec(ktime_get_real()); |
938 | 1175 | ||
939 | igb_ptp_settime_i210(&adapter->ptp_caps, &ts); | 1176 | igb_ptp_write_i210(adapter, &ts); |
940 | } else { | 1177 | } else { |
941 | timecounter_init(&adapter->tc, &adapter->cc, | 1178 | timecounter_init(&adapter->tc, &adapter->cc, |
942 | ktime_to_ns(ktime_get_real())); | 1179 | ktime_to_ns(ktime_get_real())); |
943 | } | 1180 | } |
1181 | out: | ||
1182 | spin_unlock_irqrestore(&adapter->tmreg_lock, flags); | ||
944 | } | 1183 | } |