From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 0410A42FB8; Wed, 2 Aug 2023 10:13:54 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id BE72643258; Wed, 2 Aug 2023 10:13:13 +0200 (CEST) Received: from smtpbgeu2.qq.com (smtpbgeu2.qq.com [18.194.254.142]) by mails.dpdk.org (Postfix) with ESMTP id 2337B43264 for ; Wed, 2 Aug 2023 10:13:10 +0200 (CEST) X-QQ-mid: bizesmtp91t1690963976trajd8oe Received: from steven.localdomain ( [183.81.182.182]) by bizesmtp.qq.com (ESMTP) with id ; Wed, 02 Aug 2023 16:12:54 +0800 (CST) X-QQ-SSF: 01400000000000D0E000000B0000000 X-QQ-FEAT: qOAV9bwDT/nhQwW8+sEW24mcRNrMQDxFhxMbzfuOFYI9Pcvee44F4QsvWNmQ7 dxNKXluZzhVWpvkjZkERUYP8Z7pfZgdCNsz6lHrHmWwlxO6CuhDkATC1is0LK2iPJB6+utV IqjWZK3gE/5rU7/YYSuqXYWRowwPGrbR/GDH9MkBWo0d9WwsC7ObXBQoKpsjhqQmv8Jy7mE Qm3q+SAxf/cG9R0HA8QIfbu80YUyQ1U/KohWyp5ElCoVB6FCLco3rZJtgWTeWlHxgFk9hEc 30gtYnkqsejZ0o3/LpfM2hqbipDhKgN/mEsVChn/fsH7txiz94vQUMZ286Tgbm0Zp+3ZHQ3 v6sVIBtdxxtdO04F9cqdJjwsodi/CDvYmGUxbVxArnVAasjOCmNDzbihz7BQzrkcomeOi+O X-QQ-GoodBg: 2 X-BIZMAIL-ID: 6753951482647991177 From: Wenbo Cao To: Wenbo Cao Cc: dev@dpdk.org, ferruh.yigit@intel.com, andrew.rybchenko@oktetlabs.ru Subject: [PATCH v2 8/8] net/rnp handle device interrupts Date: Wed, 2 Aug 2023 08:11:06 +0000 Message-Id: <20230802081106.2340406-9-caowenbo@mucse.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20230802081106.2340406-1-caowenbo@mucse.com> References: <20230802081106.2340406-1-caowenbo@mucse.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:mucse.com:qybglogicsvrgz:qybglogicsvrgz5a-0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Handle device lsc interrupt event Signed-off-by: Wenbo Cao --- drivers/net/rnp/base/rnp_hw.h | 5 + drivers/net/rnp/base/rnp_mac_regs.h | 279 ++++++++++++++++++++++++++++ drivers/net/rnp/rnp.h | 8 + drivers/net/rnp/rnp_ethdev.c | 17 ++ drivers/net/rnp/rnp_mbx.h | 3 +- drivers/net/rnp/rnp_mbx_fw.c | 233 +++++++++++++++++++++++ drivers/net/rnp/rnp_mbx_fw.h | 38 +++- 7 files changed, 580 insertions(+), 3 deletions(-) create mode 100644 drivers/net/rnp/base/rnp_mac_regs.h diff --git a/drivers/net/rnp/base/rnp_hw.h b/drivers/net/rnp/base/rnp_hw.h index 7b7584959e..a8a253b766 100644 --- a/drivers/net/rnp/base/rnp_hw.h +++ b/drivers/net/rnp/base/rnp_hw.h @@ -10,6 +10,7 @@ #include "rnp_osdep.h" #include "rnp_dma_regs.h" #include "rnp_eth_regs.h" +#include "rnp_mac_regs.h" #include "rnp_cfg.h" static inline unsigned int rnp_rd_reg(volatile void *addr) @@ -35,6 +36,10 @@ static inline void rnp_wr_reg(volatile void *reg, int val) rnp_eth_wr(hw, RNP_RAL_BASE_ADDR(hw_idx), val) #define RNP_MACADDR_UPDATE_HI(hw, hw_idx, val) \ rnp_eth_wr(hw, RNP_RAH_BASE_ADDR(hw_idx), val) +#define rnp_mac_rd(hw, id, off) \ + rnp_rd_reg((char *)(hw)->mac_base[id] + (off)) +#define rnp_mac_wr(hw, id, off, val) \ + rnp_wr_reg((char *)(hw)->mac_base[id] + (off), val) struct rnp_hw; /* Mbx Operate info */ enum MBX_ID { diff --git a/drivers/net/rnp/base/rnp_mac_regs.h b/drivers/net/rnp/base/rnp_mac_regs.h new file mode 100644 index 0000000000..f9466b3841 --- /dev/null +++ b/drivers/net/rnp/base/rnp_mac_regs.h @@ -0,0 +1,279 @@ +#ifndef __RNP_MAC_REGS_H__ +#define __RNP_MAC_REGS_H__ + +#include "rnp_osdep.h" +#define RNP_MAC_TX_CFG (0x0) + +/* Transmitter Enable */ +#define RNP_MAC_TE BIT(0) +/* Jabber Disable */ +#define RNP_MAC_JD BIT(16) +#define RNP_SPEED_SEL_1G (BIT(30) | BIT(29) | BIT(28)) +#define RNP_SPEED_SEL_10G BIT(30) +#define RNP_SPEED_SEL_40G (0) +#define RNP_MAC_RX_CFG (0x4) +/* Receiver Enable */ +#define RNP_MAC_RE BIT(0) +/* Automatic Pad or CRC Stripping */ +#define RNP_MAC_ACS BIT(1) +/* CRC stripping for Type packets */ +#define RNP_MAC_CST BIT(2) +/* Disable CRC Check */ +#define RNP_MAC_DCRCC BIT(3) +/* Enable Max Frame Size Limit */ +#define RNP_MAC_GPSLCE BIT(6) +/* Watchdog Disable */ +#define RNP_MAC_WD BIT(7) +/* Jumbo Packet Support En */ +#define RNP_MAC_JE BIT(8) +/* Loopback Mode */ +#define RNP_MAC_LM BIT(10) +/* Giant Packet Size Limit */ +#define RNP_MAC_GPSL_MASK GENMASK(29, 16) +#define RNP_MAC_MAX_GPSL (1518) +#define RNP_MAC_CPSL_SHIFT (16) + +#define RNP_MAC_PKT_FLT_CTRL (0x8) + +/* Receive All */ +#define RNP_MAC_RA BIT(31) +/* Pass Control Packets */ +#define RNP_MAC_PCF GENMASK(7, 6) +#define RNP_MAC_PCF_OFFSET (6) +/* Mac Filter ALL Ctrl Frame */ +#define RNP_MAC_PCF_FAC (0) +/* Mac Forward ALL Ctrl Frame Except Pause */ +#define RNP_MAC_PCF_NO_PAUSE (1) +/* Mac Forward All Ctrl Pkt */ +#define RNP_MAC_PCF_PA (2) +/* Mac Forward Ctrl Frame Match Unicast */ +#define RNP_MAC_PCF_PUN (3) +/* Promiscuous Mode */ +#define RNP_MAC_PROMISC_EN BIT(0) +/* Hash Unicast */ +#define RNP_MAC_HUC BIT(1) +/* Hash Multicast */ +#define RNP_MAC_HMC BIT(2) +/* Pass All Multicast */ +#define RNP_MAC_PM BIT(4) +/* Disable Broadcast Packets */ +#define RNP_MAC_DBF BIT(5) +/* Hash or Perfect Filter */ +#define RNP_MAC_HPF BIT(10) +#define RNP_MAC_VTFE BIT(16) +/* Interrupt Status */ +#define RNP_MAC_INT_STATUS _MAC_(0xb0) +#define RNP_MAC_LS_MASK GENMASK(25, 24) +#define RNP_MAC_LS_UP (0) +#define RNP_MAC_LS_LOCAL_FAULT BIT(25) +#define RNP_MAC_LS_REMOTE_FAULT (BIT(25) | BIT(24)) +/* Unicast Mac Hash Table */ +#define RNP_MAC_UC_HASH_TB(n) _MAC_(0x10 + ((n) * 0x4)) + + +#define RNP_MAC_LPI_CTRL (0xd0) + +/* PHY Link Status Disable */ +#define RNP_MAC_PLSDIS BIT(18) +/* PHY Link Status */ +#define RNP_MAC_PLS BIT(17) + +/* MAC VLAN CTRL Strip REG */ +#define RNP_MAC_VLAN_TAG (0x50) + +/* En Inner VLAN Strip Action */ +#define RNP_MAC_EIVLS GENMASK(29, 28) +/* Inner VLAN Strip Action Shift */ +#define RNP_MAC_IV_EIVLS_SHIFT (28) +/* Inner Vlan Don't Strip*/ +#define RNP_MAC_IV_STRIP_NONE (0x0) +/* Inner Vlan Strip When Filter Match Success */ +#define RNP_MAC_IV_STRIP_PASS (0x1) +/* Inner Vlan STRIP When Filter Match FAIL */ +#define RNP_MAC_IV_STRIP_FAIL (0x2) +/* Inner Vlan STRIP Always */ +#define RNP_MAC_IV_STRIP_ALL (0X3) +/* VLAN Strip Mode Ctrl Shift */ +#define RNP_VLAN_TAG_CTRL_EVLS_SHIFT (21) +/* En Double Vlan Processing */ +#define RNP_MAC_VLAN_EDVLP BIT(26) +/* VLAN Tag Hash Table Match Enable */ +#define RNP_MAC_VLAN_VTHM BIT(25) +/* Enable VLAN Tag in Rx status */ +#define RNP_MAC_VLAN_EVLRXS BIT(24) +/* Disable VLAN Type Check */ +#define RNP_MAC_VLAN_DOVLTC BIT(20) +/* Enable S-VLAN */ +#define RNP_MAC_VLAN_ESVL BIT(18) +/* Enable 12-Bit VLAN Tag Comparison Filter */ +#define RNP_MAC_VLAN_ETV BIT(16) +#define RNP_MAC_VLAN_HASH_EN GENMASK(15, 0) +#define RNP_MAC_VLAN_VID GENMASK(15, 0) +/* VLAN Don't Strip */ +#define RNP_MAC_VLAN_STRIP_NONE (0x0 << RNP_VLAN_TAG_CTRL_EVLS_SHIFT) +/* VLAN Filter Success Then STRIP */ +#define RNP_MAC_VLAN_STRIP_PASS (0x1 << RNP_VLAN_TAG_CTRL_EVLS_SHIFT) +/* VLAN Filter Failed Then STRIP */ +#define RNP_MAC_VLAN_STRIP_FAIL (0x2 << RNP_VLAN_TAG_CTRL_EVLS_SHIFT) +/* All Vlan Will Strip */ +#define RNP_MAC_VLAN_STRIP_ALL (0x3 << RNP_VLAN_TAG_CTRL_EVLS_SHIFT) + +#define RNP_MAC_VLAN_HASH_TB (0x58) +#define RNP_MAC_VLAN_HASH_MASK GENMASK(15, 0) + +/* MAC VLAN CTRL INSERT REG */ +#define RNP_MAC_VLAN_INCL (0x60) +#define RNP_MAC_INVLAN_INCL (0x64) + +/* VLAN Tag Input */ +/* VLAN_Tag Insert From Description */ +#define RNP_MAC_VLAN_VLTI BIT(20) +/* C-VLAN or S-VLAN */ +#define RNP_MAC_VLAN_CSVL BIT(19) +#define RNP_MAC_VLAN_INSERT_CVLAN (0 << 19) +#define RNP_MAC_VLAN_INSERT_SVLAN (1 << 19) +/* VLAN Tag Control in Transmit Packets */ +#define RNP_MAC_VLAN_VLC GENMASK(17, 16) +/* VLAN Tag Control Offset Bit */ +#define RNP_MAC_VLAN_VLC_SHIFT (16) +/* Don't Anything ON TX VLAN*/ +#define RNP_MAC_VLAN_VLC_NONE (0x0 << RNP_MAC_VLAN_VLC_SHIFT) +/* MAC Delete VLAN */ +#define RNP_MAC_VLAN_VLC_DEL (0x1 << RNP_MAC_VLAN_VLC_SHIFT) +/* MAC Add VLAN */ +#define RNP_MAC_VLAN_VLC_ADD (0x2 << RNP_MAC_VLAN_VLC_SHIFT) +/* MAC Replace VLAN */ +#define RNP_MAC_VLAN_VLC_REPLACE (0x3 << RNP_MAC_VLAN_VLC_SHIFT) +/* VLAN Tag for Transmit Packets For Insert/Remove */ +#define RNP_MAC_VLAN_VLT GENMASK(15, 0) +/* TX Peer TC Flow Ctrl */ + +#define RNP_MAC_Q0_TX_FC(n) (0x70 + ((n) * 0x4)) + +/* Edit Pause Time */ +#define RNP_MAC_FC_PT GENMASK(31, 16) +#define RNP_MAC_FC_PT_OFFSET (16) +/* Disable Zero-Quanta Pause */ +#define RNP_MAC_FC_DZPQ BIT(7) +/* Pause Low Threshold */ +#define RNP_MAC_FC_PLT GENMASK(6, 4) +#define RNP_MAC_FC_PLT_OFFSET (4) +#define RNP_MAC_FC_PLT_4_SLOT (0) +#define RNP_MAC_FC_PLT_28_SLOT (1) +#define RNP_MAC_FC_PLT_36_SLOT (2) +#define RNP_MAC_FC_PLT_144_SLOT (3) +#define RNP_MAC_FC_PLT_256_SLOT (4) +/* Transmit Flow Control Enable */ +#define RNP_MAC_FC_TEE BIT(1) +/* Transmit Flow Control Busy Immediately */ +#define RNP_MAC_FC_FCB BIT(0) +/* Mac RX Flow Ctrl*/ + +#define RNP_MAC_RX_FC (0x90) + +/* Rx Priority Based Flow Control Enable */ +#define RNP_MAC_RX_FC_PFCE BIT(8) +/* Unicast Pause Packet Detect */ +#define RNP_MAC_RX_FC_UP BIT(1) +/* Receive Flow Control Enable */ +#define RNP_MAC_RX_FC_RFE BIT(0) + +/* Rx Mac Address Base */ +#define RNP_MAC_ADDR_DEF_HI _MAC_(0x0300) + +#define RNP_MAC_AE BIT(31) +#define RNP_MAC_ADDR_LO(n) _MAC_((0x0304) + ((n) * 0x8)) +#define RNP_MAC_ADDR_HI(n) _MAC_((0x0300) + ((n) * 0x8)) + +/* Mac Manage Counts */ +#define RNP_MMC_CTRL _MAC_(0x0800) +#define RNP_MMC_RSTONRD BIT(2) +/* Tx Good And Bad Bytes Base */ +#define RNP_MMC_TX_GBOCTGB _MAC_(0x0814) +/* Tx Good And Bad Frame Num Base */ +#define RNP_MMC_TX_GBFRMB _MAC_(0x081c) +/* Tx Good Broadcast Frame Num Base */ +#define RNP_MMC_TX_BCASTB _MAC_(0x0824) +/* Tx Good Multicast Frame Num Base */ +#define RNP_MMC_TX_MCASTB _MAC_(0x082c) +/* Tx 64Bytes Frame Num */ +#define RNP_MMC_TX_64_BYTESB _MAC_(0x0834) +#define RNP_MMC_TX_65TO127_BYTESB _MAC_(0x083c) +#define RNP_MMC_TX_128TO255_BYTEB _MAC_(0x0844) +#define RNP_MMC_TX_256TO511_BYTEB _MAC_(0x084c) +#define RNP_MMC_TX_512TO1023_BYTEB _MAC_(0x0854) +#define RNP_MMC_TX_1024TOMAX_BYTEB _MAC_(0x085c) +/* Tx Good And Bad Unicast Frame Num Base */ +#define RNP_MMC_TX_GBUCASTB _MAC_(0x0864) +/* Tx Good And Bad Multicast Frame Num Base */ +#define RNP_MMC_TX_GBMCASTB _MAC_(0x086c) +/* Tx Good And Bad Broadcast Frame NUM Base */ +#define RNP_MMC_TX_GBBCASTB _MAC_(0x0874) +/* Tx Frame Underflow Error */ +#define RNP_MMC_TX_UNDRFLWB _MAC_(0x087c) +/* Tx Good Frame Bytes Base */ +#define RNP_MMC_TX_GBYTESB _MAC_(0x0884) +/* Tx Good Frame Num Base*/ +#define RNP_MMC_TX_GBRMB _MAC_(0x088c) +/* Tx Good Pause Frame Num Base */ +#define RNP_MMC_TX_PAUSEB _MAC_(0x0894) +/* Tx Good Vlan Frame Num Base */ +#define RNP_MMC_TX_VLANB _MAC_(0x089c) + +/* Rx Good And Bad Frames Num Base */ +#define RNP_MMC_RX_GBFRMB _MAC_(0x0900) +/* Rx Good And Bad Frames Bytes Base */ +#define RNP_MMC_RX_GBOCTGB _MAC_(0x0908) +/* Rx Good Framse Bytes Base */ +#define RNP_MMC_RX_GOCTGB _MAC_(0x0910) +/* Rx Good Broadcast Frames Num Base */ +#define RNP_MMC_RX_BCASTGB _MAC_(0x0918) +/* Rx Good Multicast Frames Num Base */ +#define RNP_MMC_RX_MCASTGB _MAC_(0x0920) +/* Rx Crc Error Frames Num Base */ +#define RNP_MMC_RX_CRCERB _MAC_(0x0928) +/* Rx Less Than 64Byes with Crc Err Base*/ +#define RNP_MMC_RX_RUNTERB _MAC_(0x0930) +/* Receive Jumbo Frame Error */ +#define RNP_MMC_RX_JABBER_ERR _MAC_(0x0934) +/* Shorter Than 64Bytes without Any Errora Base */ +#define RNP_MMC_RX_USIZEGB _MAC_(0x0938) +/* Len Oversize Than Support */ +#define RNP_MMC_RX_OSIZEGB _MAC_(0x093c) +/* Rx 64Byes Frame Num Base */ +#define RNP_MMC_RX_64_BYTESB _MAC_(0x0940) +/* Rx 65Bytes To 127Bytes Frame Num Base */ +#define RNP_MMC_RX_65TO127_BYTESB _MAC_(0x0948) +/* Rx 128Bytes To 255Bytes Frame Num Base */ +#define RNP_MMC_RX_128TO255_BYTESB _MAC_(0x0950) +/* Rx 256Bytes To 511Bytes Frame Num Base */ +#define RNP_MMC_RX_256TO511_BYTESB _MAC_(0x0958) +/* Rx 512Bytes To 1023Bytes Frame Num Base */ +#define RNP_MMC_RX_512TO1203_BYTESB _MAC_(0x0960) +/* Rx Len Bigger Than 1024Bytes Base */ +#define RNP_MMC_RX_1024TOMAX_BYTESB _MAC_(0x0968) +/* Rx Unicast Frame Good Num Base */ +#define RNP_MMC_RX_UCASTGB _MAC_(0x0970) +/* Rx Length Error Of Frame Part */ +#define RNP_MMC_RX_LENERRB _MAC_(0x0978) +/* Rx received with a Length field not equal to the valid frame size */ +#define RNP_MMC_RX_OUTOF_RANGE _MAC_(0x0980) +/* Rx Pause Frame Good Num Base */ +#define RNP_MMC_RX_PAUSEB _MAC_(0x0988) +/* Rx Vlan Frame Good Num Base */ +#define RNP_MMC_RX_VLANGB _MAC_(0x0998) +/* Rx With A Watchdog Timeout Err Frame Base */ +#define RNP_MMC_RX_WDOGERRB _MAC_(0x09a0) + +/* 1588 */ +#define RNP_MAC_TS_CTRL _MAC_(0X0d00) +#define RNP_MAC_SUB_SECOND_INCREMENT _MAC_(0x0d04) +#define RNP_MAC_SYS_TIME_SEC_CFG _MAC_(0x0d08) +#define RNP_MAC_SYS_TIME_NANOSEC_CFG _MAC_(0x0d0c) +#define RNP_MAC_SYS_TIME_SEC_UPDATE _MAC_(0x0d10) +#define RNP_MAC_SYS_TIME_NANOSEC_UPDATE _MAC_(0x0d14) +#define RNP_MAC_TS_ADDEND _MAC_(0x0d18) +#define RNP_MAC_TS_STATS _MAC_(0x0d20) +#define RNP_MAC_INTERRUPT_ENABLE _MAC_(0x00b4) + +#endif /* __RNP_MAC_REGS_H__ */ diff --git a/drivers/net/rnp/rnp.h b/drivers/net/rnp/rnp.h index 75789c02f4..953e1f8079 100644 --- a/drivers/net/rnp/rnp.h +++ b/drivers/net/rnp/rnp.h @@ -111,6 +111,8 @@ struct rnp_eth_port { uint8_t tx_func_sec; /* force set io tx func */ struct rte_eth_dev *eth_dev; struct rnp_port_attr attr; + uint64_t state; + rte_spinlock_t rx_mac_lock; /* Lock For Mac_cfg resource write */ /* Recvice Mac Address Record Table */ uint8_t mac_use_tb[RNP_MAX_MAC_ADDRS]; uint8_t use_num_mac; @@ -131,6 +133,12 @@ enum { RNP_IO_FUNC_USE_COMMON, }; +enum rnp_port_state { + RNP_PORT_STATE_PAUSE = 0, + RNP_PORT_STATE_FINISH, + RNP_PORT_STATE_SETTING, +}; + struct rnp_eth_adapter { enum rnp_work_mode mode; enum rnp_resource_share_m s_mode; /* Port Resource Share Policy */ diff --git a/drivers/net/rnp/rnp_ethdev.c b/drivers/net/rnp/rnp_ethdev.c index 109557eb85..8eae78c854 100644 --- a/drivers/net/rnp/rnp_ethdev.c +++ b/drivers/net/rnp/rnp_ethdev.c @@ -599,10 +599,23 @@ static int rnp_post_handle(struct rnp_eth_adapter *adapter) return 0; } +static void rnp_dev_interrupt_handler(void *param) +{ + struct rte_eth_dev *dev = (struct rte_eth_dev *)param; + struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); + struct rte_intr_handle *intr_handle = pci_dev->intr_handle; + struct rnp_eth_adapter *adapter = RNP_DEV_TO_ADAPTER(dev); + + rte_intr_disable(intr_handle); + rnp_fw_msg_handler(adapter); + rte_intr_enable(intr_handle); +} + static int rnp_eth_dev_init(struct rte_eth_dev *dev) { struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); + struct rte_intr_handle *intr_handle = pci_dev->intr_handle; struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev); struct rnp_eth_adapter *adapter = NULL; char name[RTE_ETH_NAME_MAX_LEN] = " "; @@ -678,6 +691,10 @@ rnp_eth_dev_init(struct rte_eth_dev *dev) rnp_mac_rx_disable(eth_dev); rnp_mac_tx_disable(eth_dev); } + rte_intr_disable(intr_handle); + /* Enable Link Update Event Interrupt */ + rte_intr_callback_register(intr_handle, + rnp_dev_interrupt_handler, dev); ret = rnp_post_handle(adapter); if (ret) goto eth_alloc_error; diff --git a/drivers/net/rnp/rnp_mbx.h b/drivers/net/rnp/rnp_mbx.h index 87949c1726..d6b78e32a7 100644 --- a/drivers/net/rnp/rnp_mbx.h +++ b/drivers/net/rnp/rnp_mbx.h @@ -13,7 +13,8 @@ /* Mbx Ctrl state */ #define RNP_VFMAILBOX_SIZE (14) /* 16 32 bit words - 64 bytes */ -#define TSRN10_VFMBX_SIZE (RNP_VFMAILBOX_SIZE) +#define RNP_FW_MAILBOX_SIZE RNP_VFMAILBOX_SIZE +#define RNP_VFMBX_SIZE (RNP_VFMAILBOX_SIZE) #define RNP_VT_MSGTYPE_ACK (0x80000000) #define RNP_VT_MSGTYPE_NACK (0x40000000) diff --git a/drivers/net/rnp/rnp_mbx_fw.c b/drivers/net/rnp/rnp_mbx_fw.c index d505c5732b..3fcf70d0ad 100644 --- a/drivers/net/rnp/rnp_mbx_fw.c +++ b/drivers/net/rnp/rnp_mbx_fw.c @@ -546,3 +546,236 @@ int rnp_hw_set_fw_force_speed_1g(struct rte_eth_dev *dev, int enable) { return rnp_mbx_set_dump(dev, 0x01150000 | (enable & 1)); } + +static inline int +rnp_mbx_fw_reply_handler(struct rnp_eth_adapter *adapter __rte_unused, + struct mbx_fw_cmd_reply *reply) +{ + struct mbx_req_cookie *cookie; + /* dbg_here; */ + cookie = reply->cookie; + if (!cookie || cookie->magic != COOKIE_MAGIC) { + RNP_PMD_LOG(ERR, + "[%s] invalid cookie:%p opcode: " + "0x%x v0:0x%x\n", + __func__, + cookie, + reply->opcode, + *((int *)reply)); + return -EIO; + } + + if (cookie->priv_len > 0) + memcpy(cookie->priv, reply->data, cookie->priv_len); + + cookie->done = 1; + + if (reply->flags & FLAGS_ERR) + cookie->errcode = reply->error_code; + else + cookie->errcode = 0; + + return 0; +} + +void rnp_link_stat_mark(struct rnp_hw *hw, int nr_lane, int up) +{ + u32 v; + + rte_spinlock_lock(&hw->fw_lock); + v = rnp_rd_reg(hw->link_sync); + v &= ~(0xffff0000); + v |= 0xa5a40000; + if (up) + v |= BIT(nr_lane); + else + v &= ~BIT(nr_lane); + rnp_wr_reg(hw->link_sync, v); + + rte_spinlock_unlock(&hw->fw_lock); +} + +void rnp_link_report(struct rte_eth_dev *dev, bool link_en) +{ + struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev); + struct rnp_hw *hw = RNP_DEV_TO_HW(dev); + struct rte_eth_link link; + + link.link_duplex = link_en ? port->attr.phy_meta.link_duplex : + RTE_ETH_LINK_FULL_DUPLEX; + link.link_status = link_en ? RTE_ETH_LINK_UP : RTE_ETH_LINK_DOWN; + link.link_speed = link_en ? port->attr.speed : + RTE_ETH_SPEED_NUM_UNKNOWN; + RNP_PMD_LOG(INFO, + "\nPF[%d]link changed: changed_lane:0x%x, " + "status:0x%x\n", + hw->pf_vf_num & RNP_PF_NB_MASK ? 1 : 0, + port->attr.nr_port, + link_en); + link.link_autoneg = port->attr.phy_meta.link_autoneg + ? RTE_ETH_LINK_SPEED_AUTONEG + : RTE_ETH_LINK_SPEED_FIXED; + /* Report Link Info To Upper Firmwork */ + rte_eth_linkstatus_set(dev, &link); + /* Notice Event Process Link Status Change */ + rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL); + /* Notce Firmware LSC Event SW Received */ + rnp_link_stat_mark(hw, port->attr.nr_port, link_en); +} + +static void rnp_dev_alarm_link_handler(void *param) +{ + struct rte_eth_dev *dev = (struct rte_eth_dev *)param; + struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev); + uint32_t status; + + status = port->attr.link_ready; + rnp_link_report(dev, status); +} + +static void rnp_link_event(struct rnp_eth_adapter *adapter, + struct mbx_fw_cmd_req *req) +{ + struct rnp_hw *hw = &adapter->hw; + struct rnp_eth_port *port; + bool link_change = false; + uint32_t lane_bit; + uint32_t sync_bit; + uint32_t link_en; + uint32_t ctrl; + int i; + + for (i = 0; i < adapter->num_ports; i++) { + port = adapter->ports[i]; + if (port == NULL) + continue; + link_change = false; + lane_bit = port->attr.nr_port; + if (__atomic_load_n(&port->state, __ATOMIC_RELAXED) + != RNP_PORT_STATE_FINISH) + continue; + if (!(BIT(lane_bit) & req->link_stat.changed_lanes)) + continue; + link_en = BIT(lane_bit) & req->link_stat.lane_status; + sync_bit = BIT(lane_bit) & rnp_rd_reg(hw->link_sync); + + if (link_en) { + /* Port Link Change To Up */ + if (!port->attr.link_ready) { + link_change = true; + port->attr.link_ready = true; + } + if (req->link_stat.port_st_magic == SPEED_VALID_MAGIC) { + port->attr.speed = req->link_stat.st[lane_bit].speed; + port->attr.phy_meta.link_duplex = + req->link_stat.st[lane_bit].duplex; + port->attr.phy_meta.link_autoneg = + req->link_stat.st[lane_bit].autoneg; + RNP_PMD_INIT_LOG(INFO, + "phy_id %d speed %d duplex " + "%d issgmii %d PortID %d\n", + req->link_stat.st[lane_bit].phy_addr, + req->link_stat.st[lane_bit].speed, + req->link_stat.st[lane_bit].duplex, + req->link_stat.st[lane_bit].is_sgmii, + port->attr.rte_pid); + } + } else { + /* Port Link to Down */ + if (port->attr.link_ready) { + link_change = true; + port->attr.link_ready = false; + } + } + if (link_change || sync_bit != link_en) { + /* WorkAround For Hardware When Link Down + * Eth Module Tx-side Can't Drop In some condition + * So back The Packet To Rx Side To Drop Packet + */ + /* To Protect Conflict Hw Resource */ + rte_spinlock_lock(&port->rx_mac_lock); + ctrl = rnp_mac_rd(hw, lane_bit, RNP_MAC_RX_CFG); + if (port->attr.link_ready) { + ctrl &= ~RNP_MAC_LM; + rnp_eth_wr(hw, + RNP_RX_FIFO_FULL_THRETH(lane_bit), + RNP_RX_DEFAULT_VAL); + } else { + rnp_eth_wr(hw, + RNP_RX_FIFO_FULL_THRETH(lane_bit), + RNP_RX_WORKAROUND_VAL); + ctrl |= RNP_MAC_LM; + } + rnp_mac_wr(hw, lane_bit, RNP_MAC_RX_CFG, ctrl); + rte_spinlock_unlock(&port->rx_mac_lock); + rte_eal_alarm_set(RNP_ALARM_INTERVAL, + rnp_dev_alarm_link_handler, + (void *)port->eth_dev); + } + } +} + +static inline int +rnp_mbx_fw_req_handler(struct rnp_eth_adapter *adapter, + struct mbx_fw_cmd_req *req) +{ + switch (req->opcode) { + case LINK_STATUS_EVENT: + rnp_link_event(adapter, req); + break; + default: + break; + } + + return 0; +} + +static inline int rnp_rcv_msg_from_fw(struct rnp_eth_adapter *adapter) +{ + const struct rnp_mbx_api *ops = RNP_DEV_TO_MBX_OPS(adapter->eth_dev); + struct rnp_hw *hw = &adapter->hw; + u32 msgbuf[RNP_FW_MAILBOX_SIZE]; + uint16_t check_state; + int retval; + + retval = ops->read(hw, msgbuf, RNP_FW_MAILBOX_SIZE, MBX_FW); + if (retval) { + PMD_DRV_LOG(ERR, "Error receiving message from FW\n"); + return retval; + } +#define RNP_MBX_SYNC_MASK GENMASK(15, 0) + + check_state = msgbuf[0] & RNP_MBX_SYNC_MASK; + /* this is a message we already processed, do nothing */ + if (check_state & FLAGS_DD) + return rnp_mbx_fw_reply_handler(adapter, + (struct mbx_fw_cmd_reply *)msgbuf); + else + return rnp_mbx_fw_req_handler(adapter, + (struct mbx_fw_cmd_req *)msgbuf); + + return 0; +} + +static void rnp_rcv_ack_from_fw(struct rnp_eth_adapter *adapter) +{ + struct rnp_hw *hw __rte_unused = &adapter->hw; + u32 msg __rte_unused = RNP_VT_MSGTYPE_NACK; + /* do-nothing */ +} + +int rnp_fw_msg_handler(struct rnp_eth_adapter *adapter) +{ + const struct rnp_mbx_api *ops = RNP_DEV_TO_MBX_OPS(adapter->eth_dev); + struct rnp_hw *hw = &adapter->hw; + + /* == check cpureq */ + if (!ops->check_for_msg(hw, MBX_FW)) + rnp_rcv_msg_from_fw(adapter); + + /* process any acks */ + if (!ops->check_for_ack(hw, MBX_FW)) + rnp_rcv_ack_from_fw(adapter); + + return 0; +} diff --git a/drivers/net/rnp/rnp_mbx_fw.h b/drivers/net/rnp/rnp_mbx_fw.h index 051ffd1bdc..292ad6dfbe 100644 --- a/drivers/net/rnp/rnp_mbx_fw.h +++ b/drivers/net/rnp/rnp_mbx_fw.h @@ -32,6 +32,8 @@ enum GENERIC_CMD { GET_PHY_ABALITY = 0x0601, GET_MAC_ADDRES = 0x0602, RESET_PHY = 0x0603, + GET_LINK_STATUS = 0x0607, + LINK_STATUS_EVENT = 0x0608, GET_LANE_STATUS = 0x0610, SET_EVENT_MASK = 0x0613, /* fw update */ @@ -98,6 +100,21 @@ struct phy_abilities { }; } __rte_packed __rte_aligned(4); +struct port_stat { + u8 phy_addr; /* Phy MDIO address */ + + u8 duplex : 1; /* FIBRE is always 1,Twisted Pair 1 or 0 */ + u8 autoneg : 1; /* autoned state */ + u8 fec : 1; + u8 an_rev : 1; + u8 link_traing : 1; + u8 is_sgmii : 1; /* avild fw >= 0.5.0.17 */ + u16 speed; /* cur port linked speed */ + + u16 pause : 4; + u16 rev : 12; +} __rte_packed; + #define RNP_SPEED_CAP_UNKNOWN (0) #define RNP_SPEED_CAP_10M_FULL BIT(2) #define RNP_SPEED_CAP_100M_FULL BIT(3) @@ -186,8 +203,14 @@ struct mbx_fw_cmd_reply { struct phy_abilities phy_abilities; }; } __rte_packed __rte_aligned(4); - -#define MBX_REQ_HDR_LEN 24 +/* == flags == */ +#define FLAGS_DD BIT(0) /* driver clear 0, FW must set 1 */ +#define FLAGS_CMP BIT(1) /* driver clear 0, FW mucst set */ +/* driver clear 0, FW must set only if it reporting an error */ +#define FLAGS_ERR BIT(2) + +#define MBX_REQ_HDR_LEN (24) +#define RNP_ALARM_INTERVAL (50000) /* unit us */ /* driver -> firmware */ struct mbx_fw_cmd_req { unsigned short flags; /* 0-1 */ @@ -240,6 +263,14 @@ struct mbx_fw_cmd_req { int flag; int nr_lane; } set_dump; + + struct { + unsigned short changed_lanes; + unsigned short lane_status; + unsigned int port_st_magic; +#define SPEED_VALID_MAGIC 0xa4a6a8a9 + struct port_stat st[4]; + } link_stat; /* FW->RC */ }; } __rte_packed __rte_aligned(4); @@ -364,4 +395,7 @@ int rnp_mbx_get_lane_stat(struct rte_eth_dev *dev); int rnp_fw_update(struct rnp_eth_adapter *adapter); int rnp_hw_set_fw_10g_1g_auto_detch(struct rte_eth_dev *dev, int enable); int rnp_hw_set_fw_force_speed_1g(struct rte_eth_dev *dev, int enable); +void rnp_link_stat_mark(struct rnp_hw *hw, int nr_lane, int up); +void rnp_link_report(struct rte_eth_dev *dev, bool link_en); +int rnp_fw_msg_handler(struct rnp_eth_adapter *adapter); #endif /* __RNP_MBX_FW_H__*/ -- 2.27.0