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 'mlxbf_gige-add-bluefield-3-support'

David Thompson says:

====================
mlxbf_gige: add BlueField-3 support

This patch series adds driver logic to the "mlxbf_gige"
Ethernet driver in order to support the third generation
BlueField SoC (BF3). The existing "mlxbf_gige" driver is
extended with BF3-specific logic and run-time decisions
are made by the driver depending on the SoC generation
(BF2 vs. BF3).

The BF3 SoC is similar to BF2 SoC with regards to transmit
and receive packet processing:
* Driver rings usage; consumer & producer indices
* Single queue for receive and transmit
* DMA operation

The differences between BF3 and BF2 SoC are:
* In addition to supporting 1Gbps interface speed, the BF3 SoC
adds support for 10Mbps and 100Mbps interface speeds
* BF3 requires SerDes config logic to support its SGMII interface
* BF3 adds support for "ethtool -s" for interface speed config
* BF3 utilizes different MDIO logic for accessing the
board-level PHY device

Testing
- Successful build of kernel for ARM64, ARM32, X86_64
- Tested ARM64 build on FastModels, Palladium, SoC
====================

Link: https://lore.kernel.org/r/20230112202609.21331-1-davthompson@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+372 -66
+27
drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige.h
··· 14 14 #include <linux/irqreturn.h> 15 15 #include <linux/netdevice.h> 16 16 #include <linux/irq.h> 17 + #include <linux/phy.h> 17 18 18 19 /* The silicon design supports a maximum RX ring size of 19 20 * 32K entries. Based on current testing this maximum size ··· 68 67 u64 rx_filter_discard_pkts; 69 68 }; 70 69 70 + struct mlxbf_gige_reg_param { 71 + u32 mask; 72 + u32 shift; 73 + }; 74 + 75 + struct mlxbf_gige_mdio_gw { 76 + u32 gw_address; 77 + u32 read_data_address; 78 + struct mlxbf_gige_reg_param busy; 79 + struct mlxbf_gige_reg_param write_data; 80 + struct mlxbf_gige_reg_param read_data; 81 + struct mlxbf_gige_reg_param devad; 82 + struct mlxbf_gige_reg_param partad; 83 + struct mlxbf_gige_reg_param opcode; 84 + struct mlxbf_gige_reg_param st1; 85 + }; 86 + 87 + struct mlxbf_gige_link_cfg { 88 + void (*set_phy_link_mode)(struct phy_device *phydev); 89 + void (*adjust_link)(struct net_device *netdev); 90 + phy_interface_t phy_mode; 91 + }; 92 + 71 93 struct mlxbf_gige { 72 94 void __iomem *base; 73 95 void __iomem *llu_base; ··· 126 102 u8 valid_polarity; 127 103 struct napi_struct napi; 128 104 struct mlxbf_gige_stats stats; 105 + u8 hw_version; 106 + struct mlxbf_gige_mdio_gw *mdio_gw; 107 + int prev_speed; 129 108 }; 130 109 131 110 /* Rx Work Queue Element definitions */
+1
drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_ethtool.c
··· 135 135 .nway_reset = phy_ethtool_nway_reset, 136 136 .get_pauseparam = mlxbf_gige_get_pauseparam, 137 137 .get_link_ksettings = phy_ethtool_get_link_ksettings, 138 + .set_link_ksettings = phy_ethtool_set_link_ksettings, 138 139 };
+93 -16
drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c
··· 205 205 } 206 206 207 207 static int mlxbf_gige_eth_ioctl(struct net_device *netdev, 208 - struct ifreq *ifr, int cmd) 208 + struct ifreq *ifr, int cmd) 209 209 { 210 210 if (!(netif_running(netdev))) 211 211 return -EINVAL; ··· 263 263 .ndo_get_stats64 = mlxbf_gige_get_stats64, 264 264 }; 265 265 266 - static void mlxbf_gige_adjust_link(struct net_device *netdev) 266 + static void mlxbf_gige_bf2_adjust_link(struct net_device *netdev) 267 267 { 268 268 struct phy_device *phydev = netdev->phydev; 269 269 270 270 phy_print_status(phydev); 271 271 } 272 + 273 + static void mlxbf_gige_bf3_adjust_link(struct net_device *netdev) 274 + { 275 + struct mlxbf_gige *priv = netdev_priv(netdev); 276 + struct phy_device *phydev = netdev->phydev; 277 + u8 sgmii_mode; 278 + u16 ipg_size; 279 + u32 val; 280 + 281 + if (phydev->link && phydev->speed != priv->prev_speed) { 282 + switch (phydev->speed) { 283 + case 1000: 284 + ipg_size = MLXBF_GIGE_1G_IPG_SIZE; 285 + sgmii_mode = MLXBF_GIGE_1G_SGMII_MODE; 286 + break; 287 + case 100: 288 + ipg_size = MLXBF_GIGE_100M_IPG_SIZE; 289 + sgmii_mode = MLXBF_GIGE_100M_SGMII_MODE; 290 + break; 291 + case 10: 292 + ipg_size = MLXBF_GIGE_10M_IPG_SIZE; 293 + sgmii_mode = MLXBF_GIGE_10M_SGMII_MODE; 294 + break; 295 + default: 296 + return; 297 + } 298 + 299 + val = readl(priv->plu_base + MLXBF_GIGE_PLU_TX_REG0); 300 + val &= ~(MLXBF_GIGE_PLU_TX_IPG_SIZE_MASK | MLXBF_GIGE_PLU_TX_SGMII_MODE_MASK); 301 + val |= FIELD_PREP(MLXBF_GIGE_PLU_TX_IPG_SIZE_MASK, ipg_size); 302 + val |= FIELD_PREP(MLXBF_GIGE_PLU_TX_SGMII_MODE_MASK, sgmii_mode); 303 + writel(val, priv->plu_base + MLXBF_GIGE_PLU_TX_REG0); 304 + 305 + val = readl(priv->plu_base + MLXBF_GIGE_PLU_RX_REG0); 306 + val &= ~MLXBF_GIGE_PLU_RX_SGMII_MODE_MASK; 307 + val |= FIELD_PREP(MLXBF_GIGE_PLU_RX_SGMII_MODE_MASK, sgmii_mode); 308 + writel(val, priv->plu_base + MLXBF_GIGE_PLU_RX_REG0); 309 + 310 + priv->prev_speed = phydev->speed; 311 + } 312 + 313 + phy_print_status(phydev); 314 + } 315 + 316 + static void mlxbf_gige_bf2_set_phy_link_mode(struct phy_device *phydev) 317 + { 318 + /* MAC only supports 1000T full duplex mode */ 319 + phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_1000baseT_Half_BIT); 320 + phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_100baseT_Full_BIT); 321 + phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_100baseT_Half_BIT); 322 + phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_10baseT_Full_BIT); 323 + phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_10baseT_Half_BIT); 324 + 325 + /* Only symmetric pause with flow control enabled is supported so no 326 + * need to negotiate pause. 327 + */ 328 + linkmode_clear_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydev->advertising); 329 + linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, phydev->advertising); 330 + } 331 + 332 + static void mlxbf_gige_bf3_set_phy_link_mode(struct phy_device *phydev) 333 + { 334 + /* MAC only supports full duplex mode */ 335 + phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_1000baseT_Half_BIT); 336 + phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_100baseT_Half_BIT); 337 + phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_10baseT_Half_BIT); 338 + 339 + /* Only symmetric pause with flow control enabled is supported so no 340 + * need to negotiate pause. 341 + */ 342 + linkmode_clear_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydev->advertising); 343 + linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, phydev->advertising); 344 + } 345 + 346 + static struct mlxbf_gige_link_cfg mlxbf_gige_link_cfgs[] = { 347 + [MLXBF_GIGE_VERSION_BF2] = { 348 + .set_phy_link_mode = mlxbf_gige_bf2_set_phy_link_mode, 349 + .adjust_link = mlxbf_gige_bf2_adjust_link, 350 + .phy_mode = PHY_INTERFACE_MODE_GMII 351 + }, 352 + [MLXBF_GIGE_VERSION_BF3] = { 353 + .set_phy_link_mode = mlxbf_gige_bf3_set_phy_link_mode, 354 + .adjust_link = mlxbf_gige_bf3_adjust_link, 355 + .phy_mode = PHY_INTERFACE_MODE_SGMII 356 + } 357 + }; 272 358 273 359 static int mlxbf_gige_probe(struct platform_device *pdev) 274 360 { ··· 401 315 402 316 spin_lock_init(&priv->lock); 403 317 318 + priv->hw_version = readq(base + MLXBF_GIGE_VERSION); 319 + 404 320 /* Attach MDIO device */ 405 321 err = mlxbf_gige_mdio_probe(pdev, priv); 406 322 if (err) ··· 445 357 phydev->irq = phy_irq; 446 358 447 359 err = phy_connect_direct(netdev, phydev, 448 - mlxbf_gige_adjust_link, 449 - PHY_INTERFACE_MODE_GMII); 360 + mlxbf_gige_link_cfgs[priv->hw_version].adjust_link, 361 + mlxbf_gige_link_cfgs[priv->hw_version].phy_mode); 450 362 if (err) { 451 363 dev_err(&pdev->dev, "Could not attach to PHY\n"); 452 364 goto out; 453 365 } 454 366 455 - /* MAC only supports 1000T full duplex mode */ 456 - phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_1000baseT_Half_BIT); 457 - phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_100baseT_Full_BIT); 458 - phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_100baseT_Half_BIT); 459 - phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_10baseT_Full_BIT); 460 - phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_10baseT_Half_BIT); 461 - 462 - /* Only symmetric pause with flow control enabled is supported so no 463 - * need to negotiate pause. 464 - */ 465 - linkmode_clear_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydev->advertising); 466 - linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, phydev->advertising); 367 + mlxbf_gige_link_cfgs[priv->hw_version].set_phy_link_mode(phydev); 467 368 468 369 /* Display information about attached PHY device */ 469 370 phy_attached_info(phydev);
+122 -50
drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_mdio.c
··· 23 23 24 24 #include "mlxbf_gige.h" 25 25 #include "mlxbf_gige_regs.h" 26 + #include "mlxbf_gige_mdio_bf2.h" 27 + #include "mlxbf_gige_mdio_bf3.h" 26 28 27 - #define MLXBF_GIGE_MDIO_GW_OFFSET 0x0 28 - #define MLXBF_GIGE_MDIO_CFG_OFFSET 0x4 29 + static struct mlxbf_gige_mdio_gw mlxbf_gige_mdio_gw_t[] = { 30 + [MLXBF_GIGE_VERSION_BF2] = { 31 + .gw_address = MLXBF2_GIGE_MDIO_GW_OFFSET, 32 + .read_data_address = MLXBF2_GIGE_MDIO_GW_OFFSET, 33 + .busy = { 34 + .mask = MLXBF2_GIGE_MDIO_GW_BUSY_MASK, 35 + .shift = MLXBF2_GIGE_MDIO_GW_BUSY_SHIFT, 36 + }, 37 + .read_data = { 38 + .mask = MLXBF2_GIGE_MDIO_GW_AD_MASK, 39 + .shift = MLXBF2_GIGE_MDIO_GW_AD_SHIFT, 40 + }, 41 + .write_data = { 42 + .mask = MLXBF2_GIGE_MDIO_GW_AD_MASK, 43 + .shift = MLXBF2_GIGE_MDIO_GW_AD_SHIFT, 44 + }, 45 + .devad = { 46 + .mask = MLXBF2_GIGE_MDIO_GW_DEVAD_MASK, 47 + .shift = MLXBF2_GIGE_MDIO_GW_DEVAD_SHIFT, 48 + }, 49 + .partad = { 50 + .mask = MLXBF2_GIGE_MDIO_GW_PARTAD_MASK, 51 + .shift = MLXBF2_GIGE_MDIO_GW_PARTAD_SHIFT, 52 + }, 53 + .opcode = { 54 + .mask = MLXBF2_GIGE_MDIO_GW_OPCODE_MASK, 55 + .shift = MLXBF2_GIGE_MDIO_GW_OPCODE_SHIFT, 56 + }, 57 + .st1 = { 58 + .mask = MLXBF2_GIGE_MDIO_GW_ST1_MASK, 59 + .shift = MLXBF2_GIGE_MDIO_GW_ST1_SHIFT, 60 + }, 61 + }, 62 + [MLXBF_GIGE_VERSION_BF3] = { 63 + .gw_address = MLXBF3_GIGE_MDIO_GW_OFFSET, 64 + .read_data_address = MLXBF3_GIGE_MDIO_DATA_READ, 65 + .busy = { 66 + .mask = MLXBF3_GIGE_MDIO_GW_BUSY_MASK, 67 + .shift = MLXBF3_GIGE_MDIO_GW_BUSY_SHIFT, 68 + }, 69 + .read_data = { 70 + .mask = MLXBF3_GIGE_MDIO_GW_DATA_READ_MASK, 71 + .shift = MLXBF3_GIGE_MDIO_GW_DATA_READ_SHIFT, 72 + }, 73 + .write_data = { 74 + .mask = MLXBF3_GIGE_MDIO_GW_DATA_MASK, 75 + .shift = MLXBF3_GIGE_MDIO_GW_DATA_SHIFT, 76 + }, 77 + .devad = { 78 + .mask = MLXBF3_GIGE_MDIO_GW_DEVAD_MASK, 79 + .shift = MLXBF3_GIGE_MDIO_GW_DEVAD_SHIFT, 80 + }, 81 + .partad = { 82 + .mask = MLXBF3_GIGE_MDIO_GW_PARTAD_MASK, 83 + .shift = MLXBF3_GIGE_MDIO_GW_PARTAD_SHIFT, 84 + }, 85 + .opcode = { 86 + .mask = MLXBF3_GIGE_MDIO_GW_OPCODE_MASK, 87 + .shift = MLXBF3_GIGE_MDIO_GW_OPCODE_SHIFT, 88 + }, 89 + .st1 = { 90 + .mask = MLXBF3_GIGE_MDIO_GW_ST1_MASK, 91 + .shift = MLXBF3_GIGE_MDIO_GW_ST1_SHIFT, 92 + }, 93 + }, 94 + }; 29 95 30 96 #define MLXBF_GIGE_MDIO_FREQ_REFERENCE 156250000ULL 31 97 #define MLXBF_GIGE_MDIO_COREPLL_CONST 16384ULL ··· 113 47 /* Busy bit is set by software and cleared by hardware */ 114 48 #define MLXBF_GIGE_MDIO_SET_BUSY 0x1 115 49 116 - /* MDIO GW register bits */ 117 - #define MLXBF_GIGE_MDIO_GW_AD_MASK GENMASK(15, 0) 118 - #define MLXBF_GIGE_MDIO_GW_DEVAD_MASK GENMASK(20, 16) 119 - #define MLXBF_GIGE_MDIO_GW_PARTAD_MASK GENMASK(25, 21) 120 - #define MLXBF_GIGE_MDIO_GW_OPCODE_MASK GENMASK(27, 26) 121 - #define MLXBF_GIGE_MDIO_GW_ST1_MASK GENMASK(28, 28) 122 - #define MLXBF_GIGE_MDIO_GW_BUSY_MASK GENMASK(30, 30) 123 - 124 - /* MDIO config register bits */ 125 - #define MLXBF_GIGE_MDIO_CFG_MDIO_MODE_MASK GENMASK(1, 0) 126 - #define MLXBF_GIGE_MDIO_CFG_MDIO3_3_MASK GENMASK(2, 2) 127 - #define MLXBF_GIGE_MDIO_CFG_MDIO_FULL_DRIVE_MASK GENMASK(4, 4) 128 - #define MLXBF_GIGE_MDIO_CFG_MDC_PERIOD_MASK GENMASK(15, 8) 129 - #define MLXBF_GIGE_MDIO_CFG_MDIO_IN_SAMP_MASK GENMASK(23, 16) 130 - #define MLXBF_GIGE_MDIO_CFG_MDIO_OUT_SAMP_MASK GENMASK(31, 24) 131 - 132 - #define MLXBF_GIGE_MDIO_CFG_VAL (FIELD_PREP(MLXBF_GIGE_MDIO_CFG_MDIO_MODE_MASK, 1) | \ 133 - FIELD_PREP(MLXBF_GIGE_MDIO_CFG_MDIO3_3_MASK, 1) | \ 134 - FIELD_PREP(MLXBF_GIGE_MDIO_CFG_MDIO_FULL_DRIVE_MASK, 1) | \ 135 - FIELD_PREP(MLXBF_GIGE_MDIO_CFG_MDIO_IN_SAMP_MASK, 6) | \ 136 - FIELD_PREP(MLXBF_GIGE_MDIO_CFG_MDIO_OUT_SAMP_MASK, 13)) 137 - 138 50 #define MLXBF_GIGE_BF2_COREPLL_ADDR 0x02800c30 139 51 #define MLXBF_GIGE_BF2_COREPLL_SIZE 0x0000000c 52 + #define MLXBF_GIGE_BF3_COREPLL_ADDR 0x13409824 53 + #define MLXBF_GIGE_BF3_COREPLL_SIZE 0x00000010 140 54 141 55 static struct resource corepll_params[] = { 142 56 [MLXBF_GIGE_VERSION_BF2] = { ··· 124 78 .end = MLXBF_GIGE_BF2_COREPLL_ADDR + MLXBF_GIGE_BF2_COREPLL_SIZE - 1, 125 79 .name = "COREPLL_RES" 126 80 }, 81 + [MLXBF_GIGE_VERSION_BF3] = { 82 + .start = MLXBF_GIGE_BF3_COREPLL_ADDR, 83 + .end = MLXBF_GIGE_BF3_COREPLL_ADDR + MLXBF_GIGE_BF3_COREPLL_SIZE - 1, 84 + .name = "COREPLL_RES" 85 + } 127 86 }; 128 87 129 88 /* Returns core clock i1clk in Hz */ ··· 185 134 return mdio_period; 186 135 } 187 136 188 - static u32 mlxbf_gige_mdio_create_cmd(u16 data, int phy_add, 137 + static u32 mlxbf_gige_mdio_create_cmd(struct mlxbf_gige_mdio_gw *mdio_gw, u16 data, int phy_add, 189 138 int phy_reg, u32 opcode) 190 139 { 191 140 u32 gw_reg = 0; 192 141 193 - gw_reg |= FIELD_PREP(MLXBF_GIGE_MDIO_GW_AD_MASK, data); 194 - gw_reg |= FIELD_PREP(MLXBF_GIGE_MDIO_GW_DEVAD_MASK, phy_reg); 195 - gw_reg |= FIELD_PREP(MLXBF_GIGE_MDIO_GW_PARTAD_MASK, phy_add); 196 - gw_reg |= FIELD_PREP(MLXBF_GIGE_MDIO_GW_OPCODE_MASK, opcode); 197 - gw_reg |= FIELD_PREP(MLXBF_GIGE_MDIO_GW_ST1_MASK, 198 - MLXBF_GIGE_MDIO_CL22_ST1); 199 - gw_reg |= FIELD_PREP(MLXBF_GIGE_MDIO_GW_BUSY_MASK, 200 - MLXBF_GIGE_MDIO_SET_BUSY); 142 + gw_reg |= ((data << mdio_gw->write_data.shift) & 143 + mdio_gw->write_data.mask); 144 + gw_reg |= ((phy_reg << mdio_gw->devad.shift) & 145 + mdio_gw->devad.mask); 146 + gw_reg |= ((phy_add << mdio_gw->partad.shift) & 147 + mdio_gw->partad.mask); 148 + gw_reg |= ((opcode << mdio_gw->opcode.shift) & 149 + mdio_gw->opcode.mask); 150 + gw_reg |= ((MLXBF_GIGE_MDIO_CL22_ST1 << mdio_gw->st1.shift) & 151 + mdio_gw->st1.mask); 152 + gw_reg |= ((MLXBF_GIGE_MDIO_SET_BUSY << mdio_gw->busy.shift) & 153 + mdio_gw->busy.mask); 201 154 202 155 return gw_reg; 203 156 } ··· 217 162 return -EOPNOTSUPP; 218 163 219 164 /* Send mdio read request */ 220 - cmd = mlxbf_gige_mdio_create_cmd(0, phy_add, phy_reg, MLXBF_GIGE_MDIO_CL22_READ); 165 + cmd = mlxbf_gige_mdio_create_cmd(priv->mdio_gw, 0, phy_add, phy_reg, 166 + MLXBF_GIGE_MDIO_CL22_READ); 221 167 222 - writel(cmd, priv->mdio_io + MLXBF_GIGE_MDIO_GW_OFFSET); 168 + writel(cmd, priv->mdio_io + priv->mdio_gw->gw_address); 223 169 224 - ret = readl_poll_timeout_atomic(priv->mdio_io + MLXBF_GIGE_MDIO_GW_OFFSET, 225 - val, !(val & MLXBF_GIGE_MDIO_GW_BUSY_MASK), 170 + ret = readl_poll_timeout_atomic(priv->mdio_io + priv->mdio_gw->gw_address, 171 + val, !(val & priv->mdio_gw->busy.mask), 226 172 5, 1000000); 227 173 228 174 if (ret) { 229 - writel(0, priv->mdio_io + MLXBF_GIGE_MDIO_GW_OFFSET); 175 + writel(0, priv->mdio_io + priv->mdio_gw->gw_address); 230 176 return ret; 231 177 } 232 178 233 - ret = readl(priv->mdio_io + MLXBF_GIGE_MDIO_GW_OFFSET); 179 + ret = readl(priv->mdio_io + priv->mdio_gw->read_data_address); 234 180 /* Only return ad bits of the gw register */ 235 - ret &= MLXBF_GIGE_MDIO_GW_AD_MASK; 181 + ret &= priv->mdio_gw->read_data.mask; 236 182 237 183 /* The MDIO lock is set on read. To release it, clear gw register */ 238 - writel(0, priv->mdio_io + MLXBF_GIGE_MDIO_GW_OFFSET); 184 + writel(0, priv->mdio_io + priv->mdio_gw->gw_address); 239 185 240 186 return ret; 241 187 } ··· 253 197 return -EOPNOTSUPP; 254 198 255 199 /* Send mdio write request */ 256 - cmd = mlxbf_gige_mdio_create_cmd(val, phy_add, phy_reg, 200 + cmd = mlxbf_gige_mdio_create_cmd(priv->mdio_gw, val, phy_add, phy_reg, 257 201 MLXBF_GIGE_MDIO_CL22_WRITE); 258 - writel(cmd, priv->mdio_io + MLXBF_GIGE_MDIO_GW_OFFSET); 202 + writel(cmd, priv->mdio_io + priv->mdio_gw->gw_address); 259 203 260 204 /* If the poll timed out, drop the request */ 261 - ret = readl_poll_timeout_atomic(priv->mdio_io + MLXBF_GIGE_MDIO_GW_OFFSET, 262 - temp, !(temp & MLXBF_GIGE_MDIO_GW_BUSY_MASK), 205 + ret = readl_poll_timeout_atomic(priv->mdio_io + priv->mdio_gw->gw_address, 206 + temp, !(temp & priv->mdio_gw->busy.mask), 263 207 5, 1000000); 264 208 265 209 /* The MDIO lock is set on read. To release it, clear gw register */ 266 - writel(0, priv->mdio_io + MLXBF_GIGE_MDIO_GW_OFFSET); 210 + writel(0, priv->mdio_io + priv->mdio_gw->gw_address); 267 211 268 212 return ret; 269 213 } ··· 275 219 276 220 mdio_period = mdio_period_map(priv); 277 221 278 - val = MLXBF_GIGE_MDIO_CFG_VAL; 279 - val |= FIELD_PREP(MLXBF_GIGE_MDIO_CFG_MDC_PERIOD_MASK, mdio_period); 280 - writel(val, priv->mdio_io + MLXBF_GIGE_MDIO_CFG_OFFSET); 222 + if (priv->hw_version == MLXBF_GIGE_VERSION_BF2) { 223 + val = MLXBF2_GIGE_MDIO_CFG_VAL; 224 + val |= FIELD_PREP(MLXBF2_GIGE_MDIO_CFG_MDC_PERIOD_MASK, mdio_period); 225 + writel(val, priv->mdio_io + MLXBF2_GIGE_MDIO_CFG_OFFSET); 226 + } else { 227 + val = FIELD_PREP(MLXBF3_GIGE_MDIO_CFG_MDIO_MODE_MASK, 1) | 228 + FIELD_PREP(MLXBF3_GIGE_MDIO_CFG_MDIO_FULL_DRIVE_MASK, 1); 229 + writel(val, priv->mdio_io + MLXBF3_GIGE_MDIO_CFG_REG0); 230 + val = FIELD_PREP(MLXBF3_GIGE_MDIO_CFG_MDC_PERIOD_MASK, mdio_period); 231 + writel(val, priv->mdio_io + MLXBF3_GIGE_MDIO_CFG_REG1); 232 + val = FIELD_PREP(MLXBF3_GIGE_MDIO_CFG_MDIO_IN_SAMP_MASK, 6) | 233 + FIELD_PREP(MLXBF3_GIGE_MDIO_CFG_MDIO_OUT_SAMP_MASK, 13); 234 + writel(val, priv->mdio_io + MLXBF3_GIGE_MDIO_CFG_REG2); 235 + } 281 236 } 282 237 283 238 int mlxbf_gige_mdio_probe(struct platform_device *pdev, struct mlxbf_gige *priv) ··· 296 229 struct device *dev = &pdev->dev; 297 230 struct resource *res; 298 231 int ret; 232 + 233 + if (priv->hw_version > MLXBF_GIGE_VERSION_BF3) 234 + return -ENODEV; 299 235 300 236 priv->mdio_io = devm_platform_ioremap_resource(pdev, MLXBF_GIGE_RES_MDIO9); 301 237 if (IS_ERR(priv->mdio_io)) ··· 312 242 /* For backward compatibility with older ACPI tables, also keep 313 243 * CLK resource internal to the driver. 314 244 */ 315 - res = &corepll_params[MLXBF_GIGE_VERSION_BF2]; 245 + res = &corepll_params[priv->hw_version]; 316 246 } 317 247 318 248 priv->clk_io = devm_ioremap(dev, res->start, resource_size(res)); 319 249 if (!priv->clk_io) 320 250 return -ENOMEM; 251 + 252 + priv->mdio_gw = &mlxbf_gige_mdio_gw_t[priv->hw_version]; 321 253 322 254 mlxbf_gige_mdio_cfg(priv); 323 255
+53
drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_mdio_bf2.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause */ 2 + 3 + /* MDIO support for Mellanox Gigabit Ethernet driver 4 + * 5 + * Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES, ALL RIGHTS RESERVED. 6 + * 7 + * This software product is a proprietary product of NVIDIA CORPORATION & 8 + * AFFILIATES (the "Company") and all right, title, and interest in and to the 9 + * software product, including all associated intellectual property rights, are 10 + * and shall remain exclusively with the Company. 11 + * 12 + * This software product is governed by the End User License Agreement 13 + * provided with the software product. 14 + */ 15 + 16 + #ifndef __MLXBF_GIGE_MDIO_BF2_H__ 17 + #define __MLXBF_GIGE_MDIO_BF2_H__ 18 + 19 + #include <linux/bitfield.h> 20 + 21 + #define MLXBF2_GIGE_MDIO_GW_OFFSET 0x0 22 + #define MLXBF2_GIGE_MDIO_CFG_OFFSET 0x4 23 + 24 + /* MDIO GW register bits */ 25 + #define MLXBF2_GIGE_MDIO_GW_AD_MASK GENMASK(15, 0) 26 + #define MLXBF2_GIGE_MDIO_GW_DEVAD_MASK GENMASK(20, 16) 27 + #define MLXBF2_GIGE_MDIO_GW_PARTAD_MASK GENMASK(25, 21) 28 + #define MLXBF2_GIGE_MDIO_GW_OPCODE_MASK GENMASK(27, 26) 29 + #define MLXBF2_GIGE_MDIO_GW_ST1_MASK GENMASK(28, 28) 30 + #define MLXBF2_GIGE_MDIO_GW_BUSY_MASK GENMASK(30, 30) 31 + 32 + #define MLXBF2_GIGE_MDIO_GW_AD_SHIFT 0 33 + #define MLXBF2_GIGE_MDIO_GW_DEVAD_SHIFT 16 34 + #define MLXBF2_GIGE_MDIO_GW_PARTAD_SHIFT 21 35 + #define MLXBF2_GIGE_MDIO_GW_OPCODE_SHIFT 26 36 + #define MLXBF2_GIGE_MDIO_GW_ST1_SHIFT 28 37 + #define MLXBF2_GIGE_MDIO_GW_BUSY_SHIFT 30 38 + 39 + /* MDIO config register bits */ 40 + #define MLXBF2_GIGE_MDIO_CFG_MDIO_MODE_MASK GENMASK(1, 0) 41 + #define MLXBF2_GIGE_MDIO_CFG_MDIO3_3_MASK GENMASK(2, 2) 42 + #define MLXBF2_GIGE_MDIO_CFG_MDIO_FULL_DRIVE_MASK GENMASK(4, 4) 43 + #define MLXBF2_GIGE_MDIO_CFG_MDC_PERIOD_MASK GENMASK(15, 8) 44 + #define MLXBF2_GIGE_MDIO_CFG_MDIO_IN_SAMP_MASK GENMASK(23, 16) 45 + #define MLXBF2_GIGE_MDIO_CFG_MDIO_OUT_SAMP_MASK GENMASK(31, 24) 46 + 47 + #define MLXBF2_GIGE_MDIO_CFG_VAL (FIELD_PREP(MLXBF2_GIGE_MDIO_CFG_MDIO_MODE_MASK, 1) | \ 48 + FIELD_PREP(MLXBF2_GIGE_MDIO_CFG_MDIO3_3_MASK, 1) | \ 49 + FIELD_PREP(MLXBF2_GIGE_MDIO_CFG_MDIO_FULL_DRIVE_MASK, 1) | \ 50 + FIELD_PREP(MLXBF2_GIGE_MDIO_CFG_MDIO_IN_SAMP_MASK, 6) | \ 51 + FIELD_PREP(MLXBF2_GIGE_MDIO_CFG_MDIO_OUT_SAMP_MASK, 13)) 52 + 53 + #endif /* __MLXBF_GIGE_MDIO_BF2_H__ */
+54
drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_mdio_bf3.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause */ 2 + 3 + /* MDIO support for Mellanox Gigabit Ethernet driver 4 + * 5 + * Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES, ALL RIGHTS RESERVED. 6 + * 7 + * This software product is a proprietary product of NVIDIA CORPORATION & 8 + * AFFILIATES (the "Company") and all right, title, and interest in and to the 9 + * software product, including all associated intellectual property rights, are 10 + * and shall remain exclusively with the Company. 11 + * 12 + * This software product is governed by the End User License Agreement 13 + * provided with the software product. 14 + */ 15 + 16 + #ifndef __MLXBF_GIGE_MDIO_BF3_H__ 17 + #define __MLXBF_GIGE_MDIO_BF3_H__ 18 + 19 + #include <linux/bitfield.h> 20 + 21 + #define MLXBF3_GIGE_MDIO_GW_OFFSET 0x80 22 + #define MLXBF3_GIGE_MDIO_DATA_READ 0x8c 23 + #define MLXBF3_GIGE_MDIO_CFG_REG0 0x100 24 + #define MLXBF3_GIGE_MDIO_CFG_REG1 0x104 25 + #define MLXBF3_GIGE_MDIO_CFG_REG2 0x108 26 + 27 + /* MDIO GW register bits */ 28 + #define MLXBF3_GIGE_MDIO_GW_ST1_MASK GENMASK(1, 1) 29 + #define MLXBF3_GIGE_MDIO_GW_OPCODE_MASK GENMASK(3, 2) 30 + #define MLXBF3_GIGE_MDIO_GW_PARTAD_MASK GENMASK(8, 4) 31 + #define MLXBF3_GIGE_MDIO_GW_DEVAD_MASK GENMASK(13, 9) 32 + /* For BlueField-3, this field is only used for mdio write */ 33 + #define MLXBF3_GIGE_MDIO_GW_DATA_MASK GENMASK(29, 14) 34 + #define MLXBF3_GIGE_MDIO_GW_BUSY_MASK GENMASK(30, 30) 35 + 36 + #define MLXBF3_GIGE_MDIO_GW_DATA_READ_MASK GENMASK(15, 0) 37 + 38 + #define MLXBF3_GIGE_MDIO_GW_ST1_SHIFT 1 39 + #define MLXBF3_GIGE_MDIO_GW_OPCODE_SHIFT 2 40 + #define MLXBF3_GIGE_MDIO_GW_PARTAD_SHIFT 4 41 + #define MLXBF3_GIGE_MDIO_GW_DEVAD_SHIFT 9 42 + #define MLXBF3_GIGE_MDIO_GW_DATA_SHIFT 14 43 + #define MLXBF3_GIGE_MDIO_GW_BUSY_SHIFT 30 44 + 45 + #define MLXBF3_GIGE_MDIO_GW_DATA_READ_SHIFT 0 46 + 47 + /* MDIO config register bits */ 48 + #define MLXBF3_GIGE_MDIO_CFG_MDIO_MODE_MASK GENMASK(1, 0) 49 + #define MLXBF3_GIGE_MDIO_CFG_MDIO_FULL_DRIVE_MASK GENMASK(2, 2) 50 + #define MLXBF3_GIGE_MDIO_CFG_MDC_PERIOD_MASK GENMASK(7, 0) 51 + #define MLXBF3_GIGE_MDIO_CFG_MDIO_IN_SAMP_MASK GENMASK(7, 0) 52 + #define MLXBF3_GIGE_MDIO_CFG_MDIO_OUT_SAMP_MASK GENMASK(15, 8) 53 + 54 + #endif /* __MLXBF_GIGE_MDIO_BF3_H__ */
+22
drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_regs.h
··· 8 8 #ifndef __MLXBF_GIGE_REGS_H__ 9 9 #define __MLXBF_GIGE_REGS_H__ 10 10 11 + #include <linux/bitfield.h> 12 + 11 13 #define MLXBF_GIGE_VERSION 0x0000 12 14 #define MLXBF_GIGE_VERSION_BF2 0x0 15 + #define MLXBF_GIGE_VERSION_BF3 0x1 13 16 #define MLXBF_GIGE_STATUS 0x0010 14 17 #define MLXBF_GIGE_STATUS_READY BIT(0) 15 18 #define MLXBF_GIGE_INT_STATUS 0x0028 ··· 79 76 * so use that plus size of single register to derive total size 80 77 */ 81 78 #define MLXBF_GIGE_MMIO_REG_SZ (MLXBF_GIGE_MAC_CFG + 8) 79 + 80 + #define MLXBF_GIGE_PLU_TX_REG0 0x80 81 + #define MLXBF_GIGE_PLU_TX_IPG_SIZE_MASK GENMASK(11, 0) 82 + #define MLXBF_GIGE_PLU_TX_SGMII_MODE_MASK GENMASK(15, 14) 83 + 84 + #define MLXBF_GIGE_PLU_RX_REG0 0x10 85 + #define MLXBF_GIGE_PLU_RX_SGMII_MODE_MASK GENMASK(25, 24) 86 + 87 + #define MLXBF_GIGE_1G_SGMII_MODE 0x0 88 + #define MLXBF_GIGE_10M_SGMII_MODE 0x1 89 + #define MLXBF_GIGE_100M_SGMII_MODE 0x2 90 + 91 + /* ipg_size default value for 1G is fixed by HW to 11 + End = 12. 92 + * So for 100M it is 12 * 10 - 1 = 119 93 + * For 10M, it is 12 * 100 - 1 = 1199 94 + */ 95 + #define MLXBF_GIGE_1G_IPG_SIZE 11 96 + #define MLXBF_GIGE_100M_IPG_SIZE 119 97 + #define MLXBF_GIGE_10M_IPG_SIZE 1199 82 98 83 99 #endif /* !defined(__MLXBF_GIGE_REGS_H__) */