aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAmir Vadai <amirv@mellanox.com>2012-04-04 17:33:26 -0400
committerDavid S. Miller <davem@davemloft.net>2012-04-05 05:08:04 -0400
commit564c274c3df07d727fbe23684dc3077a9dd30607 (patch)
tree32cf7763a8cb6c0035348573e4f09354230bd071 /drivers
parente5395e92a470769d67369c002a41e59619f5214b (diff)
net/mlx4_en: DCB QoS support
Set TSA, promised BW and PFC using IEEE 802.1qaz netlink commands. Signed-off-by: Amir Vadai <amirv@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/Kconfig12
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/Makefile1
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c209
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_netdev.c5
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4_en.h21
5 files changed, 248 insertions, 0 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/Kconfig b/drivers/net/ethernet/mellanox/mlx4/Kconfig
index 1bb93531f1ba..5f027f95cc84 100644
--- a/drivers/net/ethernet/mellanox/mlx4/Kconfig
+++ b/drivers/net/ethernet/mellanox/mlx4/Kconfig
@@ -11,6 +11,18 @@ config MLX4_EN
11 This driver supports Mellanox Technologies ConnectX Ethernet 11 This driver supports Mellanox Technologies ConnectX Ethernet
12 devices. 12 devices.
13 13
14config MLX4_EN_DCB
15 bool "Data Center Bridging (DCB) Support"
16 default y
17 depends on MLX4_EN && DCB
18 ---help---
19 Say Y here if you want to use Data Center Bridging (DCB) in the
20 driver.
21 If set to N, will not be able to configure QoS and ratelimit attributes.
22 This flag is depended on the kernel's DCB support.
23
24 If unsure, set to Y
25
14config MLX4_CORE 26config MLX4_CORE
15 tristate 27 tristate
16 depends on PCI 28 depends on PCI
diff --git a/drivers/net/ethernet/mellanox/mlx4/Makefile b/drivers/net/ethernet/mellanox/mlx4/Makefile
index 4a40ab967eeb..293127d28b33 100644
--- a/drivers/net/ethernet/mellanox/mlx4/Makefile
+++ b/drivers/net/ethernet/mellanox/mlx4/Makefile
@@ -7,3 +7,4 @@ obj-$(CONFIG_MLX4_EN) += mlx4_en.o
7 7
8mlx4_en-y := en_main.o en_tx.o en_rx.o en_ethtool.o en_port.o en_cq.o \ 8mlx4_en-y := en_main.o en_tx.o en_rx.o en_ethtool.o en_port.o en_cq.o \
9 en_resources.o en_netdev.o en_selftest.o 9 en_resources.o en_netdev.o en_selftest.o
10mlx4_en-$(CONFIG_MLX4_EN_DCB) += en_dcb_nl.o
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c b/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c
new file mode 100644
index 000000000000..6892320adaf7
--- /dev/null
+++ b/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c
@@ -0,0 +1,209 @@
1/*
2 * Copyright (c) 2011 Mellanox Technologies. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 *
32 */
33
34#include <linux/dcbnl.h>
35
36#include "mlx4_en.h"
37
38static int mlx4_en_dcbnl_ieee_getets(struct net_device *dev,
39 struct ieee_ets *ets)
40{
41 struct mlx4_en_priv *priv = netdev_priv(dev);
42 struct ieee_ets *my_ets = &priv->ets;
43
44 /* No IEEE PFC settings available */
45 if (!my_ets)
46 return -EINVAL;
47
48 ets->ets_cap = IEEE_8021QAZ_MAX_TCS;
49 ets->cbs = my_ets->cbs;
50 memcpy(ets->tc_tx_bw, my_ets->tc_tx_bw, sizeof(ets->tc_tx_bw));
51 memcpy(ets->tc_tsa, my_ets->tc_tsa, sizeof(ets->tc_tsa));
52 memcpy(ets->prio_tc, my_ets->prio_tc, sizeof(ets->prio_tc));
53
54 return 0;
55}
56
57static int mlx4_en_ets_validate(struct mlx4_en_priv *priv, struct ieee_ets *ets)
58{
59 int i;
60 int total_ets_bw = 0;
61 int has_ets_tc = 0;
62
63 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
64 if (ets->prio_tc[i] > MLX4_EN_NUM_UP) {
65 en_err(priv, "Bad priority in UP <=> TC mapping. TC: %d, UP: %d\n",
66 i, ets->prio_tc[i]);
67 return -EINVAL;
68 }
69
70 switch (ets->tc_tsa[i]) {
71 case IEEE_8021QAZ_TSA_STRICT:
72 break;
73 case IEEE_8021QAZ_TSA_ETS:
74 has_ets_tc = 1;
75 total_ets_bw += ets->tc_tx_bw[i];
76 break;
77 default:
78 en_err(priv, "TC[%d]: Not supported TSA: %d\n",
79 i, ets->tc_tsa[i]);
80 return -ENOTSUPP;
81 }
82 }
83
84 if (has_ets_tc && total_ets_bw != MLX4_EN_BW_MAX) {
85 en_err(priv, "Bad ETS BW sum: %d. Should be exactly 100%%\n",
86 total_ets_bw);
87 return -EINVAL;
88 }
89
90 return 0;
91}
92
93static int mlx4_en_config_port_scheduler(struct mlx4_en_priv *priv,
94 struct ieee_ets *ets, u16 *ratelimit)
95{
96 struct mlx4_en_dev *mdev = priv->mdev;
97 int num_strict = 0;
98 int i;
99 __u8 tc_tx_bw[IEEE_8021QAZ_MAX_TCS] = { 0 };
100 __u8 pg[IEEE_8021QAZ_MAX_TCS] = { 0 };
101
102 ets = ets ?: &priv->ets;
103
104 /* higher TC means higher priority => lower pg */
105 for (i = IEEE_8021QAZ_MAX_TCS - 1; i >= 0; i--) {
106 switch (ets->tc_tsa[i]) {
107 case IEEE_8021QAZ_TSA_STRICT:
108 pg[i] = num_strict++;
109 tc_tx_bw[i] = MLX4_EN_BW_MAX;
110 break;
111 case IEEE_8021QAZ_TSA_ETS:
112 pg[i] = MLX4_EN_TC_ETS;
113 tc_tx_bw[i] = ets->tc_tx_bw[i] ?: MLX4_EN_BW_MIN;
114 break;
115 }
116 }
117
118 return mlx4_SET_PORT_SCHEDULER(mdev->dev, priv->port, tc_tx_bw, pg,
119 ratelimit);
120}
121
122static int
123mlx4_en_dcbnl_ieee_setets(struct net_device *dev, struct ieee_ets *ets)
124{
125 struct mlx4_en_priv *priv = netdev_priv(dev);
126 struct mlx4_en_dev *mdev = priv->mdev;
127 int err;
128
129 err = mlx4_en_ets_validate(priv, ets);
130 if (err)
131 return err;
132
133 err = mlx4_SET_PORT_PRIO2TC(mdev->dev, priv->port, ets->prio_tc);
134 if (err)
135 return err;
136
137 err = mlx4_en_config_port_scheduler(priv, ets, NULL);
138 if (err)
139 return err;
140
141 memcpy(&priv->ets, ets, sizeof(priv->ets));
142
143 return 0;
144}
145
146static int mlx4_en_dcbnl_ieee_getpfc(struct net_device *dev,
147 struct ieee_pfc *pfc)
148{
149 struct mlx4_en_priv *priv = netdev_priv(dev);
150
151 pfc->pfc_cap = IEEE_8021QAZ_MAX_TCS;
152 pfc->pfc_en = priv->prof->tx_ppp;
153
154 return 0;
155}
156
157static int mlx4_en_dcbnl_ieee_setpfc(struct net_device *dev,
158 struct ieee_pfc *pfc)
159{
160 struct mlx4_en_priv *priv = netdev_priv(dev);
161 struct mlx4_en_dev *mdev = priv->mdev;
162 int err;
163
164 en_dbg(DRV, priv, "cap: 0x%x en: 0x%x mbc: 0x%x delay: %d\n",
165 pfc->pfc_cap,
166 pfc->pfc_en,
167 pfc->mbc,
168 pfc->delay);
169
170 priv->prof->rx_pause = priv->prof->tx_pause = !!pfc->pfc_en;
171 priv->prof->rx_ppp = priv->prof->tx_ppp = pfc->pfc_en;
172
173 err = mlx4_SET_PORT_general(mdev->dev, priv->port,
174 priv->rx_skb_size + ETH_FCS_LEN,
175 priv->prof->tx_pause,
176 priv->prof->tx_ppp,
177 priv->prof->rx_pause,
178 priv->prof->rx_ppp);
179 if (err)
180 en_err(priv, "Failed setting pause params\n");
181
182 return err;
183}
184
185static u8 mlx4_en_dcbnl_getdcbx(struct net_device *dev)
186{
187 return DCB_CAP_DCBX_VER_IEEE;
188}
189
190static u8 mlx4_en_dcbnl_setdcbx(struct net_device *dev, u8 mode)
191{
192 if ((mode & DCB_CAP_DCBX_LLD_MANAGED) ||
193 (mode & DCB_CAP_DCBX_VER_CEE) ||
194 !(mode & DCB_CAP_DCBX_VER_IEEE) ||
195 !(mode & DCB_CAP_DCBX_HOST))
196 return 1;
197
198 return 0;
199}
200
201const struct dcbnl_rtnl_ops mlx4_en_dcbnl_ops = {
202 .ieee_getets = mlx4_en_dcbnl_ieee_getets,
203 .ieee_setets = mlx4_en_dcbnl_ieee_setets,
204 .ieee_getpfc = mlx4_en_dcbnl_ieee_getpfc,
205 .ieee_setpfc = mlx4_en_dcbnl_ieee_setpfc,
206
207 .getdcbx = mlx4_en_dcbnl_getdcbx,
208 .setdcbx = mlx4_en_dcbnl_setdcbx,
209};
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index 2322622b6098..107f00553bd3 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -967,6 +967,7 @@ void mlx4_en_destroy_netdev(struct net_device *dev)
967 mutex_unlock(&mdev->state_lock); 967 mutex_unlock(&mdev->state_lock);
968 968
969 mlx4_en_free_resources(priv); 969 mlx4_en_free_resources(priv);
970
970 free_netdev(dev); 971 free_netdev(dev);
971} 972}
972 973
@@ -1080,6 +1081,10 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
1080 INIT_WORK(&priv->watchdog_task, mlx4_en_restart); 1081 INIT_WORK(&priv->watchdog_task, mlx4_en_restart);
1081 INIT_WORK(&priv->linkstate_task, mlx4_en_linkstate); 1082 INIT_WORK(&priv->linkstate_task, mlx4_en_linkstate);
1082 INIT_DELAYED_WORK(&priv->stats_task, mlx4_en_do_get_stats); 1083 INIT_DELAYED_WORK(&priv->stats_task, mlx4_en_do_get_stats);
1084#ifdef CONFIG_MLX4_EN_DCB
1085 if (!mlx4_is_slave(priv->mdev->dev))
1086 dev->dcbnl_ops = &mlx4_en_dcbnl_ops;
1087#endif
1083 1088
1084 /* Query for default mac and max mtu */ 1089 /* Query for default mac and max mtu */
1085 priv->max_mtu = mdev->dev->caps.eth_mtu_cap[priv->port]; 1090 priv->max_mtu = mdev->dev->caps.eth_mtu_cap[priv->port];
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
index 5bd7c2a3823e..97d4f3540f6e 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
@@ -40,6 +40,9 @@
40#include <linux/mutex.h> 40#include <linux/mutex.h>
41#include <linux/netdevice.h> 41#include <linux/netdevice.h>
42#include <linux/if_vlan.h> 42#include <linux/if_vlan.h>
43#ifdef CONFIG_MLX4_EN_DCB
44#include <linux/dcbnl.h>
45#endif
43 46
44#include <linux/mlx4/device.h> 47#include <linux/mlx4/device.h>
45#include <linux/mlx4/qp.h> 48#include <linux/mlx4/qp.h>
@@ -110,6 +113,7 @@ enum {
110#define MLX4_EN_NUM_TX_RINGS 8 113#define MLX4_EN_NUM_TX_RINGS 8
111#define MLX4_EN_NUM_PPP_RINGS 8 114#define MLX4_EN_NUM_PPP_RINGS 8
112#define MAX_TX_RINGS (MLX4_EN_NUM_TX_RINGS + MLX4_EN_NUM_PPP_RINGS) 115#define MAX_TX_RINGS (MLX4_EN_NUM_TX_RINGS + MLX4_EN_NUM_PPP_RINGS)
116#define MLX4_EN_NUM_UP 8
113#define MLX4_EN_DEF_TX_RING_SIZE 512 117#define MLX4_EN_DEF_TX_RING_SIZE 512
114#define MLX4_EN_DEF_RX_RING_SIZE 1024 118#define MLX4_EN_DEF_RX_RING_SIZE 1024
115 119
@@ -410,6 +414,15 @@ struct mlx4_en_frag_info {
410 414
411}; 415};
412 416
417#ifdef CONFIG_MLX4_EN_DCB
418/* Minimal TC BW - setting to 0 will block traffic */
419#define MLX4_EN_BW_MIN 1
420#define MLX4_EN_BW_MAX 100 /* Utilize 100% of the line */
421
422#define MLX4_EN_TC_ETS 7
423
424#endif
425
413struct mlx4_en_priv { 426struct mlx4_en_priv {
414 struct mlx4_en_dev *mdev; 427 struct mlx4_en_dev *mdev;
415 struct mlx4_en_port_profile *prof; 428 struct mlx4_en_port_profile *prof;
@@ -483,6 +496,10 @@ struct mlx4_en_priv {
483 int vids[128]; 496 int vids[128];
484 bool wol; 497 bool wol;
485 struct device *ddev; 498 struct device *ddev;
499
500#ifdef CONFIG_MLX4_EN_DCB
501 struct ieee_ets ets;
502#endif
486}; 503};
487 504
488enum mlx4_en_wol { 505enum mlx4_en_wol {
@@ -557,6 +574,10 @@ int mlx4_SET_VLAN_FLTR(struct mlx4_dev *dev, struct mlx4_en_priv *priv);
557int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset); 574int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset);
558int mlx4_en_QUERY_PORT(struct mlx4_en_dev *mdev, u8 port); 575int mlx4_en_QUERY_PORT(struct mlx4_en_dev *mdev, u8 port);
559 576
577#ifdef CONFIG_MLX4_EN_DCB
578extern const struct dcbnl_rtnl_ops mlx4_en_dcbnl_ops;
579#endif
580
560#define MLX4_EN_NUM_SELF_TEST 5 581#define MLX4_EN_NUM_SELF_TEST 5
561void mlx4_en_ex_selftest(struct net_device *dev, u32 *flags, u64 *buf); 582void mlx4_en_ex_selftest(struct net_device *dev, u32 *flags, u64 *buf);
562u64 mlx4_en_mac_to_u64(u8 *addr); 583u64 mlx4_en_mac_to_u64(u8 *addr);