Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'add-support-of-hibmcge-ethernet-driver'

Jijie Shao says:

====================
Add support of HIBMCGE Ethernet Driver

This patch set adds the support of Hisilicon BMC Gigabit Ethernet Driver.

This patch set includes basic Rx/Tx functionality. It also includes
the registration and interrupt codes.

This work provides the initial support to the HIBMCGE and
would incrementally add features or enhancements.
====================

Link: https://patch.msgid.link/20241015123516.4035035-1-shaojijie@huawei.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

+1737 -1
+6
MAINTAINERS
··· 10278 10278 W: http://www.hisilicon.com 10279 10279 F: drivers/net/ethernet/hisilicon/hns3/ 10280 10280 10281 + HISILICON NETWORK HIBMCGE DRIVER 10282 + M: Jijie Shao <shaojijie@huawei.com> 10283 + L: netdev@vger.kernel.org 10284 + S: Maintained 10285 + F: drivers/net/ethernet/hisilicon/hibmcge/ 10286 + 10281 10287 HISILICON NETWORK SUBSYSTEM DRIVER 10282 10288 M: Jian Shen <shenjian15@huawei.com> 10283 10289 M: Salil Mehta <salil.mehta@huawei.com>
+17 -1
drivers/net/ethernet/hisilicon/Kconfig
··· 7 7 bool "Hisilicon devices" 8 8 default y 9 9 depends on OF || ACPI 10 - depends on ARM || ARM64 || COMPILE_TEST 11 10 help 12 11 If you have a network (Ethernet) card belonging to this class, say Y. 13 12 ··· 16 17 for your specific card in the following questions. 17 18 18 19 if NET_VENDOR_HISILICON 20 + 21 + if ARM || ARM64 || COMPILE_TEST 19 22 20 23 config HIX5HD2_GMAC 21 24 tristate "Hisilicon HIX5HD2 Family Network Device Support" ··· 141 140 devices and their associated operations. 142 141 143 142 endif #HNS3 143 + 144 + endif # ARM || ARM64 || COMPILE_TEST 145 + 146 + config HIBMCGE 147 + tristate "Hisilicon BMC Gigabit Ethernet Device Support" 148 + depends on PCI && PCI_MSI 149 + select PHYLIB 150 + select MOTORCOMM_PHY 151 + select REALTEK_PHY 152 + help 153 + If you wish to compile a kernel for a BMC with HIBMC-xx_gmac 154 + then you should answer Y to this. This makes this driver suitable for use 155 + on certain boards such as the HIBMC-210. 156 + 157 + If you are unsure, say N. 144 158 145 159 endif # NET_VENDOR_HISILICON
+1
drivers/net/ethernet/hisilicon/Makefile
··· 9 9 obj-$(CONFIG_HNS) += hns/ 10 10 obj-$(CONFIG_HNS3) += hns3/ 11 11 obj-$(CONFIG_HISI_FEMAC) += hisi_femac.o 12 + obj-$(CONFIG_HIBMCGE) += hibmcge/
+8
drivers/net/ethernet/hisilicon/hibmcge/Makefile
··· 1 + # SPDX-License-Identifier: GPL-2.0+ 2 + # 3 + # Makefile for the HISILICON BMC GE network device drivers. 4 + # 5 + 6 + obj-$(CONFIG_HIBMCGE) += hibmcge.o 7 + 8 + hibmcge-objs = hbg_main.o hbg_hw.o hbg_mdio.o hbg_irq.o hbg_txrx.o hbg_ethtool.o
+131
drivers/net/ethernet/hisilicon/hibmcge/hbg_common.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 + /* Copyright (c) 2024 Hisilicon Limited. */ 3 + 4 + #ifndef __HBG_COMMON_H 5 + #define __HBG_COMMON_H 6 + 7 + #include <linux/netdevice.h> 8 + #include <linux/pci.h> 9 + #include "hbg_reg.h" 10 + 11 + #define HBG_STATUS_DISABLE 0x0 12 + #define HBG_STATUS_ENABLE 0x1 13 + #define HBG_RX_SKIP1 0x00 14 + #define HBG_RX_SKIP2 0x01 15 + #define HBG_VECTOR_NUM 4 16 + #define HBG_PCU_CACHE_LINE_SIZE 32 17 + #define HBG_TX_TIMEOUT_BUF_LEN 1024 18 + #define HBG_RX_DESCR 0x01 19 + 20 + #define HBG_PACKET_HEAD_SIZE ((HBG_RX_SKIP1 + HBG_RX_SKIP2 + \ 21 + HBG_RX_DESCR) * HBG_PCU_CACHE_LINE_SIZE) 22 + 23 + enum hbg_dir { 24 + HBG_DIR_TX = 1 << 0, 25 + HBG_DIR_RX = 1 << 1, 26 + HBG_DIR_TX_RX = HBG_DIR_TX | HBG_DIR_RX, 27 + }; 28 + 29 + enum hbg_tx_state { 30 + HBG_TX_STATE_COMPLETE = 0, /* clear state, must fix to 0 */ 31 + HBG_TX_STATE_START, 32 + }; 33 + 34 + enum hbg_nic_state { 35 + HBG_NIC_STATE_EVENT_HANDLING = 0, 36 + }; 37 + 38 + struct hbg_buffer { 39 + u32 state; 40 + dma_addr_t state_dma; 41 + 42 + struct sk_buff *skb; 43 + dma_addr_t skb_dma; 44 + u32 skb_len; 45 + 46 + enum hbg_dir dir; 47 + struct hbg_ring *ring; 48 + struct hbg_priv *priv; 49 + }; 50 + 51 + struct hbg_ring { 52 + struct hbg_buffer *queue; 53 + dma_addr_t queue_dma; 54 + 55 + union { 56 + u32 head; 57 + u32 ntc; 58 + }; 59 + union { 60 + u32 tail; 61 + u32 ntu; 62 + }; 63 + u32 len; 64 + 65 + enum hbg_dir dir; 66 + struct hbg_priv *priv; 67 + struct napi_struct napi; 68 + char *tout_log_buf; /* tx timeout log buffer */ 69 + }; 70 + 71 + enum hbg_hw_event_type { 72 + HBG_HW_EVENT_NONE = 0, 73 + HBG_HW_EVENT_INIT, /* driver is loading */ 74 + HBG_HW_EVENT_RESET, 75 + }; 76 + 77 + struct hbg_dev_specs { 78 + u32 mac_id; 79 + struct sockaddr mac_addr; 80 + u32 phy_addr; 81 + u32 mdio_frequency; 82 + u32 rx_fifo_num; 83 + u32 tx_fifo_num; 84 + u32 vlan_layers; 85 + u32 max_mtu; 86 + u32 min_mtu; 87 + 88 + u32 max_frame_len; 89 + u32 rx_buf_size; 90 + }; 91 + 92 + struct hbg_irq_info { 93 + const char *name; 94 + u32 mask; 95 + bool re_enable; 96 + bool need_print; 97 + u64 count; 98 + 99 + void (*irq_handle)(struct hbg_priv *priv, struct hbg_irq_info *info); 100 + }; 101 + 102 + struct hbg_vector { 103 + char name[HBG_VECTOR_NUM][32]; 104 + struct hbg_irq_info *info_array; 105 + u32 info_array_len; 106 + }; 107 + 108 + struct hbg_mac { 109 + struct mii_bus *mdio_bus; 110 + struct phy_device *phydev; 111 + u8 phy_addr; 112 + 113 + u32 speed; 114 + u32 duplex; 115 + u32 autoneg; 116 + u32 link_status; 117 + }; 118 + 119 + struct hbg_priv { 120 + struct net_device *netdev; 121 + struct pci_dev *pdev; 122 + u8 __iomem *io_base; 123 + struct hbg_dev_specs dev_specs; 124 + unsigned long state; 125 + struct hbg_mac mac; 126 + struct hbg_vector vectors; 127 + struct hbg_ring tx_ring; 128 + struct hbg_ring rx_ring; 129 + }; 130 + 131 + #endif
+17
drivers/net/ethernet/hisilicon/hibmcge/hbg_ethtool.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + // Copyright (c) 2024 Hisilicon Limited. 3 + 4 + #include <linux/ethtool.h> 5 + #include <linux/phy.h> 6 + #include "hbg_ethtool.h" 7 + 8 + static const struct ethtool_ops hbg_ethtool_ops = { 9 + .get_link = ethtool_op_get_link, 10 + .get_link_ksettings = phy_ethtool_get_link_ksettings, 11 + .set_link_ksettings = phy_ethtool_set_link_ksettings, 12 + }; 13 + 14 + void hbg_ethtool_set_ops(struct net_device *netdev) 15 + { 16 + netdev->ethtool_ops = &hbg_ethtool_ops; 17 + }
+11
drivers/net/ethernet/hisilicon/hibmcge/hbg_ethtool.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 + /* Copyright (c) 2024 Hisilicon Limited. */ 3 + 4 + #ifndef __HBG_ETHTOOL_H 5 + #define __HBG_ETHTOOL_H 6 + 7 + #include <linux/netdevice.h> 8 + 9 + void hbg_ethtool_set_ops(struct net_device *netdev); 10 + 11 + #endif
+271
drivers/net/ethernet/hisilicon/hibmcge/hbg_hw.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + // Copyright (c) 2024 Hisilicon Limited. 3 + 4 + #include <linux/etherdevice.h> 5 + #include <linux/ethtool.h> 6 + #include <linux/iopoll.h> 7 + #include <linux/minmax.h> 8 + #include "hbg_common.h" 9 + #include "hbg_hw.h" 10 + #include "hbg_reg.h" 11 + 12 + #define HBG_HW_EVENT_WAIT_TIMEOUT_US (2 * 1000 * 1000) 13 + #define HBG_HW_EVENT_WAIT_INTERVAL_US (10 * 1000) 14 + /* little endian or big endian. 15 + * ctrl means packet description, data means skb packet data 16 + */ 17 + #define HBG_ENDIAN_CTRL_LE_DATA_BE 0x0 18 + #define HBG_PCU_FRAME_LEN_PLUS 4 19 + 20 + static bool hbg_hw_spec_is_valid(struct hbg_priv *priv) 21 + { 22 + return hbg_reg_read(priv, HBG_REG_SPEC_VALID_ADDR) && 23 + !hbg_reg_read(priv, HBG_REG_EVENT_REQ_ADDR); 24 + } 25 + 26 + int hbg_hw_event_notify(struct hbg_priv *priv, 27 + enum hbg_hw_event_type event_type) 28 + { 29 + bool is_valid; 30 + int ret; 31 + 32 + if (test_and_set_bit(HBG_NIC_STATE_EVENT_HANDLING, &priv->state)) 33 + return -EBUSY; 34 + 35 + /* notify */ 36 + hbg_reg_write(priv, HBG_REG_EVENT_REQ_ADDR, event_type); 37 + 38 + ret = read_poll_timeout(hbg_hw_spec_is_valid, is_valid, is_valid, 39 + HBG_HW_EVENT_WAIT_INTERVAL_US, 40 + HBG_HW_EVENT_WAIT_TIMEOUT_US, 41 + HBG_HW_EVENT_WAIT_INTERVAL_US, priv); 42 + 43 + clear_bit(HBG_NIC_STATE_EVENT_HANDLING, &priv->state); 44 + 45 + if (ret) 46 + dev_err(&priv->pdev->dev, 47 + "event %d wait timeout\n", event_type); 48 + 49 + return ret; 50 + } 51 + 52 + static int hbg_hw_dev_specs_init(struct hbg_priv *priv) 53 + { 54 + struct hbg_dev_specs *specs = &priv->dev_specs; 55 + u64 mac_addr; 56 + 57 + if (!hbg_hw_spec_is_valid(priv)) { 58 + dev_err(&priv->pdev->dev, "dev_specs not init\n"); 59 + return -EINVAL; 60 + } 61 + 62 + specs->mac_id = hbg_reg_read(priv, HBG_REG_MAC_ID_ADDR); 63 + specs->phy_addr = hbg_reg_read(priv, HBG_REG_PHY_ID_ADDR); 64 + specs->mdio_frequency = hbg_reg_read(priv, HBG_REG_MDIO_FREQ_ADDR); 65 + specs->max_mtu = hbg_reg_read(priv, HBG_REG_MAX_MTU_ADDR); 66 + specs->min_mtu = hbg_reg_read(priv, HBG_REG_MIN_MTU_ADDR); 67 + specs->vlan_layers = hbg_reg_read(priv, HBG_REG_VLAN_LAYERS_ADDR); 68 + specs->rx_fifo_num = hbg_reg_read(priv, HBG_REG_RX_FIFO_NUM_ADDR); 69 + specs->tx_fifo_num = hbg_reg_read(priv, HBG_REG_TX_FIFO_NUM_ADDR); 70 + mac_addr = hbg_reg_read64(priv, HBG_REG_MAC_ADDR_ADDR); 71 + u64_to_ether_addr(mac_addr, (u8 *)specs->mac_addr.sa_data); 72 + 73 + if (!is_valid_ether_addr((u8 *)specs->mac_addr.sa_data)) 74 + return -EADDRNOTAVAIL; 75 + 76 + specs->max_frame_len = HBG_PCU_CACHE_LINE_SIZE + specs->max_mtu; 77 + specs->rx_buf_size = HBG_PACKET_HEAD_SIZE + specs->max_frame_len; 78 + return 0; 79 + } 80 + 81 + u32 hbg_hw_get_irq_status(struct hbg_priv *priv) 82 + { 83 + u32 status; 84 + 85 + status = hbg_reg_read(priv, HBG_REG_CF_INTRPT_STAT_ADDR); 86 + 87 + hbg_field_modify(status, HBG_INT_MSK_TX_B, 88 + hbg_reg_read(priv, HBG_REG_CF_IND_TXINT_STAT_ADDR)); 89 + hbg_field_modify(status, HBG_INT_MSK_RX_B, 90 + hbg_reg_read(priv, HBG_REG_CF_IND_RXINT_STAT_ADDR)); 91 + 92 + return status; 93 + } 94 + 95 + void hbg_hw_irq_clear(struct hbg_priv *priv, u32 mask) 96 + { 97 + if (FIELD_GET(HBG_INT_MSK_TX_B, mask)) 98 + return hbg_reg_write(priv, HBG_REG_CF_IND_TXINT_CLR_ADDR, 0x1); 99 + 100 + if (FIELD_GET(HBG_INT_MSK_RX_B, mask)) 101 + return hbg_reg_write(priv, HBG_REG_CF_IND_RXINT_CLR_ADDR, 0x1); 102 + 103 + return hbg_reg_write(priv, HBG_REG_CF_INTRPT_CLR_ADDR, mask); 104 + } 105 + 106 + bool hbg_hw_irq_is_enabled(struct hbg_priv *priv, u32 mask) 107 + { 108 + if (FIELD_GET(HBG_INT_MSK_TX_B, mask)) 109 + return hbg_reg_read(priv, HBG_REG_CF_IND_TXINT_MSK_ADDR); 110 + 111 + if (FIELD_GET(HBG_INT_MSK_RX_B, mask)) 112 + return hbg_reg_read(priv, HBG_REG_CF_IND_RXINT_MSK_ADDR); 113 + 114 + return hbg_reg_read(priv, HBG_REG_CF_INTRPT_MSK_ADDR) & mask; 115 + } 116 + 117 + void hbg_hw_irq_enable(struct hbg_priv *priv, u32 mask, bool enable) 118 + { 119 + u32 value; 120 + 121 + if (FIELD_GET(HBG_INT_MSK_TX_B, mask)) 122 + return hbg_reg_write(priv, 123 + HBG_REG_CF_IND_TXINT_MSK_ADDR, enable); 124 + 125 + if (FIELD_GET(HBG_INT_MSK_RX_B, mask)) 126 + return hbg_reg_write(priv, 127 + HBG_REG_CF_IND_RXINT_MSK_ADDR, enable); 128 + 129 + value = hbg_reg_read(priv, HBG_REG_CF_INTRPT_MSK_ADDR); 130 + if (enable) 131 + value |= mask; 132 + else 133 + value &= ~mask; 134 + 135 + hbg_reg_write(priv, HBG_REG_CF_INTRPT_MSK_ADDR, value); 136 + } 137 + 138 + void hbg_hw_set_uc_addr(struct hbg_priv *priv, u64 mac_addr) 139 + { 140 + hbg_reg_write64(priv, HBG_REG_STATION_ADDR_LOW_2_ADDR, mac_addr); 141 + } 142 + 143 + static void hbg_hw_set_pcu_max_frame_len(struct hbg_priv *priv, 144 + u16 max_frame_len) 145 + { 146 + max_frame_len = max_t(u32, max_frame_len, ETH_DATA_LEN); 147 + 148 + /* lower two bits of value must be set to 0 */ 149 + max_frame_len = round_up(max_frame_len, HBG_PCU_FRAME_LEN_PLUS); 150 + 151 + hbg_reg_write_field(priv, HBG_REG_MAX_FRAME_LEN_ADDR, 152 + HBG_REG_MAX_FRAME_LEN_M, max_frame_len); 153 + } 154 + 155 + static void hbg_hw_set_mac_max_frame_len(struct hbg_priv *priv, 156 + u16 max_frame_size) 157 + { 158 + hbg_reg_write_field(priv, HBG_REG_MAX_FRAME_SIZE_ADDR, 159 + HBG_REG_MAX_FRAME_LEN_M, max_frame_size); 160 + } 161 + 162 + void hbg_hw_set_mtu(struct hbg_priv *priv, u16 mtu) 163 + { 164 + hbg_hw_set_pcu_max_frame_len(priv, mtu); 165 + hbg_hw_set_mac_max_frame_len(priv, mtu); 166 + } 167 + 168 + void hbg_hw_mac_enable(struct hbg_priv *priv, u32 enable) 169 + { 170 + hbg_reg_write_field(priv, HBG_REG_PORT_ENABLE_ADDR, 171 + HBG_REG_PORT_ENABLE_TX_B, enable); 172 + hbg_reg_write_field(priv, HBG_REG_PORT_ENABLE_ADDR, 173 + HBG_REG_PORT_ENABLE_RX_B, enable); 174 + } 175 + 176 + u32 hbg_hw_get_fifo_used_num(struct hbg_priv *priv, enum hbg_dir dir) 177 + { 178 + if (dir & HBG_DIR_TX) 179 + return hbg_reg_read_field(priv, HBG_REG_CF_CFF_DATA_NUM_ADDR, 180 + HBG_REG_CF_CFF_DATA_NUM_ADDR_TX_M); 181 + 182 + if (dir & HBG_DIR_RX) 183 + return hbg_reg_read_field(priv, HBG_REG_CF_CFF_DATA_NUM_ADDR, 184 + HBG_REG_CF_CFF_DATA_NUM_ADDR_RX_M); 185 + 186 + return 0; 187 + } 188 + 189 + void hbg_hw_set_tx_desc(struct hbg_priv *priv, struct hbg_tx_desc *tx_desc) 190 + { 191 + hbg_reg_write(priv, HBG_REG_TX_CFF_ADDR_0_ADDR, tx_desc->word0); 192 + hbg_reg_write(priv, HBG_REG_TX_CFF_ADDR_1_ADDR, tx_desc->word1); 193 + hbg_reg_write(priv, HBG_REG_TX_CFF_ADDR_2_ADDR, tx_desc->word2); 194 + hbg_reg_write(priv, HBG_REG_TX_CFF_ADDR_3_ADDR, tx_desc->word3); 195 + } 196 + 197 + void hbg_hw_fill_buffer(struct hbg_priv *priv, u32 buffer_dma_addr) 198 + { 199 + hbg_reg_write(priv, HBG_REG_RX_CFF_ADDR_ADDR, buffer_dma_addr); 200 + } 201 + 202 + void hbg_hw_adjust_link(struct hbg_priv *priv, u32 speed, u32 duplex) 203 + { 204 + hbg_reg_write_field(priv, HBG_REG_PORT_MODE_ADDR, 205 + HBG_REG_PORT_MODE_M, speed); 206 + hbg_reg_write_field(priv, HBG_REG_DUPLEX_TYPE_ADDR, 207 + HBG_REG_DUPLEX_B, duplex); 208 + } 209 + 210 + static void hbg_hw_init_transmit_ctrl(struct hbg_priv *priv) 211 + { 212 + u32 ctrl = 0; 213 + 214 + ctrl |= FIELD_PREP(HBG_REG_TRANSMIT_CTRL_AN_EN_B, HBG_STATUS_ENABLE); 215 + ctrl |= FIELD_PREP(HBG_REG_TRANSMIT_CTRL_CRC_ADD_B, HBG_STATUS_ENABLE); 216 + ctrl |= FIELD_PREP(HBG_REG_TRANSMIT_CTRL_PAD_EN_B, HBG_STATUS_ENABLE); 217 + 218 + hbg_reg_write(priv, HBG_REG_TRANSMIT_CTRL_ADDR, ctrl); 219 + } 220 + 221 + static void hbg_hw_init_rx_ctrl(struct hbg_priv *priv) 222 + { 223 + u32 ctrl = 0; 224 + 225 + ctrl |= FIELD_PREP(HBG_REG_RX_CTRL_RX_GET_ADDR_MODE_B, 226 + HBG_STATUS_ENABLE); 227 + ctrl |= FIELD_PREP(HBG_REG_RX_CTRL_TIME_INF_EN_B, HBG_STATUS_DISABLE); 228 + ctrl |= FIELD_PREP(HBG_REG_RX_CTRL_RXBUF_1ST_SKIP_SIZE_M, HBG_RX_SKIP1); 229 + ctrl |= FIELD_PREP(HBG_REG_RX_CTRL_RXBUF_1ST_SKIP_SIZE2_M, 230 + HBG_RX_SKIP2); 231 + ctrl |= FIELD_PREP(HBG_REG_RX_CTRL_RX_ALIGN_NUM_M, NET_IP_ALIGN); 232 + ctrl |= FIELD_PREP(HBG_REG_RX_CTRL_PORT_NUM, priv->dev_specs.mac_id); 233 + 234 + hbg_reg_write(priv, HBG_REG_RX_CTRL_ADDR, ctrl); 235 + } 236 + 237 + static void hbg_hw_init_rx_control(struct hbg_priv *priv) 238 + { 239 + hbg_hw_init_rx_ctrl(priv); 240 + 241 + /* parse from L2 layer */ 242 + hbg_reg_write_field(priv, HBG_REG_RX_PKT_MODE_ADDR, 243 + HBG_REG_RX_PKT_MODE_PARSE_MODE_M, 0x1); 244 + 245 + hbg_reg_write_field(priv, HBG_REG_RECV_CTRL_ADDR, 246 + HBG_REG_RECV_CTRL_STRIP_PAD_EN_B, 247 + HBG_STATUS_ENABLE); 248 + hbg_reg_write_field(priv, HBG_REG_RX_BUF_SIZE_ADDR, 249 + HBG_REG_RX_BUF_SIZE_M, priv->dev_specs.rx_buf_size); 250 + hbg_reg_write_field(priv, HBG_REG_CF_CRC_STRIP_ADDR, 251 + HBG_REG_CF_CRC_STRIP_B, HBG_STATUS_DISABLE); 252 + } 253 + 254 + int hbg_hw_init(struct hbg_priv *priv) 255 + { 256 + int ret; 257 + 258 + ret = hbg_hw_dev_specs_init(priv); 259 + if (ret) 260 + return ret; 261 + 262 + hbg_reg_write_field(priv, HBG_REG_BUS_CTRL_ADDR, 263 + HBG_REG_BUS_CTRL_ENDIAN_M, 264 + HBG_ENDIAN_CTRL_LE_DATA_BE); 265 + hbg_reg_write_field(priv, HBG_REG_MODE_CHANGE_EN_ADDR, 266 + HBG_REG_MODE_CHANGE_EN_B, HBG_STATUS_ENABLE); 267 + 268 + hbg_hw_init_rx_control(priv); 269 + hbg_hw_init_transmit_ctrl(priv); 270 + return 0; 271 + }
+59
drivers/net/ethernet/hisilicon/hibmcge/hbg_hw.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 + /* Copyright (c) 2024 Hisilicon Limited. */ 3 + 4 + #ifndef __HBG_HW_H 5 + #define __HBG_HW_H 6 + 7 + #include <linux/bitfield.h> 8 + #include <linux/io-64-nonatomic-lo-hi.h> 9 + 10 + static inline u32 hbg_reg_read(struct hbg_priv *priv, u32 addr) 11 + { 12 + return readl(priv->io_base + addr); 13 + } 14 + 15 + static inline void hbg_reg_write(struct hbg_priv *priv, u32 addr, u32 value) 16 + { 17 + writel(value, priv->io_base + addr); 18 + } 19 + 20 + static inline u64 hbg_reg_read64(struct hbg_priv *priv, u32 addr) 21 + { 22 + return lo_hi_readq(priv->io_base + addr); 23 + } 24 + 25 + static inline void hbg_reg_write64(struct hbg_priv *priv, u32 addr, u64 value) 26 + { 27 + lo_hi_writeq(value, priv->io_base + addr); 28 + } 29 + 30 + #define hbg_reg_read_field(priv, addr, mask) \ 31 + FIELD_GET(mask, hbg_reg_read(priv, addr)) 32 + 33 + #define hbg_field_modify(reg_value, mask, value) ({ \ 34 + (reg_value) &= ~(mask); \ 35 + (reg_value) |= FIELD_PREP(mask, value); }) 36 + 37 + #define hbg_reg_write_field(priv, addr, mask, val) ({ \ 38 + typeof(priv) _priv = (priv); \ 39 + typeof(addr) _addr = (addr); \ 40 + u32 _value = hbg_reg_read(_priv, _addr); \ 41 + hbg_field_modify(_value, mask, val); \ 42 + hbg_reg_write(_priv, _addr, _value); }) 43 + 44 + int hbg_hw_event_notify(struct hbg_priv *priv, 45 + enum hbg_hw_event_type event_type); 46 + int hbg_hw_init(struct hbg_priv *priv); 47 + void hbg_hw_adjust_link(struct hbg_priv *priv, u32 speed, u32 duplex); 48 + u32 hbg_hw_get_irq_status(struct hbg_priv *priv); 49 + void hbg_hw_irq_clear(struct hbg_priv *priv, u32 mask); 50 + bool hbg_hw_irq_is_enabled(struct hbg_priv *priv, u32 mask); 51 + void hbg_hw_irq_enable(struct hbg_priv *priv, u32 mask, bool enable); 52 + void hbg_hw_set_mtu(struct hbg_priv *priv, u16 mtu); 53 + void hbg_hw_mac_enable(struct hbg_priv *priv, u32 enable); 54 + void hbg_hw_set_uc_addr(struct hbg_priv *priv, u64 mac_addr); 55 + u32 hbg_hw_get_fifo_used_num(struct hbg_priv *priv, enum hbg_dir dir); 56 + void hbg_hw_set_tx_desc(struct hbg_priv *priv, struct hbg_tx_desc *tx_desc); 57 + void hbg_hw_fill_buffer(struct hbg_priv *priv, u32 buffer_dma_addr); 58 + 59 + #endif
+127
drivers/net/ethernet/hisilicon/hibmcge/hbg_irq.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + // Copyright (c) 2024 Hisilicon Limited. 3 + 4 + #include <linux/interrupt.h> 5 + #include "hbg_irq.h" 6 + #include "hbg_hw.h" 7 + 8 + static void hbg_irq_handle_err(struct hbg_priv *priv, 9 + struct hbg_irq_info *irq_info) 10 + { 11 + if (irq_info->need_print) 12 + dev_err(&priv->pdev->dev, 13 + "receive error interrupt: %s\n", irq_info->name); 14 + } 15 + 16 + static void hbg_irq_handle_tx(struct hbg_priv *priv, 17 + struct hbg_irq_info *irq_info) 18 + { 19 + napi_schedule(&priv->tx_ring.napi); 20 + } 21 + 22 + static void hbg_irq_handle_rx(struct hbg_priv *priv, 23 + struct hbg_irq_info *irq_info) 24 + { 25 + napi_schedule(&priv->rx_ring.napi); 26 + } 27 + 28 + #define HBG_TXRX_IRQ_I(name, handle) \ 29 + {#name, HBG_INT_MSK_##name##_B, false, false, 0, handle} 30 + #define HBG_ERR_IRQ_I(name, need_print) \ 31 + {#name, HBG_INT_MSK_##name##_B, true, need_print, 0, hbg_irq_handle_err} 32 + 33 + static struct hbg_irq_info hbg_irqs[] = { 34 + HBG_TXRX_IRQ_I(RX, hbg_irq_handle_rx), 35 + HBG_TXRX_IRQ_I(TX, hbg_irq_handle_tx), 36 + HBG_ERR_IRQ_I(MAC_MII_FIFO_ERR, true), 37 + HBG_ERR_IRQ_I(MAC_PCS_RX_FIFO_ERR, true), 38 + HBG_ERR_IRQ_I(MAC_PCS_TX_FIFO_ERR, true), 39 + HBG_ERR_IRQ_I(MAC_APP_RX_FIFO_ERR, true), 40 + HBG_ERR_IRQ_I(MAC_APP_TX_FIFO_ERR, true), 41 + HBG_ERR_IRQ_I(SRAM_PARITY_ERR, true), 42 + HBG_ERR_IRQ_I(TX_AHB_ERR, true), 43 + HBG_ERR_IRQ_I(RX_BUF_AVL, false), 44 + HBG_ERR_IRQ_I(REL_BUF_ERR, true), 45 + HBG_ERR_IRQ_I(TXCFG_AVL, false), 46 + HBG_ERR_IRQ_I(TX_DROP, false), 47 + HBG_ERR_IRQ_I(RX_DROP, false), 48 + HBG_ERR_IRQ_I(RX_AHB_ERR, true), 49 + HBG_ERR_IRQ_I(MAC_FIFO_ERR, false), 50 + HBG_ERR_IRQ_I(RBREQ_ERR, false), 51 + HBG_ERR_IRQ_I(WE_ERR, false), 52 + }; 53 + 54 + static irqreturn_t hbg_irq_handle(int irq_num, void *p) 55 + { 56 + struct hbg_irq_info *info; 57 + struct hbg_priv *priv = p; 58 + u32 status; 59 + u32 i; 60 + 61 + status = hbg_hw_get_irq_status(priv); 62 + for (i = 0; i < priv->vectors.info_array_len; i++) { 63 + info = &priv->vectors.info_array[i]; 64 + if (status & info->mask) { 65 + if (!hbg_hw_irq_is_enabled(priv, info->mask)) 66 + continue; 67 + 68 + hbg_hw_irq_enable(priv, info->mask, false); 69 + hbg_hw_irq_clear(priv, info->mask); 70 + 71 + info->count++; 72 + if (info->irq_handle) 73 + info->irq_handle(priv, info); 74 + 75 + if (info->re_enable) 76 + hbg_hw_irq_enable(priv, info->mask, true); 77 + } 78 + } 79 + 80 + return IRQ_HANDLED; 81 + } 82 + 83 + static const char *irq_names_map[HBG_VECTOR_NUM] = { "tx", "rx", 84 + "err", "mdio" }; 85 + 86 + int hbg_irq_init(struct hbg_priv *priv) 87 + { 88 + struct hbg_vector *vectors = &priv->vectors; 89 + struct device *dev = &priv->pdev->dev; 90 + int ret, id; 91 + u32 i; 92 + 93 + /* used pcim_enable_device(), so the vectors become device managed */ 94 + ret = pci_alloc_irq_vectors(priv->pdev, HBG_VECTOR_NUM, HBG_VECTOR_NUM, 95 + PCI_IRQ_MSI | PCI_IRQ_MSIX); 96 + if (ret < 0) 97 + return dev_err_probe(dev, ret, "failed to allocate vectors\n"); 98 + 99 + if (ret != HBG_VECTOR_NUM) 100 + return dev_err_probe(dev, -EINVAL, 101 + "requested %u MSI, but allocated %d MSI\n", 102 + HBG_VECTOR_NUM, ret); 103 + 104 + /* mdio irq not requested, so the number of requested interrupts 105 + * is HBG_VECTOR_NUM - 1. 106 + */ 107 + for (i = 0; i < HBG_VECTOR_NUM - 1; i++) { 108 + id = pci_irq_vector(priv->pdev, i); 109 + if (id < 0) 110 + return dev_err_probe(dev, id, "failed to get irq id\n"); 111 + 112 + snprintf(vectors->name[i], sizeof(vectors->name[i]), "%s-%s-%s", 113 + dev_driver_string(dev), pci_name(priv->pdev), 114 + irq_names_map[i]); 115 + 116 + ret = devm_request_irq(dev, id, hbg_irq_handle, 0, 117 + vectors->name[i], priv); 118 + if (ret) 119 + return dev_err_probe(dev, ret, 120 + "failed to request irq: %s\n", 121 + irq_names_map[i]); 122 + } 123 + 124 + vectors->info_array = hbg_irqs; 125 + vectors->info_array_len = ARRAY_SIZE(hbg_irqs); 126 + return 0; 127 + }
+11
drivers/net/ethernet/hisilicon/hibmcge/hbg_irq.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 + /* Copyright (c) 2024 Hisilicon Limited. */ 3 + 4 + #ifndef __HBG_IRQ_H 5 + #define __HBG_IRQ_H 6 + 7 + #include "hbg_common.h" 8 + 9 + int hbg_irq_init(struct hbg_priv *priv); 10 + 11 + #endif
+253
drivers/net/ethernet/hisilicon/hibmcge/hbg_main.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + // Copyright (c) 2024 Hisilicon Limited. 3 + 4 + #include <linux/etherdevice.h> 5 + #include <linux/if_vlan.h> 6 + #include <linux/netdevice.h> 7 + #include <linux/pci.h> 8 + #include "hbg_common.h" 9 + #include "hbg_ethtool.h" 10 + #include "hbg_hw.h" 11 + #include "hbg_irq.h" 12 + #include "hbg_mdio.h" 13 + #include "hbg_txrx.h" 14 + 15 + static void hbg_change_mtu(struct hbg_priv *priv, int new_mtu); 16 + 17 + static void hbg_all_irq_enable(struct hbg_priv *priv, bool enabled) 18 + { 19 + struct hbg_irq_info *info; 20 + u32 i; 21 + 22 + for (i = 0; i < priv->vectors.info_array_len; i++) { 23 + info = &priv->vectors.info_array[i]; 24 + hbg_hw_irq_enable(priv, info->mask, enabled); 25 + } 26 + } 27 + 28 + static int hbg_net_open(struct net_device *netdev) 29 + { 30 + struct hbg_priv *priv = netdev_priv(netdev); 31 + int ret; 32 + 33 + ret = hbg_txrx_init(priv); 34 + if (ret) 35 + return ret; 36 + 37 + hbg_all_irq_enable(priv, true); 38 + hbg_hw_mac_enable(priv, HBG_STATUS_ENABLE); 39 + netif_start_queue(netdev); 40 + hbg_phy_start(priv); 41 + 42 + return 0; 43 + } 44 + 45 + /* This function only can be called after hbg_txrx_uninit() */ 46 + static int hbg_hw_txrx_clear(struct hbg_priv *priv) 47 + { 48 + int ret; 49 + 50 + /* After ring buffers have been released, 51 + * do a reset to release hw fifo rx ring buffer 52 + */ 53 + ret = hbg_hw_event_notify(priv, HBG_HW_EVENT_RESET); 54 + if (ret) 55 + return ret; 56 + 57 + /* After reset, regs need to be reconfigured */ 58 + hbg_hw_init(priv); 59 + hbg_hw_set_uc_addr(priv, ether_addr_to_u64(priv->netdev->dev_addr)); 60 + hbg_change_mtu(priv, priv->netdev->mtu); 61 + 62 + return 0; 63 + } 64 + 65 + static int hbg_net_stop(struct net_device *netdev) 66 + { 67 + struct hbg_priv *priv = netdev_priv(netdev); 68 + 69 + hbg_phy_stop(priv); 70 + netif_stop_queue(netdev); 71 + hbg_hw_mac_enable(priv, HBG_STATUS_DISABLE); 72 + hbg_all_irq_enable(priv, false); 73 + hbg_txrx_uninit(priv); 74 + return hbg_hw_txrx_clear(priv); 75 + } 76 + 77 + static int hbg_net_set_mac_address(struct net_device *netdev, void *addr) 78 + { 79 + struct hbg_priv *priv = netdev_priv(netdev); 80 + u8 *mac_addr; 81 + 82 + mac_addr = ((struct sockaddr *)addr)->sa_data; 83 + 84 + if (!is_valid_ether_addr(mac_addr)) 85 + return -EADDRNOTAVAIL; 86 + 87 + hbg_hw_set_uc_addr(priv, ether_addr_to_u64(mac_addr)); 88 + dev_addr_set(netdev, mac_addr); 89 + 90 + return 0; 91 + } 92 + 93 + static void hbg_change_mtu(struct hbg_priv *priv, int new_mtu) 94 + { 95 + u32 frame_len; 96 + 97 + frame_len = new_mtu + VLAN_HLEN * priv->dev_specs.vlan_layers + 98 + ETH_HLEN + ETH_FCS_LEN; 99 + hbg_hw_set_mtu(priv, frame_len); 100 + } 101 + 102 + static int hbg_net_change_mtu(struct net_device *netdev, int new_mtu) 103 + { 104 + struct hbg_priv *priv = netdev_priv(netdev); 105 + 106 + if (netif_running(netdev)) 107 + return -EBUSY; 108 + 109 + hbg_change_mtu(priv, new_mtu); 110 + WRITE_ONCE(netdev->mtu, new_mtu); 111 + 112 + dev_dbg(&priv->pdev->dev, 113 + "change mtu from %u to %u\n", netdev->mtu, new_mtu); 114 + 115 + return 0; 116 + } 117 + 118 + static void hbg_net_tx_timeout(struct net_device *netdev, unsigned int txqueue) 119 + { 120 + struct hbg_priv *priv = netdev_priv(netdev); 121 + struct hbg_ring *ring = &priv->tx_ring; 122 + char *buf = ring->tout_log_buf; 123 + u32 pos = 0; 124 + 125 + pos += scnprintf(buf + pos, HBG_TX_TIMEOUT_BUF_LEN - pos, 126 + "ring used num: %u, fifo used num: %u\n", 127 + hbg_get_queue_used_num(ring), 128 + hbg_hw_get_fifo_used_num(priv, HBG_DIR_TX)); 129 + pos += scnprintf(buf + pos, HBG_TX_TIMEOUT_BUF_LEN - pos, 130 + "ntc: %u, ntu: %u, irq enabled: %u\n", 131 + ring->ntc, ring->ntu, 132 + hbg_hw_irq_is_enabled(priv, HBG_INT_MSK_TX_B)); 133 + 134 + netdev_info(netdev, "%s", buf); 135 + } 136 + 137 + static const struct net_device_ops hbg_netdev_ops = { 138 + .ndo_open = hbg_net_open, 139 + .ndo_stop = hbg_net_stop, 140 + .ndo_start_xmit = hbg_net_start_xmit, 141 + .ndo_validate_addr = eth_validate_addr, 142 + .ndo_set_mac_address = hbg_net_set_mac_address, 143 + .ndo_change_mtu = hbg_net_change_mtu, 144 + .ndo_tx_timeout = hbg_net_tx_timeout, 145 + }; 146 + 147 + static int hbg_init(struct hbg_priv *priv) 148 + { 149 + int ret; 150 + 151 + ret = hbg_hw_event_notify(priv, HBG_HW_EVENT_INIT); 152 + if (ret) 153 + return ret; 154 + 155 + ret = hbg_hw_init(priv); 156 + if (ret) 157 + return ret; 158 + 159 + ret = hbg_irq_init(priv); 160 + if (ret) 161 + return ret; 162 + 163 + return hbg_mdio_init(priv); 164 + } 165 + 166 + static int hbg_pci_init(struct pci_dev *pdev) 167 + { 168 + struct net_device *netdev = pci_get_drvdata(pdev); 169 + struct hbg_priv *priv = netdev_priv(netdev); 170 + struct device *dev = &pdev->dev; 171 + int ret; 172 + 173 + ret = pcim_enable_device(pdev); 174 + if (ret) 175 + return dev_err_probe(dev, ret, "failed to enable PCI device\n"); 176 + 177 + ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); 178 + if (ret) 179 + return dev_err_probe(dev, ret, "failed to set PCI DMA mask\n"); 180 + 181 + ret = pcim_iomap_regions(pdev, BIT(0), dev_driver_string(dev)); 182 + if (ret) 183 + return dev_err_probe(dev, ret, "failed to map PCI bar space\n"); 184 + 185 + priv->io_base = pcim_iomap_table(pdev)[0]; 186 + if (!priv->io_base) 187 + return dev_err_probe(dev, -ENOMEM, "failed to get io base\n"); 188 + 189 + pci_set_master(pdev); 190 + return 0; 191 + } 192 + 193 + static int hbg_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 194 + { 195 + struct device *dev = &pdev->dev; 196 + struct net_device *netdev; 197 + struct hbg_priv *priv; 198 + int ret; 199 + 200 + netdev = devm_alloc_etherdev(dev, sizeof(struct hbg_priv)); 201 + if (!netdev) 202 + return -ENOMEM; 203 + 204 + pci_set_drvdata(pdev, netdev); 205 + SET_NETDEV_DEV(netdev, dev); 206 + 207 + priv = netdev_priv(netdev); 208 + priv->netdev = netdev; 209 + priv->pdev = pdev; 210 + 211 + ret = hbg_pci_init(pdev); 212 + if (ret) 213 + return ret; 214 + 215 + ret = hbg_init(priv); 216 + if (ret) 217 + return ret; 218 + 219 + netdev->pcpu_stat_type = NETDEV_PCPU_STAT_TSTATS; 220 + netdev->max_mtu = priv->dev_specs.max_mtu; 221 + netdev->min_mtu = priv->dev_specs.min_mtu; 222 + netdev->netdev_ops = &hbg_netdev_ops; 223 + netdev->watchdog_timeo = 5 * HZ; 224 + 225 + hbg_change_mtu(priv, ETH_DATA_LEN); 226 + hbg_net_set_mac_address(priv->netdev, &priv->dev_specs.mac_addr); 227 + hbg_ethtool_set_ops(netdev); 228 + 229 + ret = devm_register_netdev(dev, netdev); 230 + if (ret) 231 + return dev_err_probe(dev, ret, "failed to register netdev\n"); 232 + 233 + netif_carrier_off(netdev); 234 + return 0; 235 + } 236 + 237 + static const struct pci_device_id hbg_pci_tbl[] = { 238 + {PCI_VDEVICE(HUAWEI, 0x3730), 0}, 239 + { } 240 + }; 241 + MODULE_DEVICE_TABLE(pci, hbg_pci_tbl); 242 + 243 + static struct pci_driver hbg_driver = { 244 + .name = "hibmcge", 245 + .id_table = hbg_pci_tbl, 246 + .probe = hbg_probe, 247 + }; 248 + module_pci_driver(hbg_driver); 249 + 250 + MODULE_LICENSE("GPL"); 251 + MODULE_AUTHOR("Huawei Tech. Co., Ltd."); 252 + MODULE_DESCRIPTION("hibmcge driver"); 253 + MODULE_VERSION("1.0");
+222
drivers/net/ethernet/hisilicon/hibmcge/hbg_mdio.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + // Copyright (c) 2024 Hisilicon Limited. 3 + 4 + #include <linux/phy.h> 5 + #include "hbg_common.h" 6 + #include "hbg_hw.h" 7 + #include "hbg_mdio.h" 8 + #include "hbg_reg.h" 9 + 10 + #define HBG_MAC_GET_PRIV(mac) ((struct hbg_priv *)(mac)->mdio_bus->priv) 11 + #define HBG_MII_BUS_GET_MAC(bus) (&((struct hbg_priv *)(bus)->priv)->mac) 12 + 13 + #define HBG_MDIO_C22_MODE 0x1 14 + #define HBG_MDIO_C22_REG_WRITE 0x1 15 + #define HBG_MDIO_C22_REG_READ 0x2 16 + 17 + #define HBG_MDIO_OP_TIMEOUT_US (1 * 1000 * 1000) 18 + #define HBG_MDIO_OP_INTERVAL_US (5 * 1000) 19 + 20 + static void hbg_mdio_set_command(struct hbg_mac *mac, u32 cmd) 21 + { 22 + hbg_reg_write(HBG_MAC_GET_PRIV(mac), HBG_REG_MDIO_COMMAND_ADDR, cmd); 23 + } 24 + 25 + static void hbg_mdio_get_command(struct hbg_mac *mac, u32 *cmd) 26 + { 27 + *cmd = hbg_reg_read(HBG_MAC_GET_PRIV(mac), HBG_REG_MDIO_COMMAND_ADDR); 28 + } 29 + 30 + static void hbg_mdio_set_wdata_reg(struct hbg_mac *mac, u16 wdata_value) 31 + { 32 + hbg_reg_write_field(HBG_MAC_GET_PRIV(mac), HBG_REG_MDIO_WDATA_ADDR, 33 + HBG_REG_MDIO_WDATA_M, wdata_value); 34 + } 35 + 36 + static u32 hbg_mdio_get_rdata_reg(struct hbg_mac *mac) 37 + { 38 + return hbg_reg_read_field(HBG_MAC_GET_PRIV(mac), 39 + HBG_REG_MDIO_RDATA_ADDR, 40 + HBG_REG_MDIO_WDATA_M); 41 + } 42 + 43 + static int hbg_mdio_wait_ready(struct hbg_mac *mac) 44 + { 45 + struct hbg_priv *priv = HBG_MAC_GET_PRIV(mac); 46 + u32 cmd = 0; 47 + int ret; 48 + 49 + ret = readl_poll_timeout(priv->io_base + HBG_REG_MDIO_COMMAND_ADDR, cmd, 50 + !FIELD_GET(HBG_REG_MDIO_COMMAND_START_B, cmd), 51 + HBG_MDIO_OP_INTERVAL_US, 52 + HBG_MDIO_OP_TIMEOUT_US); 53 + 54 + return ret ? -ETIMEDOUT : 0; 55 + } 56 + 57 + static int hbg_mdio_cmd_send(struct hbg_mac *mac, u32 prt_addr, u32 dev_addr, 58 + u32 type, u32 op_code) 59 + { 60 + u32 cmd = 0; 61 + 62 + hbg_mdio_get_command(mac, &cmd); 63 + hbg_field_modify(cmd, HBG_REG_MDIO_COMMAND_ST_M, type); 64 + hbg_field_modify(cmd, HBG_REG_MDIO_COMMAND_OP_M, op_code); 65 + hbg_field_modify(cmd, HBG_REG_MDIO_COMMAND_PRTAD_M, prt_addr); 66 + hbg_field_modify(cmd, HBG_REG_MDIO_COMMAND_DEVAD_M, dev_addr); 67 + 68 + /* if auto scan enabled, this value need fix to 0 */ 69 + hbg_field_modify(cmd, HBG_REG_MDIO_COMMAND_START_B, 0x1); 70 + 71 + hbg_mdio_set_command(mac, cmd); 72 + 73 + /* wait operation complete and check the result */ 74 + return hbg_mdio_wait_ready(mac); 75 + } 76 + 77 + static int hbg_mdio_read22(struct mii_bus *bus, int phy_addr, int regnum) 78 + { 79 + struct hbg_mac *mac = HBG_MII_BUS_GET_MAC(bus); 80 + int ret; 81 + 82 + ret = hbg_mdio_cmd_send(mac, phy_addr, regnum, HBG_MDIO_C22_MODE, 83 + HBG_MDIO_C22_REG_READ); 84 + if (ret) 85 + return ret; 86 + 87 + return hbg_mdio_get_rdata_reg(mac); 88 + } 89 + 90 + static int hbg_mdio_write22(struct mii_bus *bus, int phy_addr, int regnum, 91 + u16 val) 92 + { 93 + struct hbg_mac *mac = HBG_MII_BUS_GET_MAC(bus); 94 + 95 + hbg_mdio_set_wdata_reg(mac, val); 96 + return hbg_mdio_cmd_send(mac, phy_addr, regnum, HBG_MDIO_C22_MODE, 97 + HBG_MDIO_C22_REG_WRITE); 98 + } 99 + 100 + static void hbg_mdio_init_hw(struct hbg_priv *priv) 101 + { 102 + u32 freq = priv->dev_specs.mdio_frequency; 103 + struct hbg_mac *mac = &priv->mac; 104 + u32 cmd = 0; 105 + 106 + cmd |= FIELD_PREP(HBG_REG_MDIO_COMMAND_ST_M, HBG_MDIO_C22_MODE); 107 + cmd |= FIELD_PREP(HBG_REG_MDIO_COMMAND_AUTO_SCAN_B, HBG_STATUS_DISABLE); 108 + 109 + /* freq use two bits, which are stored in clk_sel and clk_sel_exp */ 110 + cmd |= FIELD_PREP(HBG_REG_MDIO_COMMAND_CLK_SEL_B, freq & 0x1); 111 + cmd |= FIELD_PREP(HBG_REG_MDIO_COMMAND_CLK_SEL_EXP_B, 112 + (freq >> 1) & 0x1); 113 + 114 + hbg_mdio_set_command(mac, cmd); 115 + } 116 + 117 + static void hbg_phy_adjust_link(struct net_device *netdev) 118 + { 119 + struct hbg_priv *priv = netdev_priv(netdev); 120 + struct phy_device *phydev = netdev->phydev; 121 + u32 speed; 122 + 123 + if (phydev->link != priv->mac.link_status) { 124 + if (phydev->link) { 125 + switch (phydev->speed) { 126 + case SPEED_10: 127 + speed = HBG_PORT_MODE_SGMII_10M; 128 + break; 129 + case SPEED_100: 130 + speed = HBG_PORT_MODE_SGMII_100M; 131 + break; 132 + case SPEED_1000: 133 + speed = HBG_PORT_MODE_SGMII_1000M; 134 + break; 135 + default: 136 + return; 137 + } 138 + 139 + priv->mac.speed = speed; 140 + priv->mac.duplex = phydev->duplex; 141 + priv->mac.autoneg = phydev->autoneg; 142 + hbg_hw_adjust_link(priv, speed, phydev->duplex); 143 + } 144 + 145 + priv->mac.link_status = phydev->link; 146 + phy_print_status(phydev); 147 + } 148 + } 149 + 150 + static void hbg_phy_disconnect(void *data) 151 + { 152 + phy_disconnect((struct phy_device *)data); 153 + } 154 + 155 + static int hbg_phy_connect(struct hbg_priv *priv) 156 + { 157 + struct phy_device *phydev = priv->mac.phydev; 158 + struct device *dev = &priv->pdev->dev; 159 + int ret; 160 + 161 + ret = phy_connect_direct(priv->netdev, phydev, hbg_phy_adjust_link, 162 + PHY_INTERFACE_MODE_SGMII); 163 + if (ret) 164 + return dev_err_probe(dev, ret, "failed to connect phy\n"); 165 + 166 + ret = devm_add_action_or_reset(dev, hbg_phy_disconnect, phydev); 167 + if (ret) 168 + return ret; 169 + 170 + phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_1000baseT_Half_BIT); 171 + phy_attached_info(phydev); 172 + 173 + return 0; 174 + } 175 + 176 + void hbg_phy_start(struct hbg_priv *priv) 177 + { 178 + phy_start(priv->mac.phydev); 179 + } 180 + 181 + void hbg_phy_stop(struct hbg_priv *priv) 182 + { 183 + phy_stop(priv->mac.phydev); 184 + } 185 + 186 + int hbg_mdio_init(struct hbg_priv *priv) 187 + { 188 + struct device *dev = &priv->pdev->dev; 189 + struct hbg_mac *mac = &priv->mac; 190 + struct phy_device *phydev; 191 + struct mii_bus *mdio_bus; 192 + int ret; 193 + 194 + mac->phy_addr = priv->dev_specs.phy_addr; 195 + mdio_bus = devm_mdiobus_alloc(dev); 196 + if (!mdio_bus) 197 + return dev_err_probe(dev, -ENOMEM, 198 + "failed to alloc MDIO bus\n"); 199 + 200 + mdio_bus->parent = dev; 201 + mdio_bus->priv = priv; 202 + mdio_bus->phy_mask = ~(1 << mac->phy_addr); 203 + mdio_bus->name = "hibmcge mii bus"; 204 + mac->mdio_bus = mdio_bus; 205 + 206 + mdio_bus->read = hbg_mdio_read22; 207 + mdio_bus->write = hbg_mdio_write22; 208 + snprintf(mdio_bus->id, MII_BUS_ID_SIZE, "%s-%s", "mii", dev_name(dev)); 209 + 210 + ret = devm_mdiobus_register(dev, mdio_bus); 211 + if (ret) 212 + return dev_err_probe(dev, ret, "failed to register MDIO bus\n"); 213 + 214 + phydev = mdiobus_get_phy(mdio_bus, mac->phy_addr); 215 + if (!phydev) 216 + return dev_err_probe(dev, -ENODEV, 217 + "failed to get phy device\n"); 218 + 219 + mac->phydev = phydev; 220 + hbg_mdio_init_hw(priv); 221 + return hbg_phy_connect(priv); 222 + }
+12
drivers/net/ethernet/hisilicon/hibmcge/hbg_mdio.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 + /* Copyright (c) 2024 Hisilicon Limited. */ 3 + 4 + #ifndef __HBG_MDIO_H 5 + #define __HBG_MDIO_H 6 + 7 + #include "hbg_common.h" 8 + 9 + int hbg_mdio_init(struct hbg_priv *priv); 10 + void hbg_phy_start(struct hbg_priv *priv); 11 + void hbg_phy_stop(struct hbg_priv *priv); 12 + #endif
+143
drivers/net/ethernet/hisilicon/hibmcge/hbg_reg.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 + /* Copyright (c) 2024 Hisilicon Limited. */ 3 + 4 + #ifndef __HBG_REG_H 5 + #define __HBG_REG_H 6 + 7 + /* DEV SPEC */ 8 + #define HBG_REG_SPEC_VALID_ADDR 0x0000 9 + #define HBG_REG_EVENT_REQ_ADDR 0x0004 10 + #define HBG_REG_MAC_ID_ADDR 0x0008 11 + #define HBG_REG_PHY_ID_ADDR 0x000C 12 + #define HBG_REG_MAC_ADDR_ADDR 0x0010 13 + #define HBG_REG_MDIO_FREQ_ADDR 0x0024 14 + #define HBG_REG_MAX_MTU_ADDR 0x0028 15 + #define HBG_REG_MIN_MTU_ADDR 0x002C 16 + #define HBG_REG_TX_FIFO_NUM_ADDR 0x0030 17 + #define HBG_REG_RX_FIFO_NUM_ADDR 0x0034 18 + #define HBG_REG_VLAN_LAYERS_ADDR 0x0038 19 + 20 + /* MDIO */ 21 + #define HBG_REG_MDIO_BASE 0x8000 22 + #define HBG_REG_MDIO_COMMAND_ADDR (HBG_REG_MDIO_BASE + 0x0000) 23 + #define HBG_REG_MDIO_COMMAND_CLK_SEL_EXP_B BIT(17) 24 + #define HBG_REG_MDIO_COMMAND_AUTO_SCAN_B BIT(16) 25 + #define HBG_REG_MDIO_COMMAND_CLK_SEL_B BIT(15) 26 + #define HBG_REG_MDIO_COMMAND_START_B BIT(14) 27 + #define HBG_REG_MDIO_COMMAND_ST_M GENMASK(13, 12) 28 + #define HBG_REG_MDIO_COMMAND_OP_M GENMASK(11, 10) 29 + #define HBG_REG_MDIO_COMMAND_PRTAD_M GENMASK(9, 5) 30 + #define HBG_REG_MDIO_COMMAND_DEVAD_M GENMASK(4, 0) 31 + #define HBG_REG_MDIO_WDATA_ADDR (HBG_REG_MDIO_BASE + 0x0008) 32 + #define HBG_REG_MDIO_WDATA_M GENMASK(15, 0) 33 + #define HBG_REG_MDIO_RDATA_ADDR (HBG_REG_MDIO_BASE + 0x000C) 34 + #define HBG_REG_MDIO_STA_ADDR (HBG_REG_MDIO_BASE + 0x0010) 35 + 36 + /* GMAC */ 37 + #define HBG_REG_SGMII_BASE 0x10000 38 + #define HBG_REG_DUPLEX_TYPE_ADDR (HBG_REG_SGMII_BASE + 0x0008) 39 + #define HBG_REG_DUPLEX_B BIT(0) 40 + #define HBG_REG_MAX_FRAME_SIZE_ADDR (HBG_REG_SGMII_BASE + 0x003C) 41 + #define HBG_REG_PORT_MODE_ADDR (HBG_REG_SGMII_BASE + 0x0040) 42 + #define HBG_REG_PORT_MODE_M GENMASK(3, 0) 43 + #define HBG_REG_PORT_ENABLE_ADDR (HBG_REG_SGMII_BASE + 0x0044) 44 + #define HBG_REG_PORT_ENABLE_RX_B BIT(1) 45 + #define HBG_REG_PORT_ENABLE_TX_B BIT(2) 46 + #define HBG_REG_TRANSMIT_CTRL_ADDR (HBG_REG_SGMII_BASE + 0x0060) 47 + #define HBG_REG_TRANSMIT_CTRL_PAD_EN_B BIT(7) 48 + #define HBG_REG_TRANSMIT_CTRL_CRC_ADD_B BIT(6) 49 + #define HBG_REG_TRANSMIT_CTRL_AN_EN_B BIT(5) 50 + #define HBG_REG_CF_CRC_STRIP_ADDR (HBG_REG_SGMII_BASE + 0x01B0) 51 + #define HBG_REG_CF_CRC_STRIP_B BIT(0) 52 + #define HBG_REG_MODE_CHANGE_EN_ADDR (HBG_REG_SGMII_BASE + 0x01B4) 53 + #define HBG_REG_MODE_CHANGE_EN_B BIT(0) 54 + #define HBG_REG_RECV_CTRL_ADDR (HBG_REG_SGMII_BASE + 0x01E0) 55 + #define HBG_REG_RECV_CTRL_STRIP_PAD_EN_B BIT(3) 56 + #define HBG_REG_STATION_ADDR_LOW_2_ADDR (HBG_REG_SGMII_BASE + 0x0210) 57 + #define HBG_REG_STATION_ADDR_HIGH_2_ADDR (HBG_REG_SGMII_BASE + 0x0214) 58 + 59 + /* PCU */ 60 + #define HBG_REG_CF_INTRPT_MSK_ADDR (HBG_REG_SGMII_BASE + 0x042C) 61 + #define HBG_INT_MSK_WE_ERR_B BIT(31) 62 + #define HBG_INT_MSK_RBREQ_ERR_B BIT(30) 63 + #define HBG_INT_MSK_MAC_FIFO_ERR_B BIT(29) 64 + #define HBG_INT_MSK_RX_AHB_ERR_B BIT(28) 65 + #define HBG_INT_MSK_RX_DROP_B BIT(26) 66 + #define HBG_INT_MSK_TX_DROP_B BIT(25) 67 + #define HBG_INT_MSK_TXCFG_AVL_B BIT(24) 68 + #define HBG_INT_MSK_REL_BUF_ERR_B BIT(23) 69 + #define HBG_INT_MSK_RX_BUF_AVL_B BIT(22) 70 + #define HBG_INT_MSK_TX_AHB_ERR_B BIT(21) 71 + #define HBG_INT_MSK_SRAM_PARITY_ERR_B BIT(20) 72 + #define HBG_INT_MSK_MAC_APP_TX_FIFO_ERR_B BIT(19) 73 + #define HBG_INT_MSK_MAC_APP_RX_FIFO_ERR_B BIT(18) 74 + #define HBG_INT_MSK_MAC_PCS_TX_FIFO_ERR_B BIT(17) 75 + #define HBG_INT_MSK_MAC_PCS_RX_FIFO_ERR_B BIT(16) 76 + #define HBG_INT_MSK_MAC_MII_FIFO_ERR_B BIT(15) 77 + #define HBG_INT_MSK_TX_B BIT(1) /* just used in driver */ 78 + #define HBG_INT_MSK_RX_B BIT(0) /* just used in driver */ 79 + #define HBG_REG_CF_INTRPT_STAT_ADDR (HBG_REG_SGMII_BASE + 0x0434) 80 + #define HBG_REG_CF_INTRPT_CLR_ADDR (HBG_REG_SGMII_BASE + 0x0438) 81 + #define HBG_REG_MAX_FRAME_LEN_ADDR (HBG_REG_SGMII_BASE + 0x0444) 82 + #define HBG_REG_MAX_FRAME_LEN_M GENMASK(15, 0) 83 + #define HBG_REG_CF_CFF_DATA_NUM_ADDR (HBG_REG_SGMII_BASE + 0x045C) 84 + #define HBG_REG_CF_CFF_DATA_NUM_ADDR_TX_M GENMASK(8, 0) 85 + #define HBG_REG_CF_CFF_DATA_NUM_ADDR_RX_M GENMASK(24, 16) 86 + #define HBG_REG_TX_CFF_ADDR_0_ADDR (HBG_REG_SGMII_BASE + 0x0488) 87 + #define HBG_REG_TX_CFF_ADDR_1_ADDR (HBG_REG_SGMII_BASE + 0x048C) 88 + #define HBG_REG_TX_CFF_ADDR_2_ADDR (HBG_REG_SGMII_BASE + 0x0490) 89 + #define HBG_REG_TX_CFF_ADDR_3_ADDR (HBG_REG_SGMII_BASE + 0x0494) 90 + #define HBG_REG_RX_CFF_ADDR_ADDR (HBG_REG_SGMII_BASE + 0x04A0) 91 + #define HBG_REG_RX_BUF_SIZE_ADDR (HBG_REG_SGMII_BASE + 0x04E4) 92 + #define HBG_REG_RX_BUF_SIZE_M GENMASK(15, 0) 93 + #define HBG_REG_BUS_CTRL_ADDR (HBG_REG_SGMII_BASE + 0x04E8) 94 + #define HBG_REG_BUS_CTRL_ENDIAN_M GENMASK(2, 1) 95 + #define HBG_REG_RX_CTRL_ADDR (HBG_REG_SGMII_BASE + 0x04F0) 96 + #define HBG_REG_RX_CTRL_RXBUF_1ST_SKIP_SIZE_M GENMASK(31, 28) 97 + #define HBG_REG_RX_CTRL_TIME_INF_EN_B BIT(23) 98 + #define HBG_REG_RX_CTRL_RX_ALIGN_NUM_M GENMASK(18, 17) 99 + #define HBG_REG_RX_CTRL_PORT_NUM GENMASK(16, 13) 100 + #define HBG_REG_RX_CTRL_RX_GET_ADDR_MODE_B BIT(12) 101 + #define HBG_REG_RX_CTRL_RXBUF_1ST_SKIP_SIZE2_M GENMASK(3, 0) 102 + #define HBG_REG_RX_PKT_MODE_ADDR (HBG_REG_SGMII_BASE + 0x04F4) 103 + #define HBG_REG_RX_PKT_MODE_PARSE_MODE_M GENMASK(22, 21) 104 + #define HBG_REG_CF_IND_TXINT_MSK_ADDR (HBG_REG_SGMII_BASE + 0x0694) 105 + #define HBG_REG_IND_INTR_MASK_B BIT(0) 106 + #define HBG_REG_CF_IND_TXINT_STAT_ADDR (HBG_REG_SGMII_BASE + 0x0698) 107 + #define HBG_REG_CF_IND_TXINT_CLR_ADDR (HBG_REG_SGMII_BASE + 0x069C) 108 + #define HBG_REG_CF_IND_RXINT_MSK_ADDR (HBG_REG_SGMII_BASE + 0x06a0) 109 + #define HBG_REG_CF_IND_RXINT_STAT_ADDR (HBG_REG_SGMII_BASE + 0x06a4) 110 + #define HBG_REG_CF_IND_RXINT_CLR_ADDR (HBG_REG_SGMII_BASE + 0x06a8) 111 + 112 + enum hbg_port_mode { 113 + /* 0x0 ~ 0x5 are reserved */ 114 + HBG_PORT_MODE_SGMII_10M = 0x6, 115 + HBG_PORT_MODE_SGMII_100M = 0x7, 116 + HBG_PORT_MODE_SGMII_1000M = 0x8, 117 + }; 118 + 119 + struct hbg_tx_desc { 120 + u32 word0; 121 + u32 word1; 122 + u32 word2; /* pkt_addr */ 123 + u32 word3; /* clear_addr */ 124 + }; 125 + 126 + #define HBG_TX_DESC_W0_IP_OFF_M GENMASK(30, 26) 127 + #define HBG_TX_DESC_W0_l3_CS_B BIT(2) 128 + #define HBG_TX_DESC_W0_WB_B BIT(1) 129 + #define HBG_TX_DESC_W0_l4_CS_B BIT(0) 130 + #define HBG_TX_DESC_W1_SEND_LEN_M GENMASK(19, 4) 131 + 132 + struct hbg_rx_desc { 133 + u32 word0; 134 + u32 word1; /* tag */ 135 + u32 word2; 136 + u32 word3; 137 + u32 word4; 138 + u32 word5; 139 + }; 140 + 141 + #define HBG_RX_DESC_W2_PKT_LEN_M GENMASK(31, 16) 142 + 143 + #endif
+409
drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + // Copyright (c) 2024 Hisilicon Limited. 3 + 4 + #include <net/netdev_queues.h> 5 + #include "hbg_common.h" 6 + #include "hbg_irq.h" 7 + #include "hbg_reg.h" 8 + #include "hbg_txrx.h" 9 + 10 + #define netdev_get_tx_ring(netdev) \ 11 + (&(((struct hbg_priv *)netdev_priv(netdev))->tx_ring)) 12 + 13 + #define buffer_to_dma_dir(buffer) (((buffer)->dir == HBG_DIR_RX) ? \ 14 + DMA_FROM_DEVICE : DMA_TO_DEVICE) 15 + 16 + #define hbg_queue_used_num(head, tail, ring) ({ \ 17 + typeof(ring) _ring = (ring); \ 18 + ((tail) + _ring->len - (head)) % _ring->len; }) 19 + #define hbg_queue_left_num(head, tail, ring) ({ \ 20 + typeof(ring) _r = (ring); \ 21 + _r->len - hbg_queue_used_num((head), (tail), _r) - 1; }) 22 + #define hbg_queue_is_empty(head, tail, ring) \ 23 + (hbg_queue_used_num((head), (tail), (ring)) == 0) 24 + #define hbg_queue_is_full(head, tail, ring) \ 25 + (hbg_queue_left_num((head), (tail), (ring)) == 0) 26 + #define hbg_queue_next_prt(p, ring) (((p) + 1) % (ring)->len) 27 + #define hbg_queue_move_next(p, ring) ({ \ 28 + typeof(ring) _ring = (ring); \ 29 + _ring->p = hbg_queue_next_prt(_ring->p, _ring); }) 30 + 31 + #define HBG_TX_STOP_THRS 2 32 + #define HBG_TX_START_THRS (2 * HBG_TX_STOP_THRS) 33 + 34 + static int hbg_dma_map(struct hbg_buffer *buffer) 35 + { 36 + struct hbg_priv *priv = buffer->priv; 37 + 38 + buffer->skb_dma = dma_map_single(&priv->pdev->dev, 39 + buffer->skb->data, buffer->skb_len, 40 + buffer_to_dma_dir(buffer)); 41 + if (unlikely(dma_mapping_error(&priv->pdev->dev, buffer->skb_dma))) 42 + return -ENOMEM; 43 + 44 + return 0; 45 + } 46 + 47 + static void hbg_dma_unmap(struct hbg_buffer *buffer) 48 + { 49 + struct hbg_priv *priv = buffer->priv; 50 + 51 + if (unlikely(!buffer->skb_dma)) 52 + return; 53 + 54 + dma_unmap_single(&priv->pdev->dev, buffer->skb_dma, buffer->skb_len, 55 + buffer_to_dma_dir(buffer)); 56 + buffer->skb_dma = 0; 57 + } 58 + 59 + static void hbg_init_tx_desc(struct hbg_buffer *buffer, 60 + struct hbg_tx_desc *tx_desc) 61 + { 62 + u32 ip_offset = buffer->skb->network_header - buffer->skb->mac_header; 63 + u32 word0 = 0; 64 + 65 + word0 |= FIELD_PREP(HBG_TX_DESC_W0_WB_B, HBG_STATUS_ENABLE); 66 + word0 |= FIELD_PREP(HBG_TX_DESC_W0_IP_OFF_M, ip_offset); 67 + if (likely(buffer->skb->ip_summed == CHECKSUM_PARTIAL)) { 68 + word0 |= FIELD_PREP(HBG_TX_DESC_W0_l3_CS_B, HBG_STATUS_ENABLE); 69 + word0 |= FIELD_PREP(HBG_TX_DESC_W0_l4_CS_B, HBG_STATUS_ENABLE); 70 + } 71 + 72 + tx_desc->word0 = word0; 73 + tx_desc->word1 = FIELD_PREP(HBG_TX_DESC_W1_SEND_LEN_M, 74 + buffer->skb->len); 75 + tx_desc->word2 = buffer->skb_dma; 76 + tx_desc->word3 = buffer->state_dma; 77 + } 78 + 79 + netdev_tx_t hbg_net_start_xmit(struct sk_buff *skb, struct net_device *netdev) 80 + { 81 + struct hbg_ring *ring = netdev_get_tx_ring(netdev); 82 + struct hbg_priv *priv = netdev_priv(netdev); 83 + /* This smp_load_acquire() pairs with smp_store_release() in 84 + * hbg_napi_tx_recycle() called in tx interrupt handle process. 85 + */ 86 + u32 ntc = smp_load_acquire(&ring->ntc); 87 + struct hbg_buffer *buffer; 88 + struct hbg_tx_desc tx_desc; 89 + u32 ntu = ring->ntu; 90 + 91 + if (unlikely(!skb->len || 92 + skb->len > hbg_spec_max_frame_len(priv, HBG_DIR_TX))) { 93 + dev_kfree_skb_any(skb); 94 + netdev->stats.tx_errors++; 95 + return NETDEV_TX_OK; 96 + } 97 + 98 + if (!netif_subqueue_maybe_stop(netdev, 0, 99 + hbg_queue_left_num(ntc, ntu, ring), 100 + HBG_TX_STOP_THRS, HBG_TX_START_THRS)) 101 + return NETDEV_TX_BUSY; 102 + 103 + buffer = &ring->queue[ntu]; 104 + buffer->skb = skb; 105 + buffer->skb_len = skb->len; 106 + if (unlikely(hbg_dma_map(buffer))) { 107 + dev_kfree_skb_any(skb); 108 + return NETDEV_TX_OK; 109 + } 110 + 111 + buffer->state = HBG_TX_STATE_START; 112 + hbg_init_tx_desc(buffer, &tx_desc); 113 + hbg_hw_set_tx_desc(priv, &tx_desc); 114 + 115 + /* This smp_store_release() pairs with smp_load_acquire() in 116 + * hbg_napi_tx_recycle() called in tx interrupt handle process. 117 + */ 118 + smp_store_release(&ring->ntu, hbg_queue_next_prt(ntu, ring)); 119 + dev_sw_netstats_tx_add(netdev, 1, skb->len); 120 + return NETDEV_TX_OK; 121 + } 122 + 123 + static void hbg_buffer_free_skb(struct hbg_buffer *buffer) 124 + { 125 + if (unlikely(!buffer->skb)) 126 + return; 127 + 128 + dev_kfree_skb_any(buffer->skb); 129 + buffer->skb = NULL; 130 + } 131 + 132 + static int hbg_buffer_alloc_skb(struct hbg_buffer *buffer) 133 + { 134 + u32 len = hbg_spec_max_frame_len(buffer->priv, buffer->dir); 135 + struct hbg_priv *priv = buffer->priv; 136 + 137 + buffer->skb = netdev_alloc_skb(priv->netdev, len); 138 + if (unlikely(!buffer->skb)) 139 + return -ENOMEM; 140 + 141 + buffer->skb_len = len; 142 + memset(buffer->skb->data, 0, HBG_PACKET_HEAD_SIZE); 143 + return 0; 144 + } 145 + 146 + static void hbg_buffer_free(struct hbg_buffer *buffer) 147 + { 148 + hbg_dma_unmap(buffer); 149 + hbg_buffer_free_skb(buffer); 150 + } 151 + 152 + static int hbg_napi_tx_recycle(struct napi_struct *napi, int budget) 153 + { 154 + struct hbg_ring *ring = container_of(napi, struct hbg_ring, napi); 155 + /* This smp_load_acquire() pairs with smp_store_release() in 156 + * hbg_net_start_xmit() called in xmit process. 157 + */ 158 + u32 ntu = smp_load_acquire(&ring->ntu); 159 + struct hbg_priv *priv = ring->priv; 160 + struct hbg_buffer *buffer; 161 + u32 ntc = ring->ntc; 162 + int packet_done = 0; 163 + 164 + /* We need do cleanup even if budget is 0. 165 + * Per NAPI documentation budget is for Rx. 166 + * So We hardcode the amount of work Tx NAPI does to 128. 167 + */ 168 + budget = 128; 169 + while (packet_done < budget) { 170 + if (unlikely(hbg_queue_is_empty(ntc, ntu, ring))) 171 + break; 172 + 173 + /* make sure HW write desc complete */ 174 + dma_rmb(); 175 + 176 + buffer = &ring->queue[ntc]; 177 + if (buffer->state != HBG_TX_STATE_COMPLETE) 178 + break; 179 + 180 + hbg_buffer_free(buffer); 181 + ntc = hbg_queue_next_prt(ntc, ring); 182 + packet_done++; 183 + } 184 + 185 + /* This smp_store_release() pairs with smp_load_acquire() in 186 + * hbg_net_start_xmit() called in xmit process. 187 + */ 188 + smp_store_release(&ring->ntc, ntc); 189 + netif_wake_queue(priv->netdev); 190 + 191 + if (likely(packet_done < budget && 192 + napi_complete_done(napi, packet_done))) 193 + hbg_hw_irq_enable(priv, HBG_INT_MSK_TX_B, true); 194 + 195 + return packet_done; 196 + } 197 + 198 + static int hbg_rx_fill_one_buffer(struct hbg_priv *priv) 199 + { 200 + struct hbg_ring *ring = &priv->rx_ring; 201 + struct hbg_buffer *buffer; 202 + int ret; 203 + 204 + if (hbg_queue_is_full(ring->ntc, ring->ntu, ring)) 205 + return 0; 206 + 207 + buffer = &ring->queue[ring->ntu]; 208 + ret = hbg_buffer_alloc_skb(buffer); 209 + if (unlikely(ret)) 210 + return ret; 211 + 212 + ret = hbg_dma_map(buffer); 213 + if (unlikely(ret)) { 214 + hbg_buffer_free_skb(buffer); 215 + return ret; 216 + } 217 + 218 + hbg_hw_fill_buffer(priv, buffer->skb_dma); 219 + hbg_queue_move_next(ntu, ring); 220 + return 0; 221 + } 222 + 223 + static bool hbg_sync_data_from_hw(struct hbg_priv *priv, 224 + struct hbg_buffer *buffer) 225 + { 226 + struct hbg_rx_desc *rx_desc; 227 + 228 + /* make sure HW write desc complete */ 229 + dma_rmb(); 230 + 231 + dma_sync_single_for_cpu(&priv->pdev->dev, buffer->skb_dma, 232 + buffer->skb_len, DMA_FROM_DEVICE); 233 + 234 + rx_desc = (struct hbg_rx_desc *)buffer->skb->data; 235 + return FIELD_GET(HBG_RX_DESC_W2_PKT_LEN_M, rx_desc->word2) != 0; 236 + } 237 + 238 + static int hbg_napi_rx_poll(struct napi_struct *napi, int budget) 239 + { 240 + struct hbg_ring *ring = container_of(napi, struct hbg_ring, napi); 241 + struct hbg_priv *priv = ring->priv; 242 + struct hbg_rx_desc *rx_desc; 243 + struct hbg_buffer *buffer; 244 + u32 packet_done = 0; 245 + u32 pkt_len; 246 + 247 + while (packet_done < budget) { 248 + if (unlikely(hbg_queue_is_empty(ring->ntc, ring->ntu, ring))) 249 + break; 250 + 251 + buffer = &ring->queue[ring->ntc]; 252 + if (unlikely(!buffer->skb)) 253 + goto next_buffer; 254 + 255 + if (unlikely(!hbg_sync_data_from_hw(priv, buffer))) 256 + break; 257 + rx_desc = (struct hbg_rx_desc *)buffer->skb->data; 258 + pkt_len = FIELD_GET(HBG_RX_DESC_W2_PKT_LEN_M, rx_desc->word2); 259 + 260 + hbg_dma_unmap(buffer); 261 + 262 + skb_reserve(buffer->skb, HBG_PACKET_HEAD_SIZE + NET_IP_ALIGN); 263 + skb_put(buffer->skb, pkt_len); 264 + buffer->skb->protocol = eth_type_trans(buffer->skb, 265 + priv->netdev); 266 + 267 + dev_sw_netstats_rx_add(priv->netdev, pkt_len); 268 + napi_gro_receive(napi, buffer->skb); 269 + buffer->skb = NULL; 270 + 271 + next_buffer: 272 + hbg_rx_fill_one_buffer(priv); 273 + hbg_queue_move_next(ntc, ring); 274 + packet_done++; 275 + } 276 + 277 + if (likely(packet_done < budget && 278 + napi_complete_done(napi, packet_done))) 279 + hbg_hw_irq_enable(priv, HBG_INT_MSK_RX_B, true); 280 + 281 + return packet_done; 282 + } 283 + 284 + static void hbg_ring_uninit(struct hbg_ring *ring) 285 + { 286 + struct hbg_buffer *buffer; 287 + u32 i; 288 + 289 + if (!ring->queue) 290 + return; 291 + 292 + napi_disable(&ring->napi); 293 + netif_napi_del(&ring->napi); 294 + 295 + for (i = 0; i < ring->len; i++) { 296 + buffer = &ring->queue[i]; 297 + hbg_buffer_free(buffer); 298 + buffer->ring = NULL; 299 + buffer->priv = NULL; 300 + } 301 + 302 + dma_free_coherent(&ring->priv->pdev->dev, 303 + ring->len * sizeof(*ring->queue), 304 + ring->queue, ring->queue_dma); 305 + ring->queue = NULL; 306 + ring->queue_dma = 0; 307 + ring->len = 0; 308 + ring->priv = NULL; 309 + } 310 + 311 + static int hbg_ring_init(struct hbg_priv *priv, struct hbg_ring *ring, 312 + int (*napi_poll)(struct napi_struct *, int), 313 + enum hbg_dir dir) 314 + { 315 + struct hbg_buffer *buffer; 316 + u32 i, len; 317 + 318 + len = hbg_get_spec_fifo_max_num(priv, dir) + 1; 319 + ring->queue = dma_alloc_coherent(&priv->pdev->dev, 320 + len * sizeof(*ring->queue), 321 + &ring->queue_dma, GFP_KERNEL); 322 + if (!ring->queue) 323 + return -ENOMEM; 324 + 325 + for (i = 0; i < len; i++) { 326 + buffer = &ring->queue[i]; 327 + buffer->skb_len = 0; 328 + buffer->dir = dir; 329 + buffer->ring = ring; 330 + buffer->priv = priv; 331 + buffer->state_dma = ring->queue_dma + (i * sizeof(*buffer)); 332 + } 333 + 334 + ring->dir = dir; 335 + ring->priv = priv; 336 + ring->ntc = 0; 337 + ring->ntu = 0; 338 + ring->len = len; 339 + 340 + if (dir == HBG_DIR_TX) 341 + netif_napi_add_tx(priv->netdev, &ring->napi, napi_poll); 342 + else 343 + netif_napi_add(priv->netdev, &ring->napi, napi_poll); 344 + 345 + napi_enable(&ring->napi); 346 + return 0; 347 + } 348 + 349 + static int hbg_tx_ring_init(struct hbg_priv *priv) 350 + { 351 + struct hbg_ring *tx_ring = &priv->tx_ring; 352 + 353 + if (!tx_ring->tout_log_buf) 354 + tx_ring->tout_log_buf = devm_kmalloc(&priv->pdev->dev, 355 + HBG_TX_TIMEOUT_BUF_LEN, 356 + GFP_KERNEL); 357 + 358 + if (!tx_ring->tout_log_buf) 359 + return -ENOMEM; 360 + 361 + return hbg_ring_init(priv, tx_ring, hbg_napi_tx_recycle, HBG_DIR_TX); 362 + } 363 + 364 + static int hbg_rx_ring_init(struct hbg_priv *priv) 365 + { 366 + int ret; 367 + u32 i; 368 + 369 + ret = hbg_ring_init(priv, &priv->rx_ring, hbg_napi_rx_poll, HBG_DIR_RX); 370 + if (ret) 371 + return ret; 372 + 373 + for (i = 0; i < priv->rx_ring.len - 1; i++) { 374 + ret = hbg_rx_fill_one_buffer(priv); 375 + if (ret) { 376 + hbg_ring_uninit(&priv->rx_ring); 377 + return ret; 378 + } 379 + } 380 + 381 + return 0; 382 + } 383 + 384 + int hbg_txrx_init(struct hbg_priv *priv) 385 + { 386 + int ret; 387 + 388 + ret = hbg_tx_ring_init(priv); 389 + if (ret) { 390 + dev_err(&priv->pdev->dev, 391 + "failed to init tx ring, ret = %d\n", ret); 392 + return ret; 393 + } 394 + 395 + ret = hbg_rx_ring_init(priv); 396 + if (ret) { 397 + dev_err(&priv->pdev->dev, 398 + "failed to init rx ring, ret = %d\n", ret); 399 + hbg_ring_uninit(&priv->tx_ring); 400 + } 401 + 402 + return ret; 403 + } 404 + 405 + void hbg_txrx_uninit(struct hbg_priv *priv) 406 + { 407 + hbg_ring_uninit(&priv->tx_ring); 408 + hbg_ring_uninit(&priv->rx_ring); 409 + }
+39
drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 + /* Copyright (c) 2024 Hisilicon Limited. */ 3 + 4 + #ifndef __HBG_TXRX_H 5 + #define __HBG_TXRX_H 6 + 7 + #include <linux/etherdevice.h> 8 + #include "hbg_hw.h" 9 + 10 + static inline u32 hbg_spec_max_frame_len(struct hbg_priv *priv, 11 + enum hbg_dir dir) 12 + { 13 + return (dir == HBG_DIR_TX) ? priv->dev_specs.max_frame_len : 14 + priv->dev_specs.rx_buf_size; 15 + } 16 + 17 + static inline u32 hbg_get_spec_fifo_max_num(struct hbg_priv *priv, 18 + enum hbg_dir dir) 19 + { 20 + return (dir == HBG_DIR_TX) ? priv->dev_specs.tx_fifo_num : 21 + priv->dev_specs.rx_fifo_num; 22 + } 23 + 24 + static inline bool hbg_fifo_is_full(struct hbg_priv *priv, enum hbg_dir dir) 25 + { 26 + return hbg_hw_get_fifo_used_num(priv, dir) >= 27 + hbg_get_spec_fifo_max_num(priv, dir); 28 + } 29 + 30 + static inline u32 hbg_get_queue_used_num(struct hbg_ring *ring) 31 + { 32 + return (ring->ntu + ring->len - ring->ntc) % ring->len; 33 + } 34 + 35 + netdev_tx_t hbg_net_start_xmit(struct sk_buff *skb, struct net_device *netdev); 36 + int hbg_txrx_init(struct hbg_priv *priv); 37 + void hbg_txrx_uninit(struct hbg_priv *priv); 38 + 39 + #endif