diff options
author | David S. Miller <davem@davemloft.net> | 2016-11-16 06:24:42 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-11-16 06:24:42 +0300 |
commit | ceb980bc2c29dc0fafe6f108395626c6c46d5d55 (patch) | |
tree | fec666326abb74ae10b3497cf185402bdd88f4c6 | |
parent | 3418c6810ec01c0e548d75203c88fb4d6a49a22a (diff) | |
parent | 97a2532660c41118ba7bf9ddc11f6cb233fd6234 (diff) | |
download | linux-ceb980bc2c29dc0fafe6f108395626c6c46d5d55.tar.xz |
Merge branch 'liquidio-CN23XX-VF-support'
Raghu Vatsavayi says:
====================
liquidio CN23XX VF support
Following is the V6 patch series for adding VF support on
CN23XX devices. This version addressed:
1) Your concern for ordering of local variable declarations
from longest to shortest line.
2) Removed module parameters max_vfs, num_queues_per_{p,v}f.
3) Minor changes for fixing new checkpatch script related
errors on pre-existing driver.
4) Fixed compilation issues when CONFIG_PCI_IOV/CONFIG_PCI_ATS
options are disabled.
5) Modified qualifiers for printing mac addresses with pM format.
I will post remaining VF patches soon after this patchseries is
applied. Please apply patches in the following order as some of
the patches depend on earlier patches.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
33 files changed, 1687 insertions, 798 deletions
diff --git a/drivers/net/ethernet/cavium/liquidio/Makefile b/drivers/net/ethernet/cavium/liquidio/Makefile index 5a27b2a44039..14958de3126f 100644 --- a/drivers/net/ethernet/cavium/liquidio/Makefile +++ b/drivers/net/ethernet/cavium/liquidio/Makefile @@ -11,6 +11,7 @@ liquidio-$(CONFIG_LIQUIDIO) += lio_ethtool.o \ cn66xx_device.o \ cn68xx_device.o \ cn23xx_pf_device.o \ + octeon_mailbox.o \ octeon_mem_ops.o \ octeon_droq.o \ octeon_nic.o diff --git a/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c b/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c index 380a64115a98..962dcbcef8b5 100644 --- a/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c +++ b/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c @@ -1,28 +1,23 @@ /********************************************************************** -* Author: Cavium, Inc. -* -* Contact: support@cavium.com -* Please include "LiquidIO" in the subject. -* -* Copyright (c) 2003-2015 Cavium, Inc. -* -* This file is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License, Version 2, as -* published by the Free Software Foundation. -* -* This file is distributed in the hope that it will be useful, but -* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -* NONINFRINGEMENT. See the GNU General Public License for more -* details. -* -* This file may also be available under a different license from Cavium. -* Contact Cavium, Inc. for more information -**********************************************************************/ - + * Author: Cavium, Inc. + * + * Contact: support@cavium.com + * Please include "LiquidIO" in the subject. + * + * Copyright (c) 2003-2016 Cavium, Inc. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, Version 2, as + * published by the Free Software Foundation. + * + * This file is distributed in the hope that it will be useful, but + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or + * NONINFRINGEMENT. See the GNU General Public License for more details. + ***********************************************************************/ #include <linux/pci.h> -#include <linux/netdevice.h> #include <linux/vmalloc.h> +#include <linux/etherdevice.h> #include "liquidio_common.h" #include "octeon_droq.h" #include "octeon_iq.h" @@ -30,6 +25,7 @@ #include "octeon_device.h" #include "cn23xx_pf_device.h" #include "octeon_main.h" +#include "octeon_mailbox.h" #define RESET_NOTDONE 0 #define RESET_DONE 1 @@ -40,11 +36,6 @@ */ #define CN23XX_INPUT_JABBER 64600 -#define LIOLUT_RING_DISTRIBUTION 9 -const int liolut_num_vfs_to_rings_per_vf[LIOLUT_RING_DISTRIBUTION] = { - 0, 8, 4, 2, 2, 2, 1, 1, 1 -}; - void cn23xx_dump_pf_initialized_regs(struct octeon_device *oct) { int i = 0; @@ -309,9 +300,10 @@ u32 cn23xx_pf_get_oq_ticks(struct octeon_device *oct, u32 time_intr_in_us) static void cn23xx_setup_global_mac_regs(struct octeon_device *oct) { - u64 reg_val; u16 mac_no = oct->pcie_port; u16 pf_num = oct->pf_num; + u64 reg_val; + u64 temp; /* programming SRN and TRS for each MAC(0..3) */ @@ -333,6 +325,14 @@ static void cn23xx_setup_global_mac_regs(struct octeon_device *oct) /* setting TRS <23:16> */ reg_val = reg_val | (oct->sriov_info.trs << CN23XX_PKT_MAC_CTL_RINFO_TRS_BIT_POS); + /* setting RPVF <39:32> */ + temp = oct->sriov_info.rings_per_vf & 0xff; + reg_val |= (temp << CN23XX_PKT_MAC_CTL_RINFO_RPVF_BIT_POS); + + /* setting NVFS <55:48> */ + temp = oct->sriov_info.max_vfs & 0xff; + reg_val |= (temp << CN23XX_PKT_MAC_CTL_RINFO_NVFS_BIT_POS); + /* write these settings to MAC register */ octeon_write_csr64(oct, CN23XX_SLI_PKT_MAC_RINFO64(mac_no, pf_num), reg_val); @@ -399,11 +399,12 @@ static int cn23xx_reset_io_queues(struct octeon_device *oct) static int cn23xx_pf_setup_global_input_regs(struct octeon_device *oct) { + struct octeon_cn23xx_pf *cn23xx = (struct octeon_cn23xx_pf *)oct->chip; + struct octeon_instr_queue *iq; + u64 intr_threshold, reg_val; u32 q_no, ern, srn; u64 pf_num; - u64 intr_threshold, reg_val; - struct octeon_instr_queue *iq; - struct octeon_cn23xx_pf *cn23xx = (struct octeon_cn23xx_pf *)oct->chip; + u64 vf_num; pf_num = oct->pf_num; @@ -414,12 +415,22 @@ static int cn23xx_pf_setup_global_input_regs(struct octeon_device *oct) return -1; /** Set the MAC_NUM and PVF_NUM in IQ_PKT_CONTROL reg - * for all queues.Only PF can set these bits. - * bits 29:30 indicate the MAC num. - * bits 32:47 indicate the PVF num. - */ + * for all queues.Only PF can set these bits. + * bits 29:30 indicate the MAC num. + * bits 32:47 indicate the PVF num. + */ for (q_no = 0; q_no < ern; q_no++) { reg_val = oct->pcie_port << CN23XX_PKT_INPUT_CTL_MAC_NUM_POS; + + /* for VF assigned queues. */ + if (q_no < oct->sriov_info.pf_srn) { + vf_num = q_no / oct->sriov_info.rings_per_vf; + vf_num += 1; /* VF1, VF2,........ */ + } else { + vf_num = 0; + } + + reg_val |= vf_num << CN23XX_PKT_INPUT_CTL_VF_NUM_POS; reg_val |= pf_num << CN23XX_PKT_INPUT_CTL_PF_NUM_POS; octeon_write_csr64(oct, CN23XX_SLI_IQ_PKT_CONTROL64(q_no), @@ -530,8 +541,8 @@ static void cn23xx_pf_setup_global_output_regs(struct octeon_device *oct) writeq(0x40, (u8 *)oct->mmio[0].hw_addr + CN23XX_SLI_OQ_WMARK); /** Disabling setting OQs in reset when ring has no dorebells - * enabling this will cause of head of line blocking - */ + * enabling this will cause of head of line blocking + */ /* Do it only for pass1.1. and pass1.2 */ if ((oct->rev_id == OCTEON_CN23XX_REV_1_0) || (oct->rev_id == OCTEON_CN23XX_REV_1_1)) @@ -662,6 +673,118 @@ static void cn23xx_setup_oq_regs(struct octeon_device *oct, u32 oq_no) } } +static void cn23xx_pf_mbox_thread(struct work_struct *work) +{ + struct cavium_wk *wk = (struct cavium_wk *)work; + struct octeon_mbox *mbox = (struct octeon_mbox *)wk->ctxptr; + struct octeon_device *oct = mbox->oct_dev; + u64 mbox_int_val, val64; + u32 q_no, i; + + if (oct->rev_id < OCTEON_CN23XX_REV_1_1) { + /*read and clear by writing 1*/ + mbox_int_val = readq(mbox->mbox_int_reg); + writeq(mbox_int_val, mbox->mbox_int_reg); + + for (i = 0; i < oct->sriov_info.num_vfs_alloced; i++) { + q_no = i * oct->sriov_info.rings_per_vf; + + val64 = readq(oct->mbox[q_no]->mbox_write_reg); + + if (val64 && (val64 != OCTEON_PFVFACK)) { + if (octeon_mbox_read(oct->mbox[q_no])) + octeon_mbox_process_message( + oct->mbox[q_no]); + } + } + + schedule_delayed_work(&wk->work, msecs_to_jiffies(10)); + } else { + octeon_mbox_process_message(mbox); + } +} + +static int cn23xx_setup_pf_mbox(struct octeon_device *oct) +{ + struct octeon_mbox *mbox = NULL; + u16 mac_no = oct->pcie_port; + u16 pf_num = oct->pf_num; + u32 q_no, i; + + if (!oct->sriov_info.max_vfs) + return 0; + + for (i = 0; i < oct->sriov_info.max_vfs; i++) { + q_no = i * oct->sriov_info.rings_per_vf; + + mbox = vmalloc(sizeof(*mbox)); + if (!mbox) + goto free_mbox; + + memset(mbox, 0, sizeof(struct octeon_mbox)); + + spin_lock_init(&mbox->lock); + + mbox->oct_dev = oct; + + mbox->q_no = q_no; + + mbox->state = OCTEON_MBOX_STATE_IDLE; + + /* PF mbox interrupt reg */ + mbox->mbox_int_reg = (u8 *)oct->mmio[0].hw_addr + + CN23XX_SLI_MAC_PF_MBOX_INT(mac_no, pf_num); + + /* PF writes into SIG0 reg */ + mbox->mbox_write_reg = (u8 *)oct->mmio[0].hw_addr + + CN23XX_SLI_PKT_PF_VF_MBOX_SIG(q_no, 0); + + /* PF reads from SIG1 reg */ + mbox->mbox_read_reg = (u8 *)oct->mmio[0].hw_addr + + CN23XX_SLI_PKT_PF_VF_MBOX_SIG(q_no, 1); + + /*Mail Box Thread creation*/ + INIT_DELAYED_WORK(&mbox->mbox_poll_wk.work, + cn23xx_pf_mbox_thread); + mbox->mbox_poll_wk.ctxptr = (void *)mbox; + + oct->mbox[q_no] = mbox; + + writeq(OCTEON_PFVFSIG, mbox->mbox_read_reg); + } + + if (oct->rev_id < OCTEON_CN23XX_REV_1_1) + schedule_delayed_work(&oct->mbox[0]->mbox_poll_wk.work, + msecs_to_jiffies(0)); + + return 0; + +free_mbox: + while (i) { + i--; + vfree(oct->mbox[i]); + } + + return 1; +} + +static int cn23xx_free_pf_mbox(struct octeon_device *oct) +{ + u32 q_no, i; + + if (!oct->sriov_info.max_vfs) + return 0; + + for (i = 0; i < oct->sriov_info.max_vfs; i++) { + q_no = i * oct->sriov_info.rings_per_vf; + cancel_delayed_work_sync( + &oct->mbox[q_no]->mbox_poll_wk.work); + vfree(oct->mbox[q_no]); + } + + return 0; +} + static int cn23xx_enable_io_queues(struct octeon_device *oct) { u64 reg_val; @@ -856,6 +979,29 @@ static u64 cn23xx_pf_msix_interrupt_handler(void *dev) return ret; } +static void cn23xx_handle_pf_mbox_intr(struct octeon_device *oct) +{ + struct delayed_work *work; + u64 mbox_int_val; + u32 i, q_no; + + mbox_int_val = readq(oct->mbox[0]->mbox_int_reg); + + for (i = 0; i < oct->sriov_info.num_vfs_alloced; i++) { + q_no = i * oct->sriov_info.rings_per_vf; + + if (mbox_int_val & BIT_ULL(q_no)) { + writeq(BIT_ULL(q_no), + oct->mbox[0]->mbox_int_reg); + if (octeon_mbox_read(oct->mbox[q_no])) { + work = &oct->mbox[q_no]->mbox_poll_wk.work; + schedule_delayed_work(work, + msecs_to_jiffies(0)); + } + } + } +} + static irqreturn_t cn23xx_interrupt_handler(void *dev) { struct octeon_device *oct = (struct octeon_device *)dev; @@ -871,6 +1017,10 @@ static irqreturn_t cn23xx_interrupt_handler(void *dev) dev_err(&oct->pci_dev->dev, "OCTEON[%d]: Error Intr: 0x%016llx\n", oct->octeon_id, CVM_CAST64(intr64)); + /* When VFs write into MBOX_SIG2 reg,these intr is set in PF */ + if (intr64 & CN23XX_INTR_VF_MBOX) + cn23xx_handle_pf_mbox_intr(oct); + if (oct->msix_on != LIO_FLAG_MSIX_ENABLED) { if (intr64 & CN23XX_INTR_PKT_DATA) oct->int_status |= OCT_DEV_INTR_PKT_DATA; @@ -961,6 +1111,13 @@ static void cn23xx_enable_pf_interrupt(struct octeon_device *oct, u8 intr_flag) intr_val = readq(cn23xx->intr_enb_reg64); intr_val |= CN23XX_INTR_PKT_DATA; writeq(intr_val, cn23xx->intr_enb_reg64); + } else if ((intr_flag & OCTEON_MBOX_INTR) && + (oct->sriov_info.max_vfs > 0)) { + if (oct->rev_id >= OCTEON_CN23XX_REV_1_1) { + intr_val = readq(cn23xx->intr_enb_reg64); + intr_val |= CN23XX_INTR_VF_MBOX; + writeq(intr_val, cn23xx->intr_enb_reg64); + } } } @@ -976,6 +1133,13 @@ static void cn23xx_disable_pf_interrupt(struct octeon_device *oct, u8 intr_flag) intr_val = readq(cn23xx->intr_enb_reg64); intr_val &= ~CN23XX_INTR_PKT_DATA; writeq(intr_val, cn23xx->intr_enb_reg64); + } else if ((intr_flag & OCTEON_MBOX_INTR) && + (oct->sriov_info.max_vfs > 0)) { + if (oct->rev_id >= OCTEON_CN23XX_REV_1_1) { + intr_val = readq(cn23xx->intr_enb_reg64); + intr_val &= ~CN23XX_INTR_VF_MBOX; + writeq(intr_val, cn23xx->intr_enb_reg64); + } } } @@ -1048,50 +1212,59 @@ static void cn23xx_setup_reg_address(struct octeon_device *oct) static int cn23xx_sriov_config(struct octeon_device *oct) { - u32 total_rings; struct octeon_cn23xx_pf *cn23xx = (struct octeon_cn23xx_pf *)oct->chip; - /* num_vfs is already filled for us */ + u32 max_rings, total_rings, max_vfs, rings_per_vf; u32 pf_srn, num_pf_rings; + u32 max_possible_vfs; cn23xx->conf = - (struct octeon_config *)oct_get_config_info(oct, LIO_23XX); + (struct octeon_config *)oct_get_config_info(oct, LIO_23XX); switch (oct->rev_id) { case OCTEON_CN23XX_REV_1_0: - total_rings = CN23XX_MAX_RINGS_PER_PF_PASS_1_0; + max_rings = CN23XX_MAX_RINGS_PER_PF_PASS_1_0; + max_possible_vfs = CN23XX_MAX_VFS_PER_PF_PASS_1_0; break; case OCTEON_CN23XX_REV_1_1: - total_rings = CN23XX_MAX_RINGS_PER_PF_PASS_1_1; + max_rings = CN23XX_MAX_RINGS_PER_PF_PASS_1_1; + max_possible_vfs = CN23XX_MAX_VFS_PER_PF_PASS_1_1; break; default: - total_rings = CN23XX_MAX_RINGS_PER_PF; + max_rings = CN23XX_MAX_RINGS_PER_PF; + max_possible_vfs = CN23XX_MAX_VFS_PER_PF; break; } - if (!oct->sriov_info.num_pf_rings) { - if (total_rings > num_present_cpus()) - num_pf_rings = num_present_cpus(); - else - num_pf_rings = total_rings; - } else { - num_pf_rings = oct->sriov_info.num_pf_rings; - if (num_pf_rings > total_rings) { - dev_warn(&oct->pci_dev->dev, - "num_queues_per_pf requested %u is more than available rings. Reducing to %u\n", - num_pf_rings, total_rings); - num_pf_rings = total_rings; - } - } + if (max_rings <= num_present_cpus()) + num_pf_rings = 1; + else + num_pf_rings = num_present_cpus(); + +#ifdef CONFIG_PCI_IOV + max_vfs = min_t(u32, + (max_rings - num_pf_rings), max_possible_vfs); + rings_per_vf = 1; +#else + max_vfs = 0; + rings_per_vf = 0; +#endif + + total_rings = num_pf_rings + max_vfs; - total_rings = num_pf_rings; /* the first ring of the pf */ pf_srn = total_rings - num_pf_rings; oct->sriov_info.trs = total_rings; + oct->sriov_info.max_vfs = max_vfs; + oct->sriov_info.rings_per_vf = rings_per_vf; oct->sriov_info.pf_srn = pf_srn; oct->sriov_info.num_pf_rings = num_pf_rings; - dev_dbg(&oct->pci_dev->dev, "trs:%d pf_srn:%d num_pf_rings:%d\n", - oct->sriov_info.trs, oct->sriov_info.pf_srn, - oct->sriov_info.num_pf_rings); + dev_notice(&oct->pci_dev->dev, "trs:%d max_vfs:%d rings_per_vf:%d pf_srn:%d num_pf_rings:%d\n", + oct->sriov_info.trs, oct->sriov_info.max_vfs, + oct->sriov_info.rings_per_vf, oct->sriov_info.pf_srn, + oct->sriov_info.num_pf_rings); + + oct->sriov_info.sriov_enabled = 0; + return 0; } @@ -1119,6 +1292,9 @@ int setup_cn23xx_octeon_pf_device(struct octeon_device *oct) oct->fn_list.setup_iq_regs = cn23xx_setup_iq_regs; oct->fn_list.setup_oq_regs = cn23xx_setup_oq_regs; + oct->fn_list.setup_mbox = cn23xx_setup_pf_mbox; + oct->fn_list.free_mbox = cn23xx_free_pf_mbox; + oct->fn_list.process_interrupt_regs = cn23xx_interrupt_handler; oct->fn_list.msix_interrupt_handler = cn23xx_pf_msix_interrupt_handler; @@ -1209,8 +1385,7 @@ void cn23xx_dump_iq_regs(struct octeon_device *oct) dev_dbg(&oct->pci_dev->dev, "SLI_PKT[%d]_INPUT_CTL [0x%x]: 0x%016llx\n", q_no, CN23XX_SLI_IQ_PKT_CONTROL64(q_no), CVM_CAST64(octeon_read_csr64 - (oct, - CN23XX_SLI_IQ_PKT_CONTROL64(q_no)))); + (oct, CN23XX_SLI_IQ_PKT_CONTROL64(q_no)))); } pci_read_config_dword(oct->pci_dev, CN23XX_CONFIG_PCIE_DEVCTL, ®val); @@ -1235,3 +1410,24 @@ int cn23xx_fw_loaded(struct octeon_device *oct) val = octeon_read_csr64(oct, CN23XX_SLI_SCRATCH1); return (val >> 1) & 1ULL; } + +void cn23xx_tell_vf_its_macaddr_changed(struct octeon_device *oct, int vfidx, + u8 *mac) +{ + if (oct->sriov_info.vf_drv_loaded_mask & BIT_ULL(vfidx)) { + struct octeon_mbox_cmd mbox_cmd; + + mbox_cmd.msg.u64 = 0; + mbox_cmd.msg.s.type = OCTEON_MBOX_REQUEST; + mbox_cmd.msg.s.resp_needed = 0; + mbox_cmd.msg.s.cmd = OCTEON_PF_CHANGED_VF_MACADDR; + mbox_cmd.msg.s.len = 1; + mbox_cmd.recv_len = 0; + mbox_cmd.recv_status = 0; + mbox_cmd.fn = NULL; + mbox_cmd.fn_arg = 0; + ether_addr_copy(mbox_cmd.msg.s.params, mac); + mbox_cmd.q_no = vfidx * oct->sriov_info.rings_per_vf; + octeon_mbox_write(oct, &mbox_cmd); + } +} diff --git a/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.h b/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.h index 21b5c9051967..2fedd91f3df8 100644 --- a/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.h +++ b/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.h @@ -1,34 +1,31 @@ /********************************************************************** -* Author: Cavium, Inc. -* -* Contact: support@cavium.com -* Please include "LiquidIO" in the subject. -* -* Copyright (c) 2003-2015 Cavium, Inc. -* -* This file is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License, Version 2, as -* published by the Free Software Foundation. -* -* This file is distributed in the hope that it will be useful, but -* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -* NONINFRINGEMENT. See the GNU General Public License for more -* details. -* -* This file may also be available under a different license from Cavium. -* Contact Cavium, Inc. for more information -**********************************************************************/ - + * Author: Cavium, Inc. + * + * Contact: support@cavium.com + * Please include "LiquidIO" in the subject. + * + * Copyright (c) 2003-2016 Cavium, Inc. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, Version 2, as + * published by the Free Software Foundation. + * + * This file is distributed in the hope that it will be useful, but + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or + * NONINFRINGEMENT. See the GNU General Public License for more details. + ***********************************************************************/ /*! \file cn23xx_device.h * \brief Host Driver: Routines that perform CN23XX specific operations. -*/ + */ #ifndef __CN23XX_PF_DEVICE_H__ #define __CN23XX_PF_DEVICE_H__ #include "cn23xx_pf_regs.h" +#define LIO_CMD_WAIT_TM 100 + /* Register address and configuration for a CN23XX devices. * If device specific changes need to be made then add a struct to include * device specific fields as shown in the commented section @@ -56,4 +53,7 @@ u32 cn23xx_pf_get_oq_ticks(struct octeon_device *oct, u32 time_intr_in_us); void cn23xx_dump_pf_initialized_regs(struct octeon_device *oct); int cn23xx_fw_loaded(struct octeon_device *oct); + +void cn23xx_tell_vf_its_macaddr_changed(struct octeon_device *oct, int vfidx, + u8 *mac); #endif diff --git a/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_regs.h b/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_regs.h index 03d79d95ab75..e6d4ad99cc38 100644 --- a/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_regs.h +++ b/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_regs.h @@ -1,29 +1,24 @@ /********************************************************************** -* Author: Cavium, Inc. -* -* Contact: support@cavium.com -* Please include "LiquidIO" in the subject. -* -* Copyright (c) 2003-2015 Cavium, Inc. -* -* This file is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License, Version 2, as -* published by the Free Software Foundation. -* -* This file is distributed in the hope that it will be useful, but -* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -* NONINFRINGEMENT. See the GNU General Public License for more -* details. -* -* This file may also be available under a different license from Cavium. -* Contact Cavium, Inc. for more information -**********************************************************************/ - + * Author: Cavium, Inc. + * + * Contact: support@cavium.com + * Please include "LiquidIO" in the subject. + * + * Copyright (c) 2003-2016 Cavium, Inc. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, Version 2, as + * published by the Free Software Foundation. + * + * This file is distributed in the hope that it will be useful, but + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or + * NONINFRINGEMENT. See the GNU General Public License for more details. + ***********************************************************************/ /*! \file cn23xx_regs.h * \brief Host Driver: Register Address and Register Mask values for * Octeon CN23XX devices. -*/ + */ #ifndef __CN23XX_PF_REGS_H__ #define __CN23XX_PF_REGS_H__ @@ -63,7 +58,7 @@ #define CN23XX_CONFIG_SRIOV_BAR_START 0x19C #define CN23XX_CONFIG_SRIOV_BARX(i) \ - (CN23XX_CONFIG_SRIOV_BAR_START + (i * 4)) + (CN23XX_CONFIG_SRIOV_BAR_START + ((i) * 4)) #define CN23XX_CONFIG_SRIOV_BAR_PF 0x08 #define CN23XX_CONFIG_SRIOV_BAR_64BIT 0x04 #define CN23XX_CONFIG_SRIOV_BAR_IO 0x01 @@ -513,7 +508,7 @@ /* 4 Registers (64 - bit) */ #define CN23XX_SLI_S2M_PORT_CTL_START 0x23D80 #define CN23XX_SLI_S2M_PORTX_CTL(port) \ - (CN23XX_SLI_S2M_PORT_CTL_START + (port * 0x10)) + (CN23XX_SLI_S2M_PORT_CTL_START + ((port) * 0x10)) #define CN23XX_SLI_MAC_NUMBER 0x20050 @@ -554,26 +549,26 @@ * Provides DMA Engine Queue Enable */ #define CN23XX_DPI_DMA_ENG0_ENB 0x0001df0000000080ULL -#define CN23XX_DPI_DMA_ENG_ENB(eng) (CN23XX_DPI_DMA_ENG0_ENB + (eng * 8)) +#define CN23XX_DPI_DMA_ENG_ENB(eng) (CN23XX_DPI_DMA_ENG0_ENB + ((eng) * 8)) /* 8 register (64-bit) - DPI_DMA(0..7)_REQQ_CTL * Provides control bits for transaction on 8 Queues */ #define CN23XX_DPI_DMA_REQQ0_CTL 0x0001df0000000180ULL #define CN23XX_DPI_DMA_REQQ_CTL(q_no) \ - (CN23XX_DPI_DMA_REQQ0_CTL + (q_no * 8)) + (CN23XX_DPI_DMA_REQQ0_CTL + ((q_no) * 8)) /* 6 register (64-bit) - DPI_ENG(0..5)_BUF * Provides DMA Engine FIFO (Queue) Size */ #define CN23XX_DPI_DMA_ENG0_BUF 0x0001df0000000880ULL #define CN23XX_DPI_DMA_ENG_BUF(eng) \ - (CN23XX_DPI_DMA_ENG0_BUF + (eng * 8)) + (CN23XX_DPI_DMA_ENG0_BUF + ((eng) * 8)) /* 4 Registers (64-bit) */ #define CN23XX_DPI_SLI_PRT_CFG_START 0x0001df0000000900ULL #define CN23XX_DPI_SLI_PRTX_CFG(port) \ - (CN23XX_DPI_SLI_PRT_CFG_START + (port * 0x8)) + (CN23XX_DPI_SLI_PRT_CFG_START + ((port) * 0x8)) /* Masks for DPI_DMA_CONTROL Register */ #define CN23XX_DPI_DMA_COMMIT_MODE BIT_ULL(58) diff --git a/drivers/net/ethernet/cavium/liquidio/cn66xx_device.c b/drivers/net/ethernet/cavium/liquidio/cn66xx_device.c index e779af88621b..bdec051107a6 100644 --- a/drivers/net/ethernet/cavium/liquidio/cn66xx_device.c +++ b/drivers/net/ethernet/cavium/liquidio/cn66xx_device.c @@ -1,24 +1,20 @@ /********************************************************************** -* Author: Cavium, Inc. -* -* Contact: support@cavium.com -* Please include "LiquidIO" in the subject. -* -* Copyright (c) 2003-2015 Cavium, Inc. -* -* This file is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License, Version 2, as -* published by the Free Software Foundation. -* -* This file is distributed in the hope that it will be useful, but -* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -* NONINFRINGEMENT. See the GNU General Public License for more -* details. -* -* This file may also be available under a different license from Cavium. -* Contact Cavium, Inc. for more information -**********************************************************************/ + * Author: Cavium, Inc. + * + * Contact: support@cavium.com + * Please include "LiquidIO" in the subject. + * + * Copyright (c) 2003-2016 Cavium, Inc. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, Version 2, as + * published by the Free Software Foundation. + * + * This file is distributed in the hope that it will be useful, but + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or + * NONINFRINGEMENT. See the GNU General Public License for more details. + ***********************************************************************/ #include <linux/pci.h> #include <linux/netdevice.h> #include "liquidio_common.h" @@ -275,7 +271,6 @@ void lio_cn6xxx_setup_iq_regs(struct octeon_device *oct, u32 iq_no) { struct octeon_instr_queue *iq = oct->instr_queue[iq_no]; - /* Disable Packet-by-Packet mode; No Parse Mode or Skip length */ octeon_write_csr64(oct, CN6XXX_SLI_IQ_PKT_INSTR_HDR64(iq_no), 0); /* Write the start of the input queue's ring and its size */ @@ -378,7 +373,7 @@ void lio_cn6xxx_disable_io_queues(struct octeon_device *oct) /* Reset the doorbell register for each Input queue. */ for (i = 0; i < MAX_OCTEON_INSTR_QUEUES(oct); i++) { - if (!(oct->io_qmask.iq & (1ULL << i))) + if (!(oct->io_qmask.iq & BIT_ULL(i))) continue; octeon_write_csr(oct, CN6XXX_SLI_IQ_DOORBELL(i), 0xFFFFFFFF); d32 = octeon_read_csr(oct, CN6XXX_SLI_IQ_DOORBELL(i)); @@ -400,9 +395,8 @@ void lio_cn6xxx_disable_io_queues(struct octeon_device *oct) ; /* Reset the doorbell register for each Output queue. */ - /* for (i = 0; i < oct->num_oqs; i++) { */ for (i = 0; i < MAX_OCTEON_OUTPUT_QUEUES(oct); i++) { - if (!(oct->io_qmask.oq & (1ULL << i))) + if (!(oct->io_qmask.oq & BIT_ULL(i))) continue; octeon_write_csr(oct, CN6XXX_SLI_OQ_PKTS_CREDIT(i), 0xFFFFFFFF); d32 = octeon_read_csr(oct, CN6XXX_SLI_OQ_PKTS_CREDIT(i)); @@ -537,15 +531,14 @@ static int lio_cn6xxx_process_droq_intr_regs(struct octeon_device *oct) oct->droq_intr = 0; - /* for (oq_no = 0; oq_no < oct->num_oqs; oq_no++) { */ for (oq_no = 0; oq_no < MAX_OCTEON_OUTPUT_QUEUES(oct); oq_no++) { - if (!(droq_mask & (1ULL << oq_no))) + if (!(droq_mask & BIT_ULL(oq_no))) continue; droq = oct->droq[oq_no]; pkt_count = octeon_droq_check_hw_for_pkts(droq); if (pkt_count) { - oct->droq_intr |= (1ULL << oq_no); + oct->droq_intr |= BIT_ULL(oq_no); if (droq->ops.poll_mode) { u32 value; u32 reg; @@ -721,8 +714,6 @@ int lio_setup_cn66xx_octeon_device(struct octeon_device *oct) int lio_validate_cn6xxx_config_info(struct octeon_device *oct, struct octeon_config *conf6xxx) { - /* int total_instrs = 0; */ - if (CFG_GET_IQ_MAX_Q(conf6xxx) > CN6XXX_MAX_INPUT_QUEUES) { dev_err(&oct->pci_dev->dev, "%s: Num IQ (%d) exceeds Max (%d)\n", __func__, CFG_GET_IQ_MAX_Q(conf6xxx), diff --git a/drivers/net/ethernet/cavium/liquidio/cn66xx_device.h b/drivers/net/ethernet/cavium/liquidio/cn66xx_device.h index a40a91394079..8ed57134ee0c 100644 --- a/drivers/net/ethernet/cavium/liquidio/cn66xx_device.h +++ b/drivers/net/ethernet/cavium/liquidio/cn66xx_device.h @@ -1,25 +1,20 @@ /********************************************************************** -* Author: Cavium, Inc. -* -* Contact: support@cavium.com -* Please include "LiquidIO" in the subject. -* -* Copyright (c) 2003-2015 Cavium, Inc. -* -* This file is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License, Version 2, as -* published by the Free Software Foundation. -* -* This file is distributed in the hope that it will be useful, but -* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -* NONINFRINGEMENT. See the GNU General Public License for more -* details. -* -* This file may also be available under a different license from Cavium. -* Contact Cavium, Inc. for more information -**********************************************************************/ - + * Author: Cavium, Inc. + * + * Contact: support@cavium.com + * Please include "LiquidIO" in the subject. + * + * Copyright (c) 2003-2016 Cavium, Inc. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, Version 2, as + * published by the Free Software Foundation. + * + * This file is distributed in the hope that it will be useful, but + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or + * NONINFRINGEMENT. See the GNU General Public License for more details. + ***********************************************************************/ /*! \file cn66xx_device.h * \brief Host Driver: Routines that perform CN66XX specific operations. */ @@ -96,8 +91,8 @@ void lio_cn6xxx_setup_reg_address(struct octeon_device *oct, void *chip, struct octeon_reg_list *reg_list); u32 lio_cn6xxx_coprocessor_clock(struct octeon_device *oct); u32 lio_cn6xxx_get_oq_ticks(struct octeon_device *oct, u32 time_intr_in_us); -int lio_setup_cn66xx_octeon_device(struct octeon_device *); +int lio_setup_cn66xx_octeon_device(struct octeon_device *oct); int lio_validate_cn6xxx_config_info(struct octeon_device *oct, - struct octeon_config *); + struct octeon_config *conf6xxx); #endif diff --git a/drivers/net/ethernet/cavium/liquidio/cn66xx_regs.h b/drivers/net/ethernet/cavium/liquidio/cn66xx_regs.h index 5e3aff242ad3..b248966837b4 100644 --- a/drivers/net/ethernet/cavium/liquidio/cn66xx_regs.h +++ b/drivers/net/ethernet/cavium/liquidio/cn66xx_regs.h @@ -1,25 +1,20 @@ /********************************************************************** -* Author: Cavium, Inc. -* -* Contact: support@cavium.com -* Please include "LiquidIO" in the subject. -* -* Copyright (c) 2003-2015 Cavium, Inc. -* -* This file is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License, Version 2, as -* published by the Free Software Foundation. -* -* This file is distributed in the hope that it will be useful, but -* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -* NONINFRINGEMENT. See the GNU General Public License for more -* details. -* -* This file may also be available under a different license from Cavium. -* Contact Cavium, Inc. for more information -**********************************************************************/ - + * Author: Cavium, Inc. + * + * Contact: support@cavium.com + * Please include "LiquidIO" in the subject. + * + * Copyright (c) 2003-2016 Cavium, Inc. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, Version 2, as + * published by the Free Software Foundation. + * + * This file is distributed in the hope that it will be useful, but + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or + * NONINFRINGEMENT. See the GNU General Public License for more details. + ***********************************************************************/ /*! \file cn66xx_regs.h * \brief Host Driver: Register Address and Register Mask values for * Octeon CN66XX devices. @@ -443,10 +438,10 @@ #define CN6XXX_SLI_S2M_PORT0_CTL 0x3D80 #define CN6XXX_SLI_S2M_PORT1_CTL 0x3D90 #define CN6XXX_SLI_S2M_PORTX_CTL(port) \ - (CN6XXX_SLI_S2M_PORT0_CTL + (port * 0x10)) + (CN6XXX_SLI_S2M_PORT0_CTL + ((port) * 0x10)) #define CN6XXX_SLI_INT_ENB64(port) \ - (CN6XXX_SLI_INT_ENB64_PORT0 + (port * 0x10)) + (CN6XXX_SLI_INT_ENB64_PORT0 + ((port) * 0x10)) #define CN6XXX_SLI_MAC_NUMBER 0x3E00 @@ -458,7 +453,7 @@ #define CN6XXX_PCI_BAR1_OFFSET 0x8 #define CN6XXX_BAR1_REG(idx, port) \ - (CN6XXX_BAR1_INDEX_START + (port * CN6XXX_PEM_OFFSET) + \ + (CN6XXX_BAR1_INDEX_START + ((port) * CN6XXX_PEM_OFFSET) + \ (CN6XXX_PCI_BAR1_OFFSET * (idx))) /*############################ DPI #########################*/ @@ -476,17 +471,17 @@ #define CN6XXX_DPI_DMA_ENG0_ENB 0x0001df0000000080ULL #define CN6XXX_DPI_DMA_ENG_ENB(q_no) \ - (CN6XXX_DPI_DMA_ENG0_ENB + (q_no * 8)) + (CN6XXX_DPI_DMA_ENG0_ENB + ((q_no) * 8)) #define CN6XXX_DPI_DMA_ENG0_BUF 0x0001df0000000880ULL #define CN6XXX_DPI_DMA_ENG_BUF(q_no) \ - (CN6XXX_DPI_DMA_ENG0_BUF + (q_no * 8)) + (CN6XXX_DPI_DMA_ENG0_BUF + ((q_no) * 8)) #define CN6XXX_DPI_SLI_PRT0_CFG 0x0001df0000000900ULL #define CN6XXX_DPI_SLI_PRT1_CFG 0x0001df0000000908ULL #define CN6XXX_DPI_SLI_PRTX_CFG(port) \ - (CN6XXX_DPI_SLI_PRT0_CFG + (port * 0x10)) + (CN6XXX_DPI_SLI_PRT0_CFG + ((port) * 0x10)) #define CN6XXX_DPI_DMA_COMMIT_MODE BIT_ULL(58) #define CN6XXX_DPI_DMA_PKT_HP BIT_ULL(57) diff --git a/drivers/net/ethernet/cavium/liquidio/cn68xx_device.c b/drivers/net/ethernet/cavium/liquidio/cn68xx_device.c index dbf3566ead53..50b533ff58e6 100644 --- a/drivers/net/ethernet/cavium/liquidio/cn68xx_device.c +++ b/drivers/net/ethernet/cavium/liquidio/cn68xx_device.c @@ -1,24 +1,20 @@ /********************************************************************** -* Author: Cavium, Inc. -* -* Contact: support@cavium.com -* Please include "LiquidIO" in the subject. -* -* Copyright (c) 2003-2015 Cavium, Inc. -* -* This file is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License, Version 2, as -* published by the Free Software Foundation. -* -* This file is distributed in the hope that it will be useful, but -* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -* NONINFRINGEMENT. See the GNU General Public License for more -* details. -* -* This file may also be available under a different license from Cavium. -* Contact Cavium, Inc. for more information -**********************************************************************/ + * Author: Cavium, Inc. + * + * Contact: support@cavium.com + * Please include "LiquidIO" in the subject. + * + * Copyright (c) 2003-2016 Cavium, Inc. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, Version 2, as + * published by the Free Software Foundation. + * + * This file is distributed in the hope that it will be useful, but + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or + * NONINFRINGEMENT. See the GNU General Public License for more details. + ***********************************************************************/ #include <linux/pci.h> #include <linux/netdevice.h> #include "liquidio_common.h" @@ -76,7 +72,7 @@ static void lio_cn68xx_setup_pkt_ctl_regs(struct octeon_device *oct) pktctl = octeon_read_csr64(oct, CN6XXX_SLI_PKT_CTL); /* 68XX specific */ - max_oqs = CFG_GET_OQ_MAX_Q(CHIP_FIELD(oct, cn6xxx, conf)); + max_oqs = CFG_GET_OQ_MAX_Q(CHIP_CONF(oct, cn6xxx)); tx_pipe = octeon_read_csr64(oct, CN68XX_SLI_TX_PIPE); tx_pipe &= 0xffffffffff00ffffULL; /* clear out NUMP field */ tx_pipe |= max_oqs << 16; /* put max_oqs in NUMP field */ diff --git a/drivers/net/ethernet/cavium/liquidio/cn68xx_device.h b/drivers/net/ethernet/cavium/liquidio/cn68xx_device.h index ea7bdcce6044..66b8d6bf5ec4 100644 --- a/drivers/net/ethernet/cavium/liquidio/cn68xx_device.h +++ b/drivers/net/ethernet/cavium/liquidio/cn68xx_device.h @@ -1,25 +1,20 @@ /********************************************************************** -* Author: Cavium, Inc. -* -* Contact: support@cavium.com -* Please include "LiquidIO" in the subject. -* -* Copyright (c) 2003-2015 Cavium, Inc. -* -* This file is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License, Version 2, as -* published by the Free Software Foundation. -* -* This file is distributed in the hope that it will be useful, but -* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -* NONINFRINGEMENT. See the GNU General Public License for more -* details. -* -* This file may also be available under a different license from Cavium. -* Contact Cavium, Inc. for more information -**********************************************************************/ - + * Author: Cavium, Inc. + * + * Contact: support@cavium.com + * Please include "LiquidIO" in the subject. + * + * Copyright (c) 2003-2016 Cavium, Inc. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, Version 2, as + * published by the Free Software Foundation. + * + * This file is distributed in the hope that it will be useful, but + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or + * NONINFRINGEMENT. See the GNU General Public License for more details. + ***********************************************************************/ /*! \file cn68xx_device.h * \brief Host Driver: Routines that perform CN68XX specific operations. */ diff --git a/drivers/net/ethernet/cavium/liquidio/cn68xx_regs.h b/drivers/net/ethernet/cavium/liquidio/cn68xx_regs.h index d45a0f4aaf1f..0b742f09e49d 100644 --- a/drivers/net/ethernet/cavium/liquidio/cn68xx_regs.h +++ b/drivers/net/ethernet/cavium/liquidio/cn68xx_regs.h @@ -1,25 +1,20 @@ /********************************************************************** -* Author: Cavium, Inc. -* -* Contact: support@cavium.com -* Please include "LiquidIO" in the subject. -* -* Copyright (c) 2003-2015 Cavium, Inc. -* -* This file is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License, Version 2, as -* published by the Free Software Foundation. -* -* This file is distributed in the hope that it will be useful, but -* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -* NONINFRINGEMENT. See the GNU General Public License for more -* details. -* -* This file may also be available under a different license from Cavium. -* Contact Cavium, Inc. for more information -**********************************************************************/ - + * Author: Cavium, Inc. + * + * Contact: support@cavium.com + * Please include "LiquidIO" in the subject. + * + * Copyright (c) 2003-2016 Cavium, Inc. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, Version 2, as + * published by the Free Software Foundation. + * + * This file is distributed in the hope that it will be useful, but + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or + * NONINFRINGEMENT. See the GNU General Public License for more details. + ***********************************************************************/ /*! \file cn68xx_regs.h * \brief Host Driver: Register Address and Register Mask values for * Octeon CN68XX devices. The register map for CN66XX is the same diff --git a/drivers/net/ethernet/cavium/liquidio/lio_core.c b/drivers/net/ethernet/cavium/liquidio/lio_core.c index 201eddb3013a..403bcaafa774 100644 --- a/drivers/net/ethernet/cavium/liquidio/lio_core.c +++ b/drivers/net/ethernet/cavium/liquidio/lio_core.c @@ -1,24 +1,20 @@ /********************************************************************** -* Author: Cavium, Inc. -* -* Contact: support@cavium.com -* Please include "LiquidIO" in the subject. -* -* Copyright (c) 2003-2015 Cavium, Inc. -* -* This file is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License, Version 2, as -* published by the Free Software Foundation. -* -* This file is distributed in the hope that it will be useful, but -* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -* NONINFRINGEMENT. See the GNU General Public License for more -* details. -* -* This file may also be available under a different license from Cavium. -* Contact Cavium, Inc. for more information -**********************************************************************/ + * Author: Cavium, Inc. + * + * Contact: support@cavium.com + * Please include "LiquidIO" in the subject. + * + * Copyright (c) 2003-2016 Cavium, Inc. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, Version 2, as + * published by the Free Software Foundation. + * + * This file is distributed in the hope that it will be useful, but + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or + * NONINFRINGEMENT. See the GNU General Public License for more details. + ***********************************************************************/ #include <linux/pci.h> #include <linux/if_vlan.h> #include "liquidio_common.h" @@ -264,3 +260,34 @@ void liquidio_link_ctrl_cmd_completion(void *nctrl_ptr) nctrl->ncmd.s.cmd); } } + +void octeon_pf_changed_vf_macaddr(struct octeon_device *oct, u8 *mac) +{ + bool macaddr_changed = false; + struct net_device *netdev; + struct lio *lio; + + rtnl_lock(); + + netdev = oct->props[0].netdev; + lio = GET_LIO(netdev); + + lio->linfo.macaddr_is_admin_asgnd = true; + + if (!ether_addr_equal(netdev->dev_addr, mac)) { + macaddr_changed = true; + ether_addr_copy(netdev->dev_addr, mac); + ether_addr_copy(((u8 *)&lio->linfo.hw_addr) + 2, mac); + call_netdevice_notifiers(NETDEV_CHANGEADDR, netdev); + } + + rtnl_unlock(); + + if (macaddr_changed) + dev_info(&oct->pci_dev->dev, + "PF changed VF's MAC address to %pM\n", mac); + + /* no need to notify the firmware of the macaddr change because + * the PF did that already + */ +} diff --git a/drivers/net/ethernet/cavium/liquidio/lio_ethtool.c b/drivers/net/ethernet/cavium/liquidio/lio_ethtool.c index f163e0abbeb2..e233796ed4a3 100644 --- a/drivers/net/ethernet/cavium/liquidio/lio_ethtool.c +++ b/drivers/net/ethernet/cavium/liquidio/lio_ethtool.c @@ -1,24 +1,20 @@ /********************************************************************** -* Author: Cavium, Inc. -* -* Contact: support@cavium.com -* Please include "LiquidIO" in the subject. -* -* Copyright (c) 2003-2015 Cavium, Inc. -* -* This file is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License, Version 2, as -* published by the Free Software Foundation. -* -* This file is distributed in the hope that it will be useful, but -* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -* NONINFRINGEMENT. See the GNU General Public License for more -* details. -* -* This file may also be available under a different license from Cavium. -* Contact Cavium, Inc. for more information -**********************************************************************/ + * Author: Cavium, Inc. + * + * Contact: support@cavium.com + * Please include "LiquidIO" in the subject. + * + * Copyright (c) 2003-2016 Cavium, Inc. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, Version 2, as + * published by the Free Software Foundation. + * + * This file is distributed in the hope that it will be useful, but + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or + * NONINFRINGEMENT. See the GNU General Public License for more details. + ***********************************************************************/ #include <linux/netdevice.h> #include <linux/net_tstamp.h> #include <linux/pci.h> @@ -74,7 +70,6 @@ enum { INTERFACE_MODE_MIXED, }; -#define ARRAY_LENGTH(a) (sizeof(a) / sizeof((a)[0])) #define OCT_ETHTOOL_REGDUMP_LEN 4096 #define OCT_ETHTOOL_REGDUMP_LEN_23XX (4096 * 11) #define OCT_ETHTOOL_REGSVER 1 @@ -87,9 +82,9 @@ static const char oct_stats_strings[][ETH_GSTRING_LEN] = { "tx_bytes", "rx_errors", /*jabber_err+l2_err+frame_err */ "tx_errors", /*fw_err_pko+fw_err_link+fw_err_drop */ - "rx_dropped", /*st->fromwire.total_rcvd - st->fromwire.fw_total_rcvd - *+st->fromwire.dmac_drop + st->fromwire.fw_err_drop - */ + "rx_dropped", /*st->fromwire.total_rcvd - st->fromwire.fw_total_rcvd + + *st->fromwire.dmac_drop + st->fromwire.fw_err_drop + */ "tx_dropped", "tx_total_sent", @@ -259,14 +254,14 @@ lio_ethtool_get_channels(struct net_device *dev, u32 max_rx = 0, max_tx = 0, tx_count = 0, rx_count = 0; if (OCTEON_CN6XXX(oct)) { - struct octeon_config *conf6x = CHIP_FIELD(oct, cn6xxx, conf); + struct octeon_config *conf6x = CHIP_CONF(oct, cn6xxx); max_rx = CFG_GET_OQ_MAX_Q(conf6x); max_tx = CFG_GET_IQ_MAX_Q(conf6x); rx_count = CFG_GET_NUM_RXQS_NIC_IF(conf6x, lio->ifidx); tx_count = CFG_GET_NUM_TXQS_NIC_IF(conf6x, lio->ifidx); } else if (OCTEON_CN23XX_PF(oct)) { - struct octeon_config *conf23 = CHIP_FIELD(oct, cn23xx_pf, conf); + struct octeon_config *conf23 = CHIP_CONF(oct, cn23xx_pf); max_rx = CFG_GET_OQ_MAX_Q(conf23); max_tx = CFG_GET_IQ_MAX_Q(conf23); @@ -589,14 +584,14 @@ lio_ethtool_get_ringparam(struct net_device *netdev, rx_pending = 0; if (OCTEON_CN6XXX(oct)) { - struct octeon_config *conf6x = CHIP_FIELD(oct, cn6xxx, conf); + struct octeon_config *conf6x = CHIP_CONF(oct, cn6xxx); tx_max_pending = CN6XXX_MAX_IQ_DESCRIPTORS; rx_max_pending = CN6XXX_MAX_OQ_DESCRIPTORS; rx_pending = CFG_GET_NUM_RX_DESCS_NIC_IF(conf6x, lio->ifidx); tx_pending = CFG_GET_NUM_TX_DESCS_NIC_IF(conf6x, lio->ifidx); } else if (OCTEON_CN23XX_PF(oct)) { - struct octeon_config *conf23 = CHIP_FIELD(oct, cn23xx_pf, conf); + struct octeon_config *conf23 = CHIP_CONF(oct, cn23xx_pf); tx_max_pending = CN23XX_MAX_IQ_DESCRIPTORS; rx_max_pending = CN23XX_MAX_OQ_DESCRIPTORS; @@ -757,9 +752,6 @@ lio_get_ethtool_stats(struct net_device *netdev, /*sum of oct->instr_queue[iq_no]->stats.tx_dropped */ data[i++] = CVM_CAST64(netstats->tx_dropped); - /*data[i++] = CVM_CAST64(stats->multicast); */ - /*data[i++] = CVM_CAST64(stats->collisions); */ - /* firmware tx stats */ /*per_core_stats[cvmx_get_core_num()].link_stats[mdata->from_ifidx]. *fromhost.fw_total_sent @@ -910,9 +902,8 @@ lio_get_ethtool_stats(struct net_device *netdev, /*lio->link_changes*/ data[i++] = CVM_CAST64(lio->link_changes); - /* TX -- lio_update_stats(lio); */ for (j = 0; j < MAX_OCTEON_INSTR_QUEUES(oct_dev); j++) { - if (!(oct_dev->io_qmask.iq & (1ULL << j))) + if (!(oct_dev->io_qmask.iq & BIT_ULL(j))) continue; /*packets to network port*/ /*# of packets tx to network */ @@ -954,9 +945,8 @@ lio_get_ethtool_stats(struct net_device *netdev, } /* RX */ - /* for (j = 0; j < oct_dev->num_oqs; j++) { */ for (j = 0; j < MAX_OCTEON_OUTPUT_QUEUES(oct_dev); j++) { - if (!(oct_dev->io_qmask.oq & (1ULL << j))) + if (!(oct_dev->io_qmask.oq & BIT_ULL(j))) continue; /*packets send to TCP/IP network stack */ @@ -1030,7 +1020,7 @@ static void lio_get_strings(struct net_device *netdev, u32 stringset, u8 *data) num_iq_stats = ARRAY_SIZE(oct_iq_stats_strings); for (i = 0; i < MAX_OCTEON_INSTR_QUEUES(oct_dev); i++) { - if (!(oct_dev->io_qmask.iq & (1ULL << i))) + if (!(oct_dev->io_qmask.iq & BIT_ULL(i))) continue; for (j = 0; j < num_iq_stats; j++) { sprintf(data, "tx-%d-%s", i, @@ -1040,9 +1030,8 @@ static void lio_get_strings(struct net_device *netdev, u32 stringset, u8 *data) } num_oq_stats = ARRAY_SIZE(oct_droq_stats_strings); - /* for (i = 0; i < oct_dev->num_oqs; i++) { */ for (i = 0; i < MAX_OCTEON_OUTPUT_QUEUES(oct_dev); i++) { - if (!(oct_dev->io_qmask.oq & (1ULL << i))) + if (!(oct_dev->io_qmask.oq & BIT_ULL(i))) continue; for (j = 0; j < num_oq_stats; j++) { sprintf(data, "rx-%d-%s", i, diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c index 71d01a77896d..3d05b2feecc8 100644 --- a/drivers/net/ethernet/cavium/liquidio/lio_main.c +++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c @@ -1,28 +1,22 @@ /********************************************************************** -* Author: Cavium, Inc. -* -* Contact: support@cavium.com -* Please include "LiquidIO" in the subject. -* -* Copyright (c) 2003-2015 Cavium, Inc. -* -* This file is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License, Version 2, as -* published by the Free Software Foundation. -* -* This file is distributed in the hope that it will be useful, but -* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -* NONINFRINGEMENT. See the GNU General Public License for more -* details. -* -* This file may also be available under a different license from Cavium. -* Contact Cavium, Inc. for more information -**********************************************************************/ -#include <linux/version.h> + * Author: Cavium, Inc. + * + * Contact: support@cavium.com + * Please include "LiquidIO" in the subject. + * + * Copyright (c) 2003-2016 Cavium, Inc. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, Version 2, as + * published by the Free Software Foundation. + * + * This file is distributed in the hope that it will be useful, but + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or + * NONINFRINGEMENT. See the GNU General Public License for more details. + ***********************************************************************/ #include <linux/pci.h> #include <linux/firmware.h> -#include <linux/ptp_clock_kernel.h> #include <net/vxlan.h> #include <linux/kthread.h> #include "liquidio_common.h" @@ -54,9 +48,6 @@ MODULE_PARM_DESC(ddr_timeout, #define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK) -#define INCR_INSTRQUEUE_PKT_COUNT(octeon_dev_ptr, iq_no, field, count) \ - (octeon_dev_ptr->instr_queue[iq_no]->stats.field += count) - static int debug = -1; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "NETIF_MSG debug bits"); @@ -65,10 +56,6 @@ static char fw_type[LIO_MAX_FW_TYPE_LEN]; module_param_string(fw_type, fw_type, sizeof(fw_type), 0000); MODULE_PARM_DESC(fw_type, "Type of firmware to be loaded. Default \"nic\""); -static int conf_type; -module_param(conf_type, int, 0); -MODULE_PARM_DESC(conf_type, "select octeon configuration 0 default 1 ovs"); - static int ptp_enable = 1; /* Bit mask values for lio->ifstate */ @@ -180,6 +167,10 @@ struct octeon_device_priv { unsigned long napi_mask; }; +#ifdef CONFIG_PCI_IOV +static int liquidio_enable_sriov(struct pci_dev *dev, int num_vfs); +#endif + static int octeon_device_init(struct octeon_device *); static int liquidio_stop(struct net_device *netdev); static void liquidio_remove(struct pci_dev *pdev); @@ -197,9 +188,8 @@ static void octeon_droq_bh(unsigned long pdev) struct octeon_device_priv *oct_priv = (struct octeon_device_priv *)oct->priv; - /* for (q_no = 0; q_no < oct->num_oqs; q_no++) { */ for (q_no = 0; q_no < MAX_OCTEON_OUTPUT_QUEUES(oct); q_no++) { - if (!(oct->io_qmask.oq & (1ULL << q_no))) + if (!(oct->io_qmask.oq & BIT_ULL(q_no))) continue; reschedule |= octeon_droq_process_packets(oct, oct->droq[q_no], MAX_PACKET_BUDGET); @@ -234,7 +224,7 @@ static int lio_wait_for_oq_pkts(struct octeon_device *oct) pending_pkts = 0; for (i = 0; i < MAX_OCTEON_OUTPUT_QUEUES(oct); i++) { - if (!(oct->io_qmask.oq & (1ULL << i))) + if (!(oct->io_qmask.oq & BIT_ULL(i))) continue; pkt_cnt += octeon_droq_check_hw_for_pkts(oct->droq[i]); } @@ -316,7 +306,7 @@ static inline void pcierror_quiesce_device(struct octeon_device *oct) for (i = 0; i < MAX_OCTEON_INSTR_QUEUES(oct); i++) { struct octeon_instr_queue *iq; - if (!(oct->io_qmask.iq & (1ULL << i))) + if (!(oct->io_qmask.iq & BIT_ULL(i))) continue; iq = oct->instr_queue[i]; @@ -382,7 +372,6 @@ static void stop_pci_io(struct octeon_device *oct) dev_dbg(&oct->pci_dev->dev, "Device state is now %s\n", lio_get_state_string(&oct->status)); - /* cn63xx_cleanup_aer_uncorrect_error_status(oct->pci_dev); */ /* making it a common function for all OCTEON models */ cleanup_aer_uncorrect_error_status(oct->pci_dev); } @@ -518,6 +507,9 @@ static struct pci_driver liquidio_pci_driver = { .suspend = liquidio_suspend, .resume = liquidio_resume, #endif +#ifdef CONFIG_PCI_IOV + .sriov_configure = liquidio_enable_sriov, +#endif }; /** @@ -763,6 +755,7 @@ static void delete_glists(struct lio *lio) } kfree((void *)lio->glist); + kfree((void *)lio->glist_lock); } /** @@ -933,7 +926,6 @@ static inline void update_link_status(struct net_device *netdev, if (lio->linfo.link.s.link_up) { netif_carrier_on(netdev); - /* start_txq(netdev); */ txqs_wake(netdev); } else { netif_carrier_off(netdev); @@ -1011,7 +1003,7 @@ static void liquidio_schedule_droq_pkt_handlers(struct octeon_device *oct) if (oct->int_status & OCT_DEV_INTR_PKT_DATA) { for (oq_no = 0; oq_no < MAX_OCTEON_OUTPUT_QUEUES(oct); oq_no++) { - if (!(oct->droq_intr & (1ULL << oq_no))) + if (!(oct->droq_intr & BIT_ULL(oq_no))) continue; droq = oct->droq[oq_no]; @@ -1322,6 +1314,7 @@ liquidio_probe(struct pci_dev *pdev, complete(&first_stage); if (octeon_device_init(oct_dev)) { + complete(&hs->init); liquidio_remove(pdev); return -ENOMEM; } @@ -1346,7 +1339,15 @@ liquidio_probe(struct pci_dev *pdev, oct_dev->watchdog_task = kthread_create( liquidio_watchdog, oct_dev, "liowd/%02hhx:%02hhx.%hhx", bus, device, function); - wake_up_process(oct_dev->watchdog_task); + if (!IS_ERR(oct_dev->watchdog_task)) { + wake_up_process(oct_dev->watchdog_task); + } else { + oct_dev->watchdog_task = NULL; + dev_err(&oct_dev->pci_dev->dev, + "failed to create kernel_thread\n"); + liquidio_remove(pdev); + return -1; + } } } @@ -1410,6 +1411,8 @@ static void octeon_destroy_resources(struct octeon_device *oct) if (lio_wait_for_oq_pkts(oct)) dev_err(&oct->pci_dev->dev, "OQ had pending packets\n"); + /* fallthrough */ + case OCT_DEV_INTR_SET_DONE: /* Disable interrupts */ oct->fn_list.disable_interrupt(oct, OCTEON_ALL_INTR); @@ -1436,12 +1439,20 @@ static void octeon_destroy_resources(struct octeon_device *oct) pci_disable_msi(oct->pci_dev); } + /* fallthrough */ + case OCT_DEV_MSIX_ALLOC_VECTOR_DONE: if (OCTEON_CN23XX_PF(oct)) octeon_free_ioq_vector(oct); + + /* fallthrough */ + case OCT_DEV_MBOX_SETUP_DONE: + if (OCTEON_CN23XX_PF(oct)) + oct->fn_list.free_mbox(oct); + /* fallthrough */ case OCT_DEV_IN_RESET: case OCT_DEV_DROQ_INIT_DONE: - /*atomic_set(&oct->status, OCT_DEV_DROQ_INIT_DONE);*/ + /* Wait for any pending operations */ mdelay(100); for (i = 0; i < MAX_OCTEON_OUTPUT_QUEUES(oct); i++) { if (!(oct->io_qmask.oq & BIT_ULL(i))) @@ -1472,6 +1483,10 @@ static void octeon_destroy_resources(struct octeon_device *oct) continue; octeon_delete_instr_queue(oct, i); } +#ifdef CONFIG_PCI_IOV + if (oct->sriov_info.sriov_enabled) + pci_disable_sriov(oct->pci_dev); +#endif /* fallthrough */ case OCT_DEV_SC_BUFF_POOL_INIT_DONE: octeon_free_sc_buffer_pool(oct); @@ -1491,10 +1506,13 @@ static void octeon_destroy_resources(struct octeon_device *oct) octeon_unmap_pci_barx(oct, 1); /* fallthrough */ - case OCT_DEV_BEGIN_STATE: + case OCT_DEV_PCI_ENABLE_DONE: + pci_clear_master(oct->pci_dev); /* Disable the device, releasing the PCI INT */ pci_disable_device(oct->pci_dev); + /* fallthrough */ + case OCT_DEV_BEGIN_STATE: /* Nothing to be done here either */ break; } /* end switch (oct->status) */ @@ -1764,6 +1782,7 @@ static int octeon_pci_os_setup(struct octeon_device *oct) if (dma_set_mask_and_coherent(&oct->pci_dev->dev, DMA_BIT_MASK(64))) { dev_err(&oct->pci_dev->dev, "Unexpected DMA device capability\n"); + pci_disable_device(oct->pci_dev); return 1; } @@ -2426,7 +2445,6 @@ static int liquidio_napi_poll(struct napi_struct *napi, int budget) * Return back if tx_done is false. */ update_txq_status(oct, iq_no); - /*tx_done = (iq->flush_index == iq->octeon_read_index);*/ } else { dev_err(&oct->pci_dev->dev, "%s: iq (%d) num invalid\n", __func__, iq_no); @@ -3556,7 +3574,152 @@ static void liquidio_del_vxlan_port(struct net_device *netdev, OCTNET_CMD_VXLAN_PORT_DEL); } -static struct net_device_ops lionetdevops = { +static int __liquidio_set_vf_mac(struct net_device *netdev, int vfidx, + u8 *mac, bool is_admin_assigned) +{ + struct lio *lio = GET_LIO(netdev); + struct octeon_device *oct = lio->oct_dev; + struct octnic_ctrl_pkt nctrl; + + if (!is_valid_ether_addr(mac)) + return -EINVAL; + + if (vfidx < 0 || vfidx >= oct->sriov_info.max_vfs) + return -EINVAL; + + memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt)); + + nctrl.ncmd.u64 = 0; + nctrl.ncmd.s.cmd = OCTNET_CMD_CHANGE_MACADDR; + /* vfidx is 0 based, but vf_num (param1) is 1 based */ + nctrl.ncmd.s.param1 = vfidx + 1; + nctrl.ncmd.s.param2 = (is_admin_assigned ? 1 : 0); + nctrl.ncmd.s.more = 1; + nctrl.iq_no = lio->linfo.txpciq[0].s.q_no; + nctrl.cb_fn = 0; + nctrl.wait_time = LIO_CMD_WAIT_TM; + + nctrl.udd[0] = 0; + /* The MAC Address is presented in network byte order. */ + ether_addr_copy((u8 *)&nctrl.udd[0] + 2, mac); + + oct->sriov_info.vf_macaddr[vfidx] = nctrl.udd[0]; + + octnet_send_nic_ctrl_pkt(oct, &nctrl); + + return 0; +} + +static int liquidio_set_vf_mac(struct net_device *netdev, int vfidx, u8 *mac) +{ + struct lio *lio = GET_LIO(netdev); + struct octeon_device *oct = lio->oct_dev; + int retval; + + retval = __liquidio_set_vf_mac(netdev, vfidx, mac, true); + if (!retval) + cn23xx_tell_vf_its_macaddr_changed(oct, vfidx, mac); + + return retval; +} + +static int liquidio_set_vf_vlan(struct net_device *netdev, int vfidx, + u16 vlan, u8 qos, __be16 vlan_proto) +{ + struct lio *lio = GET_LIO(netdev); + struct octeon_device *oct = lio->oct_dev; + struct octnic_ctrl_pkt nctrl; + u16 vlantci; + + if (vfidx < 0 || vfidx >= oct->sriov_info.num_vfs_alloced) + return -EINVAL; + + if (vlan_proto != htons(ETH_P_8021Q)) + return -EPROTONOSUPPORT; + + if (vlan >= VLAN_N_VID || qos > 7) + return -EINVAL; + + if (vlan) + vlantci = vlan | (u16)qos << VLAN_PRIO_SHIFT; + else + vlantci = 0; + + if (oct->sriov_info.vf_vlantci[vfidx] == vlantci) + return 0; + + memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt)); + + if (vlan) + nctrl.ncmd.s.cmd = OCTNET_CMD_ADD_VLAN_FILTER; + else + nctrl.ncmd.s.cmd = OCTNET_CMD_DEL_VLAN_FILTER; + + nctrl.ncmd.s.param1 = vlantci; + nctrl.ncmd.s.param2 = + vfidx + 1; /* vfidx is 0 based, but vf_num (param2) is 1 based */ + nctrl.ncmd.s.more = 0; + nctrl.iq_no = lio->linfo.txpciq[0].s.q_no; + nctrl.cb_fn = 0; + nctrl.wait_time = LIO_CMD_WAIT_TM; + + octnet_send_nic_ctrl_pkt(oct, &nctrl); + + oct->sriov_info.vf_vlantci[vfidx] = vlantci; + + return 0; +} + +static int liquidio_get_vf_config(struct net_device *netdev, int vfidx, + struct ifla_vf_info *ivi) +{ + struct lio *lio = GET_LIO(netdev); + struct octeon_device *oct = lio->oct_dev; + u8 *macaddr; + + if (vfidx < 0 || vfidx >= oct->sriov_info.num_vfs_alloced) + return -EINVAL; + + ivi->vf = vfidx; + macaddr = 2 + (u8 *)&oct->sriov_info.vf_macaddr[vfidx]; + ether_addr_copy(&ivi->mac[0], macaddr); + ivi->vlan = oct->sriov_info.vf_vlantci[vfidx] & VLAN_VID_MASK; + ivi->qos = oct->sriov_info.vf_vlantci[vfidx] >> VLAN_PRIO_SHIFT; + ivi->linkstate = oct->sriov_info.vf_linkstate[vfidx]; + return 0; +} + +static int liquidio_set_vf_link_state(struct net_device *netdev, int vfidx, + int linkstate) +{ + struct lio *lio = GET_LIO(netdev); + struct octeon_device *oct = lio->oct_dev; + struct octnic_ctrl_pkt nctrl; + + if (vfidx < 0 || vfidx >= oct->sriov_info.num_vfs_alloced) + return -EINVAL; + + if (oct->sriov_info.vf_linkstate[vfidx] == linkstate) + return 0; + + memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt)); + nctrl.ncmd.s.cmd = OCTNET_CMD_SET_VF_LINKSTATE; + nctrl.ncmd.s.param1 = + vfidx + 1; /* vfidx is 0 based, but vf_num (param1) is 1 based */ + nctrl.ncmd.s.param2 = linkstate; + nctrl.ncmd.s.more = 0; + nctrl.iq_no = lio->linfo.txpciq[0].s.q_no; + nctrl.cb_fn = 0; + nctrl.wait_time = LIO_CMD_WAIT_TM; + + octnet_send_nic_ctrl_pkt(oct, &nctrl); + + oct->sriov_info.vf_linkstate[vfidx] = linkstate; + + return 0; +} + +static const struct net_device_ops lionetdevops = { .ndo_open = liquidio_open, .ndo_stop = liquidio_stop, .ndo_start_xmit = liquidio_xmit, @@ -3573,6 +3736,11 @@ static struct net_device_ops lionetdevops = { .ndo_set_features = liquidio_set_features, .ndo_udp_tunnel_add = liquidio_add_vxlan_port, .ndo_udp_tunnel_del = liquidio_del_vxlan_port, + .ndo_set_vf_mac = liquidio_set_vf_mac, + .ndo_set_vf_vlan = liquidio_set_vf_vlan, + .ndo_get_vf_config = liquidio_get_vf_config, + .ndo_set_vf_link_state = liquidio_set_vf_link_state, + .ndo_select_queue = select_q }; /** \brief Entry point for the liquidio module @@ -3584,7 +3752,7 @@ static int __init liquidio_init(void) init_completion(&first_stage); - octeon_init_device_list(conf_type); + octeon_init_device_list(OCTEON_CONFIG_TYPE_DEFAULT); if (liquidio_init_pci()) return -EINVAL; @@ -3805,9 +3973,6 @@ static int setup_nic_devices(struct octeon_device *octeon_dev) SET_NETDEV_DEV(netdev, &octeon_dev->pci_dev->dev); - if (num_iqueues > 1) - lionetdevops.ndo_select_queue = select_q; - /* Associate the routines that will handle different * netdev tasks. */ @@ -3895,6 +4060,19 @@ static int setup_nic_devices(struct octeon_device *octeon_dev) "if%d gmx: %d hw_addr: 0x%llx\n", i, lio->linfo.gmxport, CVM_CAST64(lio->linfo.hw_addr)); + for (j = 0; j < octeon_dev->sriov_info.max_vfs; j++) { + u8 vfmac[ETH_ALEN]; + + random_ether_addr(&vfmac[0]); + if (__liquidio_set_vf_mac(netdev, j, + &vfmac[0], false)) { + dev_err(&octeon_dev->pci_dev->dev, + "Error setting VF%d MAC address\n", + j); + goto setup_nic_dev_fail; + } + } + /* 64-bit swap required on LE machines */ octeon_swap_8B_data(&lio->linfo.hw_addr, 1); for (j = 0; j < 6; j++) @@ -3990,6 +4168,101 @@ setup_nic_wait_intr: return -ENODEV; } +#ifdef CONFIG_PCI_IOV +static int octeon_enable_sriov(struct octeon_device *oct) +{ + unsigned int num_vfs_alloced = oct->sriov_info.num_vfs_alloced; + struct pci_dev *vfdev; + int err; + u32 u; + + if (OCTEON_CN23XX_PF(oct) && num_vfs_alloced) { + err = pci_enable_sriov(oct->pci_dev, + oct->sriov_info.num_vfs_alloced); + if (err) { + dev_err(&oct->pci_dev->dev, + "OCTEON: Failed to enable PCI sriov: %d\n", + err); + oct->sriov_info.num_vfs_alloced = 0; + return err; + } + oct->sriov_info.sriov_enabled = 1; + + /* init lookup table that maps DPI ring number to VF pci_dev + * struct pointer + */ + u = 0; + vfdev = pci_get_device(PCI_VENDOR_ID_CAVIUM, + OCTEON_CN23XX_VF_VID, NULL); + while (vfdev) { + if (vfdev->is_virtfn && + (vfdev->physfn == oct->pci_dev)) { + oct->sriov_info.dpiring_to_vfpcidev_lut[u] = + vfdev; + u += oct->sriov_info.rings_per_vf; + } + vfdev = pci_get_device(PCI_VENDOR_ID_CAVIUM, + OCTEON_CN23XX_VF_VID, vfdev); + } + } + + return num_vfs_alloced; +} + +static int lio_pci_sriov_disable(struct octeon_device *oct) +{ + int u; + + if (pci_vfs_assigned(oct->pci_dev)) { + dev_err(&oct->pci_dev->dev, "VFs are still assigned to VMs.\n"); + return -EPERM; + } + + pci_disable_sriov(oct->pci_dev); + + u = 0; + while (u < MAX_POSSIBLE_VFS) { + oct->sriov_info.dpiring_to_vfpcidev_lut[u] = NULL; + u += oct->sriov_info.rings_per_vf; + } + + oct->sriov_info.num_vfs_alloced = 0; + dev_info(&oct->pci_dev->dev, "oct->pf_num:%d disabled VFs\n", + oct->pf_num); + + return 0; +} + +static int liquidio_enable_sriov(struct pci_dev *dev, int num_vfs) +{ + struct octeon_device *oct = pci_get_drvdata(dev); + int ret = 0; + + if ((num_vfs == oct->sriov_info.num_vfs_alloced) && + (oct->sriov_info.sriov_enabled)) { + dev_info(&oct->pci_dev->dev, "oct->pf_num:%d already enabled num_vfs:%d\n", + oct->pf_num, num_vfs); + return 0; + } + + if (!num_vfs) { + ret = lio_pci_sriov_disable(oct); + } else if (num_vfs > oct->sriov_info.max_vfs) { + dev_err(&oct->pci_dev->dev, + "OCTEON: Max allowed VFs:%d user requested:%d", + oct->sriov_info.max_vfs, num_vfs); + ret = -EPERM; + } else { + oct->sriov_info.num_vfs_alloced = num_vfs; + ret = octeon_enable_sriov(oct); + dev_info(&oct->pci_dev->dev, "oct->pf_num:%d num_vfs:%d\n", + oct->pf_num, num_vfs); + } + + return ret; +} +#endif + /** * \brief initialize the NIC * @param oct octeon device @@ -4095,6 +4368,52 @@ static void nic_starter(struct work_struct *work) complete(&handshake[oct->octeon_id].started); } +static int +octeon_recv_vf_drv_notice(struct octeon_recv_info *recv_info, void *buf) +{ + struct octeon_device *oct = (struct octeon_device *)buf; + struct octeon_recv_pkt *recv_pkt = recv_info->recv_pkt; + int i, notice, vf_idx; + u64 *data, vf_num; + + notice = recv_pkt->rh.r.ossp; + data = (u64 *)get_rbd(recv_pkt->buffer_ptr[0]); + + /* the first 64-bit word of data is the vf_num */ + vf_num = data[0]; + octeon_swap_8B_data(&vf_num, 1); + vf_idx = (int)vf_num - 1; + + if (notice == VF_DRV_LOADED) { + if (!(oct->sriov_info.vf_drv_loaded_mask & BIT_ULL(vf_idx))) { + oct->sriov_info.vf_drv_loaded_mask |= BIT_ULL(vf_idx); + dev_info(&oct->pci_dev->dev, + "driver for VF%d was loaded\n", vf_idx); + try_module_get(THIS_MODULE); + } + } else if (notice == VF_DRV_REMOVED) { + if (oct->sriov_info.vf_drv_loaded_mask & BIT_ULL(vf_idx)) { + oct->sriov_info.vf_drv_loaded_mask &= ~BIT_ULL(vf_idx); + dev_info(&oct->pci_dev->dev, + "driver for VF%d was removed\n", vf_idx); + module_put(THIS_MODULE); + } + } else if (notice == VF_DRV_MACADDR_CHANGED) { + u8 *b = (u8 *)&data[1]; + + oct->sriov_info.vf_macaddr[vf_idx] = data[1]; + dev_info(&oct->pci_dev->dev, + "VF driver changed VF%d's MAC address to %pM\n", + vf_idx, b + 2); + } + + for (i = 0; i < recv_pkt->buffer_count; i++) + recv_buffer_free(recv_pkt->buffer_ptr[i]); + octeon_free_recv_info(recv_info); + + return 0; +} + /** * \brief Device initialization for each Octeon device that is probed * @param octeon_dev octeon device @@ -4114,6 +4433,8 @@ static int octeon_device_init(struct octeon_device *octeon_dev) if (octeon_pci_os_setup(octeon_dev)) return 1; + atomic_set(&octeon_dev->status, OCT_DEV_PCI_ENABLE_DONE); + /* Identify the Octeon type and map the BAR address space. */ if (octeon_chip_specific_setup(octeon_dev)) { dev_err(&octeon_dev->pci_dev->dev, "Chip specific setup failed\n"); @@ -4153,6 +4474,9 @@ static int octeon_device_init(struct octeon_device *octeon_dev) octeon_core_drv_init, octeon_dev); + octeon_register_dispatch_fn(octeon_dev, OPCODE_NIC, + OPCODE_NIC_VF_DRV_NOTICE, + octeon_recv_vf_drv_notice, octeon_dev); INIT_DELAYED_WORK(&octeon_dev->nic_poll_work.work, nic_starter); octeon_dev->nic_poll_work.ctxptr = (void *)octeon_dev; schedule_delayed_work(&octeon_dev->nic_poll_work.work, @@ -4182,9 +4506,6 @@ static int octeon_device_init(struct octeon_device *octeon_dev) if (octeon_setup_instr_queues(octeon_dev)) { dev_err(&octeon_dev->pci_dev->dev, "instruction queue initialization failed\n"); - /* On error, release any previously allocated queues */ - for (j = 0; j < octeon_dev->num_iqs; j++) - octeon_delete_instr_queue(octeon_dev, j); return 1; } atomic_set(&octeon_dev->status, OCT_DEV_INSTR_QUEUE_INIT_DONE); @@ -4200,19 +4521,23 @@ static int octeon_device_init(struct octeon_device *octeon_dev) if (octeon_setup_output_queues(octeon_dev)) { dev_err(&octeon_dev->pci_dev->dev, "Output queue initialization failed\n"); - /* Release any previously allocated queues */ - for (j = 0; j < octeon_dev->num_oqs; j++) - octeon_delete_droq(octeon_dev, j); return 1; } atomic_set(&octeon_dev->status, OCT_DEV_DROQ_INIT_DONE); if (OCTEON_CN23XX_PF(octeon_dev)) { + if (octeon_dev->fn_list.setup_mbox(octeon_dev)) { + dev_err(&octeon_dev->pci_dev->dev, "OCTEON: Mailbox setup failed\n"); + return 1; + } + atomic_set(&octeon_dev->status, OCT_DEV_MBOX_SETUP_DONE); + if (octeon_allocate_ioq_vector(octeon_dev)) { dev_err(&octeon_dev->pci_dev->dev, "OCTEON: ioq vector allocation failed\n"); return 1; } + atomic_set(&octeon_dev->status, OCT_DEV_MSIX_ALLOC_VECTOR_DONE); } else { /* The input and output queue registers were setup earlier (the @@ -4240,6 +4565,8 @@ static int octeon_device_init(struct octeon_device *octeon_dev) /* Enable Octeon device interrupts */ octeon_dev->fn_list.enable_interrupt(octeon_dev, OCTEON_ALL_INTR); + atomic_set(&octeon_dev->status, OCT_DEV_INTR_SET_DONE); + /* Enable the input and output queues for this Octeon device */ ret = octeon_dev->fn_list.enable_io_queues(octeon_dev); if (ret) { diff --git a/drivers/net/ethernet/cavium/liquidio/liquidio_common.h b/drivers/net/ethernet/cavium/liquidio/liquidio_common.h index 0d990accb65e..f308ee49a754 100644 --- a/drivers/net/ethernet/cavium/liquidio/liquidio_common.h +++ b/drivers/net/ethernet/cavium/liquidio/liquidio_common.h @@ -1,25 +1,20 @@ /********************************************************************** -* Author: Cavium, Inc. -* -* Contact: support@cavium.com -* Please include "LiquidIO" in the subject. -* -* Copyright (c) 2003-2015 Cavium, Inc. -* -* This file is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License, Version 2, as -* published by the Free Software Foundation. -* -* This file is distributed in the hope that it will be useful, but -* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -* NONINFRINGEMENT. See the GNU General Public License for more -* details. -* -* This file may also be available under a different license from Cavium. -* Contact Cavium, Inc. for more information -**********************************************************************/ - + * Author: Cavium, Inc. + * + * Contact: support@cavium.com + * Please include "LiquidIO" in the subject. + * + * Copyright (c) 2003-2016 Cavium, Inc. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, Version 2, as + * published by the Free Software Foundation. + * + * This file is distributed in the hope that it will be useful, but + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or + * NONINFRINGEMENT. See the GNU General Public License for more details. + ***********************************************************************/ /*! \file liquidio_common.h * \brief Common: Structures and macros used in PCI-NIC package by core and * host driver. @@ -68,12 +63,10 @@ enum octeon_tag_type { */ #define OPCODE_CORE 0 /* used for generic core operations */ #define OPCODE_NIC 1 /* used for NIC operations */ -#define OPCODE_LAST OPCODE_NIC - /* Subcodes are used by host driver/apps to identify the sub-operation * for the core. They only need to by unique for a given subsystem. */ -#define OPCODE_SUBCODE(op, sub) (((op & 0x0f) << 8) | ((sub) & 0x7f)) +#define OPCODE_SUBCODE(op, sub) ((((op) & 0x0f) << 8) | ((sub) & 0x7f)) /** OPCODE_CORE subcodes. For future use. */ @@ -89,13 +82,13 @@ enum octeon_tag_type { #define OPCODE_NIC_TIMESTAMP 0x07 #define OPCODE_NIC_INTRMOD_CFG 0x08 #define OPCODE_NIC_IF_CFG 0x09 +#define OPCODE_NIC_VF_DRV_NOTICE 0x0A +#define VF_DRV_LOADED 1 +#define VF_DRV_REMOVED -1 +#define VF_DRV_MACADDR_CHANGED 2 #define CORE_DRV_TEST_SCATTER_OP 0xFFF5 -#define OPCODE_SLOW_PATH(rh) \ - (OPCODE_SUBCODE(rh->r.opcode, rh->r.subcode) != \ - OPCODE_SUBCODE(OPCODE_NIC, OPCODE_NIC_NW_DATA)) - /* Application codes advertised by the core driver initialization packet. */ #define CVM_DRV_APP_START 0x0 #define CVM_DRV_NO_APP 0 @@ -105,31 +98,15 @@ enum octeon_tag_type { #define CVM_DRV_INVALID_APP (CVM_DRV_APP_START + 0x2) #define CVM_DRV_APP_END (CVM_DRV_INVALID_APP - 1) -/* Macro to increment index. - * Index is incremented by count; if the sum exceeds - * max, index is wrapped-around to the start. - */ -#define INCR_INDEX(index, count, max) \ -do { \ - if (((index) + (count)) >= (max)) \ - index = ((index) + (count)) - (max); \ - else \ - index += (count); \ -} while (0) - -#define INCR_INDEX_BY1(index, max) \ -do { \ - if ((++(index)) == (max)) \ - index = 0; \ -} while (0) - -#define DECR_INDEX(index, count, max) \ -do { \ - if ((count) > (index)) \ - index = ((max) - ((count - index))); \ - else \ - index -= count; \ -} while (0) +static inline u32 incr_index(u32 index, u32 count, u32 max) +{ + if ((index + count) >= max) + index = index + count - max; + else + index += count; + + return index; +} #define OCT_BOARD_NAME 32 #define OCT_SERIAL_LEN 64 @@ -235,6 +212,7 @@ static inline void add_sg_size(struct octeon_sg_entry *sg_entry, #define OCTNET_CMD_ID_ACTIVE 0x1a +#define OCTNET_CMD_SET_VF_LINKSTATE 0x1c #define OCTNET_CMD_VXLAN_PORT_ADD 0x0 #define OCTNET_CMD_VXLAN_PORT_DEL 0x1 #define OCTNET_CMD_RXCSUM_ENABLE 0x0 @@ -731,13 +709,15 @@ struct oct_link_info { #ifdef __BIG_ENDIAN_BITFIELD u64 gmxport:16; - u64 rsvd:32; + u64 macaddr_is_admin_asgnd:1; + u64 rsvd:31; u64 num_txpciq:8; u64 num_rxpciq:8; #else u64 num_rxpciq:8; u64 num_txpciq:8; - u64 rsvd:32; + u64 rsvd:31; + u64 macaddr_is_admin_asgnd:1; u64 gmxport:16; #endif @@ -827,6 +807,16 @@ struct oct_link_stats { }; +static inline int opcode_slow_path(union octeon_rh *rh) +{ + u16 subcode1, subcode2; + + subcode1 = OPCODE_SUBCODE((rh)->r.opcode, (rh)->r.subcode); + subcode2 = OPCODE_SUBCODE(OPCODE_NIC, OPCODE_NIC_NW_DATA); + + return (subcode2 != subcode1); +} + #define LIO68XX_LED_CTRL_ADDR 0x3501 #define LIO68XX_LED_CTRL_CFGON 0x1f #define LIO68XX_LED_CTRL_CFGOFF 0x100 diff --git a/drivers/net/ethernet/cavium/liquidio/liquidio_image.h b/drivers/net/ethernet/cavium/liquidio/liquidio_image.h index 93819bd8602b..78a3685f6fe0 100644 --- a/drivers/net/ethernet/cavium/liquidio/liquidio_image.h +++ b/drivers/net/ethernet/cavium/liquidio/liquidio_image.h @@ -1,24 +1,20 @@ /********************************************************************** -* Author: Cavium, Inc. -* -* Contact: support@cavium.com -* Please include "LiquidIO" in the subject. -* -* Copyright (c) 2003-2015 Cavium, Inc. -* -* This file is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License, Version 2, as -* published by the Free Software Foundation. -* -* This file is distributed in the hope that it will be useful, but -* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -* NONINFRINGEMENT. See the GNU General Public License for more -* details. -* -* This file may also be available under a different license from Cavium. -* Contact Cavium, Inc. for more information -**********************************************************************/ + * Author: Cavium, Inc. + * + * Contact: support@cavium.com + * Please include "LiquidIO" in the subject. + * + * Copyright (c) 2003-2016 Cavium, Inc. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, Version 2, as + * published by the Free Software Foundation. + * + * This file is distributed in the hope that it will be useful, but + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or + * NONINFRINGEMENT. See the GNU General Public License for more details. + ***********************************************************************/ #ifndef _LIQUIDIO_IMAGE_H_ #define _LIQUIDIO_IMAGE_H_ diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_config.h b/drivers/net/ethernet/cavium/liquidio/octeon_config.h index c76556809ed1..1cb3514fc949 100644 --- a/drivers/net/ethernet/cavium/liquidio/octeon_config.h +++ b/drivers/net/ethernet/cavium/liquidio/octeon_config.h @@ -1,25 +1,20 @@ /********************************************************************** -* Author: Cavium, Inc. -* -* Contact: support@cavium.com -* Please include "LiquidIO" in the subject. -* -* Copyright (c) 2003-2015 Cavium, Inc. -* -* This file is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License, Version 2, as -* published by the Free Software Foundation. -* -* This file is distributed in the hope that it will be useful, but -* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -* NONINFRINGEMENT. See the GNU General Public License for more -* details. -* -* This file may also be available under a different license from Cavium. -* Contact Cavium, Inc. for more information -**********************************************************************/ - + * Author: Cavium, Inc. + * + * Contact: support@cavium.com + * Please include "LiquidIO" in the subject. + * + * Copyright (c) 2003-2016 Cavium, Inc. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, Version 2, as + * published by the Free Software Foundation. + * + * This file is distributed in the hope that it will be useful, but + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or + * NONINFRINGEMENT. See the GNU General Public License for more details. + ***********************************************************************/ /*! \file octeon_config.h * \brief Host Driver: Configuration data structures for the host driver. */ @@ -65,9 +60,15 @@ #define DEFAULT_NUM_NIC_PORTS_68XX_210NV 2 /* CN23xx IQ configuration macros */ +#define CN23XX_MAX_VFS_PER_PF_PASS_1_0 8 +#define CN23XX_MAX_VFS_PER_PF_PASS_1_1 31 +#define CN23XX_MAX_VFS_PER_PF 63 +#define CN23XX_MAX_RINGS_PER_VF 8 + #define CN23XX_MAX_RINGS_PER_PF_PASS_1_0 12 #define CN23XX_MAX_RINGS_PER_PF_PASS_1_1 32 #define CN23XX_MAX_RINGS_PER_PF 64 +#define CN23XX_MAX_RINGS_PER_VF 8 #define CN23XX_MAX_INPUT_QUEUES CN23XX_MAX_RINGS_PER_PF #define CN23XX_MAX_IQ_DESCRIPTORS 2048 @@ -466,4 +467,7 @@ struct octeon_config { #define MAX_POSSIBLE_OCTEON_INSTR_QUEUES CN23XX_MAX_INPUT_QUEUES #define MAX_POSSIBLE_OCTEON_OUTPUT_QUEUES CN23XX_MAX_OUTPUT_QUEUES + +#define MAX_POSSIBLE_VFS 64 + #endif /* __OCTEON_CONFIG_H__ */ diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_console.c b/drivers/net/ethernet/cavium/liquidio/octeon_console.c index 01a50f3b0c8e..3265e0b7923e 100644 --- a/drivers/net/ethernet/cavium/liquidio/octeon_console.c +++ b/drivers/net/ethernet/cavium/liquidio/octeon_console.c @@ -1,25 +1,20 @@ /********************************************************************** -* Author: Cavium, Inc. -* -* Contact: support@cavium.com -* Please include "LiquidIO" in the subject. -* -* Copyright (c) 2003-2015 Cavium, Inc. -* -* This file is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License, Version 2, as -* published by the Free Software Foundation. -* -* This file is distributed in the hope that it will be useful, but -* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -* NONINFRINGEMENT. See the GNU General Public License for more -* details. -* -* This file may also be available under a different license from Cavium. -* Contact Cavium, Inc. for more information -**********************************************************************/ - + * Author: Cavium, Inc. + * + * Contact: support@cavium.com + * Please include "LiquidIO" in the subject. + * + * Copyright (c) 2003-2016 Cavium, Inc. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, Version 2, as + * published by the Free Software Foundation. + * + * This file is distributed in the hope that it will be useful, but + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or + * NONINFRINGEMENT. See the GNU General Public License for more details. + ***********************************************************************/ /** * @file octeon_console.c */ @@ -76,9 +71,9 @@ MODULE_PARM_DESC(console_bitmask, #define OCTEON_CONSOLE_POLL_INTERVAL_MS 100 /* 10 times per second */ /* First three members of cvmx_bootmem_desc are left in original -** positions for backwards compatibility. -** Assumes big endian target -*/ + * positions for backwards compatibility. + * Assumes big endian target + */ struct cvmx_bootmem_desc { /** spinlock to control access to list */ u32 lock; @@ -143,46 +138,6 @@ struct octeon_pci_console_desc { }; /** - * This macro returns the size of a member of a structure. - * Logically it is the same as "sizeof(s::field)" in C++, but - * C lacks the "::" operator. - */ -#define SIZEOF_FIELD(s, field) sizeof(((s *)NULL)->field) - -/** - * This macro returns a member of the cvmx_bootmem_desc - * structure. These members can't be directly addressed as - * they might be in memory not directly reachable. In the case - * where bootmem is compiled with LINUX_HOST, the structure - * itself might be located on a remote Octeon. The argument - * "field" is the member name of the cvmx_bootmem_desc to read. - * Regardless of the type of the field, the return type is always - * a u64. - */ -#define CVMX_BOOTMEM_DESC_GET_FIELD(oct, field) \ - __cvmx_bootmem_desc_get(oct, oct->bootmem_desc_addr, \ - offsetof(struct cvmx_bootmem_desc, field), \ - SIZEOF_FIELD(struct cvmx_bootmem_desc, field)) - -#define __cvmx_bootmem_lock(flags) (flags = flags) -#define __cvmx_bootmem_unlock(flags) (flags = flags) - -/** - * This macro returns a member of the - * cvmx_bootmem_named_block_desc structure. These members can't - * be directly addressed as they might be in memory not directly - * reachable. In the case where bootmem is compiled with - * LINUX_HOST, the structure itself might be located on a remote - * Octeon. The argument "field" is the member name of the - * cvmx_bootmem_named_block_desc to read. Regardless of the type - * of the field, the return type is always a u64. The "addr" - * parameter is the physical address of the structure. - */ -#define CVMX_BOOTMEM_NAMED_GET_FIELD(oct, addr, field) \ - __cvmx_bootmem_desc_get(oct, addr, \ - offsetof(struct cvmx_bootmem_named_block_desc, field), \ - SIZEOF_FIELD(struct cvmx_bootmem_named_block_desc, field)) -/** * \brief determines if a given console has debug enabled. * @param console console to check * @returns 1 = enabled. 0 otherwise @@ -263,10 +218,15 @@ static int __cvmx_bootmem_check_version(struct octeon_device *oct, oct->bootmem_desc_addr = octeon_read_device_mem64(oct, BOOTLOADER_PCI_READ_DESC_ADDR); - major_version = - (u32)CVMX_BOOTMEM_DESC_GET_FIELD(oct, major_version); - minor_version = - (u32)CVMX_BOOTMEM_DESC_GET_FIELD(oct, minor_version); + major_version = (u32)__cvmx_bootmem_desc_get( + oct, oct->bootmem_desc_addr, + offsetof(struct cvmx_bootmem_desc, major_version), + FIELD_SIZEOF(struct cvmx_bootmem_desc, major_version)); + minor_version = (u32)__cvmx_bootmem_desc_get( + oct, oct->bootmem_desc_addr, + offsetof(struct cvmx_bootmem_desc, minor_version), + FIELD_SIZEOF(struct cvmx_bootmem_desc, minor_version)); + dev_dbg(&oct->pci_dev->dev, "%s: major_version=%d\n", __func__, major_version); if ((major_version > 3) || @@ -289,10 +249,20 @@ static const struct cvmx_bootmem_named_block_desc u64 named_addr = cvmx_bootmem_phy_named_block_find(oct, name, flags); if (named_addr) { - desc->base_addr = CVMX_BOOTMEM_NAMED_GET_FIELD(oct, named_addr, - base_addr); - desc->size = - CVMX_BOOTMEM_NAMED_GET_FIELD(oct, named_addr, size); + desc->base_addr = __cvmx_bootmem_desc_get( + oct, named_addr, + offsetof(struct cvmx_bootmem_named_block_desc, + base_addr), + FIELD_SIZEOF( + struct cvmx_bootmem_named_block_desc, + base_addr)); + desc->size = __cvmx_bootmem_desc_get(oct, named_addr, + offsetof(struct cvmx_bootmem_named_block_desc, + size), + FIELD_SIZEOF( + struct cvmx_bootmem_named_block_desc, + size)); + strncpy(desc->name, name, sizeof(desc->name)); desc->name[sizeof(desc->name) - 1] = 0; return &oct->bootmem_named_block_desc; @@ -307,22 +277,41 @@ static u64 cvmx_bootmem_phy_named_block_find(struct octeon_device *oct, { u64 result = 0; - __cvmx_bootmem_lock(flags); if (!__cvmx_bootmem_check_version(oct, 3)) { u32 i; - u64 named_block_array_addr = - CVMX_BOOTMEM_DESC_GET_FIELD(oct, - named_block_array_addr); - u32 num_blocks = (u32) - CVMX_BOOTMEM_DESC_GET_FIELD(oct, nb_num_blocks); - u32 name_length = (u32) - CVMX_BOOTMEM_DESC_GET_FIELD(oct, named_block_name_len); + + u64 named_block_array_addr = __cvmx_bootmem_desc_get( + oct, oct->bootmem_desc_addr, + offsetof(struct cvmx_bootmem_desc, + named_block_array_addr), + FIELD_SIZEOF(struct cvmx_bootmem_desc, + named_block_array_addr)); + u32 num_blocks = (u32)__cvmx_bootmem_desc_get( + oct, oct->bootmem_desc_addr, + offsetof(struct cvmx_bootmem_desc, + nb_num_blocks), + FIELD_SIZEOF(struct cvmx_bootmem_desc, + nb_num_blocks)); + + u32 name_length = (u32)__cvmx_bootmem_desc_get( + oct, oct->bootmem_desc_addr, + offsetof(struct cvmx_bootmem_desc, + named_block_name_len), + FIELD_SIZEOF(struct cvmx_bootmem_desc, + named_block_name_len)); + u64 named_addr = named_block_array_addr; for (i = 0; i < num_blocks; i++) { - u64 named_size = - CVMX_BOOTMEM_NAMED_GET_FIELD(oct, named_addr, - size); + u64 named_size = __cvmx_bootmem_desc_get( + oct, named_addr, + offsetof( + struct cvmx_bootmem_named_block_desc, + size), + FIELD_SIZEOF( + struct cvmx_bootmem_named_block_desc, + size)); + if (name && named_size) { char *name_tmp = kmalloc(name_length + 1, GFP_KERNEL); @@ -347,7 +336,6 @@ static u64 cvmx_bootmem_phy_named_block_find(struct octeon_device *oct, sizeof(struct cvmx_bootmem_named_block_desc); } } - __cvmx_bootmem_unlock(flags); return result; } diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_device.c b/drivers/net/ethernet/cavium/liquidio/octeon_device.c index 586b68899b06..79c8875ffd61 100644 --- a/drivers/net/ethernet/cavium/liquidio/octeon_device.c +++ b/drivers/net/ethernet/cavium/liquidio/octeon_device.c @@ -1,24 +1,20 @@ /********************************************************************** -* Author: Cavium, Inc. -* -* Contact: support@cavium.com -* Please include "LiquidIO" in the subject. -* -* Copyright (c) 2003-2015 Cavium, Inc. -* -* This file is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License, Version 2, as -* published by the Free Software Foundation. -* -* This file is distributed in the hope that it will be useful, but -* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -* NONINFRINGEMENT. See the GNU General Public License for more -* details. -* -* This file may also be available under a different license from Cavium. -* Contact Cavium, Inc. for more information -**********************************************************************/ + * Author: Cavium, Inc. + * + * Contact: support@cavium.com + * Please include "LiquidIO" in the subject. + * + * Copyright (c) 2003-2016 Cavium, Inc. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, Version 2, as + * published by the Free Software Foundation. + * + * This file is distributed in the hope that it will be useful, but + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or + * NONINFRINGEMENT. See the GNU General Public License for more details. + ***********************************************************************/ #include <linux/pci.h> #include <linux/netdevice.h> #include <linux/vmalloc.h> @@ -520,11 +516,6 @@ static struct octeon_config default_cn23xx_conf = { } }; -enum { - OCTEON_CONFIG_TYPE_DEFAULT = 0, - NUM_OCTEON_CONFS, -}; - static struct octeon_config_ptr { u32 conf_type; } oct_conf_info[MAX_OCTEON_DEVICES] = { @@ -649,12 +640,12 @@ void octeon_free_device_mem(struct octeon_device *oct) int i; for (i = 0; i < MAX_OCTEON_OUTPUT_QUEUES(oct); i++) { - if (oct->io_qmask.oq & (1ULL << i)) + if (oct->io_qmask.oq & BIT_ULL(i)) vfree(oct->droq[i]); } for (i = 0; i < MAX_OCTEON_INSTR_QUEUES(oct); i++) { - if (oct->io_qmask.iq & (1ULL << i)) + if (oct->io_qmask.iq & BIT_ULL(i)) vfree(oct->instr_queue[i]); } @@ -767,6 +758,7 @@ octeon_allocate_ioq_vector(struct octeon_device *oct) ioq_vector->oct_dev = oct; ioq_vector->iq_index = i; ioq_vector->droq_index = i; + ioq_vector->mbox = oct->mbox[i]; cpu_num = i % num_online_cpus(); cpumask_set_cpu(cpu_num, &ioq_vector->affinity_mask); @@ -795,10 +787,9 @@ int octeon_setup_instr_queues(struct octeon_device *oct) if (OCTEON_CN6XXX(oct)) num_descs = - CFG_GET_NUM_DEF_TX_DESCS(CHIP_FIELD(oct, cn6xxx, conf)); + CFG_GET_NUM_DEF_TX_DESCS(CHIP_CONF(oct, cn6xxx)); else if (OCTEON_CN23XX_PF(oct)) - num_descs = CFG_GET_NUM_DEF_TX_DESCS(CHIP_FIELD(oct, cn23xx_pf, - conf)); + num_descs = CFG_GET_NUM_DEF_TX_DESCS(CHIP_CONF(oct, cn23xx_pf)); oct->num_iqs = 0; @@ -821,6 +812,7 @@ int octeon_setup_instr_queues(struct octeon_device *oct) if (octeon_init_instr_queue(oct, txpciq, num_descs)) { /* prevent memory leak */ vfree(oct->instr_queue[0]); + oct->instr_queue[0] = NULL; return 1; } @@ -837,14 +829,12 @@ int octeon_setup_output_queues(struct octeon_device *oct) if (OCTEON_CN6XXX(oct)) { num_descs = - CFG_GET_NUM_DEF_RX_DESCS(CHIP_FIELD(oct, cn6xxx, conf)); + CFG_GET_NUM_DEF_RX_DESCS(CHIP_CONF(oct, cn6xxx)); desc_size = - CFG_GET_DEF_RX_BUF_SIZE(CHIP_FIELD(oct, cn6xxx, conf)); + CFG_GET_DEF_RX_BUF_SIZE(CHIP_CONF(oct, cn6xxx)); } else if (OCTEON_CN23XX_PF(oct)) { - num_descs = CFG_GET_NUM_DEF_RX_DESCS(CHIP_FIELD(oct, cn23xx_pf, - conf)); - desc_size = CFG_GET_DEF_RX_BUF_SIZE(CHIP_FIELD(oct, cn23xx_pf, - conf)); + num_descs = CFG_GET_NUM_DEF_RX_DESCS(CHIP_CONF(oct, cn23xx_pf)); + desc_size = CFG_GET_DEF_RX_BUF_SIZE(CHIP_CONF(oct, cn23xx_pf)); } oct->num_oqs = 0; oct->droq[0] = vmalloc_node(sizeof(*oct->droq[0]), numa_node); @@ -853,8 +843,11 @@ int octeon_setup_output_queues(struct octeon_device *oct) if (!oct->droq[0]) return 1; - if (octeon_init_droq(oct, oq_no, num_descs, desc_size, NULL)) + if (octeon_init_droq(oct, oq_no, num_descs, desc_size, NULL)) { + vfree(oct->droq[oq_no]); + oct->droq[oq_no] = NULL; return 1; + } oct->num_oqs++; return 0; @@ -1070,10 +1063,10 @@ int octeon_core_drv_init(struct octeon_recv_info *recv_info, void *buf) if (OCTEON_CN6XXX(oct)) num_nic_ports = - CFG_GET_NUM_NIC_PORTS(CHIP_FIELD(oct, cn6xxx, conf)); + CFG_GET_NUM_NIC_PORTS(CHIP_CONF(oct, cn6xxx)); else if (OCTEON_CN23XX_PF(oct)) num_nic_ports = - CFG_GET_NUM_NIC_PORTS(CHIP_FIELD(oct, cn23xx_pf, conf)); + CFG_GET_NUM_NIC_PORTS(CHIP_CONF(oct, cn23xx_pf)); if (atomic_read(&oct->status) >= OCT_DEV_RUNNING) { dev_err(&oct->pci_dev->dev, "Received CORE OK when device state is 0x%x\n", @@ -1143,7 +1136,7 @@ int octeon_get_tx_qsize(struct octeon_device *oct, u32 q_no) { if (oct && (q_no < MAX_OCTEON_INSTR_QUEUES(oct)) && - (oct->io_qmask.iq & (1ULL << q_no))) + (oct->io_qmask.iq & BIT_ULL(q_no))) return oct->instr_queue[q_no]->max_count; return -1; @@ -1152,7 +1145,7 @@ int octeon_get_tx_qsize(struct octeon_device *oct, u32 q_no) int octeon_get_rx_qsize(struct octeon_device *oct, u32 q_no) { if (oct && (q_no < MAX_OCTEON_OUTPUT_QUEUES(oct)) && - (oct->io_qmask.oq & (1ULL << q_no))) + (oct->io_qmask.oq & BIT_ULL(q_no))) return oct->droq[q_no]->max_count; return -1; } @@ -1168,10 +1161,10 @@ struct octeon_config *octeon_get_conf(struct octeon_device *oct) if (OCTEON_CN6XXX(oct)) { default_oct_conf = - (struct octeon_config *)(CHIP_FIELD(oct, cn6xxx, conf)); + (struct octeon_config *)(CHIP_CONF(oct, cn6xxx)); } else if (OCTEON_CN23XX_PF(oct)) { default_oct_conf = (struct octeon_config *) - (CHIP_FIELD(oct, cn23xx_pf, conf)); + (CHIP_CONF(oct, cn23xx_pf)); } return default_oct_conf; } diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_device.h b/drivers/net/ethernet/cavium/liquidio/octeon_device.h index da15c2ae9330..5ce204884a3b 100644 --- a/drivers/net/ethernet/cavium/liquidio/octeon_device.h +++ b/drivers/net/ethernet/cavium/liquidio/octeon_device.h @@ -1,25 +1,20 @@ /********************************************************************** -* Author: Cavium, Inc. -* -* Contact: support@cavium.com -* Please include "LiquidIO" in the subject. -* -* Copyright (c) 2003-2015 Cavium, Inc. -* -* This file is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License, Version 2, as -* published by the Free Software Foundation. -* -* This file is distributed in the hope that it will be useful, but -* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -* NONINFRINGEMENT. See the GNU General Public License for more -* details. -* -* This file may also be available under a different license from Cavium. -* Contact Cavium, Inc. for more information -**********************************************************************/ - + * Author: Cavium, Inc. + * + * Contact: support@cavium.com + * Please include "LiquidIO" in the subject. + * + * Copyright (c) 2003-2016 Cavium, Inc. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, Version 2, as + * published by the Free Software Foundation. + * + * This file is distributed in the hope that it will be useful, but + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or + * NONINFRINGEMENT. See the GNU General Public License for more details. + ***********************************************************************/ /*! \file octeon_device.h * \brief Host Driver: This file defines the octeon device structure. */ @@ -38,6 +33,7 @@ #define OCTEON_CN68XX 0x0091 #define OCTEON_CN66XX 0x0092 #define OCTEON_CN23XX_PF_VID 0x9702 +#define OCTEON_CN23XX_VF_VID 0x9712 /**RevisionId for the chips */ #define OCTEON_CN23XX_REV_1_0 0x00 @@ -52,7 +48,13 @@ enum octeon_pci_swap_mode { OCTEON_PCI_32BIT_LW_SWAP = 3 }; +enum { + OCTEON_CONFIG_TYPE_DEFAULT = 0, + NUM_OCTEON_CONFS, +}; + #define OCTEON_OUTPUT_INTR (2) +#define OCTEON_MBOX_INTR (4) #define OCTEON_ALL_INTR 0xff /*--------------- PCI BAR1 index registers -------------*/ @@ -70,26 +72,30 @@ enum octeon_pci_swap_mode { * as it is initialized. */ #define OCT_DEV_BEGIN_STATE 0x0 -#define OCT_DEV_PCI_MAP_DONE 0x1 -#define OCT_DEV_DISPATCH_INIT_DONE 0x2 -#define OCT_DEV_INSTR_QUEUE_INIT_DONE 0x3 -#define OCT_DEV_SC_BUFF_POOL_INIT_DONE 0x4 -#define OCT_DEV_RESP_LIST_INIT_DONE 0x5 -#define OCT_DEV_DROQ_INIT_DONE 0x6 -#define OCT_DEV_IO_QUEUES_DONE 0x7 -#define OCT_DEV_CONSOLE_INIT_DONE 0x8 -#define OCT_DEV_HOST_OK 0x9 -#define OCT_DEV_CORE_OK 0xa -#define OCT_DEV_RUNNING 0xb -#define OCT_DEV_IN_RESET 0xc -#define OCT_DEV_STATE_INVALID 0xd +#define OCT_DEV_PCI_ENABLE_DONE 0x1 +#define OCT_DEV_PCI_MAP_DONE 0x2 +#define OCT_DEV_DISPATCH_INIT_DONE 0x3 +#define OCT_DEV_INSTR_QUEUE_INIT_DONE 0x4 +#define OCT_DEV_SC_BUFF_POOL_INIT_DONE 0x5 +#define OCT_DEV_RESP_LIST_INIT_DONE 0x6 +#define OCT_DEV_DROQ_INIT_DONE 0x7 +#define OCT_DEV_MBOX_SETUP_DONE 0x8 +#define OCT_DEV_MSIX_ALLOC_VECTOR_DONE 0x9 +#define OCT_DEV_INTR_SET_DONE 0xa +#define OCT_DEV_IO_QUEUES_DONE 0xb +#define OCT_DEV_CONSOLE_INIT_DONE 0xc +#define OCT_DEV_HOST_OK 0xd +#define OCT_DEV_CORE_OK 0xe +#define OCT_DEV_RUNNING 0xf +#define OCT_DEV_IN_RESET 0x10 +#define OCT_DEV_STATE_INVALID 0x11 #define OCT_DEV_STATES OCT_DEV_STATE_INVALID /** Octeon Device interrupts - * These interrupt bits are set in int_status filed of - * octeon_device structure - */ + * These interrupt bits are set in int_status filed of + * octeon_device structure + */ #define OCT_DEV_INTR_DMA0_FORCE 0x01 #define OCT_DEV_INTR_DMA1_FORCE 0x02 #define OCT_DEV_INTR_PKT_DATA 0x04 @@ -208,6 +214,10 @@ struct octeon_fn_list { irqreturn_t (*process_interrupt_regs)(void *); u64 (*msix_interrupt_handler)(void *); + + int (*setup_mbox)(struct octeon_device *); + int (*free_mbox)(struct octeon_device *); + int (*soft_reset)(struct octeon_device *); int (*setup_device_regs)(struct octeon_device *); void (*bar1_idx_setup)(struct octeon_device *, u64, u32, int); @@ -322,14 +332,39 @@ struct octeon_pf_vf_hs_word { }; struct octeon_sriov_info { + /* Number of rings assigned to VF */ + u32 rings_per_vf; + + /** Max Number of VF devices that can be enabled. This variable can + * specified during load time or it will be derived after allocating + * PF queues. When max_vfs is derived then each VF will get one queue + **/ + u32 max_vfs; + + /** Number of VF devices enabled using sysfs. */ + u32 num_vfs_alloced; + /* Actual rings left for PF device */ u32 num_pf_rings; - /* SRN of PF usable IO queues */ + /* SRN of PF usable IO queues */ u32 pf_srn; + /* total pf rings */ u32 trs; + u32 sriov_enabled; + + /*lookup table that maps DPI ring number to VF pci_dev struct pointer*/ + struct pci_dev *dpiring_to_vfpcidev_lut[MAX_POSSIBLE_VFS]; + + u64 vf_macaddr[MAX_POSSIBLE_VFS]; + + u16 vf_vlantci[MAX_POSSIBLE_VFS]; + + int vf_linkstate[MAX_POSSIBLE_VFS]; + + u64 vf_drv_loaded_mask; }; struct octeon_ioq_vector { @@ -337,6 +372,7 @@ struct octeon_ioq_vector { int iq_index; int droq_index; int vector; + struct octeon_mbox *mbox; struct cpumask affinity_mask; u32 ioq_num; }; @@ -474,6 +510,9 @@ struct octeon_device { int msix_on; + /** Mail Box details of each octeon queue. */ + struct octeon_mbox *mbox[MAX_POSSIBLE_VFS]; + /** IOq information of it's corresponding MSI-X interrupt. */ struct octeon_ioq_vector *ioq_vector; @@ -490,11 +529,14 @@ struct octeon_device { #define OCT_DRV_ONLINE 1 #define OCT_DRV_OFFLINE 2 -#define OCTEON_CN6XXX(oct) ((oct->chip_id == OCTEON_CN66XX) || \ - (oct->chip_id == OCTEON_CN68XX)) -#define OCTEON_CN23XX_PF(oct) (oct->chip_id == OCTEON_CN23XX_PF_VID) -#define CHIP_FIELD(oct, TYPE, field) \ - (((struct octeon_ ## TYPE *)(oct->chip))->field) +#define OCTEON_CN6XXX(oct) ({ \ + typeof(oct) _oct = (oct); \ + ((_oct->chip_id == OCTEON_CN66XX) || \ + (_oct->chip_id == OCTEON_CN68XX)); }) +#define OCTEON_CN23XX_PF(oct) ((oct)->chip_id == OCTEON_CN23XX_PF_VID) +#define OCTEON_CN23XX_VF(oct) ((oct)->chip_id == OCTEON_CN23XX_VF_VID) +#define CHIP_CONF(oct, TYPE) \ + (((struct octeon_ ## TYPE *)((oct)->chip))->conf) struct oct_intrmod_cmd { struct octeon_device *oct_dev; @@ -508,7 +550,7 @@ struct oct_intrmod_cmd { void octeon_init_device_list(int conf_type); /** Free memory for Input and Output queue structures for a octeon device */ -void octeon_free_device_mem(struct octeon_device *); +void octeon_free_device_mem(struct octeon_device *oct); /* Look up a free entry in the octeon_device table and allocate resources * for the octeon_device structure for an octeon device. Called at init @@ -606,16 +648,16 @@ void lio_pci_writeq(struct octeon_device *oct, u64 val, u64 addr); /* Routines for reading and writing CSRs */ #define octeon_write_csr(oct_dev, reg_off, value) \ - writel(value, oct_dev->mmio[0].hw_addr + reg_off) + writel(value, (oct_dev)->mmio[0].hw_addr + (reg_off)) #define octeon_write_csr64(oct_dev, reg_off, val64) \ - writeq(val64, oct_dev->mmio[0].hw_addr + reg_off) + writeq(val64, (oct_dev)->mmio[0].hw_addr + (reg_off)) #define octeon_read_csr(oct_dev, reg_off) \ - readl(oct_dev->mmio[0].hw_addr + reg_off) + readl((oct_dev)->mmio[0].hw_addr + (reg_off)) #define octeon_read_csr64(oct_dev, reg_off) \ - readq(oct_dev->mmio[0].hw_addr + reg_off) + readq((oct_dev)->mmio[0].hw_addr + (reg_off)) /** * Checks if memory access is okay diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_droq.c b/drivers/net/ethernet/cavium/liquidio/octeon_droq.c index f60e5320daf4..8bf1ac76bcdc 100644 --- a/drivers/net/ethernet/cavium/liquidio/octeon_droq.c +++ b/drivers/net/ethernet/cavium/liquidio/octeon_droq.c @@ -1,24 +1,20 @@ /********************************************************************** -* Author: Cavium, Inc. -* -* Contact: support@cavium.com -* Please include "LiquidIO" in the subject. -* -* Copyright (c) 2003-2015 Cavium, Inc. -* -* This file is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License, Version 2, as -* published by the Free Software Foundation. -* -* This file is distributed in the hope that it will be useful, but -* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -* NONINFRINGEMENT. See the GNU General Public License for more -* details. -* -* This file may also be available under a different license from Cavium. -* Contact Cavium, Inc. for more information -**********************************************************************/ + * Author: Cavium, Inc. + * + * Contact: support@cavium.com + * Please include "LiquidIO" in the subject. + * + * Copyright (c) 2003-2016 Cavium, Inc. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, Version 2, as + * published by the Free Software Foundation. + * + * This file is distributed in the hope that it will be useful, but + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or + * NONINFRINGEMENT. See the GNU General Public License for more details. + ***********************************************************************/ #include <linux/pci.h> #include <linux/netdevice.h> #include <linux/vmalloc.h> @@ -33,9 +29,6 @@ #include "cn66xx_device.h" #include "cn23xx_pf_device.h" -#define CVM_MIN(d1, d2) (((d1) < (d2)) ? (d1) : (d2)) -#define CVM_MAX(d1, d2) (((d1) > (d2)) ? (d1) : (d2)) - struct niclist { struct list_head list; void *ptr; @@ -258,13 +251,13 @@ int octeon_init_droq(struct octeon_device *oct, c_num_descs = num_descs; c_buf_size = desc_size; if (OCTEON_CN6XXX(oct)) { - struct octeon_config *conf6x = CHIP_FIELD(oct, cn6xxx, conf); + struct octeon_config *conf6x = CHIP_CONF(oct, cn6xxx); c_pkts_per_intr = (u32)CFG_GET_OQ_PKTS_PER_INTR(conf6x); c_refill_threshold = (u32)CFG_GET_OQ_REFILL_THRESHOLD(conf6x); } else if (OCTEON_CN23XX_PF(oct)) { - struct octeon_config *conf23 = CHIP_FIELD(oct, cn23xx_pf, conf); + struct octeon_config *conf23 = CHIP_CONF(oct, cn23xx_pf); c_pkts_per_intr = (u32)CFG_GET_OQ_PKTS_PER_INTR(conf23); c_refill_threshold = (u32)CFG_GET_OQ_REFILL_THRESHOLD(conf23); @@ -337,7 +330,7 @@ int octeon_init_droq(struct octeon_device *oct, /* For 56xx Pass1, this function won't be called, so no checks. */ oct->fn_list.setup_oq_regs(oct, q_no); - oct->io_qmask.oq |= (1ULL << q_no); + oct->io_qmask.oq |= BIT_ULL(q_no); return 0; @@ -409,7 +402,7 @@ static inline struct octeon_recv_info *octeon_create_recv_info( recv_pkt->buffer_ptr[i] = droq->recv_buf_list[idx].buffer; droq->recv_buf_list[idx].buffer = NULL; - INCR_INDEX_BY1(idx, droq->max_count); + idx = incr_index(idx, 1, droq->max_count); bytes_left -= droq->buffer_size; i++; buf_cnt--; @@ -440,14 +433,15 @@ octeon_droq_refill_pullup_descs(struct octeon_droq *droq, droq->recv_buf_list[refill_index].buffer = NULL; desc_ring[refill_index].buffer_ptr = 0; do { - INCR_INDEX_BY1(droq->refill_idx, - droq->max_count); + droq->refill_idx = incr_index(droq->refill_idx, + 1, + droq->max_count); desc_refilled++; droq->refill_count--; } while (droq->recv_buf_list[droq->refill_idx]. buffer); } - INCR_INDEX_BY1(refill_index, droq->max_count); + refill_index = incr_index(refill_index, 1, droq->max_count); } /* while */ return desc_refilled; } @@ -514,7 +508,8 @@ octeon_droq_refill(struct octeon_device *octeon_dev, struct octeon_droq *droq) /* Reset any previous values in the length field. */ droq->info_list[droq->refill_idx].length = 0; - INCR_INDEX_BY1(droq->refill_idx, droq->max_count); + droq->refill_idx = incr_index(droq->refill_idx, 1, + droq->max_count); desc_refilled++; droq->refill_count--; } @@ -599,7 +594,8 @@ static inline void octeon_droq_drop_packets(struct octeon_device *oct, buf_cnt = 1; } - INCR_INDEX(droq->read_idx, buf_cnt, droq->max_count); + droq->read_idx = incr_index(droq->read_idx, buf_cnt, + droq->max_count); droq->refill_count += buf_cnt; } } @@ -639,11 +635,12 @@ octeon_droq_fast_process_packets(struct octeon_device *oct, rh = &info->rh; total_len += (u32)info->length; - if (OPCODE_SLOW_PATH(rh)) { + if (opcode_slow_path(rh)) { u32 buf_cnt; buf_cnt = octeon_droq_dispatch_pkt(oct, droq, rh, info); - INCR_INDEX(droq->read_idx, buf_cnt, droq->max_count); + droq->read_idx = incr_index(droq->read_idx, + buf_cnt, droq->max_count); droq->refill_count += buf_cnt; } else { if (info->length <= droq->buffer_size) { @@ -657,7 +654,8 @@ octeon_droq_fast_process_packets(struct octeon_device *oct, droq->recv_buf_list[droq->read_idx].buffer = NULL; - INCR_INDEX_BY1(droq->read_idx, droq->max_count); + droq->read_idx = incr_index(droq->read_idx, 1, + droq->max_count); droq->refill_count++; } else { nicbuf = octeon_fast_packet_alloc((u32) @@ -689,8 +687,9 @@ octeon_droq_fast_process_packets(struct octeon_device *oct, } pkt_len += cpy_len; - INCR_INDEX_BY1(droq->read_idx, - droq->max_count); + droq->read_idx = + incr_index(droq->read_idx, 1, + droq->max_count); droq->refill_count++; } } @@ -804,9 +803,8 @@ octeon_droq_process_poll_pkts(struct octeon_device *oct, while (total_pkts_processed < budget) { octeon_droq_check_hw_for_pkts(droq); - pkts_available = - CVM_MIN((budget - total_pkts_processed), - (u32)(atomic_read(&droq->pkts_pending))); + pkts_available = min((budget - total_pkts_processed), + (u32)(atomic_read(&droq->pkts_pending))); if (pkts_available == 0) break; @@ -988,7 +986,8 @@ int octeon_create_droq(struct octeon_device *oct, if (!droq) droq = vmalloc(sizeof(*droq)); if (!droq) - goto create_droq_fail; + return -1; + memset(droq, 0, sizeof(struct octeon_droq)); /*Disable the pkt o/p for this Q */ @@ -996,7 +995,11 @@ int octeon_create_droq(struct octeon_device *oct, oct->droq[q_no] = droq; /* Initialize the Droq */ - octeon_init_droq(oct, q_no, num_descs, desc_size, app_ctx); + if (octeon_init_droq(oct, q_no, num_descs, desc_size, app_ctx)) { + vfree(oct->droq[q_no]); + oct->droq[q_no] = NULL; + return -1; + } oct->num_oqs++; @@ -1009,8 +1012,4 @@ int octeon_create_droq(struct octeon_device *oct, * the same time. */ return 0; - -create_droq_fail: - octeon_delete_droq(oct, q_no); - return -ENOMEM; } diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_droq.h b/drivers/net/ethernet/cavium/liquidio/octeon_droq.h index 5be002d5dba4..e62074090681 100644 --- a/drivers/net/ethernet/cavium/liquidio/octeon_droq.h +++ b/drivers/net/ethernet/cavium/liquidio/octeon_droq.h @@ -4,7 +4,7 @@ * Contact: support@cavium.com * Please include "LiquidIO" in the subject. * - * Copyright (c) 2003-2015 Cavium, Inc. + * Copyright (c) 2003-2016 Cavium, Inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, Version 2, as @@ -13,13 +13,8 @@ * This file is distributed in the hope that it will be useful, but * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or - * NONINFRINGEMENT. See the GNU General Public License for more - * details. - * - * This file may also be available under a different license from Cavium. - * Contact Cavium, Inc. for more information - **********************************************************************/ - + * NONINFRINGEMENT. See the GNU General Public License for more details. + ***********************************************************************/ /*! \file octeon_droq.h * \brief Implementation of Octeon Output queues. "Output" is with * respect to the Octeon device on the NIC. From this driver's point of @@ -81,7 +76,7 @@ struct octeon_skb_page_info { * the Octeon device. Since the descriptor ring keeps physical (bus) * addresses, this field is required for the driver to keep track of * the virtual address pointers. -*/ + */ struct octeon_recv_buffer { /** Packet buffer, including metadata. */ void *buffer; @@ -121,7 +116,6 @@ struct oct_droq_stats { /** Num of Packets dropped due to receive path failures. */ u64 rx_dropped; - /** Num of vxlan packets received; */ u64 rx_vxlan; /** Num of failures of recv_buffer_alloc() */ @@ -359,7 +353,7 @@ struct octeon_droq { * @param q_no - droq no. ranges from 0 - 3. * @param app_ctx - pointer to application context * @return Success: 0 Failure: 1 -*/ + */ int octeon_init_droq(struct octeon_device *oct_dev, u32 q_no, u32 num_descs, @@ -372,7 +366,7 @@ int octeon_init_droq(struct octeon_device *oct_dev, * @param oct_dev - pointer to the octeon device structure * @param q_no - droq no. ranges from 0 - 3. * @return: Success: 0 Failure: 1 -*/ + */ int octeon_delete_droq(struct octeon_device *oct_dev, u32 q_no); /** Register a change in droq operations. The ops field has a pointer to a diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_iq.h b/drivers/net/ethernet/cavium/liquidio/octeon_iq.h index e4d426ba18dc..e04ca8f0b4a7 100644 --- a/drivers/net/ethernet/cavium/liquidio/octeon_iq.h +++ b/drivers/net/ethernet/cavium/liquidio/octeon_iq.h @@ -4,7 +4,7 @@ * Contact: support@cavium.com * Please include "LiquidIO" in the subject. * - * Copyright (c) 2003-2015 Cavium, Inc. + * Copyright (c) 2003-2016 Cavium, Inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, Version 2, as @@ -13,13 +13,8 @@ * This file is distributed in the hope that it will be useful, but * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or - * NONINFRINGEMENT. See the GNU General Public License for more - * details. - * - * This file may also be available under a different license from Cavium. - * Contact Cavium, Inc. for more information - **********************************************************************/ - + * NONINFRINGEMENT. See the GNU General Public License for more details. + ***********************************************************************/ /*! \file octeon_iq.h * \brief Host Driver: Implementation of Octeon input queues. "Input" is * with respect to the Octeon device on the NIC. From this driver's @@ -69,7 +64,6 @@ struct oct_iq_stats { u64 tx_vxlan; /* tunnel */ u64 tx_dmamap_fail; u64 tx_restart; - /*u64 tx_timeout_count;*/ }; #define OCT_IQ_STATS_SIZE (sizeof(struct oct_iq_stats)) @@ -78,7 +72,7 @@ struct oct_iq_stats { * The input queue is used to post raw (instruction) mode data or packet * data to Octeon device from the host. Each input queue (upto 4) for * a Octeon device has one such structure to represent it. -*/ + */ struct octeon_instr_queue { struct octeon_device *oct_dev; @@ -118,8 +112,8 @@ struct octeon_instr_queue { u32 octeon_read_index; /** This index aids in finding the window in the queue where Octeon - * has read the commands. - */ + * has read the commands. + */ u32 flush_index; /** This field keeps track of the instructions pending in this queue. */ @@ -150,8 +144,8 @@ struct octeon_instr_queue { u64 last_db_time; /** The doorbell timeout. If the doorbell was not rung for this time and - * fill_cnt is non-zero, ring the doorbell again. - */ + * fill_cnt is non-zero, ring the doorbell again. + */ u32 db_timeout; /** Statistics for this input queue. */ @@ -309,6 +303,9 @@ struct octeon_sc_buffer_pool { atomic_t alloc_buf_count; }; +#define INCR_INSTRQUEUE_PKT_COUNT(octeon_dev_ptr, iq_no, field, count) \ + (((octeon_dev_ptr)->instr_queue[iq_no]->stats.field) += count) + int octeon_setup_sc_buffer_pool(struct octeon_device *oct); int octeon_free_sc_buffer_pool(struct octeon_device *oct); struct octeon_soft_command * diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_mailbox.c b/drivers/net/ethernet/cavium/liquidio/octeon_mailbox.c new file mode 100644 index 000000000000..5309384e4cd0 --- /dev/null +++ b/drivers/net/ethernet/cavium/liquidio/octeon_mailbox.c @@ -0,0 +1,318 @@ +/********************************************************************** + * Author: Cavium, Inc. + * + * Contact: support@cavium.com + * Please include "LiquidIO" in the subject. + * + * Copyright (c) 2003-2016 Cavium, Inc. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, Version 2, as + * published by the Free Software Foundation. + * + * This file is distributed in the hope that it will be useful, but + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or + * NONINFRINGEMENT. See the GNU General Public License for more details. + ***********************************************************************/ +#include <linux/pci.h> +#include <linux/netdevice.h> +#include "liquidio_common.h" +#include "octeon_droq.h" +#include "octeon_iq.h" +#include "response_manager.h" +#include "octeon_device.h" +#include "octeon_main.h" +#include "octeon_mailbox.h" + +/** + * octeon_mbox_read: + * @oct: Pointer mailbox + * + * Reads the 8-bytes of data from the mbox register + * Writes back the acknowldgement inidcating completion of read + */ +int octeon_mbox_read(struct octeon_mbox *mbox) +{ + union octeon_mbox_message msg; + int ret = 0; + + spin_lock(&mbox->lock); + + msg.u64 = readq(mbox->mbox_read_reg); + + if ((msg.u64 == OCTEON_PFVFACK) || (msg.u64 == OCTEON_PFVFSIG)) { + spin_unlock(&mbox->lock); + return 0; + } + + if (mbox->state & OCTEON_MBOX_STATE_REQUEST_RECEIVING) { + mbox->mbox_req.data[mbox->mbox_req.recv_len - 1] = msg.u64; + mbox->mbox_req.recv_len++; + } else { + if (mbox->state & OCTEON_MBOX_STATE_RESPONSE_RECEIVING) { + mbox->mbox_resp.data[mbox->mbox_resp.recv_len - 1] = + msg.u64; + mbox->mbox_resp.recv_len++; + } else { + if ((mbox->state & OCTEON_MBOX_STATE_IDLE) && + (msg.s.type == OCTEON_MBOX_REQUEST)) { + mbox->state &= ~OCTEON_MBOX_STATE_IDLE; + mbox->state |= + OCTEON_MBOX_STATE_REQUEST_RECEIVING; + mbox->mbox_req.msg.u64 = msg.u64; + mbox->mbox_req.q_no = mbox->q_no; + mbox->mbox_req.recv_len = 1; + } else { + if ((mbox->state & + OCTEON_MBOX_STATE_RESPONSE_PENDING) && + (msg.s.type == OCTEON_MBOX_RESPONSE)) { + mbox->state &= + ~OCTEON_MBOX_STATE_RESPONSE_PENDING; + mbox->state |= + OCTEON_MBOX_STATE_RESPONSE_RECEIVING + ; + mbox->mbox_resp.msg.u64 = msg.u64; + mbox->mbox_resp.q_no = mbox->q_no; + mbox->mbox_resp.recv_len = 1; + } else { + writeq(OCTEON_PFVFERR, + mbox->mbox_read_reg); + mbox->state |= OCTEON_MBOX_STATE_ERROR; + spin_unlock(&mbox->lock); + return 1; + } + } + } + } + + if (mbox->state & OCTEON_MBOX_STATE_REQUEST_RECEIVING) { + if (mbox->mbox_req.recv_len < msg.s.len) { + ret = 0; + } else { + mbox->state &= ~OCTEON_MBOX_STATE_REQUEST_RECEIVING; + mbox->state |= OCTEON_MBOX_STATE_REQUEST_RECEIVED; + ret = 1; + } + } else { + if (mbox->state & OCTEON_MBOX_STATE_RESPONSE_RECEIVING) { + if (mbox->mbox_resp.recv_len < msg.s.len) { + ret = 0; + } else { + mbox->state &= + ~OCTEON_MBOX_STATE_RESPONSE_RECEIVING; + mbox->state |= + OCTEON_MBOX_STATE_RESPONSE_RECEIVED; + ret = 1; + } + } else { + WARN_ON(1); + } + } + + writeq(OCTEON_PFVFACK, mbox->mbox_read_reg); + + spin_unlock(&mbox->lock); + + return ret; +} + +/** + * octeon_mbox_write: + * @oct: Pointer Octeon Device + * @mbox_cmd: Cmd to send to mailbox. + * + * Populates the queue specific mbox structure + * with cmd information. + * Write the cmd to mbox register + */ +int octeon_mbox_write(struct octeon_device *oct, + struct octeon_mbox_cmd *mbox_cmd) +{ + struct octeon_mbox *mbox = oct->mbox[mbox_cmd->q_no]; + u32 count, i, ret = OCTEON_MBOX_STATUS_SUCCESS; + unsigned long flags; + + spin_lock_irqsave(&mbox->lock, flags); + + if ((mbox_cmd->msg.s.type == OCTEON_MBOX_RESPONSE) && + !(mbox->state & OCTEON_MBOX_STATE_REQUEST_RECEIVED)) { + spin_unlock_irqrestore(&mbox->lock, flags); + return OCTEON_MBOX_STATUS_FAILED; + } + + if ((mbox_cmd->msg.s.type == OCTEON_MBOX_REQUEST) && + !(mbox->state & OCTEON_MBOX_STATE_IDLE)) { + spin_unlock_irqrestore(&mbox->lock, flags); + return OCTEON_MBOX_STATUS_BUSY; + } + + if (mbox_cmd->msg.s.type == OCTEON_MBOX_REQUEST) { + memcpy(&mbox->mbox_resp, mbox_cmd, + sizeof(struct octeon_mbox_cmd)); + mbox->state = OCTEON_MBOX_STATE_RESPONSE_PENDING; + } + + spin_unlock_irqrestore(&mbox->lock, flags); + + count = 0; + + while (readq(mbox->mbox_write_reg) != OCTEON_PFVFSIG) { + schedule_timeout_uninterruptible(LIO_MBOX_WRITE_WAIT_TIME); + if (count++ == LIO_MBOX_WRITE_WAIT_CNT) { + ret = OCTEON_MBOX_STATUS_FAILED; + break; + } + } + + if (ret == OCTEON_MBOX_STATUS_SUCCESS) { + writeq(mbox_cmd->msg.u64, mbox->mbox_write_reg); + for (i = 0; i < (u32)(mbox_cmd->msg.s.len - 1); i++) { + count = 0; + while (readq(mbox->mbox_write_reg) != + OCTEON_PFVFACK) { + schedule_timeout_uninterruptible(10); + if (count++ == LIO_MBOX_WRITE_WAIT_CNT) { + ret = OCTEON_MBOX_STATUS_FAILED; + break; + } + } + writeq(mbox_cmd->data[i], mbox->mbox_write_reg); + } + } + + spin_lock_irqsave(&mbox->lock, flags); + if (mbox_cmd->msg.s.type == OCTEON_MBOX_RESPONSE) { + mbox->state = OCTEON_MBOX_STATE_IDLE; + writeq(OCTEON_PFVFSIG, mbox->mbox_read_reg); + } else { + if ((!mbox_cmd->msg.s.resp_needed) || + (ret == OCTEON_MBOX_STATUS_FAILED)) { + mbox->state &= ~OCTEON_MBOX_STATE_RESPONSE_PENDING; + if (!(mbox->state & + (OCTEON_MBOX_STATE_REQUEST_RECEIVING | + OCTEON_MBOX_STATE_REQUEST_RECEIVED))) + mbox->state = OCTEON_MBOX_STATE_IDLE; + } + } + spin_unlock_irqrestore(&mbox->lock, flags); + + return ret; +} + +/** + * octeon_mbox_process_cmd: + * @mbox: Pointer mailbox + * @mbox_cmd: Pointer to command received + * + * Process the cmd received in mbox + */ +static int octeon_mbox_process_cmd(struct octeon_mbox *mbox, + struct octeon_mbox_cmd *mbox_cmd) +{ + struct octeon_device *oct = mbox->oct_dev; + + switch (mbox_cmd->msg.s.cmd) { + case OCTEON_VF_ACTIVE: + dev_dbg(&oct->pci_dev->dev, "got vfactive sending data back\n"); + mbox_cmd->msg.s.type = OCTEON_MBOX_RESPONSE; + mbox_cmd->msg.s.resp_needed = 1; + mbox_cmd->msg.s.len = 2; + mbox_cmd->data[0] = 0; /* VF version is in mbox_cmd->data[0] */ + ((struct lio_version *)&mbox_cmd->data[0])->major = + LIQUIDIO_BASE_MAJOR_VERSION; + ((struct lio_version *)&mbox_cmd->data[0])->minor = + LIQUIDIO_BASE_MINOR_VERSION; + ((struct lio_version *)&mbox_cmd->data[0])->micro = + LIQUIDIO_BASE_MICRO_VERSION; + memcpy(mbox_cmd->msg.s.params, (uint8_t *)&oct->pfvf_hsword, 6); + /* Sending core cofig info to the corresponding active VF.*/ + octeon_mbox_write(oct, mbox_cmd); + break; + + case OCTEON_VF_FLR_REQUEST: + dev_info(&oct->pci_dev->dev, + "got a request for FLR from VF that owns DPI ring %u\n", + mbox->q_no); + pcie_capability_set_word( + oct->sriov_info.dpiring_to_vfpcidev_lut[mbox->q_no], + PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_BCR_FLR); + break; + + case OCTEON_PF_CHANGED_VF_MACADDR: + if (OCTEON_CN23XX_VF(oct)) + octeon_pf_changed_vf_macaddr(oct, + mbox_cmd->msg.s.params); + break; + + default: + break; + } + return 0; +} + +/** + *octeon_mbox_process_message: + * + * Process the received mbox message. + */ +int octeon_mbox_process_message(struct octeon_mbox *mbox) +{ + struct octeon_mbox_cmd mbox_cmd; + unsigned long flags; + + spin_lock_irqsave(&mbox->lock, flags); + + if (mbox->state & OCTEON_MBOX_STATE_ERROR) { + if (mbox->state & (OCTEON_MBOX_STATE_RESPONSE_PENDING | + OCTEON_MBOX_STATE_RESPONSE_RECEIVING)) { + memcpy(&mbox_cmd, &mbox->mbox_resp, + sizeof(struct octeon_mbox_cmd)); + mbox->state = OCTEON_MBOX_STATE_IDLE; + writeq(OCTEON_PFVFSIG, mbox->mbox_read_reg); + spin_unlock_irqrestore(&mbox->lock, flags); + mbox_cmd.recv_status = 1; + if (mbox_cmd.fn) + mbox_cmd.fn(mbox->oct_dev, &mbox_cmd, + mbox_cmd.fn_arg); + return 0; + } + + mbox->state = OCTEON_MBOX_STATE_IDLE; + writeq(OCTEON_PFVFSIG, mbox->mbox_read_reg); + spin_unlock_irqrestore(&mbox->lock, flags); + return 0; + } + + if (mbox->state & OCTEON_MBOX_STATE_RESPONSE_RECEIVED) { + memcpy(&mbox_cmd, &mbox->mbox_resp, + sizeof(struct octeon_mbox_cmd)); + mbox->state = OCTEON_MBOX_STATE_IDLE; + writeq(OCTEON_PFVFSIG, mbox->mbox_read_reg); + spin_unlock_irqrestore(&mbox->lock, flags); + mbox_cmd.recv_status = 0; + if (mbox_cmd.fn) + mbox_cmd.fn(mbox->oct_dev, &mbox_cmd, mbox_cmd.fn_arg); + return 0; + } + + if (mbox->state & OCTEON_MBOX_STATE_REQUEST_RECEIVED) { + memcpy(&mbox_cmd, &mbox->mbox_req, + sizeof(struct octeon_mbox_cmd)); + if (!mbox_cmd.msg.s.resp_needed) { + mbox->state &= ~OCTEON_MBOX_STATE_REQUEST_RECEIVED; + if (!(mbox->state && + OCTEON_MBOX_STATE_RESPONSE_PENDING)) + mbox->state = OCTEON_MBOX_STATE_IDLE; + writeq(OCTEON_PFVFSIG, mbox->mbox_read_reg); + } + + spin_unlock_irqrestore(&mbox->lock, flags); + octeon_mbox_process_cmd(mbox, &mbox_cmd); + return 0; + } + + WARN_ON(1); + + return 0; +} diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_mailbox.h b/drivers/net/ethernet/cavium/liquidio/octeon_mailbox.h new file mode 100644 index 000000000000..fe60a3e6247b --- /dev/null +++ b/drivers/net/ethernet/cavium/liquidio/octeon_mailbox.h @@ -0,0 +1,115 @@ +/********************************************************************** + * Author: Cavium, Inc. + * + * Contact: support@cavium.com + * Please include "LiquidIO" in the subject. + * + * Copyright (c) 2003-2016 Cavium, Inc. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, Version 2, as + * published by the Free Software Foundation. + * + * This file is distributed in the hope that it will be useful, but + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or + * NONINFRINGEMENT. See the GNU General Public License for more details. + ***********************************************************************/ +#ifndef __MAILBOX_H__ +#define __MAILBOX_H__ + +/* Macros for Mail Box Communication */ + +#define OCTEON_MBOX_DATA_MAX 32 + +#define OCTEON_VF_ACTIVE 0x1 +#define OCTEON_VF_FLR_REQUEST 0x2 +#define OCTEON_PF_CHANGED_VF_MACADDR 0x4 + +/*Macro for Read acknowldgement*/ +#define OCTEON_PFVFACK 0xffffffffffffffff +#define OCTEON_PFVFSIG 0x1122334455667788 +#define OCTEON_PFVFERR 0xDEADDEADDEADDEAD + +#define LIO_MBOX_WRITE_WAIT_CNT 1000 +#define LIO_MBOX_WRITE_WAIT_TIME 10 + +enum octeon_mbox_cmd_status { + OCTEON_MBOX_STATUS_SUCCESS = 0, + OCTEON_MBOX_STATUS_FAILED = 1, + OCTEON_MBOX_STATUS_BUSY = 2 +}; + +enum octeon_mbox_message_type { + OCTEON_MBOX_REQUEST = 0, + OCTEON_MBOX_RESPONSE = 1 +}; + +union octeon_mbox_message { + u64 u64; + struct { + u16 type : 1; + u16 resp_needed : 1; + u16 cmd : 6; + u16 len : 8; + u8 params[6]; + } s; +}; + +typedef void (*octeon_mbox_callback_t)(void *, void *, void *); + +struct octeon_mbox_cmd { + union octeon_mbox_message msg; + u64 data[OCTEON_MBOX_DATA_MAX]; + u32 q_no; + u32 recv_len; + u32 recv_status; + octeon_mbox_callback_t fn; + void *fn_arg; +}; + +enum octeon_mbox_state { + OCTEON_MBOX_STATE_IDLE = 1, + OCTEON_MBOX_STATE_REQUEST_RECEIVING = 2, + OCTEON_MBOX_STATE_REQUEST_RECEIVED = 4, + OCTEON_MBOX_STATE_RESPONSE_PENDING = 8, + OCTEON_MBOX_STATE_RESPONSE_RECEIVING = 16, + OCTEON_MBOX_STATE_RESPONSE_RECEIVED = 16, + OCTEON_MBOX_STATE_ERROR = 32 +}; + +struct octeon_mbox { + /** A spinlock to protect access to this q_mbox. */ + spinlock_t lock; + + struct octeon_device *oct_dev; + + u32 q_no; + + enum octeon_mbox_state state; + + struct cavium_wk mbox_poll_wk; + + /** SLI_MAC_PF_MBOX_INT for PF, SLI_PKT_MBOX_INT for VF. */ + void *mbox_int_reg; + + /** SLI_PKT_PF_VF_MBOX_SIG(0) for PF, SLI_PKT_PF_VF_MBOX_SIG(1) for VF. + */ + void *mbox_write_reg; + + /** SLI_PKT_PF_VF_MBOX_SIG(1) for PF, SLI_PKT_PF_VF_MBOX_SIG(0) for VF. + */ + void *mbox_read_reg; + + struct octeon_mbox_cmd mbox_req; + + struct octeon_mbox_cmd mbox_resp; + +}; + +int octeon_mbox_read(struct octeon_mbox *mbox); +int octeon_mbox_write(struct octeon_device *oct, + struct octeon_mbox_cmd *mbox_cmd); +int octeon_mbox_process_message(struct octeon_mbox *mbox); + +#endif diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_main.h b/drivers/net/ethernet/cavium/liquidio/octeon_main.h index 366298f7bcb2..8cd389148166 100644 --- a/drivers/net/ethernet/cavium/liquidio/octeon_main.h +++ b/drivers/net/ethernet/cavium/liquidio/octeon_main.h @@ -4,7 +4,7 @@ * Contact: support@cavium.com * Please include "LiquidIO" in the subject. * - * Copyright (c) 2003-2015 Cavium, Inc. + * Copyright (c) 2003-2016 Cavium, Inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, Version 2, as @@ -13,13 +13,8 @@ * This file is distributed in the hope that it will be useful, but * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or - * NONINFRINGEMENT. See the GNU General Public License for more - * details. - * - * This file may also be available under a different license from Cavium. - * Contact Cavium, Inc. for more information - **********************************************************************/ - + * NONINFRINGEMENT. See the GNU General Public License for more details. + ***********************************************************************/ /*! \file octeon_main.h * \brief Host Driver: This file is included by all host driver source files * to include common definitions. @@ -66,7 +61,7 @@ void octeon_update_tx_completion_counters(void *buf, int reqtype, unsigned int *bytes_compl); void octeon_report_tx_completion_to_bql(void *txq, unsigned int pkts_compl, unsigned int bytes_compl); - +void octeon_pf_changed_vf_macaddr(struct octeon_device *oct, u8 *mac); /** Swap 8B blocks */ static inline void octeon_swap_8B_data(u64 *data, u32 blocks) { @@ -78,10 +73,10 @@ static inline void octeon_swap_8B_data(u64 *data, u32 blocks) } /** - * \brief unmaps a PCI BAR - * @param oct Pointer to Octeon device - * @param baridx bar index - */ + * \brief unmaps a PCI BAR + * @param oct Pointer to Octeon device + * @param baridx bar index + */ static inline void octeon_unmap_pci_barx(struct octeon_device *oct, int baridx) { dev_dbg(&oct->pci_dev->dev, "Freeing PCI mapped regions for Bar%d\n", @@ -116,7 +111,7 @@ static inline int octeon_map_pci_barx(struct octeon_device *oct, mapped_len = oct->mmio[baridx].len; if (!mapped_len) - return 1; + goto err_release_region; if (max_map_len && (mapped_len > max_map_len)) mapped_len = max_map_len; @@ -132,11 +127,15 @@ static inline int octeon_map_pci_barx(struct octeon_device *oct, if (!oct->mmio[baridx].hw_addr) { dev_err(&oct->pci_dev->dev, "error ioremap for bar %d\n", baridx); - return 1; + goto err_release_region; } oct->mmio[baridx].done = 1; return 0; + +err_release_region: + pci_release_region(oct->pci_dev, baridx * 2); + return 1; } static inline void * @@ -203,24 +202,6 @@ out: return errno; } -static inline void -sleep_atomic_cond(wait_queue_head_t *waitq, atomic_t *pcond) -{ - wait_queue_t we; - - init_waitqueue_entry(&we, current); - add_wait_queue(waitq, &we); - while (!atomic_read(pcond)) { - set_current_state(TASK_INTERRUPTIBLE); - if (signal_pending(current)) - goto out; - schedule(); - } -out: - set_current_state(TASK_RUNNING); - remove_wait_queue(waitq, &we); -} - /* Gives up the CPU for a timeout period. * Check that the condition is not true before we go to sleep for a * timeout period. diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_mem_ops.c b/drivers/net/ethernet/cavium/liquidio/octeon_mem_ops.c index 0dc081a99b30..13a18c9a7a51 100644 --- a/drivers/net/ethernet/cavium/liquidio/octeon_mem_ops.c +++ b/drivers/net/ethernet/cavium/liquidio/octeon_mem_ops.c @@ -4,7 +4,7 @@ * Contact: support@cavium.com * Please include "LiquidIO" in the subject. * - * Copyright (c) 2003-2015 Cavium, Inc. + * Copyright (c) 2003-2016 Cavium, Inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, Version 2, as @@ -15,9 +15,6 @@ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or * NONINFRINGEMENT. See the GNU General Public License for more * details. - * - * This file may also be available under a different license from Cavium. - * Contact Cavium, Inc. for more information **********************************************************************/ #include <linux/netdevice.h> #include "liquidio_common.h" @@ -39,7 +36,7 @@ octeon_toggle_bar1_swapmode(struct octeon_device *oct, u32 idx) oct->fn_list.bar1_idx_write(oct, idx, mask); } #else -#define octeon_toggle_bar1_swapmode(oct, idx) (oct = oct) +#define octeon_toggle_bar1_swapmode(oct, idx) #endif static void diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_mem_ops.h b/drivers/net/ethernet/cavium/liquidio/octeon_mem_ops.h index 11b183377b44..bae2fdd89503 100644 --- a/drivers/net/ethernet/cavium/liquidio/octeon_mem_ops.h +++ b/drivers/net/ethernet/cavium/liquidio/octeon_mem_ops.h @@ -4,7 +4,7 @@ * Contact: support@cavium.com * Please include "LiquidIO" in the subject. * - * Copyright (c) 2003-2015 Cavium, Inc. + * Copyright (c) 2003-2016 Cavium, Inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, Version 2, as @@ -15,9 +15,6 @@ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or * NONINFRINGEMENT. See the GNU General Public License for more * details. - * - * This file may also be available under a different license from Cavium. - * Contact Cavium, Inc. for more information **********************************************************************/ /*! \file octeon_mem_ops.h diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_network.h b/drivers/net/ethernet/cavium/liquidio/octeon_network.h index 54b966596323..e94edc841cad 100644 --- a/drivers/net/ethernet/cavium/liquidio/octeon_network.h +++ b/drivers/net/ethernet/cavium/liquidio/octeon_network.h @@ -4,7 +4,7 @@ * Contact: support@cavium.com * Please include "LiquidIO" in the subject. * - * Copyright (c) 2003-2015 Cavium, Inc. + * Copyright (c) 2003-2016 Cavium, Inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, Version 2, as @@ -15,9 +15,6 @@ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or * NONINFRINGEMENT. See the GNU General Public License for more * details. - * - * This file may also be available under a different license from Cavium. - * Contact Cavium, Inc. for more information **********************************************************************/ /*! \file octeon_network.h @@ -131,7 +128,7 @@ struct lio { #define LIO_SIZE (sizeof(struct lio)) #define GET_LIO(netdev) ((struct lio *)netdev_priv(netdev)) -#define CIU3_WDOG(c) (0x1010000020000ULL + (c << 3)) +#define CIU3_WDOG(c) (0x1010000020000ULL + ((c) << 3)) #define CIU3_WDOG_MASK 12ULL #define LIO_MONITOR_WDOG_EXPIRE 1 #define LIO_MONITOR_CORE_STUCK_MSGD 2 @@ -342,9 +339,9 @@ static inline void tx_buffer_free(void *buffer) } #define lio_dma_alloc(oct, size, dma_addr) \ - dma_alloc_coherent(&oct->pci_dev->dev, size, dma_addr, GFP_KERNEL) + dma_alloc_coherent(&(oct)->pci_dev->dev, size, dma_addr, GFP_KERNEL) #define lio_dma_free(oct, size, virt_addr, dma_addr) \ - dma_free_coherent(&oct->pci_dev->dev, size, virt_addr, dma_addr) + dma_free_coherent(&(oct)->pci_dev->dev, size, virt_addr, dma_addr) static inline void *get_rbd(struct sk_buff *skb) diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_nic.c b/drivers/net/ethernet/cavium/liquidio/octeon_nic.c index 40ac1fe88956..c3d6a8228362 100644 --- a/drivers/net/ethernet/cavium/liquidio/octeon_nic.c +++ b/drivers/net/ethernet/cavium/liquidio/octeon_nic.c @@ -4,7 +4,7 @@ * Contact: support@cavium.com * Please include "LiquidIO" in the subject. * - * Copyright (c) 2003-2015 Cavium, Inc. + * Copyright (c) 2003-2016 Cavium, Inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, Version 2, as @@ -15,9 +15,6 @@ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or * NONINFRINGEMENT. See the GNU General Public License for more * details. - * - * This file may also be available under a different license from Cavium. - * Contact Cavium, Inc. for more information **********************************************************************/ #include <linux/pci.h> #include <linux/netdevice.h> diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_nic.h b/drivers/net/ethernet/cavium/liquidio/octeon_nic.h index 4b8da67b995f..0c7a5c9b2932 100644 --- a/drivers/net/ethernet/cavium/liquidio/octeon_nic.h +++ b/drivers/net/ethernet/cavium/liquidio/octeon_nic.h @@ -4,7 +4,7 @@ * Contact: support@cavium.com * Please include "LiquidIO" in the subject. * - * Copyright (c) 2003-2015 Cavium, Inc. + * Copyright (c) 2003-2016 Cavium, Inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, Version 2, as @@ -15,9 +15,6 @@ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or * NONINFRINGEMENT. See the GNU General Public License for more * details. - * - * This file may also be available under a different license from Cavium. - * Contact Cavium, Inc. for more information **********************************************************************/ /*! \file octeon_nic.h @@ -67,7 +64,7 @@ struct octnic_ctrl_pkt { octnic_ctrl_pkt_cb_fn_t cb_fn; }; -#define MAX_UDD_SIZE(nctrl) (sizeof(nctrl->udd)) +#define MAX_UDD_SIZE(nctrl) (sizeof((nctrl)->udd)) /** Structure of data information passed by the NIC module to the OSI * layer when forwarding data to Octeon device software. diff --git a/drivers/net/ethernet/cavium/liquidio/request_manager.c b/drivers/net/ethernet/cavium/liquidio/request_manager.c index 90866bb50033..8531a004ad3e 100644 --- a/drivers/net/ethernet/cavium/liquidio/request_manager.c +++ b/drivers/net/ethernet/cavium/liquidio/request_manager.c @@ -4,7 +4,7 @@ * Contact: support@cavium.com * Please include "LiquidIO" in the subject. * - * Copyright (c) 2003-2015 Cavium, Inc. + * Copyright (c) 2003-2016 Cavium, Inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, Version 2, as @@ -15,9 +15,6 @@ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or * NONINFRINGEMENT. See the GNU General Public License for more * details. - * - * This file may also be available under a different license from Cavium. - * Contact Cavium, Inc. for more information **********************************************************************/ #include <linux/pci.h> #include <linux/netdevice.h> @@ -32,9 +29,6 @@ #include "cn66xx_device.h" #include "cn23xx_pf_device.h" -#define INCR_INSTRQUEUE_PKT_COUNT(octeon_dev_ptr, iq_no, field, count) \ - (octeon_dev_ptr->instr_queue[iq_no]->stats.field += count) - struct iq_post_status { int status; int index; @@ -71,9 +65,9 @@ int octeon_init_instr_queue(struct octeon_device *oct, int numa_node = cpu_to_node(iq_no % num_online_cpus()); if (OCTEON_CN6XXX(oct)) - conf = &(CFG_GET_IQ_CFG(CHIP_FIELD(oct, cn6xxx, conf))); + conf = &(CFG_GET_IQ_CFG(CHIP_CONF(oct, cn6xxx))); else if (OCTEON_CN23XX_PF(oct)) - conf = &(CFG_GET_IQ_CFG(CHIP_FIELD(oct, cn23xx_pf, conf))); + conf = &(CFG_GET_IQ_CFG(CHIP_CONF(oct, cn23xx_pf))); if (!conf) { dev_err(&oct->pci_dev->dev, "Unsupported Chip %x\n", oct->chip_id); @@ -145,7 +139,7 @@ int octeon_init_instr_queue(struct octeon_device *oct, spin_lock_init(&iq->iq_flush_running_lock); - oct->io_qmask.iq |= (1ULL << iq_no); + oct->io_qmask.iq |= BIT_ULL(iq_no); /* Set the 32B/64B mode for each input queue */ oct->io_qmask.iq64B |= ((conf->instr_type == 64) << iq_no); @@ -157,6 +151,8 @@ int octeon_init_instr_queue(struct octeon_device *oct, WQ_MEM_RECLAIM, 0); if (!oct->check_db_wq[iq_no].wq) { + vfree(iq->request_list); + iq->request_list = NULL; lio_dma_free(oct, q_size, iq->base_addr, iq->base_addr_dma); dev_err(&oct->pci_dev->dev, "check db wq create failed for iq %d\n", iq_no); @@ -183,10 +179,10 @@ int octeon_delete_instr_queue(struct octeon_device *oct, u32 iq_no) if (OCTEON_CN6XXX(oct)) desc_size = - CFG_GET_IQ_INSTR_TYPE(CHIP_FIELD(oct, cn6xxx, conf)); + CFG_GET_IQ_INSTR_TYPE(CHIP_CONF(oct, cn6xxx)); else if (OCTEON_CN23XX_PF(oct)) desc_size = - CFG_GET_IQ_INSTR_TYPE(CHIP_FIELD(oct, cn23xx_pf, conf)); + CFG_GET_IQ_INSTR_TYPE(CHIP_CONF(oct, cn23xx_pf)); vfree(iq->request_list); @@ -250,9 +246,8 @@ int lio_wait_for_instr_fetch(struct octeon_device *oct) do { instr_cnt = 0; - /*for (i = 0; i < oct->num_iqs; i++) {*/ for (i = 0; i < MAX_OCTEON_INSTR_QUEUES(oct); i++) { - if (!(oct->io_qmask.iq & (1ULL << i))) + if (!(oct->io_qmask.iq & BIT_ULL(i))) continue; pending = atomic_read(&oct-> @@ -319,7 +314,8 @@ __post_command2(struct octeon_instr_queue *iq, u8 *cmd) /* "index" is returned, host_write_index is modified. */ st.index = iq->host_write_index; - INCR_INDEX_BY1(iq->host_write_index, iq->max_count); + iq->host_write_index = incr_index(iq->host_write_index, 1, + iq->max_count); iq->fill_cnt++; /* Flush the command into memory. We need to be sure the data is in @@ -434,7 +430,7 @@ lio_process_iq_request_list(struct octeon_device *oct, skip_this: inst_count++; - INCR_INDEX_BY1(old, iq->max_count); + old = incr_index(old, 1, iq->max_count); if ((napi_budget) && (inst_count >= napi_budget)) break; @@ -577,8 +573,6 @@ octeon_send_command(struct octeon_device *oct, u32 iq_no, /* This is only done here to expedite packets being flushed * for cases where there are no IQ completion interrupts. */ - /*if (iq->do_auto_flush)*/ - /* octeon_flush_iq(oct, iq, 2, 0);*/ return st.status; } @@ -749,8 +743,10 @@ int octeon_setup_sc_buffer_pool(struct octeon_device *oct) lio_dma_alloc(oct, SOFT_COMMAND_BUFFER_SIZE, (dma_addr_t *)&dma_addr); - if (!sc) + if (!sc) { + octeon_free_sc_buffer_pool(oct); return 1; + } sc->dma_addr = dma_addr; sc->size = SOFT_COMMAND_BUFFER_SIZE; diff --git a/drivers/net/ethernet/cavium/liquidio/response_manager.c b/drivers/net/ethernet/cavium/liquidio/response_manager.c index be52178d8cb6..fdaf742a59cb 100644 --- a/drivers/net/ethernet/cavium/liquidio/response_manager.c +++ b/drivers/net/ethernet/cavium/liquidio/response_manager.c @@ -4,7 +4,7 @@ * Contact: support@cavium.com * Please include "LiquidIO" in the subject. * - * Copyright (c) 2003-2015 Cavium, Inc. + * Copyright (c) 2003-2016 Cavium, Inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, Version 2, as @@ -15,9 +15,6 @@ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or * NONINFRINGEMENT. See the GNU General Public License for more * details. - * - * This file may also be available under a different license from Cavium. - * Contact Cavium, Inc. for more information **********************************************************************/ #include <linux/pci.h> #include <linux/netdevice.h> @@ -81,11 +78,7 @@ int lio_process_ordered_list(struct octeon_device *octeon_dev, spin_lock_bh(&ordered_sc_list->lock); if (ordered_sc_list->head.next == &ordered_sc_list->head) { - /* ordered_sc_list is empty; there is - * nothing to process - */ - spin_unlock_bh - (&ordered_sc_list->lock); + spin_unlock_bh(&ordered_sc_list->lock); return 1; } diff --git a/drivers/net/ethernet/cavium/liquidio/response_manager.h b/drivers/net/ethernet/cavium/liquidio/response_manager.h index 7a48752dcb10..cbb2d84e8932 100644 --- a/drivers/net/ethernet/cavium/liquidio/response_manager.h +++ b/drivers/net/ethernet/cavium/liquidio/response_manager.h @@ -4,7 +4,7 @@ * Contact: support@cavium.com * Please include "LiquidIO" in the subject. * - * Copyright (c) 2003-2015 Cavium, Inc. + * Copyright (c) 2003-2016 Cavium, Inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, Version 2, as @@ -15,9 +15,6 @@ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or * NONINFRINGEMENT. See the GNU General Public License for more * details. - * - * This file may also be available under a different license from Cavium. - * Contact Cavium, Inc. for more information **********************************************************************/ /*! \file response_manager.h @@ -85,7 +82,6 @@ enum { /** A value of 0x00000000 indicates no error i.e. success */ #define DRIVER_ERROR_NONE 0x00000000 -/** (Major number: 0x0000; Minor Number: 0x0001) */ #define DRIVER_ERROR_REQ_PENDING 0x00000001 #define DRIVER_ERROR_REQ_TIMEOUT 0x00000003 #define DRIVER_ERROR_REQ_EINTR 0x00000004 |