brintos

brintos / linux-shallow public Read only

0
0
Text · 60.8 KiB · cd17a3f Raw
2175 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 34#include <linux/kernel.h>35#include <linux/ethtool.h>36#include <linux/netdevice.h>37#include <linux/mlx4/driver.h>38#include <linux/mlx4/device.h>39#include <linux/in.h>40#include <net/ip.h>41#include <linux/bitmap.h>42#include <linux/mii.h>43 44#include "mlx4_en.h"45#include "en_port.h"46 47#define EN_ETHTOOL_QP_ATTACH (1ull << 63)48#define EN_ETHTOOL_SHORT_MASK cpu_to_be16(0xffff)49#define EN_ETHTOOL_WORD_MASK  cpu_to_be32(0xffffffff)50 51int mlx4_en_moderation_update(struct mlx4_en_priv *priv)52{53	int i, t;54	int err = 0;55 56	for (t = 0 ; t < MLX4_EN_NUM_TX_TYPES; t++) {57		for (i = 0; i < priv->tx_ring_num[t]; i++) {58			priv->tx_cq[t][i]->moder_cnt = priv->tx_frames;59			priv->tx_cq[t][i]->moder_time = priv->tx_usecs;60			if (priv->port_up) {61				err = mlx4_en_set_cq_moder(priv,62							   priv->tx_cq[t][i]);63				if (err)64					return err;65			}66		}67	}68 69	if (priv->adaptive_rx_coal)70		return 0;71 72	for (i = 0; i < priv->rx_ring_num; i++) {73		priv->rx_cq[i]->moder_cnt = priv->rx_frames;74		priv->rx_cq[i]->moder_time = priv->rx_usecs;75		priv->last_moder_time[i] = MLX4_EN_AUTO_CONF;76		if (priv->port_up) {77			err = mlx4_en_set_cq_moder(priv, priv->rx_cq[i]);78			if (err)79				return err;80		}81	}82 83	return err;84}85 86static void87mlx4_en_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)88{89	struct mlx4_en_priv *priv = netdev_priv(dev);90	struct mlx4_en_dev *mdev = priv->mdev;91 92	strscpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver));93	strscpy(drvinfo->version, DRV_VERSION,94		sizeof(drvinfo->version));95	snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),96		"%d.%d.%d",97		(u16) (mdev->dev->caps.fw_ver >> 32),98		(u16) ((mdev->dev->caps.fw_ver >> 16) & 0xffff),99		(u16) (mdev->dev->caps.fw_ver & 0xffff));100	strscpy(drvinfo->bus_info, pci_name(mdev->dev->persist->pdev),101		sizeof(drvinfo->bus_info));102}103 104static const char mlx4_en_priv_flags[][ETH_GSTRING_LEN] = {105	"blueflame",106	"phv-bit"107};108 109static const char main_strings[][ETH_GSTRING_LEN] = {110	/* main statistics */111	"rx_packets", "tx_packets", "rx_bytes", "tx_bytes", "rx_errors",112	"tx_errors", "rx_dropped", "tx_dropped", "multicast", "collisions",113	"rx_length_errors", "rx_over_errors", "rx_crc_errors",114	"rx_frame_errors", "rx_fifo_errors", "rx_missed_errors",115	"tx_aborted_errors", "tx_carrier_errors", "tx_fifo_errors",116	"tx_heartbeat_errors", "tx_window_errors",117 118	/* port statistics */119	"tso_packets",120	"xmit_more",121	"queue_stopped", "wake_queue", "tx_timeout", "rx_alloc_pages",122	"rx_csum_good", "rx_csum_none", "rx_csum_complete", "tx_chksum_offload",123 124	/* pf statistics */125	"pf_rx_packets",126	"pf_rx_bytes",127	"pf_tx_packets",128	"pf_tx_bytes",129 130	/* priority flow control statistics rx */131	"rx_pause_prio_0", "rx_pause_duration_prio_0",132	"rx_pause_transition_prio_0",133	"rx_pause_prio_1", "rx_pause_duration_prio_1",134	"rx_pause_transition_prio_1",135	"rx_pause_prio_2", "rx_pause_duration_prio_2",136	"rx_pause_transition_prio_2",137	"rx_pause_prio_3", "rx_pause_duration_prio_3",138	"rx_pause_transition_prio_3",139	"rx_pause_prio_4", "rx_pause_duration_prio_4",140	"rx_pause_transition_prio_4",141	"rx_pause_prio_5", "rx_pause_duration_prio_5",142	"rx_pause_transition_prio_5",143	"rx_pause_prio_6", "rx_pause_duration_prio_6",144	"rx_pause_transition_prio_6",145	"rx_pause_prio_7", "rx_pause_duration_prio_7",146	"rx_pause_transition_prio_7",147 148	/* flow control statistics rx */149	"rx_pause", "rx_pause_duration", "rx_pause_transition",150 151	/* priority flow control statistics tx */152	"tx_pause_prio_0", "tx_pause_duration_prio_0",153	"tx_pause_transition_prio_0",154	"tx_pause_prio_1", "tx_pause_duration_prio_1",155	"tx_pause_transition_prio_1",156	"tx_pause_prio_2", "tx_pause_duration_prio_2",157	"tx_pause_transition_prio_2",158	"tx_pause_prio_3", "tx_pause_duration_prio_3",159	"tx_pause_transition_prio_3",160	"tx_pause_prio_4", "tx_pause_duration_prio_4",161	"tx_pause_transition_prio_4",162	"tx_pause_prio_5", "tx_pause_duration_prio_5",163	"tx_pause_transition_prio_5",164	"tx_pause_prio_6", "tx_pause_duration_prio_6",165	"tx_pause_transition_prio_6",166	"tx_pause_prio_7", "tx_pause_duration_prio_7",167	"tx_pause_transition_prio_7",168 169	/* flow control statistics tx */170	"tx_pause", "tx_pause_duration", "tx_pause_transition",171 172	/* packet statistics */173	"rx_multicast_packets",174	"rx_broadcast_packets",175	"rx_jabbers",176	"rx_in_range_length_error",177	"rx_out_range_length_error",178	"tx_multicast_packets",179	"tx_broadcast_packets",180	"rx_prio_0_packets", "rx_prio_0_bytes",181	"rx_prio_1_packets", "rx_prio_1_bytes",182	"rx_prio_2_packets", "rx_prio_2_bytes",183	"rx_prio_3_packets", "rx_prio_3_bytes",184	"rx_prio_4_packets", "rx_prio_4_bytes",185	"rx_prio_5_packets", "rx_prio_5_bytes",186	"rx_prio_6_packets", "rx_prio_6_bytes",187	"rx_prio_7_packets", "rx_prio_7_bytes",188	"rx_novlan_packets", "rx_novlan_bytes",189	"tx_prio_0_packets", "tx_prio_0_bytes",190	"tx_prio_1_packets", "tx_prio_1_bytes",191	"tx_prio_2_packets", "tx_prio_2_bytes",192	"tx_prio_3_packets", "tx_prio_3_bytes",193	"tx_prio_4_packets", "tx_prio_4_bytes",194	"tx_prio_5_packets", "tx_prio_5_bytes",195	"tx_prio_6_packets", "tx_prio_6_bytes",196	"tx_prio_7_packets", "tx_prio_7_bytes",197	"tx_novlan_packets", "tx_novlan_bytes",198 199	/* xdp statistics */200	"rx_xdp_drop",201	"rx_xdp_redirect",202	"rx_xdp_redirect_fail",203	"rx_xdp_tx",204	"rx_xdp_tx_full",205 206	/* phy statistics */207	"rx_packets_phy", "rx_bytes_phy",208	"tx_packets_phy", "tx_bytes_phy",209};210 211static const char mlx4_en_test_names[][ETH_GSTRING_LEN]= {212	"Interrupt Test",213	"Link Test",214	"Speed Test",215	"Register Test",216	"Loopback Test",217};218 219static u32 mlx4_en_get_msglevel(struct net_device *dev)220{221	return ((struct mlx4_en_priv *) netdev_priv(dev))->msg_enable;222}223 224static void mlx4_en_set_msglevel(struct net_device *dev, u32 val)225{226	((struct mlx4_en_priv *) netdev_priv(dev))->msg_enable = val;227}228 229static void mlx4_en_get_wol(struct net_device *netdev,230			    struct ethtool_wolinfo *wol)231{232	struct mlx4_en_priv *priv = netdev_priv(netdev);233	struct mlx4_caps *caps = &priv->mdev->dev->caps;234	int err = 0;235	u64 config = 0;236	u64 mask;237 238	if ((priv->port < 1) || (priv->port > 2)) {239		en_err(priv, "Failed to get WoL information\n");240		return;241	}242 243	mask = (priv->port == 1) ? MLX4_DEV_CAP_FLAG_WOL_PORT1 :244		MLX4_DEV_CAP_FLAG_WOL_PORT2;245 246	if (!(caps->flags & mask)) {247		wol->supported = 0;248		wol->wolopts = 0;249		return;250	}251 252	if (caps->wol_port[priv->port])253		wol->supported = WAKE_MAGIC;254	else255		wol->supported = 0;256 257	err = mlx4_wol_read(priv->mdev->dev, &config, priv->port);258	if (err) {259		en_err(priv, "Failed to get WoL information\n");260		return;261	}262 263	if ((config & MLX4_EN_WOL_ENABLED) && (config & MLX4_EN_WOL_MAGIC))264		wol->wolopts = WAKE_MAGIC;265	else266		wol->wolopts = 0;267}268 269static int mlx4_en_set_wol(struct net_device *netdev,270			    struct ethtool_wolinfo *wol)271{272	struct mlx4_en_priv *priv = netdev_priv(netdev);273	u64 config = 0;274	int err = 0;275	u64 mask;276 277	if ((priv->port < 1) || (priv->port > 2))278		return -EOPNOTSUPP;279 280	mask = (priv->port == 1) ? MLX4_DEV_CAP_FLAG_WOL_PORT1 :281		MLX4_DEV_CAP_FLAG_WOL_PORT2;282 283	if (!(priv->mdev->dev->caps.flags & mask))284		return -EOPNOTSUPP;285 286	if (wol->supported & ~WAKE_MAGIC)287		return -EINVAL;288 289	err = mlx4_wol_read(priv->mdev->dev, &config, priv->port);290	if (err) {291		en_err(priv, "Failed to get WoL info, unable to modify\n");292		return err;293	}294 295	if (wol->wolopts & WAKE_MAGIC) {296		config |= MLX4_EN_WOL_DO_MODIFY | MLX4_EN_WOL_ENABLED |297				MLX4_EN_WOL_MAGIC;298	} else {299		config &= ~(MLX4_EN_WOL_ENABLED | MLX4_EN_WOL_MAGIC);300		config |= MLX4_EN_WOL_DO_MODIFY;301	}302 303	err = mlx4_wol_write(priv->mdev->dev, config, priv->port);304	if (err)305		en_err(priv, "Failed to set WoL information\n");306 307	return err;308}309 310struct bitmap_iterator {311	unsigned long *stats_bitmap;312	unsigned int count;313	unsigned int iterator;314	bool advance_array; /* if set, force no increments */315};316 317static inline void bitmap_iterator_init(struct bitmap_iterator *h,318					unsigned long *stats_bitmap,319					int count)320{321	h->iterator = 0;322	h->advance_array = !bitmap_empty(stats_bitmap, count);323	h->count = h->advance_array ? bitmap_weight(stats_bitmap, count)324		: count;325	h->stats_bitmap = stats_bitmap;326}327 328static inline int bitmap_iterator_test(struct bitmap_iterator *h)329{330	return !h->advance_array ? 1 : test_bit(h->iterator, h->stats_bitmap);331}332 333static inline int bitmap_iterator_inc(struct bitmap_iterator *h)334{335	return h->iterator++;336}337 338static inline unsigned int339bitmap_iterator_count(struct bitmap_iterator *h)340{341	return h->count;342}343 344static int mlx4_en_get_sset_count(struct net_device *dev, int sset)345{346	struct mlx4_en_priv *priv = netdev_priv(dev);347	struct bitmap_iterator it;348 349	bitmap_iterator_init(&it, priv->stats_bitmap.bitmap, NUM_ALL_STATS);350 351	switch (sset) {352	case ETH_SS_STATS:353		return bitmap_iterator_count(&it) +354			(priv->tx_ring_num[TX] * 2) +355			(priv->rx_ring_num * (3 + NUM_XDP_STATS));356	case ETH_SS_TEST:357		return MLX4_EN_NUM_SELF_TEST - !(priv->mdev->dev->caps.flags358					& MLX4_DEV_CAP_FLAG_UC_LOOPBACK) * 2;359	case ETH_SS_PRIV_FLAGS:360		return ARRAY_SIZE(mlx4_en_priv_flags);361	default:362		return -EOPNOTSUPP;363	}364}365 366static void mlx4_en_get_ethtool_stats(struct net_device *dev,367		struct ethtool_stats *stats, uint64_t *data)368{369	struct mlx4_en_priv *priv = netdev_priv(dev);370	int index = 0;371	int i;372	struct bitmap_iterator it;373 374	bitmap_iterator_init(&it, priv->stats_bitmap.bitmap, NUM_ALL_STATS);375 376	spin_lock_bh(&priv->stats_lock);377 378	mlx4_en_fold_software_stats(dev);379 380	for (i = 0; i < NUM_MAIN_STATS; i++, bitmap_iterator_inc(&it))381		if (bitmap_iterator_test(&it))382			data[index++] = ((unsigned long *)&dev->stats)[i];383 384	for (i = 0; i < NUM_PORT_STATS; i++, bitmap_iterator_inc(&it))385		if (bitmap_iterator_test(&it))386			data[index++] = ((unsigned long *)&priv->port_stats)[i];387 388	for (i = 0; i < NUM_PF_STATS; i++, bitmap_iterator_inc(&it))389		if (bitmap_iterator_test(&it))390			data[index++] =391				((unsigned long *)&priv->pf_stats)[i];392 393	for (i = 0; i < NUM_FLOW_PRIORITY_STATS_RX;394	     i++, bitmap_iterator_inc(&it))395		if (bitmap_iterator_test(&it))396			data[index++] =397				((u64 *)&priv->rx_priority_flowstats)[i];398 399	for (i = 0; i < NUM_FLOW_STATS_RX; i++, bitmap_iterator_inc(&it))400		if (bitmap_iterator_test(&it))401			data[index++] = ((u64 *)&priv->rx_flowstats)[i];402 403	for (i = 0; i < NUM_FLOW_PRIORITY_STATS_TX;404	     i++, bitmap_iterator_inc(&it))405		if (bitmap_iterator_test(&it))406			data[index++] =407				((u64 *)&priv->tx_priority_flowstats)[i];408 409	for (i = 0; i < NUM_FLOW_STATS_TX; i++, bitmap_iterator_inc(&it))410		if (bitmap_iterator_test(&it))411			data[index++] = ((u64 *)&priv->tx_flowstats)[i];412 413	for (i = 0; i < NUM_PKT_STATS; i++, bitmap_iterator_inc(&it))414		if (bitmap_iterator_test(&it))415			data[index++] = ((unsigned long *)&priv->pkstats)[i];416 417	for (i = 0; i < NUM_XDP_STATS; i++, bitmap_iterator_inc(&it))418		if (bitmap_iterator_test(&it))419			data[index++] = ((unsigned long *)&priv->xdp_stats)[i];420 421	for (i = 0; i < NUM_PHY_STATS; i++, bitmap_iterator_inc(&it))422		if (bitmap_iterator_test(&it))423			data[index++] = ((unsigned long *)&priv->phy_stats)[i];424 425	for (i = 0; i < priv->tx_ring_num[TX]; i++) {426		data[index++] = priv->tx_ring[TX][i]->packets;427		data[index++] = priv->tx_ring[TX][i]->bytes;428	}429	for (i = 0; i < priv->rx_ring_num; i++) {430		data[index++] = priv->rx_ring[i]->packets;431		data[index++] = priv->rx_ring[i]->bytes;432		data[index++] = priv->rx_ring[i]->dropped;433		data[index++] = priv->rx_ring[i]->xdp_drop;434		data[index++] = priv->rx_ring[i]->xdp_redirect;435		data[index++] = priv->rx_ring[i]->xdp_redirect_fail;436		data[index++] = priv->rx_ring[i]->xdp_tx;437		data[index++] = priv->rx_ring[i]->xdp_tx_full;438	}439	spin_unlock_bh(&priv->stats_lock);440 441}442 443static void mlx4_en_self_test(struct net_device *dev,444			      struct ethtool_test *etest, u64 *buf)445{446	mlx4_en_ex_selftest(dev, &etest->flags, buf);447}448 449static void mlx4_en_get_strings(struct net_device *dev,450				uint32_t stringset, uint8_t *data)451{452	struct mlx4_en_priv *priv = netdev_priv(dev);453	int i, strings = 0;454	struct bitmap_iterator it;455 456	bitmap_iterator_init(&it, priv->stats_bitmap.bitmap, NUM_ALL_STATS);457 458	switch (stringset) {459	case ETH_SS_TEST:460		for (i = 0; i < MLX4_EN_NUM_SELF_TEST - 2; i++)461			ethtool_puts(&data, mlx4_en_test_names[i]);462		if (priv->mdev->dev->caps.flags & MLX4_DEV_CAP_FLAG_UC_LOOPBACK)463			for (; i < MLX4_EN_NUM_SELF_TEST; i++)464				ethtool_puts(&data, mlx4_en_test_names[i]);465		break;466 467	case ETH_SS_STATS:468		/* Add main counters */469		for (i = 0; i < NUM_MAIN_STATS; i++, strings++,470		     bitmap_iterator_inc(&it))471			if (bitmap_iterator_test(&it))472				ethtool_puts(&data, main_strings[strings]);473 474		for (i = 0; i < NUM_PORT_STATS; i++, strings++,475		     bitmap_iterator_inc(&it))476			if (bitmap_iterator_test(&it))477				ethtool_puts(&data, main_strings[strings]);478 479		for (i = 0; i < NUM_PF_STATS; i++, strings++,480		     bitmap_iterator_inc(&it))481			if (bitmap_iterator_test(&it))482				ethtool_puts(&data, main_strings[strings]);483 484		for (i = 0; i < NUM_FLOW_STATS; i++, strings++,485		     bitmap_iterator_inc(&it))486			if (bitmap_iterator_test(&it))487				ethtool_puts(&data, main_strings[strings]);488 489		for (i = 0; i < NUM_PKT_STATS; i++, strings++,490		     bitmap_iterator_inc(&it))491			if (bitmap_iterator_test(&it))492				ethtool_puts(&data, main_strings[strings]);493 494		for (i = 0; i < NUM_XDP_STATS; i++, strings++,495		     bitmap_iterator_inc(&it))496			if (bitmap_iterator_test(&it))497				ethtool_puts(&data, main_strings[strings]);498 499		for (i = 0; i < NUM_PHY_STATS; i++, strings++,500		     bitmap_iterator_inc(&it))501			if (bitmap_iterator_test(&it))502				ethtool_puts(&data, main_strings[strings]);503 504		for (i = 0; i < priv->tx_ring_num[TX]; i++) {505			ethtool_sprintf(&data, "tx%d_packets", i);506			ethtool_sprintf(&data, "tx%d_bytes", i);507		}508		for (i = 0; i < priv->rx_ring_num; i++) {509			ethtool_sprintf(&data, "rx%d_packets", i);510			ethtool_sprintf(&data, "rx%d_bytes", i);511			ethtool_sprintf(&data, "rx%d_dropped", i);512			ethtool_sprintf(&data, "rx%d_xdp_drop", i);513			ethtool_sprintf(&data, "rx%d_xdp_redirect", i);514			ethtool_sprintf(&data, "rx%d_xdp_redirect_fail", i);515			ethtool_sprintf(&data, "rx%d_xdp_tx", i);516			ethtool_sprintf(&data, "rx%d_xdp_tx_full", i);517		}518		break;519	case ETH_SS_PRIV_FLAGS:520		for (i = 0; i < ARRAY_SIZE(mlx4_en_priv_flags); i++)521			ethtool_puts(&data, mlx4_en_priv_flags[i]);522		break;523 524	}525}526 527static u32 mlx4_en_autoneg_get(struct net_device *dev)528{529	struct mlx4_en_priv *priv = netdev_priv(dev);530	struct mlx4_en_dev *mdev = priv->mdev;531	u32 autoneg = AUTONEG_DISABLE;532 533	if ((mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_ETH_BACKPL_AN_REP) &&534	    (priv->port_state.flags & MLX4_EN_PORT_ANE))535		autoneg = AUTONEG_ENABLE;536 537	return autoneg;538}539 540static void ptys2ethtool_update_supported_port(unsigned long *mask,541					       struct mlx4_ptys_reg *ptys_reg)542{543	u32 eth_proto = be32_to_cpu(ptys_reg->eth_proto_cap);544 545	if (eth_proto & (MLX4_PROT_MASK(MLX4_10GBASE_T)546			 | MLX4_PROT_MASK(MLX4_1000BASE_T)547			 | MLX4_PROT_MASK(MLX4_100BASE_TX))) {548		__set_bit(ETHTOOL_LINK_MODE_TP_BIT, mask);549	} else if (eth_proto & (MLX4_PROT_MASK(MLX4_10GBASE_CR)550			 | MLX4_PROT_MASK(MLX4_10GBASE_SR)551			 | MLX4_PROT_MASK(MLX4_56GBASE_SR4)552			 | MLX4_PROT_MASK(MLX4_40GBASE_CR4)553			 | MLX4_PROT_MASK(MLX4_40GBASE_SR4)554			 | MLX4_PROT_MASK(MLX4_1000BASE_CX_SGMII))) {555		__set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, mask);556	} else if (eth_proto & (MLX4_PROT_MASK(MLX4_56GBASE_KR4)557			 | MLX4_PROT_MASK(MLX4_40GBASE_KR4)558			 | MLX4_PROT_MASK(MLX4_20GBASE_KR2)559			 | MLX4_PROT_MASK(MLX4_10GBASE_KR)560			 | MLX4_PROT_MASK(MLX4_10GBASE_KX4)561			 | MLX4_PROT_MASK(MLX4_1000BASE_KX))) {562		__set_bit(ETHTOOL_LINK_MODE_Backplane_BIT, mask);563	}564}565 566static u32 ptys_get_active_port(struct mlx4_ptys_reg *ptys_reg)567{568	u32 eth_proto = be32_to_cpu(ptys_reg->eth_proto_oper);569 570	if (!eth_proto) /* link down */571		eth_proto = be32_to_cpu(ptys_reg->eth_proto_cap);572 573	if (eth_proto & (MLX4_PROT_MASK(MLX4_10GBASE_T)574			 | MLX4_PROT_MASK(MLX4_1000BASE_T)575			 | MLX4_PROT_MASK(MLX4_100BASE_TX))) {576			return PORT_TP;577	}578 579	if (eth_proto & (MLX4_PROT_MASK(MLX4_10GBASE_SR)580			 | MLX4_PROT_MASK(MLX4_56GBASE_SR4)581			 | MLX4_PROT_MASK(MLX4_40GBASE_SR4)582			 | MLX4_PROT_MASK(MLX4_1000BASE_CX_SGMII))) {583			return PORT_FIBRE;584	}585 586	if (eth_proto & (MLX4_PROT_MASK(MLX4_10GBASE_CR)587			 | MLX4_PROT_MASK(MLX4_56GBASE_CR4)588			 | MLX4_PROT_MASK(MLX4_40GBASE_CR4))) {589			return PORT_DA;590	}591 592	if (eth_proto & (MLX4_PROT_MASK(MLX4_56GBASE_KR4)593			 | MLX4_PROT_MASK(MLX4_40GBASE_KR4)594			 | MLX4_PROT_MASK(MLX4_20GBASE_KR2)595			 | MLX4_PROT_MASK(MLX4_10GBASE_KR)596			 | MLX4_PROT_MASK(MLX4_10GBASE_KX4)597			 | MLX4_PROT_MASK(MLX4_1000BASE_KX))) {598			return PORT_NONE;599	}600	return PORT_OTHER;601}602 603#define MLX4_LINK_MODES_SZ \604	(sizeof_field(struct mlx4_ptys_reg, eth_proto_cap) * 8)605 606enum ethtool_report {607	SUPPORTED = 0,608	ADVERTISED = 1,609};610 611struct ptys2ethtool_config {612	__ETHTOOL_DECLARE_LINK_MODE_MASK(supported);613	__ETHTOOL_DECLARE_LINK_MODE_MASK(advertised);614	u32 speed;615};616 617static unsigned long *ptys2ethtool_link_mode(struct ptys2ethtool_config *cfg,618					     enum ethtool_report report)619{620	switch (report) {621	case SUPPORTED:622		return cfg->supported;623	case ADVERTISED:624		return cfg->advertised;625	}626	return NULL;627}628 629#define MLX4_BUILD_PTYS2ETHTOOL_CONFIG(reg_, speed_, ...)		\630	({								\631		struct ptys2ethtool_config *cfg;			\632		static const unsigned int modes[] = { __VA_ARGS__ };	\633		unsigned int i;						\634		cfg = &ptys2ethtool_map[reg_];				\635		cfg->speed = speed_;					\636		linkmode_zero(cfg->supported);				\637		linkmode_zero(cfg->advertised);				\638		for (i = 0 ; i < ARRAY_SIZE(modes) ; ++i) {		\639			__set_bit(modes[i], cfg->supported);		\640			__set_bit(modes[i], cfg->advertised);		\641		}							\642	})643 644/* Translates mlx4 link mode to equivalent ethtool Link modes/speed */645static struct ptys2ethtool_config ptys2ethtool_map[MLX4_LINK_MODES_SZ];646 647void __init mlx4_en_init_ptys2ethtool_map(void)648{649	MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_100BASE_TX, SPEED_100,650				       ETHTOOL_LINK_MODE_100baseT_Full_BIT);651	MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_1000BASE_T, SPEED_1000,652				       ETHTOOL_LINK_MODE_1000baseT_Full_BIT);653	MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_1000BASE_CX_SGMII, SPEED_1000,654				       ETHTOOL_LINK_MODE_1000baseX_Full_BIT);655	MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_1000BASE_KX, SPEED_1000,656				       ETHTOOL_LINK_MODE_1000baseKX_Full_BIT);657	MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_10GBASE_T, SPEED_10000,658				       ETHTOOL_LINK_MODE_10000baseT_Full_BIT);659	MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_10GBASE_CX4, SPEED_10000,660				       ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT);661	MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_10GBASE_KX4, SPEED_10000,662				       ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT);663	MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_10GBASE_KR, SPEED_10000,664				       ETHTOOL_LINK_MODE_10000baseKR_Full_BIT);665	MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_10GBASE_CR, SPEED_10000,666				       ETHTOOL_LINK_MODE_10000baseCR_Full_BIT);667	MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_10GBASE_SR, SPEED_10000,668				       ETHTOOL_LINK_MODE_10000baseSR_Full_BIT);669	MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_20GBASE_KR2, SPEED_20000,670				       ETHTOOL_LINK_MODE_20000baseMLD2_Full_BIT,671				       ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT);672	MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_40GBASE_CR4, SPEED_40000,673				       ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT);674	MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_40GBASE_KR4, SPEED_40000,675				       ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT);676	MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_40GBASE_SR4, SPEED_40000,677				       ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT);678	MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_56GBASE_KR4, SPEED_56000,679				       ETHTOOL_LINK_MODE_56000baseKR4_Full_BIT);680	MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_56GBASE_CR4, SPEED_56000,681				       ETHTOOL_LINK_MODE_56000baseCR4_Full_BIT);682	MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_56GBASE_SR4, SPEED_56000,683				       ETHTOOL_LINK_MODE_56000baseSR4_Full_BIT);684};685 686static void ptys2ethtool_update_link_modes(unsigned long *link_modes,687					   u32 eth_proto,688					   enum ethtool_report report)689{690	int i;691	for (i = 0; i < MLX4_LINK_MODES_SZ; i++) {692		if (eth_proto & MLX4_PROT_MASK(i))693			linkmode_or(link_modes, link_modes,694				    ptys2ethtool_link_mode(&ptys2ethtool_map[i], report));695	}696}697 698static u32 ethtool2ptys_link_modes(const unsigned long *link_modes,699				   enum ethtool_report report)700{701	int i;702	u32 ptys_modes = 0;703 704	for (i = 0; i < MLX4_LINK_MODES_SZ; i++) {705		ulong *map_mode = ptys2ethtool_link_mode(&ptys2ethtool_map[i],706							 report);707		if (linkmode_intersects(map_mode, link_modes))708			ptys_modes |= 1 << i;709	}710	return ptys_modes;711}712 713/* Convert actual speed (SPEED_XXX) to ptys link modes */714static u32 speed2ptys_link_modes(u32 speed)715{716	int i;717	u32 ptys_modes = 0;718 719	for (i = 0; i < MLX4_LINK_MODES_SZ; i++) {720		if (ptys2ethtool_map[i].speed == speed)721			ptys_modes |= 1 << i;722	}723	return ptys_modes;724}725 726static int727ethtool_get_ptys_link_ksettings(struct net_device *dev,728				struct ethtool_link_ksettings *link_ksettings)729{730	struct mlx4_en_priv *priv = netdev_priv(dev);731	struct mlx4_ptys_reg ptys_reg;732	u32 eth_proto;733	int ret;734 735	memset(&ptys_reg, 0, sizeof(ptys_reg));736	ptys_reg.local_port = priv->port;737	ptys_reg.proto_mask = MLX4_PTYS_EN;738	ret = mlx4_ACCESS_PTYS_REG(priv->mdev->dev,739				   MLX4_ACCESS_REG_QUERY, &ptys_reg);740	if (ret) {741		en_warn(priv, "Failed to run mlx4_ACCESS_PTYS_REG status(%x)",742			ret);743		return ret;744	}745	en_dbg(DRV, priv, "ptys_reg.proto_mask       %x\n",746	       ptys_reg.proto_mask);747	en_dbg(DRV, priv, "ptys_reg.eth_proto_cap    %x\n",748	       be32_to_cpu(ptys_reg.eth_proto_cap));749	en_dbg(DRV, priv, "ptys_reg.eth_proto_admin  %x\n",750	       be32_to_cpu(ptys_reg.eth_proto_admin));751	en_dbg(DRV, priv, "ptys_reg.eth_proto_oper   %x\n",752	       be32_to_cpu(ptys_reg.eth_proto_oper));753	en_dbg(DRV, priv, "ptys_reg.eth_proto_lp_adv %x\n",754	       be32_to_cpu(ptys_reg.eth_proto_lp_adv));755 756	/* reset supported/advertising masks */757	ethtool_link_ksettings_zero_link_mode(link_ksettings, supported);758	ethtool_link_ksettings_zero_link_mode(link_ksettings, advertising);759 760	ptys2ethtool_update_supported_port(link_ksettings->link_modes.supported,761					   &ptys_reg);762 763	eth_proto = be32_to_cpu(ptys_reg.eth_proto_cap);764	ptys2ethtool_update_link_modes(link_ksettings->link_modes.supported,765				       eth_proto, SUPPORTED);766 767	eth_proto = be32_to_cpu(ptys_reg.eth_proto_admin);768	ptys2ethtool_update_link_modes(link_ksettings->link_modes.advertising,769				       eth_proto, ADVERTISED);770 771	ethtool_link_ksettings_add_link_mode(link_ksettings, supported,772					     Pause);773	ethtool_link_ksettings_add_link_mode(link_ksettings, supported,774					     Asym_Pause);775 776	if (priv->prof->tx_pause)777		ethtool_link_ksettings_add_link_mode(link_ksettings,778						     advertising, Pause);779	if (priv->prof->tx_pause ^ priv->prof->rx_pause)780		ethtool_link_ksettings_add_link_mode(link_ksettings,781						     advertising, Asym_Pause);782 783	link_ksettings->base.port = ptys_get_active_port(&ptys_reg);784 785	if (mlx4_en_autoneg_get(dev)) {786		ethtool_link_ksettings_add_link_mode(link_ksettings,787						     supported, Autoneg);788		ethtool_link_ksettings_add_link_mode(link_ksettings,789						     advertising, Autoneg);790	}791 792	link_ksettings->base.autoneg793		= (priv->port_state.flags & MLX4_EN_PORT_ANC) ?794		AUTONEG_ENABLE : AUTONEG_DISABLE;795 796	eth_proto = be32_to_cpu(ptys_reg.eth_proto_lp_adv);797 798	ethtool_link_ksettings_zero_link_mode(link_ksettings, lp_advertising);799	ptys2ethtool_update_link_modes(800		link_ksettings->link_modes.lp_advertising,801		eth_proto, ADVERTISED);802	if (priv->port_state.flags & MLX4_EN_PORT_ANC)803		ethtool_link_ksettings_add_link_mode(link_ksettings,804						     lp_advertising, Autoneg);805 806	link_ksettings->base.phy_address = 0;807	link_ksettings->base.mdio_support = 0;808	link_ksettings->base.eth_tp_mdix = ETH_TP_MDI_INVALID;809	link_ksettings->base.eth_tp_mdix_ctrl = ETH_TP_MDI_AUTO;810 811	return ret;812}813 814static void815ethtool_get_default_link_ksettings(816	struct net_device *dev, struct ethtool_link_ksettings *link_ksettings)817{818	struct mlx4_en_priv *priv = netdev_priv(dev);819	int trans_type;820 821	link_ksettings->base.autoneg = AUTONEG_DISABLE;822 823	ethtool_link_ksettings_zero_link_mode(link_ksettings, supported);824	ethtool_link_ksettings_add_link_mode(link_ksettings, supported,825					     10000baseT_Full);826 827	ethtool_link_ksettings_zero_link_mode(link_ksettings, advertising);828	ethtool_link_ksettings_add_link_mode(link_ksettings, advertising,829					     10000baseT_Full);830 831	trans_type = priv->port_state.transceiver;832	if (trans_type > 0 && trans_type <= 0xC) {833		link_ksettings->base.port = PORT_FIBRE;834		ethtool_link_ksettings_add_link_mode(link_ksettings,835						     supported, FIBRE);836		ethtool_link_ksettings_add_link_mode(link_ksettings,837						     advertising, FIBRE);838	} else if (trans_type == 0x80 || trans_type == 0) {839		link_ksettings->base.port = PORT_TP;840		ethtool_link_ksettings_add_link_mode(link_ksettings,841						     supported, TP);842		ethtool_link_ksettings_add_link_mode(link_ksettings,843						     advertising, TP);844	} else  {845		link_ksettings->base.port = -1;846	}847}848 849static int850mlx4_en_get_link_ksettings(struct net_device *dev,851			   struct ethtool_link_ksettings *link_ksettings)852{853	struct mlx4_en_priv *priv = netdev_priv(dev);854	int ret = -EINVAL;855 856	if (mlx4_en_QUERY_PORT(priv->mdev, priv->port))857		return -ENOMEM;858 859	en_dbg(DRV, priv, "query port state.flags ANC(%x) ANE(%x)\n",860	       priv->port_state.flags & MLX4_EN_PORT_ANC,861	       priv->port_state.flags & MLX4_EN_PORT_ANE);862 863	if (priv->mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_ETH_PROT_CTRL)864		ret = ethtool_get_ptys_link_ksettings(dev, link_ksettings);865	if (ret) /* ETH PROT CRTL is not supported or PTYS CMD failed */866		ethtool_get_default_link_ksettings(dev, link_ksettings);867 868	if (netif_carrier_ok(dev)) {869		link_ksettings->base.speed = priv->port_state.link_speed;870		link_ksettings->base.duplex = DUPLEX_FULL;871	} else {872		link_ksettings->base.speed = SPEED_UNKNOWN;873		link_ksettings->base.duplex = DUPLEX_UNKNOWN;874	}875	return 0;876}877 878/* Calculate PTYS admin according ethtool speed (SPEED_XXX) */879static __be32 speed_set_ptys_admin(struct mlx4_en_priv *priv, u32 speed,880				   __be32 proto_cap)881{882	__be32 proto_admin = 0;883 884	if (!speed) { /* Speed = 0 ==> Reset Link modes */885		proto_admin = proto_cap;886		en_info(priv, "Speed was set to 0, Reset advertised Link Modes to default (%x)\n",887			be32_to_cpu(proto_cap));888	} else {889		u32 ptys_link_modes = speed2ptys_link_modes(speed);890 891		proto_admin = cpu_to_be32(ptys_link_modes) & proto_cap;892		en_info(priv, "Setting Speed to %d\n", speed);893	}894	return proto_admin;895}896 897static int898mlx4_en_set_link_ksettings(struct net_device *dev,899			   const struct ethtool_link_ksettings *link_ksettings)900{901	struct mlx4_en_priv *priv = netdev_priv(dev);902	struct mlx4_ptys_reg ptys_reg;903	__be32 proto_admin;904	u8 cur_autoneg;905	int ret;906 907	u32 ptys_adv = ethtool2ptys_link_modes(908		link_ksettings->link_modes.advertising, ADVERTISED);909	const int speed = link_ksettings->base.speed;910 911	en_dbg(DRV, priv,912	       "Set Speed=%d adv={%*pbl} autoneg=%d duplex=%d\n",913	       speed, __ETHTOOL_LINK_MODE_MASK_NBITS,914	       link_ksettings->link_modes.advertising,915	       link_ksettings->base.autoneg,916	       link_ksettings->base.duplex);917 918	if (!(priv->mdev->dev->caps.flags2 &919	      MLX4_DEV_CAP_FLAG2_ETH_PROT_CTRL) ||920	    (link_ksettings->base.duplex == DUPLEX_HALF))921		return -EINVAL;922 923	memset(&ptys_reg, 0, sizeof(ptys_reg));924	ptys_reg.local_port = priv->port;925	ptys_reg.proto_mask = MLX4_PTYS_EN;926	ret = mlx4_ACCESS_PTYS_REG(priv->mdev->dev,927				   MLX4_ACCESS_REG_QUERY, &ptys_reg);928	if (ret) {929		en_warn(priv, "Failed to QUERY mlx4_ACCESS_PTYS_REG status(%x)\n",930			ret);931		return 0;932	}933 934	cur_autoneg = ptys_reg.flags & MLX4_PTYS_AN_DISABLE_ADMIN ?935				AUTONEG_DISABLE : AUTONEG_ENABLE;936 937	if (link_ksettings->base.autoneg == AUTONEG_DISABLE) {938		proto_admin = speed_set_ptys_admin(priv, speed,939						   ptys_reg.eth_proto_cap);940		if ((be32_to_cpu(proto_admin) &941		     (MLX4_PROT_MASK(MLX4_1000BASE_CX_SGMII) |942		      MLX4_PROT_MASK(MLX4_1000BASE_KX))) &&943		    (ptys_reg.flags & MLX4_PTYS_AN_DISABLE_CAP))944			ptys_reg.flags |= MLX4_PTYS_AN_DISABLE_ADMIN;945	} else {946		proto_admin = cpu_to_be32(ptys_adv);947		ptys_reg.flags &= ~MLX4_PTYS_AN_DISABLE_ADMIN;948	}949 950	proto_admin &= ptys_reg.eth_proto_cap;951	if (!proto_admin) {952		en_warn(priv, "Not supported link mode(s) requested, check supported link modes.\n");953		return -EINVAL; /* nothing to change due to bad input */954	}955 956	if ((proto_admin == ptys_reg.eth_proto_admin) &&957	    ((ptys_reg.flags & MLX4_PTYS_AN_DISABLE_CAP) &&958	     (link_ksettings->base.autoneg == cur_autoneg)))959		return 0; /* Nothing to change */960 961	en_dbg(DRV, priv, "mlx4_ACCESS_PTYS_REG SET: ptys_reg.eth_proto_admin = 0x%x\n",962	       be32_to_cpu(proto_admin));963 964	ptys_reg.eth_proto_admin = proto_admin;965	ret = mlx4_ACCESS_PTYS_REG(priv->mdev->dev, MLX4_ACCESS_REG_WRITE,966				   &ptys_reg);967	if (ret) {968		en_warn(priv, "Failed to write mlx4_ACCESS_PTYS_REG eth_proto_admin(0x%x) status(0x%x)",969			be32_to_cpu(ptys_reg.eth_proto_admin), ret);970		return ret;971	}972 973	mutex_lock(&priv->mdev->state_lock);974	if (priv->port_up) {975		en_warn(priv, "Port link mode changed, restarting port...\n");976		mlx4_en_stop_port(dev, 1);977		if (mlx4_en_start_port(dev))978			en_err(priv, "Failed restarting port %d\n", priv->port);979	}980	mutex_unlock(&priv->mdev->state_lock);981	return 0;982}983 984static int mlx4_en_get_coalesce(struct net_device *dev,985				struct ethtool_coalesce *coal,986				struct kernel_ethtool_coalesce *kernel_coal,987				struct netlink_ext_ack *extack)988{989	struct mlx4_en_priv *priv = netdev_priv(dev);990 991	coal->tx_coalesce_usecs = priv->tx_usecs;992	coal->tx_max_coalesced_frames = priv->tx_frames;993	coal->tx_max_coalesced_frames_irq = priv->tx_work_limit;994 995	coal->rx_coalesce_usecs = priv->rx_usecs;996	coal->rx_max_coalesced_frames = priv->rx_frames;997 998	coal->pkt_rate_low = priv->pkt_rate_low;999	coal->rx_coalesce_usecs_low = priv->rx_usecs_low;1000	coal->pkt_rate_high = priv->pkt_rate_high;1001	coal->rx_coalesce_usecs_high = priv->rx_usecs_high;1002	coal->rate_sample_interval = priv->sample_interval;1003	coal->use_adaptive_rx_coalesce = priv->adaptive_rx_coal;1004 1005	return 0;1006}1007 1008static int mlx4_en_set_coalesce(struct net_device *dev,1009				struct ethtool_coalesce *coal,1010				struct kernel_ethtool_coalesce *kernel_coal,1011				struct netlink_ext_ack *extack)1012{1013	struct mlx4_en_priv *priv = netdev_priv(dev);1014 1015	if (!coal->tx_max_coalesced_frames_irq)1016		return -EINVAL;1017 1018	if (coal->tx_coalesce_usecs > MLX4_EN_MAX_COAL_TIME ||1019	    coal->rx_coalesce_usecs > MLX4_EN_MAX_COAL_TIME ||1020	    coal->rx_coalesce_usecs_low > MLX4_EN_MAX_COAL_TIME ||1021	    coal->rx_coalesce_usecs_high > MLX4_EN_MAX_COAL_TIME) {1022		netdev_info(dev, "%s: maximum coalesce time supported is %d usecs\n",1023			    __func__, MLX4_EN_MAX_COAL_TIME);1024		return -ERANGE;1025	}1026 1027	if (coal->tx_max_coalesced_frames > MLX4_EN_MAX_COAL_PKTS ||1028	    coal->rx_max_coalesced_frames > MLX4_EN_MAX_COAL_PKTS) {1029		netdev_info(dev, "%s: maximum coalesced frames supported is %d\n",1030			    __func__, MLX4_EN_MAX_COAL_PKTS);1031		return -ERANGE;1032	}1033 1034	priv->rx_frames = (coal->rx_max_coalesced_frames ==1035			   MLX4_EN_AUTO_CONF) ?1036				MLX4_EN_RX_COAL_TARGET :1037				coal->rx_max_coalesced_frames;1038	priv->rx_usecs = (coal->rx_coalesce_usecs ==1039			  MLX4_EN_AUTO_CONF) ?1040				MLX4_EN_RX_COAL_TIME :1041				coal->rx_coalesce_usecs;1042 1043	/* Setting TX coalescing parameters */1044	if (coal->tx_coalesce_usecs != priv->tx_usecs ||1045	    coal->tx_max_coalesced_frames != priv->tx_frames) {1046		priv->tx_usecs = coal->tx_coalesce_usecs;1047		priv->tx_frames = coal->tx_max_coalesced_frames;1048	}1049 1050	/* Set adaptive coalescing params */1051	priv->pkt_rate_low = coal->pkt_rate_low;1052	priv->rx_usecs_low = coal->rx_coalesce_usecs_low;1053	priv->pkt_rate_high = coal->pkt_rate_high;1054	priv->rx_usecs_high = coal->rx_coalesce_usecs_high;1055	priv->sample_interval = coal->rate_sample_interval;1056	priv->adaptive_rx_coal = coal->use_adaptive_rx_coalesce;1057	priv->tx_work_limit = coal->tx_max_coalesced_frames_irq;1058 1059	return mlx4_en_moderation_update(priv);1060}1061 1062static int mlx4_en_set_pauseparam(struct net_device *dev,1063				struct ethtool_pauseparam *pause)1064{1065	struct mlx4_en_priv *priv = netdev_priv(dev);1066	struct mlx4_en_dev *mdev = priv->mdev;1067	u8 tx_pause, tx_ppp, rx_pause, rx_ppp;1068	int err;1069 1070	if (pause->autoneg)1071		return -EINVAL;1072 1073	tx_pause = !!(pause->tx_pause);1074	rx_pause = !!(pause->rx_pause);1075	rx_ppp = (tx_pause || rx_pause) ? 0 : priv->prof->rx_ppp;1076	tx_ppp = (tx_pause || rx_pause) ? 0 : priv->prof->tx_ppp;1077 1078	err = mlx4_SET_PORT_general(mdev->dev, priv->port,1079				    priv->rx_skb_size + ETH_FCS_LEN,1080				    tx_pause, tx_ppp, rx_pause, rx_ppp);1081	if (err) {1082		en_err(priv, "Failed setting pause params, err = %d\n", err);1083		return err;1084	}1085 1086	mlx4_en_update_pfc_stats_bitmap(mdev->dev, &priv->stats_bitmap,1087					rx_ppp, rx_pause, tx_ppp, tx_pause);1088 1089	priv->prof->tx_pause = tx_pause;1090	priv->prof->rx_pause = rx_pause;1091	priv->prof->tx_ppp = tx_ppp;1092	priv->prof->rx_ppp = rx_ppp;1093 1094	return err;1095}1096 1097static void mlx4_en_get_pause_stats(struct net_device *dev,1098				    struct ethtool_pause_stats *stats)1099{1100	struct mlx4_en_priv *priv = netdev_priv(dev);1101	struct bitmap_iterator it;1102 1103	bitmap_iterator_init(&it, priv->stats_bitmap.bitmap, NUM_ALL_STATS);1104 1105	spin_lock_bh(&priv->stats_lock);1106	if (test_bit(FLOW_PRIORITY_STATS_IDX_TX_FRAMES,1107		     priv->stats_bitmap.bitmap))1108		stats->tx_pause_frames = priv->tx_flowstats.tx_pause;1109	if (test_bit(FLOW_PRIORITY_STATS_IDX_RX_FRAMES,1110		     priv->stats_bitmap.bitmap))1111		stats->rx_pause_frames = priv->rx_flowstats.rx_pause;1112	spin_unlock_bh(&priv->stats_lock);1113}1114 1115static void mlx4_en_get_pauseparam(struct net_device *dev,1116				 struct ethtool_pauseparam *pause)1117{1118	struct mlx4_en_priv *priv = netdev_priv(dev);1119 1120	pause->tx_pause = priv->prof->tx_pause;1121	pause->rx_pause = priv->prof->rx_pause;1122}1123 1124static int mlx4_en_set_ringparam(struct net_device *dev,1125				 struct ethtool_ringparam *param,1126				 struct kernel_ethtool_ringparam *kernel_param,1127				 struct netlink_ext_ack *extack)1128{1129	struct mlx4_en_priv *priv = netdev_priv(dev);1130	struct mlx4_en_dev *mdev = priv->mdev;1131	struct mlx4_en_port_profile new_prof;1132	struct mlx4_en_priv *tmp;1133	u32 rx_size, tx_size;1134	int port_up = 0;1135	int err = 0;1136 1137	if (param->rx_jumbo_pending || param->rx_mini_pending)1138		return -EINVAL;1139 1140	if (param->rx_pending < MLX4_EN_MIN_RX_SIZE) {1141		en_warn(priv, "%s: rx_pending (%d) < min (%d)\n",1142			__func__, param->rx_pending,1143			MLX4_EN_MIN_RX_SIZE);1144		return -EINVAL;1145	}1146	if (param->tx_pending < MLX4_EN_MIN_TX_SIZE) {1147		en_warn(priv, "%s: tx_pending (%d) < min (%lu)\n",1148			__func__, param->tx_pending,1149			MLX4_EN_MIN_TX_SIZE);1150		return -EINVAL;1151	}1152 1153	rx_size = roundup_pow_of_two(param->rx_pending);1154	tx_size = roundup_pow_of_two(param->tx_pending);1155 1156	if (rx_size == (priv->port_up ? priv->rx_ring[0]->actual_size :1157					priv->rx_ring[0]->size) &&1158	    tx_size == priv->tx_ring[TX][0]->size)1159		return 0;1160 1161	tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);1162	if (!tmp)1163		return -ENOMEM;1164 1165	mutex_lock(&mdev->state_lock);1166	memcpy(&new_prof, priv->prof, sizeof(struct mlx4_en_port_profile));1167	new_prof.tx_ring_size = tx_size;1168	new_prof.rx_ring_size = rx_size;1169	err = mlx4_en_try_alloc_resources(priv, tmp, &new_prof, true);1170	if (err)1171		goto out;1172 1173	if (priv->port_up) {1174		port_up = 1;1175		mlx4_en_stop_port(dev, 1);1176	}1177 1178	mlx4_en_safe_replace_resources(priv, tmp);1179 1180	if (port_up) {1181		err = mlx4_en_start_port(dev);1182		if (err)1183			en_err(priv, "Failed starting port\n");1184	}1185 1186	err = mlx4_en_moderation_update(priv);1187out:1188	kfree(tmp);1189	mutex_unlock(&mdev->state_lock);1190	return err;1191}1192 1193static void mlx4_en_get_ringparam(struct net_device *dev,1194				  struct ethtool_ringparam *param,1195				  struct kernel_ethtool_ringparam *kernel_param,1196				  struct netlink_ext_ack *extack)1197{1198	struct mlx4_en_priv *priv = netdev_priv(dev);1199 1200	memset(param, 0, sizeof(*param));1201	param->rx_max_pending = MLX4_EN_MAX_RX_SIZE;1202	param->tx_max_pending = MLX4_EN_MAX_TX_SIZE;1203	param->rx_pending = priv->port_up ?1204		priv->rx_ring[0]->actual_size : priv->rx_ring[0]->size;1205	param->tx_pending = priv->tx_ring[TX][0]->size;1206}1207 1208static u32 mlx4_en_get_rxfh_indir_size(struct net_device *dev)1209{1210	struct mlx4_en_priv *priv = netdev_priv(dev);1211 1212	return rounddown_pow_of_two(priv->rx_ring_num);1213}1214 1215static u32 mlx4_en_get_rxfh_key_size(struct net_device *netdev)1216{1217	return MLX4_EN_RSS_KEY_SIZE;1218}1219 1220static int mlx4_en_check_rxfh_func(struct net_device *dev, u8 hfunc)1221{1222	struct mlx4_en_priv *priv = netdev_priv(dev);1223 1224	/* check if requested function is supported by the device */1225	if (hfunc == ETH_RSS_HASH_TOP) {1226		if (!(priv->mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_RSS_TOP))1227			return -EINVAL;1228		if (!(dev->features & NETIF_F_RXHASH))1229			en_warn(priv, "Toeplitz hash function should be used in conjunction with RX hashing for optimal performance\n");1230		return 0;1231	} else if (hfunc == ETH_RSS_HASH_XOR) {1232		if (!(priv->mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_RSS_XOR))1233			return -EINVAL;1234		if (dev->features & NETIF_F_RXHASH)1235			en_warn(priv, "Enabling both XOR Hash function and RX Hashing can limit RPS functionality\n");1236		return 0;1237	}1238 1239	return -EINVAL;1240}1241 1242static int mlx4_en_get_rxfh(struct net_device *dev,1243			    struct ethtool_rxfh_param *rxfh)1244{1245	struct mlx4_en_priv *priv = netdev_priv(dev);1246	u32 n = mlx4_en_get_rxfh_indir_size(dev);1247	u32 i, rss_rings;1248 1249	rss_rings = priv->prof->rss_rings ?: n;1250	rss_rings = rounddown_pow_of_two(rss_rings);1251 1252	for (i = 0; i < n; i++) {1253		if (!rxfh->indir)1254			break;1255		rxfh->indir[i] = i % rss_rings;1256	}1257	if (rxfh->key)1258		memcpy(rxfh->key, priv->rss_key, MLX4_EN_RSS_KEY_SIZE);1259	rxfh->hfunc = priv->rss_hash_fn;1260	return 0;1261}1262 1263static int mlx4_en_set_rxfh(struct net_device *dev,1264			    struct ethtool_rxfh_param *rxfh,1265			    struct netlink_ext_ack *extack)1266{1267	struct mlx4_en_priv *priv = netdev_priv(dev);1268	u32 n = mlx4_en_get_rxfh_indir_size(dev);1269	struct mlx4_en_dev *mdev = priv->mdev;1270	int port_up = 0;1271	int err = 0;1272	int i;1273	int rss_rings = 0;1274 1275	/* Calculate RSS table size and make sure flows are spread evenly1276	 * between rings1277	 */1278	for (i = 0; i < n; i++) {1279		if (!rxfh->indir)1280			break;1281		if (i > 0 && !rxfh->indir[i] && !rss_rings)1282			rss_rings = i;1283 1284		if (rxfh->indir[i] != (i % (rss_rings ?: n)))1285			return -EINVAL;1286	}1287 1288	if (!rss_rings)1289		rss_rings = n;1290 1291	/* RSS table size must be an order of 2 */1292	if (!is_power_of_2(rss_rings))1293		return -EINVAL;1294 1295	if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE) {1296		err = mlx4_en_check_rxfh_func(dev, rxfh->hfunc);1297		if (err)1298			return err;1299	}1300 1301	mutex_lock(&mdev->state_lock);1302	if (priv->port_up) {1303		port_up = 1;1304		mlx4_en_stop_port(dev, 1);1305	}1306 1307	if (rxfh->indir)1308		priv->prof->rss_rings = rss_rings;1309	if (rxfh->key)1310		memcpy(priv->rss_key, rxfh->key, MLX4_EN_RSS_KEY_SIZE);1311	if (rxfh->hfunc !=  ETH_RSS_HASH_NO_CHANGE)1312		priv->rss_hash_fn = rxfh->hfunc;1313 1314	if (port_up) {1315		err = mlx4_en_start_port(dev);1316		if (err)1317			en_err(priv, "Failed starting port\n");1318	}1319 1320	mutex_unlock(&mdev->state_lock);1321	return err;1322}1323 1324#define all_zeros_or_all_ones(field)		\1325	((field) == 0 || (field) == (__force typeof(field))-1)1326 1327static int mlx4_en_validate_flow(struct net_device *dev,1328				 struct ethtool_rxnfc *cmd)1329{1330	struct ethtool_usrip4_spec *l3_mask;1331	struct ethtool_tcpip4_spec *l4_mask;1332	struct ethhdr *eth_mask;1333 1334	if (cmd->fs.location >= MAX_NUM_OF_FS_RULES)1335		return -EINVAL;1336 1337	if (cmd->fs.flow_type & FLOW_MAC_EXT) {1338		/* dest mac mask must be ff:ff:ff:ff:ff:ff */1339		if (!is_broadcast_ether_addr(cmd->fs.m_ext.h_dest))1340			return -EINVAL;1341	}1342 1343	switch (cmd->fs.flow_type & ~(FLOW_EXT | FLOW_MAC_EXT)) {1344	case TCP_V4_FLOW:1345	case UDP_V4_FLOW:1346		if (cmd->fs.m_u.tcp_ip4_spec.tos)1347			return -EINVAL;1348		l4_mask = &cmd->fs.m_u.tcp_ip4_spec;1349		/* don't allow mask which isn't all 0 or 1 */1350		if (!all_zeros_or_all_ones(l4_mask->ip4src) ||1351		    !all_zeros_or_all_ones(l4_mask->ip4dst) ||1352		    !all_zeros_or_all_ones(l4_mask->psrc) ||1353		    !all_zeros_or_all_ones(l4_mask->pdst))1354			return -EINVAL;1355		break;1356	case IP_USER_FLOW:1357		l3_mask = &cmd->fs.m_u.usr_ip4_spec;1358		if (l3_mask->l4_4_bytes || l3_mask->tos || l3_mask->proto ||1359		    cmd->fs.h_u.usr_ip4_spec.ip_ver != ETH_RX_NFC_IP4 ||1360		    (!l3_mask->ip4src && !l3_mask->ip4dst) ||1361		    !all_zeros_or_all_ones(l3_mask->ip4src) ||1362		    !all_zeros_or_all_ones(l3_mask->ip4dst))1363			return -EINVAL;1364		break;1365	case ETHER_FLOW:1366		eth_mask = &cmd->fs.m_u.ether_spec;1367		/* source mac mask must not be set */1368		if (!is_zero_ether_addr(eth_mask->h_source))1369			return -EINVAL;1370 1371		/* dest mac mask must be ff:ff:ff:ff:ff:ff */1372		if (!is_broadcast_ether_addr(eth_mask->h_dest))1373			return -EINVAL;1374 1375		if (!all_zeros_or_all_ones(eth_mask->h_proto))1376			return -EINVAL;1377		break;1378	default:1379		return -EINVAL;1380	}1381 1382	if ((cmd->fs.flow_type & FLOW_EXT)) {1383		if (cmd->fs.m_ext.vlan_etype ||1384		    !((cmd->fs.m_ext.vlan_tci & cpu_to_be16(VLAN_VID_MASK)) ==1385		      0 ||1386		      (cmd->fs.m_ext.vlan_tci & cpu_to_be16(VLAN_VID_MASK)) ==1387		      cpu_to_be16(VLAN_VID_MASK)))1388			return -EINVAL;1389 1390		if (cmd->fs.m_ext.vlan_tci) {1391			if (be16_to_cpu(cmd->fs.h_ext.vlan_tci) >= VLAN_N_VID)1392				return -EINVAL;1393 1394		}1395	}1396 1397	return 0;1398}1399 1400static int mlx4_en_ethtool_add_mac_rule(struct ethtool_rxnfc *cmd,1401					struct list_head *rule_list_h,1402					struct mlx4_spec_list *spec_l2,1403					unsigned char *mac)1404{1405	__be64 mac_msk = cpu_to_be64(MLX4_MAC_MASK << 16);1406 1407	spec_l2->id = MLX4_NET_TRANS_RULE_ID_ETH;1408	memcpy(spec_l2->eth.dst_mac_msk, &mac_msk, ETH_ALEN);1409	memcpy(spec_l2->eth.dst_mac, mac, ETH_ALEN);1410 1411	if ((cmd->fs.flow_type & FLOW_EXT) &&1412	    (cmd->fs.m_ext.vlan_tci & cpu_to_be16(VLAN_VID_MASK))) {1413		spec_l2->eth.vlan_id = cmd->fs.h_ext.vlan_tci;1414		spec_l2->eth.vlan_id_msk = cpu_to_be16(VLAN_VID_MASK);1415	}1416 1417	list_add_tail(&spec_l2->list, rule_list_h);1418 1419	return 0;1420}1421 1422static int mlx4_en_ethtool_add_mac_rule_by_ipv4(struct mlx4_en_priv *priv,1423						struct ethtool_rxnfc *cmd,1424						struct list_head *rule_list_h,1425						struct mlx4_spec_list *spec_l2,1426						__be32 ipv4_dst)1427{1428#ifdef CONFIG_INET1429	unsigned char mac[ETH_ALEN];1430 1431	if (!ipv4_is_multicast(ipv4_dst)) {1432		if (cmd->fs.flow_type & FLOW_MAC_EXT)1433			memcpy(&mac, cmd->fs.h_ext.h_dest, ETH_ALEN);1434		else1435			memcpy(&mac, priv->dev->dev_addr, ETH_ALEN);1436	} else {1437		ip_eth_mc_map(ipv4_dst, mac);1438	}1439 1440	return mlx4_en_ethtool_add_mac_rule(cmd, rule_list_h, spec_l2, &mac[0]);1441#else1442	return -EINVAL;1443#endif1444}1445 1446static int add_ip_rule(struct mlx4_en_priv *priv,1447		       struct ethtool_rxnfc *cmd,1448		       struct list_head *list_h)1449{1450	int err;1451	struct mlx4_spec_list *spec_l2;1452	struct mlx4_spec_list *spec_l3;1453	struct ethtool_usrip4_spec *l3_mask = &cmd->fs.m_u.usr_ip4_spec;1454 1455	spec_l3 = kzalloc(sizeof(*spec_l3), GFP_KERNEL);1456	spec_l2 = kzalloc(sizeof(*spec_l2), GFP_KERNEL);1457	if (!spec_l2 || !spec_l3) {1458		err = -ENOMEM;1459		goto free_spec;1460	}1461 1462	err = mlx4_en_ethtool_add_mac_rule_by_ipv4(priv, cmd, list_h, spec_l2,1463						   cmd->fs.h_u.1464						   usr_ip4_spec.ip4dst);1465	if (err)1466		goto free_spec;1467	spec_l3->id = MLX4_NET_TRANS_RULE_ID_IPV4;1468	spec_l3->ipv4.src_ip = cmd->fs.h_u.usr_ip4_spec.ip4src;1469	if (l3_mask->ip4src)1470		spec_l3->ipv4.src_ip_msk = EN_ETHTOOL_WORD_MASK;1471	spec_l3->ipv4.dst_ip = cmd->fs.h_u.usr_ip4_spec.ip4dst;1472	if (l3_mask->ip4dst)1473		spec_l3->ipv4.dst_ip_msk = EN_ETHTOOL_WORD_MASK;1474	list_add_tail(&spec_l3->list, list_h);1475 1476	return 0;1477 1478free_spec:1479	kfree(spec_l2);1480	kfree(spec_l3);1481	return err;1482}1483 1484static int add_tcp_udp_rule(struct mlx4_en_priv *priv,1485			     struct ethtool_rxnfc *cmd,1486			     struct list_head *list_h, int proto)1487{1488	int err;1489	struct mlx4_spec_list *spec_l2;1490	struct mlx4_spec_list *spec_l3;1491	struct mlx4_spec_list *spec_l4;1492	struct ethtool_tcpip4_spec *l4_mask = &cmd->fs.m_u.tcp_ip4_spec;1493 1494	spec_l2 = kzalloc(sizeof(*spec_l2), GFP_KERNEL);1495	spec_l3 = kzalloc(sizeof(*spec_l3), GFP_KERNEL);1496	spec_l4 = kzalloc(sizeof(*spec_l4), GFP_KERNEL);1497	if (!spec_l2 || !spec_l3 || !spec_l4) {1498		err = -ENOMEM;1499		goto free_spec;1500	}1501 1502	spec_l3->id = MLX4_NET_TRANS_RULE_ID_IPV4;1503 1504	if (proto == TCP_V4_FLOW) {1505		err = mlx4_en_ethtool_add_mac_rule_by_ipv4(priv, cmd, list_h,1506							   spec_l2,1507							   cmd->fs.h_u.1508							   tcp_ip4_spec.ip4dst);1509		if (err)1510			goto free_spec;1511		spec_l4->id = MLX4_NET_TRANS_RULE_ID_TCP;1512		spec_l3->ipv4.src_ip = cmd->fs.h_u.tcp_ip4_spec.ip4src;1513		spec_l3->ipv4.dst_ip = cmd->fs.h_u.tcp_ip4_spec.ip4dst;1514		spec_l4->tcp_udp.src_port = cmd->fs.h_u.tcp_ip4_spec.psrc;1515		spec_l4->tcp_udp.dst_port = cmd->fs.h_u.tcp_ip4_spec.pdst;1516	} else {1517		err = mlx4_en_ethtool_add_mac_rule_by_ipv4(priv, cmd, list_h,1518							   spec_l2,1519							   cmd->fs.h_u.1520							   udp_ip4_spec.ip4dst);1521		if (err)1522			goto free_spec;1523		spec_l4->id = MLX4_NET_TRANS_RULE_ID_UDP;1524		spec_l3->ipv4.src_ip = cmd->fs.h_u.udp_ip4_spec.ip4src;1525		spec_l3->ipv4.dst_ip = cmd->fs.h_u.udp_ip4_spec.ip4dst;1526		spec_l4->tcp_udp.src_port = cmd->fs.h_u.udp_ip4_spec.psrc;1527		spec_l4->tcp_udp.dst_port = cmd->fs.h_u.udp_ip4_spec.pdst;1528	}1529 1530	if (l4_mask->ip4src)1531		spec_l3->ipv4.src_ip_msk = EN_ETHTOOL_WORD_MASK;1532	if (l4_mask->ip4dst)1533		spec_l3->ipv4.dst_ip_msk = EN_ETHTOOL_WORD_MASK;1534 1535	if (l4_mask->psrc)1536		spec_l4->tcp_udp.src_port_msk = EN_ETHTOOL_SHORT_MASK;1537	if (l4_mask->pdst)1538		spec_l4->tcp_udp.dst_port_msk = EN_ETHTOOL_SHORT_MASK;1539 1540	list_add_tail(&spec_l3->list, list_h);1541	list_add_tail(&spec_l4->list, list_h);1542 1543	return 0;1544 1545free_spec:1546	kfree(spec_l2);1547	kfree(spec_l3);1548	kfree(spec_l4);1549	return err;1550}1551 1552static int mlx4_en_ethtool_to_net_trans_rule(struct net_device *dev,1553					     struct ethtool_rxnfc *cmd,1554					     struct list_head *rule_list_h)1555{1556	int err;1557	struct ethhdr *eth_spec;1558	struct mlx4_spec_list *spec_l2;1559	struct mlx4_en_priv *priv = netdev_priv(dev);1560 1561	err = mlx4_en_validate_flow(dev, cmd);1562	if (err)1563		return err;1564 1565	switch (cmd->fs.flow_type & ~(FLOW_EXT | FLOW_MAC_EXT)) {1566	case ETHER_FLOW:1567		spec_l2 = kzalloc(sizeof(*spec_l2), GFP_KERNEL);1568		if (!spec_l2)1569			return -ENOMEM;1570 1571		eth_spec = &cmd->fs.h_u.ether_spec;1572		mlx4_en_ethtool_add_mac_rule(cmd, rule_list_h, spec_l2,1573					     &eth_spec->h_dest[0]);1574		spec_l2->eth.ether_type = eth_spec->h_proto;1575		if (eth_spec->h_proto)1576			spec_l2->eth.ether_type_enable = 1;1577		break;1578	case IP_USER_FLOW:1579		err = add_ip_rule(priv, cmd, rule_list_h);1580		break;1581	case TCP_V4_FLOW:1582		err = add_tcp_udp_rule(priv, cmd, rule_list_h, TCP_V4_FLOW);1583		break;1584	case UDP_V4_FLOW:1585		err = add_tcp_udp_rule(priv, cmd, rule_list_h, UDP_V4_FLOW);1586		break;1587	}1588 1589	return err;1590}1591 1592static int mlx4_en_flow_replace(struct net_device *dev,1593				struct ethtool_rxnfc *cmd)1594{1595	int err;1596	struct mlx4_en_priv *priv = netdev_priv(dev);1597	struct ethtool_flow_id *loc_rule;1598	struct mlx4_spec_list *spec, *tmp_spec;1599	u32 qpn;1600	u64 reg_id;1601 1602	struct mlx4_net_trans_rule rule = {1603		.queue_mode = MLX4_NET_TRANS_Q_FIFO,1604		.exclusive = 0,1605		.allow_loopback = 1,1606		.promisc_mode = MLX4_FS_REGULAR,1607	};1608 1609	rule.port = priv->port;1610	rule.priority = MLX4_DOMAIN_ETHTOOL | cmd->fs.location;1611	INIT_LIST_HEAD(&rule.list);1612 1613	/* Allow direct QP attaches if the EN_ETHTOOL_QP_ATTACH flag is set */1614	if (cmd->fs.ring_cookie == RX_CLS_FLOW_DISC)1615		qpn = priv->drop_qp.qpn;1616	else if (cmd->fs.ring_cookie & EN_ETHTOOL_QP_ATTACH) {1617		qpn = cmd->fs.ring_cookie & (EN_ETHTOOL_QP_ATTACH - 1);1618	} else {1619		if (cmd->fs.ring_cookie >= priv->rx_ring_num) {1620			en_warn(priv, "rxnfc: RX ring (%llu) doesn't exist\n",1621				cmd->fs.ring_cookie);1622			return -EINVAL;1623		}1624		qpn = priv->rss_map.qps[cmd->fs.ring_cookie].qpn;1625		if (!qpn) {1626			en_warn(priv, "rxnfc: RX ring (%llu) is inactive\n",1627				cmd->fs.ring_cookie);1628			return -EINVAL;1629		}1630	}1631	rule.qpn = qpn;1632	err = mlx4_en_ethtool_to_net_trans_rule(dev, cmd, &rule.list);1633	if (err)1634		goto out_free_list;1635 1636	loc_rule = &priv->ethtool_rules[cmd->fs.location];1637	if (loc_rule->id) {1638		err = mlx4_flow_detach(priv->mdev->dev, loc_rule->id);1639		if (err) {1640			en_err(priv, "Fail to detach network rule at location %d. registration id = %llx\n",1641			       cmd->fs.location, loc_rule->id);1642			goto out_free_list;1643		}1644		loc_rule->id = 0;1645		memset(&loc_rule->flow_spec, 0,1646		       sizeof(struct ethtool_rx_flow_spec));1647		list_del(&loc_rule->list);1648	}1649	err = mlx4_flow_attach(priv->mdev->dev, &rule, &reg_id);1650	if (err) {1651		en_err(priv, "Fail to attach network rule at location %d\n",1652		       cmd->fs.location);1653		goto out_free_list;1654	}1655	loc_rule->id = reg_id;1656	memcpy(&loc_rule->flow_spec, &cmd->fs,1657	       sizeof(struct ethtool_rx_flow_spec));1658	list_add_tail(&loc_rule->list, &priv->ethtool_list);1659 1660out_free_list:1661	list_for_each_entry_safe(spec, tmp_spec, &rule.list, list) {1662		list_del(&spec->list);1663		kfree(spec);1664	}1665	return err;1666}1667 1668static int mlx4_en_flow_detach(struct net_device *dev,1669			       struct ethtool_rxnfc *cmd)1670{1671	int err = 0;1672	struct ethtool_flow_id *rule;1673	struct mlx4_en_priv *priv = netdev_priv(dev);1674 1675	if (cmd->fs.location >= MAX_NUM_OF_FS_RULES)1676		return -EINVAL;1677 1678	rule = &priv->ethtool_rules[cmd->fs.location];1679	if (!rule->id) {1680		err =  -ENOENT;1681		goto out;1682	}1683 1684	err = mlx4_flow_detach(priv->mdev->dev, rule->id);1685	if (err) {1686		en_err(priv, "Fail to detach network rule at location %d. registration id = 0x%llx\n",1687		       cmd->fs.location, rule->id);1688		goto out;1689	}1690	rule->id = 0;1691	memset(&rule->flow_spec, 0, sizeof(struct ethtool_rx_flow_spec));1692	list_del(&rule->list);1693out:1694	return err;1695 1696}1697 1698static int mlx4_en_get_flow(struct net_device *dev, struct ethtool_rxnfc *cmd,1699			    int loc)1700{1701	int err = 0;1702	struct ethtool_flow_id *rule;1703	struct mlx4_en_priv *priv = netdev_priv(dev);1704 1705	if (loc < 0 || loc >= MAX_NUM_OF_FS_RULES)1706		return -EINVAL;1707 1708	rule = &priv->ethtool_rules[loc];1709	if (rule->id)1710		memcpy(&cmd->fs, &rule->flow_spec,1711		       sizeof(struct ethtool_rx_flow_spec));1712	else1713		err = -ENOENT;1714 1715	return err;1716}1717 1718static int mlx4_en_get_num_flows(struct mlx4_en_priv *priv)1719{1720 1721	int i, res = 0;1722	for (i = 0; i < MAX_NUM_OF_FS_RULES; i++) {1723		if (priv->ethtool_rules[i].id)1724			res++;1725	}1726	return res;1727 1728}1729 1730static int mlx4_en_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,1731			     u32 *rule_locs)1732{1733	struct mlx4_en_priv *priv = netdev_priv(dev);1734	struct mlx4_en_dev *mdev = priv->mdev;1735	int err = 0;1736	int i = 0, priority = 0;1737 1738	if ((cmd->cmd == ETHTOOL_GRXCLSRLCNT ||1739	     cmd->cmd == ETHTOOL_GRXCLSRULE ||1740	     cmd->cmd == ETHTOOL_GRXCLSRLALL) &&1741	    (mdev->dev->caps.steering_mode !=1742	     MLX4_STEERING_MODE_DEVICE_MANAGED || !priv->port_up))1743		return -EINVAL;1744 1745	switch (cmd->cmd) {1746	case ETHTOOL_GRXRINGS:1747		cmd->data = priv->rx_ring_num;1748		break;1749	case ETHTOOL_GRXCLSRLCNT:1750		cmd->rule_cnt = mlx4_en_get_num_flows(priv);1751		break;1752	case ETHTOOL_GRXCLSRULE:1753		err = mlx4_en_get_flow(dev, cmd, cmd->fs.location);1754		break;1755	case ETHTOOL_GRXCLSRLALL:1756		cmd->data = MAX_NUM_OF_FS_RULES;1757		while ((!err || err == -ENOENT) && priority < cmd->rule_cnt) {1758			err = mlx4_en_get_flow(dev, cmd, i);1759			if (!err)1760				rule_locs[priority++] = i;1761			i++;1762		}1763		err = 0;1764		break;1765	default:1766		err = -EOPNOTSUPP;1767		break;1768	}1769 1770	return err;1771}1772 1773static int mlx4_en_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)1774{1775	int err = 0;1776	struct mlx4_en_priv *priv = netdev_priv(dev);1777	struct mlx4_en_dev *mdev = priv->mdev;1778 1779	if (mdev->dev->caps.steering_mode !=1780	    MLX4_STEERING_MODE_DEVICE_MANAGED || !priv->port_up)1781		return -EINVAL;1782 1783	switch (cmd->cmd) {1784	case ETHTOOL_SRXCLSRLINS:1785		err = mlx4_en_flow_replace(dev, cmd);1786		break;1787	case ETHTOOL_SRXCLSRLDEL:1788		err = mlx4_en_flow_detach(dev, cmd);1789		break;1790	default:1791		en_warn(priv, "Unsupported ethtool command. (%d)\n", cmd->cmd);1792		return -EINVAL;1793	}1794 1795	return err;1796}1797 1798static int mlx4_en_get_max_num_rx_rings(struct net_device *dev)1799{1800	return min_t(int, num_online_cpus(), MAX_RX_RINGS);1801}1802 1803static void mlx4_en_get_channels(struct net_device *dev,1804				 struct ethtool_channels *channel)1805{1806	struct mlx4_en_priv *priv = netdev_priv(dev);1807 1808	channel->max_rx = mlx4_en_get_max_num_rx_rings(dev);1809	channel->max_tx = priv->mdev->profile.max_num_tx_rings_p_up;1810 1811	channel->rx_count = priv->rx_ring_num;1812	channel->tx_count = priv->tx_ring_num[TX] /1813			    priv->prof->num_up;1814}1815 1816static int mlx4_en_set_channels(struct net_device *dev,1817				struct ethtool_channels *channel)1818{1819	struct mlx4_en_priv *priv = netdev_priv(dev);1820	struct mlx4_en_dev *mdev = priv->mdev;1821	struct mlx4_en_port_profile new_prof;1822	struct mlx4_en_priv *tmp;1823	int total_tx_count;1824	int port_up = 0;1825	int xdp_count;1826	int err = 0;1827	u8 up;1828 1829	if (!channel->tx_count || !channel->rx_count)1830		return -EINVAL;1831 1832	tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);1833	if (!tmp)1834		return -ENOMEM;1835 1836	mutex_lock(&mdev->state_lock);1837	xdp_count = priv->tx_ring_num[TX_XDP] ? channel->rx_count : 0;1838	total_tx_count = channel->tx_count * priv->prof->num_up + xdp_count;1839	if (total_tx_count > MAX_TX_RINGS) {1840		err = -EINVAL;1841		en_err(priv,1842		       "Total number of TX and XDP rings (%d) exceeds the maximum supported (%d)\n",1843		       total_tx_count, MAX_TX_RINGS);1844		goto out;1845	}1846 1847	memcpy(&new_prof, priv->prof, sizeof(struct mlx4_en_port_profile));1848	new_prof.num_tx_rings_p_up = channel->tx_count;1849	new_prof.tx_ring_num[TX] = channel->tx_count * priv->prof->num_up;1850	new_prof.tx_ring_num[TX_XDP] = xdp_count;1851	new_prof.rx_ring_num = channel->rx_count;1852 1853	err = mlx4_en_try_alloc_resources(priv, tmp, &new_prof, true);1854	if (err)1855		goto out;1856 1857	if (priv->port_up) {1858		port_up = 1;1859		mlx4_en_stop_port(dev, 1);1860	}1861 1862	mlx4_en_safe_replace_resources(priv, tmp);1863 1864	netif_set_real_num_rx_queues(dev, priv->rx_ring_num);1865 1866	up = (priv->prof->num_up == MLX4_EN_NUM_UP_LOW) ?1867				    0 : priv->prof->num_up;1868	mlx4_en_setup_tc(dev, up);1869 1870	en_warn(priv, "Using %d TX rings\n", priv->tx_ring_num[TX]);1871	en_warn(priv, "Using %d RX rings\n", priv->rx_ring_num);1872 1873	if (port_up) {1874		err = mlx4_en_start_port(dev);1875		if (err)1876			en_err(priv, "Failed starting port\n");1877	}1878 1879	err = mlx4_en_moderation_update(priv);1880out:1881	mutex_unlock(&mdev->state_lock);1882	kfree(tmp);1883	return err;1884}1885 1886static int mlx4_en_get_ts_info(struct net_device *dev,1887			       struct kernel_ethtool_ts_info *info)1888{1889	struct mlx4_en_priv *priv = netdev_priv(dev);1890	struct mlx4_en_dev *mdev = priv->mdev;1891	int ret;1892 1893	ret = ethtool_op_get_ts_info(dev, info);1894	if (ret)1895		return ret;1896 1897	if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_TS) {1898		info->so_timestamping |=1899			SOF_TIMESTAMPING_TX_HARDWARE |1900			SOF_TIMESTAMPING_RX_HARDWARE |1901			SOF_TIMESTAMPING_RAW_HARDWARE;1902 1903		info->tx_types =1904			(1 << HWTSTAMP_TX_OFF) |1905			(1 << HWTSTAMP_TX_ON);1906 1907		info->rx_filters =1908			(1 << HWTSTAMP_FILTER_NONE) |1909			(1 << HWTSTAMP_FILTER_ALL);1910 1911		if (mdev->ptp_clock)1912			info->phc_index = ptp_clock_index(mdev->ptp_clock);1913	}1914 1915	return ret;1916}1917 1918static int mlx4_en_set_priv_flags(struct net_device *dev, u32 flags)1919{1920	struct mlx4_en_priv *priv = netdev_priv(dev);1921	struct mlx4_en_dev *mdev = priv->mdev;1922	bool bf_enabled_new = !!(flags & MLX4_EN_PRIV_FLAGS_BLUEFLAME);1923	bool bf_enabled_old = !!(priv->pflags & MLX4_EN_PRIV_FLAGS_BLUEFLAME);1924	bool phv_enabled_new = !!(flags & MLX4_EN_PRIV_FLAGS_PHV);1925	bool phv_enabled_old = !!(priv->pflags & MLX4_EN_PRIV_FLAGS_PHV);1926	int i;1927	int ret = 0;1928 1929	if (bf_enabled_new != bf_enabled_old) {1930		int t;1931 1932		if (bf_enabled_new) {1933			bool bf_supported = true;1934 1935			for (t = 0; t < MLX4_EN_NUM_TX_TYPES; t++)1936				for (i = 0; i < priv->tx_ring_num[t]; i++)1937					bf_supported &=1938						priv->tx_ring[t][i]->bf_alloced;1939 1940			if (!bf_supported) {1941				en_err(priv, "BlueFlame is not supported\n");1942				return -EINVAL;1943			}1944 1945			priv->pflags |= MLX4_EN_PRIV_FLAGS_BLUEFLAME;1946		} else {1947			priv->pflags &= ~MLX4_EN_PRIV_FLAGS_BLUEFLAME;1948		}1949 1950		for (t = 0; t < MLX4_EN_NUM_TX_TYPES; t++)1951			for (i = 0; i < priv->tx_ring_num[t]; i++)1952				priv->tx_ring[t][i]->bf_enabled =1953					bf_enabled_new;1954 1955		en_info(priv, "BlueFlame %s\n",1956			bf_enabled_new ?  "Enabled" : "Disabled");1957	}1958 1959	if (phv_enabled_new != phv_enabled_old) {1960		ret = set_phv_bit(mdev->dev, priv->port, (int)phv_enabled_new);1961		if (ret)1962			return ret;1963		else if (phv_enabled_new)1964			priv->pflags |= MLX4_EN_PRIV_FLAGS_PHV;1965		else1966			priv->pflags &= ~MLX4_EN_PRIV_FLAGS_PHV;1967		en_info(priv, "PHV bit %s\n",1968			phv_enabled_new ?  "Enabled" : "Disabled");1969	}1970	return 0;1971}1972 1973static u32 mlx4_en_get_priv_flags(struct net_device *dev)1974{1975	struct mlx4_en_priv *priv = netdev_priv(dev);1976 1977	return priv->pflags;1978}1979 1980static int mlx4_en_get_tunable(struct net_device *dev,1981			       const struct ethtool_tunable *tuna,1982			       void *data)1983{1984	const struct mlx4_en_priv *priv = netdev_priv(dev);1985	int ret = 0;1986 1987	switch (tuna->id) {1988	case ETHTOOL_TX_COPYBREAK:1989		*(u32 *)data = priv->prof->inline_thold;1990		break;1991	default:1992		ret = -EINVAL;1993		break;1994	}1995 1996	return ret;1997}1998 1999static int mlx4_en_set_tunable(struct net_device *dev,2000			       const struct ethtool_tunable *tuna,2001			       const void *data)2002{2003	struct mlx4_en_priv *priv = netdev_priv(dev);2004	int val, ret = 0;2005 2006	switch (tuna->id) {2007	case ETHTOOL_TX_COPYBREAK:2008		val = *(u32 *)data;2009		if (val < MIN_PKT_LEN || val > MAX_INLINE)2010			ret = -EINVAL;2011		else2012			priv->prof->inline_thold = val;2013		break;2014	default:2015		ret = -EINVAL;2016		break;2017	}2018 2019	return ret;2020}2021 2022static int mlx4_en_get_module_info(struct net_device *dev,2023				   struct ethtool_modinfo *modinfo)2024{2025	struct mlx4_en_priv *priv = netdev_priv(dev);2026	struct mlx4_en_dev *mdev = priv->mdev;2027	int ret;2028	u8 data[4];2029 2030	/* Read first 2 bytes to get Module & REV ID */2031	ret = mlx4_get_module_info(mdev->dev, priv->port,2032				   0/*offset*/, 2/*size*/, data);2033	if (ret < 2)2034		return -EIO;2035 2036	switch (data[0] /* identifier */) {2037	case MLX4_MODULE_ID_QSFP:2038		modinfo->type = ETH_MODULE_SFF_8436;2039		modinfo->eeprom_len = ETH_MODULE_SFF_8436_MAX_LEN;2040		break;2041	case MLX4_MODULE_ID_QSFP_PLUS:2042		if (data[1] >= 0x3) { /* revision id */2043			modinfo->type = ETH_MODULE_SFF_8636;2044			modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;2045		} else {2046			modinfo->type = ETH_MODULE_SFF_8436;2047			modinfo->eeprom_len = ETH_MODULE_SFF_8436_MAX_LEN;2048		}2049		break;2050	case MLX4_MODULE_ID_QSFP28:2051		modinfo->type = ETH_MODULE_SFF_8636;2052		modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;2053		break;2054	case MLX4_MODULE_ID_SFP:2055		modinfo->type = ETH_MODULE_SFF_8472;2056		modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;2057		break;2058	default:2059		return -EINVAL;2060	}2061 2062	return 0;2063}2064 2065static int mlx4_en_get_module_eeprom(struct net_device *dev,2066				     struct ethtool_eeprom *ee,2067				     u8 *data)2068{2069	struct mlx4_en_priv *priv = netdev_priv(dev);2070	struct mlx4_en_dev *mdev = priv->mdev;2071	int offset = ee->offset;2072	int i = 0, ret;2073 2074	if (ee->len == 0)2075		return -EINVAL;2076 2077	memset(data, 0, ee->len);2078 2079	while (i < ee->len) {2080		en_dbg(DRV, priv,2081		       "mlx4_get_module_info i(%d) offset(%d) len(%d)\n",2082		       i, offset, ee->len - i);2083 2084		ret = mlx4_get_module_info(mdev->dev, priv->port,2085					   offset, ee->len - i, data + i);2086 2087		if (!ret) /* Done reading */2088			return 0;2089 2090		if (ret < 0) {2091			en_err(priv,2092			       "mlx4_get_module_info i(%d) offset(%d) bytes_to_read(%d) - FAILED (0x%x)\n",2093			       i, offset, ee->len - i, ret);2094			return ret;2095		}2096 2097		i += ret;2098		offset += ret;2099	}2100	return 0;2101}2102 2103static int mlx4_en_set_phys_id(struct net_device *dev,2104			       enum ethtool_phys_id_state state)2105{2106	int err;2107	u16 beacon_duration;2108	struct mlx4_en_priv *priv = netdev_priv(dev);2109	struct mlx4_en_dev *mdev = priv->mdev;2110 2111	if (!(mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_PORT_BEACON))2112		return -EOPNOTSUPP;2113 2114	switch (state) {2115	case ETHTOOL_ID_ACTIVE:2116		beacon_duration = PORT_BEACON_MAX_LIMIT;2117		break;2118	case ETHTOOL_ID_INACTIVE:2119		beacon_duration = 0;2120		break;2121	default:2122		return -EOPNOTSUPP;2123	}2124 2125	err = mlx4_SET_PORT_BEACON(mdev->dev, priv->port, beacon_duration);2126	return err;2127}2128 2129const struct ethtool_ops mlx4_en_ethtool_ops = {2130	.supported_coalesce_params = ETHTOOL_COALESCE_USECS |2131				     ETHTOOL_COALESCE_MAX_FRAMES |2132				     ETHTOOL_COALESCE_TX_MAX_FRAMES_IRQ |2133				     ETHTOOL_COALESCE_PKT_RATE_RX_USECS,2134	.get_drvinfo = mlx4_en_get_drvinfo,2135	.get_link_ksettings = mlx4_en_get_link_ksettings,2136	.set_link_ksettings = mlx4_en_set_link_ksettings,2137	.get_link = ethtool_op_get_link,2138	.get_strings = mlx4_en_get_strings,2139	.get_sset_count = mlx4_en_get_sset_count,2140	.get_ethtool_stats = mlx4_en_get_ethtool_stats,2141	.self_test = mlx4_en_self_test,2142	.set_phys_id = mlx4_en_set_phys_id,2143	.get_wol = mlx4_en_get_wol,2144	.set_wol = mlx4_en_set_wol,2145	.get_msglevel = mlx4_en_get_msglevel,2146	.set_msglevel = mlx4_en_set_msglevel,2147	.get_coalesce = mlx4_en_get_coalesce,2148	.set_coalesce = mlx4_en_set_coalesce,2149	.get_pause_stats = mlx4_en_get_pause_stats,2150	.get_pauseparam = mlx4_en_get_pauseparam,2151	.set_pauseparam = mlx4_en_set_pauseparam,2152	.get_ringparam = mlx4_en_get_ringparam,2153	.set_ringparam = mlx4_en_set_ringparam,2154	.get_rxnfc = mlx4_en_get_rxnfc,2155	.set_rxnfc = mlx4_en_set_rxnfc,2156	.get_rxfh_indir_size = mlx4_en_get_rxfh_indir_size,2157	.get_rxfh_key_size = mlx4_en_get_rxfh_key_size,2158	.get_rxfh = mlx4_en_get_rxfh,2159	.set_rxfh = mlx4_en_set_rxfh,2160	.get_channels = mlx4_en_get_channels,2161	.set_channels = mlx4_en_set_channels,2162	.get_ts_info = mlx4_en_get_ts_info,2163	.set_priv_flags = mlx4_en_set_priv_flags,2164	.get_priv_flags = mlx4_en_get_priv_flags,2165	.get_tunable		= mlx4_en_get_tunable,2166	.set_tunable		= mlx4_en_set_tunable,2167	.get_module_info = mlx4_en_get_module_info,2168	.get_module_eeprom = mlx4_en_get_module_eeprom2169};2170 2171 2172 2173 2174 2175