aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/mlx4
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/mlx4')
-rw-r--r--drivers/net/mlx4/Makefile2
-rw-r--r--drivers/net/mlx4/alloc.c17
-rw-r--r--drivers/net/mlx4/en_ethtool.c173
-rw-r--r--drivers/net/mlx4/en_main.c24
-rw-r--r--drivers/net/mlx4/en_netdev.c28
-rw-r--r--drivers/net/mlx4/en_port.c32
-rw-r--r--drivers/net/mlx4/en_port.h14
-rw-r--r--drivers/net/mlx4/en_rx.c104
-rw-r--r--drivers/net/mlx4/en_selftest.c179
-rw-r--r--drivers/net/mlx4/en_tx.c20
-rw-r--r--drivers/net/mlx4/eq.c44
-rw-r--r--drivers/net/mlx4/fw.c15
-rw-r--r--drivers/net/mlx4/fw.h6
-rw-r--r--drivers/net/mlx4/main.c6
-rw-r--r--drivers/net/mlx4/mlx4_en.h39
-rw-r--r--drivers/net/mlx4/profile.c2
16 files changed, 510 insertions, 195 deletions
diff --git a/drivers/net/mlx4/Makefile b/drivers/net/mlx4/Makefile
index 1fd068e1d930..d1aa45a15854 100644
--- a/drivers/net/mlx4/Makefile
+++ b/drivers/net/mlx4/Makefile
@@ -6,4 +6,4 @@ mlx4_core-y := alloc.o catas.o cmd.o cq.o eq.o fw.o icm.o intf.o main.o mcg.o \
6obj-$(CONFIG_MLX4_EN) += mlx4_en.o 6obj-$(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 9 en_resources.o en_netdev.o en_selftest.o
diff --git a/drivers/net/mlx4/alloc.c b/drivers/net/mlx4/alloc.c
index 8c8515619b8e..8f4bf1f07c11 100644
--- a/drivers/net/mlx4/alloc.c
+++ b/drivers/net/mlx4/alloc.c
@@ -74,7 +74,7 @@ void mlx4_bitmap_free(struct mlx4_bitmap *bitmap, u32 obj)
74 74
75u32 mlx4_bitmap_alloc_range(struct mlx4_bitmap *bitmap, int cnt, int align) 75u32 mlx4_bitmap_alloc_range(struct mlx4_bitmap *bitmap, int cnt, int align)
76{ 76{
77 u32 obj, i; 77 u32 obj;
78 78
79 if (likely(cnt == 1 && align == 1)) 79 if (likely(cnt == 1 && align == 1))
80 return mlx4_bitmap_alloc(bitmap); 80 return mlx4_bitmap_alloc(bitmap);
@@ -91,8 +91,7 @@ u32 mlx4_bitmap_alloc_range(struct mlx4_bitmap *bitmap, int cnt, int align)
91 } 91 }
92 92
93 if (obj < bitmap->max) { 93 if (obj < bitmap->max) {
94 for (i = 0; i < cnt; i++) 94 bitmap_set(bitmap->table, obj, cnt);
95 set_bit(obj + i, bitmap->table);
96 if (obj == bitmap->last) { 95 if (obj == bitmap->last) {
97 bitmap->last = (obj + cnt); 96 bitmap->last = (obj + cnt);
98 if (bitmap->last >= bitmap->max) 97 if (bitmap->last >= bitmap->max)
@@ -109,13 +108,10 @@ u32 mlx4_bitmap_alloc_range(struct mlx4_bitmap *bitmap, int cnt, int align)
109 108
110void mlx4_bitmap_free_range(struct mlx4_bitmap *bitmap, u32 obj, int cnt) 109void mlx4_bitmap_free_range(struct mlx4_bitmap *bitmap, u32 obj, int cnt)
111{ 110{
112 u32 i;
113
114 obj &= bitmap->max + bitmap->reserved_top - 1; 111 obj &= bitmap->max + bitmap->reserved_top - 1;
115 112
116 spin_lock(&bitmap->lock); 113 spin_lock(&bitmap->lock);
117 for (i = 0; i < cnt; i++) 114 bitmap_clear(bitmap->table, obj, cnt);
118 clear_bit(obj + i, bitmap->table);
119 bitmap->last = min(bitmap->last, obj); 115 bitmap->last = min(bitmap->last, obj);
120 bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top) 116 bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top)
121 & bitmap->mask; 117 & bitmap->mask;
@@ -125,8 +121,6 @@ void mlx4_bitmap_free_range(struct mlx4_bitmap *bitmap, u32 obj, int cnt)
125int mlx4_bitmap_init(struct mlx4_bitmap *bitmap, u32 num, u32 mask, 121int mlx4_bitmap_init(struct mlx4_bitmap *bitmap, u32 num, u32 mask,
126 u32 reserved_bot, u32 reserved_top) 122 u32 reserved_bot, u32 reserved_top)
127{ 123{
128 int i;
129
130 /* num must be a power of 2 */ 124 /* num must be a power of 2 */
131 if (num != roundup_pow_of_two(num)) 125 if (num != roundup_pow_of_two(num))
132 return -EINVAL; 126 return -EINVAL;
@@ -142,8 +136,7 @@ int mlx4_bitmap_init(struct mlx4_bitmap *bitmap, u32 num, u32 mask,
142 if (!bitmap->table) 136 if (!bitmap->table)
143 return -ENOMEM; 137 return -ENOMEM;
144 138
145 for (i = 0; i < reserved_bot; ++i) 139 bitmap_set(bitmap->table, 0, reserved_bot);
146 set_bit(i, bitmap->table);
147 140
148 return 0; 141 return 0;
149} 142}
@@ -188,7 +181,7 @@ int mlx4_buf_alloc(struct mlx4_dev *dev, int size, int max_direct,
188 buf->nbufs = (size + PAGE_SIZE - 1) / PAGE_SIZE; 181 buf->nbufs = (size + PAGE_SIZE - 1) / PAGE_SIZE;
189 buf->npages = buf->nbufs; 182 buf->npages = buf->nbufs;
190 buf->page_shift = PAGE_SHIFT; 183 buf->page_shift = PAGE_SHIFT;
191 buf->page_list = kzalloc(buf->nbufs * sizeof *buf->page_list, 184 buf->page_list = kcalloc(buf->nbufs, sizeof(*buf->page_list),
192 GFP_KERNEL); 185 GFP_KERNEL);
193 if (!buf->page_list) 186 if (!buf->page_list)
194 return -ENOMEM; 187 return -ENOMEM;
diff --git a/drivers/net/mlx4/en_ethtool.c b/drivers/net/mlx4/en_ethtool.c
index b275238fe70d..056152b3ff58 100644
--- a/drivers/net/mlx4/en_ethtool.c
+++ b/drivers/net/mlx4/en_ethtool.c
@@ -39,21 +39,6 @@
39#include "en_port.h" 39#include "en_port.h"
40 40
41 41
42static void mlx4_en_update_lro_stats(struct mlx4_en_priv *priv)
43{
44 int i;
45
46 priv->port_stats.lro_aggregated = 0;
47 priv->port_stats.lro_flushed = 0;
48 priv->port_stats.lro_no_desc = 0;
49
50 for (i = 0; i < priv->rx_ring_num; i++) {
51 priv->port_stats.lro_aggregated += priv->rx_ring[i].lro.stats.aggregated;
52 priv->port_stats.lro_flushed += priv->rx_ring[i].lro.stats.flushed;
53 priv->port_stats.lro_no_desc += priv->rx_ring[i].lro.stats.no_desc;
54 }
55}
56
57static void 42static void
58mlx4_en_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo) 43mlx4_en_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
59{ 44{
@@ -112,7 +97,7 @@ static const char main_strings[][ETH_GSTRING_LEN] = {
112 "tx_heartbeat_errors", "tx_window_errors", 97 "tx_heartbeat_errors", "tx_window_errors",
113 98
114 /* port statistics */ 99 /* port statistics */
115 "lro_aggregated", "lro_flushed", "lro_no_desc", "tso_packets", 100 "tso_packets",
116 "queue_stopped", "wake_queue", "tx_timeout", "rx_alloc_failed", 101 "queue_stopped", "wake_queue", "tx_timeout", "rx_alloc_failed",
117 "rx_csum_good", "rx_csum_none", "tx_chksum_offload", 102 "rx_csum_good", "rx_csum_none", "tx_chksum_offload",
118 103
@@ -125,6 +110,14 @@ static const char main_strings[][ETH_GSTRING_LEN] = {
125#define NUM_MAIN_STATS 21 110#define NUM_MAIN_STATS 21
126#define NUM_ALL_STATS (NUM_MAIN_STATS + NUM_PORT_STATS + NUM_PKT_STATS + NUM_PERF_STATS) 111#define NUM_ALL_STATS (NUM_MAIN_STATS + NUM_PORT_STATS + NUM_PKT_STATS + NUM_PERF_STATS)
127 112
113static const char mlx4_en_test_names[][ETH_GSTRING_LEN]= {
114 "Interupt Test",
115 "Link Test",
116 "Speed Test",
117 "Register Test",
118 "Loopback Test",
119};
120
128static u32 mlx4_en_get_msglevel(struct net_device *dev) 121static u32 mlx4_en_get_msglevel(struct net_device *dev)
129{ 122{
130 return ((struct mlx4_en_priv *) netdev_priv(dev))->msg_enable; 123 return ((struct mlx4_en_priv *) netdev_priv(dev))->msg_enable;
@@ -146,10 +139,15 @@ static int mlx4_en_get_sset_count(struct net_device *dev, int sset)
146{ 139{
147 struct mlx4_en_priv *priv = netdev_priv(dev); 140 struct mlx4_en_priv *priv = netdev_priv(dev);
148 141
149 if (sset != ETH_SS_STATS) 142 switch (sset) {
143 case ETH_SS_STATS:
144 return NUM_ALL_STATS +
145 (priv->tx_ring_num + priv->rx_ring_num) * 2;
146 case ETH_SS_TEST:
147 return MLX4_EN_NUM_SELF_TEST - !(priv->mdev->dev->caps.loopback_support) * 2;
148 default:
150 return -EOPNOTSUPP; 149 return -EOPNOTSUPP;
151 150 }
152 return NUM_ALL_STATS + (priv->tx_ring_num + priv->rx_ring_num) * 2;
153} 151}
154 152
155static void mlx4_en_get_ethtool_stats(struct net_device *dev, 153static void mlx4_en_get_ethtool_stats(struct net_device *dev,
@@ -161,8 +159,6 @@ static void mlx4_en_get_ethtool_stats(struct net_device *dev,
161 159
162 spin_lock_bh(&priv->stats_lock); 160 spin_lock_bh(&priv->stats_lock);
163 161
164 mlx4_en_update_lro_stats(priv);
165
166 for (i = 0; i < NUM_MAIN_STATS; i++) 162 for (i = 0; i < NUM_MAIN_STATS; i++)
167 data[index++] = ((unsigned long *) &priv->stats)[i]; 163 data[index++] = ((unsigned long *) &priv->stats)[i];
168 for (i = 0; i < NUM_PORT_STATS; i++) 164 for (i = 0; i < NUM_PORT_STATS; i++)
@@ -181,6 +177,12 @@ static void mlx4_en_get_ethtool_stats(struct net_device *dev,
181 177
182} 178}
183 179
180static void mlx4_en_self_test(struct net_device *dev,
181 struct ethtool_test *etest, u64 *buf)
182{
183 mlx4_en_ex_selftest(dev, &etest->flags, buf);
184}
185
184static void mlx4_en_get_strings(struct net_device *dev, 186static void mlx4_en_get_strings(struct net_device *dev,
185 uint32_t stringset, uint8_t *data) 187 uint32_t stringset, uint8_t *data)
186{ 188{
@@ -188,44 +190,76 @@ static void mlx4_en_get_strings(struct net_device *dev,
188 int index = 0; 190 int index = 0;
189 int i; 191 int i;
190 192
191 if (stringset != ETH_SS_STATS) 193 switch (stringset) {
192 return; 194 case ETH_SS_TEST:
193 195 for (i = 0; i < MLX4_EN_NUM_SELF_TEST - 2; i++)
194 /* Add main counters */ 196 strcpy(data + i * ETH_GSTRING_LEN, mlx4_en_test_names[i]);
195 for (i = 0; i < NUM_MAIN_STATS; i++) 197 if (priv->mdev->dev->caps.loopback_support)
196 strcpy(data + (index++) * ETH_GSTRING_LEN, main_strings[i]); 198 for (; i < MLX4_EN_NUM_SELF_TEST; i++)
197 for (i = 0; i < NUM_PORT_STATS; i++) 199 strcpy(data + i * ETH_GSTRING_LEN, mlx4_en_test_names[i]);
198 strcpy(data + (index++) * ETH_GSTRING_LEN, 200 break;
201
202 case ETH_SS_STATS:
203 /* Add main counters */
204 for (i = 0; i < NUM_MAIN_STATS; i++)
205 strcpy(data + (index++) * ETH_GSTRING_LEN, main_strings[i]);
206 for (i = 0; i< NUM_PORT_STATS; i++)
207 strcpy(data + (index++) * ETH_GSTRING_LEN,
199 main_strings[i + NUM_MAIN_STATS]); 208 main_strings[i + NUM_MAIN_STATS]);
200 for (i = 0; i < priv->tx_ring_num; i++) { 209 for (i = 0; i < priv->tx_ring_num; i++) {
201 sprintf(data + (index++) * ETH_GSTRING_LEN, 210 sprintf(data + (index++) * ETH_GSTRING_LEN,
202 "tx%d_packets", i); 211 "tx%d_packets", i);
203 sprintf(data + (index++) * ETH_GSTRING_LEN, 212 sprintf(data + (index++) * ETH_GSTRING_LEN,
204 "tx%d_bytes", i); 213 "tx%d_bytes", i);
205 } 214 }
206 for (i = 0; i < priv->rx_ring_num; i++) { 215 for (i = 0; i < priv->rx_ring_num; i++) {
207 sprintf(data + (index++) * ETH_GSTRING_LEN, 216 sprintf(data + (index++) * ETH_GSTRING_LEN,
208 "rx%d_packets", i); 217 "rx%d_packets", i);
209 sprintf(data + (index++) * ETH_GSTRING_LEN, 218 sprintf(data + (index++) * ETH_GSTRING_LEN,
210 "rx%d_bytes", i); 219 "rx%d_bytes", i);
211 } 220 }
212 for (i = 0; i < NUM_PKT_STATS; i++) 221 for (i = 0; i< NUM_PKT_STATS; i++)
213 strcpy(data + (index++) * ETH_GSTRING_LEN, 222 strcpy(data + (index++) * ETH_GSTRING_LEN,
214 main_strings[i + NUM_MAIN_STATS + NUM_PORT_STATS]); 223 main_strings[i + NUM_MAIN_STATS + NUM_PORT_STATS]);
224 break;
225 }
215} 226}
216 227
217static int mlx4_en_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) 228static int mlx4_en_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
218{ 229{
230 struct mlx4_en_priv *priv = netdev_priv(dev);
231 int trans_type;
232
219 cmd->autoneg = AUTONEG_DISABLE; 233 cmd->autoneg = AUTONEG_DISABLE;
220 cmd->supported = SUPPORTED_10000baseT_Full; 234 cmd->supported = SUPPORTED_10000baseT_Full;
221 cmd->advertising = ADVERTISED_1000baseT_Full; 235 cmd->advertising = ADVERTISED_10000baseT_Full;
236
237 if (mlx4_en_QUERY_PORT(priv->mdev, priv->port))
238 return -ENOMEM;
239
240 trans_type = priv->port_state.transciver;
222 if (netif_carrier_ok(dev)) { 241 if (netif_carrier_ok(dev)) {
223 cmd->speed = SPEED_10000; 242 cmd->speed = priv->port_state.link_speed;
224 cmd->duplex = DUPLEX_FULL; 243 cmd->duplex = DUPLEX_FULL;
225 } else { 244 } else {
226 cmd->speed = -1; 245 cmd->speed = -1;
227 cmd->duplex = -1; 246 cmd->duplex = -1;
228 } 247 }
248
249 if (trans_type > 0 && trans_type <= 0xC) {
250 cmd->port = PORT_FIBRE;
251 cmd->transceiver = XCVR_EXTERNAL;
252 cmd->supported |= SUPPORTED_FIBRE;
253 cmd->advertising |= ADVERTISED_FIBRE;
254 } else if (trans_type == 0x80 || trans_type == 0) {
255 cmd->port = PORT_TP;
256 cmd->transceiver = XCVR_INTERNAL;
257 cmd->supported |= SUPPORTED_TP;
258 cmd->advertising |= ADVERTISED_TP;
259 } else {
260 cmd->port = -1;
261 cmd->transceiver = -1;
262 }
229 return 0; 263 return 0;
230} 264}
231 265
@@ -343,8 +377,9 @@ static int mlx4_en_set_ringparam(struct net_device *dev,
343 tx_size = max_t(u32, tx_size, MLX4_EN_MIN_TX_SIZE); 377 tx_size = max_t(u32, tx_size, MLX4_EN_MIN_TX_SIZE);
344 tx_size = min_t(u32, tx_size, MLX4_EN_MAX_TX_SIZE); 378 tx_size = min_t(u32, tx_size, MLX4_EN_MAX_TX_SIZE);
345 379
346 if (rx_size == priv->prof->rx_ring_size && 380 if (rx_size == (priv->port_up ? priv->rx_ring[0].actual_size :
347 tx_size == priv->prof->tx_ring_size) 381 priv->rx_ring[0].size) &&
382 tx_size == priv->tx_ring[0].size)
348 return 0; 383 return 0;
349 384
350 mutex_lock(&mdev->state_lock); 385 mutex_lock(&mdev->state_lock);
@@ -378,49 +413,13 @@ static void mlx4_en_get_ringparam(struct net_device *dev,
378 struct ethtool_ringparam *param) 413 struct ethtool_ringparam *param)
379{ 414{
380 struct mlx4_en_priv *priv = netdev_priv(dev); 415 struct mlx4_en_priv *priv = netdev_priv(dev);
381 struct mlx4_en_dev *mdev = priv->mdev;
382 416
383 memset(param, 0, sizeof(*param)); 417 memset(param, 0, sizeof(*param));
384 param->rx_max_pending = MLX4_EN_MAX_RX_SIZE; 418 param->rx_max_pending = MLX4_EN_MAX_RX_SIZE;
385 param->tx_max_pending = MLX4_EN_MAX_TX_SIZE; 419 param->tx_max_pending = MLX4_EN_MAX_TX_SIZE;
386 param->rx_pending = mdev->profile.prof[priv->port].rx_ring_size; 420 param->rx_pending = priv->port_up ?
387 param->tx_pending = mdev->profile.prof[priv->port].tx_ring_size; 421 priv->rx_ring[0].actual_size : priv->rx_ring[0].size;
388} 422 param->tx_pending = priv->tx_ring[0].size;
389
390static int mlx4_ethtool_op_set_flags(struct net_device *dev, u32 data)
391{
392 struct mlx4_en_priv *priv = netdev_priv(dev);
393 struct mlx4_en_dev *mdev = priv->mdev;
394 int rc = 0;
395 int changed = 0;
396
397 if (data & ~ETH_FLAG_LRO)
398 return -EOPNOTSUPP;
399
400 if (data & ETH_FLAG_LRO) {
401 if (mdev->profile.num_lro == 0)
402 return -EOPNOTSUPP;
403 if (!(dev->features & NETIF_F_LRO))
404 changed = 1;
405 } else if (dev->features & NETIF_F_LRO) {
406 changed = 1;
407 }
408
409 if (changed) {
410 if (netif_running(dev)) {
411 mutex_lock(&mdev->state_lock);
412 mlx4_en_stop_port(dev);
413 }
414 dev->features ^= NETIF_F_LRO;
415 if (netif_running(dev)) {
416 rc = mlx4_en_start_port(dev);
417 if (rc)
418 en_err(priv, "Failed to restart port\n");
419 mutex_unlock(&mdev->state_lock);
420 }
421 }
422
423 return rc;
424} 423}
425 424
426const struct ethtool_ops mlx4_en_ethtool_ops = { 425const struct ethtool_ops mlx4_en_ethtool_ops = {
@@ -441,6 +440,7 @@ const struct ethtool_ops mlx4_en_ethtool_ops = {
441 .get_strings = mlx4_en_get_strings, 440 .get_strings = mlx4_en_get_strings,
442 .get_sset_count = mlx4_en_get_sset_count, 441 .get_sset_count = mlx4_en_get_sset_count,
443 .get_ethtool_stats = mlx4_en_get_ethtool_stats, 442 .get_ethtool_stats = mlx4_en_get_ethtool_stats,
443 .self_test = mlx4_en_self_test,
444 .get_wol = mlx4_en_get_wol, 444 .get_wol = mlx4_en_get_wol,
445 .get_msglevel = mlx4_en_get_msglevel, 445 .get_msglevel = mlx4_en_get_msglevel,
446 .set_msglevel = mlx4_en_set_msglevel, 446 .set_msglevel = mlx4_en_set_msglevel,
@@ -451,7 +451,6 @@ const struct ethtool_ops mlx4_en_ethtool_ops = {
451 .get_ringparam = mlx4_en_get_ringparam, 451 .get_ringparam = mlx4_en_get_ringparam,
452 .set_ringparam = mlx4_en_set_ringparam, 452 .set_ringparam = mlx4_en_set_ringparam,
453 .get_flags = ethtool_op_get_flags, 453 .get_flags = ethtool_op_get_flags,
454 .set_flags = mlx4_ethtool_op_set_flags,
455}; 454};
456 455
457 456
diff --git a/drivers/net/mlx4/en_main.c b/drivers/net/mlx4/en_main.c
index 97934f1ec53a..143906417048 100644
--- a/drivers/net/mlx4/en_main.c
+++ b/drivers/net/mlx4/en_main.c
@@ -63,15 +63,12 @@ static const char mlx4_en_version[] =
63 */ 63 */
64 64
65 65
66/* Use a XOR rathern than Toeplitz hash function for RSS */ 66/* Enable RSS TCP traffic */
67MLX4_EN_PARM_INT(rss_xor, 0, "Use XOR hash function for RSS"); 67MLX4_EN_PARM_INT(tcp_rss, 1,
68 68 "Enable RSS for incomming TCP traffic or disabled (0)");
69/* RSS hash type mask - default to <saddr, daddr, sport, dport> */ 69/* Enable RSS UDP traffic */
70MLX4_EN_PARM_INT(rss_mask, 0xf, "RSS hash type bitmask"); 70MLX4_EN_PARM_INT(udp_rss, 1,
71 71 "Enable RSS for incomming UDP traffic or disabled (0)");
72/* Number of LRO sessions per Rx ring (rounded up to a power of two) */
73MLX4_EN_PARM_INT(num_lro, MLX4_EN_MAX_LRO_DESCRIPTORS,
74 "Number of LRO sessions per ring or disabled (0)");
75 72
76/* Priority pausing */ 73/* Priority pausing */
77MLX4_EN_PARM_INT(pfctx, 0, "Priority based Flow Control policy on TX[7:0]." 74MLX4_EN_PARM_INT(pfctx, 0, "Priority based Flow Control policy on TX[7:0]."
@@ -107,9 +104,12 @@ static int mlx4_en_get_profile(struct mlx4_en_dev *mdev)
107 struct mlx4_en_profile *params = &mdev->profile; 104 struct mlx4_en_profile *params = &mdev->profile;
108 int i; 105 int i;
109 106
110 params->rss_xor = (rss_xor != 0); 107 params->tcp_rss = tcp_rss;
111 params->rss_mask = rss_mask & 0x1f; 108 params->udp_rss = udp_rss;
112 params->num_lro = min_t(int, num_lro , MLX4_EN_MAX_LRO_DESCRIPTORS); 109 if (params->udp_rss && !mdev->dev->caps.udp_rss) {
110 mlx4_warn(mdev, "UDP RSS is not supported on this device.\n");
111 params->udp_rss = 0;
112 }
113 for (i = 1; i <= MLX4_MAX_PORTS; i++) { 113 for (i = 1; i <= MLX4_MAX_PORTS; i++) {
114 params->prof[i].rx_pause = 1; 114 params->prof[i].rx_pause = 1;
115 params->prof[i].rx_ppp = pfcrx; 115 params->prof[i].rx_ppp = pfcrx;
diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c
index a0d8a26f5a02..411bda581c04 100644
--- a/drivers/net/mlx4/en_netdev.c
+++ b/drivers/net/mlx4/en_netdev.c
@@ -109,7 +109,7 @@ static void mlx4_en_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
109 mutex_unlock(&mdev->state_lock); 109 mutex_unlock(&mdev->state_lock);
110} 110}
111 111
112static u64 mlx4_en_mac_to_u64(u8 *addr) 112u64 mlx4_en_mac_to_u64(u8 *addr)
113{ 113{
114 u64 mac = 0; 114 u64 mac = 0;
115 int i; 115 int i;
@@ -513,6 +513,10 @@ static void mlx4_en_do_get_stats(struct work_struct *work)
513 513
514 queue_delayed_work(mdev->workqueue, &priv->stats_task, STATS_DELAY); 514 queue_delayed_work(mdev->workqueue, &priv->stats_task, STATS_DELAY);
515 } 515 }
516 if (mdev->mac_removed[MLX4_MAX_PORTS + 1 - priv->port]) {
517 queue_work(mdev->workqueue, &priv->mac_task);
518 mdev->mac_removed[MLX4_MAX_PORTS + 1 - priv->port] = 0;
519 }
516 mutex_unlock(&mdev->state_lock); 520 mutex_unlock(&mdev->state_lock);
517} 521}
518 522
@@ -528,10 +532,10 @@ static void mlx4_en_linkstate(struct work_struct *work)
528 * report to system log */ 532 * report to system log */
529 if (priv->last_link_state != linkstate) { 533 if (priv->last_link_state != linkstate) {
530 if (linkstate == MLX4_DEV_EVENT_PORT_DOWN) { 534 if (linkstate == MLX4_DEV_EVENT_PORT_DOWN) {
531 en_dbg(LINK, priv, "Link Down\n"); 535 en_info(priv, "Link Down\n");
532 netif_carrier_off(priv->dev); 536 netif_carrier_off(priv->dev);
533 } else { 537 } else {
534 en_dbg(LINK, priv, "Link Up\n"); 538 en_info(priv, "Link Up\n");
535 netif_carrier_on(priv->dev); 539 netif_carrier_on(priv->dev);
536 } 540 }
537 } 541 }
@@ -653,6 +657,7 @@ int mlx4_en_start_port(struct net_device *dev)
653 en_err(priv, "Failed setting port mac\n"); 657 en_err(priv, "Failed setting port mac\n");
654 goto tx_err; 658 goto tx_err;
655 } 659 }
660 mdev->mac_removed[priv->port] = 0;
656 661
657 /* Init port */ 662 /* Init port */
658 en_dbg(HW, priv, "Initializing port\n"); 663 en_dbg(HW, priv, "Initializing port\n");
@@ -704,12 +709,12 @@ void mlx4_en_stop_port(struct net_device *dev)
704 netif_tx_stop_all_queues(dev); 709 netif_tx_stop_all_queues(dev);
705 netif_tx_unlock_bh(dev); 710 netif_tx_unlock_bh(dev);
706 711
707 /* close port*/ 712 /* Set port as not active */
708 priv->port_up = false; 713 priv->port_up = false;
709 mlx4_CLOSE_PORT(mdev->dev, priv->port);
710 714
711 /* Unregister Mac address for the port */ 715 /* Unregister Mac address for the port */
712 mlx4_unregister_mac(mdev->dev, priv->port, priv->mac_index); 716 mlx4_unregister_mac(mdev->dev, priv->port, priv->mac_index);
717 mdev->mac_removed[priv->port] = 1;
713 718
714 /* Free TX Rings */ 719 /* Free TX Rings */
715 for (i = 0; i < priv->tx_ring_num; i++) { 720 for (i = 0; i < priv->tx_ring_num; i++) {
@@ -731,6 +736,9 @@ void mlx4_en_stop_port(struct net_device *dev)
731 msleep(1); 736 msleep(1);
732 mlx4_en_deactivate_cq(priv, &priv->rx_cq[i]); 737 mlx4_en_deactivate_cq(priv, &priv->rx_cq[i]);
733 } 738 }
739
740 /* close port*/
741 mlx4_CLOSE_PORT(mdev->dev, priv->port);
734} 742}
735 743
736static void mlx4_en_restart(struct work_struct *work) 744static void mlx4_en_restart(struct work_struct *work)
@@ -1023,9 +1031,10 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
1023 1031
1024 /* Set defualt MAC */ 1032 /* Set defualt MAC */
1025 dev->addr_len = ETH_ALEN; 1033 dev->addr_len = ETH_ALEN;
1026 for (i = 0; i < ETH_ALEN; i++) 1034 for (i = 0; i < ETH_ALEN; i++) {
1027 dev->dev_addr[ETH_ALEN - 1 - i] = 1035 dev->dev_addr[ETH_ALEN - 1 - i] = (u8) (priv->mac >> (8 * i));
1028 (u8) (priv->mac >> (8 * i)); 1036 dev->perm_addr[ETH_ALEN - 1 - i] = (u8) (priv->mac >> (8 * i));
1037 }
1029 1038
1030 /* 1039 /*
1031 * Set driver features 1040 * Set driver features
@@ -1038,8 +1047,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
1038 dev->features |= NETIF_F_HW_VLAN_TX | 1047 dev->features |= NETIF_F_HW_VLAN_TX |
1039 NETIF_F_HW_VLAN_RX | 1048 NETIF_F_HW_VLAN_RX |
1040 NETIF_F_HW_VLAN_FILTER; 1049 NETIF_F_HW_VLAN_FILTER;
1041 if (mdev->profile.num_lro) 1050 dev->features |= NETIF_F_GRO;
1042 dev->features |= NETIF_F_LRO;
1043 if (mdev->LSO_support) { 1051 if (mdev->LSO_support) {
1044 dev->features |= NETIF_F_TSO; 1052 dev->features |= NETIF_F_TSO;
1045 dev->features |= NETIF_F_TSO6; 1053 dev->features |= NETIF_F_TSO6;
diff --git a/drivers/net/mlx4/en_port.c b/drivers/net/mlx4/en_port.c
index a29abe845d2e..aa3ef2aee5bf 100644
--- a/drivers/net/mlx4/en_port.c
+++ b/drivers/net/mlx4/en_port.c
@@ -142,6 +142,38 @@ int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn,
142 return err; 142 return err;
143} 143}
144 144
145int mlx4_en_QUERY_PORT(struct mlx4_en_dev *mdev, u8 port)
146{
147 struct mlx4_en_query_port_context *qport_context;
148 struct mlx4_en_priv *priv = netdev_priv(mdev->pndev[port]);
149 struct mlx4_en_port_state *state = &priv->port_state;
150 struct mlx4_cmd_mailbox *mailbox;
151 int err;
152
153 mailbox = mlx4_alloc_cmd_mailbox(mdev->dev);
154 if (IS_ERR(mailbox))
155 return PTR_ERR(mailbox);
156 memset(mailbox->buf, 0, sizeof(*qport_context));
157 err = mlx4_cmd_box(mdev->dev, 0, mailbox->dma, port, 0,
158 MLX4_CMD_QUERY_PORT, MLX4_CMD_TIME_CLASS_B);
159 if (err)
160 goto out;
161 qport_context = mailbox->buf;
162
163 /* This command is always accessed from Ethtool context
164 * already synchronized, no need in locking */
165 state->link_state = !!(qport_context->link_up & MLX4_EN_LINK_UP_MASK);
166 if ((qport_context->link_speed & MLX4_EN_SPEED_MASK) ==
167 MLX4_EN_1G_SPEED)
168 state->link_speed = 1000;
169 else
170 state->link_speed = 10000;
171 state->transciver = qport_context->transceiver;
172
173out:
174 mlx4_free_cmd_mailbox(mdev->dev, mailbox);
175 return err;
176}
145 177
146int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset) 178int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset)
147{ 179{
diff --git a/drivers/net/mlx4/en_port.h b/drivers/net/mlx4/en_port.h
index e6477f12beb5..f6511aa2b7df 100644
--- a/drivers/net/mlx4/en_port.h
+++ b/drivers/net/mlx4/en_port.h
@@ -84,6 +84,20 @@ enum {
84 MLX4_MCAST_ENABLE = 2, 84 MLX4_MCAST_ENABLE = 2,
85}; 85};
86 86
87struct mlx4_en_query_port_context {
88 u8 link_up;
89#define MLX4_EN_LINK_UP_MASK 0x80
90 u8 reserved;
91 __be16 mtu;
92 u8 reserved2;
93 u8 link_speed;
94#define MLX4_EN_SPEED_MASK 0x3
95#define MLX4_EN_1G_SPEED 0x2
96 u16 reserved3[5];
97 __be64 mac;
98 u8 transceiver;
99};
100
87 101
88struct mlx4_en_stat_out_mbox { 102struct mlx4_en_stat_out_mbox {
89 /* Received frames with a length of 64 octets */ 103 /* Received frames with a length of 64 octets */
diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c
index 8e2fcb7103c3..570f2508fb30 100644
--- a/drivers/net/mlx4/en_rx.c
+++ b/drivers/net/mlx4/en_rx.c
@@ -42,18 +42,6 @@
42#include "mlx4_en.h" 42#include "mlx4_en.h"
43 43
44 44
45static int mlx4_en_get_frag_header(struct skb_frag_struct *frags, void **mac_hdr,
46 void **ip_hdr, void **tcpudp_hdr,
47 u64 *hdr_flags, void *priv)
48{
49 *mac_hdr = page_address(frags->page) + frags->page_offset;
50 *ip_hdr = *mac_hdr + ETH_HLEN;
51 *tcpudp_hdr = (struct tcphdr *)(*ip_hdr + sizeof(struct iphdr));
52 *hdr_flags = LRO_IPV4 | LRO_TCP;
53
54 return 0;
55}
56
57static int mlx4_en_alloc_frag(struct mlx4_en_priv *priv, 45static int mlx4_en_alloc_frag(struct mlx4_en_priv *priv,
58 struct mlx4_en_rx_desc *rx_desc, 46 struct mlx4_en_rx_desc *rx_desc,
59 struct skb_frag_struct *skb_frags, 47 struct skb_frag_struct *skb_frags,
@@ -251,7 +239,6 @@ reduce_rings:
251 ring->prod--; 239 ring->prod--;
252 mlx4_en_free_rx_desc(priv, ring, ring->actual_size); 240 mlx4_en_free_rx_desc(priv, ring, ring->actual_size);
253 } 241 }
254 ring->size_mask = ring->actual_size - 1;
255 } 242 }
256 243
257 return 0; 244 return 0;
@@ -313,28 +300,8 @@ int mlx4_en_create_rx_ring(struct mlx4_en_priv *priv,
313 } 300 }
314 ring->buf = ring->wqres.buf.direct.buf; 301 ring->buf = ring->wqres.buf.direct.buf;
315 302
316 /* Configure lro mngr */
317 memset(&ring->lro, 0, sizeof(struct net_lro_mgr));
318 ring->lro.dev = priv->dev;
319 ring->lro.features = LRO_F_NAPI;
320 ring->lro.frag_align_pad = NET_IP_ALIGN;
321 ring->lro.ip_summed = CHECKSUM_UNNECESSARY;
322 ring->lro.ip_summed_aggr = CHECKSUM_UNNECESSARY;
323 ring->lro.max_desc = mdev->profile.num_lro;
324 ring->lro.max_aggr = MAX_SKB_FRAGS;
325 ring->lro.lro_arr = kzalloc(mdev->profile.num_lro *
326 sizeof(struct net_lro_desc),
327 GFP_KERNEL);
328 if (!ring->lro.lro_arr) {
329 en_err(priv, "Failed to allocate lro array\n");
330 goto err_map;
331 }
332 ring->lro.get_frag_header = mlx4_en_get_frag_header;
333
334 return 0; 303 return 0;
335 304
336err_map:
337 mlx4_en_unmap_buffer(&ring->wqres.buf);
338err_hwq: 305err_hwq:
339 mlx4_free_hwq_res(mdev->dev, &ring->wqres, ring->buf_size); 306 mlx4_free_hwq_res(mdev->dev, &ring->wqres, ring->buf_size);
340err_ring: 307err_ring:
@@ -389,6 +356,7 @@ int mlx4_en_activate_rx_rings(struct mlx4_en_priv *priv)
389 for (ring_ind = 0; ring_ind < priv->rx_ring_num; ring_ind++) { 356 for (ring_ind = 0; ring_ind < priv->rx_ring_num; ring_ind++) {
390 ring = &priv->rx_ring[ring_ind]; 357 ring = &priv->rx_ring[ring_ind];
391 358
359 ring->size_mask = ring->actual_size - 1;
392 mlx4_en_update_rx_prod_db(ring); 360 mlx4_en_update_rx_prod_db(ring);
393 } 361 }
394 362
@@ -412,7 +380,6 @@ void mlx4_en_destroy_rx_ring(struct mlx4_en_priv *priv,
412{ 380{
413 struct mlx4_en_dev *mdev = priv->mdev; 381 struct mlx4_en_dev *mdev = priv->mdev;
414 382
415 kfree(ring->lro.lro_arr);
416 mlx4_en_unmap_buffer(&ring->wqres.buf); 383 mlx4_en_unmap_buffer(&ring->wqres.buf);
417 mlx4_free_hwq_res(mdev->dev, &ring->wqres, ring->buf_size + TXBB_SIZE); 384 mlx4_free_hwq_res(mdev->dev, &ring->wqres, ring->buf_size + TXBB_SIZE);
418 vfree(ring->rx_info); 385 vfree(ring->rx_info);
@@ -459,7 +426,7 @@ static int mlx4_en_complete_rx_desc(struct mlx4_en_priv *priv,
459 goto fail; 426 goto fail;
460 427
461 /* Unmap buffer */ 428 /* Unmap buffer */
462 pci_unmap_single(mdev->pdev, dma, skb_frags[nr].size, 429 pci_unmap_single(mdev->pdev, dma, skb_frags_rx[nr].size,
463 PCI_DMA_FROMDEVICE); 430 PCI_DMA_FROMDEVICE);
464 } 431 }
465 /* Adjust size of last fragment to match actual length */ 432 /* Adjust size of last fragment to match actual length */
@@ -541,6 +508,21 @@ static struct sk_buff *mlx4_en_rx_skb(struct mlx4_en_priv *priv,
541 return skb; 508 return skb;
542} 509}
543 510
511static void validate_loopback(struct mlx4_en_priv *priv, struct sk_buff *skb)
512{
513 int i;
514 int offset = ETH_HLEN;
515
516 for (i = 0; i < MLX4_LOOPBACK_TEST_PAYLOAD; i++, offset++) {
517 if (*(skb->data + offset) != (unsigned char) (i & 0xff))
518 goto out_loopback;
519 }
520 /* Loopback found */
521 priv->loopback_ok = 1;
522
523out_loopback:
524 dev_kfree_skb_any(skb);
525}
544 526
545int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int budget) 527int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int budget)
546{ 528{
@@ -548,7 +530,6 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
548 struct mlx4_cqe *cqe; 530 struct mlx4_cqe *cqe;
549 struct mlx4_en_rx_ring *ring = &priv->rx_ring[cq->ring]; 531 struct mlx4_en_rx_ring *ring = &priv->rx_ring[cq->ring];
550 struct skb_frag_struct *skb_frags; 532 struct skb_frag_struct *skb_frags;
551 struct skb_frag_struct lro_frags[MLX4_EN_MAX_RX_FRAGS];
552 struct mlx4_en_rx_desc *rx_desc; 533 struct mlx4_en_rx_desc *rx_desc;
553 struct sk_buff *skb; 534 struct sk_buff *skb;
554 int index; 535 int index;
@@ -608,37 +589,35 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
608 * - TCP/IP (v4) 589 * - TCP/IP (v4)
609 * - without IP options 590 * - without IP options
610 * - not an IP fragment */ 591 * - not an IP fragment */
611 if (mlx4_en_can_lro(cqe->status) && 592 if (dev->features & NETIF_F_GRO) {
612 dev->features & NETIF_F_LRO) { 593 struct sk_buff *gro_skb = napi_get_frags(&cq->napi);
594 if (!gro_skb)
595 goto next;
613 596
614 nr = mlx4_en_complete_rx_desc( 597 nr = mlx4_en_complete_rx_desc(
615 priv, rx_desc, 598 priv, rx_desc,
616 skb_frags, lro_frags, 599 skb_frags, skb_shinfo(gro_skb)->frags,
617 ring->page_alloc, length); 600 ring->page_alloc, length);
618 if (!nr) 601 if (!nr)
619 goto next; 602 goto next;
620 603
604 skb_shinfo(gro_skb)->nr_frags = nr;
605 gro_skb->len = length;
606 gro_skb->data_len = length;
607 gro_skb->truesize += length;
608 gro_skb->ip_summed = CHECKSUM_UNNECESSARY;
609
621 if (priv->vlgrp && (cqe->vlan_my_qpn & 610 if (priv->vlgrp && (cqe->vlan_my_qpn &
622 cpu_to_be32(MLX4_CQE_VLAN_PRESENT_MASK))) { 611 cpu_to_be32(MLX4_CQE_VLAN_PRESENT_MASK)))
623 lro_vlan_hwaccel_receive_frags( 612 vlan_gro_frags(&cq->napi, priv->vlgrp, be16_to_cpu(cqe->sl_vid));
624 &ring->lro, lro_frags, 613 else
625 length, length, 614 napi_gro_frags(&cq->napi);
626 priv->vlgrp,
627 be16_to_cpu(cqe->sl_vid),
628 NULL, 0);
629 } else
630 lro_receive_frags(&ring->lro,
631 lro_frags,
632 length,
633 length,
634 NULL, 0);
635 615
636 goto next; 616 goto next;
637 } 617 }
638 618
639 /* LRO not possible, complete processing here */ 619 /* LRO not possible, complete processing here */
640 ip_summed = CHECKSUM_UNNECESSARY; 620 ip_summed = CHECKSUM_UNNECESSARY;
641 INC_PERF_COUNTER(priv->pstats.lro_misses);
642 } else { 621 } else {
643 ip_summed = CHECKSUM_NONE; 622 ip_summed = CHECKSUM_NONE;
644 priv->port_stats.rx_chksum_none++; 623 priv->port_stats.rx_chksum_none++;
@@ -655,6 +634,11 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
655 goto next; 634 goto next;
656 } 635 }
657 636
637 if (unlikely(priv->validate_loopback)) {
638 validate_loopback(priv, skb);
639 goto next;
640 }
641
658 skb->ip_summed = ip_summed; 642 skb->ip_summed = ip_summed;
659 skb->protocol = eth_type_trans(skb, dev); 643 skb->protocol = eth_type_trans(skb, dev);
660 skb_record_rx_queue(skb, cq->ring); 644 skb_record_rx_queue(skb, cq->ring);
@@ -674,14 +658,10 @@ next:
674 if (++polled == budget) { 658 if (++polled == budget) {
675 /* We are here because we reached the NAPI budget - 659 /* We are here because we reached the NAPI budget -
676 * flush only pending LRO sessions */ 660 * flush only pending LRO sessions */
677 lro_flush_all(&ring->lro);
678 goto out; 661 goto out;
679 } 662 }
680 } 663 }
681 664
682 /* If CQ is empty flush all LRO sessions unconditionally */
683 lro_flush_all(&ring->lro);
684
685out: 665out:
686 AVG_PERF_COUNTER(priv->pstats.rx_coal_avg, polled); 666 AVG_PERF_COUNTER(priv->pstats.rx_coal_avg, polled);
687 mlx4_cq_set_ci(&cq->mcq); 667 mlx4_cq_set_ci(&cq->mcq);
@@ -816,7 +796,7 @@ static int mlx4_en_config_rss_qp(struct mlx4_en_priv *priv, int qpn,
816 qp->event = mlx4_en_sqp_event; 796 qp->event = mlx4_en_sqp_event;
817 797
818 memset(context, 0, sizeof *context); 798 memset(context, 0, sizeof *context);
819 mlx4_en_fill_qp_context(priv, ring->size, ring->stride, 0, 0, 799 mlx4_en_fill_qp_context(priv, ring->actual_size, ring->stride, 0, 0,
820 qpn, ring->cqn, context); 800 qpn, ring->cqn, context);
821 context->db_rec_addr = cpu_to_be64(ring->wqres.db.dma); 801 context->db_rec_addr = cpu_to_be64(ring->wqres.db.dma);
822 802
@@ -839,8 +819,7 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv)
839 struct mlx4_qp_context context; 819 struct mlx4_qp_context context;
840 struct mlx4_en_rss_context *rss_context; 820 struct mlx4_en_rss_context *rss_context;
841 void *ptr; 821 void *ptr;
842 int rss_xor = mdev->profile.rss_xor; 822 u8 rss_mask = 0x3f;
843 u8 rss_mask = mdev->profile.rss_mask;
844 int i, qpn; 823 int i, qpn;
845 int err = 0; 824 int err = 0;
846 int good_qps = 0; 825 int good_qps = 0;
@@ -886,9 +865,10 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv)
886 rss_context->base_qpn = cpu_to_be32(ilog2(priv->rx_ring_num) << 24 | 865 rss_context->base_qpn = cpu_to_be32(ilog2(priv->rx_ring_num) << 24 |
887 (rss_map->base_qpn)); 866 (rss_map->base_qpn));
888 rss_context->default_qpn = cpu_to_be32(rss_map->base_qpn); 867 rss_context->default_qpn = cpu_to_be32(rss_map->base_qpn);
889 rss_context->hash_fn = rss_xor & 0x3; 868 rss_context->flags = rss_mask;
890 rss_context->flags = rss_mask << 2;
891 869
870 if (priv->mdev->profile.udp_rss)
871 rss_context->base_qpn_udp = rss_context->default_qpn;
892 err = mlx4_qp_to_ready(mdev->dev, &priv->res.mtt, &context, 872 err = mlx4_qp_to_ready(mdev->dev, &priv->res.mtt, &context,
893 &rss_map->indir_qp, &rss_map->indir_state); 873 &rss_map->indir_qp, &rss_map->indir_state);
894 if (err) 874 if (err)
diff --git a/drivers/net/mlx4/en_selftest.c b/drivers/net/mlx4/en_selftest.c
new file mode 100644
index 000000000000..9c91a92da705
--- /dev/null
+++ b/drivers/net/mlx4/en_selftest.c
@@ -0,0 +1,179 @@
1/*
2 * Copyright (c) 2007 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/kernel.h>
35#include <linux/ethtool.h>
36#include <linux/netdevice.h>
37#include <linux/delay.h>
38#include <linux/mlx4/driver.h>
39
40#include "mlx4_en.h"
41
42
43static int mlx4_en_test_registers(struct mlx4_en_priv *priv)
44{
45 return mlx4_cmd(priv->mdev->dev, 0, 0, 0, MLX4_CMD_HW_HEALTH_CHECK,
46 MLX4_CMD_TIME_CLASS_A);
47}
48
49static int mlx4_en_test_loopback_xmit(struct mlx4_en_priv *priv)
50{
51 struct sk_buff *skb;
52 struct ethhdr *ethh;
53 unsigned char *packet;
54 unsigned int packet_size = MLX4_LOOPBACK_TEST_PAYLOAD;
55 unsigned int i;
56 int err;
57
58
59 /* build the pkt before xmit */
60 skb = netdev_alloc_skb(priv->dev, MLX4_LOOPBACK_TEST_PAYLOAD + ETH_HLEN + NET_IP_ALIGN);
61 if (!skb) {
62 en_err(priv, "-LOOPBACK_TEST_XMIT- failed to create skb for xmit\n");
63 return -ENOMEM;
64 }
65 skb_reserve(skb, NET_IP_ALIGN);
66
67 ethh = (struct ethhdr *)skb_put(skb, sizeof(struct ethhdr));
68 packet = (unsigned char *)skb_put(skb, packet_size);
69 memcpy(ethh->h_dest, priv->dev->dev_addr, ETH_ALEN);
70 memset(ethh->h_source, 0, ETH_ALEN);
71 ethh->h_proto = htons(ETH_P_ARP);
72 skb_set_mac_header(skb, 0);
73 for (i = 0; i < packet_size; ++i) /* fill our packet */
74 packet[i] = (unsigned char)(i & 0xff);
75
76 /* xmit the pkt */
77 err = mlx4_en_xmit(skb, priv->dev);
78 return err;
79}
80
81static int mlx4_en_test_loopback(struct mlx4_en_priv *priv)
82{
83 u32 loopback_ok = 0;
84 int i;
85
86
87 priv->loopback_ok = 0;
88 priv->validate_loopback = 1;
89
90 /* xmit */
91 if (mlx4_en_test_loopback_xmit(priv)) {
92 en_err(priv, "Transmitting loopback packet failed\n");
93 goto mlx4_en_test_loopback_exit;
94 }
95
96 /* polling for result */
97 for (i = 0; i < MLX4_EN_LOOPBACK_RETRIES; ++i) {
98 msleep(MLX4_EN_LOOPBACK_TIMEOUT);
99 if (priv->loopback_ok) {
100 loopback_ok = 1;
101 break;
102 }
103 }
104 if (!loopback_ok)
105 en_err(priv, "Loopback packet didn't arrive\n");
106
107mlx4_en_test_loopback_exit:
108
109 priv->validate_loopback = 0;
110 return !loopback_ok;
111}
112
113
114static int mlx4_en_test_link(struct mlx4_en_priv *priv)
115{
116 if (mlx4_en_QUERY_PORT(priv->mdev, priv->port))
117 return -ENOMEM;
118 if (priv->port_state.link_state == 1)
119 return 0;
120 else
121 return 1;
122}
123
124static int mlx4_en_test_speed(struct mlx4_en_priv *priv)
125{
126
127 if (mlx4_en_QUERY_PORT(priv->mdev, priv->port))
128 return -ENOMEM;
129
130 /* The device currently only supports 10G speed */
131 if (priv->port_state.link_speed != SPEED_10000)
132 return priv->port_state.link_speed;
133 return 0;
134}
135
136
137void mlx4_en_ex_selftest(struct net_device *dev, u32 *flags, u64 *buf)
138{
139 struct mlx4_en_priv *priv = netdev_priv(dev);
140 struct mlx4_en_dev *mdev = priv->mdev;
141 struct mlx4_en_tx_ring *tx_ring;
142 int i, carrier_ok;
143
144 memset(buf, 0, sizeof(u64) * MLX4_EN_NUM_SELF_TEST);
145
146 if (*flags & ETH_TEST_FL_OFFLINE) {
147 /* disable the interface */
148 carrier_ok = netif_carrier_ok(dev);
149
150 netif_carrier_off(dev);
151retry_tx:
152 /* Wait untill all tx queues are empty.
153 * there should not be any additional incoming traffic
154 * since we turned the carrier off */
155 msleep(200);
156 for (i = 0; i < priv->tx_ring_num && carrier_ok; i++) {
157 tx_ring = &priv->tx_ring[i];
158 if (tx_ring->prod != (tx_ring->cons + tx_ring->last_nr_txbb))
159 goto retry_tx;
160 }
161
162 if (priv->mdev->dev->caps.loopback_support){
163 buf[3] = mlx4_en_test_registers(priv);
164 buf[4] = mlx4_en_test_loopback(priv);
165 }
166
167 if (carrier_ok)
168 netif_carrier_on(dev);
169
170 }
171 buf[0] = mlx4_test_interrupts(mdev->dev);
172 buf[1] = mlx4_en_test_link(priv);
173 buf[2] = mlx4_en_test_speed(priv);
174
175 for (i = 0; i < MLX4_EN_NUM_SELF_TEST; i++) {
176 if (buf[i])
177 *flags |= ETH_TEST_FL_FAILED;
178 }
179}
diff --git a/drivers/net/mlx4/en_tx.c b/drivers/net/mlx4/en_tx.c
index 580968f304eb..98dd620042a8 100644
--- a/drivers/net/mlx4/en_tx.c
+++ b/drivers/net/mlx4/en_tx.c
@@ -38,6 +38,7 @@
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/vmalloc.h> 40#include <linux/vmalloc.h>
41#include <linux/tcp.h>
41 42
42#include "mlx4_en.h" 43#include "mlx4_en.h"
43 44
@@ -600,6 +601,9 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
600 struct mlx4_wqe_data_seg *data; 601 struct mlx4_wqe_data_seg *data;
601 struct skb_frag_struct *frag; 602 struct skb_frag_struct *frag;
602 struct mlx4_en_tx_info *tx_info; 603 struct mlx4_en_tx_info *tx_info;
604 struct ethhdr *ethh;
605 u64 mac;
606 u32 mac_l, mac_h;
603 int tx_ind = 0; 607 int tx_ind = 0;
604 int nr_txbb; 608 int nr_txbb;
605 int desc_size; 609 int desc_size;
@@ -612,6 +616,9 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
612 int lso_header_size; 616 int lso_header_size;
613 void *fragptr; 617 void *fragptr;
614 618
619 if (!priv->port_up)
620 goto tx_drop;
621
615 real_size = get_real_size(skb, dev, &lso_header_size); 622 real_size = get_real_size(skb, dev, &lso_header_size);
616 if (unlikely(!real_size)) 623 if (unlikely(!real_size))
617 goto tx_drop; 624 goto tx_drop;
@@ -676,6 +683,19 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
676 priv->port_stats.tx_chksum_offload++; 683 priv->port_stats.tx_chksum_offload++;
677 } 684 }
678 685
686 if (unlikely(priv->validate_loopback)) {
687 /* Copy dst mac address to wqe */
688 skb_reset_mac_header(skb);
689 ethh = eth_hdr(skb);
690 if (ethh && ethh->h_dest) {
691 mac = mlx4_en_mac_to_u64(ethh->h_dest);
692 mac_h = (u32) ((mac & 0xffff00000000ULL) >> 16);
693 mac_l = (u32) (mac & 0xffffffff);
694 tx_desc->ctrl.srcrb_flags |= cpu_to_be32(mac_h);
695 tx_desc->ctrl.imm = cpu_to_be32(mac_l);
696 }
697 }
698
679 /* Handle LSO (TSO) packets */ 699 /* Handle LSO (TSO) packets */
680 if (lso_header_size) { 700 if (lso_header_size) {
681 /* Mark opcode as LSO */ 701 /* Mark opcode as LSO */
diff --git a/drivers/net/mlx4/eq.c b/drivers/net/mlx4/eq.c
index 6d7b2bf210ce..552d0fce6f67 100644
--- a/drivers/net/mlx4/eq.c
+++ b/drivers/net/mlx4/eq.c
@@ -699,3 +699,47 @@ void mlx4_cleanup_eq_table(struct mlx4_dev *dev)
699 699
700 kfree(priv->eq_table.uar_map); 700 kfree(priv->eq_table.uar_map);
701} 701}
702
703/* A test that verifies that we can accept interrupts on all
704 * the irq vectors of the device.
705 * Interrupts are checked using the NOP command.
706 */
707int mlx4_test_interrupts(struct mlx4_dev *dev)
708{
709 struct mlx4_priv *priv = mlx4_priv(dev);
710 int i;
711 int err;
712
713 err = mlx4_NOP(dev);
714 /* When not in MSI_X, there is only one irq to check */
715 if (!(dev->flags & MLX4_FLAG_MSI_X))
716 return err;
717
718 /* A loop over all completion vectors, for each vector we will check
719 * whether it works by mapping command completions to that vector
720 * and performing a NOP command
721 */
722 for(i = 0; !err && (i < dev->caps.num_comp_vectors); ++i) {
723 /* Temporary use polling for command completions */
724 mlx4_cmd_use_polling(dev);
725
726 /* Map the new eq to handle all asyncronous events */
727 err = mlx4_MAP_EQ(dev, MLX4_ASYNC_EVENT_MASK, 0,
728 priv->eq_table.eq[i].eqn);
729 if (err) {
730 mlx4_warn(dev, "Failed mapping eq for interrupt test\n");
731 mlx4_cmd_use_events(dev);
732 break;
733 }
734
735 /* Go back to using events */
736 mlx4_cmd_use_events(dev);
737 err = mlx4_NOP(dev);
738 }
739
740 /* Return to default */
741 mlx4_MAP_EQ(dev, MLX4_ASYNC_EVENT_MASK, 0,
742 priv->eq_table.eq[dev->caps.num_comp_vectors].eqn);
743 return err;
744}
745EXPORT_SYMBOL(mlx4_test_interrupts);
diff --git a/drivers/net/mlx4/fw.c b/drivers/net/mlx4/fw.c
index 04f42ae1eda0..b716e1a1b298 100644
--- a/drivers/net/mlx4/fw.c
+++ b/drivers/net/mlx4/fw.c
@@ -141,6 +141,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
141 struct mlx4_cmd_mailbox *mailbox; 141 struct mlx4_cmd_mailbox *mailbox;
142 u32 *outbox; 142 u32 *outbox;
143 u8 field; 143 u8 field;
144 u32 field32;
144 u16 size; 145 u16 size;
145 u16 stat_rate; 146 u16 stat_rate;
146 int err; 147 int err;
@@ -178,6 +179,8 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
178#define QUERY_DEV_CAP_MAX_GID_OFFSET 0x3b 179#define QUERY_DEV_CAP_MAX_GID_OFFSET 0x3b
179#define QUERY_DEV_CAP_RATE_SUPPORT_OFFSET 0x3c 180#define QUERY_DEV_CAP_RATE_SUPPORT_OFFSET 0x3c
180#define QUERY_DEV_CAP_MAX_PKEY_OFFSET 0x3f 181#define QUERY_DEV_CAP_MAX_PKEY_OFFSET 0x3f
182#define QUERY_DEV_CAP_UDP_RSS_OFFSET 0x42
183#define QUERY_DEV_CAP_ETH_UC_LOOPBACK_OFFSET 0x43
181#define QUERY_DEV_CAP_FLAGS_OFFSET 0x44 184#define QUERY_DEV_CAP_FLAGS_OFFSET 0x44
182#define QUERY_DEV_CAP_RSVD_UAR_OFFSET 0x48 185#define QUERY_DEV_CAP_RSVD_UAR_OFFSET 0x48
183#define QUERY_DEV_CAP_UAR_SZ_OFFSET 0x49 186#define QUERY_DEV_CAP_UAR_SZ_OFFSET 0x49
@@ -268,6 +271,10 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
268 dev_cap->max_msg_sz = 1 << (field & 0x1f); 271 dev_cap->max_msg_sz = 1 << (field & 0x1f);
269 MLX4_GET(stat_rate, outbox, QUERY_DEV_CAP_RATE_SUPPORT_OFFSET); 272 MLX4_GET(stat_rate, outbox, QUERY_DEV_CAP_RATE_SUPPORT_OFFSET);
270 dev_cap->stat_rate_support = stat_rate; 273 dev_cap->stat_rate_support = stat_rate;
274 MLX4_GET(field, outbox, QUERY_DEV_CAP_UDP_RSS_OFFSET);
275 dev_cap->udp_rss = field & 0x1;
276 MLX4_GET(field, outbox, QUERY_DEV_CAP_ETH_UC_LOOPBACK_OFFSET);
277 dev_cap->loopback_support = field & 0x1;
271 MLX4_GET(dev_cap->flags, outbox, QUERY_DEV_CAP_FLAGS_OFFSET); 278 MLX4_GET(dev_cap->flags, outbox, QUERY_DEV_CAP_FLAGS_OFFSET);
272 MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_UAR_OFFSET); 279 MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_UAR_OFFSET);
273 dev_cap->reserved_uars = field >> 4; 280 dev_cap->reserved_uars = field >> 4;
@@ -365,6 +372,9 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
365#define QUERY_PORT_MAX_MACVLAN_OFFSET 0x0a 372#define QUERY_PORT_MAX_MACVLAN_OFFSET 0x0a
366#define QUERY_PORT_MAX_VL_OFFSET 0x0b 373#define QUERY_PORT_MAX_VL_OFFSET 0x0b
367#define QUERY_PORT_MAC_OFFSET 0x10 374#define QUERY_PORT_MAC_OFFSET 0x10
375#define QUERY_PORT_TRANS_VENDOR_OFFSET 0x18
376#define QUERY_PORT_WAVELENGTH_OFFSET 0x1c
377#define QUERY_PORT_TRANS_CODE_OFFSET 0x20
368 378
369 for (i = 1; i <= dev_cap->num_ports; ++i) { 379 for (i = 1; i <= dev_cap->num_ports; ++i) {
370 err = mlx4_cmd_box(dev, 0, mailbox->dma, i, 0, MLX4_CMD_QUERY_PORT, 380 err = mlx4_cmd_box(dev, 0, mailbox->dma, i, 0, MLX4_CMD_QUERY_PORT,
@@ -388,6 +398,11 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
388 dev_cap->log_max_vlans[i] = field >> 4; 398 dev_cap->log_max_vlans[i] = field >> 4;
389 MLX4_GET(dev_cap->eth_mtu[i], outbox, QUERY_PORT_ETH_MTU_OFFSET); 399 MLX4_GET(dev_cap->eth_mtu[i], outbox, QUERY_PORT_ETH_MTU_OFFSET);
390 MLX4_GET(dev_cap->def_mac[i], outbox, QUERY_PORT_MAC_OFFSET); 400 MLX4_GET(dev_cap->def_mac[i], outbox, QUERY_PORT_MAC_OFFSET);
401 MLX4_GET(field32, outbox, QUERY_PORT_TRANS_VENDOR_OFFSET);
402 dev_cap->trans_type[i] = field32 >> 24;
403 dev_cap->vendor_oui[i] = field32 & 0xffffff;
404 MLX4_GET(dev_cap->wavelength[i], outbox, QUERY_PORT_WAVELENGTH_OFFSET);
405 MLX4_GET(dev_cap->trans_code[i], outbox, QUERY_PORT_TRANS_CODE_OFFSET);
391 } 406 }
392 } 407 }
393 408
diff --git a/drivers/net/mlx4/fw.h b/drivers/net/mlx4/fw.h
index 526d7f30c041..65cc72eb899d 100644
--- a/drivers/net/mlx4/fw.h
+++ b/drivers/net/mlx4/fw.h
@@ -73,7 +73,13 @@ struct mlx4_dev_cap {
73 int max_pkeys[MLX4_MAX_PORTS + 1]; 73 int max_pkeys[MLX4_MAX_PORTS + 1];
74 u64 def_mac[MLX4_MAX_PORTS + 1]; 74 u64 def_mac[MLX4_MAX_PORTS + 1];
75 u16 eth_mtu[MLX4_MAX_PORTS + 1]; 75 u16 eth_mtu[MLX4_MAX_PORTS + 1];
76 int trans_type[MLX4_MAX_PORTS + 1];
77 int vendor_oui[MLX4_MAX_PORTS + 1];
78 u16 wavelength[MLX4_MAX_PORTS + 1];
79 u64 trans_code[MLX4_MAX_PORTS + 1];
76 u16 stat_rate_support; 80 u16 stat_rate_support;
81 int udp_rss;
82 int loopback_support;
77 u32 flags; 83 u32 flags;
78 int reserved_uars; 84 int reserved_uars;
79 int uar_size; 85 int uar_size;
diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c
index 5102ab1ac561..569fa3df381f 100644
--- a/drivers/net/mlx4/main.c
+++ b/drivers/net/mlx4/main.c
@@ -184,6 +184,10 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
184 dev->caps.eth_mtu_cap[i] = dev_cap->eth_mtu[i]; 184 dev->caps.eth_mtu_cap[i] = dev_cap->eth_mtu[i];
185 dev->caps.def_mac[i] = dev_cap->def_mac[i]; 185 dev->caps.def_mac[i] = dev_cap->def_mac[i];
186 dev->caps.supported_type[i] = dev_cap->supported_port_types[i]; 186 dev->caps.supported_type[i] = dev_cap->supported_port_types[i];
187 dev->caps.trans_type[i] = dev_cap->trans_type[i];
188 dev->caps.vendor_oui[i] = dev_cap->vendor_oui[i];
189 dev->caps.wavelength[i] = dev_cap->wavelength[i];
190 dev->caps.trans_code[i] = dev_cap->trans_code[i];
187 } 191 }
188 192
189 dev->caps.num_uars = dev_cap->uar_size / PAGE_SIZE; 193 dev->caps.num_uars = dev_cap->uar_size / PAGE_SIZE;
@@ -221,6 +225,8 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
221 dev->caps.bmme_flags = dev_cap->bmme_flags; 225 dev->caps.bmme_flags = dev_cap->bmme_flags;
222 dev->caps.reserved_lkey = dev_cap->reserved_lkey; 226 dev->caps.reserved_lkey = dev_cap->reserved_lkey;
223 dev->caps.stat_rate_support = dev_cap->stat_rate_support; 227 dev->caps.stat_rate_support = dev_cap->stat_rate_support;
228 dev->caps.udp_rss = dev_cap->udp_rss;
229 dev->caps.loopback_support = dev_cap->loopback_support;
224 dev->caps.max_gso_sz = dev_cap->max_gso_sz; 230 dev->caps.max_gso_sz = dev_cap->max_gso_sz;
225 231
226 dev->caps.log_num_macs = log_num_mac; 232 dev->caps.log_num_macs = log_num_mac;
diff --git a/drivers/net/mlx4/mlx4_en.h b/drivers/net/mlx4/mlx4_en.h
index 449210994ee9..1fc16ab7ad2f 100644
--- a/drivers/net/mlx4/mlx4_en.h
+++ b/drivers/net/mlx4/mlx4_en.h
@@ -38,19 +38,19 @@
38#include <linux/list.h> 38#include <linux/list.h>
39#include <linux/mutex.h> 39#include <linux/mutex.h>
40#include <linux/netdevice.h> 40#include <linux/netdevice.h>
41#include <linux/inet_lro.h>
42 41
43#include <linux/mlx4/device.h> 42#include <linux/mlx4/device.h>
44#include <linux/mlx4/qp.h> 43#include <linux/mlx4/qp.h>
45#include <linux/mlx4/cq.h> 44#include <linux/mlx4/cq.h>
46#include <linux/mlx4/srq.h> 45#include <linux/mlx4/srq.h>
47#include <linux/mlx4/doorbell.h> 46#include <linux/mlx4/doorbell.h>
47#include <linux/mlx4/cmd.h>
48 48
49#include "en_port.h" 49#include "en_port.h"
50 50
51#define DRV_NAME "mlx4_en" 51#define DRV_NAME "mlx4_en"
52#define DRV_VERSION "1.4.1.1" 52#define DRV_VERSION "1.5.1.6"
53#define DRV_RELDATE "June 2009" 53#define DRV_RELDATE "August 2010"
54 54
55#define MLX4_EN_MSG_LEVEL (NETIF_MSG_LINK | NETIF_MSG_IFDOWN) 55#define MLX4_EN_MSG_LEVEL (NETIF_MSG_LINK | NETIF_MSG_IFDOWN)
56 56
@@ -61,7 +61,6 @@
61 61
62#define MLX4_EN_PAGE_SHIFT 12 62#define MLX4_EN_PAGE_SHIFT 12
63#define MLX4_EN_PAGE_SIZE (1 << MLX4_EN_PAGE_SHIFT) 63#define MLX4_EN_PAGE_SIZE (1 << MLX4_EN_PAGE_SHIFT)
64#define MAX_TX_RINGS 16
65#define MAX_RX_RINGS 16 64#define MAX_RX_RINGS 16
66#define TXBB_SIZE 64 65#define TXBB_SIZE 64
67#define HEADROOM (2048 / TXBB_SIZE + 1) 66#define HEADROOM (2048 / TXBB_SIZE + 1)
@@ -107,6 +106,7 @@ enum {
107#define MLX4_EN_SMALL_PKT_SIZE 64 106#define MLX4_EN_SMALL_PKT_SIZE 64
108#define MLX4_EN_NUM_TX_RINGS 8 107#define MLX4_EN_NUM_TX_RINGS 8
109#define MLX4_EN_NUM_PPP_RINGS 8 108#define MLX4_EN_NUM_PPP_RINGS 8
109#define MAX_TX_RINGS (MLX4_EN_NUM_TX_RINGS + MLX4_EN_NUM_PPP_RINGS)
110#define MLX4_EN_DEF_TX_RING_SIZE 512 110#define MLX4_EN_DEF_TX_RING_SIZE 512
111#define MLX4_EN_DEF_RX_RING_SIZE 1024 111#define MLX4_EN_DEF_RX_RING_SIZE 1024
112 112
@@ -139,10 +139,14 @@ enum {
139 139
140#define SMALL_PACKET_SIZE (256 - NET_IP_ALIGN) 140#define SMALL_PACKET_SIZE (256 - NET_IP_ALIGN)
141#define HEADER_COPY_SIZE (128 - NET_IP_ALIGN) 141#define HEADER_COPY_SIZE (128 - NET_IP_ALIGN)
142#define MLX4_LOOPBACK_TEST_PAYLOAD (HEADER_COPY_SIZE - ETH_HLEN)
142 143
143#define MLX4_EN_MIN_MTU 46 144#define MLX4_EN_MIN_MTU 46
144#define ETH_BCAST 0xffffffffffffULL 145#define ETH_BCAST 0xffffffffffffULL
145 146
147#define MLX4_EN_LOOPBACK_RETRIES 5
148#define MLX4_EN_LOOPBACK_TIMEOUT 100
149
146#ifdef MLX4_EN_PERF_STAT 150#ifdef MLX4_EN_PERF_STAT
147/* Number of samples to 'average' */ 151/* Number of samples to 'average' */
148#define AVG_SIZE 128 152#define AVG_SIZE 128
@@ -249,7 +253,6 @@ struct mlx4_en_rx_desc {
249struct mlx4_en_rx_ring { 253struct mlx4_en_rx_ring {
250 struct mlx4_hwq_resources wqres; 254 struct mlx4_hwq_resources wqres;
251 struct mlx4_en_rx_alloc page_alloc[MLX4_EN_MAX_RX_FRAGS]; 255 struct mlx4_en_rx_alloc page_alloc[MLX4_EN_MAX_RX_FRAGS];
252 struct net_lro_mgr lro;
253 u32 size ; /* number of Rx descs*/ 256 u32 size ; /* number of Rx descs*/
254 u32 actual_size; 257 u32 actual_size;
255 u32 size_mask; 258 u32 size_mask;
@@ -313,7 +316,8 @@ struct mlx4_en_port_profile {
313 316
314struct mlx4_en_profile { 317struct mlx4_en_profile {
315 int rss_xor; 318 int rss_xor;
316 int num_lro; 319 int tcp_rss;
320 int udp_rss;
317 u8 rss_mask; 321 u8 rss_mask;
318 u32 active_ports; 322 u32 active_ports;
319 u32 small_pkt_int; 323 u32 small_pkt_int;
@@ -337,6 +341,7 @@ struct mlx4_en_dev {
337 struct mlx4_mr mr; 341 struct mlx4_mr mr;
338 u32 priv_pdn; 342 u32 priv_pdn;
339 spinlock_t uar_lock; 343 spinlock_t uar_lock;
344 u8 mac_removed[MLX4_MAX_PORTS + 1];
340}; 345};
341 346
342 347
@@ -355,6 +360,13 @@ struct mlx4_en_rss_context {
355 u8 hash_fn; 360 u8 hash_fn;
356 u8 flags; 361 u8 flags;
357 __be32 rss_key[10]; 362 __be32 rss_key[10];
363 __be32 base_qpn_udp;
364};
365
366struct mlx4_en_port_state {
367 int link_state;
368 int link_speed;
369 int transciver;
358}; 370};
359 371
360struct mlx4_en_pkt_stats { 372struct mlx4_en_pkt_stats {
@@ -365,9 +377,6 @@ struct mlx4_en_pkt_stats {
365}; 377};
366 378
367struct mlx4_en_port_stats { 379struct mlx4_en_port_stats {
368 unsigned long lro_aggregated;
369 unsigned long lro_flushed;
370 unsigned long lro_no_desc;
371 unsigned long tso_packets; 380 unsigned long tso_packets;
372 unsigned long queue_stopped; 381 unsigned long queue_stopped;
373 unsigned long wake_queue; 382 unsigned long wake_queue;
@@ -376,7 +385,7 @@ struct mlx4_en_port_stats {
376 unsigned long rx_chksum_good; 385 unsigned long rx_chksum_good;
377 unsigned long rx_chksum_none; 386 unsigned long rx_chksum_none;
378 unsigned long tx_chksum_offload; 387 unsigned long tx_chksum_offload;
379#define NUM_PORT_STATS 11 388#define NUM_PORT_STATS 8
380}; 389};
381 390
382struct mlx4_en_perf_stats { 391struct mlx4_en_perf_stats {
@@ -405,6 +414,7 @@ struct mlx4_en_priv {
405 struct vlan_group *vlgrp; 414 struct vlan_group *vlgrp;
406 struct net_device_stats stats; 415 struct net_device_stats stats;
407 struct net_device_stats ret_stats; 416 struct net_device_stats ret_stats;
417 struct mlx4_en_port_state port_state;
408 spinlock_t stats_lock; 418 spinlock_t stats_lock;
409 419
410 unsigned long last_moder_packets; 420 unsigned long last_moder_packets;
@@ -423,6 +433,8 @@ struct mlx4_en_priv {
423 u16 sample_interval; 433 u16 sample_interval;
424 u16 adaptive_rx_coal; 434 u16 adaptive_rx_coal;
425 u32 msg_enable; 435 u32 msg_enable;
436 u32 loopback_ok;
437 u32 validate_loopback;
426 438
427 struct mlx4_hwq_resources res; 439 struct mlx4_hwq_resources res;
428 int link_state; 440 int link_state;
@@ -531,6 +543,11 @@ int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn,
531 u8 promisc); 543 u8 promisc);
532 544
533int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset); 545int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset);
546int mlx4_en_QUERY_PORT(struct mlx4_en_dev *mdev, u8 port);
547
548#define MLX4_EN_NUM_SELF_TEST 5
549void mlx4_en_ex_selftest(struct net_device *dev, u32 *flags, u64 *buf);
550u64 mlx4_en_mac_to_u64(u8 *addr);
534 551
535/* 552/*
536 * Globals 553 * Globals
@@ -555,6 +572,8 @@ do { \
555 en_print(KERN_WARNING, priv, format, ##arg) 572 en_print(KERN_WARNING, priv, format, ##arg)
556#define en_err(priv, format, arg...) \ 573#define en_err(priv, format, arg...) \
557 en_print(KERN_ERR, priv, format, ##arg) 574 en_print(KERN_ERR, priv, format, ##arg)
575#define en_info(priv, format, arg...) \
576 en_print(KERN_INFO, priv, format, ## arg)
558 577
559#define mlx4_err(mdev, format, arg...) \ 578#define mlx4_err(mdev, format, arg...) \
560 pr_err("%s %s: " format, DRV_NAME, \ 579 pr_err("%s %s: " format, DRV_NAME, \
diff --git a/drivers/net/mlx4/profile.c b/drivers/net/mlx4/profile.c
index 5caf0115fa5b..e749f82865fe 100644
--- a/drivers/net/mlx4/profile.c
+++ b/drivers/net/mlx4/profile.c
@@ -85,7 +85,7 @@ u64 mlx4_make_profile(struct mlx4_dev *dev,
85 struct mlx4_resource tmp; 85 struct mlx4_resource tmp;
86 int i, j; 86 int i, j;
87 87
88 profile = kzalloc(MLX4_RES_NUM * sizeof *profile, GFP_KERNEL); 88 profile = kcalloc(MLX4_RES_NUM, sizeof(*profile), GFP_KERNEL);
89 if (!profile) 89 if (!profile)
90 return -ENOMEM; 90 return -ENOMEM;
91 91