From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Qiu, Michael" Subject: Re: [PATCH 05/18] fm10k: Add code to register fm10k pmd PF driver Date: Mon, 2 Feb 2015 09:10:19 +0000 Message-ID: <533710CFB86FA344BFBF2D6802E60286CD36A6@SHSMSX101.ccr.corp.intel.com> References: <1422594454-11045-1-git-send-email-jing.d.chen@intel.com> <1422594454-11045-6-git-send-email-jing.d.chen@intel.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable To: "Chen, Jing D" , "dev-VfR2kkLFssw@public.gmane.org" Return-path: Content-Language: en-US List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces-VfR2kkLFssw@public.gmane.org Sender: "dev" On 1/30/2015 1:08 PM, Chen, Jing D wrote:=0A= > From: Jeff Shaw =0A= >=0A= > 1. Add function to scan and initialize fm10k PF device.=0A= > 2. Add implementation to register fm10k pmd PF driver.=0A= > 3. Add 3 functions fm10k_dev_configure, fm10k_stats_get and=0A= > fm10k_stats_get.=0A= >=0A= > Signed-off-by: Jeff Shaw =0A= > Signed-off-by: Chen Jing D(Mark) =0A= > ---=0A= > lib/librte_pmd_fm10k/fm10k_ethdev.c | 339 +++++++++++++++++++++++++++++= ++++++=0A= > 1 files changed, 339 insertions(+), 0 deletions(-)=0A= >=0A= > diff --git a/lib/librte_pmd_fm10k/fm10k_ethdev.c b/lib/librte_pmd_fm10k/f= m10k_ethdev.c=0A= > index e69de29..400d841 100644=0A= > --- a/lib/librte_pmd_fm10k/fm10k_ethdev.c=0A= > +++ b/lib/librte_pmd_fm10k/fm10k_ethdev.c=0A= > @@ -0,0 +1,339 @@=0A= > +/*-=0A= > + * BSD LICENSE=0A= > + *=0A= > + * Copyright(c) 2013-2014 Intel Corporation. All rights reserved.=0A= > + * All rights reserved.=0A= > + *=0A= > + * Redistribution and use in source and binary forms, with or without= =0A= > + * modification, are permitted provided that the following conditions= =0A= > + * are met:=0A= > + *=0A= > + * * Redistributions of source code must retain the above copyright= =0A= > + * notice, this list of conditions and the following disclaimer.= =0A= > + * * Redistributions in binary form must reproduce the above copyrig= ht=0A= > + * notice, this list of conditions and the following disclaimer in= =0A= > + * the documentation and/or other materials provided with the=0A= > + * distribution.=0A= > + * * Neither the name of Intel Corporation nor the names of its=0A= > + * contributors may be used to endorse or promote products derived= =0A= > + * from this software without specific prior written permission.= =0A= > + *=0A= > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS= =0A= > + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT= =0A= > + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS F= OR=0A= > + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGH= T=0A= > + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTA= L,=0A= > + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT=0A= > + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF US= E,=0A= > + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON A= NY=0A= > + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT= =0A= > + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE U= SE=0A= > + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE= .=0A= > + */=0A= > +=0A= > +#include =0A= > +#include =0A= > +#include =0A= > +#include =0A= > +#include =0A= > +#include =0A= > +=0A= > +#include "fm10k.h"=0A= > +#include "SHARED/fm10k_api.h"=0A= > +=0A= > +/* Default delay to acquire mailbox lock */=0A= > +#define FM10K_MBXLOCK_DELAY_US 20=0A= > +=0A= > +static void=0A= > +fm10k_mbx_initlock(struct fm10k_hw *hw)=0A= > +{=0A= > + rte_spinlock_init(FM10K_DEV_PRIVATE_TO_MBXLOCK(hw->back));=0A= > +}=0A= > +=0A= > +static void=0A= > +fm10k_mbx_lock(struct fm10k_hw *hw)=0A= > +{=0A= > + while (!rte_spinlock_trylock(FM10K_DEV_PRIVATE_TO_MBXLOCK(hw->back)))= =0A= > + rte_delay_us(FM10K_MBXLOCK_DELAY_US);=0A= > +}=0A= > +=0A= > +static void=0A= > +fm10k_mbx_unlock(struct fm10k_hw *hw)=0A= > +{=0A= > + rte_spinlock_unlock(FM10K_DEV_PRIVATE_TO_MBXLOCK(hw->back));=0A= > +}=0A= > +=0A= > +static int=0A= > +fm10k_dev_configure(struct rte_eth_dev *dev)=0A= > +{=0A= > + PMD_FUNC_TRACE();=0A= > +=0A= > + if (dev->data->dev_conf.rxmode.hw_strip_crc =3D=3D 0)=0A= > + PMD_LOG(WARNING, "fm10k always strip CRC");=0A= > +=0A= > + return 0;=0A= > +}=0A= > +=0A= > +static void=0A= > +fm10k_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)=0A= > +{=0A= > + uint64_t ipackets, opackets, ibytes, obytes;=0A= > + struct fm10k_hw *hw =3D=0A= > + FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);=0A= > + struct fm10k_hw_stats *hw_stats =3D=0A= > + FM10K_DEV_PRIVATE_TO_STATS(dev->data->dev_private);=0A= > + int i;=0A= > + PMD_FUNC_TRACE();=0A= > +=0A= > + fm10k_update_hw_stats(hw, hw_stats);=0A= > +=0A= > + ipackets =3D opackets =3D ibytes =3D obytes =3D 0;=0A= > + for (i =3D 0; (i < RTE_ETHDEV_QUEUE_STAT_CNTRS) &&=0A= > + (i < FM10K_MAX_QUEUES_PF); ++i) {=0A= > + stats->q_ipackets[i] =3D hw_stats->q[i].rx_packets.count;=0A= > + stats->q_opackets[i] =3D hw_stats->q[i].tx_packets.count;=0A= > + stats->q_ibytes[i] =3D hw_stats->q[i].rx_bytes.count;=0A= > + stats->q_obytes[i] =3D hw_stats->q[i].tx_bytes.count;=0A= > + ipackets +=3D stats->q_ipackets[i];=0A= > + opackets +=3D stats->q_opackets[i];=0A= > + ibytes +=3D stats->q_ibytes[i];=0A= > + obytes +=3D stats->q_obytes[i];=0A= > + }=0A= > + stats->ipackets =3D ipackets;=0A= > + stats->opackets =3D opackets;=0A= > + stats->ibytes =3D ibytes;=0A= > + stats->obytes =3D obytes;=0A= > +}=0A= > +=0A= > +static void=0A= > +fm10k_stats_reset(struct rte_eth_dev *dev)=0A= > +{=0A= > + struct fm10k_hw *hw =3D FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private)= ;=0A= > + struct fm10k_hw_stats *hw_stats =3D=0A= > + FM10K_DEV_PRIVATE_TO_STATS(dev->data->dev_private);=0A= > + PMD_FUNC_TRACE();=0A= > +=0A= > + memset(hw_stats, 0, sizeof(*hw_stats));=0A= > + fm10k_rebind_hw_stats(hw, hw_stats);=0A= > +}=0A= > +=0A= > +/* Mailbox message handler in VF */=0A= > +static const struct fm10k_msg_data fm10k_msgdata_vf[] =3D {=0A= > + FM10K_TLV_MSG_TEST_HANDLER(fm10k_tlv_msg_test),=0A= > + FM10K_VF_MSG_MAC_VLAN_HANDLER(fm10k_msg_mac_vlan_vf),=0A= > + FM10K_VF_MSG_LPORT_STATE_HANDLER(fm10k_msg_lport_state_vf),=0A= > + FM10K_TLV_MSG_ERROR_HANDLER(fm10k_tlv_msg_error),=0A= > +};=0A= > +=0A= > +/* Mailbox message handler in PF */=0A= > +static const struct fm10k_msg_data fm10k_msgdata_pf[] =3D {=0A= > + FM10K_PF_MSG_ERR_HANDLER(XCAST_MODES, fm10k_msg_err_pf),=0A= > + FM10K_PF_MSG_ERR_HANDLER(UPDATE_MAC_FWD_RULE, fm10k_msg_err_pf),=0A= > + FM10K_PF_MSG_LPORT_MAP_HANDLER(fm10k_msg_lport_map_pf),=0A= > + FM10K_PF_MSG_ERR_HANDLER(LPORT_CREATE, fm10k_msg_err_pf),=0A= > + FM10K_PF_MSG_ERR_HANDLER(LPORT_DELETE, fm10k_msg_err_pf),=0A= > + FM10K_PF_MSG_UPDATE_PVID_HANDLER(fm10k_msg_update_pvid_pf),=0A= > + FM10K_TLV_MSG_ERROR_HANDLER(fm10k_tlv_msg_error),=0A= > +};=0A= > +=0A= > +static int=0A= > +fm10k_setup_mbx_service(struct fm10k_hw *hw)=0A= > +{=0A= > + int err;=0A= > +=0A= > + /* Initialize mailbox lock */=0A= > + fm10k_mbx_initlock(hw);=0A= > +=0A= > + /* Replace default message handler with new ones */=0A= > + if (hw->mac.type =3D=3D fm10k_mac_pf)=0A= > + err =3D hw->mbx.ops.register_handlers(&hw->mbx, fm10k_msgdata_pf);=0A= > + else=0A= > + err =3D hw->mbx.ops.register_handlers(&hw->mbx, fm10k_msgdata_vf);=0A= > +=0A= > + if (err) {=0A= > + PMD_LOG(ERR, "Failed to register mailbox handler.err:%d", err);=0A= > + return err;=0A= > + }=0A= > + /* Connect to SM for PF device or PF for VF device */=0A= > + return hw->mbx.ops.connect(hw, &hw->mbx);=0A= > +}=0A= > +=0A= > +static struct eth_dev_ops fm10k_eth_dev_ops =3D {=0A= > + .dev_configure =3D fm10k_dev_configure,=0A= > + .stats_get =3D fm10k_stats_get,=0A= > + .stats_reset =3D fm10k_stats_reset,=0A= > +};=0A= > +=0A= > +static int=0A= > +eth_fm10k_dev_init(__rte_unused struct eth_driver *eth_drv,=0A= > + struct rte_eth_dev *dev)=0A= > +{=0A= > + struct fm10k_hw *hw =3D FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private)= ;=0A= > + int diag;=0A= > + PMD_FUNC_TRACE();=0A= > +=0A= > + dev->dev_ops =3D &fm10k_eth_dev_ops;=0A= > +=0A= > + /* only initialize in the primary process */=0A= > + if (rte_eal_process_type() !=3D RTE_PROC_PRIMARY)=0A= > + return 0;=0A= > +=0A= > + /* Vendor and Device ID need to be set before init of shared code */=0A= > + memset(hw, 0, sizeof(*hw));=0A= > + hw->device_id =3D dev->pci_dev->id.device_id;=0A= > + hw->vendor_id =3D dev->pci_dev->id.vendor_id;=0A= > + hw->subsystem_device_id =3D dev->pci_dev->id.subsystem_device_id;=0A= > + hw->subsystem_vendor_id =3D dev->pci_dev->id.subsystem_vendor_id;=0A= > + hw->revision_id =3D 0;=0A= > + hw->hw_addr =3D (void *)dev->pci_dev->mem_resource[0].addr;=0A= > + if (hw->hw_addr =3D=3D NULL) {=0A= > + PMD_LOG(ERR, "Bad mem resource."=0A= > + " Try to blacklist unused devices.\n");=0A= =0A= Here no need "\n", after that,=0A= =0A= Acked-by: Michael Qiu =0A= =0A= Thanks,=0A= Michael=0A= > + return -EIO;=0A= > + }=0A= > +=0A= > + /* Store fm10k_adapter pointer */=0A= > + hw->back =3D dev->data->dev_private;=0A= > +=0A= > + /* Initialize the shared code */=0A= > + diag =3D fm10k_init_shared_code(hw);=0A= > + if (diag !=3D FM10K_SUCCESS) {=0A= > + PMD_LOG(ERR, "Shared code init failed: %d", diag);=0A= > + return -EIO;=0A= > + }=0A= > +=0A= > + /*=0A= > + * Inialize bus info. Normally we would call fm10k_get_bus_info(), but= =0A= > + * there is no way to get link status without reading BAR4. Until this= =0A= > + * works, assume we have maximum bandwidth.=0A= > + * @todo - fix bus info=0A= > + */=0A= > + hw->bus_caps.speed =3D fm10k_bus_speed_8000;=0A= > + hw->bus_caps.width =3D fm10k_bus_width_pcie_x8;=0A= > + hw->bus_caps.payload =3D fm10k_bus_payload_512;=0A= > + hw->bus.speed =3D fm10k_bus_speed_8000;=0A= > + hw->bus.width =3D fm10k_bus_width_pcie_x8;=0A= > + hw->bus.payload =3D fm10k_bus_payload_256;=0A= > +=0A= > + /* Initialize the hw */=0A= > + diag =3D fm10k_init_hw(hw);=0A= > + if (diag !=3D FM10K_SUCCESS) {=0A= > + PMD_LOG(ERR, "Hardware init failed: %d", diag);=0A= > + return -EIO;=0A= > + }=0A= > +=0A= > + /* Initialize MAC address(es) */=0A= > + dev->data->mac_addrs =3D rte_zmalloc("fm10k", ETHER_ADDR_LEN, 0);=0A= > + if (dev->data->mac_addrs =3D=3D NULL) {=0A= > + PMD_LOG(ERR, "Cannot allocate memory for MAC addresses");=0A= > + return -ENOMEM;=0A= > + }=0A= > +=0A= > + diag =3D fm10k_read_mac_addr(hw);=0A= > + if (diag !=3D FM10K_SUCCESS) {=0A= > + /*=0A= > + * TODO: remove special handling on VF. Need shared code to=0A= > + * fix first.=0A= > + */=0A= > + if (hw->mac.type =3D=3D fm10k_mac_pf) {=0A= > + PMD_LOG(ERR, "Read MAC addr failed: %d", diag);=0A= > + return -EIO;=0A= > + } else {=0A= > + /* Generate a random addr */=0A= > + eth_random_addr(hw->mac.addr);=0A= > + memcpy(hw->mac.perm_addr, hw->mac.addr, ETH_ALEN);=0A= > + }=0A= > + }=0A= > +=0A= > + ether_addr_copy((const struct ether_addr *)hw->mac.addr,=0A= > + &dev->data->mac_addrs[0]);=0A= > +=0A= > + /* Reset the hw statistics */=0A= > + fm10k_stats_reset(dev);=0A= > +=0A= > + /* Reset the hw */=0A= > + diag =3D fm10k_reset_hw(hw);=0A= > + if (diag !=3D FM10K_SUCCESS) {=0A= > + PMD_LOG(ERR, "Hardware reset failed: %d", diag);=0A= > + return -EIO;=0A= > + }=0A= > +=0A= > + /* Setup mailbox service */=0A= > + diag =3D fm10k_setup_mbx_service(hw);=0A= > + if (diag !=3D FM10K_SUCCESS) {=0A= > + PMD_LOG(ERR, "Failed to setup mailbox: %d", diag);=0A= > + return -EIO;=0A= > + }=0A= > +=0A= > + /*=0A= > + * Below function will trigger operations on mailbox, acquire lock to= =0A= > + * avoid race condition from interrupt handler. Operations on mailbox= =0A= > + * FIFO will trigger interrupt to PF/SM, in which interrupt handler=0A= > + * will handle and generate an interrupt to our side. Then, FIFO in=0A= > + * mailbox will be touched.=0A= > + */=0A= > + fm10k_mbx_lock(hw);=0A= > + /* Enable port first */=0A= > + hw->mac.ops.update_lport_state(hw, 0, 0, 1);=0A= > +=0A= > + /* Update default vlan */=0A= > + hw->mac.ops.update_vlan(hw, hw->mac.default_vid, 0, true);=0A= > +=0A= > + /*=0A= > + * Add default mac/vlan filter. glort is assigned by SM for PF, while i= s=0A= > + * unused for VF. PF will assign correct glort for VF.=0A= > + */=0A= > + hw->mac.ops.update_uc_addr(hw, hw->mac.dglort_map, hw->mac.addr,=0A= > + hw->mac.default_vid, 1, 0);=0A= > +=0A= > + /* Set unicast mode by default. App can change to other mode in other= =0A= > + * API func.=0A= > + */=0A= > + hw->mac.ops.update_xcast_mode(hw, hw->mac.dglort_map,=0A= > + FM10K_XCAST_MODE_MULTI);=0A= > +=0A= > + fm10k_mbx_unlock(hw);=0A= > +=0A= > + return 0;=0A= > +}=0A= > +=0A= > +/*=0A= > + * The set of PCI devices this driver supports. This driver will enable = both PF=0A= > + * and SRIOV-VF devices.=0A= > + */=0A= > +static struct rte_pci_id pci_id_fm10k_map[] =3D {=0A= > +#define RTE_PCI_DEV_ID_DECL_FM10K(vend, dev) { RTE_PCI_DEVICE(vend, dev)= },=0A= > +#include "rte_pci_dev_ids.h"=0A= > + { .vendor_id =3D 0, /* sentinel */ },=0A= > +};=0A= > +=0A= > +static struct eth_driver rte_pmd_fm10k =3D {=0A= > + {=0A= > + .name =3D "rte_pmd_fm10k",=0A= > + .id_table =3D pci_id_fm10k_map,=0A= > + .drv_flags =3D RTE_PCI_DRV_NEED_MAPPING,=0A= > + },=0A= > + .eth_dev_init =3D eth_fm10k_dev_init,=0A= > + .dev_private_size =3D sizeof(struct fm10k_adapter),=0A= > +};=0A= > +=0A= > +/*=0A= > + * Driver initialization routine.=0A= > + * Invoked once at EAL init time.=0A= > + * Register itself as the [Poll Mode] Driver of PCI FM10K devices.=0A= > + */=0A= > +static int=0A= > +rte_pmd_fm10k_init(__rte_unused const char *name,=0A= > + __rte_unused const char *params)=0A= > +{=0A= > + PMD_FUNC_TRACE();=0A= > + rte_eth_driver_register(&rte_pmd_fm10k);=0A= > + return 0;=0A= > +}=0A= > +=0A= > +static struct rte_driver rte_fm10k_driver =3D {=0A= > + .type =3D PMD_PDEV,=0A= > + .init =3D rte_pmd_fm10k_init,=0A= > +};=0A= > +=0A= > +PMD_REGISTER_DRIVER(rte_fm10k_driver);=0A= =0A=