aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmir Vadai <amirv@mellanox.com>2012-04-04 17:33:24 -0400
committerDavid S. Miller <davem@davemloft.net>2012-04-05 05:08:03 -0400
commit0e98b523c4a4119cbd17e58dff385cc329064694 (patch)
tree4c16b13b5f118cfcf607195d1683ed01ba508b77
parent73a0d907301ece200d32b4e8ba2da2ca296b507f (diff)
net/mlx4_en: Force user priority by QP attribute
Instead of relying on HW to change schedule queue by UP, schedule queue is fixed for a tx_ring, and UP in WQE is ignored in this aspect. This resolves two issues with untagged traffic: 1. untagged traffic has no UP in packet which is needed for QoS. The change above allows setting the schedule queue (and by that the UP) of such a stream. 2. BlueFlame uses the same field used by vlan tag. So forcing UP from QPC allows using BF for untagged but prioritized traffic. In old firmware that force UP is not supported, untagged traffic will not subject to QoS. Because UP is set by QP, need to always have a tx ring per UP, even if pfcrx module paramter is false. Signed-off-by: Amir Vadai <amirv@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_main.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_netdev.c3
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_resources.c6
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_rx.c4
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_tx.c12
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4_en.h6
-rw-r--r--include/linux/mlx4/qp.h3
7 files changed, 19 insertions, 17 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_main.c b/drivers/net/ethernet/mellanox/mlx4/en_main.c
index 2097a7d3c5b8..346fdb2e92a6 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_main.c
@@ -114,7 +114,7 @@ static int mlx4_en_get_profile(struct mlx4_en_dev *mdev)
114 params->prof[i].tx_ring_size = MLX4_EN_DEF_TX_RING_SIZE; 114 params->prof[i].tx_ring_size = MLX4_EN_DEF_TX_RING_SIZE;
115 params->prof[i].rx_ring_size = MLX4_EN_DEF_RX_RING_SIZE; 115 params->prof[i].rx_ring_size = MLX4_EN_DEF_RX_RING_SIZE;
116 params->prof[i].tx_ring_num = MLX4_EN_NUM_TX_RINGS + 116 params->prof[i].tx_ring_num = MLX4_EN_NUM_TX_RINGS +
117 (!!pfcrx) * MLX4_EN_NUM_PPP_RINGS; 117 MLX4_EN_NUM_PPP_RINGS;
118 params->prof[i].rss_rings = 0; 118 params->prof[i].rss_rings = 0;
119 } 119 }
120 120
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index 31b455a49273..2322622b6098 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -650,7 +650,8 @@ int mlx4_en_start_port(struct net_device *dev)
650 650
651 /* Configure ring */ 651 /* Configure ring */
652 tx_ring = &priv->tx_ring[i]; 652 tx_ring = &priv->tx_ring[i];
653 err = mlx4_en_activate_tx_ring(priv, tx_ring, cq->mcq.cqn); 653 err = mlx4_en_activate_tx_ring(priv, tx_ring, cq->mcq.cqn,
654 max(0, i - MLX4_EN_NUM_TX_RINGS));
654 if (err) { 655 if (err) {
655 en_err(priv, "Failed allocating Tx ring\n"); 656 en_err(priv, "Failed allocating Tx ring\n");
656 mlx4_en_deactivate_cq(priv, cq); 657 mlx4_en_deactivate_cq(priv, cq);
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_resources.c b/drivers/net/ethernet/mellanox/mlx4/en_resources.c
index bcbc54c16947..10c24c784b70 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_resources.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_resources.c
@@ -39,7 +39,7 @@
39 39
40void mlx4_en_fill_qp_context(struct mlx4_en_priv *priv, int size, int stride, 40void mlx4_en_fill_qp_context(struct mlx4_en_priv *priv, int size, int stride,
41 int is_tx, int rss, int qpn, int cqn, 41 int is_tx, int rss, int qpn, int cqn,
42 struct mlx4_qp_context *context) 42 int user_prio, struct mlx4_qp_context *context)
43{ 43{
44 struct mlx4_en_dev *mdev = priv->mdev; 44 struct mlx4_en_dev *mdev = priv->mdev;
45 45
@@ -57,6 +57,10 @@ void mlx4_en_fill_qp_context(struct mlx4_en_priv *priv, int size, int stride,
57 context->local_qpn = cpu_to_be32(qpn); 57 context->local_qpn = cpu_to_be32(qpn);
58 context->pri_path.ackto = 1 & 0x07; 58 context->pri_path.ackto = 1 & 0x07;
59 context->pri_path.sched_queue = 0x83 | (priv->port - 1) << 6; 59 context->pri_path.sched_queue = 0x83 | (priv->port - 1) << 6;
60 if (user_prio >= 0) {
61 context->pri_path.sched_queue |= user_prio << 3;
62 context->pri_path.feup = 1 << 6;
63 }
60 context->pri_path.counter_index = 0xff; 64 context->pri_path.counter_index = 0xff;
61 context->cqn_send = cpu_to_be32(cqn); 65 context->cqn_send = cpu_to_be32(cqn);
62 context->cqn_recv = cpu_to_be32(cqn); 66 context->cqn_recv = cpu_to_be32(cqn);
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
index 9adbd53da525..d49a7ac3187d 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
@@ -823,7 +823,7 @@ static int mlx4_en_config_rss_qp(struct mlx4_en_priv *priv, int qpn,
823 823
824 memset(context, 0, sizeof *context); 824 memset(context, 0, sizeof *context);
825 mlx4_en_fill_qp_context(priv, ring->actual_size, ring->stride, 0, 0, 825 mlx4_en_fill_qp_context(priv, ring->actual_size, ring->stride, 0, 0,
826 qpn, ring->cqn, context); 826 qpn, ring->cqn, -1, context);
827 context->db_rec_addr = cpu_to_be64(ring->wqres.db.dma); 827 context->db_rec_addr = cpu_to_be64(ring->wqres.db.dma);
828 828
829 /* Cancel FCS removal if FW allows */ 829 /* Cancel FCS removal if FW allows */
@@ -890,7 +890,7 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv)
890 } 890 }
891 rss_map->indir_qp.event = mlx4_en_sqp_event; 891 rss_map->indir_qp.event = mlx4_en_sqp_event;
892 mlx4_en_fill_qp_context(priv, 0, 0, 0, 1, priv->base_qpn, 892 mlx4_en_fill_qp_context(priv, 0, 0, 0, 1, priv->base_qpn,
893 priv->rx_ring[0].cqn, &context); 893 priv->rx_ring[0].cqn, -1, &context);
894 894
895 if (!priv->prof->rss_rings || priv->prof->rss_rings > priv->rx_ring_num) 895 if (!priv->prof->rss_rings || priv->prof->rss_rings > priv->rx_ring_num)
896 rss_rings = priv->rx_ring_num; 896 rss_rings = priv->rx_ring_num;
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
index 17968244c399..94a605a7cd24 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
@@ -156,7 +156,7 @@ void mlx4_en_destroy_tx_ring(struct mlx4_en_priv *priv,
156 156
157int mlx4_en_activate_tx_ring(struct mlx4_en_priv *priv, 157int mlx4_en_activate_tx_ring(struct mlx4_en_priv *priv,
158 struct mlx4_en_tx_ring *ring, 158 struct mlx4_en_tx_ring *ring,
159 int cq) 159 int cq, int user_prio)
160{ 160{
161 struct mlx4_en_dev *mdev = priv->mdev; 161 struct mlx4_en_dev *mdev = priv->mdev;
162 int err; 162 int err;
@@ -174,7 +174,7 @@ int mlx4_en_activate_tx_ring(struct mlx4_en_priv *priv,
174 ring->doorbell_qpn = ring->qp.qpn << 8; 174 ring->doorbell_qpn = ring->qp.qpn << 8;
175 175
176 mlx4_en_fill_qp_context(priv, ring->size, ring->stride, 1, 0, ring->qpn, 176 mlx4_en_fill_qp_context(priv, ring->size, ring->stride, 1, 0, ring->qpn,
177 ring->cqn, &ring->context); 177 ring->cqn, user_prio, &ring->context);
178 if (ring->bf_enabled) 178 if (ring->bf_enabled)
179 ring->context.usr_page = cpu_to_be32(ring->bf.uar->index); 179 ring->context.usr_page = cpu_to_be32(ring->bf.uar->index);
180 180
@@ -570,18 +570,14 @@ static void build_inline_wqe(struct mlx4_en_tx_desc *tx_desc, struct sk_buff *sk
570 570
571u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb) 571u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb)
572{ 572{
573 struct mlx4_en_priv *priv = netdev_priv(dev);
574 u16 vlan_tag = 0; 573 u16 vlan_tag = 0;
575 574
576 /* If we support per priority flow control and the packet contains 575 if (vlan_tx_tag_present(skb)) {
577 * a vlan tag, send the packet to the TX ring assigned to that priority
578 */
579 if (priv->prof->rx_ppp && vlan_tx_tag_present(skb)) {
580 vlan_tag = vlan_tx_tag_get(skb); 576 vlan_tag = vlan_tx_tag_get(skb);
581 return MLX4_EN_NUM_TX_RINGS + (vlan_tag >> 13); 577 return MLX4_EN_NUM_TX_RINGS + (vlan_tag >> 13);
582 } 578 }
583 579
584 return skb_tx_hash(dev, skb); 580 return __skb_tx_hash(dev, skb, MLX4_EN_NUM_TX_RINGS);
585} 581}
586 582
587static void mlx4_bf_copy(void __iomem *dst, unsigned long *src, unsigned bytecnt) 583static void mlx4_bf_copy(void __iomem *dst, unsigned long *src, unsigned bytecnt)
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
index 9e2b911a1230..5bd7c2a3823e 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
@@ -521,7 +521,7 @@ int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv, struct mlx4_en_tx_ring *ri
521void mlx4_en_destroy_tx_ring(struct mlx4_en_priv *priv, struct mlx4_en_tx_ring *ring); 521void mlx4_en_destroy_tx_ring(struct mlx4_en_priv *priv, struct mlx4_en_tx_ring *ring);
522int mlx4_en_activate_tx_ring(struct mlx4_en_priv *priv, 522int mlx4_en_activate_tx_ring(struct mlx4_en_priv *priv,
523 struct mlx4_en_tx_ring *ring, 523 struct mlx4_en_tx_ring *ring,
524 int cq); 524 int cq, int user_prio);
525void mlx4_en_deactivate_tx_ring(struct mlx4_en_priv *priv, 525void mlx4_en_deactivate_tx_ring(struct mlx4_en_priv *priv,
526 struct mlx4_en_tx_ring *ring); 526 struct mlx4_en_tx_ring *ring);
527 527
@@ -539,8 +539,8 @@ int mlx4_en_process_rx_cq(struct net_device *dev,
539 int budget); 539 int budget);
540int mlx4_en_poll_rx_cq(struct napi_struct *napi, int budget); 540int mlx4_en_poll_rx_cq(struct napi_struct *napi, int budget);
541void mlx4_en_fill_qp_context(struct mlx4_en_priv *priv, int size, int stride, 541void mlx4_en_fill_qp_context(struct mlx4_en_priv *priv, int size, int stride,
542 int is_tx, int rss, int qpn, int cqn, 542 int is_tx, int rss, int qpn, int cqn, int user_prio,
543 struct mlx4_qp_context *context); 543 struct mlx4_qp_context *context);
544void mlx4_en_sqp_event(struct mlx4_qp *qp, enum mlx4_event event); 544void mlx4_en_sqp_event(struct mlx4_qp *qp, enum mlx4_event event);
545int mlx4_en_map_buffer(struct mlx4_buf *buf); 545int mlx4_en_map_buffer(struct mlx4_buf *buf);
546void mlx4_en_unmap_buffer(struct mlx4_buf *buf); 546void mlx4_en_unmap_buffer(struct mlx4_buf *buf);
diff --git a/include/linux/mlx4/qp.h b/include/linux/mlx4/qp.h
index 091f9e7dc8b9..96005d75893c 100644
--- a/include/linux/mlx4/qp.h
+++ b/include/linux/mlx4/qp.h
@@ -139,7 +139,8 @@ struct mlx4_qp_path {
139 u8 rgid[16]; 139 u8 rgid[16];
140 u8 sched_queue; 140 u8 sched_queue;
141 u8 vlan_index; 141 u8 vlan_index;
142 u8 reserved3[2]; 142 u8 feup;
143 u8 reserved3;
143 u8 reserved4[2]; 144 u8 reserved4[2];
144 u8 dmac[6]; 145 u8 dmac[6];
145}; 146};