linux/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c
<<
>>
Prefs
   1/*
   2 * This file is part of the Chelsio T4 PCI-E SR-IOV Virtual Function Ethernet
   3 * driver for Linux.
   4 *
   5 * Copyright (c) 2009-2010 Chelsio Communications, Inc. All rights reserved.
   6 *
   7 * This software is available to you under a choice of one of two
   8 * licenses.  You may choose to be licensed under the terms of the GNU
   9 * General Public License (GPL) Version 2, available from the file
  10 * COPYING in the main directory of this source tree, or the
  11 * OpenIB.org BSD license below:
  12 *
  13 *     Redistribution and use in source and binary forms, with or
  14 *     without modification, are permitted provided that the following
  15 *     conditions are met:
  16 *
  17 *      - Redistributions of source code must retain the above
  18 *        copyright notice, this list of conditions and the following
  19 *        disclaimer.
  20 *
  21 *      - Redistributions in binary form must reproduce the above
  22 *        copyright notice, this list of conditions and the following
  23 *        disclaimer in the documentation and/or other materials
  24 *        provided with the distribution.
  25 *
  26 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  27 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  28 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  29 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  30 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  31 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  32 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  33 * SOFTWARE.
  34 */
  35
  36#include <linux/pci.h>
  37
  38#include "t4vf_common.h"
  39#include "t4vf_defs.h"
  40
  41#include "../cxgb4/t4_regs.h"
  42#include "../cxgb4/t4fw_api.h"
  43
  44/*
  45 * Wait for the device to become ready (signified by our "who am I" register
  46 * returning a value other than all 1's).  Return an error if it doesn't
  47 * become ready ...
  48 */
  49int __devinit t4vf_wait_dev_ready(struct adapter *adapter)
  50{
  51        const u32 whoami = T4VF_PL_BASE_ADDR + PL_VF_WHOAMI;
  52        const u32 notready1 = 0xffffffff;
  53        const u32 notready2 = 0xeeeeeeee;
  54        u32 val;
  55
  56        val = t4_read_reg(adapter, whoami);
  57        if (val != notready1 && val != notready2)
  58                return 0;
  59        msleep(500);
  60        val = t4_read_reg(adapter, whoami);
  61        if (val != notready1 && val != notready2)
  62                return 0;
  63        else
  64                return -EIO;
  65}
  66
  67/*
  68 * Get the reply to a mailbox command and store it in @rpl in big-endian order
  69 * (since the firmware data structures are specified in a big-endian layout).
  70 */
  71static void get_mbox_rpl(struct adapter *adapter, __be64 *rpl, int size,
  72                         u32 mbox_data)
  73{
  74        for ( ; size; size -= 8, mbox_data += 8)
  75                *rpl++ = cpu_to_be64(t4_read_reg64(adapter, mbox_data));
  76}
  77
  78/*
  79 * Dump contents of mailbox with a leading tag.
  80 */
  81static void dump_mbox(struct adapter *adapter, const char *tag, u32 mbox_data)
  82{
  83        dev_err(adapter->pdev_dev,
  84                "mbox %s: %llx %llx %llx %llx %llx %llx %llx %llx\n", tag,
  85                (unsigned long long)t4_read_reg64(adapter, mbox_data +  0),
  86                (unsigned long long)t4_read_reg64(adapter, mbox_data +  8),
  87                (unsigned long long)t4_read_reg64(adapter, mbox_data + 16),
  88                (unsigned long long)t4_read_reg64(adapter, mbox_data + 24),
  89                (unsigned long long)t4_read_reg64(adapter, mbox_data + 32),
  90                (unsigned long long)t4_read_reg64(adapter, mbox_data + 40),
  91                (unsigned long long)t4_read_reg64(adapter, mbox_data + 48),
  92                (unsigned long long)t4_read_reg64(adapter, mbox_data + 56));
  93}
  94
  95/**
  96 *      t4vf_wr_mbox_core - send a command to FW through the mailbox
  97 *      @adapter: the adapter
  98 *      @cmd: the command to write
  99 *      @size: command length in bytes
 100 *      @rpl: where to optionally store the reply
 101 *      @sleep_ok: if true we may sleep while awaiting command completion
 102 *
 103 *      Sends the given command to FW through the mailbox and waits for the
 104 *      FW to execute the command.  If @rpl is not %NULL it is used to store
 105 *      the FW's reply to the command.  The command and its optional reply
 106 *      are of the same length.  FW can take up to 500 ms to respond.
 107 *      @sleep_ok determines whether we may sleep while awaiting the response.
 108 *      If sleeping is allowed we use progressive backoff otherwise we spin.
 109 *
 110 *      The return value is 0 on success or a negative errno on failure.  A
 111 *      failure can happen either because we are not able to execute the
 112 *      command or FW executes it but signals an error.  In the latter case
 113 *      the return value is the error code indicated by FW (negated).
 114 */
 115int t4vf_wr_mbox_core(struct adapter *adapter, const void *cmd, int size,
 116                      void *rpl, bool sleep_ok)
 117{
 118        static const int delay[] = {
 119                1, 1, 3, 5, 10, 10, 20, 50, 100
 120        };
 121
 122        u32 v;
 123        int i, ms, delay_idx;
 124        const __be64 *p;
 125        u32 mbox_data = T4VF_MBDATA_BASE_ADDR;
 126        u32 mbox_ctl = T4VF_CIM_BASE_ADDR + CIM_VF_EXT_MAILBOX_CTRL;
 127
 128        /*
 129         * Commands must be multiples of 16 bytes in length and may not be
 130         * larger than the size of the Mailbox Data register array.
 131         */
 132        if ((size % 16) != 0 ||
 133            size > NUM_CIM_VF_MAILBOX_DATA_INSTANCES * 4)
 134                return -EINVAL;
 135
 136        /*
 137         * Loop trying to get ownership of the mailbox.  Return an error
 138         * if we can't gain ownership.
 139         */
 140        v = MBOWNER_GET(t4_read_reg(adapter, mbox_ctl));
 141        for (i = 0; v == MBOX_OWNER_NONE && i < 3; i++)
 142                v = MBOWNER_GET(t4_read_reg(adapter, mbox_ctl));
 143        if (v != MBOX_OWNER_DRV)
 144                return v == MBOX_OWNER_FW ? -EBUSY : -ETIMEDOUT;
 145
 146        /*
 147         * Write the command array into the Mailbox Data register array and
 148         * transfer ownership of the mailbox to the firmware.
 149         *
 150         * For the VFs, the Mailbox Data "registers" are actually backed by
 151         * T4's "MA" interface rather than PL Registers (as is the case for
 152         * the PFs).  Because these are in different coherency domains, the
 153         * write to the VF's PL-register-backed Mailbox Control can race in
 154         * front of the writes to the MA-backed VF Mailbox Data "registers".
 155         * So we need to do a read-back on at least one byte of the VF Mailbox
 156         * Data registers before doing the write to the VF Mailbox Control
 157         * register.
 158         */
 159        for (i = 0, p = cmd; i < size; i += 8)
 160                t4_write_reg64(adapter, mbox_data + i, be64_to_cpu(*p++));
 161        t4_read_reg(adapter, mbox_data);         /* flush write */
 162
 163        t4_write_reg(adapter, mbox_ctl,
 164                     MBMSGVALID | MBOWNER(MBOX_OWNER_FW));
 165        t4_read_reg(adapter, mbox_ctl);          /* flush write */
 166
 167        /*
 168         * Spin waiting for firmware to acknowledge processing our command.
 169         */
 170        delay_idx = 0;
 171        ms = delay[0];
 172
 173        for (i = 0; i < FW_CMD_MAX_TIMEOUT; i += ms) {
 174                if (sleep_ok) {
 175                        ms = delay[delay_idx];
 176                        if (delay_idx < ARRAY_SIZE(delay) - 1)
 177                                delay_idx++;
 178                        msleep(ms);
 179                } else
 180                        mdelay(ms);
 181
 182                /*
 183                 * If we're the owner, see if this is the reply we wanted.
 184                 */
 185                v = t4_read_reg(adapter, mbox_ctl);
 186                if (MBOWNER_GET(v) == MBOX_OWNER_DRV) {
 187                        /*
 188                         * If the Message Valid bit isn't on, revoke ownership
 189                         * of the mailbox and continue waiting for our reply.
 190                         */
 191                        if ((v & MBMSGVALID) == 0) {
 192                                t4_write_reg(adapter, mbox_ctl,
 193                                             MBOWNER(MBOX_OWNER_NONE));
 194                                continue;
 195                        }
 196
 197                        /*
 198                         * We now have our reply.  Extract the command return
 199                         * value, copy the reply back to our caller's buffer
 200                         * (if specified) and revoke ownership of the mailbox.
 201                         * We return the (negated) firmware command return
 202                         * code (this depends on FW_SUCCESS == 0).
 203                         */
 204
 205                        /* return value in low-order little-endian word */
 206                        v = t4_read_reg(adapter, mbox_data);
 207                        if (FW_CMD_RETVAL_GET(v))
 208                                dump_mbox(adapter, "FW Error", mbox_data);
 209
 210                        if (rpl) {
 211                                /* request bit in high-order BE word */
 212                                WARN_ON((be32_to_cpu(*(const u32 *)cmd)
 213                                         & FW_CMD_REQUEST) == 0);
 214                                get_mbox_rpl(adapter, rpl, size, mbox_data);
 215                                WARN_ON((be32_to_cpu(*(u32 *)rpl)
 216                                         & FW_CMD_REQUEST) != 0);
 217                        }
 218                        t4_write_reg(adapter, mbox_ctl,
 219                                     MBOWNER(MBOX_OWNER_NONE));
 220                        return -FW_CMD_RETVAL_GET(v);
 221                }
 222        }
 223
 224        /*
 225         * We timed out.  Return the error ...
 226         */
 227        dump_mbox(adapter, "FW Timeout", mbox_data);
 228        return -ETIMEDOUT;
 229}
 230
 231/**
 232 *      hash_mac_addr - return the hash value of a MAC address
 233 *      @addr: the 48-bit Ethernet MAC address
 234 *
 235 *      Hashes a MAC address according to the hash function used by hardware
 236 *      inexact (hash) address matching.
 237 */
 238static int hash_mac_addr(const u8 *addr)
 239{
 240        u32 a = ((u32)addr[0] << 16) | ((u32)addr[1] << 8) | addr[2];
 241        u32 b = ((u32)addr[3] << 16) | ((u32)addr[4] << 8) | addr[5];
 242        a ^= b;
 243        a ^= (a >> 12);
 244        a ^= (a >> 6);
 245        return a & 0x3f;
 246}
 247
 248/**
 249 *      init_link_config - initialize a link's SW state
 250 *      @lc: structure holding the link state
 251 *      @caps: link capabilities
 252 *
 253 *      Initializes the SW state maintained for each link, including the link's
 254 *      capabilities and default speed/flow-control/autonegotiation settings.
 255 */
 256static void __devinit init_link_config(struct link_config *lc,
 257                                       unsigned int caps)
 258{
 259        lc->supported = caps;
 260        lc->requested_speed = 0;
 261        lc->speed = 0;
 262        lc->requested_fc = lc->fc = PAUSE_RX | PAUSE_TX;
 263        if (lc->supported & SUPPORTED_Autoneg) {
 264                lc->advertising = lc->supported;
 265                lc->autoneg = AUTONEG_ENABLE;
 266                lc->requested_fc |= PAUSE_AUTONEG;
 267        } else {
 268                lc->advertising = 0;
 269                lc->autoneg = AUTONEG_DISABLE;
 270        }
 271}
 272
 273/**
 274 *      t4vf_port_init - initialize port hardware/software state
 275 *      @adapter: the adapter
 276 *      @pidx: the adapter port index
 277 */
 278int __devinit t4vf_port_init(struct adapter *adapter, int pidx)
 279{
 280        struct port_info *pi = adap2pinfo(adapter, pidx);
 281        struct fw_vi_cmd vi_cmd, vi_rpl;
 282        struct fw_port_cmd port_cmd, port_rpl;
 283        int v;
 284        u32 word;
 285
 286        /*
 287         * Execute a VI Read command to get our Virtual Interface information
 288         * like MAC address, etc.
 289         */
 290        memset(&vi_cmd, 0, sizeof(vi_cmd));
 291        vi_cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP(FW_VI_CMD) |
 292                                       FW_CMD_REQUEST |
 293                                       FW_CMD_READ);
 294        vi_cmd.alloc_to_len16 = cpu_to_be32(FW_LEN16(vi_cmd));
 295        vi_cmd.type_viid = cpu_to_be16(FW_VI_CMD_VIID(pi->viid));
 296        v = t4vf_wr_mbox(adapter, &vi_cmd, sizeof(vi_cmd), &vi_rpl);
 297        if (v)
 298                return v;
 299
 300        BUG_ON(pi->port_id != FW_VI_CMD_PORTID_GET(vi_rpl.portid_pkd));
 301        pi->rss_size = FW_VI_CMD_RSSSIZE_GET(be16_to_cpu(vi_rpl.rsssize_pkd));
 302        t4_os_set_hw_addr(adapter, pidx, vi_rpl.mac);
 303
 304        /*
 305         * If we don't have read access to our port information, we're done
 306         * now.  Otherwise, execute a PORT Read command to get it ...
 307         */
 308        if (!(adapter->params.vfres.r_caps & FW_CMD_CAP_PORT))
 309                return 0;
 310
 311        memset(&port_cmd, 0, sizeof(port_cmd));
 312        port_cmd.op_to_portid = cpu_to_be32(FW_CMD_OP(FW_PORT_CMD) |
 313                                            FW_CMD_REQUEST |
 314                                            FW_CMD_READ |
 315                                            FW_PORT_CMD_PORTID(pi->port_id));
 316        port_cmd.action_to_len16 =
 317                cpu_to_be32(FW_PORT_CMD_ACTION(FW_PORT_ACTION_GET_PORT_INFO) |
 318                            FW_LEN16(port_cmd));
 319        v = t4vf_wr_mbox(adapter, &port_cmd, sizeof(port_cmd), &port_rpl);
 320        if (v)
 321                return v;
 322
 323        v = 0;
 324        word = be16_to_cpu(port_rpl.u.info.pcap);
 325        if (word & FW_PORT_CAP_SPEED_100M)
 326                v |= SUPPORTED_100baseT_Full;
 327        if (word & FW_PORT_CAP_SPEED_1G)
 328                v |= SUPPORTED_1000baseT_Full;
 329        if (word & FW_PORT_CAP_SPEED_10G)
 330                v |= SUPPORTED_10000baseT_Full;
 331        if (word & FW_PORT_CAP_ANEG)
 332                v |= SUPPORTED_Autoneg;
 333        init_link_config(&pi->link_cfg, v);
 334
 335        return 0;
 336}
 337
 338/**
 339 *      t4vf_fw_reset - issue a reset to FW
 340 *      @adapter: the adapter
 341 *
 342 *      Issues a reset command to FW.  For a Physical Function this would
 343 *      result in the Firmware reseting all of its state.  For a Virtual
 344 *      Function this just resets the state associated with the VF.
 345 */
 346int t4vf_fw_reset(struct adapter *adapter)
 347{
 348        struct fw_reset_cmd cmd;
 349
 350        memset(&cmd, 0, sizeof(cmd));
 351        cmd.op_to_write = cpu_to_be32(FW_CMD_OP(FW_RESET_CMD) |
 352                                      FW_CMD_WRITE);
 353        cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd));
 354        return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL);
 355}
 356
 357/**
 358 *      t4vf_query_params - query FW or device parameters
 359 *      @adapter: the adapter
 360 *      @nparams: the number of parameters
 361 *      @params: the parameter names
 362 *      @vals: the parameter values
 363 *
 364 *      Reads the values of firmware or device parameters.  Up to 7 parameters
 365 *      can be queried at once.
 366 */
 367int t4vf_query_params(struct adapter *adapter, unsigned int nparams,
 368                      const u32 *params, u32 *vals)
 369{
 370        int i, ret;
 371        struct fw_params_cmd cmd, rpl;
 372        struct fw_params_param *p;
 373        size_t len16;
 374
 375        if (nparams > 7)
 376                return -EINVAL;
 377
 378        memset(&cmd, 0, sizeof(cmd));
 379        cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP(FW_PARAMS_CMD) |
 380                                    FW_CMD_REQUEST |
 381                                    FW_CMD_READ);
 382        len16 = DIV_ROUND_UP(offsetof(struct fw_params_cmd,
 383                                      param[nparams].mnem), 16);
 384        cmd.retval_len16 = cpu_to_be32(FW_CMD_LEN16(len16));
 385        for (i = 0, p = &cmd.param[0]; i < nparams; i++, p++)
 386                p->mnem = htonl(*params++);
 387
 388        ret = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl);
 389        if (ret == 0)
 390                for (i = 0, p = &rpl.param[0]; i < nparams; i++, p++)
 391                        *vals++ = be32_to_cpu(p->val);
 392        return ret;
 393}
 394
 395/**
 396 *      t4vf_set_params - sets FW or device parameters
 397 *      @adapter: the adapter
 398 *      @nparams: the number of parameters
 399 *      @params: the parameter names
 400 *      @vals: the parameter values
 401 *
 402 *      Sets the values of firmware or device parameters.  Up to 7 parameters
 403 *      can be specified at once.
 404 */
 405int t4vf_set_params(struct adapter *adapter, unsigned int nparams,
 406                    const u32 *params, const u32 *vals)
 407{
 408        int i;
 409        struct fw_params_cmd cmd;
 410        struct fw_params_param *p;
 411        size_t len16;
 412
 413        if (nparams > 7)
 414                return -EINVAL;
 415
 416        memset(&cmd, 0, sizeof(cmd));
 417        cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP(FW_PARAMS_CMD) |
 418                                    FW_CMD_REQUEST |
 419                                    FW_CMD_WRITE);
 420        len16 = DIV_ROUND_UP(offsetof(struct fw_params_cmd,
 421                                      param[nparams]), 16);
 422        cmd.retval_len16 = cpu_to_be32(FW_CMD_LEN16(len16));
 423        for (i = 0, p = &cmd.param[0]; i < nparams; i++, p++) {
 424                p->mnem = cpu_to_be32(*params++);
 425                p->val = cpu_to_be32(*vals++);
 426        }
 427
 428        return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL);
 429}
 430
 431/**
 432 *      t4vf_get_sge_params - retrieve adapter Scatter gather Engine parameters
 433 *      @adapter: the adapter
 434 *
 435 *      Retrieves various core SGE parameters in the form of hardware SGE
 436 *      register values.  The caller is responsible for decoding these as
 437 *      needed.  The SGE parameters are stored in @adapter->params.sge.
 438 */
 439int t4vf_get_sge_params(struct adapter *adapter)
 440{
 441        struct sge_params *sge_params = &adapter->params.sge;
 442        u32 params[7], vals[7];
 443        int v;
 444
 445        params[0] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
 446                     FW_PARAMS_PARAM_XYZ(SGE_CONTROL));
 447        params[1] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
 448                     FW_PARAMS_PARAM_XYZ(SGE_HOST_PAGE_SIZE));
 449        params[2] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
 450                     FW_PARAMS_PARAM_XYZ(SGE_FL_BUFFER_SIZE0));
 451        params[3] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
 452                     FW_PARAMS_PARAM_XYZ(SGE_FL_BUFFER_SIZE1));
 453        params[4] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
 454                     FW_PARAMS_PARAM_XYZ(SGE_TIMER_VALUE_0_AND_1));
 455        params[5] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
 456                     FW_PARAMS_PARAM_XYZ(SGE_TIMER_VALUE_2_AND_3));
 457        params[6] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
 458                     FW_PARAMS_PARAM_XYZ(SGE_TIMER_VALUE_4_AND_5));
 459        v = t4vf_query_params(adapter, 7, params, vals);
 460        if (v)
 461                return v;
 462        sge_params->sge_control = vals[0];
 463        sge_params->sge_host_page_size = vals[1];
 464        sge_params->sge_fl_buffer_size[0] = vals[2];
 465        sge_params->sge_fl_buffer_size[1] = vals[3];
 466        sge_params->sge_timer_value_0_and_1 = vals[4];
 467        sge_params->sge_timer_value_2_and_3 = vals[5];
 468        sge_params->sge_timer_value_4_and_5 = vals[6];
 469
 470        params[0] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
 471                     FW_PARAMS_PARAM_XYZ(SGE_INGRESS_RX_THRESHOLD));
 472        v = t4vf_query_params(adapter, 1, params, vals);
 473        if (v)
 474                return v;
 475        sge_params->sge_ingress_rx_threshold = vals[0];
 476
 477        return 0;
 478}
 479
 480/**
 481 *      t4vf_get_vpd_params - retrieve device VPD paremeters
 482 *      @adapter: the adapter
 483 *
 484 *      Retrives various device Vital Product Data parameters.  The parameters
 485 *      are stored in @adapter->params.vpd.
 486 */
 487int t4vf_get_vpd_params(struct adapter *adapter)
 488{
 489        struct vpd_params *vpd_params = &adapter->params.vpd;
 490        u32 params[7], vals[7];
 491        int v;
 492
 493        params[0] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) |
 494                     FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_CCLK));
 495        v = t4vf_query_params(adapter, 1, params, vals);
 496        if (v)
 497                return v;
 498        vpd_params->cclk = vals[0];
 499
 500        return 0;
 501}
 502
 503/**
 504 *      t4vf_get_dev_params - retrieve device paremeters
 505 *      @adapter: the adapter
 506 *
 507 *      Retrives various device parameters.  The parameters are stored in
 508 *      @adapter->params.dev.
 509 */
 510int t4vf_get_dev_params(struct adapter *adapter)
 511{
 512        struct dev_params *dev_params = &adapter->params.dev;
 513        u32 params[7], vals[7];
 514        int v;
 515
 516        params[0] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) |
 517                     FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_FWREV));
 518        params[1] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) |
 519                     FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_TPREV));
 520        v = t4vf_query_params(adapter, 2, params, vals);
 521        if (v)
 522                return v;
 523        dev_params->fwrev = vals[0];
 524        dev_params->tprev = vals[1];
 525
 526        return 0;
 527}
 528
 529/**
 530 *      t4vf_get_rss_glb_config - retrieve adapter RSS Global Configuration
 531 *      @adapter: the adapter
 532 *
 533 *      Retrieves global RSS mode and parameters with which we have to live
 534 *      and stores them in the @adapter's RSS parameters.
 535 */
 536int t4vf_get_rss_glb_config(struct adapter *adapter)
 537{
 538        struct rss_params *rss = &adapter->params.rss;
 539        struct fw_rss_glb_config_cmd cmd, rpl;
 540        int v;
 541
 542        /*
 543         * Execute an RSS Global Configuration read command to retrieve
 544         * our RSS configuration.
 545         */
 546        memset(&cmd, 0, sizeof(cmd));
 547        cmd.op_to_write = cpu_to_be32(FW_CMD_OP(FW_RSS_GLB_CONFIG_CMD) |
 548                                      FW_CMD_REQUEST |
 549                                      FW_CMD_READ);
 550        cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd));
 551        v = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl);
 552        if (v)
 553                return v;
 554
 555        /*
 556         * Transate the big-endian RSS Global Configuration into our
 557         * cpu-endian format based on the RSS mode.  We also do first level
 558         * filtering at this point to weed out modes which don't support
 559         * VF Drivers ...
 560         */
 561        rss->mode = FW_RSS_GLB_CONFIG_CMD_MODE_GET(
 562                        be32_to_cpu(rpl.u.manual.mode_pkd));
 563        switch (rss->mode) {
 564        case FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL: {
 565                u32 word = be32_to_cpu(
 566                                rpl.u.basicvirtual.synmapen_to_hashtoeplitz);
 567
 568                rss->u.basicvirtual.synmapen =
 569                        ((word & FW_RSS_GLB_CONFIG_CMD_SYNMAPEN) != 0);
 570                rss->u.basicvirtual.syn4tupenipv6 =
 571                        ((word & FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV6) != 0);
 572                rss->u.basicvirtual.syn2tupenipv6 =
 573                        ((word & FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV6) != 0);
 574                rss->u.basicvirtual.syn4tupenipv4 =
 575                        ((word & FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV4) != 0);
 576                rss->u.basicvirtual.syn2tupenipv4 =
 577                        ((word & FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV4) != 0);
 578
 579                rss->u.basicvirtual.ofdmapen =
 580                        ((word & FW_RSS_GLB_CONFIG_CMD_OFDMAPEN) != 0);
 581
 582                rss->u.basicvirtual.tnlmapen =
 583                        ((word & FW_RSS_GLB_CONFIG_CMD_TNLMAPEN) != 0);
 584                rss->u.basicvirtual.tnlalllookup =
 585                        ((word  & FW_RSS_GLB_CONFIG_CMD_TNLALLLKP) != 0);
 586
 587                rss->u.basicvirtual.hashtoeplitz =
 588                        ((word & FW_RSS_GLB_CONFIG_CMD_HASHTOEPLITZ) != 0);
 589
 590                /* we need at least Tunnel Map Enable to be set */
 591                if (!rss->u.basicvirtual.tnlmapen)
 592                        return -EINVAL;
 593                break;
 594        }
 595
 596        default:
 597                /* all unknown/unsupported RSS modes result in an error */
 598                return -EINVAL;
 599        }
 600
 601        return 0;
 602}
 603
 604/**
 605 *      t4vf_get_vfres - retrieve VF resource limits
 606 *      @adapter: the adapter
 607 *
 608 *      Retrieves configured resource limits and capabilities for a virtual
 609 *      function.  The results are stored in @adapter->vfres.
 610 */
 611int t4vf_get_vfres(struct adapter *adapter)
 612{
 613        struct vf_resources *vfres = &adapter->params.vfres;
 614        struct fw_pfvf_cmd cmd, rpl;
 615        int v;
 616        u32 word;
 617
 618        /*
 619         * Execute PFVF Read command to get VF resource limits; bail out early
 620         * with error on command failure.
 621         */
 622        memset(&cmd, 0, sizeof(cmd));
 623        cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP(FW_PFVF_CMD) |
 624                                    FW_CMD_REQUEST |
 625                                    FW_CMD_READ);
 626        cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd));
 627        v = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl);
 628        if (v)
 629                return v;
 630
 631        /*
 632         * Extract VF resource limits and return success.
 633         */
 634        word = be32_to_cpu(rpl.niqflint_niq);
 635        vfres->niqflint = FW_PFVF_CMD_NIQFLINT_GET(word);
 636        vfres->niq = FW_PFVF_CMD_NIQ_GET(word);
 637
 638        word = be32_to_cpu(rpl.type_to_neq);
 639        vfres->neq = FW_PFVF_CMD_NEQ_GET(word);
 640        vfres->pmask = FW_PFVF_CMD_PMASK_GET(word);
 641
 642        word = be32_to_cpu(rpl.tc_to_nexactf);
 643        vfres->tc = FW_PFVF_CMD_TC_GET(word);
 644        vfres->nvi = FW_PFVF_CMD_NVI_GET(word);
 645        vfres->nexactf = FW_PFVF_CMD_NEXACTF_GET(word);
 646
 647        word = be32_to_cpu(rpl.r_caps_to_nethctrl);
 648        vfres->r_caps = FW_PFVF_CMD_R_CAPS_GET(word);
 649        vfres->wx_caps = FW_PFVF_CMD_WX_CAPS_GET(word);
 650        vfres->nethctrl = FW_PFVF_CMD_NETHCTRL_GET(word);
 651
 652        return 0;
 653}
 654
 655/**
 656 *      t4vf_read_rss_vi_config - read a VI's RSS configuration
 657 *      @adapter: the adapter
 658 *      @viid: Virtual Interface ID
 659 *      @config: pointer to host-native VI RSS Configuration buffer
 660 *
 661 *      Reads the Virtual Interface's RSS configuration information and
 662 *      translates it into CPU-native format.
 663 */
 664int t4vf_read_rss_vi_config(struct adapter *adapter, unsigned int viid,
 665                            union rss_vi_config *config)
 666{
 667        struct fw_rss_vi_config_cmd cmd, rpl;
 668        int v;
 669
 670        memset(&cmd, 0, sizeof(cmd));
 671        cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_RSS_VI_CONFIG_CMD) |
 672                                     FW_CMD_REQUEST |
 673                                     FW_CMD_READ |
 674                                     FW_RSS_VI_CONFIG_CMD_VIID(viid));
 675        cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd));
 676        v = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl);
 677        if (v)
 678                return v;
 679
 680        switch (adapter->params.rss.mode) {
 681        case FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL: {
 682                u32 word = be32_to_cpu(rpl.u.basicvirtual.defaultq_to_udpen);
 683
 684                config->basicvirtual.ip6fourtupen =
 685                        ((word & FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN) != 0);
 686                config->basicvirtual.ip6twotupen =
 687                        ((word & FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN) != 0);
 688                config->basicvirtual.ip4fourtupen =
 689                        ((word & FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN) != 0);
 690                config->basicvirtual.ip4twotupen =
 691                        ((word & FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN) != 0);
 692                config->basicvirtual.udpen =
 693                        ((word & FW_RSS_VI_CONFIG_CMD_UDPEN) != 0);
 694                config->basicvirtual.defaultq =
 695                        FW_RSS_VI_CONFIG_CMD_DEFAULTQ_GET(word);
 696                break;
 697        }
 698
 699        default:
 700                return -EINVAL;
 701        }
 702
 703        return 0;
 704}
 705
 706/**
 707 *      t4vf_write_rss_vi_config - write a VI's RSS configuration
 708 *      @adapter: the adapter
 709 *      @viid: Virtual Interface ID
 710 *      @config: pointer to host-native VI RSS Configuration buffer
 711 *
 712 *      Write the Virtual Interface's RSS configuration information
 713 *      (translating it into firmware-native format before writing).
 714 */
 715int t4vf_write_rss_vi_config(struct adapter *adapter, unsigned int viid,
 716                             union rss_vi_config *config)
 717{
 718        struct fw_rss_vi_config_cmd cmd, rpl;
 719
 720        memset(&cmd, 0, sizeof(cmd));
 721        cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_RSS_VI_CONFIG_CMD) |
 722                                     FW_CMD_REQUEST |
 723                                     FW_CMD_WRITE |
 724                                     FW_RSS_VI_CONFIG_CMD_VIID(viid));
 725        cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd));
 726        switch (adapter->params.rss.mode) {
 727        case FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL: {
 728                u32 word = 0;
 729
 730                if (config->basicvirtual.ip6fourtupen)
 731                        word |= FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN;
 732                if (config->basicvirtual.ip6twotupen)
 733                        word |= FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN;
 734                if (config->basicvirtual.ip4fourtupen)
 735                        word |= FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN;
 736                if (config->basicvirtual.ip4twotupen)
 737                        word |= FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN;
 738                if (config->basicvirtual.udpen)
 739                        word |= FW_RSS_VI_CONFIG_CMD_UDPEN;
 740                word |= FW_RSS_VI_CONFIG_CMD_DEFAULTQ(
 741                                config->basicvirtual.defaultq);
 742                cmd.u.basicvirtual.defaultq_to_udpen = cpu_to_be32(word);
 743                break;
 744        }
 745
 746        default:
 747                return -EINVAL;
 748        }
 749
 750        return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl);
 751}
 752
 753/**
 754 *      t4vf_config_rss_range - configure a portion of the RSS mapping table
 755 *      @adapter: the adapter
 756 *      @viid: Virtual Interface of RSS Table Slice
 757 *      @start: starting entry in the table to write
 758 *      @n: how many table entries to write
 759 *      @rspq: values for the "Response Queue" (Ingress Queue) lookup table
 760 *      @nrspq: number of values in @rspq
 761 *
 762 *      Programs the selected part of the VI's RSS mapping table with the
 763 *      provided values.  If @nrspq < @n the supplied values are used repeatedly
 764 *      until the full table range is populated.
 765 *
 766 *      The caller must ensure the values in @rspq are in the range 0..1023.
 767 */
 768int t4vf_config_rss_range(struct adapter *adapter, unsigned int viid,
 769                          int start, int n, const u16 *rspq, int nrspq)
 770{
 771        const u16 *rsp = rspq;
 772        const u16 *rsp_end = rspq+nrspq;
 773        struct fw_rss_ind_tbl_cmd cmd;
 774
 775        /*
 776         * Initialize firmware command template to write the RSS table.
 777         */
 778        memset(&cmd, 0, sizeof(cmd));
 779        cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_RSS_IND_TBL_CMD) |
 780                                     FW_CMD_REQUEST |
 781                                     FW_CMD_WRITE |
 782                                     FW_RSS_IND_TBL_CMD_VIID(viid));
 783        cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd));
 784
 785        /*
 786         * Each firmware RSS command can accommodate up to 32 RSS Ingress
 787         * Queue Identifiers.  These Ingress Queue IDs are packed three to
 788         * a 32-bit word as 10-bit values with the upper remaining 2 bits
 789         * reserved.
 790         */
 791        while (n > 0) {
 792                __be32 *qp = &cmd.iq0_to_iq2;
 793                int nq = min(n, 32);
 794                int ret;
 795
 796                /*
 797                 * Set up the firmware RSS command header to send the next
 798                 * "nq" Ingress Queue IDs to the firmware.
 799                 */
 800                cmd.niqid = cpu_to_be16(nq);
 801                cmd.startidx = cpu_to_be16(start);
 802
 803                /*
 804                 * "nq" more done for the start of the next loop.
 805                 */
 806                start += nq;
 807                n -= nq;
 808
 809                /*
 810                 * While there are still Ingress Queue IDs to stuff into the
 811                 * current firmware RSS command, retrieve them from the
 812                 * Ingress Queue ID array and insert them into the command.
 813                 */
 814                while (nq > 0) {
 815                        /*
 816                         * Grab up to the next 3 Ingress Queue IDs (wrapping
 817                         * around the Ingress Queue ID array if necessary) and
 818                         * insert them into the firmware RSS command at the
 819                         * current 3-tuple position within the commad.
 820                         */
 821                        u16 qbuf[3];
 822                        u16 *qbp = qbuf;
 823                        int nqbuf = min(3, nq);
 824
 825                        nq -= nqbuf;
 826                        qbuf[0] = qbuf[1] = qbuf[2] = 0;
 827                        while (nqbuf) {
 828                                nqbuf--;
 829                                *qbp++ = *rsp++;
 830                                if (rsp >= rsp_end)
 831                                        rsp = rspq;
 832                        }
 833                        *qp++ = cpu_to_be32(FW_RSS_IND_TBL_CMD_IQ0(qbuf[0]) |
 834                                            FW_RSS_IND_TBL_CMD_IQ1(qbuf[1]) |
 835                                            FW_RSS_IND_TBL_CMD_IQ2(qbuf[2]));
 836                }
 837
 838                /*
 839                 * Send this portion of the RRS table update to the firmware;
 840                 * bail out on any errors.
 841                 */
 842                ret = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL);
 843                if (ret)
 844                        return ret;
 845        }
 846        return 0;
 847}
 848
 849/**
 850 *      t4vf_alloc_vi - allocate a virtual interface on a port
 851 *      @adapter: the adapter
 852 *      @port_id: physical port associated with the VI
 853 *
 854 *      Allocate a new Virtual Interface and bind it to the indicated
 855 *      physical port.  Return the new Virtual Interface Identifier on
 856 *      success, or a [negative] error number on failure.
 857 */
 858int t4vf_alloc_vi(struct adapter *adapter, int port_id)
 859{
 860        struct fw_vi_cmd cmd, rpl;
 861        int v;
 862
 863        /*
 864         * Execute a VI command to allocate Virtual Interface and return its
 865         * VIID.
 866         */
 867        memset(&cmd, 0, sizeof(cmd));
 868        cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP(FW_VI_CMD) |
 869                                    FW_CMD_REQUEST |
 870                                    FW_CMD_WRITE |
 871                                    FW_CMD_EXEC);
 872        cmd.alloc_to_len16 = cpu_to_be32(FW_LEN16(cmd) |
 873                                         FW_VI_CMD_ALLOC);
 874        cmd.portid_pkd = FW_VI_CMD_PORTID(port_id);
 875        v = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl);
 876        if (v)
 877                return v;
 878
 879        return FW_VI_CMD_VIID_GET(be16_to_cpu(rpl.type_viid));
 880}
 881
 882/**
 883 *      t4vf_free_vi -- free a virtual interface
 884 *      @adapter: the adapter
 885 *      @viid: the virtual interface identifier
 886 *
 887 *      Free a previously allocated Virtual Interface.  Return an error on
 888 *      failure.
 889 */
 890int t4vf_free_vi(struct adapter *adapter, int viid)
 891{
 892        struct fw_vi_cmd cmd;
 893
 894        /*
 895         * Execute a VI command to free the Virtual Interface.
 896         */
 897        memset(&cmd, 0, sizeof(cmd));
 898        cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP(FW_VI_CMD) |
 899                                    FW_CMD_REQUEST |
 900                                    FW_CMD_EXEC);
 901        cmd.alloc_to_len16 = cpu_to_be32(FW_LEN16(cmd) |
 902                                         FW_VI_CMD_FREE);
 903        cmd.type_viid = cpu_to_be16(FW_VI_CMD_VIID(viid));
 904        return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL);
 905}
 906
 907/**
 908 *      t4vf_enable_vi - enable/disable a virtual interface
 909 *      @adapter: the adapter
 910 *      @viid: the Virtual Interface ID
 911 *      @rx_en: 1=enable Rx, 0=disable Rx
 912 *      @tx_en: 1=enable Tx, 0=disable Tx
 913 *
 914 *      Enables/disables a virtual interface.
 915 */
 916int t4vf_enable_vi(struct adapter *adapter, unsigned int viid,
 917                   bool rx_en, bool tx_en)
 918{
 919        struct fw_vi_enable_cmd cmd;
 920
 921        memset(&cmd, 0, sizeof(cmd));
 922        cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_VI_ENABLE_CMD) |
 923                                     FW_CMD_REQUEST |
 924                                     FW_CMD_EXEC |
 925                                     FW_VI_ENABLE_CMD_VIID(viid));
 926        cmd.ien_to_len16 = cpu_to_be32(FW_VI_ENABLE_CMD_IEN(rx_en) |
 927                                       FW_VI_ENABLE_CMD_EEN(tx_en) |
 928                                       FW_LEN16(cmd));
 929        return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL);
 930}
 931
 932/**
 933 *      t4vf_identify_port - identify a VI's port by blinking its LED
 934 *      @adapter: the adapter
 935 *      @viid: the Virtual Interface ID
 936 *      @nblinks: how many times to blink LED at 2.5 Hz
 937 *
 938 *      Identifies a VI's port by blinking its LED.
 939 */
 940int t4vf_identify_port(struct adapter *adapter, unsigned int viid,
 941                       unsigned int nblinks)
 942{
 943        struct fw_vi_enable_cmd cmd;
 944
 945        memset(&cmd, 0, sizeof(cmd));
 946        cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_VI_ENABLE_CMD) |
 947                                     FW_CMD_REQUEST |
 948                                     FW_CMD_EXEC |
 949                                     FW_VI_ENABLE_CMD_VIID(viid));
 950        cmd.ien_to_len16 = cpu_to_be32(FW_VI_ENABLE_CMD_LED |
 951                                       FW_LEN16(cmd));
 952        cmd.blinkdur = cpu_to_be16(nblinks);
 953        return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL);
 954}
 955
 956/**
 957 *      t4vf_set_rxmode - set Rx properties of a virtual interface
 958 *      @adapter: the adapter
 959 *      @viid: the VI id
 960 *      @mtu: the new MTU or -1 for no change
 961 *      @promisc: 1 to enable promiscuous mode, 0 to disable it, -1 no change
 962 *      @all_multi: 1 to enable all-multi mode, 0 to disable it, -1 no change
 963 *      @bcast: 1 to enable broadcast Rx, 0 to disable it, -1 no change
 964 *      @vlanex: 1 to enable hardware VLAN Tag extraction, 0 to disable it,
 965 *              -1 no change
 966 *
 967 *      Sets Rx properties of a virtual interface.
 968 */
 969int t4vf_set_rxmode(struct adapter *adapter, unsigned int viid,
 970                    int mtu, int promisc, int all_multi, int bcast, int vlanex,
 971                    bool sleep_ok)
 972{
 973        struct fw_vi_rxmode_cmd cmd;
 974
 975        /* convert to FW values */
 976        if (mtu < 0)
 977                mtu = FW_VI_RXMODE_CMD_MTU_MASK;
 978        if (promisc < 0)
 979                promisc = FW_VI_RXMODE_CMD_PROMISCEN_MASK;
 980        if (all_multi < 0)
 981                all_multi = FW_VI_RXMODE_CMD_ALLMULTIEN_MASK;
 982        if (bcast < 0)
 983                bcast = FW_VI_RXMODE_CMD_BROADCASTEN_MASK;
 984        if (vlanex < 0)
 985                vlanex = FW_VI_RXMODE_CMD_VLANEXEN_MASK;
 986
 987        memset(&cmd, 0, sizeof(cmd));
 988        cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_VI_RXMODE_CMD) |
 989                                     FW_CMD_REQUEST |
 990                                     FW_CMD_WRITE |
 991                                     FW_VI_RXMODE_CMD_VIID(viid));
 992        cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd));
 993        cmd.mtu_to_vlanexen =
 994                cpu_to_be32(FW_VI_RXMODE_CMD_MTU(mtu) |
 995                            FW_VI_RXMODE_CMD_PROMISCEN(promisc) |
 996                            FW_VI_RXMODE_CMD_ALLMULTIEN(all_multi) |
 997                            FW_VI_RXMODE_CMD_BROADCASTEN(bcast) |
 998                            FW_VI_RXMODE_CMD_VLANEXEN(vlanex));
 999        return t4vf_wr_mbox_core(adapter, &cmd, sizeof(cmd), NULL, sleep_ok);
1000}
1001
1002/**
1003 *      t4vf_alloc_mac_filt - allocates exact-match filters for MAC addresses
1004 *      @adapter: the adapter
1005 *      @viid: the Virtual Interface Identifier
1006 *      @free: if true any existing filters for this VI id are first removed
1007 *      @naddr: the number of MAC addresses to allocate filters for (up to 7)
1008 *      @addr: the MAC address(es)
1009 *      @idx: where to store the index of each allocated filter
1010 *      @hash: pointer to hash address filter bitmap
1011 *      @sleep_ok: call is allowed to sleep
1012 *
1013 *      Allocates an exact-match filter for each of the supplied addresses and
1014 *      sets it to the corresponding address.  If @idx is not %NULL it should
1015 *      have at least @naddr entries, each of which will be set to the index of
1016 *      the filter allocated for the corresponding MAC address.  If a filter
1017 *      could not be allocated for an address its index is set to 0xffff.
1018 *      If @hash is not %NULL addresses that fail to allocate an exact filter
1019 *      are hashed and update the hash filter bitmap pointed at by @hash.
1020 *
1021 *      Returns a negative error number or the number of filters allocated.
1022 */
1023int t4vf_alloc_mac_filt(struct adapter *adapter, unsigned int viid, bool free,
1024                        unsigned int naddr, const u8 **addr, u16 *idx,
1025                        u64 *hash, bool sleep_ok)
1026{
1027        int offset, ret = 0;
1028        unsigned nfilters = 0;
1029        unsigned int rem = naddr;
1030        struct fw_vi_mac_cmd cmd, rpl;
1031
1032        if (naddr > FW_CLS_TCAM_NUM_ENTRIES)
1033                return -EINVAL;
1034
1035        for (offset = 0; offset < naddr; /**/) {
1036                unsigned int fw_naddr = (rem < ARRAY_SIZE(cmd.u.exact)
1037                                         ? rem
1038                                         : ARRAY_SIZE(cmd.u.exact));
1039                size_t len16 = DIV_ROUND_UP(offsetof(struct fw_vi_mac_cmd,
1040                                                     u.exact[fw_naddr]), 16);
1041                struct fw_vi_mac_exact *p;
1042                int i;
1043
1044                memset(&cmd, 0, sizeof(cmd));
1045                cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_VI_MAC_CMD) |
1046                                             FW_CMD_REQUEST |
1047                                             FW_CMD_WRITE |
1048                                             (free ? FW_CMD_EXEC : 0) |
1049                                             FW_VI_MAC_CMD_VIID(viid));
1050                cmd.freemacs_to_len16 =
1051                        cpu_to_be32(FW_VI_MAC_CMD_FREEMACS(free) |
1052                                    FW_CMD_LEN16(len16));
1053
1054                for (i = 0, p = cmd.u.exact; i < fw_naddr; i++, p++) {
1055                        p->valid_to_idx = cpu_to_be16(
1056                                FW_VI_MAC_CMD_VALID |
1057                                FW_VI_MAC_CMD_IDX(FW_VI_MAC_ADD_MAC));
1058                        memcpy(p->macaddr, addr[offset+i], sizeof(p->macaddr));
1059                }
1060
1061
1062                ret = t4vf_wr_mbox_core(adapter, &cmd, sizeof(cmd), &rpl,
1063                                        sleep_ok);
1064                if (ret && ret != -ENOMEM)
1065                        break;
1066
1067                for (i = 0, p = rpl.u.exact; i < fw_naddr; i++, p++) {
1068                        u16 index = FW_VI_MAC_CMD_IDX_GET(
1069                                be16_to_cpu(p->valid_to_idx));
1070
1071                        if (idx)
1072                                idx[offset+i] =
1073                                        (index >= FW_CLS_TCAM_NUM_ENTRIES
1074                                         ? 0xffff
1075                                         : index);
1076                        if (index < FW_CLS_TCAM_NUM_ENTRIES)
1077                                nfilters++;
1078                        else if (hash)
1079                                *hash |= (1ULL << hash_mac_addr(addr[offset+i]));
1080                }
1081
1082                free = false;
1083                offset += fw_naddr;
1084                rem -= fw_naddr;
1085        }
1086
1087        /*
1088         * If there were no errors or we merely ran out of room in our MAC
1089         * address arena, return the number of filters actually written.
1090         */
1091        if (ret == 0 || ret == -ENOMEM)
1092                ret = nfilters;
1093        return ret;
1094}
1095
1096/**
1097 *      t4vf_change_mac - modifies the exact-match filter for a MAC address
1098 *      @adapter: the adapter
1099 *      @viid: the Virtual Interface ID
1100 *      @idx: index of existing filter for old value of MAC address, or -1
1101 *      @addr: the new MAC address value
1102 *      @persist: if idx < 0, the new MAC allocation should be persistent
1103 *
1104 *      Modifies an exact-match filter and sets it to the new MAC address.
1105 *      Note that in general it is not possible to modify the value of a given
1106 *      filter so the generic way to modify an address filter is to free the
1107 *      one being used by the old address value and allocate a new filter for
1108 *      the new address value.  @idx can be -1 if the address is a new
1109 *      addition.
1110 *
1111 *      Returns a negative error number or the index of the filter with the new
1112 *      MAC value.
1113 */
1114int t4vf_change_mac(struct adapter *adapter, unsigned int viid,
1115                    int idx, const u8 *addr, bool persist)
1116{
1117        int ret;
1118        struct fw_vi_mac_cmd cmd, rpl;
1119        struct fw_vi_mac_exact *p = &cmd.u.exact[0];
1120        size_t len16 = DIV_ROUND_UP(offsetof(struct fw_vi_mac_cmd,
1121                                             u.exact[1]), 16);
1122
1123        /*
1124         * If this is a new allocation, determine whether it should be
1125         * persistent (across a "freemacs" operation) or not.
1126         */
1127        if (idx < 0)
1128                idx = persist ? FW_VI_MAC_ADD_PERSIST_MAC : FW_VI_MAC_ADD_MAC;
1129
1130        memset(&cmd, 0, sizeof(cmd));
1131        cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_VI_MAC_CMD) |
1132                                     FW_CMD_REQUEST |
1133                                     FW_CMD_WRITE |
1134                                     FW_VI_MAC_CMD_VIID(viid));
1135        cmd.freemacs_to_len16 = cpu_to_be32(FW_CMD_LEN16(len16));
1136        p->valid_to_idx = cpu_to_be16(FW_VI_MAC_CMD_VALID |
1137                                      FW_VI_MAC_CMD_IDX(idx));
1138        memcpy(p->macaddr, addr, sizeof(p->macaddr));
1139
1140        ret = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl);
1141        if (ret == 0) {
1142                p = &rpl.u.exact[0];
1143                ret = FW_VI_MAC_CMD_IDX_GET(be16_to_cpu(p->valid_to_idx));
1144                if (ret >= FW_CLS_TCAM_NUM_ENTRIES)
1145                        ret = -ENOMEM;
1146        }
1147        return ret;
1148}
1149
1150/**
1151 *      t4vf_set_addr_hash - program the MAC inexact-match hash filter
1152 *      @adapter: the adapter
1153 *      @viid: the Virtual Interface Identifier
1154 *      @ucast: whether the hash filter should also match unicast addresses
1155 *      @vec: the value to be written to the hash filter
1156 *      @sleep_ok: call is allowed to sleep
1157 *
1158 *      Sets the 64-bit inexact-match hash filter for a virtual interface.
1159 */
1160int t4vf_set_addr_hash(struct adapter *adapter, unsigned int viid,
1161                       bool ucast, u64 vec, bool sleep_ok)
1162{
1163        struct fw_vi_mac_cmd cmd;
1164        size_t len16 = DIV_ROUND_UP(offsetof(struct fw_vi_mac_cmd,
1165                                             u.exact[0]), 16);
1166
1167        memset(&cmd, 0, sizeof(cmd));
1168        cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_VI_MAC_CMD) |
1169                                     FW_CMD_REQUEST |
1170                                     FW_CMD_WRITE |
1171                                     FW_VI_ENABLE_CMD_VIID(viid));
1172        cmd.freemacs_to_len16 = cpu_to_be32(FW_VI_MAC_CMD_HASHVECEN |
1173                                            FW_VI_MAC_CMD_HASHUNIEN(ucast) |
1174                                            FW_CMD_LEN16(len16));
1175        cmd.u.hash.hashvec = cpu_to_be64(vec);
1176        return t4vf_wr_mbox_core(adapter, &cmd, sizeof(cmd), NULL, sleep_ok);
1177}
1178
1179/**
1180 *      t4vf_get_port_stats - collect "port" statistics
1181 *      @adapter: the adapter
1182 *      @pidx: the port index
1183 *      @s: the stats structure to fill
1184 *
1185 *      Collect statistics for the "port"'s Virtual Interface.
1186 */
1187int t4vf_get_port_stats(struct adapter *adapter, int pidx,
1188                        struct t4vf_port_stats *s)
1189{
1190        struct port_info *pi = adap2pinfo(adapter, pidx);
1191        struct fw_vi_stats_vf fwstats;
1192        unsigned int rem = VI_VF_NUM_STATS;
1193        __be64 *fwsp = (__be64 *)&fwstats;
1194
1195        /*
1196         * Grab the Virtual Interface statistics a chunk at a time via mailbox
1197         * commands.  We could use a Work Request and get all of them at once
1198         * but that's an asynchronous interface which is awkward to use.
1199         */
1200        while (rem) {
1201                unsigned int ix = VI_VF_NUM_STATS - rem;
1202                unsigned int nstats = min(6U, rem);
1203                struct fw_vi_stats_cmd cmd, rpl;
1204                size_t len = (offsetof(struct fw_vi_stats_cmd, u) +
1205                              sizeof(struct fw_vi_stats_ctl));
1206                size_t len16 = DIV_ROUND_UP(len, 16);
1207                int ret;
1208
1209                memset(&cmd, 0, sizeof(cmd));
1210                cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_VI_STATS_CMD) |
1211                                             FW_VI_STATS_CMD_VIID(pi->viid) |
1212                                             FW_CMD_REQUEST |
1213                                             FW_CMD_READ);
1214                cmd.retval_len16 = cpu_to_be32(FW_CMD_LEN16(len16));
1215                cmd.u.ctl.nstats_ix =
1216                        cpu_to_be16(FW_VI_STATS_CMD_IX(ix) |
1217                                    FW_VI_STATS_CMD_NSTATS(nstats));
1218                ret = t4vf_wr_mbox_ns(adapter, &cmd, len, &rpl);
1219                if (ret)
1220                        return ret;
1221
1222                memcpy(fwsp, &rpl.u.ctl.stat0, sizeof(__be64) * nstats);
1223
1224                rem -= nstats;
1225                fwsp += nstats;
1226        }
1227
1228        /*
1229         * Translate firmware statistics into host native statistics.
1230         */
1231        s->tx_bcast_bytes = be64_to_cpu(fwstats.tx_bcast_bytes);
1232        s->tx_bcast_frames = be64_to_cpu(fwstats.tx_bcast_frames);
1233        s->tx_mcast_bytes = be64_to_cpu(fwstats.tx_mcast_bytes);
1234        s->tx_mcast_frames = be64_to_cpu(fwstats.tx_mcast_frames);
1235        s->tx_ucast_bytes = be64_to_cpu(fwstats.tx_ucast_bytes);
1236        s->tx_ucast_frames = be64_to_cpu(fwstats.tx_ucast_frames);
1237        s->tx_drop_frames = be64_to_cpu(fwstats.tx_drop_frames);
1238        s->tx_offload_bytes = be64_to_cpu(fwstats.tx_offload_bytes);
1239        s->tx_offload_frames = be64_to_cpu(fwstats.tx_offload_frames);
1240
1241        s->rx_bcast_bytes = be64_to_cpu(fwstats.rx_bcast_bytes);
1242        s->rx_bcast_frames = be64_to_cpu(fwstats.rx_bcast_frames);
1243        s->rx_mcast_bytes = be64_to_cpu(fwstats.rx_mcast_bytes);
1244        s->rx_mcast_frames = be64_to_cpu(fwstats.rx_mcast_frames);
1245        s->rx_ucast_bytes = be64_to_cpu(fwstats.rx_ucast_bytes);
1246        s->rx_ucast_frames = be64_to_cpu(fwstats.rx_ucast_frames);
1247
1248        s->rx_err_frames = be64_to_cpu(fwstats.rx_err_frames);
1249
1250        return 0;
1251}
1252
1253/**
1254 *      t4vf_iq_free - free an ingress queue and its free lists
1255 *      @adapter: the adapter
1256 *      @iqtype: the ingress queue type (FW_IQ_TYPE_FL_INT_CAP, etc.)
1257 *      @iqid: ingress queue ID
1258 *      @fl0id: FL0 queue ID or 0xffff if no attached FL0
1259 *      @fl1id: FL1 queue ID or 0xffff if no attached FL1
1260 *
1261 *      Frees an ingress queue and its associated free lists, if any.
1262 */
1263int t4vf_iq_free(struct adapter *adapter, unsigned int iqtype,
1264                 unsigned int iqid, unsigned int fl0id, unsigned int fl1id)
1265{
1266        struct fw_iq_cmd cmd;
1267
1268        memset(&cmd, 0, sizeof(cmd));
1269        cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP(FW_IQ_CMD) |
1270                                    FW_CMD_REQUEST |
1271                                    FW_CMD_EXEC);
1272        cmd.alloc_to_len16 = cpu_to_be32(FW_IQ_CMD_FREE |
1273                                         FW_LEN16(cmd));
1274        cmd.type_to_iqandstindex =
1275                cpu_to_be32(FW_IQ_CMD_TYPE(iqtype));
1276
1277        cmd.iqid = cpu_to_be16(iqid);
1278        cmd.fl0id = cpu_to_be16(fl0id);
1279        cmd.fl1id = cpu_to_be16(fl1id);
1280        return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL);
1281}
1282
1283/**
1284 *      t4vf_eth_eq_free - free an Ethernet egress queue
1285 *      @adapter: the adapter
1286 *      @eqid: egress queue ID
1287 *
1288 *      Frees an Ethernet egress queue.
1289 */
1290int t4vf_eth_eq_free(struct adapter *adapter, unsigned int eqid)
1291{
1292        struct fw_eq_eth_cmd cmd;
1293
1294        memset(&cmd, 0, sizeof(cmd));
1295        cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP(FW_EQ_ETH_CMD) |
1296                                    FW_CMD_REQUEST |
1297                                    FW_CMD_EXEC);
1298        cmd.alloc_to_len16 = cpu_to_be32(FW_EQ_ETH_CMD_FREE |
1299                                         FW_LEN16(cmd));
1300        cmd.eqid_pkd = cpu_to_be32(FW_EQ_ETH_CMD_EQID(eqid));
1301        return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL);
1302}
1303
1304/**
1305 *      t4vf_handle_fw_rpl - process a firmware reply message
1306 *      @adapter: the adapter
1307 *      @rpl: start of the firmware message
1308 *
1309 *      Processes a firmware message, such as link state change messages.
1310 */
1311int t4vf_handle_fw_rpl(struct adapter *adapter, const __be64 *rpl)
1312{
1313        const struct fw_cmd_hdr *cmd_hdr = (const struct fw_cmd_hdr *)rpl;
1314        u8 opcode = FW_CMD_OP_GET(be32_to_cpu(cmd_hdr->hi));
1315
1316        switch (opcode) {
1317        case FW_PORT_CMD: {
1318                /*
1319                 * Link/module state change message.
1320                 */
1321                const struct fw_port_cmd *port_cmd =
1322                        (const struct fw_port_cmd *)rpl;
1323                u32 word;
1324                int action, port_id, link_ok, speed, fc, pidx;
1325
1326                /*
1327                 * Extract various fields from port status change message.
1328                 */
1329                action = FW_PORT_CMD_ACTION_GET(
1330                        be32_to_cpu(port_cmd->action_to_len16));
1331                if (action != FW_PORT_ACTION_GET_PORT_INFO) {
1332                        dev_err(adapter->pdev_dev,
1333                                "Unknown firmware PORT reply action %x\n",
1334                                action);
1335                        break;
1336                }
1337
1338                port_id = FW_PORT_CMD_PORTID_GET(
1339                        be32_to_cpu(port_cmd->op_to_portid));
1340
1341                word = be32_to_cpu(port_cmd->u.info.lstatus_to_modtype);
1342                link_ok = (word & FW_PORT_CMD_LSTATUS) != 0;
1343                speed = 0;
1344                fc = 0;
1345                if (word & FW_PORT_CMD_RXPAUSE)
1346                        fc |= PAUSE_RX;
1347                if (word & FW_PORT_CMD_TXPAUSE)
1348                        fc |= PAUSE_TX;
1349                if (word & FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M))
1350                        speed = SPEED_100;
1351                else if (word & FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G))
1352                        speed = SPEED_1000;
1353                else if (word & FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_10G))
1354                        speed = SPEED_10000;
1355
1356                /*
1357                 * Scan all of our "ports" (Virtual Interfaces) looking for
1358                 * those bound to the physical port which has changed.  If
1359                 * our recorded state doesn't match the current state,
1360                 * signal that change to the OS code.
1361                 */
1362                for_each_port(adapter, pidx) {
1363                        struct port_info *pi = adap2pinfo(adapter, pidx);
1364                        struct link_config *lc;
1365
1366                        if (pi->port_id != port_id)
1367                                continue;
1368
1369                        lc = &pi->link_cfg;
1370                        if (link_ok != lc->link_ok || speed != lc->speed ||
1371                            fc != lc->fc) {
1372                                /* something changed */
1373                                lc->link_ok = link_ok;
1374                                lc->speed = speed;
1375                                lc->fc = fc;
1376                                t4vf_os_link_changed(adapter, pidx, link_ok);
1377                        }
1378                }
1379                break;
1380        }
1381
1382        default:
1383                dev_err(adapter->pdev_dev, "Unknown firmware reply %X\n",
1384                        opcode);
1385        }
1386        return 0;
1387}
1388
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.