aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-10-06 01:04:21 -0400
committerDavid S. Miller <davem@davemloft.net>2014-10-06 01:04:21 -0400
commit4e62ccd901062c532673f4fda16c484de2c3c8fc (patch)
tree33befd15a97dcb8bb8b3a78bc6d355caf2d37f59
parentf2600cf02b5b59aaee082c3485b7f01fc7f7b70c (diff)
parent1556b8746e52501fdfaadd65837baaa63a9fa937 (diff)
Merge branch 'mlx4-next'
Amir Vadai says: ==================== net/mlx4_en: Optimizations to TX flow This patchset contains optimizations to TX flow in mlx4_en driver. It also introduce setting/getting tx copybreak, to enable controlling inline threshold dynamically. TX flow optimizations was authored and posted to the mailing list by Eric Dumazet [1] as a single patch. I splitted this patch to smaller patches, Reviewed it and tested. Changed from original patch: - s/iowrite32be/iowrite32/, since ring->doorbell_qpn is stored as be32 The tx copybreak patch was also suggested by Eric Dumazet, and was edited and reviewed by me. User space patch will be sent after kernel code is ready. I am sending this patchset now since the merge window is near and don't want to miss it. More work need to do: - Disable BF when xmit_more is in use - Make TSO use xmit_more too. Maybe by splitting small TSO packets in the driver itself, to avoid extra cpu/memory costs of GSO before the driver - Fix mlx4_en_xmit buggy handling of queue full in the middle of a burst partially posted to send queue using xmit_more Eric, I edited the patches to have you as the Author and the first signed-off-by. I hope it is ok with you (I wasn't sure if it is ok to sign by you), anyway all the credit to those changes should go to you. Patchset was tested and applied over commit 1e203c1 "(net: sched: suspicious RCU usage in qdisc_watchdog") [1] - https://patchwork.ozlabs.org/patch/394256/ ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_ethtool.c44
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_tx.c330
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4_en.h90
-rw-r--r--include/linux/mlx4/device.h2
-rw-r--r--include/uapi/linux/ethtool.h1
-rw-r--r--net/core/ethtool.c1
6 files changed, 290 insertions, 178 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
index 42c9f8b09a6e..ae83da9cd18a 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
@@ -1267,6 +1267,48 @@ static u32 mlx4_en_get_priv_flags(struct net_device *dev)
1267 return priv->pflags; 1267 return priv->pflags;
1268} 1268}
1269 1269
1270static int mlx4_en_get_tunable(struct net_device *dev,
1271 const struct ethtool_tunable *tuna,
1272 void *data)
1273{
1274 const struct mlx4_en_priv *priv = netdev_priv(dev);
1275 int ret = 0;
1276
1277 switch (tuna->id) {
1278 case ETHTOOL_TX_COPYBREAK:
1279 *(u32 *)data = priv->prof->inline_thold;
1280 break;
1281 default:
1282 ret = -EINVAL;
1283 break;
1284 }
1285
1286 return ret;
1287}
1288
1289static int mlx4_en_set_tunable(struct net_device *dev,
1290 const struct ethtool_tunable *tuna,
1291 const void *data)
1292{
1293 struct mlx4_en_priv *priv = netdev_priv(dev);
1294 int val, ret = 0;
1295
1296 switch (tuna->id) {
1297 case ETHTOOL_TX_COPYBREAK:
1298 val = *(u32 *)data;
1299 if (val < MIN_PKT_LEN || val > MAX_INLINE)
1300 ret = -EINVAL;
1301 else
1302 priv->prof->inline_thold = val;
1303 break;
1304 default:
1305 ret = -EINVAL;
1306 break;
1307 }
1308
1309 return ret;
1310}
1311
1270 1312
1271const struct ethtool_ops mlx4_en_ethtool_ops = { 1313const struct ethtool_ops mlx4_en_ethtool_ops = {
1272 .get_drvinfo = mlx4_en_get_drvinfo, 1314 .get_drvinfo = mlx4_en_get_drvinfo,
@@ -1297,6 +1339,8 @@ const struct ethtool_ops mlx4_en_ethtool_ops = {
1297 .get_ts_info = mlx4_en_get_ts_info, 1339 .get_ts_info = mlx4_en_get_ts_info,
1298 .set_priv_flags = mlx4_en_set_priv_flags, 1340 .set_priv_flags = mlx4_en_set_priv_flags,
1299 .get_priv_flags = mlx4_en_get_priv_flags, 1341 .get_priv_flags = mlx4_en_get_priv_flags,
1342 .get_tunable = mlx4_en_get_tunable,
1343 .set_tunable = mlx4_en_set_tunable,
1300}; 1344};
1301 1345
1302 1346
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
index 0c501253fdab..92a7cf46d9af 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
@@ -37,6 +37,7 @@
37#include <linux/mlx4/qp.h> 37#include <linux/mlx4/qp.h>
38#include <linux/skbuff.h> 38#include <linux/skbuff.h>
39#include <linux/if_vlan.h> 39#include <linux/if_vlan.h>
40#include <linux/prefetch.h>
40#include <linux/vmalloc.h> 41#include <linux/vmalloc.h>
41#include <linux/tcp.h> 42#include <linux/tcp.h>
42#include <linux/ip.h> 43#include <linux/ip.h>
@@ -65,10 +66,9 @@ int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv,
65 ring->size = size; 66 ring->size = size;
66 ring->size_mask = size - 1; 67 ring->size_mask = size - 1;
67 ring->stride = stride; 68 ring->stride = stride;
68 ring->inline_thold = priv->prof->inline_thold;
69 69
70 tmp = size * sizeof(struct mlx4_en_tx_info); 70 tmp = size * sizeof(struct mlx4_en_tx_info);
71 ring->tx_info = vmalloc_node(tmp, node); 71 ring->tx_info = kmalloc_node(tmp, GFP_KERNEL | __GFP_NOWARN, node);
72 if (!ring->tx_info) { 72 if (!ring->tx_info) {
73 ring->tx_info = vmalloc(tmp); 73 ring->tx_info = vmalloc(tmp);
74 if (!ring->tx_info) { 74 if (!ring->tx_info) {
@@ -151,7 +151,7 @@ err_bounce:
151 kfree(ring->bounce_buf); 151 kfree(ring->bounce_buf);
152 ring->bounce_buf = NULL; 152 ring->bounce_buf = NULL;
153err_info: 153err_info:
154 vfree(ring->tx_info); 154 kvfree(ring->tx_info);
155 ring->tx_info = NULL; 155 ring->tx_info = NULL;
156err_ring: 156err_ring:
157 kfree(ring); 157 kfree(ring);
@@ -174,7 +174,7 @@ void mlx4_en_destroy_tx_ring(struct mlx4_en_priv *priv,
174 mlx4_free_hwq_res(mdev->dev, &ring->wqres, ring->buf_size); 174 mlx4_free_hwq_res(mdev->dev, &ring->wqres, ring->buf_size);
175 kfree(ring->bounce_buf); 175 kfree(ring->bounce_buf);
176 ring->bounce_buf = NULL; 176 ring->bounce_buf = NULL;
177 vfree(ring->tx_info); 177 kvfree(ring->tx_info);
178 ring->tx_info = NULL; 178 ring->tx_info = NULL;
179 kfree(ring); 179 kfree(ring);
180 *pring = NULL; 180 *pring = NULL;
@@ -191,12 +191,12 @@ int mlx4_en_activate_tx_ring(struct mlx4_en_priv *priv,
191 ring->prod = 0; 191 ring->prod = 0;
192 ring->cons = 0xffffffff; 192 ring->cons = 0xffffffff;
193 ring->last_nr_txbb = 1; 193 ring->last_nr_txbb = 1;
194 ring->poll_cnt = 0;
195 memset(ring->tx_info, 0, ring->size * sizeof(struct mlx4_en_tx_info)); 194 memset(ring->tx_info, 0, ring->size * sizeof(struct mlx4_en_tx_info));
196 memset(ring->buf, 0, ring->buf_size); 195 memset(ring->buf, 0, ring->buf_size);
197 196
198 ring->qp_state = MLX4_QP_STATE_RST; 197 ring->qp_state = MLX4_QP_STATE_RST;
199 ring->doorbell_qpn = ring->qp.qpn << 8; 198 ring->doorbell_qpn = cpu_to_be32(ring->qp.qpn << 8);
199 ring->mr_key = cpu_to_be32(mdev->mr.key);
200 200
201 mlx4_en_fill_qp_context(priv, ring->size, ring->stride, 1, 0, ring->qpn, 201 mlx4_en_fill_qp_context(priv, ring->size, ring->stride, 1, 0, ring->qpn,
202 ring->cqn, user_prio, &ring->context); 202 ring->cqn, user_prio, &ring->context);
@@ -259,38 +259,45 @@ static u32 mlx4_en_free_tx_desc(struct mlx4_en_priv *priv,
259 struct mlx4_en_tx_ring *ring, 259 struct mlx4_en_tx_ring *ring,
260 int index, u8 owner, u64 timestamp) 260 int index, u8 owner, u64 timestamp)
261{ 261{
262 struct mlx4_en_dev *mdev = priv->mdev;
263 struct mlx4_en_tx_info *tx_info = &ring->tx_info[index]; 262 struct mlx4_en_tx_info *tx_info = &ring->tx_info[index];
264 struct mlx4_en_tx_desc *tx_desc = ring->buf + index * TXBB_SIZE; 263 struct mlx4_en_tx_desc *tx_desc = ring->buf + index * TXBB_SIZE;
265 struct mlx4_wqe_data_seg *data = (void *) tx_desc + tx_info->data_offset; 264 struct mlx4_wqe_data_seg *data = (void *) tx_desc + tx_info->data_offset;
266 struct sk_buff *skb = tx_info->skb;
267 struct skb_frag_struct *frag;
268 void *end = ring->buf + ring->buf_size; 265 void *end = ring->buf + ring->buf_size;
269 int frags = skb_shinfo(skb)->nr_frags; 266 struct sk_buff *skb = tx_info->skb;
267 int nr_maps = tx_info->nr_maps;
270 int i; 268 int i;
271 struct skb_shared_hwtstamps hwts;
272 269
273 if (timestamp) { 270 /* We do not touch skb here, so prefetch skb->users location
274 mlx4_en_fill_hwtstamps(mdev, &hwts, timestamp); 271 * to speedup consume_skb()
272 */
273 prefetchw(&skb->users);
274
275 if (unlikely(timestamp)) {
276 struct skb_shared_hwtstamps hwts;
277
278 mlx4_en_fill_hwtstamps(priv->mdev, &hwts, timestamp);
275 skb_tstamp_tx(skb, &hwts); 279 skb_tstamp_tx(skb, &hwts);
276 } 280 }
277 281
278 /* Optimize the common case when there are no wraparounds */ 282 /* Optimize the common case when there are no wraparounds */
279 if (likely((void *) tx_desc + tx_info->nr_txbb * TXBB_SIZE <= end)) { 283 if (likely((void *) tx_desc + tx_info->nr_txbb * TXBB_SIZE <= end)) {
280 if (!tx_info->inl) { 284 if (!tx_info->inl) {
281 if (tx_info->linear) { 285 if (tx_info->linear)
282 dma_unmap_single(priv->ddev, 286 dma_unmap_single(priv->ddev,
283 (dma_addr_t) be64_to_cpu(data->addr), 287 tx_info->map0_dma,
284 be32_to_cpu(data->byte_count), 288 tx_info->map0_byte_count,
285 PCI_DMA_TODEVICE); 289 PCI_DMA_TODEVICE);
286 ++data; 290 else
287 } 291 dma_unmap_page(priv->ddev,
288 292 tx_info->map0_dma,
289 for (i = 0; i < frags; i++) { 293 tx_info->map0_byte_count,
290 frag = &skb_shinfo(skb)->frags[i]; 294 PCI_DMA_TODEVICE);
295 for (i = 1; i < nr_maps; i++) {
296 data++;
291 dma_unmap_page(priv->ddev, 297 dma_unmap_page(priv->ddev,
292 (dma_addr_t) be64_to_cpu(data[i].addr), 298 (dma_addr_t)be64_to_cpu(data->addr),
293 skb_frag_size(frag), PCI_DMA_TODEVICE); 299 be32_to_cpu(data->byte_count),
300 PCI_DMA_TODEVICE);
294 } 301 }
295 } 302 }
296 } else { 303 } else {
@@ -299,23 +306,25 @@ static u32 mlx4_en_free_tx_desc(struct mlx4_en_priv *priv,
299 data = ring->buf + ((void *)data - end); 306 data = ring->buf + ((void *)data - end);
300 } 307 }
301 308
302 if (tx_info->linear) { 309 if (tx_info->linear)
303 dma_unmap_single(priv->ddev, 310 dma_unmap_single(priv->ddev,
304 (dma_addr_t) be64_to_cpu(data->addr), 311 tx_info->map0_dma,
305 be32_to_cpu(data->byte_count), 312 tx_info->map0_byte_count,
306 PCI_DMA_TODEVICE); 313 PCI_DMA_TODEVICE);
307 ++data; 314 else
308 } 315 dma_unmap_page(priv->ddev,
309 316 tx_info->map0_dma,
310 for (i = 0; i < frags; i++) { 317 tx_info->map0_byte_count,
318 PCI_DMA_TODEVICE);
319 for (i = 1; i < nr_maps; i++) {
320 data++;
311 /* Check for wraparound before unmapping */ 321 /* Check for wraparound before unmapping */
312 if ((void *) data >= end) 322 if ((void *) data >= end)
313 data = ring->buf; 323 data = ring->buf;
314 frag = &skb_shinfo(skb)->frags[i];
315 dma_unmap_page(priv->ddev, 324 dma_unmap_page(priv->ddev,
316 (dma_addr_t) be64_to_cpu(data->addr), 325 (dma_addr_t)be64_to_cpu(data->addr),
317 skb_frag_size(frag), PCI_DMA_TODEVICE); 326 be32_to_cpu(data->byte_count),
318 ++data; 327 PCI_DMA_TODEVICE);
319 } 328 }
320 } 329 }
321 } 330 }
@@ -377,13 +386,18 @@ static bool mlx4_en_process_tx_cq(struct net_device *dev,
377 u64 timestamp = 0; 386 u64 timestamp = 0;
378 int done = 0; 387 int done = 0;
379 int budget = priv->tx_work_limit; 388 int budget = priv->tx_work_limit;
389 u32 last_nr_txbb;
390 u32 ring_cons;
380 391
381 if (!priv->port_up) 392 if (!priv->port_up)
382 return true; 393 return true;
383 394
395 prefetchw(&ring->tx_queue->dql.limit);
384 index = cons_index & size_mask; 396 index = cons_index & size_mask;
385 cqe = mlx4_en_get_cqe(buf, index, priv->cqe_size) + factor; 397 cqe = mlx4_en_get_cqe(buf, index, priv->cqe_size) + factor;
386 ring_index = ring->cons & size_mask; 398 last_nr_txbb = ACCESS_ONCE(ring->last_nr_txbb);
399 ring_cons = ACCESS_ONCE(ring->cons);
400 ring_index = ring_cons & size_mask;
387 stamp_index = ring_index; 401 stamp_index = ring_index;
388 402
389 /* Process all completed CQEs */ 403 /* Process all completed CQEs */
@@ -408,19 +422,19 @@ static bool mlx4_en_process_tx_cq(struct net_device *dev,
408 new_index = be16_to_cpu(cqe->wqe_index) & size_mask; 422 new_index = be16_to_cpu(cqe->wqe_index) & size_mask;
409 423
410 do { 424 do {
411 txbbs_skipped += ring->last_nr_txbb; 425 txbbs_skipped += last_nr_txbb;
412 ring_index = (ring_index + ring->last_nr_txbb) & size_mask; 426 ring_index = (ring_index + last_nr_txbb) & size_mask;
413 if (ring->tx_info[ring_index].ts_requested) 427 if (ring->tx_info[ring_index].ts_requested)
414 timestamp = mlx4_en_get_cqe_ts(cqe); 428 timestamp = mlx4_en_get_cqe_ts(cqe);
415 429
416 /* free next descriptor */ 430 /* free next descriptor */
417 ring->last_nr_txbb = mlx4_en_free_tx_desc( 431 last_nr_txbb = mlx4_en_free_tx_desc(
418 priv, ring, ring_index, 432 priv, ring, ring_index,
419 !!((ring->cons + txbbs_skipped) & 433 !!((ring_cons + txbbs_skipped) &
420 ring->size), timestamp); 434 ring->size), timestamp);
421 435
422 mlx4_en_stamp_wqe(priv, ring, stamp_index, 436 mlx4_en_stamp_wqe(priv, ring, stamp_index,
423 !!((ring->cons + txbbs_stamp) & 437 !!((ring_cons + txbbs_stamp) &
424 ring->size)); 438 ring->size));
425 stamp_index = ring_index; 439 stamp_index = ring_index;
426 txbbs_stamp = txbbs_skipped; 440 txbbs_stamp = txbbs_skipped;
@@ -441,7 +455,11 @@ static bool mlx4_en_process_tx_cq(struct net_device *dev,
441 mcq->cons_index = cons_index; 455 mcq->cons_index = cons_index;
442 mlx4_cq_set_ci(mcq); 456 mlx4_cq_set_ci(mcq);
443 wmb(); 457 wmb();
444 ring->cons += txbbs_skipped; 458
459 /* we want to dirty this cache line once */
460 ACCESS_ONCE(ring->last_nr_txbb) = last_nr_txbb;
461 ACCESS_ONCE(ring->cons) = ring_cons + txbbs_skipped;
462
445 netdev_tx_completed_queue(ring->tx_queue, packets, bytes); 463 netdev_tx_completed_queue(ring->tx_queue, packets, bytes);
446 464
447 /* 465 /*
@@ -512,30 +530,35 @@ static struct mlx4_en_tx_desc *mlx4_en_bounce_to_desc(struct mlx4_en_priv *priv,
512 return ring->buf + index * TXBB_SIZE; 530 return ring->buf + index * TXBB_SIZE;
513} 531}
514 532
515static int is_inline(int inline_thold, struct sk_buff *skb, void **pfrag) 533/* Decide if skb can be inlined in tx descriptor to avoid dma mapping
534 *
535 * It seems strange we do not simply use skb_copy_bits().
536 * This would allow to inline all skbs iff skb->len <= inline_thold
537 *
538 * Note that caller already checked skb was not a gso packet
539 */
540static bool is_inline(int inline_thold, const struct sk_buff *skb,
541 const struct skb_shared_info *shinfo,
542 void **pfrag)
516{ 543{
517 void *ptr; 544 void *ptr;
518 545
519 if (inline_thold && !skb_is_gso(skb) && skb->len <= inline_thold) { 546 if (skb->len > inline_thold || !inline_thold)
520 if (skb_shinfo(skb)->nr_frags == 1) { 547 return false;
521 ptr = skb_frag_address_safe(&skb_shinfo(skb)->frags[0]);
522 if (unlikely(!ptr))
523 return 0;
524
525 if (pfrag)
526 *pfrag = ptr;
527 548
528 return 1; 549 if (shinfo->nr_frags == 1) {
529 } else if (unlikely(skb_shinfo(skb)->nr_frags)) 550 ptr = skb_frag_address_safe(&shinfo->frags[0]);
530 return 0; 551 if (unlikely(!ptr))
531 else 552 return false;
532 return 1; 553 *pfrag = ptr;
554 return true;
533 } 555 }
534 556 if (shinfo->nr_frags)
535 return 0; 557 return false;
558 return true;
536} 559}
537 560
538static int inline_size(struct sk_buff *skb) 561static int inline_size(const struct sk_buff *skb)
539{ 562{
540 if (skb->len + CTRL_SIZE + sizeof(struct mlx4_wqe_inline_seg) 563 if (skb->len + CTRL_SIZE + sizeof(struct mlx4_wqe_inline_seg)
541 <= MLX4_INLINE_ALIGN) 564 <= MLX4_INLINE_ALIGN)
@@ -546,18 +569,23 @@ static int inline_size(struct sk_buff *skb)
546 sizeof(struct mlx4_wqe_inline_seg), 16); 569 sizeof(struct mlx4_wqe_inline_seg), 16);
547} 570}
548 571
549static int get_real_size(struct sk_buff *skb, struct net_device *dev, 572static int get_real_size(const struct sk_buff *skb,
550 int *lso_header_size) 573 const struct skb_shared_info *shinfo,
574 struct net_device *dev,
575 int *lso_header_size,
576 bool *inline_ok,
577 void **pfrag)
551{ 578{
552 struct mlx4_en_priv *priv = netdev_priv(dev); 579 struct mlx4_en_priv *priv = netdev_priv(dev);
553 int real_size; 580 int real_size;
554 581
555 if (skb_is_gso(skb)) { 582 if (shinfo->gso_size) {
583 *inline_ok = false;
556 if (skb->encapsulation) 584 if (skb->encapsulation)
557 *lso_header_size = (skb_inner_transport_header(skb) - skb->data) + inner_tcp_hdrlen(skb); 585 *lso_header_size = (skb_inner_transport_header(skb) - skb->data) + inner_tcp_hdrlen(skb);
558 else 586 else
559 *lso_header_size = skb_transport_offset(skb) + tcp_hdrlen(skb); 587 *lso_header_size = skb_transport_offset(skb) + tcp_hdrlen(skb);
560 real_size = CTRL_SIZE + skb_shinfo(skb)->nr_frags * DS_SIZE + 588 real_size = CTRL_SIZE + shinfo->nr_frags * DS_SIZE +
561 ALIGN(*lso_header_size + 4, DS_SIZE); 589 ALIGN(*lso_header_size + 4, DS_SIZE);
562 if (unlikely(*lso_header_size != skb_headlen(skb))) { 590 if (unlikely(*lso_header_size != skb_headlen(skb))) {
563 /* We add a segment for the skb linear buffer only if 591 /* We add a segment for the skb linear buffer only if
@@ -572,20 +600,28 @@ static int get_real_size(struct sk_buff *skb, struct net_device *dev,
572 } 600 }
573 } else { 601 } else {
574 *lso_header_size = 0; 602 *lso_header_size = 0;
575 if (!is_inline(priv->prof->inline_thold, skb, NULL)) 603 *inline_ok = is_inline(priv->prof->inline_thold, skb,
576 real_size = CTRL_SIZE + (skb_shinfo(skb)->nr_frags + 1) * DS_SIZE; 604 shinfo, pfrag);
577 else 605
606 if (*inline_ok)
578 real_size = inline_size(skb); 607 real_size = inline_size(skb);
608 else
609 real_size = CTRL_SIZE +
610 (shinfo->nr_frags + 1) * DS_SIZE;
579 } 611 }
580 612
581 return real_size; 613 return real_size;
582} 614}
583 615
584static void build_inline_wqe(struct mlx4_en_tx_desc *tx_desc, struct sk_buff *skb, 616static void build_inline_wqe(struct mlx4_en_tx_desc *tx_desc,
585 int real_size, u16 *vlan_tag, int tx_ind, void *fragptr) 617 const struct sk_buff *skb,
618 const struct skb_shared_info *shinfo,
619 int real_size, u16 *vlan_tag,
620 int tx_ind, void *fragptr)
586{ 621{
587 struct mlx4_wqe_inline_seg *inl = &tx_desc->inl; 622 struct mlx4_wqe_inline_seg *inl = &tx_desc->inl;
588 int spc = MLX4_INLINE_ALIGN - CTRL_SIZE - sizeof *inl; 623 int spc = MLX4_INLINE_ALIGN - CTRL_SIZE - sizeof *inl;
624 unsigned int hlen = skb_headlen(skb);
589 625
590 if (skb->len <= spc) { 626 if (skb->len <= spc) {
591 if (likely(skb->len >= MIN_PKT_LEN)) { 627 if (likely(skb->len >= MIN_PKT_LEN)) {
@@ -595,19 +631,19 @@ static void build_inline_wqe(struct mlx4_en_tx_desc *tx_desc, struct sk_buff *sk
595 memset(((void *)(inl + 1)) + skb->len, 0, 631 memset(((void *)(inl + 1)) + skb->len, 0,
596 MIN_PKT_LEN - skb->len); 632 MIN_PKT_LEN - skb->len);
597 } 633 }
598 skb_copy_from_linear_data(skb, inl + 1, skb_headlen(skb)); 634 skb_copy_from_linear_data(skb, inl + 1, hlen);
599 if (skb_shinfo(skb)->nr_frags) 635 if (shinfo->nr_frags)
600 memcpy(((void *)(inl + 1)) + skb_headlen(skb), fragptr, 636 memcpy(((void *)(inl + 1)) + hlen, fragptr,
601 skb_frag_size(&skb_shinfo(skb)->frags[0])); 637 skb_frag_size(&shinfo->frags[0]));
602 638
603 } else { 639 } else {
604 inl->byte_count = cpu_to_be32(1 << 31 | spc); 640 inl->byte_count = cpu_to_be32(1 << 31 | spc);
605 if (skb_headlen(skb) <= spc) { 641 if (hlen <= spc) {
606 skb_copy_from_linear_data(skb, inl + 1, skb_headlen(skb)); 642 skb_copy_from_linear_data(skb, inl + 1, hlen);
607 if (skb_headlen(skb) < spc) { 643 if (hlen < spc) {
608 memcpy(((void *)(inl + 1)) + skb_headlen(skb), 644 memcpy(((void *)(inl + 1)) + hlen,
609 fragptr, spc - skb_headlen(skb)); 645 fragptr, spc - hlen);
610 fragptr += spc - skb_headlen(skb); 646 fragptr += spc - hlen;
611 } 647 }
612 inl = (void *) (inl + 1) + spc; 648 inl = (void *) (inl + 1) + spc;
613 memcpy(((void *)(inl + 1)), fragptr, skb->len - spc); 649 memcpy(((void *)(inl + 1)), fragptr, skb->len - spc);
@@ -615,10 +651,11 @@ static void build_inline_wqe(struct mlx4_en_tx_desc *tx_desc, struct sk_buff *sk
615 skb_copy_from_linear_data(skb, inl + 1, spc); 651 skb_copy_from_linear_data(skb, inl + 1, spc);
616 inl = (void *) (inl + 1) + spc; 652 inl = (void *) (inl + 1) + spc;
617 skb_copy_from_linear_data_offset(skb, spc, inl + 1, 653 skb_copy_from_linear_data_offset(skb, spc, inl + 1,
618 skb_headlen(skb) - spc); 654 hlen - spc);
619 if (skb_shinfo(skb)->nr_frags) 655 if (shinfo->nr_frags)
620 memcpy(((void *)(inl + 1)) + skb_headlen(skb) - spc, 656 memcpy(((void *)(inl + 1)) + hlen - spc,
621 fragptr, skb_frag_size(&skb_shinfo(skb)->frags[0])); 657 fragptr,
658 skb_frag_size(&shinfo->frags[0]));
622 } 659 }
623 660
624 wmb(); 661 wmb();
@@ -642,15 +679,16 @@ u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb,
642 return fallback(dev, skb) % rings_p_up + up * rings_p_up; 679 return fallback(dev, skb) % rings_p_up + up * rings_p_up;
643} 680}
644 681
645static void mlx4_bf_copy(void __iomem *dst, unsigned long *src, unsigned bytecnt) 682static void mlx4_bf_copy(void __iomem *dst, const void *src,
683 unsigned int bytecnt)
646{ 684{
647 __iowrite64_copy(dst, src, bytecnt / 8); 685 __iowrite64_copy(dst, src, bytecnt / 8);
648} 686}
649 687
650netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) 688netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
651{ 689{
690 struct skb_shared_info *shinfo = skb_shinfo(skb);
652 struct mlx4_en_priv *priv = netdev_priv(dev); 691 struct mlx4_en_priv *priv = netdev_priv(dev);
653 struct mlx4_en_dev *mdev = priv->mdev;
654 struct device *ddev = priv->ddev; 692 struct device *ddev = priv->ddev;
655 struct mlx4_en_tx_ring *ring; 693 struct mlx4_en_tx_ring *ring;
656 struct mlx4_en_tx_desc *tx_desc; 694 struct mlx4_en_tx_desc *tx_desc;
@@ -663,16 +701,25 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
663 u32 index, bf_index; 701 u32 index, bf_index;
664 __be32 op_own; 702 __be32 op_own;
665 u16 vlan_tag = 0; 703 u16 vlan_tag = 0;
666 int i; 704 int i_frag;
667 int lso_header_size; 705 int lso_header_size;
668 void *fragptr; 706 void *fragptr = NULL;
669 bool bounce = false; 707 bool bounce = false;
670 bool send_doorbell; 708 bool send_doorbell;
709 bool inline_ok;
710 u32 ring_cons;
671 711
672 if (!priv->port_up) 712 if (!priv->port_up)
673 goto tx_drop; 713 goto tx_drop;
674 714
675 real_size = get_real_size(skb, dev, &lso_header_size); 715 tx_ind = skb_get_queue_mapping(skb);
716 ring = priv->tx_ring[tx_ind];
717
718 /* fetch ring->cons far ahead before needing it to avoid stall */
719 ring_cons = ACCESS_ONCE(ring->cons);
720
721 real_size = get_real_size(skb, shinfo, dev, &lso_header_size,
722 &inline_ok, &fragptr);
676 if (unlikely(!real_size)) 723 if (unlikely(!real_size))
677 goto tx_drop; 724 goto tx_drop;
678 725
@@ -685,13 +732,11 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
685 goto tx_drop; 732 goto tx_drop;
686 } 733 }
687 734
688 tx_ind = skb->queue_mapping;
689 ring = priv->tx_ring[tx_ind];
690 if (vlan_tx_tag_present(skb)) 735 if (vlan_tx_tag_present(skb))
691 vlan_tag = vlan_tx_tag_get(skb); 736 vlan_tag = vlan_tx_tag_get(skb);
692 737
693 /* Check available TXBBs And 2K spare for prefetch */ 738 /* Check available TXBBs And 2K spare for prefetch */
694 if (unlikely(((int)(ring->prod - ring->cons)) > 739 if (unlikely(((int)(ring->prod - ring_cons)) >
695 ring->size - HEADROOM - MAX_DESC_TXBBS)) { 740 ring->size - HEADROOM - MAX_DESC_TXBBS)) {
696 /* every full Tx ring stops queue */ 741 /* every full Tx ring stops queue */
697 netif_tx_stop_queue(ring->tx_queue); 742 netif_tx_stop_queue(ring->tx_queue);
@@ -705,7 +750,8 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
705 */ 750 */
706 wmb(); 751 wmb();
707 752
708 if (unlikely(((int)(ring->prod - ring->cons)) <= 753 ring_cons = ACCESS_ONCE(ring->cons);
754 if (unlikely(((int)(ring->prod - ring_cons)) <=
709 ring->size - HEADROOM - MAX_DESC_TXBBS)) { 755 ring->size - HEADROOM - MAX_DESC_TXBBS)) {
710 netif_tx_wake_queue(ring->tx_queue); 756 netif_tx_wake_queue(ring->tx_queue);
711 ring->wake_queue++; 757 ring->wake_queue++;
@@ -714,9 +760,11 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
714 } 760 }
715 } 761 }
716 762
763 prefetchw(&ring->tx_queue->dql);
764
717 /* Track current inflight packets for performance analysis */ 765 /* Track current inflight packets for performance analysis */
718 AVG_PERF_COUNTER(priv->pstats.inflight_avg, 766 AVG_PERF_COUNTER(priv->pstats.inflight_avg,
719 (u32) (ring->prod - ring->cons - 1)); 767 (u32)(ring->prod - ring_cons - 1));
720 768
721 /* Packet is good - grab an index and transmit it */ 769 /* Packet is good - grab an index and transmit it */
722 index = ring->prod & ring->size_mask; 770 index = ring->prod & ring->size_mask;
@@ -736,46 +784,48 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
736 tx_info->skb = skb; 784 tx_info->skb = skb;
737 tx_info->nr_txbb = nr_txbb; 785 tx_info->nr_txbb = nr_txbb;
738 786
787 data = &tx_desc->data;
739 if (lso_header_size) 788 if (lso_header_size)
740 data = ((void *)&tx_desc->lso + ALIGN(lso_header_size + 4, 789 data = ((void *)&tx_desc->lso + ALIGN(lso_header_size + 4,
741 DS_SIZE)); 790 DS_SIZE));
742 else
743 data = &tx_desc->data;
744 791
745 /* valid only for none inline segments */ 792 /* valid only for none inline segments */
746 tx_info->data_offset = (void *)data - (void *)tx_desc; 793 tx_info->data_offset = (void *)data - (void *)tx_desc;
747 794
795 tx_info->inl = inline_ok;
796
748 tx_info->linear = (lso_header_size < skb_headlen(skb) && 797 tx_info->linear = (lso_header_size < skb_headlen(skb) &&
749 !is_inline(ring->inline_thold, skb, NULL)) ? 1 : 0; 798 !inline_ok) ? 1 : 0;
750 799
751 data += skb_shinfo(skb)->nr_frags + tx_info->linear - 1; 800 tx_info->nr_maps = shinfo->nr_frags + tx_info->linear;
801 data += tx_info->nr_maps - 1;
752 802
753 if (is_inline(ring->inline_thold, skb, &fragptr)) { 803 if (!tx_info->inl) {
754 tx_info->inl = 1; 804 dma_addr_t dma = 0;
755 } else { 805 u32 byte_count = 0;
756 /* Map fragments */
757 for (i = skb_shinfo(skb)->nr_frags - 1; i >= 0; i--) {
758 struct skb_frag_struct *frag;
759 dma_addr_t dma;
760 806
761 frag = &skb_shinfo(skb)->frags[i]; 807 /* Map fragments if any */
808 for (i_frag = shinfo->nr_frags - 1; i_frag >= 0; i_frag--) {
809 const struct skb_frag_struct *frag;
810
811 frag = &shinfo->frags[i_frag];
812 byte_count = skb_frag_size(frag);
762 dma = skb_frag_dma_map(ddev, frag, 813 dma = skb_frag_dma_map(ddev, frag,
763 0, skb_frag_size(frag), 814 0, byte_count,
764 DMA_TO_DEVICE); 815 DMA_TO_DEVICE);
765 if (dma_mapping_error(ddev, dma)) 816 if (dma_mapping_error(ddev, dma))
766 goto tx_drop_unmap; 817 goto tx_drop_unmap;
767 818
768 data->addr = cpu_to_be64(dma); 819 data->addr = cpu_to_be64(dma);
769 data->lkey = cpu_to_be32(mdev->mr.key); 820 data->lkey = ring->mr_key;
770 wmb(); 821 wmb();
771 data->byte_count = cpu_to_be32(skb_frag_size(frag)); 822 data->byte_count = cpu_to_be32(byte_count);
772 --data; 823 --data;
773 } 824 }
774 825
775 /* Map linear part */ 826 /* Map linear part if needed */
776 if (tx_info->linear) { 827 if (tx_info->linear) {
777 u32 byte_count = skb_headlen(skb) - lso_header_size; 828 byte_count = skb_headlen(skb) - lso_header_size;
778 dma_addr_t dma;
779 829
780 dma = dma_map_single(ddev, skb->data + 830 dma = dma_map_single(ddev, skb->data +
781 lso_header_size, byte_count, 831 lso_header_size, byte_count,
@@ -784,29 +834,28 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
784 goto tx_drop_unmap; 834 goto tx_drop_unmap;
785 835
786 data->addr = cpu_to_be64(dma); 836 data->addr = cpu_to_be64(dma);
787 data->lkey = cpu_to_be32(mdev->mr.key); 837 data->lkey = ring->mr_key;
788 wmb(); 838 wmb();
789 data->byte_count = cpu_to_be32(byte_count); 839 data->byte_count = cpu_to_be32(byte_count);
790 } 840 }
791 tx_info->inl = 0; 841 /* tx completion can avoid cache line miss for common cases */
842 tx_info->map0_dma = dma;
843 tx_info->map0_byte_count = byte_count;
792 } 844 }
793 845
794 /* 846 /*
795 * For timestamping add flag to skb_shinfo and 847 * For timestamping add flag to skb_shinfo and
796 * set flag for further reference 848 * set flag for further reference
797 */ 849 */
798 if (ring->hwtstamp_tx_type == HWTSTAMP_TX_ON && 850 tx_info->ts_requested = 0;
799 skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) { 851 if (unlikely(ring->hwtstamp_tx_type == HWTSTAMP_TX_ON &&
800 skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; 852 shinfo->tx_flags & SKBTX_HW_TSTAMP)) {
853 shinfo->tx_flags |= SKBTX_IN_PROGRESS;
801 tx_info->ts_requested = 1; 854 tx_info->ts_requested = 1;
802 } 855 }
803 856
804 /* Prepare ctrl segement apart opcode+ownership, which depends on 857 /* Prepare ctrl segement apart opcode+ownership, which depends on
805 * whether LSO is used */ 858 * whether LSO is used */
806 tx_desc->ctrl.vlan_tag = cpu_to_be16(vlan_tag);
807 tx_desc->ctrl.ins_vlan = MLX4_WQE_CTRL_INS_VLAN *
808 !!vlan_tx_tag_present(skb);
809 tx_desc->ctrl.fence_size = (real_size / 16) & 0x3f;
810 tx_desc->ctrl.srcrb_flags = priv->ctrl_flags; 859 tx_desc->ctrl.srcrb_flags = priv->ctrl_flags;
811 if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) { 860 if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
812 tx_desc->ctrl.srcrb_flags |= cpu_to_be32(MLX4_WQE_CTRL_IP_CSUM | 861 tx_desc->ctrl.srcrb_flags |= cpu_to_be32(MLX4_WQE_CTRL_IP_CSUM |
@@ -827,6 +876,8 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
827 876
828 /* Handle LSO (TSO) packets */ 877 /* Handle LSO (TSO) packets */
829 if (lso_header_size) { 878 if (lso_header_size) {
879 int i;
880
830 /* Mark opcode as LSO */ 881 /* Mark opcode as LSO */
831 op_own = cpu_to_be32(MLX4_OPCODE_LSO | (1 << 6)) | 882 op_own = cpu_to_be32(MLX4_OPCODE_LSO | (1 << 6)) |
832 ((ring->prod & ring->size) ? 883 ((ring->prod & ring->size) ?
@@ -834,15 +885,16 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
834 885
835 /* Fill in the LSO prefix */ 886 /* Fill in the LSO prefix */
836 tx_desc->lso.mss_hdr_size = cpu_to_be32( 887 tx_desc->lso.mss_hdr_size = cpu_to_be32(
837 skb_shinfo(skb)->gso_size << 16 | lso_header_size); 888 shinfo->gso_size << 16 | lso_header_size);
838 889
839 /* Copy headers; 890 /* Copy headers;
840 * note that we already verified that it is linear */ 891 * note that we already verified that it is linear */
841 memcpy(tx_desc->lso.header, skb->data, lso_header_size); 892 memcpy(tx_desc->lso.header, skb->data, lso_header_size);
842 893
843 ring->tso_packets++; 894 ring->tso_packets++;
844 i = ((skb->len - lso_header_size) / skb_shinfo(skb)->gso_size) + 895
845 !!((skb->len - lso_header_size) % skb_shinfo(skb)->gso_size); 896 i = ((skb->len - lso_header_size) / shinfo->gso_size) +
897 !!((skb->len - lso_header_size) % shinfo->gso_size);
846 tx_info->nr_bytes = skb->len + (i - 1) * lso_header_size; 898 tx_info->nr_bytes = skb->len + (i - 1) * lso_header_size;
847 ring->packets += i; 899 ring->packets += i;
848 } else { 900 } else {
@@ -852,16 +904,14 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
852 cpu_to_be32(MLX4_EN_BIT_DESC_OWN) : 0); 904 cpu_to_be32(MLX4_EN_BIT_DESC_OWN) : 0);
853 tx_info->nr_bytes = max_t(unsigned int, skb->len, ETH_ZLEN); 905 tx_info->nr_bytes = max_t(unsigned int, skb->len, ETH_ZLEN);
854 ring->packets++; 906 ring->packets++;
855
856 } 907 }
857 ring->bytes += tx_info->nr_bytes; 908 ring->bytes += tx_info->nr_bytes;
858 netdev_tx_sent_queue(ring->tx_queue, tx_info->nr_bytes); 909 netdev_tx_sent_queue(ring->tx_queue, tx_info->nr_bytes);
859 AVG_PERF_COUNTER(priv->pstats.tx_pktsz_avg, skb->len); 910 AVG_PERF_COUNTER(priv->pstats.tx_pktsz_avg, skb->len);
860 911
861 if (tx_info->inl) { 912 if (tx_info->inl)
862 build_inline_wqe(tx_desc, skb, real_size, &vlan_tag, tx_ind, fragptr); 913 build_inline_wqe(tx_desc, skb, shinfo, real_size, &vlan_tag,
863 tx_info->inl = 1; 914 tx_ind, fragptr);
864 }
865 915
866 if (skb->encapsulation) { 916 if (skb->encapsulation) {
867 struct iphdr *ipv4 = (struct iphdr *)skb_inner_network_header(skb); 917 struct iphdr *ipv4 = (struct iphdr *)skb_inner_network_header(skb);
@@ -874,16 +924,19 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
874 ring->prod += nr_txbb; 924 ring->prod += nr_txbb;
875 925
876 /* If we used a bounce buffer then copy descriptor back into place */ 926 /* If we used a bounce buffer then copy descriptor back into place */
877 if (bounce) 927 if (unlikely(bounce))
878 tx_desc = mlx4_en_bounce_to_desc(priv, ring, index, desc_size); 928 tx_desc = mlx4_en_bounce_to_desc(priv, ring, index, desc_size);
879 929
880 skb_tx_timestamp(skb); 930 skb_tx_timestamp(skb);
881 931
882 send_doorbell = !skb->xmit_more || netif_xmit_stopped(ring->tx_queue); 932 send_doorbell = !skb->xmit_more || netif_xmit_stopped(ring->tx_queue);
883 933
934 real_size = (real_size / 16) & 0x3f;
935
884 if (ring->bf_enabled && desc_size <= MAX_BF && !bounce && 936 if (ring->bf_enabled && desc_size <= MAX_BF && !bounce &&
885 !vlan_tx_tag_present(skb) && send_doorbell) { 937 !vlan_tx_tag_present(skb) && send_doorbell) {
886 tx_desc->ctrl.bf_qpn |= cpu_to_be32(ring->doorbell_qpn); 938 tx_desc->ctrl.bf_qpn = ring->doorbell_qpn |
939 cpu_to_be32(real_size);
887 940
888 op_own |= htonl((bf_index & 0xffff) << 8); 941 op_own |= htonl((bf_index & 0xffff) << 8);
889 /* Ensure new descriptor hits memory 942 /* Ensure new descriptor hits memory
@@ -894,13 +947,18 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
894 947
895 wmb(); 948 wmb();
896 949
897 mlx4_bf_copy(ring->bf.reg + ring->bf.offset, (unsigned long *) &tx_desc->ctrl, 950 mlx4_bf_copy(ring->bf.reg + ring->bf.offset, &tx_desc->ctrl,
898 desc_size); 951 desc_size);
899 952
900 wmb(); 953 wmb();
901 954
902 ring->bf.offset ^= ring->bf.buf_size; 955 ring->bf.offset ^= ring->bf.buf_size;
903 } else { 956 } else {
957 tx_desc->ctrl.vlan_tag = cpu_to_be16(vlan_tag);
958 tx_desc->ctrl.ins_vlan = MLX4_WQE_CTRL_INS_VLAN *
959 !!vlan_tx_tag_present(skb);
960 tx_desc->ctrl.fence_size = real_size;
961
904 /* Ensure new descriptor hits memory 962 /* Ensure new descriptor hits memory
905 * before setting ownership of this descriptor to HW 963 * before setting ownership of this descriptor to HW
906 */ 964 */
@@ -908,8 +966,8 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
908 tx_desc->ctrl.owner_opcode = op_own; 966 tx_desc->ctrl.owner_opcode = op_own;
909 if (send_doorbell) { 967 if (send_doorbell) {
910 wmb(); 968 wmb();
911 iowrite32be(ring->doorbell_qpn, 969 iowrite32(ring->doorbell_qpn,
912 ring->bf.uar->map + MLX4_SEND_DOORBELL); 970 ring->bf.uar->map + MLX4_SEND_DOORBELL);
913 } else { 971 } else {
914 ring->xmit_more++; 972 ring->xmit_more++;
915 } 973 }
@@ -920,8 +978,8 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
920tx_drop_unmap: 978tx_drop_unmap:
921 en_err(priv, "DMA mapping error\n"); 979 en_err(priv, "DMA mapping error\n");
922 980
923 for (i++; i < skb_shinfo(skb)->nr_frags; i++) { 981 while (++i_frag < shinfo->nr_frags) {
924 data++; 982 ++data;
925 dma_unmap_page(ddev, (dma_addr_t) be64_to_cpu(data->addr), 983 dma_unmap_page(ddev, (dma_addr_t) be64_to_cpu(data->addr),
926 be32_to_cpu(data->byte_count), 984 be32_to_cpu(data->byte_count),
927 PCI_DMA_TODEVICE); 985 PCI_DMA_TODEVICE);
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
index 84c9d5dbfa4f..8fef65840b3b 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
@@ -216,13 +216,16 @@ enum cq_type {
216 216
217struct mlx4_en_tx_info { 217struct mlx4_en_tx_info {
218 struct sk_buff *skb; 218 struct sk_buff *skb;
219 u32 nr_txbb; 219 dma_addr_t map0_dma;
220 u32 nr_bytes; 220 u32 map0_byte_count;
221 u8 linear; 221 u32 nr_txbb;
222 u8 data_offset; 222 u32 nr_bytes;
223 u8 inl; 223 u8 linear;
224 u8 ts_requested; 224 u8 data_offset;
225}; 225 u8 inl;
226 u8 ts_requested;
227 u8 nr_maps;
228} ____cacheline_aligned_in_smp;
226 229
227 230
228#define MLX4_EN_BIT_DESC_OWN 0x80000000 231#define MLX4_EN_BIT_DESC_OWN 0x80000000
@@ -253,41 +256,46 @@ struct mlx4_en_rx_alloc {
253}; 256};
254 257
255struct mlx4_en_tx_ring { 258struct mlx4_en_tx_ring {
259 /* cache line used and dirtied in tx completion
260 * (mlx4_en_free_tx_buf())
261 */
262 u32 last_nr_txbb;
263 u32 cons;
264 unsigned long wake_queue;
265
266 /* cache line used and dirtied in mlx4_en_xmit() */
267 u32 prod ____cacheline_aligned_in_smp;
268 unsigned long bytes;
269 unsigned long packets;
270 unsigned long tx_csum;
271 unsigned long tso_packets;
272 unsigned long xmit_more;
273 struct mlx4_bf bf;
274 unsigned long queue_stopped;
275
276 /* Following part should be mostly read */
277 cpumask_t affinity_mask;
278 struct mlx4_qp qp;
256 struct mlx4_hwq_resources wqres; 279 struct mlx4_hwq_resources wqres;
257 u32 size ; /* number of TXBBs */ 280 u32 size; /* number of TXBBs */
258 u32 size_mask; 281 u32 size_mask;
259 u16 stride; 282 u16 stride;
260 u16 cqn; /* index of port CQ associated with this ring */ 283 u16 cqn; /* index of port CQ associated with this ring */
261 u32 prod; 284 u32 buf_size;
262 u32 cons; 285 __be32 doorbell_qpn;
263 u32 buf_size; 286 __be32 mr_key;
264 u32 doorbell_qpn; 287 void *buf;
265 void *buf; 288 struct mlx4_en_tx_info *tx_info;
266 u16 poll_cnt; 289 u8 *bounce_buf;
267 struct mlx4_en_tx_info *tx_info; 290 struct mlx4_qp_context context;
268 u8 *bounce_buf; 291 int qpn;
269 u8 queue_index; 292 enum mlx4_qp_state qp_state;
270 cpumask_t affinity_mask; 293 u8 queue_index;
271 u32 last_nr_txbb; 294 bool bf_enabled;
272 struct mlx4_qp qp; 295 bool bf_alloced;
273 struct mlx4_qp_context context; 296 struct netdev_queue *tx_queue;
274 int qpn; 297 int hwtstamp_tx_type;
275 enum mlx4_qp_state qp_state; 298} ____cacheline_aligned_in_smp;
276 struct mlx4_srq dummy;
277 unsigned long bytes;
278 unsigned long packets;
279 unsigned long tx_csum;
280 unsigned long queue_stopped;
281 unsigned long wake_queue;
282 unsigned long tso_packets;
283 unsigned long xmit_more;
284 struct mlx4_bf bf;
285 bool bf_enabled;
286 bool bf_alloced;
287 struct netdev_queue *tx_queue;
288 int hwtstamp_tx_type;
289 int inline_thold;
290};
291 299
292struct mlx4_en_rx_desc { 300struct mlx4_en_rx_desc {
293 /* actual number of entries depends on rx ring stride */ 301 /* actual number of entries depends on rx ring stride */
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
index b2f8ab9a57c4..37e4404d0227 100644
--- a/include/linux/mlx4/device.h
+++ b/include/linux/mlx4/device.h
@@ -583,7 +583,7 @@ struct mlx4_uar {
583}; 583};
584 584
585struct mlx4_bf { 585struct mlx4_bf {
586 unsigned long offset; 586 unsigned int offset;
587 int buf_size; 587 int buf_size;
588 struct mlx4_uar *uar; 588 struct mlx4_uar *uar;
589 void __iomem *reg; 589 void __iomem *reg;
diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h
index 7a364f2f3d3f..99b43056a6fe 100644
--- a/include/uapi/linux/ethtool.h
+++ b/include/uapi/linux/ethtool.h
@@ -212,6 +212,7 @@ struct ethtool_value {
212enum tunable_id { 212enum tunable_id {
213 ETHTOOL_ID_UNSPEC, 213 ETHTOOL_ID_UNSPEC,
214 ETHTOOL_RX_COPYBREAK, 214 ETHTOOL_RX_COPYBREAK,
215 ETHTOOL_TX_COPYBREAK,
215}; 216};
216 217
217enum tunable_type_id { 218enum tunable_type_id {
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 27e61b886520..1600aa24d36b 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -1625,6 +1625,7 @@ static int ethtool_tunable_valid(const struct ethtool_tunable *tuna)
1625{ 1625{
1626 switch (tuna->id) { 1626 switch (tuna->id) {
1627 case ETHTOOL_RX_COPYBREAK: 1627 case ETHTOOL_RX_COPYBREAK:
1628 case ETHTOOL_TX_COPYBREAK:
1628 if (tuna->len != sizeof(u32) || 1629 if (tuna->len != sizeof(u32) ||
1629 tuna->type_id != ETHTOOL_TUNABLE_U32) 1630 tuna->type_id != ETHTOOL_TUNABLE_U32)
1630 return -EINVAL; 1631 return -EINVAL;