net/ngbe: set MAC type and LAN ID with initialization

Add basic init and uninit function.
Map device IDs and subsystem IDs to single ID for easy operation.
Then initialize the shared code.

Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
This commit is contained in:
Jiawen Wu 2021-07-08 17:32:25 +08:00 committed by Andrew Rybchenko
parent ed5f3bd337
commit 68eb13a1ef
9 changed files with 582 additions and 5 deletions

View File

@ -1,7 +1,9 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2018-2021 Beijing WangXun Technology Co., Ltd.
sources = []
sources = [
'ngbe_hw.c',
]
error_cflags = []

View File

@ -0,0 +1,11 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2018-2021 Beijing WangXun Technology Co., Ltd.
*/
#ifndef _NGBE_H_
#define _NGBE_H_
#include "ngbe_type.h"
#include "ngbe_hw.h"
#endif /* _NGBE_H_ */

View File

@ -0,0 +1,37 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2018-2021 Beijing WangXun Technology Co., Ltd.
*/
#ifndef _NGBE_TYPE_DUMMY_H_
#define _NGBE_TYPE_DUMMY_H_
#ifdef TUP
#elif defined(__GNUC__)
#define TUP(x) x##_unused ngbe_unused
#elif defined(__LCLINT__)
#define TUP(x) x /*@unused@*/
#else
#define TUP(x) x
#endif /*TUP*/
#define TUP0 TUP(p0)
#define TUP1 TUP(p1)
#define TUP2 TUP(p2)
#define TUP3 TUP(p3)
#define TUP4 TUP(p4)
#define TUP5 TUP(p5)
#define TUP6 TUP(p6)
#define TUP7 TUP(p7)
#define TUP8 TUP(p8)
#define TUP9 TUP(p9)
/* struct ngbe_bus_operations */
static inline void ngbe_bus_set_lan_id_dummy(struct ngbe_hw *TUP0)
{
}
static inline void ngbe_init_ops_dummy(struct ngbe_hw *hw)
{
hw->bus.set_lan_id = ngbe_bus_set_lan_id_dummy;
}
#endif /* _NGBE_TYPE_DUMMY_H_ */

View File

@ -0,0 +1,182 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2018-2021 Beijing WangXun Technology Co., Ltd.
* Copyright(c) 2010-2017 Intel Corporation
*/
#include "ngbe_type.h"
#include "ngbe_hw.h"
/**
* ngbe_set_lan_id_multi_port - Set LAN id for PCIe multiple port devices
* @hw: pointer to the HW structure
*
* Determines the LAN function id by reading memory-mapped registers and swaps
* the port value if requested, and set MAC instance for devices.
**/
void ngbe_set_lan_id_multi_port(struct ngbe_hw *hw)
{
struct ngbe_bus_info *bus = &hw->bus;
u32 reg = 0;
DEBUGFUNC("ngbe_set_lan_id_multi_port");
reg = rd32(hw, NGBE_PORTSTAT);
bus->lan_id = NGBE_PORTSTAT_ID(reg);
bus->func = bus->lan_id;
}
/**
* ngbe_set_mac_type - Sets MAC type
* @hw: pointer to the HW structure
*
* This function sets the mac type of the adapter based on the
* vendor ID and device ID stored in the hw structure.
**/
s32 ngbe_set_mac_type(struct ngbe_hw *hw)
{
s32 err = 0;
DEBUGFUNC("ngbe_set_mac_type");
if (hw->vendor_id != PCI_VENDOR_ID_WANGXUN) {
DEBUGOUT("Unsupported vendor id: %x", hw->vendor_id);
return NGBE_ERR_DEVICE_NOT_SUPPORTED;
}
switch (hw->sub_device_id) {
case NGBE_SUB_DEV_ID_EM_RTL_SGMII:
case NGBE_SUB_DEV_ID_EM_MVL_RGMII:
hw->phy.media_type = ngbe_media_type_copper;
hw->mac.type = ngbe_mac_em;
break;
case NGBE_SUB_DEV_ID_EM_MVL_SFP:
case NGBE_SUB_DEV_ID_EM_YT8521S_SFP:
hw->phy.media_type = ngbe_media_type_fiber;
hw->mac.type = ngbe_mac_em;
break;
case NGBE_SUB_DEV_ID_EM_VF:
hw->phy.media_type = ngbe_media_type_virtual;
hw->mac.type = ngbe_mac_em_vf;
break;
default:
err = NGBE_ERR_DEVICE_NOT_SUPPORTED;
hw->phy.media_type = ngbe_media_type_unknown;
hw->mac.type = ngbe_mac_unknown;
DEBUGOUT("Unsupported device id: %x", hw->device_id);
break;
}
DEBUGOUT("found mac: %d media: %d, returns: %d\n",
hw->mac.type, hw->phy.media_type, err);
return err;
}
void ngbe_map_device_id(struct ngbe_hw *hw)
{
u16 oem = hw->sub_system_id & NGBE_OEM_MASK;
u16 internal = hw->sub_system_id & NGBE_INTERNAL_MASK;
hw->is_pf = true;
/* move subsystem_device_id to device_id */
switch (hw->device_id) {
case NGBE_DEV_ID_EM_WX1860AL_W_VF:
case NGBE_DEV_ID_EM_WX1860A2_VF:
case NGBE_DEV_ID_EM_WX1860A2S_VF:
case NGBE_DEV_ID_EM_WX1860A4_VF:
case NGBE_DEV_ID_EM_WX1860A4S_VF:
case NGBE_DEV_ID_EM_WX1860AL2_VF:
case NGBE_DEV_ID_EM_WX1860AL2S_VF:
case NGBE_DEV_ID_EM_WX1860AL4_VF:
case NGBE_DEV_ID_EM_WX1860AL4S_VF:
case NGBE_DEV_ID_EM_WX1860NCSI_VF:
case NGBE_DEV_ID_EM_WX1860A1_VF:
case NGBE_DEV_ID_EM_WX1860A1L_VF:
hw->device_id = NGBE_DEV_ID_EM_VF;
hw->sub_device_id = NGBE_SUB_DEV_ID_EM_VF;
hw->is_pf = false;
break;
case NGBE_DEV_ID_EM_WX1860AL_W:
case NGBE_DEV_ID_EM_WX1860A2:
case NGBE_DEV_ID_EM_WX1860A2S:
case NGBE_DEV_ID_EM_WX1860A4:
case NGBE_DEV_ID_EM_WX1860A4S:
case NGBE_DEV_ID_EM_WX1860AL2:
case NGBE_DEV_ID_EM_WX1860AL2S:
case NGBE_DEV_ID_EM_WX1860AL4:
case NGBE_DEV_ID_EM_WX1860AL4S:
case NGBE_DEV_ID_EM_WX1860NCSI:
case NGBE_DEV_ID_EM_WX1860A1:
case NGBE_DEV_ID_EM_WX1860A1L:
hw->device_id = NGBE_DEV_ID_EM;
if (oem == NGBE_LY_M88E1512_SFP ||
internal == NGBE_INTERNAL_SFP)
hw->sub_device_id = NGBE_SUB_DEV_ID_EM_MVL_SFP;
else if (hw->sub_system_id == NGBE_SUB_DEV_ID_EM_M88E1512_RJ45)
hw->sub_device_id = NGBE_SUB_DEV_ID_EM_MVL_RGMII;
else if (oem == NGBE_YT8521S_SFP ||
oem == NGBE_LY_YT8521S_SFP)
hw->sub_device_id = NGBE_SUB_DEV_ID_EM_YT8521S_SFP;
else
hw->sub_device_id = NGBE_SUB_DEV_ID_EM_RTL_SGMII;
break;
default:
break;
}
}
/**
* ngbe_init_ops_pf - Inits func ptrs and MAC type
* @hw: pointer to hardware structure
*
* Initialize the function pointers and assign the MAC type.
* Does not touch the hardware.
**/
s32 ngbe_init_ops_pf(struct ngbe_hw *hw)
{
struct ngbe_bus_info *bus = &hw->bus;
DEBUGFUNC("ngbe_init_ops_pf");
/* BUS */
bus->set_lan_id = ngbe_set_lan_id_multi_port;
return 0;
}
/**
* ngbe_init_shared_code - Initialize the shared code
* @hw: pointer to hardware structure
*
* This will assign function pointers and assign the MAC type and PHY code.
* Does not touch the hardware. This function must be called prior to any
* other function in the shared code. The ngbe_hw structure should be
* memset to 0 prior to calling this function. The following fields in
* hw structure should be filled in prior to calling this function:
* hw_addr, back, device_id, vendor_id, subsystem_device_id
**/
s32 ngbe_init_shared_code(struct ngbe_hw *hw)
{
s32 status = 0;
DEBUGFUNC("ngbe_init_shared_code");
/*
* Set the mac type
*/
ngbe_set_mac_type(hw);
ngbe_init_ops_dummy(hw);
switch (hw->mac.type) {
case ngbe_mac_em:
ngbe_init_ops_pf(hw);
break;
default:
status = NGBE_ERR_DEVICE_NOT_SUPPORTED;
break;
}
hw->bus.set_lan_id(hw);
return status;
}

View File

@ -0,0 +1,18 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2018-2021 Beijing WangXun Technology Co., Ltd.
* Copyright(c) 2010-2017 Intel Corporation
*/
#ifndef _NGBE_HW_H_
#define _NGBE_HW_H_
#include "ngbe_type.h"
void ngbe_set_lan_id_multi_port(struct ngbe_hw *hw);
s32 ngbe_init_shared_code(struct ngbe_hw *hw);
s32 ngbe_set_mac_type(struct ngbe_hw *hw);
s32 ngbe_init_ops_pf(struct ngbe_hw *hw);
void ngbe_map_device_id(struct ngbe_hw *hw);
#endif /* _NGBE_HW_H_ */

View File

@ -0,0 +1,183 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2018-2021 Beijing WangXun Technology Co., Ltd.
* Copyright(c) 2010-2017 Intel Corporation
*/
#ifndef _NGBE_OS_H_
#define _NGBE_OS_H_
#include <string.h>
#include <stdint.h>
#include <stdio.h>
#include <stdarg.h>
#include <rte_version.h>
#include <rte_common.h>
#include <rte_debug.h>
#include <rte_cycles.h>
#include <rte_log.h>
#include <rte_byteorder.h>
#include <rte_config.h>
#include <rte_io.h>
#include <rte_ether.h>
#include "../ngbe_logs.h"
#define RTE_LIBRTE_NGBE_TM DCPV(1, 0)
#define TMZ_PADDR(mz) ((mz)->iova)
#define TMZ_VADDR(mz) ((mz)->addr)
#define TDEV_NAME(eth_dev) ((eth_dev)->device->name)
#define ASSERT(x) do { \
if (!(x)) \
PMD_DRV_LOG(ERR, "NGBE: %d", x); \
} while (0)
#define ngbe_unused __rte_unused
#define usec_delay(x) rte_delay_us(x)
#define msec_delay(x) rte_delay_ms(x)
#define usleep(x) rte_delay_us(x)
#define msleep(x) rte_delay_ms(x)
#define FALSE 0
#define TRUE 1
#ifndef false
#define false 0
#endif
#ifndef true
#define true 1
#endif
#define min(a, b) RTE_MIN(a, b)
#define max(a, b) RTE_MAX(a, b)
/* Bunch of defines for shared code bogosity */
static inline void UNREFERENCED(const char *a __rte_unused, ...) {}
#define UNREFERENCED_PARAMETER(args...) UNREFERENCED("", ##args)
#define STATIC static
typedef uint8_t u8;
typedef int8_t s8;
typedef uint16_t u16;
typedef int16_t s16;
typedef uint32_t u32;
typedef int32_t s32;
typedef uint64_t u64;
typedef int64_t s64;
/* Little Endian defines */
#ifndef __le16
#define __le16 u16
#define __le32 u32
#define __le64 u64
#endif
#ifndef __be16
#define __be16 u16
#define __be32 u32
#define __be64 u64
#endif
/* Bit shift and mask */
#define BIT_MASK4 (0x0000000FU)
#define BIT_MASK8 (0x000000FFU)
#define BIT_MASK16 (0x0000FFFFU)
#define BIT_MASK32 (0xFFFFFFFFU)
#define BIT_MASK64 (0xFFFFFFFFFFFFFFFFUL)
#ifndef cpu_to_le32
#define cpu_to_le16(v) rte_cpu_to_le_16((u16)(v))
#define cpu_to_le32(v) rte_cpu_to_le_32((u32)(v))
#define cpu_to_le64(v) rte_cpu_to_le_64((u64)(v))
#define le_to_cpu16(v) rte_le_to_cpu_16((u16)(v))
#define le_to_cpu32(v) rte_le_to_cpu_32((u32)(v))
#define le_to_cpu64(v) rte_le_to_cpu_64((u64)(v))
#define cpu_to_be16(v) rte_cpu_to_be_16((u16)(v))
#define cpu_to_be32(v) rte_cpu_to_be_32((u32)(v))
#define cpu_to_be64(v) rte_cpu_to_be_64((u64)(v))
#define be_to_cpu16(v) rte_be_to_cpu_16((u16)(v))
#define be_to_cpu32(v) rte_be_to_cpu_32((u32)(v))
#define be_to_cpu64(v) rte_be_to_cpu_64((u64)(v))
#define le_to_be16(v) rte_bswap16((u16)(v))
#define le_to_be32(v) rte_bswap32((u32)(v))
#define le_to_be64(v) rte_bswap64((u64)(v))
#define be_to_le16(v) rte_bswap16((u16)(v))
#define be_to_le32(v) rte_bswap32((u32)(v))
#define be_to_le64(v) rte_bswap64((u64)(v))
#define npu_to_le16(v) (v)
#define npu_to_le32(v) (v)
#define npu_to_le64(v) (v)
#define le_to_npu16(v) (v)
#define le_to_npu32(v) (v)
#define le_to_npu64(v) (v)
#define npu_to_be16(v) le_to_be16((u16)(v))
#define npu_to_be32(v) le_to_be32((u32)(v))
#define npu_to_be64(v) le_to_be64((u64)(v))
#define be_to_npu16(v) be_to_le16((u16)(v))
#define be_to_npu32(v) be_to_le32((u32)(v))
#define be_to_npu64(v) be_to_le64((u64)(v))
#endif /* !cpu_to_le32 */
static inline u16 REVERT_BIT_MASK16(u16 mask)
{
mask = ((mask & 0x5555) << 1) | ((mask & 0xAAAA) >> 1);
mask = ((mask & 0x3333) << 2) | ((mask & 0xCCCC) >> 2);
mask = ((mask & 0x0F0F) << 4) | ((mask & 0xF0F0) >> 4);
return ((mask & 0x00FF) << 8) | ((mask & 0xFF00) >> 8);
}
static inline u32 REVERT_BIT_MASK32(u32 mask)
{
mask = ((mask & 0x55555555) << 1) | ((mask & 0xAAAAAAAA) >> 1);
mask = ((mask & 0x33333333) << 2) | ((mask & 0xCCCCCCCC) >> 2);
mask = ((mask & 0x0F0F0F0F) << 4) | ((mask & 0xF0F0F0F0) >> 4);
mask = ((mask & 0x00FF00FF) << 8) | ((mask & 0xFF00FF00) >> 8);
return ((mask & 0x0000FFFF) << 16) | ((mask & 0xFFFF0000) >> 16);
}
static inline u64 REVERT_BIT_MASK64(u64 mask)
{
mask = ((mask & 0x5555555555555555) << 1) |
((mask & 0xAAAAAAAAAAAAAAAA) >> 1);
mask = ((mask & 0x3333333333333333) << 2) |
((mask & 0xCCCCCCCCCCCCCCCC) >> 2);
mask = ((mask & 0x0F0F0F0F0F0F0F0F) << 4) |
((mask & 0xF0F0F0F0F0F0F0F0) >> 4);
mask = ((mask & 0x00FF00FF00FF00FF) << 8) |
((mask & 0xFF00FF00FF00FF00) >> 8);
mask = ((mask & 0x0000FFFF0000FFFF) << 16) |
((mask & 0xFFFF0000FFFF0000) >> 16);
return ((mask & 0x00000000FFFFFFFF) << 32) |
((mask & 0xFFFFFFFF00000000) >> 32);
}
#define IOMEM
#define prefetch(x) rte_prefetch0(x)
#define ARRAY_SIZE(x) ((int32_t)RTE_DIM(x))
#ifndef MAX_UDELAY_MS
#define MAX_UDELAY_MS 5
#endif
#define ETH_ADDR_LEN 6
#define ETH_FCS_LEN 4
/* Check whether address is multicast. This is little-endian specific check.*/
#define NGBE_IS_MULTICAST(address) \
rte_is_multicast_ether_addr(address)
/* Check whether an address is broadcast. */
#define NGBE_IS_BROADCAST(address) \
rte_is_broadcast_ether_addr(address)
#define ETH_P_8021Q 0x8100
#define ETH_P_8021AD 0x88A8
#endif /* _NGBE_OS_H_ */

View File

@ -0,0 +1,78 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2018-2021 Beijing WangXun Technology Co., Ltd.
* Copyright(c) 2010-2017 Intel Corporation
*/
#ifndef _NGBE_TYPE_H_
#define _NGBE_TYPE_H_
#include "ngbe_status.h"
#include "ngbe_osdep.h"
#include "ngbe_devids.h"
enum ngbe_mac_type {
ngbe_mac_unknown = 0,
ngbe_mac_em,
ngbe_mac_em_vf,
ngbe_num_macs
};
enum ngbe_phy_type {
ngbe_phy_unknown = 0,
ngbe_phy_none,
ngbe_phy_rtl,
ngbe_phy_mvl,
ngbe_phy_mvl_sfi,
ngbe_phy_yt8521s,
ngbe_phy_yt8521s_sfi,
ngbe_phy_zte,
ngbe_phy_cu_mtd,
};
enum ngbe_media_type {
ngbe_media_type_unknown = 0,
ngbe_media_type_fiber,
ngbe_media_type_fiber_qsfp,
ngbe_media_type_copper,
ngbe_media_type_backplane,
ngbe_media_type_cx4,
ngbe_media_type_virtual
};
struct ngbe_hw;
/* Bus parameters */
struct ngbe_bus_info {
void (*set_lan_id)(struct ngbe_hw *hw);
u16 func;
u8 lan_id;
};
struct ngbe_mac_info {
enum ngbe_mac_type type;
};
struct ngbe_phy_info {
enum ngbe_media_type media_type;
enum ngbe_phy_type type;
};
struct ngbe_hw {
void IOMEM *hw_addr;
void *back;
struct ngbe_mac_info mac;
struct ngbe_phy_info phy;
struct ngbe_bus_info bus;
u16 device_id;
u16 vendor_id;
u16 sub_device_id;
u16 sub_system_id;
bool is_pf;
};
#include "ngbe_regs.h"
#include "ngbe_dummy.h"
#endif /* _NGBE_TYPE_H_ */

View File

@ -8,7 +8,10 @@
#include <ethdev_pci.h>
#include "ngbe_logs.h"
#include "ngbe_devids.h"
#include "ngbe.h"
#include "ngbe_ethdev.h"
static int ngbe_dev_close(struct rte_eth_dev *dev);
/*
* The set of PCI devices this driver supports
@ -33,6 +36,8 @@ static int
eth_ngbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused)
{
struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
struct ngbe_hw *hw = ngbe_dev_hw(eth_dev);
int err;
PMD_INIT_FUNC_TRACE();
@ -41,7 +46,21 @@ eth_ngbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused)
rte_eth_copy_pci_info(eth_dev, pci_dev);
return -EINVAL;
/* Vendor and Device ID need to be set before init of shared code */
hw->device_id = pci_dev->id.device_id;
hw->vendor_id = pci_dev->id.vendor_id;
hw->sub_system_id = pci_dev->id.subsystem_device_id;
ngbe_map_device_id(hw);
hw->hw_addr = (void *)pci_dev->mem_resource[0].addr;
/* Initialize the shared code (base driver) */
err = ngbe_init_shared_code(hw);
if (err != 0) {
PMD_INIT_LOG(ERR, "Shared code init failed: %d", err);
return -EIO;
}
return 0;
}
static int
@ -52,7 +71,7 @@ eth_ngbe_dev_uninit(struct rte_eth_dev *eth_dev)
if (rte_eal_process_type() != RTE_PROC_PRIMARY)
return 0;
RTE_SET_USED(eth_dev);
ngbe_dev_close(eth_dev);
return -EINVAL;
}
@ -62,7 +81,8 @@ eth_ngbe_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
struct rte_pci_device *pci_dev)
{
return rte_eth_dev_create(&pci_dev->device, pci_dev->device.name,
0, eth_dev_pci_specific_init, pci_dev,
sizeof(struct ngbe_adapter),
eth_dev_pci_specific_init, pci_dev,
eth_ngbe_dev_init, NULL);
}
@ -84,6 +104,19 @@ static struct rte_pci_driver rte_ngbe_pmd = {
.remove = eth_ngbe_pci_remove,
};
/*
* Reset and stop device.
*/
static int
ngbe_dev_close(struct rte_eth_dev *dev)
{
PMD_INIT_FUNC_TRACE();
RTE_SET_USED(dev);
return -EINVAL;
}
RTE_PMD_REGISTER_PCI(net_ngbe, rte_ngbe_pmd);
RTE_PMD_REGISTER_PCI_TABLE(net_ngbe, pci_id_ngbe_map);
RTE_PMD_REGISTER_KMOD_DEP(net_ngbe, "* igb_uio | uio_pci_generic | vfio-pci");

View File

@ -0,0 +1,33 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2018-2021 Beijing WangXun Technology Co., Ltd.
* Copyright(c) 2010-2017 Intel Corporation
*/
#ifndef _NGBE_ETHDEV_H_
#define _NGBE_ETHDEV_H_
/*
* Structure to store private data for each driver instance (for each port).
*/
struct ngbe_adapter {
struct ngbe_hw hw;
};
static inline struct ngbe_adapter *
ngbe_dev_adapter(struct rte_eth_dev *dev)
{
struct ngbe_adapter *ad = dev->data->dev_private;
return ad;
}
static inline struct ngbe_hw *
ngbe_dev_hw(struct rte_eth_dev *dev)
{
struct ngbe_adapter *ad = ngbe_dev_adapter(dev);
struct ngbe_hw *hw = &ad->hw;
return hw;
}
#endif /* _NGBE_ETHDEV_H_ */