Commit 02338c48 authored by Mengyuan Lou's avatar Mengyuan Lou Committed by David S. Miller

net: ngbe: Initialize sw info and register netdev

Initialize ngbe mac/phy type.
Check whether the firmware is initialized.
Initialize ngbe hw and register netdev.
Signed-off-by: default avatarMengyuan Lou <mengyuanlou@net-swift.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 049fe536
......@@ -24,6 +24,7 @@ config LIBWX
config NGBE
tristate "Wangxun(R) GbE PCI Express adapters support"
depends on PCI
select LIBWX
help
This driver supports Wangxun(R) GbE PCI Express family of
adapters.
......
......@@ -162,8 +162,8 @@ static int wx_acquire_sw_sync(struct wx_hw *wxhw, u32 mask)
* So we will leave this up to the caller to read back the data
* in these cases.
**/
static int wx_host_interface_command(struct wx_hw *wxhw, u32 *buffer,
u32 length, u32 timeout, bool return_data)
int wx_host_interface_command(struct wx_hw *wxhw, u32 *buffer,
u32 length, u32 timeout, bool return_data)
{
u32 hdr_size = sizeof(struct wx_hic_hdr);
u32 hicr, i, bi, buf[64] = {};
......@@ -265,6 +265,7 @@ static int wx_host_interface_command(struct wx_hw *wxhw, u32 *buffer,
wx_release_sw_sync(wxhw, WX_MNG_SWFW_SYNC_SW_MB);
return status;
}
EXPORT_SYMBOL(wx_host_interface_command);
/**
* wx_read_ee_hostif_data - Read EEPROM word using a host interface cmd
......@@ -870,6 +871,41 @@ void wx_reset_misc(struct wx_hw *wxhw)
}
EXPORT_SYMBOL(wx_reset_misc);
/**
* wx_get_pcie_msix_counts - Gets MSI-X vector count
* @wxhw: pointer to hardware structure
* @msix_count: number of MSI interrupts that can be obtained
* @max_msix_count: number of MSI interrupts that mac need
*
* Read PCIe configuration space, and get the MSI-X vector count from
* the capabilities table.
**/
int wx_get_pcie_msix_counts(struct wx_hw *wxhw, u16 *msix_count, u16 max_msix_count)
{
struct pci_dev *pdev = wxhw->pdev;
struct device *dev = &pdev->dev;
int pos;
*msix_count = 1;
pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX);
if (!pos) {
dev_err(dev, "Unable to find MSI-X Capabilities\n");
return -EINVAL;
}
pci_read_config_word(pdev,
pos + PCI_MSIX_FLAGS,
msix_count);
*msix_count &= WX_PCIE_MSIX_TBL_SZ_MASK;
/* MSI-X count is zero-based in HW */
*msix_count += 1;
if (*msix_count > max_msix_count)
*msix_count = max_msix_count;
return 0;
}
EXPORT_SYMBOL(wx_get_pcie_msix_counts);
int wx_sw_init(struct wx_hw *wxhw)
{
struct pci_dev *pdev = wxhw->pdev;
......
......@@ -7,6 +7,8 @@
int wx_check_flash_load(struct wx_hw *hw, u32 check_bit);
void wx_control_hw(struct wx_hw *wxhw, bool drv);
int wx_mng_present(struct wx_hw *wxhw);
int wx_host_interface_command(struct wx_hw *wxhw, u32 *buffer,
u32 length, u32 timeout, bool return_data);
int wx_read_ee_hostif(struct wx_hw *wxhw, u16 offset, u16 *data);
int wx_read_ee_hostif_buffer(struct wx_hw *wxhw,
u16 offset, u16 words, u16 *data);
......@@ -20,6 +22,7 @@ void wx_disable_rx(struct wx_hw *wxhw);
int wx_disable_pcie_master(struct wx_hw *wxhw);
int wx_stop_adapter(struct wx_hw *wxhw);
void wx_reset_misc(struct wx_hw *wxhw);
int wx_get_pcie_msix_counts(struct wx_hw *wxhw, u16 *msix_count, u16 max_msix_count);
int wx_sw_init(struct wx_hw *wxhw);
#endif /* _WX_HW_H_ */
......@@ -14,6 +14,10 @@
#define WX_WOL_SUP 0x4000
#define WX_WOL_MASK 0x4000
/* MSI-X capability fields masks */
#define WX_PCIE_MSIX_TBL_SZ_MASK 0x7FF
#define WX_PCI_LINK_STATUS 0xB2
/**************** Global Registers ****************************/
/* chip control Registers */
#define WX_MIS_PWR 0x10000
......@@ -255,6 +259,8 @@ struct wx_mac_info {
u32 num_rar_entries;
u32 max_tx_queues;
u32 max_rx_queues;
u16 max_msix_vectors;
struct wx_thermal_sensor_data sensor;
};
......
......@@ -6,4 +6,4 @@
obj-$(CONFIG_NGBE) += ngbe.o
ngbe-objs := ngbe_main.o
ngbe-objs := ngbe_main.o ngbe_hw.o
......@@ -11,12 +11,67 @@
#define NGBE_MAX_RX_QUEUES (NGBE_MAX_FDIR_INDICES + 1)
#define NGBE_MAX_TX_QUEUES (NGBE_MAX_FDIR_INDICES + 1)
#define NGBE_ETH_LENGTH_OF_ADDRESS 6
#define NGBE_MAX_MSIX_VECTORS 0x09
#define NGBE_RAR_ENTRIES 32
/* TX/RX descriptor defines */
#define NGBE_DEFAULT_TXD 512 /* default ring size */
#define NGBE_DEFAULT_TX_WORK 256
#define NGBE_MAX_TXD 8192
#define NGBE_MIN_TXD 128
#define NGBE_DEFAULT_RXD 512 /* default ring size */
#define NGBE_DEFAULT_RX_WORK 256
#define NGBE_MAX_RXD 8192
#define NGBE_MIN_RXD 128
#define NGBE_MAC_STATE_DEFAULT 0x1
#define NGBE_MAC_STATE_MODIFIED 0x2
#define NGBE_MAC_STATE_IN_USE 0x4
struct ngbe_mac_addr {
u8 addr[ETH_ALEN];
u16 state; /* bitmask */
u64 pools;
};
/* board specific private data structure */
struct ngbe_adapter {
u8 __iomem *io_addr; /* Mainly for iounmap use */
/* OS defined structs */
struct net_device *netdev;
struct pci_dev *pdev;
/* structs defined in ngbe_hw.h */
struct ngbe_hw hw;
struct ngbe_mac_addr *mac_table;
u16 msg_enable;
/* Tx fast path data */
int num_tx_queues;
u16 tx_itr_setting;
u16 tx_work_limit;
/* Rx fast path data */
int num_rx_queues;
u16 rx_itr_setting;
u16 rx_work_limit;
int num_q_vectors; /* current number of q_vectors for device */
int max_q_vectors; /* upper limit of q_vectors for device */
u32 tx_ring_count;
u32 rx_ring_count;
#define NGBE_MAX_RETA_ENTRIES 128
u8 rss_indir_tbl[NGBE_MAX_RETA_ENTRIES];
#define NGBE_RSS_KEY_SIZE 40 /* size of RSS Hash Key in bytes */
u32 *rss_key;
u32 wol;
u16 bd_number;
};
extern char ngbe_driver_name[];
......
// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2019 - 2022 Beijing WangXun Technology Co., Ltd. */
#include <linux/etherdevice.h>
#include <linux/iopoll.h>
#include <linux/pci.h>
#include "../libwx/wx_type.h"
#include "../libwx/wx_hw.h"
#include "ngbe_type.h"
#include "ngbe_hw.h"
#include "ngbe.h"
int ngbe_eeprom_chksum_hostif(struct ngbe_hw *hw)
{
struct wx_hic_read_shadow_ram buffer;
struct wx_hw *wxhw = &hw->wxhw;
int status;
int tmp;
buffer.hdr.req.cmd = NGBE_FW_EEPROM_CHECKSUM_CMD;
buffer.hdr.req.buf_lenh = 0;
buffer.hdr.req.buf_lenl = 0;
buffer.hdr.req.checksum = NGBE_FW_CMD_DEFAULT_CHECKSUM;
/* convert offset from words to bytes */
buffer.address = 0;
/* one word */
buffer.length = 0;
status = wx_host_interface_command(wxhw, (u32 *)&buffer, sizeof(buffer),
WX_HI_COMMAND_TIMEOUT, false);
if (status < 0)
return status;
tmp = rd32a(wxhw, WX_MNG_MBOX, 1);
if (tmp == NGBE_FW_CMD_ST_PASS)
return 0;
return -EIO;
}
static int ngbe_reset_misc(struct ngbe_hw *hw)
{
struct wx_hw *wxhw = &hw->wxhw;
wx_reset_misc(wxhw);
if (hw->mac_type == ngbe_mac_type_rgmii)
wr32(wxhw, NGBE_MDIO_CLAUSE_SELECT, 0xF);
if (hw->gpio_ctrl) {
/* gpio0 is used to power on/off control*/
wr32(wxhw, NGBE_GPIO_DDR, 0x1);
wr32(wxhw, NGBE_GPIO_DR, NGBE_GPIO_DR_0);
}
return 0;
}
/**
* ngbe_reset_hw - Perform hardware reset
* @hw: pointer to hardware structure
*
* Resets the hardware by resetting the transmit and receive units, masks
* and clears all interrupts, perform a PHY reset, and perform a link (MAC)
* reset.
**/
int ngbe_reset_hw(struct ngbe_hw *hw)
{
struct wx_hw *wxhw = &hw->wxhw;
int status = 0;
u32 reset = 0;
/* Call adapter stop to disable tx/rx and clear interrupts */
status = wx_stop_adapter(wxhw);
if (status != 0)
return status;
reset = WX_MIS_RST_LAN_RST(wxhw->bus.func);
wr32(wxhw, WX_MIS_RST, reset | rd32(wxhw, WX_MIS_RST));
ngbe_reset_misc(hw);
/* Store the permanent mac address */
wx_get_mac_addr(wxhw, wxhw->mac.perm_addr);
/* reset num_rar_entries to 128 */
wxhw->mac.num_rar_entries = NGBE_RAR_ENTRIES;
wx_init_rx_addrs(wxhw);
pci_set_master(wxhw->pdev);
return 0;
}
/* SPDX-License-Identifier: GPL-2.0 */
/*
* WangXun Gigabit PCI Express Linux driver
* Copyright (c) 2019 - 2022 Beijing WangXun Technology Co., Ltd.
*/
#ifndef _NGBE_HW_H_
#define _NGBE_HW_H_
int ngbe_eeprom_chksum_hostif(struct ngbe_hw *hw);
int ngbe_reset_hw(struct ngbe_hw *hw);
#endif /* _NGBE_HW_H_ */
......@@ -8,11 +8,6 @@
#include <linux/netdevice.h>
/************ NGBE_register.h ************/
/* Vendor ID */
#ifndef PCI_VENDOR_ID_WANGXUN
#define PCI_VENDOR_ID_WANGXUN 0x8088
#endif
/* Device IDs */
#define NGBE_DEV_ID_EM_WX1860AL_W 0x0100
#define NGBE_DEV_ID_EM_WX1860A2 0x0101
......@@ -47,4 +42,98 @@
#define NGBE_WOL_SUP 0x4000
#define NGBE_WOL_MASK 0x4000
/**************** EM Registers ****************************/
/* chip control Registers */
#define NGBE_MIS_PRB_CTL 0x10010
/* FMGR Registers */
#define NGBE_SPI_ILDR_STATUS 0x10120
#define NGBE_SPI_ILDR_STATUS_PERST BIT(0) /* PCIE_PERST is done */
#define NGBE_SPI_ILDR_STATUS_PWRRST BIT(1) /* Power on reset is done */
#define NGBE_SPI_ILDR_STATUS_LAN_SW_RST(_i) BIT((_i) + 9) /* lan soft reset done */
/* Checksum and EEPROM pointers */
#define NGBE_CALSUM_COMMAND 0xE9
#define NGBE_CALSUM_CAP_STATUS 0x10224
#define NGBE_EEPROM_VERSION_STORE_REG 0x1022C
#define NGBE_SAN_MAC_ADDR_PTR 0x18
#define NGBE_DEVICE_CAPS 0x1C
#define NGBE_EEPROM_VERSION_L 0x1D
#define NGBE_EEPROM_VERSION_H 0x1E
/* Media-dependent registers. */
#define NGBE_MDIO_CLAUSE_SELECT 0x11220
/* GPIO Registers */
#define NGBE_GPIO_DR 0x14800
#define NGBE_GPIO_DDR 0x14804
/*GPIO bit */
#define NGBE_GPIO_DR_0 BIT(0) /* SDP0 Data Value */
#define NGBE_GPIO_DR_1 BIT(1) /* SDP1 Data Value */
#define NGBE_GPIO_DDR_0 BIT(0) /* SDP0 IO direction */
#define NGBE_GPIO_DDR_1 BIT(1) /* SDP1 IO direction */
/* Wake up registers */
#define NGBE_PSR_WKUP_CTL 0x15B80
/* Wake Up Filter Control Bit */
#define NGBE_PSR_WKUP_CTL_LNKC BIT(0) /* Link Status Change Wakeup Enable*/
#define NGBE_PSR_WKUP_CTL_MAG BIT(1) /* Magic Packet Wakeup Enable */
#define NGBE_PSR_WKUP_CTL_EX BIT(2) /* Directed Exact Wakeup Enable */
#define NGBE_PSR_WKUP_CTL_MC BIT(3) /* Directed Multicast Wakeup Enable*/
#define NGBE_PSR_WKUP_CTL_BC BIT(4) /* Broadcast Wakeup Enable */
#define NGBE_PSR_WKUP_CTL_ARP BIT(5) /* ARP Request Packet Wakeup Enable*/
#define NGBE_PSR_WKUP_CTL_IPV4 BIT(6) /* Directed IPv4 Pkt Wakeup Enable */
#define NGBE_PSR_WKUP_CTL_IPV6 BIT(7) /* Directed IPv6 Pkt Wakeup Enable */
#define NGBE_FW_EEPROM_CHECKSUM_CMD 0xE9
#define NGBE_FW_NVM_DATA_OFFSET 3
#define NGBE_FW_CMD_DEFAULT_CHECKSUM 0xFF /* checksum always 0xFF */
#define NGBE_FW_CMD_ST_PASS 0x80658383
#define NGBE_FW_CMD_ST_FAIL 0x70657376
enum ngbe_phy_type {
ngbe_phy_unknown = 0,
ngbe_phy_none,
ngbe_phy_internal,
ngbe_phy_m88e1512,
ngbe_phy_m88e1512_sfi,
ngbe_phy_m88e1512_unknown,
ngbe_phy_yt8521s,
ngbe_phy_yt8521s_sfi,
ngbe_phy_internal_yt8521s_sfi,
ngbe_phy_generic
};
enum ngbe_media_type {
ngbe_media_type_unknown = 0,
ngbe_media_type_fiber,
ngbe_media_type_copper,
ngbe_media_type_backplane,
};
enum ngbe_mac_type {
ngbe_mac_type_unknown = 0,
ngbe_mac_type_mdi,
ngbe_mac_type_rgmii
};
struct ngbe_phy_info {
enum ngbe_phy_type type;
enum ngbe_media_type media_type;
u32 addr;
u32 id;
bool reset_if_overtemp;
};
struct ngbe_hw {
struct wx_hw wxhw;
struct ngbe_phy_info phy;
enum ngbe_mac_type mac_type;
bool wol_enabled;
bool ncsi_enabled;
bool gpio_ctrl;
};
#endif /* _NGBE_TYPE_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment