aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2015-06-18 06:57:44 -0400
committerDavid S. Miller <davem@davemloft.net>2015-06-18 06:58:55 -0400
commitb67ea97fcd4e29c97ced1ecba15443ecfce395b1 (patch)
tree20650c580b1f392d54e802c8d2af69255aea5739
parentd42202dce002ce0417448d11a091b4da21cacbd1 (diff)
parent986eec4341729549778f374dfc97e69a991302df (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-queue
Jeff Kirsher says: ==================== This series contains updates to fm10k only. Alex provides two fixes for the fm10k, first folds the fm10k_pull_tail() call into fm10k_add_rx_frag(), this way the fragment does not have to be modified after it is added to the skb. The second fixes missing braces to an if statement. The remaining patches are from Jacob which contain improvements and fixes for fm10k. First fix makes it so that invalid address will simply be skipped and allows synchronizing the full list to proceed with using iproute2 tool. Fixed a possible kernel panic by using the correct transmit timestamp function. Simplified the code flow for setting the IN_PROGRESS bit of the shinfo for an skb that we will be timestamping. Fix a bug in the timestamping transmit enqueue code responsible for a NULL pointer dereference and invalid access of the skb list by freeing the clone in the cases where we did not add it to the queue. Update the PF code so that it resets the empty TQMAP/RQMAP regirsters post-VFLR to prevent innocent VF drivers from triggering malicious driver events. The SYSTIME_CFG.Adjust direction bit is actually supposed to indicate that the adjustment is positive, so fix the code to align correctly with the hardware and documentation. Cleanup local variable that is no longer used after a previous refactor of the code. Fix the code flow so that we actually clear the enabled flag as part of our removal of the LPORT. v2: - updated patch 07 description based on feedback from Sergei Shtylyov - updated patch 09 & 10 to use %d in error message based on feedback from Sergei Shtylyov ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c5
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_iov.c38
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_main.c66
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_mbx.c5
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_netdev.c11
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_pci.c27
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_pf.c18
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_pf.h8
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_ptp.c13
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_type.h2
10 files changed, 84 insertions, 109 deletions
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c b/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c
index 4b9d9f88af70..c6dc9683429e 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c
@@ -124,7 +124,7 @@ static void fm10k_get_strings(struct net_device *dev, u32 stringset, u8 *data)
124{ 124{
125 struct fm10k_intfc *interface = netdev_priv(dev); 125 struct fm10k_intfc *interface = netdev_priv(dev);
126 char *p = (char *)data; 126 char *p = (char *)data;
127 int i; 127 unsigned int i;
128 128
129 switch (stringset) { 129 switch (stringset) {
130 case ETH_SS_TEST: 130 case ETH_SS_TEST:
@@ -143,12 +143,13 @@ static void fm10k_get_strings(struct net_device *dev, u32 stringset, u8 *data)
143 p += ETH_GSTRING_LEN; 143 p += ETH_GSTRING_LEN;
144 } 144 }
145 145
146 if (interface->hw.mac.type != fm10k_mac_vf) 146 if (interface->hw.mac.type != fm10k_mac_vf) {
147 for (i = 0; i < FM10K_PF_STATS_LEN; i++) { 147 for (i = 0; i < FM10K_PF_STATS_LEN; i++) {
148 memcpy(p, fm10k_gstrings_pf_stats[i].stat_string, 148 memcpy(p, fm10k_gstrings_pf_stats[i].stat_string,
149 ETH_GSTRING_LEN); 149 ETH_GSTRING_LEN);
150 p += ETH_GSTRING_LEN; 150 p += ETH_GSTRING_LEN;
151 } 151 }
152 }
152 153
153 for (i = 0; i < interface->hw.mac.max_queues; i++) { 154 for (i = 0; i < interface->hw.mac.max_queues; i++) {
154 sprintf(p, "tx_queue_%u_packets", i); 155 sprintf(p, "tx_queue_%u_packets", i);
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_iov.c b/drivers/net/ethernet/intel/fm10k/fm10k_iov.c
index 5b08e6284a3c..94571e6e790c 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_iov.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_iov.c
@@ -400,11 +400,31 @@ int fm10k_iov_configure(struct pci_dev *pdev, int num_vfs)
400 return num_vfs; 400 return num_vfs;
401} 401}
402 402
403static inline void fm10k_reset_vf_info(struct fm10k_intfc *interface,
404 struct fm10k_vf_info *vf_info)
405{
406 struct fm10k_hw *hw = &interface->hw;
407
408 /* assigning the MAC address will send a mailbox message */
409 fm10k_mbx_lock(interface);
410
411 /* disable LPORT for this VF which clears switch rules */
412 hw->iov.ops.reset_lport(hw, vf_info);
413
414 /* assign new MAC+VLAN for this VF */
415 hw->iov.ops.assign_default_mac_vlan(hw, vf_info);
416
417 /* re-enable the LPORT for this VF */
418 hw->iov.ops.set_lport(hw, vf_info, vf_info->vf_idx,
419 FM10K_VF_FLAG_MULTI_CAPABLE);
420
421 fm10k_mbx_unlock(interface);
422}
423
403int fm10k_ndo_set_vf_mac(struct net_device *netdev, int vf_idx, u8 *mac) 424int fm10k_ndo_set_vf_mac(struct net_device *netdev, int vf_idx, u8 *mac)
404{ 425{
405 struct fm10k_intfc *interface = netdev_priv(netdev); 426 struct fm10k_intfc *interface = netdev_priv(netdev);
406 struct fm10k_iov_data *iov_data = interface->iov_data; 427 struct fm10k_iov_data *iov_data = interface->iov_data;
407 struct fm10k_hw *hw = &interface->hw;
408 struct fm10k_vf_info *vf_info; 428 struct fm10k_vf_info *vf_info;
409 429
410 /* verify SR-IOV is active and that vf idx is valid */ 430 /* verify SR-IOV is active and that vf idx is valid */
@@ -419,13 +439,7 @@ int fm10k_ndo_set_vf_mac(struct net_device *netdev, int vf_idx, u8 *mac)
419 vf_info = &iov_data->vf_info[vf_idx]; 439 vf_info = &iov_data->vf_info[vf_idx];
420 ether_addr_copy(vf_info->mac, mac); 440 ether_addr_copy(vf_info->mac, mac);
421 441
422 /* assigning the MAC will send a mailbox message so lock is needed */ 442 fm10k_reset_vf_info(interface, vf_info);
423 fm10k_mbx_lock(interface);
424
425 /* assign MAC address to VF */
426 hw->iov.ops.assign_default_mac_vlan(hw, vf_info);
427
428 fm10k_mbx_unlock(interface);
429 443
430 return 0; 444 return 0;
431} 445}
@@ -455,16 +469,10 @@ int fm10k_ndo_set_vf_vlan(struct net_device *netdev, int vf_idx, u16 vid,
455 /* record default VLAN ID for VF */ 469 /* record default VLAN ID for VF */
456 vf_info->pf_vid = vid; 470 vf_info->pf_vid = vid;
457 471
458 /* assigning the VLAN will send a mailbox message so lock is needed */
459 fm10k_mbx_lock(interface);
460
461 /* Clear the VLAN table for the VF */ 472 /* Clear the VLAN table for the VF */
462 hw->mac.ops.update_vlan(hw, FM10K_VLAN_ALL, vf_info->vsi, false); 473 hw->mac.ops.update_vlan(hw, FM10K_VLAN_ALL, vf_info->vsi, false);
463 474
464 /* Update VF assignment and trigger reset */ 475 fm10k_reset_vf_info(interface, vf_info);
465 hw->iov.ops.assign_default_mac_vlan(hw, vf_info);
466
467 fm10k_mbx_unlock(interface);
468 476
469 return 0; 477 return 0;
470} 478}
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_main.c b/drivers/net/ethernet/intel/fm10k/fm10k_main.c
index c754b2027281..982fdcdc795b 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_main.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_main.c
@@ -269,16 +269,19 @@ static bool fm10k_add_rx_frag(struct fm10k_rx_buffer *rx_buffer,
269 struct sk_buff *skb) 269 struct sk_buff *skb)
270{ 270{
271 struct page *page = rx_buffer->page; 271 struct page *page = rx_buffer->page;
272 unsigned char *va = page_address(page) + rx_buffer->page_offset;
272 unsigned int size = le16_to_cpu(rx_desc->w.length); 273 unsigned int size = le16_to_cpu(rx_desc->w.length);
273#if (PAGE_SIZE < 8192) 274#if (PAGE_SIZE < 8192)
274 unsigned int truesize = FM10K_RX_BUFSZ; 275 unsigned int truesize = FM10K_RX_BUFSZ;
275#else 276#else
276 unsigned int truesize = ALIGN(size, L1_CACHE_BYTES); 277 unsigned int truesize = SKB_DATA_ALIGN(size);
277#endif 278#endif
279 unsigned int pull_len;
278 280
279 if ((size <= FM10K_RX_HDR_LEN) && !skb_is_nonlinear(skb)) { 281 if (unlikely(skb_is_nonlinear(skb)))
280 unsigned char *va = page_address(page) + rx_buffer->page_offset; 282 goto add_tail_frag;
281 283
284 if (likely(size <= FM10K_RX_HDR_LEN)) {
282 memcpy(__skb_put(skb, size), va, ALIGN(size, sizeof(long))); 285 memcpy(__skb_put(skb, size), va, ALIGN(size, sizeof(long)));
283 286
284 /* page is not reserved, we can reuse buffer as-is */ 287 /* page is not reserved, we can reuse buffer as-is */
@@ -290,8 +293,21 @@ static bool fm10k_add_rx_frag(struct fm10k_rx_buffer *rx_buffer,
290 return false; 293 return false;
291 } 294 }
292 295
296 /* we need the header to contain the greater of either ETH_HLEN or
297 * 60 bytes if the skb->len is less than 60 for skb_pad.
298 */
299 pull_len = eth_get_headlen(va, FM10K_RX_HDR_LEN);
300
301 /* align pull length to size of long to optimize memcpy performance */
302 memcpy(__skb_put(skb, pull_len), va, ALIGN(pull_len, sizeof(long)));
303
304 /* update all of the pointers */
305 va += pull_len;
306 size -= pull_len;
307
308add_tail_frag:
293 skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page, 309 skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
294 rx_buffer->page_offset, size, truesize); 310 (unsigned long)va & ~PAGE_MASK, size, truesize);
295 311
296 return fm10k_can_reuse_rx_page(rx_buffer, page, truesize); 312 return fm10k_can_reuse_rx_page(rx_buffer, page, truesize);
297} 313}
@@ -518,44 +534,6 @@ static bool fm10k_is_non_eop(struct fm10k_ring *rx_ring,
518} 534}
519 535
520/** 536/**
521 * fm10k_pull_tail - fm10k specific version of skb_pull_tail
522 * @skb: pointer to current skb being adjusted
523 *
524 * This function is an fm10k specific version of __pskb_pull_tail. The
525 * main difference between this version and the original function is that
526 * this function can make several assumptions about the state of things
527 * that allow for significant optimizations versus the standard function.
528 * As a result we can do things like drop a frag and maintain an accurate
529 * truesize for the skb.
530 */
531static void fm10k_pull_tail(struct sk_buff *skb)
532{
533 struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[0];
534 unsigned char *va;
535 unsigned int pull_len;
536
537 /* it is valid to use page_address instead of kmap since we are
538 * working with pages allocated out of the lomem pool per
539 * alloc_page(GFP_ATOMIC)
540 */
541 va = skb_frag_address(frag);
542
543 /* we need the header to contain the greater of either ETH_HLEN or
544 * 60 bytes if the skb->len is less than 60 for skb_pad.
545 */
546 pull_len = eth_get_headlen(va, FM10K_RX_HDR_LEN);
547
548 /* align pull length to size of long to optimize memcpy performance */
549 skb_copy_to_linear_data(skb, va, ALIGN(pull_len, sizeof(long)));
550
551 /* update all of the pointers */
552 skb_frag_size_sub(frag, pull_len);
553 frag->page_offset += pull_len;
554 skb->data_len -= pull_len;
555 skb->tail += pull_len;
556}
557
558/**
559 * fm10k_cleanup_headers - Correct corrupted or empty headers 537 * fm10k_cleanup_headers - Correct corrupted or empty headers
560 * @rx_ring: rx descriptor ring packet is being transacted on 538 * @rx_ring: rx descriptor ring packet is being transacted on
561 * @rx_desc: pointer to the EOP Rx descriptor 539 * @rx_desc: pointer to the EOP Rx descriptor
@@ -580,10 +558,6 @@ static bool fm10k_cleanup_headers(struct fm10k_ring *rx_ring,
580 return true; 558 return true;
581 } 559 }
582 560
583 /* place header in linear portion of buffer */
584 if (skb_is_nonlinear(skb))
585 fm10k_pull_tail(skb);
586
587 /* if eth_skb_pad returns an error the skb was freed */ 561 /* if eth_skb_pad returns an error the skb was freed */
588 if (eth_skb_pad(skb)) 562 if (eth_skb_pad(skb))
589 return true; 563 return true;
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_mbx.c b/drivers/net/ethernet/intel/fm10k/fm10k_mbx.c
index 1b2738380518..1a4b52637de9 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_mbx.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_mbx.c
@@ -1259,16 +1259,11 @@ static s32 fm10k_mbx_process_error(struct fm10k_hw *hw,
1259 struct fm10k_mbx_info *mbx) 1259 struct fm10k_mbx_info *mbx)
1260{ 1260{
1261 const u32 *hdr = &mbx->mbx_hdr; 1261 const u32 *hdr = &mbx->mbx_hdr;
1262 s32 err_no;
1263 u16 head; 1262 u16 head;
1264 1263
1265 /* we will need to pull all of the fields for verification */ 1264 /* we will need to pull all of the fields for verification */
1266 head = FM10K_MSG_HDR_FIELD_GET(*hdr, HEAD); 1265 head = FM10K_MSG_HDR_FIELD_GET(*hdr, HEAD);
1267 1266
1268 /* we only have lower 10 bits of error number so add upper bits */
1269 err_no = FM10K_MSG_HDR_FIELD_GET(*hdr, ERR_NO);
1270 err_no |= ~FM10K_MSG_HDR_MASK(ERR_NO);
1271
1272 switch (mbx->state) { 1267 switch (mbx->state) {
1273 case FM10K_STATE_OPEN: 1268 case FM10K_STATE_OPEN:
1274 case FM10K_STATE_DISCONNECT: 1269 case FM10K_STATE_DISCONNECT:
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c
index 2f4f41b7eae7..99228bf46c12 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c
@@ -923,18 +923,12 @@ static int __fm10k_mc_sync(struct net_device *dev,
923 struct fm10k_intfc *interface = netdev_priv(dev); 923 struct fm10k_intfc *interface = netdev_priv(dev);
924 struct fm10k_hw *hw = &interface->hw; 924 struct fm10k_hw *hw = &interface->hw;
925 u16 vid, glort = interface->glort; 925 u16 vid, glort = interface->glort;
926 s32 err;
927
928 if (!is_multicast_ether_addr(addr))
929 return -EADDRNOTAVAIL;
930 926
931 /* update table with current entries */ 927 /* update table with current entries */
932 for (vid = hw->mac.default_vid ? fm10k_find_next_vlan(interface, 0) : 0; 928 for (vid = hw->mac.default_vid ? fm10k_find_next_vlan(interface, 0) : 0;
933 vid < VLAN_N_VID; 929 vid < VLAN_N_VID;
934 vid = fm10k_find_next_vlan(interface, vid)) { 930 vid = fm10k_find_next_vlan(interface, vid)) {
935 err = hw->mac.ops.update_mc_addr(hw, glort, addr, vid, sync); 931 hw->mac.ops.update_mc_addr(hw, glort, addr, vid, sync);
936 if (err)
937 return err;
938 } 932 }
939 933
940 return 0; 934 return 0;
@@ -1339,8 +1333,7 @@ static void fm10k_dfwd_del_station(struct net_device *dev, void *priv)
1339 dglort.rss_l = fls(interface->ring_feature[RING_F_RSS].mask); 1333 dglort.rss_l = fls(interface->ring_feature[RING_F_RSS].mask);
1340 dglort.pc_l = fls(interface->ring_feature[RING_F_QOS].mask); 1334 dglort.pc_l = fls(interface->ring_feature[RING_F_QOS].mask);
1341 dglort.glort = interface->glort; 1335 dglort.glort = interface->glort;
1342 if (l2_accel) 1336 dglort.shared_l = fls(l2_accel->size);
1343 dglort.shared_l = fls(l2_accel->size);
1344 hw->mac.ops.configure_dglort_map(hw, &dglort); 1337 hw->mac.ops.configure_dglort_map(hw, &dglort);
1345 1338
1346 /* If table is empty remove it */ 1339 /* If table is empty remove it */
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c
index df9fda38bdd1..ce53ff25f88d 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c
@@ -1559,6 +1559,7 @@ void fm10k_down(struct fm10k_intfc *interface)
1559 1559
1560 /* free any buffers still on the rings */ 1560 /* free any buffers still on the rings */
1561 fm10k_clean_all_tx_rings(interface); 1561 fm10k_clean_all_tx_rings(interface);
1562 fm10k_clean_all_rx_rings(interface);
1562} 1563}
1563 1564
1564/** 1565/**
@@ -1740,30 +1741,18 @@ static int fm10k_probe(struct pci_dev *pdev,
1740 struct fm10k_intfc *interface; 1741 struct fm10k_intfc *interface;
1741 struct fm10k_hw *hw; 1742 struct fm10k_hw *hw;
1742 int err; 1743 int err;
1743 u64 dma_mask;
1744 1744
1745 err = pci_enable_device_mem(pdev); 1745 err = pci_enable_device_mem(pdev);
1746 if (err) 1746 if (err)
1747 return err; 1747 return err;
1748 1748
1749 /* By default fm10k only supports a 48 bit DMA mask */ 1749 err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(48));
1750 dma_mask = DMA_BIT_MASK(48) | dma_get_required_mask(&pdev->dev); 1750 if (err)
1751
1752 if ((dma_mask <= DMA_BIT_MASK(32)) ||
1753 dma_set_mask_and_coherent(&pdev->dev, dma_mask)) {
1754 dma_mask &= DMA_BIT_MASK(32);
1755
1756 err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); 1751 err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
1757 err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); 1752 if (err) {
1758 if (err) { 1753 dev_err(&pdev->dev,
1759 err = dma_set_coherent_mask(&pdev->dev, 1754 "DMA configuration failed: %d\n", err);
1760 DMA_BIT_MASK(32)); 1755 goto err_dma;
1761 if (err) {
1762 dev_err(&pdev->dev,
1763 "No usable DMA configuration, aborting\n");
1764 goto err_dma;
1765 }
1766 }
1767 } 1756 }
1768 1757
1769 err = pci_request_selected_regions(pdev, 1758 err = pci_request_selected_regions(pdev,
@@ -1772,7 +1761,7 @@ static int fm10k_probe(struct pci_dev *pdev,
1772 fm10k_driver_name); 1761 fm10k_driver_name);
1773 if (err) { 1762 if (err) {
1774 dev_err(&pdev->dev, 1763 dev_err(&pdev->dev,
1775 "pci_request_selected_regions failed 0x%x\n", err); 1764 "pci_request_selected_regions failed: %d\n", err);
1776 goto err_pci_reg; 1765 goto err_pci_reg;
1777 } 1766 }
1778 1767
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_pf.c b/drivers/net/ethernet/intel/fm10k/fm10k_pf.c
index 891e21874b2a..3ca0233b3ea2 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_pf.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_pf.c
@@ -1046,6 +1046,12 @@ static s32 fm10k_iov_reset_resources_pf(struct fm10k_hw *hw,
1046 fm10k_write_reg(hw, FM10K_RQMAP(qmap_idx + i), vf_q_idx + i); 1046 fm10k_write_reg(hw, FM10K_RQMAP(qmap_idx + i), vf_q_idx + i);
1047 } 1047 }
1048 1048
1049 /* repeat the first ring for all the remaining VF rings */
1050 for (i = queues_per_pool; i < qmap_stride; i++) {
1051 fm10k_write_reg(hw, FM10K_TQMAP(qmap_idx + i), vf_q_idx);
1052 fm10k_write_reg(hw, FM10K_RQMAP(qmap_idx + i), vf_q_idx);
1053 }
1054
1049 return 0; 1055 return 0;
1050} 1056}
1051 1057
@@ -1345,6 +1351,14 @@ s32 fm10k_iov_msg_lport_state_pf(struct fm10k_hw *hw, u32 **results,
1345 err = fm10k_update_lport_state_pf(hw, vf_info->glort, 1351 err = fm10k_update_lport_state_pf(hw, vf_info->glort,
1346 1, false); 1352 1, false);
1347 1353
1354 /* we need to clear VF_FLAG_ENABLED flags in order to ensure
1355 * that we actually re-enable the LPORT state below. Note that
1356 * this has no impact if the VF is already disabled, as the
1357 * flags are already cleared.
1358 */
1359 if (!err)
1360 vf_info->vf_flags = FM10K_VF_FLAG_CAPABLE(vf_info);
1361
1348 /* when enabling the port we should reset the rate limiters */ 1362 /* when enabling the port we should reset the rate limiters */
1349 hw->iov.ops.configure_tc(hw, vf_info->vf_idx, vf_info->rate); 1363 hw->iov.ops.configure_tc(hw, vf_info->vf_idx, vf_info->rate);
1350 1364
@@ -1786,8 +1800,8 @@ static s32 fm10k_adjust_systime_pf(struct fm10k_hw *hw, s32 ppb)
1786 if (systime_adjust > FM10K_SW_SYSTIME_ADJUST_MASK) 1800 if (systime_adjust > FM10K_SW_SYSTIME_ADJUST_MASK)
1787 return FM10K_ERR_PARAM; 1801 return FM10K_ERR_PARAM;
1788 1802
1789 if (ppb < 0) 1803 if (ppb > 0)
1790 systime_adjust |= FM10K_SW_SYSTIME_ADJUST_DIR_NEGATIVE; 1804 systime_adjust |= FM10K_SW_SYSTIME_ADJUST_DIR_POSITIVE;
1791 1805
1792 fm10k_write_sw_reg(hw, FM10K_SW_SYSTIME_ADJUST, (u32)systime_adjust); 1806 fm10k_write_sw_reg(hw, FM10K_SW_SYSTIME_ADJUST, (u32)systime_adjust);
1793 1807
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_pf.h b/drivers/net/ethernet/intel/fm10k/fm10k_pf.h
index 7ab1db4fff32..40a0dbc62a04 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_pf.h
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_pf.h
@@ -81,26 +81,26 @@ struct fm10k_mac_update {
81 __le16 glort; 81 __le16 glort;
82 u8 flags; 82 u8 flags;
83 u8 action; 83 u8 action;
84}; 84} __packed;
85 85
86struct fm10k_global_table_data { 86struct fm10k_global_table_data {
87 __le32 used; 87 __le32 used;
88 __le32 avail; 88 __le32 avail;
89}; 89} __packed;
90 90
91struct fm10k_swapi_error { 91struct fm10k_swapi_error {
92 __le32 status; 92 __le32 status;
93 struct fm10k_global_table_data mac; 93 struct fm10k_global_table_data mac;
94 struct fm10k_global_table_data nexthop; 94 struct fm10k_global_table_data nexthop;
95 struct fm10k_global_table_data ffu; 95 struct fm10k_global_table_data ffu;
96}; 96} __packed;
97 97
98struct fm10k_swapi_1588_timestamp { 98struct fm10k_swapi_1588_timestamp {
99 __le64 egress; 99 __le64 egress;
100 __le64 ingress; 100 __le64 ingress;
101 __le16 dglort; 101 __le16 dglort;
102 __le16 sglort; 102 __le16 sglort;
103}; 103} __packed;
104 104
105s32 fm10k_msg_lport_map_pf(struct fm10k_hw *, u32 **, struct fm10k_mbx_info *); 105s32 fm10k_msg_lport_map_pf(struct fm10k_hw *, u32 **, struct fm10k_mbx_info *);
106extern const struct fm10k_tlv_attr fm10k_lport_map_msg_attr[]; 106extern const struct fm10k_tlv_attr fm10k_lport_map_msg_attr[];
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_ptp.c b/drivers/net/ethernet/intel/fm10k/fm10k_ptp.c
index 9043633c3e50..b4945e8abe03 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_ptp.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_ptp.c
@@ -70,16 +70,16 @@ void fm10k_ts_tx_enqueue(struct fm10k_intfc *interface, struct sk_buff *skb)
70 * if none are present then insert skb in tail of list 70 * if none are present then insert skb in tail of list
71 */ 71 */
72 skb = fm10k_ts_tx_skb(interface, FM10K_CB(clone)->fi.w.dglort); 72 skb = fm10k_ts_tx_skb(interface, FM10K_CB(clone)->fi.w.dglort);
73 if (!skb) 73 if (!skb) {
74 skb_shinfo(clone)->tx_flags |= SKBTX_IN_PROGRESS;
74 __skb_queue_tail(list, clone); 75 __skb_queue_tail(list, clone);
76 }
75 77
76 spin_unlock_irqrestore(&list->lock, flags); 78 spin_unlock_irqrestore(&list->lock, flags);
77 79
78 /* if list is already has one then we just free the clone */ 80 /* if list is already has one then we just free the clone */
79 if (skb) 81 if (skb)
80 kfree_skb(skb); 82 dev_kfree_skb(clone);
81 else
82 skb_shinfo(clone)->tx_flags |= SKBTX_IN_PROGRESS;
83} 83}
84 84
85void fm10k_ts_tx_hwtstamp(struct fm10k_intfc *interface, __le16 dglort, 85void fm10k_ts_tx_hwtstamp(struct fm10k_intfc *interface, __le16 dglort,
@@ -103,9 +103,10 @@ void fm10k_ts_tx_hwtstamp(struct fm10k_intfc *interface, __le16 dglort,
103 if (!skb) 103 if (!skb)
104 return; 104 return;
105 105
106 /* timestamp the sk_buff and return it to the socket */ 106 /* timestamp the sk_buff and free out copy */
107 fm10k_systime_to_hwtstamp(interface, &shhwtstamps, systime); 107 fm10k_systime_to_hwtstamp(interface, &shhwtstamps, systime);
108 skb_complete_tx_timestamp(skb, &shhwtstamps); 108 skb_tstamp_tx(skb, &shhwtstamps);
109 dev_kfree_skb_any(skb);
109} 110}
110 111
111void fm10k_ts_tx_subtask(struct fm10k_intfc *interface) 112void fm10k_ts_tx_subtask(struct fm10k_intfc *interface)
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_type.h b/drivers/net/ethernet/intel/fm10k/fm10k_type.h
index 4af96686c584..2a17d82fa37d 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_type.h
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_type.h
@@ -369,7 +369,7 @@ struct fm10k_hw;
369/* Registers contained in BAR 4 for Switch management */ 369/* Registers contained in BAR 4 for Switch management */
370#define FM10K_SW_SYSTIME_ADJUST 0x0224D 370#define FM10K_SW_SYSTIME_ADJUST 0x0224D
371#define FM10K_SW_SYSTIME_ADJUST_MASK 0x3FFFFFFF 371#define FM10K_SW_SYSTIME_ADJUST_MASK 0x3FFFFFFF
372#define FM10K_SW_SYSTIME_ADJUST_DIR_NEGATIVE 0x80000000 372#define FM10K_SW_SYSTIME_ADJUST_DIR_POSITIVE 0x80000000
373#define FM10K_SW_SYSTIME_PULSE(_n) ((_n) + 0x02252) 373#define FM10K_SW_SYSTIME_PULSE(_n) ((_n) + 0x02252)
374 374
375enum fm10k_int_source { 375enum fm10k_int_source {