1219820Sjeff/* 2219820Sjeff * Copyright (c) 2007 Mellanox Technologies. All rights reserved. 3219820Sjeff * 4219820Sjeff * This software is available to you under a choice of one of two 5219820Sjeff * licenses. You may choose to be licensed under the terms of the GNU 6219820Sjeff * General Public License (GPL) Version 2, available from the file 7219820Sjeff * COPYING in the main directory of this source tree, or the 8219820Sjeff * OpenIB.org BSD license below: 9219820Sjeff * 10219820Sjeff * Redistribution and use in source and binary forms, with or 11219820Sjeff * without modification, are permitted provided that the following 12219820Sjeff * conditions are met: 13219820Sjeff * 14219820Sjeff * - Redistributions of source code must retain the above 15219820Sjeff * copyright notice, this list of conditions and the following 16219820Sjeff * disclaimer. 17219820Sjeff * 18219820Sjeff * - Redistributions in binary form must reproduce the above 19219820Sjeff * copyright notice, this list of conditions and the following 20219820Sjeff * disclaimer in the documentation and/or other materials 21219820Sjeff * provided with the distribution. 22219820Sjeff * 23219820Sjeff * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24219820Sjeff * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25219820Sjeff * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26219820Sjeff * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27219820Sjeff * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28219820Sjeff * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29219820Sjeff * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30219820Sjeff * SOFTWARE. 31219820Sjeff * 32219820Sjeff */ 33219820Sjeff 34219820Sjeff 35219820Sjeff#include "mlx4_en.h" 36219820Sjeff 37219820Sjeff#include <linux/if_vlan.h> 38219820Sjeff 39219820Sjeff#include <linux/mlx4/device.h> 40219820Sjeff#include <linux/mlx4/cmd.h> 41219820Sjeff 42255932Salfred#if 0 // moved to port.c 43219820Sjeffint mlx4_SET_MCAST_FLTR(struct mlx4_dev *dev, u8 port, 44219820Sjeff u64 mac, u64 clear, u8 mode) 45219820Sjeff{ 46219820Sjeff return mlx4_cmd(dev, (mac | (clear << 63)), port, mode, 47255932Salfred MLX4_CMD_SET_MCAST_FLTR, MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE); 48219820Sjeff} 49255932Salfred#endif 50219820Sjeff 51219820Sjeffint mlx4_SET_VLAN_FLTR(struct mlx4_dev *dev, u8 port, u32 *vlans) 52219820Sjeff{ 53219820Sjeff struct mlx4_cmd_mailbox *mailbox; 54219820Sjeff struct mlx4_set_vlan_fltr_mbox *filter; 55219893Sjeff int i, j; 56219820Sjeff int err = 0; 57219820Sjeff 58219820Sjeff mailbox = mlx4_alloc_cmd_mailbox(dev); 59219820Sjeff if (IS_ERR(mailbox)) 60219820Sjeff return PTR_ERR(mailbox); 61219820Sjeff 62219820Sjeff filter = mailbox->buf; 63219820Sjeff memset(filter, 0, sizeof *filter); 64219820Sjeff if (vlans) 65219893Sjeff for (i = 0, j = VLAN_FLTR_SIZE - 1; i < VLAN_FLTR_SIZE; 66219893Sjeff i++, j--) 67219893Sjeff filter->entry[j] = cpu_to_be32(vlans[i]); 68219820Sjeff err = mlx4_cmd(dev, mailbox->dma, port, 0, MLX4_CMD_SET_VLAN_FLTR, 69255932Salfred MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE); 70219820Sjeff mlx4_free_cmd_mailbox(dev, mailbox); 71219820Sjeff return err; 72219820Sjeff} 73219820Sjeff 74219820Sjeff 75255932Salfred#if 0 //moved to port.c - shahark 76219820Sjeffint mlx4_SET_PORT_general(struct mlx4_dev *dev, u8 port, int mtu, 77219820Sjeff u8 pptx, u8 pfctx, u8 pprx, u8 pfcrx) 78219820Sjeff{ 79219820Sjeff struct mlx4_cmd_mailbox *mailbox; 80219820Sjeff struct mlx4_set_port_general_context *context; 81219820Sjeff int err; 82219820Sjeff u32 in_mod; 83219820Sjeff 84219820Sjeff mailbox = mlx4_alloc_cmd_mailbox(dev); 85219820Sjeff if (IS_ERR(mailbox)) 86219820Sjeff return PTR_ERR(mailbox); 87219820Sjeff context = mailbox->buf; 88219820Sjeff memset(context, 0, sizeof *context); 89219820Sjeff 90219820Sjeff context->flags = SET_PORT_GEN_ALL_VALID; 91219820Sjeff context->mtu = cpu_to_be16(mtu); 92219820Sjeff context->pptx = (pptx * (!pfctx)) << 7; 93219820Sjeff context->pfctx = pfctx; 94219820Sjeff context->pprx = (pprx * (!pfcrx)) << 7; 95219820Sjeff context->pfcrx = pfcrx; 96219820Sjeff 97219820Sjeff in_mod = MLX4_SET_PORT_GENERAL << 8 | port; 98219820Sjeff err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT, 99255932Salfred MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE); 100219820Sjeff 101219820Sjeff mlx4_free_cmd_mailbox(dev, mailbox); 102219820Sjeff return err; 103219820Sjeff} 104219820Sjeffint mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn, 105219820Sjeff u8 promisc) 106219820Sjeff{ 107255932Salfred 108255932Salfred printf("%s %s:%d\n", __func__, __FILE__, __LINE__); 109255932Salfred 110255932Salfred 111255932Salfred 112219820Sjeff struct mlx4_cmd_mailbox *mailbox; 113219820Sjeff struct mlx4_set_port_rqp_calc_context *context; 114219820Sjeff int err; 115219820Sjeff u32 in_mod; 116219820Sjeff 117219820Sjeff mailbox = mlx4_alloc_cmd_mailbox(dev); 118219820Sjeff if (IS_ERR(mailbox)) 119219820Sjeff return PTR_ERR(mailbox); 120219820Sjeff context = mailbox->buf; 121219820Sjeff memset(context, 0, sizeof *context); 122219820Sjeff 123219820Sjeff context->base_qpn = cpu_to_be32(base_qpn); 124219820Sjeff context->promisc = cpu_to_be32(promisc << SET_PORT_PROMISC_EN_SHIFT | base_qpn); 125255932Salfred/* 126219820Sjeff context->mcast = cpu_to_be32((dev->caps.mc_promisc_mode << 127219820Sjeff SET_PORT_PROMISC_MODE_SHIFT) | base_qpn); 128255932Salfred*/ 129219820Sjeff context->intra_no_vlan = 0; 130219820Sjeff context->no_vlan = MLX4_NO_VLAN_IDX; 131219820Sjeff context->intra_vlan_miss = 0; 132219820Sjeff context->vlan_miss = MLX4_VLAN_MISS_IDX; 133219820Sjeff 134219820Sjeff in_mod = MLX4_SET_PORT_RQP_CALC << 8 | port; 135219820Sjeff err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT, 136255932Salfred MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE); 137219820Sjeff 138219820Sjeff mlx4_free_cmd_mailbox(dev, mailbox); 139219820Sjeff return err; 140219820Sjeff} 141255932Salfred#endif 142219820Sjeff 143219820Sjeffint mlx4_en_QUERY_PORT(struct mlx4_en_dev *mdev, u8 port) 144219820Sjeff{ 145219820Sjeff struct mlx4_en_query_port_context *qport_context; 146219820Sjeff struct mlx4_en_priv *priv = netdev_priv(mdev->pndev[port]); 147219820Sjeff struct mlx4_en_port_state *state = &priv->port_state; 148219820Sjeff struct mlx4_cmd_mailbox *mailbox; 149219820Sjeff int err; 150219820Sjeff 151219820Sjeff mailbox = mlx4_alloc_cmd_mailbox(mdev->dev); 152219820Sjeff if (IS_ERR(mailbox)) 153219820Sjeff return PTR_ERR(mailbox); 154219820Sjeff memset(mailbox->buf, 0, sizeof(*qport_context)); 155219820Sjeff err = mlx4_cmd_box(mdev->dev, 0, mailbox->dma, port, 0, 156255932Salfred MLX4_CMD_QUERY_PORT, MLX4_CMD_TIME_CLASS_B, MLX4_CMD_WRAPPED); 157219820Sjeff if (err) 158219820Sjeff goto out; 159219820Sjeff qport_context = mailbox->buf; 160219820Sjeff 161219820Sjeff /* This command is always accessed from Ethtool context 162219820Sjeff * already synchronized, no need in locking */ 163219820Sjeff state->link_state = !!(qport_context->link_up & MLX4_EN_LINK_UP_MASK); 164234099Sjhb switch (qport_context->link_speed & MLX4_EN_SPEED_MASK) { 165234099Sjhb case MLX4_EN_1G_SPEED: 166219820Sjeff state->link_speed = 1000; 167234099Sjhb break; 168234099Sjhb case MLX4_EN_10G_SPEED_XAUI: 169234099Sjhb case MLX4_EN_10G_SPEED_XFI: 170219820Sjeff state->link_speed = 10000; 171234099Sjhb break; 172234099Sjhb case MLX4_EN_40G_SPEED: 173234099Sjhb state->link_speed = 40000; 174234099Sjhb break; 175234099Sjhb default: 176234099Sjhb state->link_speed = -1; 177234099Sjhb break; 178234099Sjhb } 179219820Sjeff state->transciver = qport_context->transceiver; 180219820Sjeff if (be32_to_cpu(qport_context->transceiver_code_hi) & 0x400) 181219820Sjeff state->transciver = 0x80; 182219820Sjeff 183219820Sjeffout: 184219820Sjeff mlx4_free_cmd_mailbox(mdev->dev, mailbox); 185219820Sjeff return err; 186219820Sjeff} 187219820Sjeff 188255932Salfred#if 0 189219820Sjeffstatic int read_iboe_counters(struct mlx4_dev *dev, int index, u64 counters[]) 190219820Sjeff{ 191219820Sjeff struct mlx4_cmd_mailbox *mailbox; 192219820Sjeff int err; 193219820Sjeff int mode; 194219820Sjeff struct mlx4_counters_ext *ext; 195219820Sjeff struct mlx4_counters *reg; 196219820Sjeff 197219820Sjeff mailbox = mlx4_alloc_cmd_mailbox(dev); 198219820Sjeff if (IS_ERR(mailbox)) 199219820Sjeff return -ENOMEM; 200219820Sjeff 201219820Sjeff err = mlx4_cmd_box(dev, 0, mailbox->dma, index, 0, 202255932Salfred MLX4_CMD_QUERY_IF_STAT, MLX4_CMD_TIME_CLASS_C, MLX4_CMD_WRAPPED); 203219820Sjeff if (err) 204219820Sjeff goto out; 205219820Sjeff 206219820Sjeff mode = be32_to_cpu(((struct mlx4_counters *)mailbox->buf)->counter_mode) & 0xf; 207219820Sjeff switch (mode) { 208219820Sjeff case 0: 209219820Sjeff reg = mailbox->buf; 210219820Sjeff counters[0] = be64_to_cpu(reg->rx_frames); 211219820Sjeff counters[1] = be64_to_cpu(reg->tx_frames); 212219820Sjeff counters[2] = be64_to_cpu(reg->rx_bytes); 213219820Sjeff counters[3] = be64_to_cpu(reg->tx_bytes); 214219820Sjeff break; 215219820Sjeff case 1: 216219820Sjeff ext = mailbox->buf; 217219820Sjeff counters[0] = be64_to_cpu(ext->rx_uni_frames); 218219820Sjeff counters[1] = be64_to_cpu(ext->tx_uni_frames); 219219820Sjeff counters[2] = be64_to_cpu(ext->rx_uni_bytes); 220219820Sjeff counters[3] = be64_to_cpu(ext->tx_uni_bytes); 221219820Sjeff break; 222219820Sjeff default: 223219820Sjeff err = -EINVAL; 224219820Sjeff } 225219820Sjeff 226219820Sjeffout: 227219820Sjeff mlx4_free_cmd_mailbox(dev, mailbox); 228219820Sjeff return err; 229219820Sjeff} 230255932Salfred#endif 231219820Sjeff 232219820Sjeffint mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset) 233219820Sjeff{ 234219820Sjeff struct mlx4_en_stat_out_mbox *mlx4_en_stats; 235219820Sjeff struct net_device *dev; 236219820Sjeff struct mlx4_en_priv *priv; 237219820Sjeff struct mlx4_cmd_mailbox *mailbox; 238219820Sjeff u64 in_mod = reset << 8 | port; 239219820Sjeff unsigned long oerror; 240219820Sjeff unsigned long ierror; 241219820Sjeff int err; 242219820Sjeff int i; 243255932Salfred //int counter; 244219820Sjeff u64 counters[4]; 245219820Sjeff 246219820Sjeff dev = mdev->pndev[port]; 247219820Sjeff priv = netdev_priv(dev); 248219820Sjeff memset(counters, 0, sizeof counters); 249255932Salfred /* 250219820Sjeff counter = mlx4_get_iboe_counter(priv->mdev->dev, port); 251219820Sjeff if (counter >= 0) 252219820Sjeff err = read_iboe_counters(priv->mdev->dev, counter, counters); 253255932Salfred */ 254219820Sjeff 255219820Sjeff mailbox = mlx4_alloc_cmd_mailbox(mdev->dev); 256219820Sjeff if (IS_ERR(mailbox)) 257219820Sjeff return PTR_ERR(mailbox); 258219820Sjeff memset(mailbox->buf, 0, sizeof(*mlx4_en_stats)); 259219820Sjeff err = mlx4_cmd_box(mdev->dev, 0, mailbox->dma, in_mod, 0, 260255932Salfred MLX4_CMD_DUMP_ETH_STATS, MLX4_CMD_TIME_CLASS_B, MLX4_CMD_WRAPPED); 261219820Sjeff if (err) 262219820Sjeff goto out; 263219820Sjeff 264219820Sjeff mlx4_en_stats = mailbox->buf; 265219820Sjeff 266219820Sjeff spin_lock(&priv->stats_lock); 267219820Sjeff 268219820Sjeff oerror = ierror = 0; 269219820Sjeff dev->if_ipackets = counters[0]; 270219820Sjeff dev->if_ibytes = counters[2]; 271219820Sjeff for (i = 0; i < priv->rx_ring_num; i++) { 272219820Sjeff dev->if_ipackets += priv->rx_ring[i].packets; 273219820Sjeff dev->if_ibytes += priv->rx_ring[i].bytes; 274219820Sjeff ierror += priv->rx_ring[i].errors; 275219820Sjeff } 276219820Sjeff dev->if_opackets = counters[1]; 277219820Sjeff dev->if_obytes = counters[3]; 278219820Sjeff for (i = 0; i <= priv->tx_ring_num; i++) { 279219820Sjeff dev->if_opackets += priv->tx_ring[i].packets; 280219820Sjeff dev->if_obytes += priv->tx_ring[i].bytes; 281219820Sjeff oerror += priv->tx_ring[i].errors; 282219820Sjeff } 283219820Sjeff 284219820Sjeff dev->if_ierrors = be32_to_cpu(mlx4_en_stats->RDROP) + ierror; 285219820Sjeff dev->if_oerrors = be32_to_cpu(mlx4_en_stats->TDROP) + oerror; 286219820Sjeff dev->if_imcasts = be64_to_cpu(mlx4_en_stats->MCAST_prio_0) + 287219820Sjeff be64_to_cpu(mlx4_en_stats->MCAST_prio_1) + 288219820Sjeff be64_to_cpu(mlx4_en_stats->MCAST_prio_2) + 289219820Sjeff be64_to_cpu(mlx4_en_stats->MCAST_prio_3) + 290219820Sjeff be64_to_cpu(mlx4_en_stats->MCAST_prio_4) + 291219820Sjeff be64_to_cpu(mlx4_en_stats->MCAST_prio_5) + 292219820Sjeff be64_to_cpu(mlx4_en_stats->MCAST_prio_6) + 293219820Sjeff be64_to_cpu(mlx4_en_stats->MCAST_prio_7) + 294219820Sjeff be64_to_cpu(mlx4_en_stats->MCAST_novlan); 295219820Sjeff dev->if_omcasts = be64_to_cpu(mlx4_en_stats->TMCAST_prio_0) + 296219820Sjeff be64_to_cpu(mlx4_en_stats->TMCAST_prio_1) + 297219820Sjeff be64_to_cpu(mlx4_en_stats->TMCAST_prio_2) + 298219820Sjeff be64_to_cpu(mlx4_en_stats->TMCAST_prio_3) + 299219820Sjeff be64_to_cpu(mlx4_en_stats->TMCAST_prio_4) + 300219820Sjeff be64_to_cpu(mlx4_en_stats->TMCAST_prio_5) + 301219820Sjeff be64_to_cpu(mlx4_en_stats->TMCAST_prio_6) + 302219820Sjeff be64_to_cpu(mlx4_en_stats->TMCAST_prio_7) + 303219820Sjeff be64_to_cpu(mlx4_en_stats->TMCAST_novlan); 304219820Sjeff dev->if_collisions = 0; 305219820Sjeff 306219820Sjeff priv->pkstats.broadcast = 307219820Sjeff be64_to_cpu(mlx4_en_stats->RBCAST_prio_0) + 308219820Sjeff be64_to_cpu(mlx4_en_stats->RBCAST_prio_1) + 309219820Sjeff be64_to_cpu(mlx4_en_stats->RBCAST_prio_2) + 310219820Sjeff be64_to_cpu(mlx4_en_stats->RBCAST_prio_3) + 311219820Sjeff be64_to_cpu(mlx4_en_stats->RBCAST_prio_4) + 312219820Sjeff be64_to_cpu(mlx4_en_stats->RBCAST_prio_5) + 313219820Sjeff be64_to_cpu(mlx4_en_stats->RBCAST_prio_6) + 314219820Sjeff be64_to_cpu(mlx4_en_stats->RBCAST_prio_7) + 315219820Sjeff be64_to_cpu(mlx4_en_stats->RBCAST_novlan); 316219820Sjeff priv->pkstats.rx_prio[0] = be64_to_cpu(mlx4_en_stats->RTOT_prio_0); 317219820Sjeff priv->pkstats.rx_prio[1] = be64_to_cpu(mlx4_en_stats->RTOT_prio_1); 318219820Sjeff priv->pkstats.rx_prio[2] = be64_to_cpu(mlx4_en_stats->RTOT_prio_2); 319219820Sjeff priv->pkstats.rx_prio[3] = be64_to_cpu(mlx4_en_stats->RTOT_prio_3); 320219820Sjeff priv->pkstats.rx_prio[4] = be64_to_cpu(mlx4_en_stats->RTOT_prio_4); 321219820Sjeff priv->pkstats.rx_prio[5] = be64_to_cpu(mlx4_en_stats->RTOT_prio_5); 322219820Sjeff priv->pkstats.rx_prio[6] = be64_to_cpu(mlx4_en_stats->RTOT_prio_6); 323219820Sjeff priv->pkstats.rx_prio[7] = be64_to_cpu(mlx4_en_stats->RTOT_prio_7); 324219820Sjeff priv->pkstats.tx_prio[0] = be64_to_cpu(mlx4_en_stats->TTOT_prio_0); 325219820Sjeff priv->pkstats.tx_prio[1] = be64_to_cpu(mlx4_en_stats->TTOT_prio_1); 326219820Sjeff priv->pkstats.tx_prio[2] = be64_to_cpu(mlx4_en_stats->TTOT_prio_2); 327219820Sjeff priv->pkstats.tx_prio[3] = be64_to_cpu(mlx4_en_stats->TTOT_prio_3); 328219820Sjeff priv->pkstats.tx_prio[4] = be64_to_cpu(mlx4_en_stats->TTOT_prio_4); 329219820Sjeff priv->pkstats.tx_prio[5] = be64_to_cpu(mlx4_en_stats->TTOT_prio_5); 330219820Sjeff priv->pkstats.tx_prio[6] = be64_to_cpu(mlx4_en_stats->TTOT_prio_6); 331219820Sjeff priv->pkstats.tx_prio[7] = be64_to_cpu(mlx4_en_stats->TTOT_prio_7); 332219820Sjeff spin_unlock(&priv->stats_lock); 333219820Sjeff 334219820Sjeffout: 335219820Sjeff mlx4_free_cmd_mailbox(mdev->dev, mailbox); 336219820Sjeff return err; 337219820Sjeff} 338219820Sjeff 339