brintos

brintos / linux-shallow public Read only

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