Merge branch 'for-4.7/dax' into libnvdimm-for-next
[linux-2.6-block.git] / drivers / net / ethernet / mellanox / mlx4 / port.c
CommitLineData
2a2336f8
YP
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#include <linux/errno.h>
34#include <linux/if_ether.h>
c59fec20 35#include <linux/if_vlan.h>
ee40fa06 36#include <linux/export.h>
2a2336f8
YP
37
38#include <linux/mlx4/cmd.h>
39
40#include "mlx4.h"
b4b6e842 41#include "mlx4_stats.h"
2a2336f8
YP
42
43#define MLX4_MAC_VALID (1ull << 63)
2a2336f8
YP
44
45#define MLX4_VLAN_VALID (1u << 31)
46#define MLX4_VLAN_MASK 0xfff
47
78500b8c
MM
48#define MLX4_STATS_TRAFFIC_COUNTERS_MASK 0xfULL
49#define MLX4_STATS_TRAFFIC_DROPS_MASK 0xc0ULL
50#define MLX4_STATS_ERROR_COUNTERS_MASK 0x1ffc30ULL
51#define MLX4_STATS_PORT_COUNTERS_MASK 0x1fe00000ULL
52
53#define MLX4_FLAG_V_IGNORE_FCS_MASK 0x2
54#define MLX4_IGNORE_FCS_MASK 0x1
55
2a2336f8
YP
56void mlx4_init_mac_table(struct mlx4_dev *dev, struct mlx4_mac_table *table)
57{
58 int i;
59
60 mutex_init(&table->mutex);
61 for (i = 0; i < MLX4_MAX_MAC_NUM; i++) {
62 table->entries[i] = 0;
63 table->refs[i] = 0;
5f61385d 64 table->is_dup[i] = false;
2a2336f8
YP
65 }
66 table->max = 1 << dev->caps.log_num_macs;
67 table->total = 0;
68}
69
70void mlx4_init_vlan_table(struct mlx4_dev *dev, struct mlx4_vlan_table *table)
71{
72 int i;
73
74 mutex_init(&table->mutex);
75 for (i = 0; i < MLX4_MAX_VLAN_NUM; i++) {
76 table->entries[i] = 0;
77 table->refs[i] = 0;
5f61385d 78 table->is_dup[i] = false;
2a2336f8 79 }
e72ebf5a 80 table->max = (1 << dev->caps.log_num_vlans) - MLX4_VLAN_REGULAR;
2a2336f8
YP
81 table->total = 0;
82}
83
111c6094
JM
84void mlx4_init_roce_gid_table(struct mlx4_dev *dev,
85 struct mlx4_roce_gid_table *table)
86{
87 int i;
88
89 mutex_init(&table->mutex);
90 for (i = 0; i < MLX4_ROCE_MAX_GIDS; i++)
91 memset(table->roce_gids[i].raw, 0, MLX4_ROCE_GID_ENTRY_SIZE);
92}
93
ffe455ad
EE
94static int validate_index(struct mlx4_dev *dev,
95 struct mlx4_mac_table *table, int index)
96{
97 int err = 0;
98
99 if (index < 0 || index >= table->max || !table->entries[index]) {
100 mlx4_warn(dev, "No valid Mac entry for the given index\n");
101 err = -EINVAL;
102 }
103 return err;
104}
105
106static int find_index(struct mlx4_dev *dev,
107 struct mlx4_mac_table *table, u64 mac)
108{
109 int i;
110
111 for (i = 0; i < MLX4_MAX_MAC_NUM; i++) {
f4fd40b2
JM
112 if (table->refs[i] &&
113 (MLX4_MAC_MASK & mac) ==
ffe455ad
EE
114 (MLX4_MAC_MASK & be64_to_cpu(table->entries[i])))
115 return i;
116 }
117 /* Mac not found */
118 return -EINVAL;
1679200f
YP
119}
120
ffe455ad
EE
121static int mlx4_set_port_mac_table(struct mlx4_dev *dev, u8 port,
122 __be64 *entries)
123{
124 struct mlx4_cmd_mailbox *mailbox;
125 u32 in_mod;
126 int err;
127
128 mailbox = mlx4_alloc_cmd_mailbox(dev);
129 if (IS_ERR(mailbox))
130 return PTR_ERR(mailbox);
131
132 memcpy(mailbox->buf, entries, MLX4_MAC_TABLE_SIZE);
133
134 in_mod = MLX4_SET_PORT_MAC_TABLE << 8 | port;
0f6740c7 135
a130b590
IS
136 err = mlx4_cmd(dev, mailbox->dma, in_mod, MLX4_SET_PORT_ETH_OPCODE,
137 MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B,
138 MLX4_CMD_NATIVE);
ffe455ad
EE
139
140 mlx4_free_cmd_mailbox(dev, mailbox);
141 return err;
142}
143
297e0dad
MS
144int mlx4_find_cached_mac(struct mlx4_dev *dev, u8 port, u64 mac, int *idx)
145{
146 struct mlx4_port_info *info = &mlx4_priv(dev)->port[port];
147 struct mlx4_mac_table *table = &info->mac_table;
148 int i;
149
150 for (i = 0; i < MLX4_MAX_MAC_NUM; i++) {
151 if (!table->refs[i])
152 continue;
153
154 if (mac == (MLX4_MAC_MASK & be64_to_cpu(table->entries[i]))) {
155 *idx = i;
156 return 0;
157 }
158 }
159
160 return -ENOENT;
161}
162EXPORT_SYMBOL_GPL(mlx4_find_cached_mac);
163
5f61385d
MS
164static bool mlx4_need_mf_bond(struct mlx4_dev *dev)
165{
166 int i, num_eth_ports = 0;
167
168 if (!mlx4_is_mfunc(dev))
169 return false;
170 mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_ETH)
171 ++num_eth_ports;
172
173 return (num_eth_ports == 2) ? true : false;
174}
175
ffe455ad
EE
176int __mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac)
177{
178 struct mlx4_port_info *info = &mlx4_priv(dev)->port[port];
179 struct mlx4_mac_table *table = &info->mac_table;
180 int i, err = 0;
181 int free = -1;
5f61385d
MS
182 int free_for_dup = -1;
183 bool dup = mlx4_is_mf_bonded(dev);
184 u8 dup_port = (port == 1) ? 2 : 1;
185 struct mlx4_mac_table *dup_table = &mlx4_priv(dev)->port[dup_port].mac_table;
186 bool need_mf_bond = mlx4_need_mf_bond(dev);
187 bool can_mf_bond = true;
188
189 mlx4_dbg(dev, "Registering MAC: 0x%llx for port %d %s duplicate\n",
190 (unsigned long long)mac, port,
191 dup ? "with" : "without");
192
193 if (need_mf_bond) {
194 if (port == 1) {
195 mutex_lock(&table->mutex);
03a79f31 196 mutex_lock_nested(&dup_table->mutex, SINGLE_DEPTH_NESTING);
5f61385d
MS
197 } else {
198 mutex_lock(&dup_table->mutex);
03a79f31 199 mutex_lock_nested(&table->mutex, SINGLE_DEPTH_NESTING);
5f61385d
MS
200 }
201 } else {
202 mutex_lock(&table->mutex);
203 }
ffe455ad 204
5f61385d
MS
205 if (need_mf_bond) {
206 int index_at_port = -1;
207 int index_at_dup_port = -1;
208
209 for (i = 0; i < MLX4_MAX_MAC_NUM; i++) {
210 if (((MLX4_MAC_MASK & mac) == (MLX4_MAC_MASK & be64_to_cpu(table->entries[i]))))
211 index_at_port = i;
212 if (((MLX4_MAC_MASK & mac) == (MLX4_MAC_MASK & be64_to_cpu(dup_table->entries[i]))))
213 index_at_dup_port = i;
214 }
215
216 /* check that same mac is not in the tables at different indices */
217 if ((index_at_port != index_at_dup_port) &&
218 (index_at_port >= 0) &&
219 (index_at_dup_port >= 0))
220 can_mf_bond = false;
221
222 /* If the mac is already in the primary table, the slot must be
223 * available in the duplicate table as well.
224 */
225 if (index_at_port >= 0 && index_at_dup_port < 0 &&
226 dup_table->refs[index_at_port]) {
227 can_mf_bond = false;
228 }
229 /* If the mac is already in the duplicate table, check that the
230 * corresponding index is not occupied in the primary table, or
231 * the primary table already contains the mac at the same index.
232 * Otherwise, you cannot bond (primary contains a different mac
233 * at that index).
234 */
235 if (index_at_dup_port >= 0) {
236 if (!table->refs[index_at_dup_port] ||
237 ((MLX4_MAC_MASK & mac) == (MLX4_MAC_MASK & be64_to_cpu(table->entries[index_at_dup_port]))))
238 free_for_dup = index_at_dup_port;
239 else
240 can_mf_bond = false;
241 }
242 }
0f6740c7 243
ffe455ad 244 for (i = 0; i < MLX4_MAX_MAC_NUM; i++) {
f4fd40b2
JM
245 if (!table->refs[i]) {
246 if (free < 0)
247 free = i;
5f61385d
MS
248 if (free_for_dup < 0 && need_mf_bond && can_mf_bond) {
249 if (!dup_table->refs[i])
250 free_for_dup = i;
251 }
2a2336f8
YP
252 continue;
253 }
254
f4fd40b2
JM
255 if ((MLX4_MAC_MASK & mac) ==
256 (MLX4_MAC_MASK & be64_to_cpu(table->entries[i]))) {
6ce71acd
RE
257 /* MAC already registered, increment ref count */
258 err = i;
259 ++table->refs[i];
5f61385d
MS
260 if (dup) {
261 u64 dup_mac = MLX4_MAC_MASK & be64_to_cpu(dup_table->entries[i]);
262
263 if (dup_mac != mac || !dup_table->is_dup[i]) {
264 mlx4_warn(dev, "register mac: expect duplicate mac 0x%llx on port %d index %d\n",
265 mac, dup_port, i);
266 }
267 }
2a2336f8
YP
268 goto out;
269 }
270 }
0926f910 271
5f61385d
MS
272 if (need_mf_bond && (free_for_dup < 0)) {
273 if (dup) {
274 mlx4_warn(dev, "Fail to allocate duplicate MAC table entry\n");
275 mlx4_warn(dev, "High Availability for virtual functions may not work as expected\n");
276 dup = false;
277 }
278 can_mf_bond = false;
279 }
280
281 if (need_mf_bond && can_mf_bond)
282 free = free_for_dup;
283
2a2336f8
YP
284 mlx4_dbg(dev, "Free MAC index is %d\n", free);
285
286 if (table->total == table->max) {
287 /* No free mac entries */
288 err = -ENOSPC;
289 goto out;
290 }
291
292 /* Register new MAC */
2a2336f8
YP
293 table->entries[free] = cpu_to_be64(mac | MLX4_MAC_VALID);
294
295 err = mlx4_set_port_mac_table(dev, port, table->entries);
296 if (unlikely(err)) {
ffe455ad
EE
297 mlx4_err(dev, "Failed adding MAC: 0x%llx\n",
298 (unsigned long long) mac);
2a2336f8
YP
299 table->entries[free] = 0;
300 goto out;
301 }
6ce71acd 302 table->refs[free] = 1;
5f61385d 303 table->is_dup[free] = false;
2a2336f8 304 ++table->total;
5f61385d
MS
305 if (dup) {
306 dup_table->refs[free] = 0;
307 dup_table->is_dup[free] = true;
308 dup_table->entries[free] = cpu_to_be64(mac | MLX4_MAC_VALID);
309
310 err = mlx4_set_port_mac_table(dev, dup_port, dup_table->entries);
311 if (unlikely(err)) {
312 mlx4_warn(dev, "Failed adding duplicate mac: 0x%llx\n", mac);
313 dup_table->is_dup[free] = false;
314 dup_table->entries[free] = 0;
315 goto out;
316 }
317 ++dup_table->total;
318 }
319 err = free;
2a2336f8 320out:
5f61385d
MS
321 if (need_mf_bond) {
322 if (port == 2) {
323 mutex_unlock(&table->mutex);
324 mutex_unlock(&dup_table->mutex);
325 } else {
326 mutex_unlock(&dup_table->mutex);
327 mutex_unlock(&table->mutex);
328 }
329 } else {
330 mutex_unlock(&table->mutex);
331 }
2a2336f8
YP
332 return err;
333}
ffe455ad 334EXPORT_SYMBOL_GPL(__mlx4_register_mac);
2a2336f8 335
ffe455ad 336int mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac)
2a2336f8 337{
e7dbeba8 338 u64 out_param = 0;
acddd5dd 339 int err = -EINVAL;
2a2336f8 340
ffe455ad 341 if (mlx4_is_mfunc(dev)) {
acddd5dd
JM
342 if (!(dev->flags & MLX4_FLAG_OLD_REG_MAC)) {
343 err = mlx4_cmd_imm(dev, mac, &out_param,
344 ((u32) port) << 8 | (u32) RES_MAC,
345 RES_OP_RESERVE_AND_MAP, MLX4_CMD_ALLOC_RES,
346 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
347 }
348 if (err && err == -EINVAL && mlx4_is_slave(dev)) {
349 /* retry using old REG_MAC format */
350 set_param_l(&out_param, port);
351 err = mlx4_cmd_imm(dev, mac, &out_param, RES_MAC,
352 RES_OP_RESERVE_AND_MAP, MLX4_CMD_ALLOC_RES,
353 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
354 if (!err)
355 dev->flags |= MLX4_FLAG_OLD_REG_MAC;
356 }
ffe455ad
EE
357 if (err)
358 return err;
1679200f 359
ffe455ad 360 return get_param_l(&out_param);
1679200f 361 }
ffe455ad 362 return __mlx4_register_mac(dev, port, mac);
1679200f 363}
ffe455ad
EE
364EXPORT_SYMBOL_GPL(mlx4_register_mac);
365
16a10ffd
YB
366int mlx4_get_base_qpn(struct mlx4_dev *dev, u8 port)
367{
368 return dev->caps.reserved_qps_base[MLX4_QP_REGION_ETH_ADDR] +
369 (port - 1) * (1 << dev->caps.log_num_macs);
370}
371EXPORT_SYMBOL_GPL(mlx4_get_base_qpn);
1679200f 372
ffe455ad 373void __mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, u64 mac)
1679200f 374{
143b3efb
EE
375 struct mlx4_port_info *info;
376 struct mlx4_mac_table *table;
ffe455ad 377 int index;
5f61385d
MS
378 bool dup = mlx4_is_mf_bonded(dev);
379 u8 dup_port = (port == 1) ? 2 : 1;
380 struct mlx4_mac_table *dup_table = &mlx4_priv(dev)->port[dup_port].mac_table;
1679200f 381
143b3efb
EE
382 if (port < 1 || port > dev->caps.num_ports) {
383 mlx4_warn(dev, "invalid port number (%d), aborting...\n", port);
384 return;
385 }
386 info = &mlx4_priv(dev)->port[port];
387 table = &info->mac_table;
5f61385d
MS
388
389 if (dup) {
390 if (port == 1) {
391 mutex_lock(&table->mutex);
03a79f31 392 mutex_lock_nested(&dup_table->mutex, SINGLE_DEPTH_NESTING);
5f61385d
MS
393 } else {
394 mutex_lock(&dup_table->mutex);
03a79f31 395 mutex_lock_nested(&table->mutex, SINGLE_DEPTH_NESTING);
5f61385d
MS
396 }
397 } else {
398 mutex_lock(&table->mutex);
399 }
400
6ce71acd 401 index = find_index(dev, table, mac);
1679200f
YP
402
403 if (validate_index(dev, table, index))
404 goto out;
5f61385d
MS
405
406 if (--table->refs[index] || table->is_dup[index]) {
1a91de28
JP
407 mlx4_dbg(dev, "Have more references for index %d, no need to modify mac table\n",
408 index);
5f61385d
MS
409 if (!table->refs[index])
410 dup_table->is_dup[index] = false;
6ce71acd
RE
411 goto out;
412 }
1679200f 413
ffe455ad 414 table->entries[index] = 0;
5f61385d
MS
415 if (mlx4_set_port_mac_table(dev, port, table->entries))
416 mlx4_warn(dev, "Fail to set mac in port %d during unregister\n", port);
ffe455ad 417 --table->total;
5f61385d
MS
418
419 if (dup) {
420 dup_table->is_dup[index] = false;
421 if (dup_table->refs[index])
422 goto out;
423 dup_table->entries[index] = 0;
424 if (mlx4_set_port_mac_table(dev, dup_port, dup_table->entries))
425 mlx4_warn(dev, "Fail to set mac in duplicate port %d during unregister\n", dup_port);
426
427 --table->total;
428 }
2a2336f8 429out:
5f61385d
MS
430 if (dup) {
431 if (port == 2) {
432 mutex_unlock(&table->mutex);
433 mutex_unlock(&dup_table->mutex);
434 } else {
435 mutex_unlock(&dup_table->mutex);
436 mutex_unlock(&table->mutex);
437 }
438 } else {
439 mutex_unlock(&table->mutex);
440 }
2a2336f8 441}
ffe455ad
EE
442EXPORT_SYMBOL_GPL(__mlx4_unregister_mac);
443
444void mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, u64 mac)
445{
e7dbeba8 446 u64 out_param = 0;
ffe455ad
EE
447
448 if (mlx4_is_mfunc(dev)) {
acddd5dd
JM
449 if (!(dev->flags & MLX4_FLAG_OLD_REG_MAC)) {
450 (void) mlx4_cmd_imm(dev, mac, &out_param,
451 ((u32) port) << 8 | (u32) RES_MAC,
452 RES_OP_RESERVE_AND_MAP, MLX4_CMD_FREE_RES,
453 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
454 } else {
455 /* use old unregister mac format */
456 set_param_l(&out_param, port);
457 (void) mlx4_cmd_imm(dev, mac, &out_param, RES_MAC,
458 RES_OP_RESERVE_AND_MAP, MLX4_CMD_FREE_RES,
459 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
460 }
ffe455ad
EE
461 return;
462 }
463 __mlx4_unregister_mac(dev, port, mac);
464 return;
465}
2a2336f8
YP
466EXPORT_SYMBOL_GPL(mlx4_unregister_mac);
467
16a10ffd 468int __mlx4_replace_mac(struct mlx4_dev *dev, u8 port, int qpn, u64 new_mac)
1679200f
YP
469{
470 struct mlx4_port_info *info = &mlx4_priv(dev)->port[port];
471 struct mlx4_mac_table *table = &info->mac_table;
ffe455ad
EE
472 int index = qpn - info->base_qpn;
473 int err = 0;
5f61385d
MS
474 bool dup = mlx4_is_mf_bonded(dev);
475 u8 dup_port = (port == 1) ? 2 : 1;
476 struct mlx4_mac_table *dup_table = &mlx4_priv(dev)->port[dup_port].mac_table;
1679200f 477
ffe455ad 478 /* CX1 doesn't support multi-functions */
5f61385d
MS
479 if (dup) {
480 if (port == 1) {
481 mutex_lock(&table->mutex);
03a79f31 482 mutex_lock_nested(&dup_table->mutex, SINGLE_DEPTH_NESTING);
5f61385d
MS
483 } else {
484 mutex_lock(&dup_table->mutex);
03a79f31 485 mutex_lock_nested(&table->mutex, SINGLE_DEPTH_NESTING);
5f61385d
MS
486 }
487 } else {
488 mutex_lock(&table->mutex);
489 }
1679200f
YP
490
491 err = validate_index(dev, table, index);
492 if (err)
493 goto out;
494
495 table->entries[index] = cpu_to_be64(new_mac | MLX4_MAC_VALID);
496
497 err = mlx4_set_port_mac_table(dev, port, table->entries);
498 if (unlikely(err)) {
ffe455ad
EE
499 mlx4_err(dev, "Failed adding MAC: 0x%llx\n",
500 (unsigned long long) new_mac);
1679200f 501 table->entries[index] = 0;
5f61385d
MS
502 } else {
503 if (dup) {
504 dup_table->entries[index] = cpu_to_be64(new_mac | MLX4_MAC_VALID);
505
506 err = mlx4_set_port_mac_table(dev, dup_port, dup_table->entries);
507 if (unlikely(err)) {
508 mlx4_err(dev, "Failed adding duplicate MAC: 0x%llx\n",
509 (unsigned long long)new_mac);
510 dup_table->entries[index] = 0;
511 }
512 }
1679200f
YP
513 }
514out:
5f61385d
MS
515 if (dup) {
516 if (port == 2) {
517 mutex_unlock(&table->mutex);
518 mutex_unlock(&dup_table->mutex);
519 } else {
520 mutex_unlock(&dup_table->mutex);
521 mutex_unlock(&table->mutex);
522 }
523 } else {
524 mutex_unlock(&table->mutex);
525 }
1679200f
YP
526 return err;
527}
16a10ffd 528EXPORT_SYMBOL_GPL(__mlx4_replace_mac);
ffe455ad 529
2a2336f8
YP
530static int mlx4_set_port_vlan_table(struct mlx4_dev *dev, u8 port,
531 __be32 *entries)
532{
533 struct mlx4_cmd_mailbox *mailbox;
534 u32 in_mod;
535 int err;
536
537 mailbox = mlx4_alloc_cmd_mailbox(dev);
538 if (IS_ERR(mailbox))
539 return PTR_ERR(mailbox);
540
541 memcpy(mailbox->buf, entries, MLX4_VLAN_TABLE_SIZE);
542 in_mod = MLX4_SET_PORT_VLAN_TABLE << 8 | port;
a130b590
IS
543 err = mlx4_cmd(dev, mailbox->dma, in_mod, MLX4_SET_PORT_ETH_OPCODE,
544 MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B,
545 MLX4_CMD_NATIVE);
2a2336f8
YP
546
547 mlx4_free_cmd_mailbox(dev, mailbox);
548
549 return err;
550}
551
4c3eb3ca
EC
552int mlx4_find_cached_vlan(struct mlx4_dev *dev, u8 port, u16 vid, int *idx)
553{
554 struct mlx4_vlan_table *table = &mlx4_priv(dev)->port[port].vlan_table;
555 int i;
556
557 for (i = 0; i < MLX4_MAX_VLAN_NUM; ++i) {
558 if (table->refs[i] &&
559 (vid == (MLX4_VLAN_MASK &
560 be32_to_cpu(table->entries[i])))) {
561 /* VLAN already registered, increase reference count */
562 *idx = i;
563 return 0;
564 }
565 }
566
567 return -ENOENT;
568}
569EXPORT_SYMBOL_GPL(mlx4_find_cached_vlan);
570
3f7fb021 571int __mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan,
ffe455ad 572 int *index)
2a2336f8
YP
573{
574 struct mlx4_vlan_table *table = &mlx4_priv(dev)->port[port].vlan_table;
575 int i, err = 0;
576 int free = -1;
5f61385d
MS
577 int free_for_dup = -1;
578 bool dup = mlx4_is_mf_bonded(dev);
579 u8 dup_port = (port == 1) ? 2 : 1;
580 struct mlx4_vlan_table *dup_table = &mlx4_priv(dev)->port[dup_port].vlan_table;
581 bool need_mf_bond = mlx4_need_mf_bond(dev);
582 bool can_mf_bond = true;
583
584 mlx4_dbg(dev, "Registering VLAN: %d for port %d %s duplicate\n",
585 vlan, port,
586 dup ? "with" : "without");
587
588 if (need_mf_bond) {
589 if (port == 1) {
590 mutex_lock(&table->mutex);
03a79f31 591 mutex_lock_nested(&dup_table->mutex, SINGLE_DEPTH_NESTING);
5f61385d
MS
592 } else {
593 mutex_lock(&dup_table->mutex);
03a79f31 594 mutex_lock_nested(&table->mutex, SINGLE_DEPTH_NESTING);
5f61385d
MS
595 }
596 } else {
597 mutex_lock(&table->mutex);
598 }
e72ebf5a
YP
599
600 if (table->total == table->max) {
601 /* No free vlan entries */
602 err = -ENOSPC;
603 goto out;
604 }
605
5f61385d
MS
606 if (need_mf_bond) {
607 int index_at_port = -1;
608 int index_at_dup_port = -1;
609
610 for (i = MLX4_VLAN_REGULAR; i < MLX4_MAX_VLAN_NUM; i++) {
611 if ((vlan == (MLX4_VLAN_MASK & be32_to_cpu(table->entries[i]))))
612 index_at_port = i;
613 if ((vlan == (MLX4_VLAN_MASK & be32_to_cpu(dup_table->entries[i]))))
614 index_at_dup_port = i;
615 }
616 /* check that same vlan is not in the tables at different indices */
617 if ((index_at_port != index_at_dup_port) &&
618 (index_at_port >= 0) &&
619 (index_at_dup_port >= 0))
620 can_mf_bond = false;
621
622 /* If the vlan is already in the primary table, the slot must be
623 * available in the duplicate table as well.
624 */
625 if (index_at_port >= 0 && index_at_dup_port < 0 &&
626 dup_table->refs[index_at_port]) {
627 can_mf_bond = false;
628 }
629 /* If the vlan is already in the duplicate table, check that the
630 * corresponding index is not occupied in the primary table, or
631 * the primary table already contains the vlan at the same index.
632 * Otherwise, you cannot bond (primary contains a different vlan
633 * at that index).
634 */
635 if (index_at_dup_port >= 0) {
636 if (!table->refs[index_at_dup_port] ||
637 (vlan == (MLX4_VLAN_MASK & be32_to_cpu(dup_table->entries[index_at_dup_port]))))
638 free_for_dup = index_at_dup_port;
639 else
640 can_mf_bond = false;
641 }
642 }
643
2a2336f8 644 for (i = MLX4_VLAN_REGULAR; i < MLX4_MAX_VLAN_NUM; i++) {
5f61385d
MS
645 if (!table->refs[i]) {
646 if (free < 0)
647 free = i;
648 if (free_for_dup < 0 && need_mf_bond && can_mf_bond) {
649 if (!dup_table->refs[i])
650 free_for_dup = i;
651 }
2a2336f8
YP
652 }
653
5f61385d 654 if ((table->refs[i] || table->is_dup[i]) &&
2a2336f8
YP
655 (vlan == (MLX4_VLAN_MASK &
656 be32_to_cpu(table->entries[i])))) {
25985edc 657 /* Vlan already registered, increase references count */
5f61385d 658 mlx4_dbg(dev, "vlan %u is already registered.\n", vlan);
2a2336f8
YP
659 *index = i;
660 ++table->refs[i];
5f61385d
MS
661 if (dup) {
662 u16 dup_vlan = MLX4_VLAN_MASK & be32_to_cpu(dup_table->entries[i]);
663
664 if (dup_vlan != vlan || !dup_table->is_dup[i]) {
665 mlx4_warn(dev, "register vlan: expected duplicate vlan %u on port %d index %d\n",
666 vlan, dup_port, i);
667 }
668 }
2a2336f8
YP
669 goto out;
670 }
671 }
672
5f61385d
MS
673 if (need_mf_bond && (free_for_dup < 0)) {
674 if (dup) {
675 mlx4_warn(dev, "Fail to allocate duplicate VLAN table entry\n");
676 mlx4_warn(dev, "High Availability for virtual functions may not work as expected\n");
677 dup = false;
678 }
679 can_mf_bond = false;
680 }
681
682 if (need_mf_bond && can_mf_bond)
683 free = free_for_dup;
684
0926f910
EC
685 if (free < 0) {
686 err = -ENOMEM;
687 goto out;
688 }
689
ffe455ad 690 /* Register new VLAN */
2a2336f8 691 table->refs[free] = 1;
5f61385d 692 table->is_dup[free] = false;
2a2336f8
YP
693 table->entries[free] = cpu_to_be32(vlan | MLX4_VLAN_VALID);
694
695 err = mlx4_set_port_vlan_table(dev, port, table->entries);
696 if (unlikely(err)) {
697 mlx4_warn(dev, "Failed adding vlan: %u\n", vlan);
698 table->refs[free] = 0;
699 table->entries[free] = 0;
700 goto out;
701 }
5f61385d
MS
702 ++table->total;
703 if (dup) {
704 dup_table->refs[free] = 0;
705 dup_table->is_dup[free] = true;
706 dup_table->entries[free] = cpu_to_be32(vlan | MLX4_VLAN_VALID);
707
708 err = mlx4_set_port_vlan_table(dev, dup_port, dup_table->entries);
709 if (unlikely(err)) {
710 mlx4_warn(dev, "Failed adding duplicate vlan: %u\n", vlan);
711 dup_table->is_dup[free] = false;
712 dup_table->entries[free] = 0;
713 goto out;
714 }
715 ++dup_table->total;
716 }
2a2336f8
YP
717
718 *index = free;
2a2336f8 719out:
5f61385d
MS
720 if (need_mf_bond) {
721 if (port == 2) {
722 mutex_unlock(&table->mutex);
723 mutex_unlock(&dup_table->mutex);
724 } else {
725 mutex_unlock(&dup_table->mutex);
726 mutex_unlock(&table->mutex);
727 }
728 } else {
729 mutex_unlock(&table->mutex);
730 }
2a2336f8
YP
731 return err;
732}
ffe455ad
EE
733
734int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index)
735{
e7dbeba8 736 u64 out_param = 0;
ffe455ad
EE
737 int err;
738
162226a1
JM
739 if (vlan > 4095)
740 return -EINVAL;
741
ffe455ad 742 if (mlx4_is_mfunc(dev)) {
acddd5dd
JM
743 err = mlx4_cmd_imm(dev, vlan, &out_param,
744 ((u32) port) << 8 | (u32) RES_VLAN,
ffe455ad
EE
745 RES_OP_RESERVE_AND_MAP, MLX4_CMD_ALLOC_RES,
746 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
747 if (!err)
748 *index = get_param_l(&out_param);
749
750 return err;
751 }
752 return __mlx4_register_vlan(dev, port, vlan, index);
753}
2a2336f8
YP
754EXPORT_SYMBOL_GPL(mlx4_register_vlan);
755
2009d005 756void __mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, u16 vlan)
2a2336f8
YP
757{
758 struct mlx4_vlan_table *table = &mlx4_priv(dev)->port[port].vlan_table;
2009d005 759 int index;
5f61385d
MS
760 bool dup = mlx4_is_mf_bonded(dev);
761 u8 dup_port = (port == 1) ? 2 : 1;
762 struct mlx4_vlan_table *dup_table = &mlx4_priv(dev)->port[dup_port].vlan_table;
763
764 if (dup) {
765 if (port == 1) {
766 mutex_lock(&table->mutex);
03a79f31 767 mutex_lock_nested(&dup_table->mutex, SINGLE_DEPTH_NESTING);
5f61385d
MS
768 } else {
769 mutex_lock(&dup_table->mutex);
03a79f31 770 mutex_lock_nested(&table->mutex, SINGLE_DEPTH_NESTING);
5f61385d
MS
771 }
772 } else {
773 mutex_lock(&table->mutex);
774 }
2a2336f8 775
2009d005
JM
776 if (mlx4_find_cached_vlan(dev, port, vlan, &index)) {
777 mlx4_warn(dev, "vlan 0x%x is not in the vlan table\n", vlan);
778 goto out;
2a2336f8
YP
779 }
780
2009d005
JM
781 if (index < MLX4_VLAN_REGULAR) {
782 mlx4_warn(dev, "Trying to free special vlan index %d\n", index);
2a2336f8
YP
783 goto out;
784 }
2009d005 785
5f61385d 786 if (--table->refs[index] || table->is_dup[index]) {
1a91de28
JP
787 mlx4_dbg(dev, "Have %d more references for index %d, no need to modify vlan table\n",
788 table->refs[index], index);
5f61385d
MS
789 if (!table->refs[index])
790 dup_table->is_dup[index] = false;
2a2336f8
YP
791 goto out;
792 }
793 table->entries[index] = 0;
5f61385d
MS
794 if (mlx4_set_port_vlan_table(dev, port, table->entries))
795 mlx4_warn(dev, "Fail to set vlan in port %d during unregister\n", port);
2a2336f8 796 --table->total;
5f61385d
MS
797 if (dup) {
798 dup_table->is_dup[index] = false;
799 if (dup_table->refs[index])
800 goto out;
801 dup_table->entries[index] = 0;
802 if (mlx4_set_port_vlan_table(dev, dup_port, dup_table->entries))
803 mlx4_warn(dev, "Fail to set vlan in duplicate port %d during unregister\n", dup_port);
804 --dup_table->total;
805 }
2a2336f8 806out:
5f61385d
MS
807 if (dup) {
808 if (port == 2) {
809 mutex_unlock(&table->mutex);
810 mutex_unlock(&dup_table->mutex);
811 } else {
812 mutex_unlock(&dup_table->mutex);
813 mutex_unlock(&table->mutex);
814 }
815 } else {
816 mutex_unlock(&table->mutex);
817 }
2a2336f8 818}
ffe455ad 819
2009d005 820void mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, u16 vlan)
ffe455ad 821{
162226a1 822 u64 out_param = 0;
ffe455ad
EE
823
824 if (mlx4_is_mfunc(dev)) {
2009d005 825 (void) mlx4_cmd_imm(dev, vlan, &out_param,
acddd5dd 826 ((u32) port) << 8 | (u32) RES_VLAN,
162226a1
JM
827 RES_OP_RESERVE_AND_MAP,
828 MLX4_CMD_FREE_RES, MLX4_CMD_TIME_CLASS_A,
829 MLX4_CMD_WRAPPED);
ffe455ad
EE
830 return;
831 }
2009d005 832 __mlx4_unregister_vlan(dev, port, vlan);
ffe455ad 833}
2a2336f8 834EXPORT_SYMBOL_GPL(mlx4_unregister_vlan);
7ff93f8b 835
5f61385d
MS
836int mlx4_bond_mac_table(struct mlx4_dev *dev)
837{
838 struct mlx4_mac_table *t1 = &mlx4_priv(dev)->port[1].mac_table;
839 struct mlx4_mac_table *t2 = &mlx4_priv(dev)->port[2].mac_table;
840 int ret = 0;
841 int i;
842 bool update1 = false;
843 bool update2 = false;
844
845 mutex_lock(&t1->mutex);
846 mutex_lock(&t2->mutex);
847 for (i = 0; i < MLX4_MAX_MAC_NUM; i++) {
848 if ((t1->entries[i] != t2->entries[i]) &&
849 t1->entries[i] && t2->entries[i]) {
850 mlx4_warn(dev, "can't duplicate entry %d in mac table\n", i);
851 ret = -EINVAL;
852 goto unlock;
853 }
854 }
855
856 for (i = 0; i < MLX4_MAX_MAC_NUM; i++) {
857 if (t1->entries[i] && !t2->entries[i]) {
858 t2->entries[i] = t1->entries[i];
859 t2->is_dup[i] = true;
860 update2 = true;
861 } else if (!t1->entries[i] && t2->entries[i]) {
862 t1->entries[i] = t2->entries[i];
863 t1->is_dup[i] = true;
864 update1 = true;
865 } else if (t1->entries[i] && t2->entries[i]) {
866 t1->is_dup[i] = true;
867 t2->is_dup[i] = true;
868 }
869 }
870
871 if (update1) {
872 ret = mlx4_set_port_mac_table(dev, 1, t1->entries);
873 if (ret)
874 mlx4_warn(dev, "failed to set MAC table for port 1 (%d)\n", ret);
875 }
876 if (!ret && update2) {
877 ret = mlx4_set_port_mac_table(dev, 2, t2->entries);
878 if (ret)
879 mlx4_warn(dev, "failed to set MAC table for port 2 (%d)\n", ret);
880 }
881
882 if (ret)
883 mlx4_warn(dev, "failed to create mirror MAC tables\n");
884unlock:
885 mutex_unlock(&t2->mutex);
886 mutex_unlock(&t1->mutex);
887 return ret;
888}
889
890int mlx4_unbond_mac_table(struct mlx4_dev *dev)
891{
892 struct mlx4_mac_table *t1 = &mlx4_priv(dev)->port[1].mac_table;
893 struct mlx4_mac_table *t2 = &mlx4_priv(dev)->port[2].mac_table;
894 int ret = 0;
895 int ret1;
896 int i;
897 bool update1 = false;
898 bool update2 = false;
899
900 mutex_lock(&t1->mutex);
901 mutex_lock(&t2->mutex);
902 for (i = 0; i < MLX4_MAX_MAC_NUM; i++) {
903 if (t1->entries[i] != t2->entries[i]) {
904 mlx4_warn(dev, "mac table is in an unexpected state when trying to unbond\n");
905 ret = -EINVAL;
906 goto unlock;
907 }
908 }
909
910 for (i = 0; i < MLX4_MAX_MAC_NUM; i++) {
911 if (!t1->entries[i])
912 continue;
913 t1->is_dup[i] = false;
914 if (!t1->refs[i]) {
915 t1->entries[i] = 0;
916 update1 = true;
917 }
918 t2->is_dup[i] = false;
919 if (!t2->refs[i]) {
920 t2->entries[i] = 0;
921 update2 = true;
922 }
923 }
924
925 if (update1) {
926 ret = mlx4_set_port_mac_table(dev, 1, t1->entries);
927 if (ret)
928 mlx4_warn(dev, "failed to unmirror MAC tables for port 1(%d)\n", ret);
929 }
930 if (update2) {
931 ret1 = mlx4_set_port_mac_table(dev, 2, t2->entries);
932 if (ret1) {
933 mlx4_warn(dev, "failed to unmirror MAC tables for port 2(%d)\n", ret1);
934 ret = ret1;
935 }
936 }
937unlock:
938 mutex_unlock(&t2->mutex);
939 mutex_unlock(&t1->mutex);
940 return ret;
941}
942
943int mlx4_bond_vlan_table(struct mlx4_dev *dev)
944{
945 struct mlx4_vlan_table *t1 = &mlx4_priv(dev)->port[1].vlan_table;
946 struct mlx4_vlan_table *t2 = &mlx4_priv(dev)->port[2].vlan_table;
947 int ret = 0;
948 int i;
949 bool update1 = false;
950 bool update2 = false;
951
952 mutex_lock(&t1->mutex);
953 mutex_lock(&t2->mutex);
954 for (i = 0; i < MLX4_MAX_VLAN_NUM; i++) {
955 if ((t1->entries[i] != t2->entries[i]) &&
956 t1->entries[i] && t2->entries[i]) {
957 mlx4_warn(dev, "can't duplicate entry %d in vlan table\n", i);
958 ret = -EINVAL;
959 goto unlock;
960 }
961 }
962
963 for (i = 0; i < MLX4_MAX_VLAN_NUM; i++) {
964 if (t1->entries[i] && !t2->entries[i]) {
965 t2->entries[i] = t1->entries[i];
966 t2->is_dup[i] = true;
967 update2 = true;
968 } else if (!t1->entries[i] && t2->entries[i]) {
969 t1->entries[i] = t2->entries[i];
970 t1->is_dup[i] = true;
971 update1 = true;
972 } else if (t1->entries[i] && t2->entries[i]) {
973 t1->is_dup[i] = true;
974 t2->is_dup[i] = true;
975 }
976 }
977
978 if (update1) {
979 ret = mlx4_set_port_vlan_table(dev, 1, t1->entries);
980 if (ret)
981 mlx4_warn(dev, "failed to set VLAN table for port 1 (%d)\n", ret);
982 }
983 if (!ret && update2) {
984 ret = mlx4_set_port_vlan_table(dev, 2, t2->entries);
985 if (ret)
986 mlx4_warn(dev, "failed to set VLAN table for port 2 (%d)\n", ret);
987 }
988
989 if (ret)
990 mlx4_warn(dev, "failed to create mirror VLAN tables\n");
991unlock:
992 mutex_unlock(&t2->mutex);
993 mutex_unlock(&t1->mutex);
994 return ret;
995}
996
997int mlx4_unbond_vlan_table(struct mlx4_dev *dev)
998{
999 struct mlx4_vlan_table *t1 = &mlx4_priv(dev)->port[1].vlan_table;
1000 struct mlx4_vlan_table *t2 = &mlx4_priv(dev)->port[2].vlan_table;
1001 int ret = 0;
1002 int ret1;
1003 int i;
1004 bool update1 = false;
1005 bool update2 = false;
1006
1007 mutex_lock(&t1->mutex);
1008 mutex_lock(&t2->mutex);
1009 for (i = 0; i < MLX4_MAX_VLAN_NUM; i++) {
1010 if (t1->entries[i] != t2->entries[i]) {
1011 mlx4_warn(dev, "vlan table is in an unexpected state when trying to unbond\n");
1012 ret = -EINVAL;
1013 goto unlock;
1014 }
1015 }
1016
1017 for (i = 0; i < MLX4_MAX_VLAN_NUM; i++) {
1018 if (!t1->entries[i])
1019 continue;
1020 t1->is_dup[i] = false;
1021 if (!t1->refs[i]) {
1022 t1->entries[i] = 0;
1023 update1 = true;
1024 }
1025 t2->is_dup[i] = false;
1026 if (!t2->refs[i]) {
1027 t2->entries[i] = 0;
1028 update2 = true;
1029 }
1030 }
1031
1032 if (update1) {
1033 ret = mlx4_set_port_vlan_table(dev, 1, t1->entries);
1034 if (ret)
1035 mlx4_warn(dev, "failed to unmirror VLAN tables for port 1(%d)\n", ret);
1036 }
1037 if (update2) {
1038 ret1 = mlx4_set_port_vlan_table(dev, 2, t2->entries);
1039 if (ret1) {
1040 mlx4_warn(dev, "failed to unmirror VLAN tables for port 2(%d)\n", ret1);
1041 ret = ret1;
1042 }
1043 }
1044unlock:
1045 mutex_unlock(&t2->mutex);
1046 mutex_unlock(&t1->mutex);
1047 return ret;
1048}
1049
9a5aa622
JM
1050int mlx4_get_port_ib_caps(struct mlx4_dev *dev, u8 port, __be32 *caps)
1051{
1052 struct mlx4_cmd_mailbox *inmailbox, *outmailbox;
1053 u8 *inbuf, *outbuf;
1054 int err;
1055
1056 inmailbox = mlx4_alloc_cmd_mailbox(dev);
1057 if (IS_ERR(inmailbox))
1058 return PTR_ERR(inmailbox);
1059
1060 outmailbox = mlx4_alloc_cmd_mailbox(dev);
1061 if (IS_ERR(outmailbox)) {
1062 mlx4_free_cmd_mailbox(dev, inmailbox);
1063 return PTR_ERR(outmailbox);
1064 }
1065
1066 inbuf = inmailbox->buf;
1067 outbuf = outmailbox->buf;
9a5aa622
JM
1068 inbuf[0] = 1;
1069 inbuf[1] = 1;
1070 inbuf[2] = 1;
1071 inbuf[3] = 1;
1072 *(__be16 *) (&inbuf[16]) = cpu_to_be16(0x0015);
1073 *(__be32 *) (&inbuf[20]) = cpu_to_be32(port);
1074
1075 err = mlx4_cmd_box(dev, inmailbox->dma, outmailbox->dma, port, 3,
f9baff50
JM
1076 MLX4_CMD_MAD_IFC, MLX4_CMD_TIME_CLASS_C,
1077 MLX4_CMD_NATIVE);
9a5aa622
JM
1078 if (!err)
1079 *caps = *(__be32 *) (outbuf + 84);
1080 mlx4_free_cmd_mailbox(dev, inmailbox);
1081 mlx4_free_cmd_mailbox(dev, outmailbox);
1082 return err;
1083}
9cd59352 1084static struct mlx4_roce_gid_entry zgid_entry;
9a5aa622 1085
449fc488 1086int mlx4_get_slave_num_gids(struct mlx4_dev *dev, int slave, int port)
b6ffaeff 1087{
449fc488
MB
1088 int vfs;
1089 int slave_gid = slave;
1090 unsigned i;
1091 struct mlx4_slaves_pport slaves_pport;
1092 struct mlx4_active_ports actv_ports;
1093 unsigned max_port_p_one;
1094
b6ffaeff
JM
1095 if (slave == 0)
1096 return MLX4_ROCE_PF_GIDS;
449fc488
MB
1097
1098 /* Slave is a VF */
1099 slaves_pport = mlx4_phys_to_slaves_pport(dev, port);
1100 actv_ports = mlx4_get_active_ports(dev, slave);
1101 max_port_p_one = find_first_bit(actv_ports.ports, dev->caps.num_ports) +
1102 bitmap_weight(actv_ports.ports, dev->caps.num_ports) + 1;
1103
1104 for (i = 1; i < max_port_p_one; i++) {
1105 struct mlx4_active_ports exclusive_ports;
1106 struct mlx4_slaves_pport slaves_pport_actv;
1107 bitmap_zero(exclusive_ports.ports, dev->caps.num_ports);
1108 set_bit(i - 1, exclusive_ports.ports);
1109 if (i == port)
1110 continue;
1111 slaves_pport_actv = mlx4_phys_to_slaves_pport_actv(
1112 dev, &exclusive_ports);
1113 slave_gid -= bitmap_weight(slaves_pport_actv.slaves,
872bf2fb 1114 dev->persist->num_vfs + 1);
449fc488 1115 }
872bf2fb 1116 vfs = bitmap_weight(slaves_pport.slaves, dev->persist->num_vfs + 1) - 1;
449fc488
MB
1117 if (slave_gid <= ((MLX4_ROCE_MAX_GIDS - MLX4_ROCE_PF_GIDS) % vfs))
1118 return ((MLX4_ROCE_MAX_GIDS - MLX4_ROCE_PF_GIDS) / vfs) + 1;
1119 return (MLX4_ROCE_MAX_GIDS - MLX4_ROCE_PF_GIDS) / vfs;
b6ffaeff
JM
1120}
1121
449fc488 1122int mlx4_get_base_gid_ix(struct mlx4_dev *dev, int slave, int port)
b6ffaeff
JM
1123{
1124 int gids;
449fc488
MB
1125 unsigned i;
1126 int slave_gid = slave;
b6ffaeff
JM
1127 int vfs;
1128
449fc488
MB
1129 struct mlx4_slaves_pport slaves_pport;
1130 struct mlx4_active_ports actv_ports;
1131 unsigned max_port_p_one;
b6ffaeff
JM
1132
1133 if (slave == 0)
1134 return 0;
b6ffaeff 1135
449fc488
MB
1136 slaves_pport = mlx4_phys_to_slaves_pport(dev, port);
1137 actv_ports = mlx4_get_active_ports(dev, slave);
1138 max_port_p_one = find_first_bit(actv_ports.ports, dev->caps.num_ports) +
1139 bitmap_weight(actv_ports.ports, dev->caps.num_ports) + 1;
1140
1141 for (i = 1; i < max_port_p_one; i++) {
1142 struct mlx4_active_ports exclusive_ports;
1143 struct mlx4_slaves_pport slaves_pport_actv;
1144 bitmap_zero(exclusive_ports.ports, dev->caps.num_ports);
1145 set_bit(i - 1, exclusive_ports.ports);
1146 if (i == port)
1147 continue;
1148 slaves_pport_actv = mlx4_phys_to_slaves_pport_actv(
1149 dev, &exclusive_ports);
1150 slave_gid -= bitmap_weight(slaves_pport_actv.slaves,
872bf2fb 1151 dev->persist->num_vfs + 1);
449fc488
MB
1152 }
1153 gids = MLX4_ROCE_MAX_GIDS - MLX4_ROCE_PF_GIDS;
872bf2fb 1154 vfs = bitmap_weight(slaves_pport.slaves, dev->persist->num_vfs + 1) - 1;
449fc488
MB
1155 if (slave_gid <= gids % vfs)
1156 return MLX4_ROCE_PF_GIDS + ((gids / vfs) + 1) * (slave_gid - 1);
1157
1158 return MLX4_ROCE_PF_GIDS + (gids % vfs) +
1159 ((gids / vfs) * (slave_gid - 1));
b6ffaeff 1160}
449fc488 1161EXPORT_SYMBOL_GPL(mlx4_get_base_gid_ix);
b6ffaeff 1162
111c6094
JM
1163static int mlx4_reset_roce_port_gids(struct mlx4_dev *dev, int slave,
1164 int port, struct mlx4_cmd_mailbox *mailbox)
1165{
1166 struct mlx4_roce_gid_entry *gid_entry_mbox;
1167 struct mlx4_priv *priv = mlx4_priv(dev);
1168 int num_gids, base, offset;
1169 int i, err;
1170
1171 num_gids = mlx4_get_slave_num_gids(dev, slave, port);
1172 base = mlx4_get_base_gid_ix(dev, slave, port);
1173
1174 memset(mailbox->buf, 0, MLX4_MAILBOX_SIZE);
1175
1176 mutex_lock(&(priv->port[port].gid_table.mutex));
1177 /* Zero-out gids belonging to that slave in the port GID table */
1178 for (i = 0, offset = base; i < num_gids; offset++, i++)
1179 memcpy(priv->port[port].gid_table.roce_gids[offset].raw,
1180 zgid_entry.raw, MLX4_ROCE_GID_ENTRY_SIZE);
1181
1182 /* Now, copy roce port gids table to mailbox for passing to FW */
1183 gid_entry_mbox = (struct mlx4_roce_gid_entry *)mailbox->buf;
1184 for (i = 0; i < MLX4_ROCE_MAX_GIDS; gid_entry_mbox++, i++)
1185 memcpy(gid_entry_mbox->raw,
1186 priv->port[port].gid_table.roce_gids[i].raw,
1187 MLX4_ROCE_GID_ENTRY_SIZE);
1188
1189 err = mlx4_cmd(dev, mailbox->dma,
a130b590
IS
1190 ((u32)port) | (MLX4_SET_PORT_GID_TABLE << 8),
1191 MLX4_SET_PORT_ETH_OPCODE, MLX4_CMD_SET_PORT,
1192 MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE);
111c6094
JM
1193 mutex_unlock(&(priv->port[port].gid_table.mutex));
1194 return err;
1195}
1196
1197
1198void mlx4_reset_roce_gids(struct mlx4_dev *dev, int slave)
1199{
1200 struct mlx4_active_ports actv_ports;
1201 struct mlx4_cmd_mailbox *mailbox;
1202 int num_eth_ports, err;
1203 int i;
1204
872bf2fb 1205 if (slave < 0 || slave > dev->persist->num_vfs)
111c6094
JM
1206 return;
1207
1208 actv_ports = mlx4_get_active_ports(dev, slave);
1209
1210 for (i = 0, num_eth_ports = 0; i < dev->caps.num_ports; i++) {
1211 if (test_bit(i, actv_ports.ports)) {
1212 if (dev->caps.port_type[i + 1] != MLX4_PORT_TYPE_ETH)
1213 continue;
1214 num_eth_ports++;
1215 }
1216 }
1217
1218 if (!num_eth_ports)
1219 return;
1220
1221 /* have ETH ports. Alloc mailbox for SET_PORT command */
1222 mailbox = mlx4_alloc_cmd_mailbox(dev);
1223 if (IS_ERR(mailbox))
1224 return;
1225
1226 for (i = 0; i < dev->caps.num_ports; i++) {
1227 if (test_bit(i, actv_ports.ports)) {
1228 if (dev->caps.port_type[i + 1] != MLX4_PORT_TYPE_ETH)
1229 continue;
1230 err = mlx4_reset_roce_port_gids(dev, slave, i + 1, mailbox);
1231 if (err)
1232 mlx4_warn(dev, "Could not reset ETH port GID table for slave %d, port %d (%d)\n",
1233 slave, i + 1, err);
1234 }
1235 }
1236
1237 mlx4_free_cmd_mailbox(dev, mailbox);
1238 return;
1239}
1240
ffe455ad
EE
1241static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod,
1242 u8 op_mod, struct mlx4_cmd_mailbox *inbox)
1243{
1244 struct mlx4_priv *priv = mlx4_priv(dev);
1245 struct mlx4_port_info *port_info;
1246 struct mlx4_mfunc_master_ctx *master = &priv->mfunc.master;
1247 struct mlx4_slave_state *slave_st = &master->slave_state[slave];
1248 struct mlx4_set_port_rqp_calc_context *qpn_context;
1249 struct mlx4_set_port_general_context *gen_context;
b6ffaeff 1250 struct mlx4_roce_gid_entry *gid_entry_tbl, *gid_entry_mbox, *gid_entry_mb1;
ffe455ad
EE
1251 int reset_qkey_viols;
1252 int port;
1253 int is_eth;
b6ffaeff
JM
1254 int num_gids;
1255 int base;
ffe455ad
EE
1256 u32 in_modifier;
1257 u32 promisc;
1258 u16 mtu, prev_mtu;
1259 int err;
b6ffaeff
JM
1260 int i, j;
1261 int offset;
ffe455ad
EE
1262 __be32 agg_cap_mask;
1263 __be32 slave_cap_mask;
1264 __be32 new_cap_mask;
1265
1266 port = in_mod & 0xff;
1267 in_modifier = in_mod >> 8;
1268 is_eth = op_mod;
1269 port_info = &priv->port[port];
1270
1271 /* Slaves cannot perform SET_PORT operations except changing MTU */
1272 if (is_eth) {
1273 if (slave != dev->caps.function &&
9cd59352
JM
1274 in_modifier != MLX4_SET_PORT_GENERAL &&
1275 in_modifier != MLX4_SET_PORT_GID_TABLE) {
ffe455ad
EE
1276 mlx4_warn(dev, "denying SET_PORT for slave:%d\n",
1277 slave);
1278 return -EINVAL;
1279 }
1280 switch (in_modifier) {
1281 case MLX4_SET_PORT_RQP_CALC:
1282 qpn_context = inbox->buf;
1283 qpn_context->base_qpn =
1284 cpu_to_be32(port_info->base_qpn);
1285 qpn_context->n_mac = 0x7;
1286 promisc = be32_to_cpu(qpn_context->promisc) >>
1287 SET_PORT_PROMISC_SHIFT;
1288 qpn_context->promisc = cpu_to_be32(
1289 promisc << SET_PORT_PROMISC_SHIFT |
1290 port_info->base_qpn);
1291 promisc = be32_to_cpu(qpn_context->mcast) >>
1292 SET_PORT_MC_PROMISC_SHIFT;
1293 qpn_context->mcast = cpu_to_be32(
1294 promisc << SET_PORT_MC_PROMISC_SHIFT |
1295 port_info->base_qpn);
1296 break;
1297 case MLX4_SET_PORT_GENERAL:
1298 gen_context = inbox->buf;
1299 /* Mtu is configured as the max MTU among all the
1300 * the functions on the port. */
1301 mtu = be16_to_cpu(gen_context->mtu);
c59fec20
EE
1302 mtu = min_t(int, mtu, dev->caps.eth_mtu_cap[port] +
1303 ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN);
ffe455ad
EE
1304 prev_mtu = slave_st->mtu[port];
1305 slave_st->mtu[port] = mtu;
1306 if (mtu > master->max_mtu[port])
1307 master->max_mtu[port] = mtu;
1308 if (mtu < prev_mtu && prev_mtu ==
1309 master->max_mtu[port]) {
1310 slave_st->mtu[port] = mtu;
1311 master->max_mtu[port] = mtu;
1312 for (i = 0; i < dev->num_slaves; i++) {
1313 master->max_mtu[port] =
1314 max(master->max_mtu[port],
1315 master->slave_state[i].mtu[port]);
1316 }
1317 }
1318
1319 gen_context->mtu = cpu_to_be16(master->max_mtu[port]);
2a500090
EE
1320 /* Slave cannot change Global Pause configuration */
1321 if (slave != mlx4_master_func_num(dev) &&
1322 ((gen_context->pptx != master->pptx) ||
1323 (gen_context->pprx != master->pprx))) {
1324 gen_context->pptx = master->pptx;
1325 gen_context->pprx = master->pprx;
1326 mlx4_warn(dev,
1327 "denying Global Pause change for slave:%d\n",
1328 slave);
1329 } else {
1330 master->pptx = gen_context->pptx;
1331 master->pprx = gen_context->pprx;
1332 }
ffe455ad 1333 break;
9cd59352 1334 case MLX4_SET_PORT_GID_TABLE:
b6ffaeff
JM
1335 /* change to MULTIPLE entries: number of guest's gids
1336 * need a FOR-loop here over number of gids the guest has.
1337 * 1. Check no duplicates in gids passed by slave
1338 */
449fc488
MB
1339 num_gids = mlx4_get_slave_num_gids(dev, slave, port);
1340 base = mlx4_get_base_gid_ix(dev, slave, port);
b6ffaeff
JM
1341 gid_entry_mbox = (struct mlx4_roce_gid_entry *)(inbox->buf);
1342 for (i = 0; i < num_gids; gid_entry_mbox++, i++) {
1343 if (!memcmp(gid_entry_mbox->raw, zgid_entry.raw,
1344 sizeof(zgid_entry)))
1345 continue;
1346 gid_entry_mb1 = gid_entry_mbox + 1;
1347 for (j = i + 1; j < num_gids; gid_entry_mb1++, j++) {
1348 if (!memcmp(gid_entry_mb1->raw,
1349 zgid_entry.raw, sizeof(zgid_entry)))
1350 continue;
1351 if (!memcmp(gid_entry_mb1->raw, gid_entry_mbox->raw,
1352 sizeof(gid_entry_mbox->raw))) {
1353 /* found duplicate */
1354 return -EINVAL;
9cd59352
JM
1355 }
1356 }
1357 }
b6ffaeff
JM
1358
1359 /* 2. Check that do not have duplicates in OTHER
1360 * entries in the port GID table
1361 */
111c6094
JM
1362
1363 mutex_lock(&(priv->port[port].gid_table.mutex));
9cd59352 1364 for (i = 0; i < MLX4_ROCE_MAX_GIDS; i++) {
b6ffaeff
JM
1365 if (i >= base && i < base + num_gids)
1366 continue; /* don't compare to slave's current gids */
111c6094 1367 gid_entry_tbl = &priv->port[port].gid_table.roce_gids[i];
b6ffaeff
JM
1368 if (!memcmp(gid_entry_tbl->raw, zgid_entry.raw, sizeof(zgid_entry)))
1369 continue;
1370 gid_entry_mbox = (struct mlx4_roce_gid_entry *)(inbox->buf);
1371 for (j = 0; j < num_gids; gid_entry_mbox++, j++) {
1372 if (!memcmp(gid_entry_mbox->raw, zgid_entry.raw,
1373 sizeof(zgid_entry)))
1374 continue;
1375 if (!memcmp(gid_entry_mbox->raw, gid_entry_tbl->raw,
1376 sizeof(gid_entry_tbl->raw))) {
1377 /* found duplicate */
1a91de28 1378 mlx4_warn(dev, "requested gid entry for slave:%d is a duplicate of gid at index %d\n",
b6ffaeff 1379 slave, i);
111c6094 1380 mutex_unlock(&(priv->port[port].gid_table.mutex));
b6ffaeff
JM
1381 return -EINVAL;
1382 }
1383 }
9cd59352 1384 }
b6ffaeff
JM
1385
1386 /* insert slave GIDs with memcpy, starting at slave's base index */
1387 gid_entry_mbox = (struct mlx4_roce_gid_entry *)(inbox->buf);
1388 for (i = 0, offset = base; i < num_gids; gid_entry_mbox++, offset++, i++)
111c6094
JM
1389 memcpy(priv->port[port].gid_table.roce_gids[offset].raw,
1390 gid_entry_mbox->raw, MLX4_ROCE_GID_ENTRY_SIZE);
b6ffaeff
JM
1391
1392 /* Now, copy roce port gids table to current mailbox for passing to FW */
1393 gid_entry_mbox = (struct mlx4_roce_gid_entry *)(inbox->buf);
1394 for (i = 0; i < MLX4_ROCE_MAX_GIDS; gid_entry_mbox++, i++)
111c6094
JM
1395 memcpy(gid_entry_mbox->raw,
1396 priv->port[port].gid_table.roce_gids[i].raw,
1397 MLX4_ROCE_GID_ENTRY_SIZE);
1398
1399 err = mlx4_cmd(dev, inbox->dma, in_mod & 0xffff, op_mod,
1400 MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B,
1401 MLX4_CMD_NATIVE);
1402 mutex_unlock(&(priv->port[port].gid_table.mutex));
1403 return err;
ffe455ad 1404 }
111c6094
JM
1405
1406 return mlx4_cmd(dev, inbox->dma, in_mod & 0xffff, op_mod,
ffe455ad
EE
1407 MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B,
1408 MLX4_CMD_NATIVE);
1409 }
1410
51af33cf
IS
1411 /* Slaves are not allowed to SET_PORT beacon (LED) blink */
1412 if (op_mod == MLX4_SET_PORT_BEACON_OPCODE) {
1413 mlx4_warn(dev, "denying SET_PORT Beacon slave:%d\n", slave);
1414 return -EPERM;
1415 }
1416
ffe455ad
EE
1417 /* For IB, we only consider:
1418 * - The capability mask, which is set to the aggregate of all
1419 * slave function capabilities
1420 * - The QKey violatin counter - reset according to each request.
1421 */
1422
1423 if (dev->flags & MLX4_FLAG_OLD_PORT_CMDS) {
1424 reset_qkey_viols = (*(u8 *) inbox->buf) & 0x40;
1425 new_cap_mask = ((__be32 *) inbox->buf)[2];
1426 } else {
1427 reset_qkey_viols = ((u8 *) inbox->buf)[3] & 0x1;
1428 new_cap_mask = ((__be32 *) inbox->buf)[1];
1429 }
1430
efcd235d
JM
1431 /* slave may not set the IS_SM capability for the port */
1432 if (slave != mlx4_master_func_num(dev) &&
1433 (be32_to_cpu(new_cap_mask) & MLX4_PORT_CAP_IS_SM))
1434 return -EINVAL;
1435
1436 /* No DEV_MGMT in multifunc mode */
1437 if (mlx4_is_mfunc(dev) &&
1438 (be32_to_cpu(new_cap_mask) & MLX4_PORT_CAP_DEV_MGMT_SUP))
1439 return -EINVAL;
1440
ffe455ad
EE
1441 agg_cap_mask = 0;
1442 slave_cap_mask =
1443 priv->mfunc.master.slave_state[slave].ib_cap_mask[port];
1444 priv->mfunc.master.slave_state[slave].ib_cap_mask[port] = new_cap_mask;
1445 for (i = 0; i < dev->num_slaves; i++)
1446 agg_cap_mask |=
1447 priv->mfunc.master.slave_state[i].ib_cap_mask[port];
1448
1449 /* only clear mailbox for guests. Master may be setting
1450 * MTU or PKEY table size
1451 */
1452 if (slave != dev->caps.function)
1453 memset(inbox->buf, 0, 256);
1454 if (dev->flags & MLX4_FLAG_OLD_PORT_CMDS) {
edc4a67e 1455 *(u8 *) inbox->buf |= !!reset_qkey_viols << 6;
ffe455ad
EE
1456 ((__be32 *) inbox->buf)[2] = agg_cap_mask;
1457 } else {
edc4a67e 1458 ((u8 *) inbox->buf)[3] |= !!reset_qkey_viols;
ffe455ad
EE
1459 ((__be32 *) inbox->buf)[1] = agg_cap_mask;
1460 }
1461
1462 err = mlx4_cmd(dev, inbox->dma, port, is_eth, MLX4_CMD_SET_PORT,
1463 MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE);
1464 if (err)
1465 priv->mfunc.master.slave_state[slave].ib_cap_mask[port] =
1466 slave_cap_mask;
1467 return err;
1468}
1469
1470int mlx4_SET_PORT_wrapper(struct mlx4_dev *dev, int slave,
1471 struct mlx4_vhcr *vhcr,
1472 struct mlx4_cmd_mailbox *inbox,
1473 struct mlx4_cmd_mailbox *outbox,
1474 struct mlx4_cmd_info *cmd)
1475{
449fc488
MB
1476 int port = mlx4_slave_convert_port(
1477 dev, slave, vhcr->in_modifier & 0xFF);
1478
1479 if (port < 0)
1480 return -EINVAL;
1481
1482 vhcr->in_modifier = (vhcr->in_modifier & ~0xFF) |
1483 (port & 0xFF);
1484
ffe455ad
EE
1485 return mlx4_common_set_port(dev, slave, vhcr->in_modifier,
1486 vhcr->op_modifier, inbox);
1487}
1488
096335b3
OG
1489/* bit locations for set port command with zero op modifier */
1490enum {
1491 MLX4_SET_PORT_VL_CAP = 4, /* bits 7:4 */
1492 MLX4_SET_PORT_MTU_CAP = 12, /* bits 15:12 */
6634961c 1493 MLX4_CHANGE_PORT_PKEY_TBL_SZ = 20,
096335b3
OG
1494 MLX4_CHANGE_PORT_VL_CAP = 21,
1495 MLX4_CHANGE_PORT_MTU_CAP = 22,
1496};
1497
6634961c 1498int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port, int pkey_tbl_sz)
7ff93f8b
YP
1499{
1500 struct mlx4_cmd_mailbox *mailbox;
6634961c 1501 int err, vl_cap, pkey_tbl_flag = 0;
7ff93f8b 1502
352b09ed
RD
1503 if (dev->caps.port_type[port] == MLX4_PORT_TYPE_ETH)
1504 return 0;
1505
7ff93f8b
YP
1506 mailbox = mlx4_alloc_cmd_mailbox(dev);
1507 if (IS_ERR(mailbox))
1508 return PTR_ERR(mailbox);
1509
793730bf 1510 ((__be32 *) mailbox->buf)[1] = dev->caps.ib_port_def_cap[port];
096335b3 1511
6634961c
JM
1512 if (pkey_tbl_sz >= 0 && mlx4_is_master(dev)) {
1513 pkey_tbl_flag = 1;
1514 ((__be16 *) mailbox->buf)[20] = cpu_to_be16(pkey_tbl_sz);
1515 }
1516
096335b3
OG
1517 /* IB VL CAP enum isn't used by the firmware, just numerical values */
1518 for (vl_cap = 8; vl_cap >= 1; vl_cap >>= 1) {
1519 ((__be32 *) mailbox->buf)[0] = cpu_to_be32(
1520 (1 << MLX4_CHANGE_PORT_MTU_CAP) |
1521 (1 << MLX4_CHANGE_PORT_VL_CAP) |
6634961c 1522 (pkey_tbl_flag << MLX4_CHANGE_PORT_PKEY_TBL_SZ) |
096335b3
OG
1523 (dev->caps.port_ib_mtu[port] << MLX4_SET_PORT_MTU_CAP) |
1524 (vl_cap << MLX4_SET_PORT_VL_CAP));
a130b590
IS
1525 err = mlx4_cmd(dev, mailbox->dma, port,
1526 MLX4_SET_PORT_IB_OPCODE, MLX4_CMD_SET_PORT,
1527 MLX4_CMD_TIME_CLASS_B, MLX4_CMD_WRAPPED);
096335b3
OG
1528 if (err != -ENOMEM)
1529 break;
1530 }
7ff93f8b
YP
1531
1532 mlx4_free_cmd_mailbox(dev, mailbox);
1533 return err;
1534}
ffe455ad 1535
1da494cb
MS
1536#define SET_PORT_ROCE_2_FLAGS 0x10
1537#define MLX4_SET_PORT_ROCE_V1_V2 0x2
cb9ffb76 1538int mlx4_SET_PORT_general(struct mlx4_dev *dev, u8 port, int mtu,
ffe455ad
EE
1539 u8 pptx, u8 pfctx, u8 pprx, u8 pfcrx)
1540{
1541 struct mlx4_cmd_mailbox *mailbox;
1542 struct mlx4_set_port_general_context *context;
1543 int err;
1544 u32 in_mod;
1545
1546 mailbox = mlx4_alloc_cmd_mailbox(dev);
1547 if (IS_ERR(mailbox))
1548 return PTR_ERR(mailbox);
1549 context = mailbox->buf;
ffe455ad
EE
1550 context->flags = SET_PORT_GEN_ALL_VALID;
1551 context->mtu = cpu_to_be16(mtu);
1552 context->pptx = (pptx * (!pfctx)) << 7;
1553 context->pfctx = pfctx;
1554 context->pprx = (pprx * (!pfcrx)) << 7;
1555 context->pfcrx = pfcrx;
1556
1da494cb
MS
1557 if (dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_ROCE_V1_V2) {
1558 context->flags |= SET_PORT_ROCE_2_FLAGS;
1559 context->roce_mode |=
1560 MLX4_SET_PORT_ROCE_V1_V2 << 4;
1561 }
ffe455ad 1562 in_mod = MLX4_SET_PORT_GENERAL << 8 | port;
a130b590
IS
1563 err = mlx4_cmd(dev, mailbox->dma, in_mod, MLX4_SET_PORT_ETH_OPCODE,
1564 MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B,
1565 MLX4_CMD_WRAPPED);
ffe455ad
EE
1566
1567 mlx4_free_cmd_mailbox(dev, mailbox);
1568 return err;
1569}
1570EXPORT_SYMBOL(mlx4_SET_PORT_general);
1571
cb9ffb76 1572int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn,
ffe455ad
EE
1573 u8 promisc)
1574{
1575 struct mlx4_cmd_mailbox *mailbox;
1576 struct mlx4_set_port_rqp_calc_context *context;
1577 int err;
1578 u32 in_mod;
1579 u32 m_promisc = (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER) ?
1580 MCAST_DIRECT : MCAST_DEFAULT;
1581
c96d97f4 1582 if (dev->caps.steering_mode != MLX4_STEERING_MODE_A0)
ffe455ad
EE
1583 return 0;
1584
1585 mailbox = mlx4_alloc_cmd_mailbox(dev);
1586 if (IS_ERR(mailbox))
1587 return PTR_ERR(mailbox);
1588 context = mailbox->buf;
ffe455ad
EE
1589 context->base_qpn = cpu_to_be32(base_qpn);
1590 context->n_mac = dev->caps.log_num_macs;
1591 context->promisc = cpu_to_be32(promisc << SET_PORT_PROMISC_SHIFT |
1592 base_qpn);
1593 context->mcast = cpu_to_be32(m_promisc << SET_PORT_MC_PROMISC_SHIFT |
1594 base_qpn);
1595 context->intra_no_vlan = 0;
1596 context->no_vlan = MLX4_NO_VLAN_IDX;
1597 context->intra_vlan_miss = 0;
1598 context->vlan_miss = MLX4_VLAN_MISS_IDX;
1599
1600 in_mod = MLX4_SET_PORT_RQP_CALC << 8 | port;
a130b590
IS
1601 err = mlx4_cmd(dev, mailbox->dma, in_mod, MLX4_SET_PORT_ETH_OPCODE,
1602 MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B,
1603 MLX4_CMD_WRAPPED);
ffe455ad
EE
1604
1605 mlx4_free_cmd_mailbox(dev, mailbox);
1606 return err;
1607}
1608EXPORT_SYMBOL(mlx4_SET_PORT_qpn_calc);
1609
78500b8c
MM
1610int mlx4_SET_PORT_fcs_check(struct mlx4_dev *dev, u8 port, u8 ignore_fcs_value)
1611{
1612 struct mlx4_cmd_mailbox *mailbox;
1613 struct mlx4_set_port_general_context *context;
1614 u32 in_mod;
1615 int err;
1616
1617 mailbox = mlx4_alloc_cmd_mailbox(dev);
1618 if (IS_ERR(mailbox))
1619 return PTR_ERR(mailbox);
1620 context = mailbox->buf;
1621 context->v_ignore_fcs |= MLX4_FLAG_V_IGNORE_FCS_MASK;
1622 if (ignore_fcs_value)
1623 context->ignore_fcs |= MLX4_IGNORE_FCS_MASK;
1624 else
1625 context->ignore_fcs &= ~MLX4_IGNORE_FCS_MASK;
1626
1627 in_mod = MLX4_SET_PORT_GENERAL << 8 | port;
1628 err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT,
1629 MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE);
1630
1631 mlx4_free_cmd_mailbox(dev, mailbox);
1632 return err;
1633}
1634EXPORT_SYMBOL(mlx4_SET_PORT_fcs_check);
1635
7ffdf726
OG
1636enum {
1637 VXLAN_ENABLE_MODIFY = 1 << 7,
1638 VXLAN_STEERING_MODIFY = 1 << 6,
1639
1640 VXLAN_ENABLE = 1 << 7,
1641};
1642
1643struct mlx4_set_port_vxlan_context {
1644 u32 reserved1;
1645 u8 modify_flags;
1646 u8 reserved2;
1647 u8 enable_flags;
1648 u8 steering;
1649};
1650
1b136de1 1651int mlx4_SET_PORT_VXLAN(struct mlx4_dev *dev, u8 port, u8 steering, int enable)
7ffdf726
OG
1652{
1653 int err;
1654 u32 in_mod;
1655 struct mlx4_cmd_mailbox *mailbox;
1656 struct mlx4_set_port_vxlan_context *context;
1657
1658 mailbox = mlx4_alloc_cmd_mailbox(dev);
1659 if (IS_ERR(mailbox))
1660 return PTR_ERR(mailbox);
1661 context = mailbox->buf;
1662 memset(context, 0, sizeof(*context));
1663
1664 context->modify_flags = VXLAN_ENABLE_MODIFY | VXLAN_STEERING_MODIFY;
1b136de1
OG
1665 if (enable)
1666 context->enable_flags = VXLAN_ENABLE;
7ffdf726
OG
1667 context->steering = steering;
1668
1669 in_mod = MLX4_SET_PORT_VXLAN << 8 | port;
a130b590
IS
1670 err = mlx4_cmd(dev, mailbox->dma, in_mod, MLX4_SET_PORT_ETH_OPCODE,
1671 MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B,
1672 MLX4_CMD_NATIVE);
7ffdf726
OG
1673
1674 mlx4_free_cmd_mailbox(dev, mailbox);
1675 return err;
1676}
1677EXPORT_SYMBOL(mlx4_SET_PORT_VXLAN);
1678
51af33cf
IS
1679int mlx4_SET_PORT_BEACON(struct mlx4_dev *dev, u8 port, u16 time)
1680{
1681 int err;
1682 struct mlx4_cmd_mailbox *mailbox;
1683
1684 mailbox = mlx4_alloc_cmd_mailbox(dev);
1685 if (IS_ERR(mailbox))
1686 return PTR_ERR(mailbox);
1687
1688 *((__be32 *)mailbox->buf) = cpu_to_be32(time);
1689
1690 err = mlx4_cmd(dev, mailbox->dma, port, MLX4_SET_PORT_BEACON_OPCODE,
1691 MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B,
1692 MLX4_CMD_NATIVE);
1693
1694 mlx4_free_cmd_mailbox(dev, mailbox);
1695 return err;
1696}
1697EXPORT_SYMBOL(mlx4_SET_PORT_BEACON);
1698
ffe455ad
EE
1699int mlx4_SET_MCAST_FLTR_wrapper(struct mlx4_dev *dev, int slave,
1700 struct mlx4_vhcr *vhcr,
1701 struct mlx4_cmd_mailbox *inbox,
1702 struct mlx4_cmd_mailbox *outbox,
1703 struct mlx4_cmd_info *cmd)
1704{
1705 int err = 0;
1706
1707 return err;
1708}
1709
1710int mlx4_SET_MCAST_FLTR(struct mlx4_dev *dev, u8 port,
1711 u64 mac, u64 clear, u8 mode)
1712{
1713 return mlx4_cmd(dev, (mac | (clear << 63)), port, mode,
1714 MLX4_CMD_SET_MCAST_FLTR, MLX4_CMD_TIME_CLASS_B,
1715 MLX4_CMD_WRAPPED);
1716}
1717EXPORT_SYMBOL(mlx4_SET_MCAST_FLTR);
1718
1719int mlx4_SET_VLAN_FLTR_wrapper(struct mlx4_dev *dev, int slave,
1720 struct mlx4_vhcr *vhcr,
1721 struct mlx4_cmd_mailbox *inbox,
1722 struct mlx4_cmd_mailbox *outbox,
1723 struct mlx4_cmd_info *cmd)
1724{
1725 int err = 0;
1726
1727 return err;
1728}
1729
1730int mlx4_common_dump_eth_stats(struct mlx4_dev *dev, int slave,
1731 u32 in_mod, struct mlx4_cmd_mailbox *outbox)
1732{
1733 return mlx4_cmd_box(dev, 0, outbox->dma, in_mod, 0,
1734 MLX4_CMD_DUMP_ETH_STATS, MLX4_CMD_TIME_CLASS_B,
1735 MLX4_CMD_NATIVE);
1736}
1737
1738int mlx4_DUMP_ETH_STATS_wrapper(struct mlx4_dev *dev, int slave,
1739 struct mlx4_vhcr *vhcr,
1740 struct mlx4_cmd_mailbox *inbox,
1741 struct mlx4_cmd_mailbox *outbox,
1742 struct mlx4_cmd_info *cmd)
1743{
35fb9afb
EE
1744 if (slave != dev->caps.function)
1745 return 0;
ffe455ad
EE
1746 return mlx4_common_dump_eth_stats(dev, slave,
1747 vhcr->in_modifier, outbox);
1748}
93ece0c1 1749
9cd59352
JM
1750int mlx4_get_slave_from_roce_gid(struct mlx4_dev *dev, int port, u8 *gid,
1751 int *slave_id)
6ee51a4e
JM
1752{
1753 struct mlx4_priv *priv = mlx4_priv(dev);
1754 int i, found_ix = -1;
b6ffaeff 1755 int vf_gids = MLX4_ROCE_MAX_GIDS - MLX4_ROCE_PF_GIDS;
449fc488
MB
1756 struct mlx4_slaves_pport slaves_pport;
1757 unsigned num_vfs;
1758 int slave_gid;
6ee51a4e
JM
1759
1760 if (!mlx4_is_mfunc(dev))
1761 return -EINVAL;
1762
449fc488 1763 slaves_pport = mlx4_phys_to_slaves_pport(dev, port);
872bf2fb
YH
1764 num_vfs = bitmap_weight(slaves_pport.slaves,
1765 dev->persist->num_vfs + 1) - 1;
449fc488 1766
6ee51a4e 1767 for (i = 0; i < MLX4_ROCE_MAX_GIDS; i++) {
111c6094
JM
1768 if (!memcmp(priv->port[port].gid_table.roce_gids[i].raw, gid,
1769 MLX4_ROCE_GID_ENTRY_SIZE)) {
6ee51a4e
JM
1770 found_ix = i;
1771 break;
1772 }
1773 }
1774
b6ffaeff 1775 if (found_ix >= 0) {
0254bc82
MB
1776 /* Calculate a slave_gid which is the slave number in the gid
1777 * table and not a globally unique slave number.
1778 */
b6ffaeff 1779 if (found_ix < MLX4_ROCE_PF_GIDS)
449fc488
MB
1780 slave_gid = 0;
1781 else if (found_ix < MLX4_ROCE_PF_GIDS + (vf_gids % num_vfs) *
1782 (vf_gids / num_vfs + 1))
1783 slave_gid = ((found_ix - MLX4_ROCE_PF_GIDS) /
1784 (vf_gids / num_vfs + 1)) + 1;
b6ffaeff 1785 else
449fc488 1786 slave_gid =
b6ffaeff 1787 ((found_ix - MLX4_ROCE_PF_GIDS -
449fc488
MB
1788 ((vf_gids % num_vfs) * ((vf_gids / num_vfs + 1)))) /
1789 (vf_gids / num_vfs)) + vf_gids % num_vfs + 1;
1790
0254bc82 1791 /* Calculate the globally unique slave id */
449fc488
MB
1792 if (slave_gid) {
1793 struct mlx4_active_ports exclusive_ports;
1794 struct mlx4_active_ports actv_ports;
1795 struct mlx4_slaves_pport slaves_pport_actv;
1796 unsigned max_port_p_one;
0254bc82
MB
1797 int num_vfs_before = 0;
1798 int candidate_slave_gid;
449fc488 1799
0254bc82 1800 /* Calculate how many VFs are on the previous port, if exists */
449fc488
MB
1801 for (i = 1; i < port; i++) {
1802 bitmap_zero(exclusive_ports.ports, dev->caps.num_ports);
0254bc82 1803 set_bit(i - 1, exclusive_ports.ports);
449fc488
MB
1804 slaves_pport_actv =
1805 mlx4_phys_to_slaves_pport_actv(
1806 dev, &exclusive_ports);
0254bc82 1807 num_vfs_before += bitmap_weight(
449fc488 1808 slaves_pport_actv.slaves,
872bf2fb 1809 dev->persist->num_vfs + 1);
449fc488
MB
1810 }
1811
0254bc82
MB
1812 /* candidate_slave_gid isn't necessarily the correct slave, but
1813 * it has the same number of ports and is assigned to the same
1814 * ports as the real slave we're looking for. On dual port VF,
1815 * slave_gid = [single port VFs on port <port>] +
1816 * [offset of the current slave from the first dual port VF] +
1817 * 1 (for the PF).
1818 */
1819 candidate_slave_gid = slave_gid + num_vfs_before;
1820
1821 actv_ports = mlx4_get_active_ports(dev, candidate_slave_gid);
449fc488
MB
1822 max_port_p_one = find_first_bit(
1823 actv_ports.ports, dev->caps.num_ports) +
1824 bitmap_weight(actv_ports.ports,
1825 dev->caps.num_ports) + 1;
1826
0254bc82 1827 /* Calculate the real slave number */
449fc488
MB
1828 for (i = 1; i < max_port_p_one; i++) {
1829 if (i == port)
1830 continue;
1831 bitmap_zero(exclusive_ports.ports,
1832 dev->caps.num_ports);
1833 set_bit(i - 1, exclusive_ports.ports);
1834 slaves_pport_actv =
1835 mlx4_phys_to_slaves_pport_actv(
1836 dev, &exclusive_ports);
1837 slave_gid += bitmap_weight(
1838 slaves_pport_actv.slaves,
872bf2fb 1839 dev->persist->num_vfs + 1);
449fc488
MB
1840 }
1841 }
1842 *slave_id = slave_gid;
b6ffaeff 1843 }
6ee51a4e
JM
1844
1845 return (found_ix >= 0) ? 0 : -EINVAL;
1846}
1847EXPORT_SYMBOL(mlx4_get_slave_from_roce_gid);
1848
9cd59352
JM
1849int mlx4_get_roce_gid_from_slave(struct mlx4_dev *dev, int port, int slave_id,
1850 u8 *gid)
6ee51a4e
JM
1851{
1852 struct mlx4_priv *priv = mlx4_priv(dev);
1853
1854 if (!mlx4_is_master(dev))
1855 return -EINVAL;
1856
111c6094
JM
1857 memcpy(gid, priv->port[port].gid_table.roce_gids[slave_id].raw,
1858 MLX4_ROCE_GID_ENTRY_SIZE);
6ee51a4e
JM
1859 return 0;
1860}
1861EXPORT_SYMBOL(mlx4_get_roce_gid_from_slave);
32a173c7
SM
1862
1863/* Cable Module Info */
1864#define MODULE_INFO_MAX_READ 48
1865
1866#define I2C_ADDR_LOW 0x50
1867#define I2C_ADDR_HIGH 0x51
1868#define I2C_PAGE_SIZE 256
1869
1870/* Module Info Data */
1871struct mlx4_cable_info {
1872 u8 i2c_addr;
1873 u8 page_num;
1874 __be16 dev_mem_address;
1875 __be16 reserved1;
1876 __be16 size;
1877 __be32 reserved2[2];
1878 u8 data[MODULE_INFO_MAX_READ];
1879};
1880
1881enum cable_info_err {
1882 CABLE_INF_INV_PORT = 0x1,
1883 CABLE_INF_OP_NOSUP = 0x2,
1884 CABLE_INF_NOT_CONN = 0x3,
1885 CABLE_INF_NO_EEPRM = 0x4,
1886 CABLE_INF_PAGE_ERR = 0x5,
1887 CABLE_INF_INV_ADDR = 0x6,
1888 CABLE_INF_I2C_ADDR = 0x7,
1889 CABLE_INF_QSFP_VIO = 0x8,
1890 CABLE_INF_I2C_BUSY = 0x9,
1891};
1892
1893#define MAD_STATUS_2_CABLE_ERR(mad_status) ((mad_status >> 8) & 0xFF)
1894
1895static inline const char *cable_info_mad_err_str(u16 mad_status)
1896{
1897 u8 err = MAD_STATUS_2_CABLE_ERR(mad_status);
1898
1899 switch (err) {
1900 case CABLE_INF_INV_PORT:
1901 return "invalid port selected";
1902 case CABLE_INF_OP_NOSUP:
1903 return "operation not supported for this port (the port is of type CX4 or internal)";
1904 case CABLE_INF_NOT_CONN:
1905 return "cable is not connected";
1906 case CABLE_INF_NO_EEPRM:
1907 return "the connected cable has no EPROM (passive copper cable)";
1908 case CABLE_INF_PAGE_ERR:
1909 return "page number is greater than 15";
1910 case CABLE_INF_INV_ADDR:
1911 return "invalid device_address or size (that is, size equals 0 or address+size is greater than 256)";
1912 case CABLE_INF_I2C_ADDR:
1913 return "invalid I2C slave address";
1914 case CABLE_INF_QSFP_VIO:
1915 return "at least one cable violates the QSFP specification and ignores the modsel signal";
1916 case CABLE_INF_I2C_BUSY:
1917 return "I2C bus is constantly busy";
1918 }
1919 return "Unknown Error";
1920}
1921
1922/**
1923 * mlx4_get_module_info - Read cable module eeprom data
1924 * @dev: mlx4_dev.
1925 * @port: port number.
1926 * @offset: byte offset in eeprom to start reading data from.
1927 * @size: num of bytes to read.
1928 * @data: output buffer to put the requested data into.
1929 *
1930 * Reads cable module eeprom data, puts the outcome data into
1931 * data pointer paramer.
1932 * Returns num of read bytes on success or a negative error
1933 * code.
1934 */
1935int mlx4_get_module_info(struct mlx4_dev *dev, u8 port,
1936 u16 offset, u16 size, u8 *data)
1937{
1938 struct mlx4_cmd_mailbox *inbox, *outbox;
1939 struct mlx4_mad_ifc *inmad, *outmad;
1940 struct mlx4_cable_info *cable_info;
1941 u16 i2c_addr;
1942 int ret;
1943
1944 if (size > MODULE_INFO_MAX_READ)
1945 size = MODULE_INFO_MAX_READ;
1946
1947 inbox = mlx4_alloc_cmd_mailbox(dev);
1948 if (IS_ERR(inbox))
1949 return PTR_ERR(inbox);
1950
1951 outbox = mlx4_alloc_cmd_mailbox(dev);
1952 if (IS_ERR(outbox)) {
1953 mlx4_free_cmd_mailbox(dev, inbox);
1954 return PTR_ERR(outbox);
1955 }
1956
1957 inmad = (struct mlx4_mad_ifc *)(inbox->buf);
1958 outmad = (struct mlx4_mad_ifc *)(outbox->buf);
1959
1960 inmad->method = 0x1; /* Get */
1961 inmad->class_version = 0x1;
1962 inmad->mgmt_class = 0x1;
1963 inmad->base_version = 0x1;
1964 inmad->attr_id = cpu_to_be16(0xFF60); /* Module Info */
1965
1966 if (offset < I2C_PAGE_SIZE && offset + size > I2C_PAGE_SIZE)
1967 /* Cross pages reads are not allowed
1968 * read until offset 256 in low page
1969 */
1970 size -= offset + size - I2C_PAGE_SIZE;
1971
1972 i2c_addr = I2C_ADDR_LOW;
1973 if (offset >= I2C_PAGE_SIZE) {
1974 /* Reset offset to high page */
1975 i2c_addr = I2C_ADDR_HIGH;
1976 offset -= I2C_PAGE_SIZE;
1977 }
1978
1979 cable_info = (struct mlx4_cable_info *)inmad->data;
1980 cable_info->dev_mem_address = cpu_to_be16(offset);
1981 cable_info->page_num = 0;
1982 cable_info->i2c_addr = i2c_addr;
1983 cable_info->size = cpu_to_be16(size);
1984
1985 ret = mlx4_cmd_box(dev, inbox->dma, outbox->dma, port, 3,
1986 MLX4_CMD_MAD_IFC, MLX4_CMD_TIME_CLASS_C,
1987 MLX4_CMD_NATIVE);
1988 if (ret)
1989 goto out;
1990
1991 if (be16_to_cpu(outmad->status)) {
1992 /* Mad returned with bad status */
1993 ret = be16_to_cpu(outmad->status);
1994 mlx4_warn(dev,
1995 "MLX4_CMD_MAD_IFC Get Module info attr(%x) port(%d) i2c_addr(%x) offset(%d) size(%d): Response Mad Status(%x) - %s\n",
1996 0xFF60, port, i2c_addr, offset, size,
1997 ret, cable_info_mad_err_str(ret));
1998
1999 if (i2c_addr == I2C_ADDR_HIGH &&
2000 MAD_STATUS_2_CABLE_ERR(ret) == CABLE_INF_I2C_ADDR)
2001 /* Some SFP cables do not support i2c slave
2002 * address 0x51 (high page), abort silently.
2003 */
2004 ret = 0;
2005 else
2006 ret = -ret;
2007 goto out;
2008 }
2009 cable_info = (struct mlx4_cable_info *)outmad->data;
2010 memcpy(data, cable_info->data, size);
2011 ret = size;
2012out:
2013 mlx4_free_cmd_mailbox(dev, inbox);
2014 mlx4_free_cmd_mailbox(dev, outbox);
2015 return ret;
2016}
2017EXPORT_SYMBOL(mlx4_get_module_info);