/* SPDX-License-Identifier: GPL-2.0 */ /* Marvell Octeon EP (EndPoint) Ethernet Driver * * Copyright (C) 2020 Marvell. * */ #ifndef _OCTEP_MAIN_H_ #define _OCTEP_MAIN_H_ #include "octep_tx.h" #include "octep_rx.h" #include "octep_ctrl_mbox.h" #define OCTEP_DRV_NAME "octeon_ep" #define OCTEP_DRV_STRING "Marvell Octeon EndPoint NIC Driver" #define OCTEP_PCIID_CN93_PF 0xB200177d #define OCTEP_PCIID_CN93_VF 0xB203177d #define OCTEP_PCI_DEVICE_ID_CN93_PF 0xB200 #define OCTEP_PCI_DEVICE_ID_CN93_VF 0xB203 #define OCTEP_PCI_DEVICE_ID_CNF95N_PF 0xB400 //95N PF #define OCTEP_MAX_QUEUES 63 #define OCTEP_MAX_IQ OCTEP_MAX_QUEUES #define OCTEP_MAX_OQ OCTEP_MAX_QUEUES #define OCTEP_MAX_VF 64 #define OCTEP_MAX_MSIX_VECTORS OCTEP_MAX_OQ /* Flags to disable and enable Interrupts */ #define OCTEP_INPUT_INTR (1) #define OCTEP_OUTPUT_INTR (2) #define OCTEP_MBOX_INTR (4) #define OCTEP_ALL_INTR 0xff #define OCTEP_IQ_INTR_RESEND_BIT 59 #define OCTEP_OQ_INTR_RESEND_BIT 59 #define OCTEP_MMIO_REGIONS 3 /* PCI address space mapping information. * Each of the 3 address spaces given by BAR0, BAR2 and BAR4 of * Octeon gets mapped to different physical address spaces in * the kernel. */ struct octep_mmio { /* The physical address to which the PCI address space is mapped. */ u8 __iomem *hw_addr; /* Flag indicating the mapping was successful. */ int mapped; }; struct octep_pci_win_regs { u8 __iomem *pci_win_wr_addr; u8 __iomem *pci_win_rd_addr; u8 __iomem *pci_win_wr_data; u8 __iomem *pci_win_rd_data; }; struct octep_hw_ops { void (*setup_iq_regs)(struct octep_device *oct, int q); void (*setup_oq_regs)(struct octep_device *oct, int q); void (*setup_mbox_regs)(struct octep_device *oct, int mbox); irqreturn_t (*non_ioq_intr_handler)(void *ioq_vector); irqreturn_t (*ioq_intr_handler)(void *ioq_vector); int (*soft_reset)(struct octep_device *oct); void (*reinit_regs)(struct octep_device *oct); u32 (*update_iq_read_idx)(struct octep_iq *iq); void (*enable_interrupts)(struct octep_device *oct); void (*disable_interrupts)(struct octep_device *oct); void (*enable_io_queues)(struct octep_device *oct); void (*disable_io_queues)(struct octep_device *oct); void (*enable_iq)(struct octep_device *oct, int q); void (*disable_iq)(struct octep_device *oct, int q); void (*enable_oq)(struct octep_device *oct, int q); void (*disable_oq)(struct octep_device *oct, int q); void (*reset_io_queues)(struct octep_device *oct); void (*dump_registers)(struct octep_device *oct); }; /* Octeon mailbox data */ struct octep_mbox_data { u32 cmd; u32 total_len; u32 recv_len; u32 rsvd; u64 *data; }; /* Octeon device mailbox */ struct octep_mbox { /* A spinlock to protect access to this q_mbox. */ spinlock_t lock; u32 q_no; u32 state; /* SLI_MAC_PF_MBOX_INT for PF, SLI_PKT_MBOX_INT for VF. */ u8 __iomem *mbox_int_reg; /* SLI_PKT_PF_VF_MBOX_SIG(0) for PF, * SLI_PKT_PF_VF_MBOX_SIG(1) for VF. */ u8 __iomem *mbox_write_reg; /* SLI_PKT_PF_VF_MBOX_SIG(1) for PF, * SLI_PKT_PF_VF_MBOX_SIG(0) for VF. */ u8 __iomem *mbox_read_reg; struct octep_mbox_data mbox_data; }; /* Tx/Rx queue vector per interrupt. */ struct octep_ioq_vector { char name[OCTEP_MSIX_NAME_SIZE]; struct napi_struct napi; struct octep_device *octep_dev; struct octep_iq *iq; struct octep_oq *oq; cpumask_t affinity_mask; }; /* Octeon hardware/firmware offload capability flags. */ #define OCTEP_CAP_TX_CHECKSUM BIT(0) #define OCTEP_CAP_RX_CHECKSUM BIT(1) #define OCTEP_CAP_TSO BIT(2) /* Link modes */ enum octep_link_mode_bit_indices { OCTEP_LINK_MODE_10GBASE_T = 0, OCTEP_LINK_MODE_10GBASE_R, OCTEP_LINK_MODE_10GBASE_CR, OCTEP_LINK_MODE_10GBASE_KR, OCTEP_LINK_MODE_10GBASE_LR, OCTEP_LINK_MODE_10GBASE_SR, OCTEP_LINK_MODE_25GBASE_CR, OCTEP_LINK_MODE_25GBASE_KR, OCTEP_LINK_MODE_25GBASE_SR, OCTEP_LINK_MODE_40GBASE_CR4, OCTEP_LINK_MODE_40GBASE_KR4, OCTEP_LINK_MODE_40GBASE_LR4, OCTEP_LINK_MODE_40GBASE_SR4, OCTEP_LINK_MODE_50GBASE_CR2, OCTEP_LINK_MODE_50GBASE_KR2, OCTEP_LINK_MODE_50GBASE_SR2, OCTEP_LINK_MODE_50GBASE_CR, OCTEP_LINK_MODE_50GBASE_KR, OCTEP_LINK_MODE_50GBASE_LR, OCTEP_LINK_MODE_50GBASE_SR, OCTEP_LINK_MODE_100GBASE_CR4, OCTEP_LINK_MODE_100GBASE_KR4, OCTEP_LINK_MODE_100GBASE_LR4, OCTEP_LINK_MODE_100GBASE_SR4, OCTEP_LINK_MODE_NBITS }; /* Hardware interface link state information. */ struct octep_iface_link_info { /* Bitmap of Supported link speeds/modes. */ u64 supported_modes; /* Bitmap of Advertised link speeds/modes. */ u64 advertised_modes; /* Negotiated link speed in Mbps. */ u32 speed; /* MTU */ u16 mtu; /* Autonegotation state. */ #define OCTEP_LINK_MODE_AUTONEG_SUPPORTED BIT(0) #define OCTEP_LINK_MODE_AUTONEG_ADVERTISED BIT(1) u8 autoneg; /* Pause frames setting. */ #define OCTEP_LINK_MODE_PAUSE_SUPPORTED BIT(0) #define OCTEP_LINK_MODE_PAUSE_ADVERTISED BIT(1) u8 pause; /* Admin state of the link (ifconfig up/down */ u8 admin_up; /* Operational state of the link: physical link is up down */ u8 oper_up; }; /* The Octeon device specific private data structure. * Each Octeon device has this structure to represent all its components. */ struct octep_device { struct octep_config *conf; /* Octeon Chip type. */ u16 chip_id; u16 rev_id; /* Device capabilities enabled */ u64 caps_enabled; /* Device capabilities supported */ u64 caps_supported; /* Pointer to basic Linux device */ struct device *dev; /* Linux PCI device pointer */ struct pci_dev *pdev; /* Netdev corresponding to the Octeon device */ struct net_device *netdev; /* memory mapped io range */ struct octep_mmio mmio[OCTEP_MMIO_REGIONS]; /* MAC address */ u8 mac_addr[ETH_ALEN]; /* Tx queues (IQ: Instruction Queue) */ u16 num_iqs; /* pkind value to be used in every Tx hardware descriptor */ u8 pkind; /* Pointers to Octeon Tx queues */ struct octep_iq *iq[OCTEP_MAX_IQ]; /* Rx queues (OQ: Output Queue) */ u16 num_oqs; /* Pointers to Octeon Rx queues */ struct octep_oq *oq[OCTEP_MAX_OQ]; /* Hardware port number of the PCIe interface */ u16 pcie_port; /* PCI Window registers to access some hardware CSRs */ struct octep_pci_win_regs pci_win_regs; /* Hardware operations */ struct octep_hw_ops hw_ops; /* IRQ info */ u16 num_irqs; u16 num_non_ioq_irqs; char *non_ioq_irq_names; struct msix_entry *msix_entries; /* IOq information of it's corresponding MSI-X interrupt. */ struct octep_ioq_vector *ioq_vector[OCTEP_MAX_QUEUES]; /* Hardware Interface Tx statistics */ struct octep_iface_tx_stats iface_tx_stats; /* Hardware Interface Rx statistics */ struct octep_iface_rx_stats iface_rx_stats; /* Hardware Interface Link info like supported modes, aneg support */ struct octep_iface_link_info link_info; /* Mailbox to talk to VFs */ struct octep_mbox *mbox[OCTEP_MAX_VF]; /* Work entry to handle Tx timeout */ struct work_struct tx_timeout_task; /* control mbox over pf */ struct octep_ctrl_mbox ctrl_mbox; /* offset for iface stats */ u32 ctrl_mbox_ifstats_offset; /* Work entry to handle ctrl mbox interrupt */ struct work_struct ctrl_mbox_task; }; static inline u16 OCTEP_MAJOR_REV(struct octep_device *oct) { u16 rev = (oct->rev_id & 0xC) >> 2; return (rev == 0) ? 1 : rev; } static inline u16 OCTEP_MINOR_REV(struct octep_device *oct) { return (oct->rev_id & 0x3); } /* Octeon CSR read/write access APIs */ #define octep_write_csr(octep_dev, reg_off, value) \ writel(value, (octep_dev)->mmio[0].hw_addr + (reg_off)) #define octep_write_csr64(octep_dev, reg_off, val64) \ writeq(val64, (octep_dev)->mmio[0].hw_addr + (reg_off)) #define octep_read_csr(octep_dev, reg_off) \ readl((octep_dev)->mmio[0].hw_addr + (reg_off)) #define octep_read_csr64(octep_dev, reg_off) \ readq((octep_dev)->mmio[0].hw_addr + (reg_off)) /* Read windowed register. * @param oct - pointer to the Octeon device. * @param addr - Address of the register to read. * * This routine is called to read from the indirectly accessed * Octeon registers that are visible through a PCI BAR0 mapped window * register. * @return - 64 bit value read from the register. */ static inline u64 OCTEP_PCI_WIN_READ(struct octep_device *oct, u64 addr) { u64 val64; addr |= 1ull << 53; /* read 8 bytes */ writeq(addr, oct->pci_win_regs.pci_win_rd_addr); val64 = readq(oct->pci_win_regs.pci_win_rd_data); dev_dbg(&oct->pdev->dev, "%s: reg: 0x%016llx val: 0x%016llx\n", __func__, addr, val64); return val64; } /* Write windowed register. * @param oct - pointer to the Octeon device. * @param addr - Address of the register to write * @param val - Value to write * * This routine is called to write to the indirectly accessed * Octeon registers that are visible through a PCI BAR0 mapped window * register. * @return Nothing. */ static inline void OCTEP_PCI_WIN_WRITE(struct octep_device *oct, u64 addr, u64 val) { writeq(addr, oct->pci_win_regs.pci_win_wr_addr); writeq(val, oct->pci_win_regs.pci_win_wr_data); dev_dbg(&oct->pdev->dev, "%s: reg: 0x%016llx val: 0x%016llx\n", __func__, addr, val); } extern struct workqueue_struct *octep_wq; int octep_device_setup(struct octep_device *oct); int octep_setup_iqs(struct octep_device *oct); void octep_free_iqs(struct octep_device *oct); void octep_clean_iqs(struct octep_device *oct); int octep_setup_oqs(struct octep_device *oct); void octep_free_oqs(struct octep_device *oct); void octep_oq_dbell_init(struct octep_device *oct); void octep_device_setup_cn93_pf(struct octep_device *oct); int octep_iq_process_completions(struct octep_iq *iq, u16 budget); int octep_oq_process_rx(struct octep_oq *oq, int budget); void octep_set_ethtool_ops(struct net_device *netdev); #endif /* _OCTEP_MAIN_H_ */