mlx4: remove redundant adding of steering type to gid
[cascardo/linux.git] / drivers / net / ethernet / mellanox / mlx4 / port.c
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>
35 #include <linux/export.h>
36
37 #include <linux/mlx4/cmd.h>
38
39 #include "mlx4.h"
40
41 #define MLX4_MAC_VALID          (1ull << 63)
42 #define MLX4_MAC_MASK           0xffffffffffffULL
43
44 #define MLX4_VLAN_VALID         (1u << 31)
45 #define MLX4_VLAN_MASK          0xfff
46
47 #define MLX4_STATS_TRAFFIC_COUNTERS_MASK        0xfULL
48 #define MLX4_STATS_TRAFFIC_DROPS_MASK           0xc0ULL
49 #define MLX4_STATS_ERROR_COUNTERS_MASK          0x1ffc30ULL
50 #define MLX4_STATS_PORT_COUNTERS_MASK           0x1fe00000ULL
51
52 void mlx4_init_mac_table(struct mlx4_dev *dev, struct mlx4_mac_table *table)
53 {
54         int i;
55
56         mutex_init(&table->mutex);
57         for (i = 0; i < MLX4_MAX_MAC_NUM; i++) {
58                 table->entries[i] = 0;
59                 table->refs[i]   = 0;
60         }
61         table->max   = 1 << dev->caps.log_num_macs;
62         table->total = 0;
63 }
64
65 void mlx4_init_vlan_table(struct mlx4_dev *dev, struct mlx4_vlan_table *table)
66 {
67         int i;
68
69         mutex_init(&table->mutex);
70         for (i = 0; i < MLX4_MAX_VLAN_NUM; i++) {
71                 table->entries[i] = 0;
72                 table->refs[i]   = 0;
73         }
74         table->max   = (1 << dev->caps.log_num_vlans) - MLX4_VLAN_REGULAR;
75         table->total = 0;
76 }
77
78 static int mlx4_uc_steer_add(struct mlx4_dev *dev, u8 port, u64 mac, int *qpn)
79 {
80         struct mlx4_qp qp;
81         u8 gid[16] = {0};
82         int err;
83
84         qp.qpn = *qpn;
85
86         mac &= 0xffffffffffffULL;
87         mac = cpu_to_be64(mac << 16);
88         memcpy(&gid[10], &mac, ETH_ALEN);
89         gid[5] = port;
90
91         err = mlx4_unicast_attach(dev, &qp, gid, 0, MLX4_PROT_ETH);
92         if (err)
93                 mlx4_warn(dev, "Failed Attaching Unicast\n");
94
95         return err;
96 }
97
98 static void mlx4_uc_steer_release(struct mlx4_dev *dev, u8 port,
99                                   u64 mac, int qpn)
100 {
101         struct mlx4_qp qp;
102         u8 gid[16] = {0};
103
104         qp.qpn = qpn;
105         mac &= 0xffffffffffffULL;
106         mac = cpu_to_be64(mac << 16);
107         memcpy(&gid[10], &mac, ETH_ALEN);
108         gid[5] = port;
109
110         mlx4_unicast_detach(dev, &qp, gid, MLX4_PROT_ETH);
111 }
112
113 static int validate_index(struct mlx4_dev *dev,
114                           struct mlx4_mac_table *table, int index)
115 {
116         int err = 0;
117
118         if (index < 0 || index >= table->max || !table->entries[index]) {
119                 mlx4_warn(dev, "No valid Mac entry for the given index\n");
120                 err = -EINVAL;
121         }
122         return err;
123 }
124
125 static int find_index(struct mlx4_dev *dev,
126                       struct mlx4_mac_table *table, u64 mac)
127 {
128         int i;
129
130         for (i = 0; i < MLX4_MAX_MAC_NUM; i++) {
131                 if ((mac & MLX4_MAC_MASK) ==
132                     (MLX4_MAC_MASK & be64_to_cpu(table->entries[i])))
133                         return i;
134         }
135         /* Mac not found */
136         return -EINVAL;
137 }
138
139 int mlx4_get_eth_qp(struct mlx4_dev *dev, u8 port, u64 mac, int *qpn)
140 {
141         struct mlx4_port_info *info = &mlx4_priv(dev)->port[port];
142         struct mlx4_mac_entry *entry;
143         int index = 0;
144         int err = 0;
145
146         mlx4_dbg(dev, "Registering MAC: 0x%llx for adding\n",
147                         (unsigned long long) mac);
148         index = mlx4_register_mac(dev, port, mac);
149         if (index < 0) {
150                 err = index;
151                 mlx4_err(dev, "Failed adding MAC: 0x%llx\n",
152                          (unsigned long long) mac);
153                 return err;
154         }
155
156         if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER)) {
157                 *qpn = info->base_qpn + index;
158                 return 0;
159         }
160
161         err = mlx4_qp_reserve_range(dev, 1, 1, qpn);
162         mlx4_dbg(dev, "Reserved qp %d\n", *qpn);
163         if (err) {
164                 mlx4_err(dev, "Failed to reserve qp for mac registration\n");
165                 goto qp_err;
166         }
167
168         err = mlx4_uc_steer_add(dev, port, mac, qpn);
169         if (err)
170                 goto steer_err;
171
172         entry = kmalloc(sizeof *entry, GFP_KERNEL);
173         if (!entry) {
174                 err = -ENOMEM;
175                 goto alloc_err;
176         }
177         entry->mac = mac;
178         err = radix_tree_insert(&info->mac_tree, *qpn, entry);
179         if (err)
180                 goto insert_err;
181         return 0;
182
183 insert_err:
184         kfree(entry);
185
186 alloc_err:
187         mlx4_uc_steer_release(dev, port, mac, *qpn);
188
189 steer_err:
190         mlx4_qp_release_range(dev, *qpn, 1);
191
192 qp_err:
193         mlx4_unregister_mac(dev, port, mac);
194         return err;
195 }
196 EXPORT_SYMBOL_GPL(mlx4_get_eth_qp);
197
198 void mlx4_put_eth_qp(struct mlx4_dev *dev, u8 port, u64 mac, int qpn)
199 {
200         struct mlx4_port_info *info = &mlx4_priv(dev)->port[port];
201         struct mlx4_mac_entry *entry;
202
203         mlx4_dbg(dev, "Registering MAC: 0x%llx for deleting\n",
204                  (unsigned long long) mac);
205         mlx4_unregister_mac(dev, port, mac);
206
207         if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER) {
208                 entry = radix_tree_lookup(&info->mac_tree, qpn);
209                 if (entry) {
210                         mlx4_dbg(dev, "Releasing qp: port %d, mac 0x%llx,"
211                                  " qpn %d\n", port,
212                                  (unsigned long long) mac, qpn);
213                         mlx4_uc_steer_release(dev, port, entry->mac, qpn);
214                         mlx4_qp_release_range(dev, qpn, 1);
215                         radix_tree_delete(&info->mac_tree, qpn);
216                         kfree(entry);
217                 }
218         }
219 }
220 EXPORT_SYMBOL_GPL(mlx4_put_eth_qp);
221
222 static int mlx4_set_port_mac_table(struct mlx4_dev *dev, u8 port,
223                                    __be64 *entries)
224 {
225         struct mlx4_cmd_mailbox *mailbox;
226         u32 in_mod;
227         int err;
228
229         mailbox = mlx4_alloc_cmd_mailbox(dev);
230         if (IS_ERR(mailbox))
231                 return PTR_ERR(mailbox);
232
233         memcpy(mailbox->buf, entries, MLX4_MAC_TABLE_SIZE);
234
235         in_mod = MLX4_SET_PORT_MAC_TABLE << 8 | port;
236
237         err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT,
238                        MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE);
239
240         mlx4_free_cmd_mailbox(dev, mailbox);
241         return err;
242 }
243
244 int __mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac)
245 {
246         struct mlx4_port_info *info = &mlx4_priv(dev)->port[port];
247         struct mlx4_mac_table *table = &info->mac_table;
248         int i, err = 0;
249         int free = -1;
250
251         mlx4_dbg(dev, "Registering MAC: 0x%llx for port %d\n",
252                  (unsigned long long) mac, port);
253
254         mutex_lock(&table->mutex);
255         for (i = 0; i < MLX4_MAX_MAC_NUM; i++) {
256                 if (free < 0 && !table->entries[i]) {
257                         free = i;
258                         continue;
259                 }
260
261                 if (mac == (MLX4_MAC_MASK & be64_to_cpu(table->entries[i]))) {
262                         /* MAC already registered, Must not have duplicates */
263                         err = -EEXIST;
264                         goto out;
265                 }
266         }
267
268         mlx4_dbg(dev, "Free MAC index is %d\n", free);
269
270         if (table->total == table->max) {
271                 /* No free mac entries */
272                 err = -ENOSPC;
273                 goto out;
274         }
275
276         /* Register new MAC */
277         table->entries[free] = cpu_to_be64(mac | MLX4_MAC_VALID);
278
279         err = mlx4_set_port_mac_table(dev, port, table->entries);
280         if (unlikely(err)) {
281                 mlx4_err(dev, "Failed adding MAC: 0x%llx\n",
282                          (unsigned long long) mac);
283                 table->entries[free] = 0;
284                 goto out;
285         }
286
287         err = free;
288         ++table->total;
289 out:
290         mutex_unlock(&table->mutex);
291         return err;
292 }
293 EXPORT_SYMBOL_GPL(__mlx4_register_mac);
294
295 int mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac)
296 {
297         u64 out_param;
298         int err;
299
300         if (mlx4_is_mfunc(dev)) {
301                 set_param_l(&out_param, port);
302                 err = mlx4_cmd_imm(dev, mac, &out_param, RES_MAC,
303                                    RES_OP_RESERVE_AND_MAP, MLX4_CMD_ALLOC_RES,
304                                    MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
305                 if (err)
306                         return err;
307
308                 return get_param_l(&out_param);
309         }
310         return __mlx4_register_mac(dev, port, mac);
311 }
312 EXPORT_SYMBOL_GPL(mlx4_register_mac);
313
314
315 void __mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, u64 mac)
316 {
317         struct mlx4_port_info *info = &mlx4_priv(dev)->port[port];
318         struct mlx4_mac_table *table = &info->mac_table;
319         int index;
320
321         index = find_index(dev, table, mac);
322
323         mutex_lock(&table->mutex);
324
325         if (validate_index(dev, table, index))
326                 goto out;
327
328         table->entries[index] = 0;
329         mlx4_set_port_mac_table(dev, port, table->entries);
330         --table->total;
331 out:
332         mutex_unlock(&table->mutex);
333 }
334 EXPORT_SYMBOL_GPL(__mlx4_unregister_mac);
335
336 void mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, u64 mac)
337 {
338         u64 out_param;
339         int err;
340
341         if (mlx4_is_mfunc(dev)) {
342                 set_param_l(&out_param, port);
343                 err = mlx4_cmd_imm(dev, mac, &out_param, RES_MAC,
344                                    RES_OP_RESERVE_AND_MAP, MLX4_CMD_FREE_RES,
345                                    MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
346                 return;
347         }
348         __mlx4_unregister_mac(dev, port, mac);
349         return;
350 }
351 EXPORT_SYMBOL_GPL(mlx4_unregister_mac);
352
353 int mlx4_replace_mac(struct mlx4_dev *dev, u8 port, int qpn, u64 new_mac)
354 {
355         struct mlx4_port_info *info = &mlx4_priv(dev)->port[port];
356         struct mlx4_mac_table *table = &info->mac_table;
357         struct mlx4_mac_entry *entry;
358         int index = qpn - info->base_qpn;
359         int err = 0;
360
361         if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER) {
362                 entry = radix_tree_lookup(&info->mac_tree, qpn);
363                 if (!entry)
364                         return -EINVAL;
365                 mlx4_uc_steer_release(dev, port, entry->mac, qpn);
366                 mlx4_unregister_mac(dev, port, entry->mac);
367                 entry->mac = new_mac;
368                 mlx4_register_mac(dev, port, new_mac);
369                 err = mlx4_uc_steer_add(dev, port, entry->mac, &qpn);
370                 return err;
371         }
372
373         /* CX1 doesn't support multi-functions */
374         mutex_lock(&table->mutex);
375
376         err = validate_index(dev, table, index);
377         if (err)
378                 goto out;
379
380         table->entries[index] = cpu_to_be64(new_mac | MLX4_MAC_VALID);
381
382         err = mlx4_set_port_mac_table(dev, port, table->entries);
383         if (unlikely(err)) {
384                 mlx4_err(dev, "Failed adding MAC: 0x%llx\n",
385                          (unsigned long long) new_mac);
386                 table->entries[index] = 0;
387         }
388 out:
389         mutex_unlock(&table->mutex);
390         return err;
391 }
392 EXPORT_SYMBOL_GPL(mlx4_replace_mac);
393
394 static int mlx4_set_port_vlan_table(struct mlx4_dev *dev, u8 port,
395                                     __be32 *entries)
396 {
397         struct mlx4_cmd_mailbox *mailbox;
398         u32 in_mod;
399         int err;
400
401         mailbox = mlx4_alloc_cmd_mailbox(dev);
402         if (IS_ERR(mailbox))
403                 return PTR_ERR(mailbox);
404
405         memcpy(mailbox->buf, entries, MLX4_VLAN_TABLE_SIZE);
406         in_mod = MLX4_SET_PORT_VLAN_TABLE << 8 | port;
407         err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT,
408                        MLX4_CMD_TIME_CLASS_B, MLX4_CMD_WRAPPED);
409
410         mlx4_free_cmd_mailbox(dev, mailbox);
411
412         return err;
413 }
414
415 int mlx4_find_cached_vlan(struct mlx4_dev *dev, u8 port, u16 vid, int *idx)
416 {
417         struct mlx4_vlan_table *table = &mlx4_priv(dev)->port[port].vlan_table;
418         int i;
419
420         for (i = 0; i < MLX4_MAX_VLAN_NUM; ++i) {
421                 if (table->refs[i] &&
422                     (vid == (MLX4_VLAN_MASK &
423                               be32_to_cpu(table->entries[i])))) {
424                         /* VLAN already registered, increase reference count */
425                         *idx = i;
426                         return 0;
427                 }
428         }
429
430         return -ENOENT;
431 }
432 EXPORT_SYMBOL_GPL(mlx4_find_cached_vlan);
433
434 static int __mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan,
435                                 int *index)
436 {
437         struct mlx4_vlan_table *table = &mlx4_priv(dev)->port[port].vlan_table;
438         int i, err = 0;
439         int free = -1;
440
441         mutex_lock(&table->mutex);
442
443         if (table->total == table->max) {
444                 /* No free vlan entries */
445                 err = -ENOSPC;
446                 goto out;
447         }
448
449         for (i = MLX4_VLAN_REGULAR; i < MLX4_MAX_VLAN_NUM; i++) {
450                 if (free < 0 && (table->refs[i] == 0)) {
451                         free = i;
452                         continue;
453                 }
454
455                 if (table->refs[i] &&
456                     (vlan == (MLX4_VLAN_MASK &
457                               be32_to_cpu(table->entries[i])))) {
458                         /* Vlan already registered, increase references count */
459                         *index = i;
460                         ++table->refs[i];
461                         goto out;
462                 }
463         }
464
465         if (free < 0) {
466                 err = -ENOMEM;
467                 goto out;
468         }
469
470         /* Register new VLAN */
471         table->refs[free] = 1;
472         table->entries[free] = cpu_to_be32(vlan | MLX4_VLAN_VALID);
473
474         err = mlx4_set_port_vlan_table(dev, port, table->entries);
475         if (unlikely(err)) {
476                 mlx4_warn(dev, "Failed adding vlan: %u\n", vlan);
477                 table->refs[free] = 0;
478                 table->entries[free] = 0;
479                 goto out;
480         }
481
482         *index = free;
483         ++table->total;
484 out:
485         mutex_unlock(&table->mutex);
486         return err;
487 }
488
489 int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index)
490 {
491         u64 out_param;
492         int err;
493
494         if (mlx4_is_mfunc(dev)) {
495                 set_param_l(&out_param, port);
496                 err = mlx4_cmd_imm(dev, vlan, &out_param, RES_VLAN,
497                                    RES_OP_RESERVE_AND_MAP, MLX4_CMD_ALLOC_RES,
498                                    MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
499                 if (!err)
500                         *index = get_param_l(&out_param);
501
502                 return err;
503         }
504         return __mlx4_register_vlan(dev, port, vlan, index);
505 }
506 EXPORT_SYMBOL_GPL(mlx4_register_vlan);
507
508 static void __mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, int index)
509 {
510         struct mlx4_vlan_table *table = &mlx4_priv(dev)->port[port].vlan_table;
511
512         if (index < MLX4_VLAN_REGULAR) {
513                 mlx4_warn(dev, "Trying to free special vlan index %d\n", index);
514                 return;
515         }
516
517         mutex_lock(&table->mutex);
518         if (!table->refs[index]) {
519                 mlx4_warn(dev, "No vlan entry for index %d\n", index);
520                 goto out;
521         }
522         if (--table->refs[index]) {
523                 mlx4_dbg(dev, "Have more references for index %d,"
524                          "no need to modify vlan table\n", index);
525                 goto out;
526         }
527         table->entries[index] = 0;
528         mlx4_set_port_vlan_table(dev, port, table->entries);
529         --table->total;
530 out:
531         mutex_unlock(&table->mutex);
532 }
533
534 void mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, int index)
535 {
536         u64 in_param;
537         int err;
538
539         if (mlx4_is_mfunc(dev)) {
540                 set_param_l(&in_param, port);
541                 err = mlx4_cmd(dev, in_param, RES_VLAN, RES_OP_RESERVE_AND_MAP,
542                                MLX4_CMD_FREE_RES, MLX4_CMD_TIME_CLASS_A,
543                                MLX4_CMD_WRAPPED);
544                 if (!err)
545                         mlx4_warn(dev, "Failed freeing vlan at index:%d\n",
546                                         index);
547
548                 return;
549         }
550         __mlx4_unregister_vlan(dev, port, index);
551 }
552 EXPORT_SYMBOL_GPL(mlx4_unregister_vlan);
553
554 int mlx4_get_port_ib_caps(struct mlx4_dev *dev, u8 port, __be32 *caps)
555 {
556         struct mlx4_cmd_mailbox *inmailbox, *outmailbox;
557         u8 *inbuf, *outbuf;
558         int err;
559
560         inmailbox = mlx4_alloc_cmd_mailbox(dev);
561         if (IS_ERR(inmailbox))
562                 return PTR_ERR(inmailbox);
563
564         outmailbox = mlx4_alloc_cmd_mailbox(dev);
565         if (IS_ERR(outmailbox)) {
566                 mlx4_free_cmd_mailbox(dev, inmailbox);
567                 return PTR_ERR(outmailbox);
568         }
569
570         inbuf = inmailbox->buf;
571         outbuf = outmailbox->buf;
572         memset(inbuf, 0, 256);
573         memset(outbuf, 0, 256);
574         inbuf[0] = 1;
575         inbuf[1] = 1;
576         inbuf[2] = 1;
577         inbuf[3] = 1;
578         *(__be16 *) (&inbuf[16]) = cpu_to_be16(0x0015);
579         *(__be32 *) (&inbuf[20]) = cpu_to_be32(port);
580
581         err = mlx4_cmd_box(dev, inmailbox->dma, outmailbox->dma, port, 3,
582                            MLX4_CMD_MAD_IFC, MLX4_CMD_TIME_CLASS_C,
583                            MLX4_CMD_NATIVE);
584         if (!err)
585                 *caps = *(__be32 *) (outbuf + 84);
586         mlx4_free_cmd_mailbox(dev, inmailbox);
587         mlx4_free_cmd_mailbox(dev, outmailbox);
588         return err;
589 }
590
591 int mlx4_check_ext_port_caps(struct mlx4_dev *dev, u8 port)
592 {
593         struct mlx4_cmd_mailbox *inmailbox, *outmailbox;
594         u8 *inbuf, *outbuf;
595         int err, packet_error;
596
597         inmailbox = mlx4_alloc_cmd_mailbox(dev);
598         if (IS_ERR(inmailbox))
599                 return PTR_ERR(inmailbox);
600
601         outmailbox = mlx4_alloc_cmd_mailbox(dev);
602         if (IS_ERR(outmailbox)) {
603                 mlx4_free_cmd_mailbox(dev, inmailbox);
604                 return PTR_ERR(outmailbox);
605         }
606
607         inbuf = inmailbox->buf;
608         outbuf = outmailbox->buf;
609         memset(inbuf, 0, 256);
610         memset(outbuf, 0, 256);
611         inbuf[0] = 1;
612         inbuf[1] = 1;
613         inbuf[2] = 1;
614         inbuf[3] = 1;
615
616         *(__be16 *) (&inbuf[16]) = MLX4_ATTR_EXTENDED_PORT_INFO;
617         *(__be32 *) (&inbuf[20]) = cpu_to_be32(port);
618
619         err = mlx4_cmd_box(dev, inmailbox->dma, outmailbox->dma, port, 3,
620                            MLX4_CMD_MAD_IFC, MLX4_CMD_TIME_CLASS_C,
621                            MLX4_CMD_NATIVE);
622
623         packet_error = be16_to_cpu(*(__be16 *) (outbuf + 4));
624
625         dev->caps.ext_port_cap[port] = (!err && !packet_error) ?
626                                        MLX_EXT_PORT_CAP_FLAG_EXTENDED_PORT_INFO
627                                        : 0;
628
629         mlx4_free_cmd_mailbox(dev, inmailbox);
630         mlx4_free_cmd_mailbox(dev, outmailbox);
631         return err;
632 }
633
634 static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod,
635                                 u8 op_mod, struct mlx4_cmd_mailbox *inbox)
636 {
637         struct mlx4_priv *priv = mlx4_priv(dev);
638         struct mlx4_port_info *port_info;
639         struct mlx4_mfunc_master_ctx *master = &priv->mfunc.master;
640         struct mlx4_slave_state *slave_st = &master->slave_state[slave];
641         struct mlx4_set_port_rqp_calc_context *qpn_context;
642         struct mlx4_set_port_general_context *gen_context;
643         int reset_qkey_viols;
644         int port;
645         int is_eth;
646         u32 in_modifier;
647         u32 promisc;
648         u16 mtu, prev_mtu;
649         int err;
650         int i;
651         __be32 agg_cap_mask;
652         __be32 slave_cap_mask;
653         __be32 new_cap_mask;
654
655         port = in_mod & 0xff;
656         in_modifier = in_mod >> 8;
657         is_eth = op_mod;
658         port_info = &priv->port[port];
659
660         /* Slaves cannot perform SET_PORT operations except changing MTU */
661         if (is_eth) {
662                 if (slave != dev->caps.function &&
663                     in_modifier != MLX4_SET_PORT_GENERAL) {
664                         mlx4_warn(dev, "denying SET_PORT for slave:%d\n",
665                                         slave);
666                         return -EINVAL;
667                 }
668                 switch (in_modifier) {
669                 case MLX4_SET_PORT_RQP_CALC:
670                         qpn_context = inbox->buf;
671                         qpn_context->base_qpn =
672                                 cpu_to_be32(port_info->base_qpn);
673                         qpn_context->n_mac = 0x7;
674                         promisc = be32_to_cpu(qpn_context->promisc) >>
675                                 SET_PORT_PROMISC_SHIFT;
676                         qpn_context->promisc = cpu_to_be32(
677                                 promisc << SET_PORT_PROMISC_SHIFT |
678                                 port_info->base_qpn);
679                         promisc = be32_to_cpu(qpn_context->mcast) >>
680                                 SET_PORT_MC_PROMISC_SHIFT;
681                         qpn_context->mcast = cpu_to_be32(
682                                 promisc << SET_PORT_MC_PROMISC_SHIFT |
683                                 port_info->base_qpn);
684                         break;
685                 case MLX4_SET_PORT_GENERAL:
686                         gen_context = inbox->buf;
687                         /* Mtu is configured as the max MTU among all the
688                          * the functions on the port. */
689                         mtu = be16_to_cpu(gen_context->mtu);
690                         mtu = min_t(int, mtu, dev->caps.eth_mtu_cap[port]);
691                         prev_mtu = slave_st->mtu[port];
692                         slave_st->mtu[port] = mtu;
693                         if (mtu > master->max_mtu[port])
694                                 master->max_mtu[port] = mtu;
695                         if (mtu < prev_mtu && prev_mtu ==
696                                                 master->max_mtu[port]) {
697                                 slave_st->mtu[port] = mtu;
698                                 master->max_mtu[port] = mtu;
699                                 for (i = 0; i < dev->num_slaves; i++) {
700                                         master->max_mtu[port] =
701                                         max(master->max_mtu[port],
702                                             master->slave_state[i].mtu[port]);
703                                 }
704                         }
705
706                         gen_context->mtu = cpu_to_be16(master->max_mtu[port]);
707                         break;
708                 }
709                 return mlx4_cmd(dev, inbox->dma, in_mod, op_mod,
710                                 MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B,
711                                 MLX4_CMD_NATIVE);
712         }
713
714         /* For IB, we only consider:
715          * - The capability mask, which is set to the aggregate of all
716          *   slave function capabilities
717          * - The QKey violatin counter - reset according to each request.
718          */
719
720         if (dev->flags & MLX4_FLAG_OLD_PORT_CMDS) {
721                 reset_qkey_viols = (*(u8 *) inbox->buf) & 0x40;
722                 new_cap_mask = ((__be32 *) inbox->buf)[2];
723         } else {
724                 reset_qkey_viols = ((u8 *) inbox->buf)[3] & 0x1;
725                 new_cap_mask = ((__be32 *) inbox->buf)[1];
726         }
727
728         agg_cap_mask = 0;
729         slave_cap_mask =
730                 priv->mfunc.master.slave_state[slave].ib_cap_mask[port];
731         priv->mfunc.master.slave_state[slave].ib_cap_mask[port] = new_cap_mask;
732         for (i = 0; i < dev->num_slaves; i++)
733                 agg_cap_mask |=
734                         priv->mfunc.master.slave_state[i].ib_cap_mask[port];
735
736         /* only clear mailbox for guests.  Master may be setting
737         * MTU or PKEY table size
738         */
739         if (slave != dev->caps.function)
740                 memset(inbox->buf, 0, 256);
741         if (dev->flags & MLX4_FLAG_OLD_PORT_CMDS) {
742                 *(u8 *) inbox->buf         = !!reset_qkey_viols << 6;
743                 ((__be32 *) inbox->buf)[2] = agg_cap_mask;
744         } else {
745                 ((u8 *) inbox->buf)[3]     = !!reset_qkey_viols;
746                 ((__be32 *) inbox->buf)[1] = agg_cap_mask;
747         }
748
749         err = mlx4_cmd(dev, inbox->dma, port, is_eth, MLX4_CMD_SET_PORT,
750                        MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE);
751         if (err)
752                 priv->mfunc.master.slave_state[slave].ib_cap_mask[port] =
753                         slave_cap_mask;
754         return err;
755 }
756
757 int mlx4_SET_PORT_wrapper(struct mlx4_dev *dev, int slave,
758                           struct mlx4_vhcr *vhcr,
759                           struct mlx4_cmd_mailbox *inbox,
760                           struct mlx4_cmd_mailbox *outbox,
761                           struct mlx4_cmd_info *cmd)
762 {
763         return mlx4_common_set_port(dev, slave, vhcr->in_modifier,
764                                     vhcr->op_modifier, inbox);
765 }
766
767 int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port)
768 {
769         struct mlx4_cmd_mailbox *mailbox;
770         int err;
771
772         if (dev->caps.port_type[port] == MLX4_PORT_TYPE_ETH)
773                 return 0;
774
775         mailbox = mlx4_alloc_cmd_mailbox(dev);
776         if (IS_ERR(mailbox))
777                 return PTR_ERR(mailbox);
778
779         memset(mailbox->buf, 0, 256);
780
781         ((__be32 *) mailbox->buf)[1] = dev->caps.ib_port_def_cap[port];
782         err = mlx4_cmd(dev, mailbox->dma, port, 0, MLX4_CMD_SET_PORT,
783                        MLX4_CMD_TIME_CLASS_B, MLX4_CMD_WRAPPED);
784
785         mlx4_free_cmd_mailbox(dev, mailbox);
786         return err;
787 }
788
789 int mlx4_SET_PORT_general(struct mlx4_dev *dev, u8 port, int mtu,
790                           u8 pptx, u8 pfctx, u8 pprx, u8 pfcrx)
791 {
792         struct mlx4_cmd_mailbox *mailbox;
793         struct mlx4_set_port_general_context *context;
794         int err;
795         u32 in_mod;
796
797         mailbox = mlx4_alloc_cmd_mailbox(dev);
798         if (IS_ERR(mailbox))
799                 return PTR_ERR(mailbox);
800         context = mailbox->buf;
801         memset(context, 0, sizeof *context);
802
803         context->flags = SET_PORT_GEN_ALL_VALID;
804         context->mtu = cpu_to_be16(mtu);
805         context->pptx = (pptx * (!pfctx)) << 7;
806         context->pfctx = pfctx;
807         context->pprx = (pprx * (!pfcrx)) << 7;
808         context->pfcrx = pfcrx;
809
810         in_mod = MLX4_SET_PORT_GENERAL << 8 | port;
811         err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT,
812                        MLX4_CMD_TIME_CLASS_B,  MLX4_CMD_WRAPPED);
813
814         mlx4_free_cmd_mailbox(dev, mailbox);
815         return err;
816 }
817 EXPORT_SYMBOL(mlx4_SET_PORT_general);
818
819 int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn,
820                            u8 promisc)
821 {
822         struct mlx4_cmd_mailbox *mailbox;
823         struct mlx4_set_port_rqp_calc_context *context;
824         int err;
825         u32 in_mod;
826         u32 m_promisc = (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER) ?
827                 MCAST_DIRECT : MCAST_DEFAULT;
828
829         if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER  &&
830             dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER)
831                 return 0;
832
833         mailbox = mlx4_alloc_cmd_mailbox(dev);
834         if (IS_ERR(mailbox))
835                 return PTR_ERR(mailbox);
836         context = mailbox->buf;
837         memset(context, 0, sizeof *context);
838
839         context->base_qpn = cpu_to_be32(base_qpn);
840         context->n_mac = dev->caps.log_num_macs;
841         context->promisc = cpu_to_be32(promisc << SET_PORT_PROMISC_SHIFT |
842                                        base_qpn);
843         context->mcast = cpu_to_be32(m_promisc << SET_PORT_MC_PROMISC_SHIFT |
844                                      base_qpn);
845         context->intra_no_vlan = 0;
846         context->no_vlan = MLX4_NO_VLAN_IDX;
847         context->intra_vlan_miss = 0;
848         context->vlan_miss = MLX4_VLAN_MISS_IDX;
849
850         in_mod = MLX4_SET_PORT_RQP_CALC << 8 | port;
851         err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT,
852                        MLX4_CMD_TIME_CLASS_B,  MLX4_CMD_WRAPPED);
853
854         mlx4_free_cmd_mailbox(dev, mailbox);
855         return err;
856 }
857 EXPORT_SYMBOL(mlx4_SET_PORT_qpn_calc);
858
859 int mlx4_SET_MCAST_FLTR_wrapper(struct mlx4_dev *dev, int slave,
860                                 struct mlx4_vhcr *vhcr,
861                                 struct mlx4_cmd_mailbox *inbox,
862                                 struct mlx4_cmd_mailbox *outbox,
863                                 struct mlx4_cmd_info *cmd)
864 {
865         int err = 0;
866
867         return err;
868 }
869
870 int mlx4_SET_MCAST_FLTR(struct mlx4_dev *dev, u8 port,
871                         u64 mac, u64 clear, u8 mode)
872 {
873         return mlx4_cmd(dev, (mac | (clear << 63)), port, mode,
874                         MLX4_CMD_SET_MCAST_FLTR, MLX4_CMD_TIME_CLASS_B,
875                         MLX4_CMD_WRAPPED);
876 }
877 EXPORT_SYMBOL(mlx4_SET_MCAST_FLTR);
878
879 int mlx4_SET_VLAN_FLTR_wrapper(struct mlx4_dev *dev, int slave,
880                                struct mlx4_vhcr *vhcr,
881                                struct mlx4_cmd_mailbox *inbox,
882                                struct mlx4_cmd_mailbox *outbox,
883                                struct mlx4_cmd_info *cmd)
884 {
885         int err = 0;
886
887         return err;
888 }
889
890 int mlx4_common_dump_eth_stats(struct mlx4_dev *dev, int slave,
891                                u32 in_mod, struct mlx4_cmd_mailbox *outbox)
892 {
893         return mlx4_cmd_box(dev, 0, outbox->dma, in_mod, 0,
894                             MLX4_CMD_DUMP_ETH_STATS, MLX4_CMD_TIME_CLASS_B,
895                             MLX4_CMD_NATIVE);
896 }
897
898 int mlx4_DUMP_ETH_STATS_wrapper(struct mlx4_dev *dev, int slave,
899                                 struct mlx4_vhcr *vhcr,
900                                 struct mlx4_cmd_mailbox *inbox,
901                                 struct mlx4_cmd_mailbox *outbox,
902                                 struct mlx4_cmd_info *cmd)
903 {
904         if (slave != dev->caps.function)
905                 return 0;
906         return mlx4_common_dump_eth_stats(dev, slave,
907                                           vhcr->in_modifier, outbox);
908 }
909
910 void mlx4_set_stats_bitmap(struct mlx4_dev *dev, u64 *stats_bitmap)
911 {
912         if (!mlx4_is_mfunc(dev)) {
913                 *stats_bitmap = 0;
914                 return;
915         }
916
917         *stats_bitmap = (MLX4_STATS_TRAFFIC_COUNTERS_MASK |
918                          MLX4_STATS_TRAFFIC_DROPS_MASK |
919                          MLX4_STATS_PORT_COUNTERS_MASK);
920
921         if (mlx4_is_master(dev))
922                 *stats_bitmap |= MLX4_STATS_ERROR_COUNTERS_MASK;
923 }
924 EXPORT_SYMBOL(mlx4_set_stats_bitmap);