1738 lines · c
1// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause2/* ADIN1110 Low Power 10BASE-T1L Ethernet MAC-PHY3 * ADIN2111 2-Port Ethernet Switch with Integrated 10BASE-T1L PHY4 *5 * Copyright 2021 Analog Devices Inc.6 */7 8#include <linux/bitfield.h>9#include <linux/bits.h>10#include <linux/cache.h>11#include <linux/crc8.h>12#include <linux/etherdevice.h>13#include <linux/ethtool.h>14#include <linux/gpio/consumer.h>15#include <linux/if_bridge.h>16#include <linux/interrupt.h>17#include <linux/iopoll.h>18#include <linux/kernel.h>19#include <linux/mii.h>20#include <linux/module.h>21#include <linux/netdevice.h>22#include <linux/regulator/consumer.h>23#include <linux/phy.h>24#include <linux/property.h>25#include <linux/spi/spi.h>26 27#include <net/switchdev.h>28 29#include <linux/unaligned.h>30 31#define ADIN1110_PHY_ID 0x132 33#define ADIN1110_RESET 0x0334#define ADIN1110_SWRESET BIT(0)35 36#define ADIN1110_CONFIG1 0x0437#define ADIN1110_CONFIG1_SYNC BIT(15)38 39#define ADIN1110_CONFIG2 0x0640#define ADIN2111_P2_FWD_UNK2HOST BIT(12)41#define ADIN2111_PORT_CUT_THRU_EN BIT(11)42#define ADIN1110_CRC_APPEND BIT(5)43#define ADIN1110_FWD_UNK2HOST BIT(2)44 45#define ADIN1110_STATUS0 0x0846 47#define ADIN1110_STATUS1 0x0948#define ADIN2111_P2_RX_RDY BIT(17)49#define ADIN1110_SPI_ERR BIT(10)50#define ADIN1110_RX_RDY BIT(4)51 52#define ADIN1110_IMASK1 0x0D53#define ADIN2111_RX_RDY_IRQ BIT(17)54#define ADIN1110_SPI_ERR_IRQ BIT(10)55#define ADIN1110_RX_RDY_IRQ BIT(4)56#define ADIN1110_TX_RDY_IRQ BIT(3)57 58#define ADIN1110_MDIOACC 0x2059#define ADIN1110_MDIO_TRDONE BIT(31)60#define ADIN1110_MDIO_ST GENMASK(29, 28)61#define ADIN1110_MDIO_OP GENMASK(27, 26)62#define ADIN1110_MDIO_PRTAD GENMASK(25, 21)63#define ADIN1110_MDIO_DEVAD GENMASK(20, 16)64#define ADIN1110_MDIO_DATA GENMASK(15, 0)65 66#define ADIN1110_TX_FSIZE 0x3067#define ADIN1110_TX 0x3168#define ADIN1110_TX_SPACE 0x3269 70#define ADIN1110_MAC_ADDR_FILTER_UPR 0x5071#define ADIN2111_MAC_ADDR_APPLY2PORT2 BIT(31)72#define ADIN1110_MAC_ADDR_APPLY2PORT BIT(30)73#define ADIN2111_MAC_ADDR_TO_OTHER_PORT BIT(17)74#define ADIN1110_MAC_ADDR_TO_HOST BIT(16)75 76#define ADIN1110_MAC_ADDR_FILTER_LWR 0x5177 78#define ADIN1110_MAC_ADDR_MASK_UPR 0x7079#define ADIN1110_MAC_ADDR_MASK_LWR 0x7180 81#define ADIN1110_RX_FSIZE 0x9082#define ADIN1110_RX 0x9183 84#define ADIN2111_RX_P2_FSIZE 0xC085#define ADIN2111_RX_P2 0xC186 87#define ADIN1110_CLEAR_STATUS0 0xFFF88 89/* MDIO_OP codes */90#define ADIN1110_MDIO_OP_WR 0x191#define ADIN1110_MDIO_OP_RD 0x392 93#define ADIN1110_CD BIT(7)94#define ADIN1110_WRITE BIT(5)95 96#define ADIN1110_MAX_BUFF 204897#define ADIN1110_MAX_FRAMES_READ 6498#define ADIN1110_WR_HEADER_LEN 299#define ADIN1110_FRAME_HEADER_LEN 2100#define ADIN1110_INTERNAL_SIZE_HEADER_LEN 2101#define ADIN1110_RD_HEADER_LEN 3102#define ADIN1110_REG_LEN 4103#define ADIN1110_FEC_LEN 4104 105#define ADIN1110_PHY_ID_VAL 0x0283BC91106#define ADIN2111_PHY_ID_VAL 0x0283BCA1107 108#define ADIN_MAC_MAX_PORTS 2109#define ADIN_MAC_MAX_ADDR_SLOTS 16110 111#define ADIN_MAC_MULTICAST_ADDR_SLOT 0112#define ADIN_MAC_BROADCAST_ADDR_SLOT 1113#define ADIN_MAC_P1_ADDR_SLOT 2114#define ADIN_MAC_P2_ADDR_SLOT 3115#define ADIN_MAC_FDB_ADDR_SLOT 4116 117DECLARE_CRC8_TABLE(adin1110_crc_table);118 119enum adin1110_chips_id {120 ADIN1110_MAC = 0,121 ADIN2111_MAC,122};123 124struct adin1110_cfg {125 enum adin1110_chips_id id;126 char name[MDIO_NAME_SIZE];127 u32 phy_ids[PHY_MAX_ADDR];128 u32 ports_nr;129 u32 phy_id_val;130};131 132struct adin1110_port_priv {133 struct adin1110_priv *priv;134 struct net_device *netdev;135 struct net_device *bridge;136 struct phy_device *phydev;137 struct work_struct tx_work;138 u64 rx_packets;139 u64 tx_packets;140 u64 rx_bytes;141 u64 tx_bytes;142 struct work_struct rx_mode_work;143 u32 flags;144 struct sk_buff_head txq;145 u32 nr;146 u32 state;147 struct adin1110_cfg *cfg;148};149 150struct adin1110_priv {151 struct mutex lock; /* protect spi */152 spinlock_t state_lock; /* protect RX mode */153 struct mii_bus *mii_bus;154 struct spi_device *spidev;155 bool append_crc;156 struct adin1110_cfg *cfg;157 u32 tx_space;158 u32 irq_mask;159 bool forwarding;160 int irq;161 struct adin1110_port_priv *ports[ADIN_MAC_MAX_PORTS];162 char mii_bus_name[MII_BUS_ID_SIZE];163 u8 data[ADIN1110_MAX_BUFF] ____cacheline_aligned;164};165 166struct adin1110_switchdev_event_work {167 struct work_struct work;168 struct switchdev_notifier_fdb_info fdb_info;169 struct adin1110_port_priv *port_priv;170 unsigned long event;171};172 173static struct adin1110_cfg adin1110_cfgs[] = {174 {175 .id = ADIN1110_MAC,176 .name = "adin1110",177 .phy_ids = {1},178 .ports_nr = 1,179 .phy_id_val = ADIN1110_PHY_ID_VAL,180 },181 {182 .id = ADIN2111_MAC,183 .name = "adin2111",184 .phy_ids = {1, 2},185 .ports_nr = 2,186 .phy_id_val = ADIN2111_PHY_ID_VAL,187 },188};189 190static u8 adin1110_crc_data(u8 *data, u32 len)191{192 return crc8(adin1110_crc_table, data, len, 0);193}194 195static int adin1110_read_reg(struct adin1110_priv *priv, u16 reg, u32 *val)196{197 u32 header_len = ADIN1110_RD_HEADER_LEN;198 u32 read_len = ADIN1110_REG_LEN;199 struct spi_transfer t = {0};200 int ret;201 202 priv->data[0] = ADIN1110_CD | FIELD_GET(GENMASK(12, 8), reg);203 priv->data[1] = FIELD_GET(GENMASK(7, 0), reg);204 priv->data[2] = 0x00;205 206 if (priv->append_crc) {207 priv->data[2] = adin1110_crc_data(&priv->data[0], 2);208 priv->data[3] = 0x00;209 header_len++;210 }211 212 if (priv->append_crc)213 read_len++;214 215 memset(&priv->data[header_len], 0, read_len);216 t.tx_buf = &priv->data[0];217 t.rx_buf = &priv->data[0];218 t.len = read_len + header_len;219 220 ret = spi_sync_transfer(priv->spidev, &t, 1);221 if (ret)222 return ret;223 224 if (priv->append_crc) {225 u8 recv_crc;226 u8 crc;227 228 crc = adin1110_crc_data(&priv->data[header_len],229 ADIN1110_REG_LEN);230 recv_crc = priv->data[header_len + ADIN1110_REG_LEN];231 232 if (crc != recv_crc) {233 dev_err_ratelimited(&priv->spidev->dev, "CRC error.");234 return -EBADMSG;235 }236 }237 238 *val = get_unaligned_be32(&priv->data[header_len]);239 240 return ret;241}242 243static int adin1110_write_reg(struct adin1110_priv *priv, u16 reg, u32 val)244{245 u32 header_len = ADIN1110_WR_HEADER_LEN;246 u32 write_len = ADIN1110_REG_LEN;247 248 priv->data[0] = ADIN1110_CD | ADIN1110_WRITE | FIELD_GET(GENMASK(12, 8), reg);249 priv->data[1] = FIELD_GET(GENMASK(7, 0), reg);250 251 if (priv->append_crc) {252 priv->data[2] = adin1110_crc_data(&priv->data[0], header_len);253 header_len++;254 }255 256 put_unaligned_be32(val, &priv->data[header_len]);257 if (priv->append_crc) {258 priv->data[header_len + write_len] = adin1110_crc_data(&priv->data[header_len],259 write_len);260 write_len++;261 }262 263 return spi_write(priv->spidev, &priv->data[0], header_len + write_len);264}265 266static int adin1110_set_bits(struct adin1110_priv *priv, u16 reg,267 unsigned long mask, unsigned long val)268{269 u32 write_val;270 int ret;271 272 ret = adin1110_read_reg(priv, reg, &write_val);273 if (ret < 0)274 return ret;275 276 set_mask_bits(&write_val, mask, val);277 278 return adin1110_write_reg(priv, reg, write_val);279}280 281static int adin1110_round_len(int len)282{283 /* can read/write only mutiples of 4 bytes of payload */284 len = ALIGN(len, 4);285 286 /* NOTE: ADIN1110_WR_HEADER_LEN should be used for write ops. */287 if (len + ADIN1110_RD_HEADER_LEN > ADIN1110_MAX_BUFF)288 return -EINVAL;289 290 return len;291}292 293static int adin1110_read_fifo(struct adin1110_port_priv *port_priv)294{295 struct adin1110_priv *priv = port_priv->priv;296 u32 header_len = ADIN1110_RD_HEADER_LEN;297 struct spi_transfer t = {0};298 u32 frame_size_no_fcs;299 struct sk_buff *rxb;300 u32 frame_size;301 int round_len;302 u16 reg;303 int ret;304 305 if (!port_priv->nr) {306 reg = ADIN1110_RX;307 ret = adin1110_read_reg(priv, ADIN1110_RX_FSIZE, &frame_size);308 } else {309 reg = ADIN2111_RX_P2;310 ret = adin1110_read_reg(priv, ADIN2111_RX_P2_FSIZE,311 &frame_size);312 }313 314 if (ret < 0)315 return ret;316 317 /* The read frame size includes the extra 2 bytes318 * from the ADIN1110 frame header.319 */320 if (frame_size < ADIN1110_FRAME_HEADER_LEN + ADIN1110_FEC_LEN)321 return -EINVAL;322 323 round_len = adin1110_round_len(frame_size);324 if (round_len < 0)325 return -EINVAL;326 327 frame_size_no_fcs = frame_size - ADIN1110_FRAME_HEADER_LEN - ADIN1110_FEC_LEN;328 memset(priv->data, 0, ADIN1110_RD_HEADER_LEN);329 330 priv->data[0] = ADIN1110_CD | FIELD_GET(GENMASK(12, 8), reg);331 priv->data[1] = FIELD_GET(GENMASK(7, 0), reg);332 333 if (priv->append_crc) {334 priv->data[2] = adin1110_crc_data(&priv->data[0], 2);335 header_len++;336 }337 338 rxb = netdev_alloc_skb(port_priv->netdev, round_len + header_len);339 if (!rxb)340 return -ENOMEM;341 342 skb_put(rxb, frame_size_no_fcs + header_len + ADIN1110_FRAME_HEADER_LEN);343 344 t.tx_buf = &priv->data[0];345 t.rx_buf = &rxb->data[0];346 t.len = header_len + round_len;347 348 ret = spi_sync_transfer(priv->spidev, &t, 1);349 if (ret) {350 kfree_skb(rxb);351 return ret;352 }353 354 skb_pull(rxb, header_len + ADIN1110_FRAME_HEADER_LEN);355 rxb->protocol = eth_type_trans(rxb, port_priv->netdev);356 357 if ((port_priv->flags & IFF_ALLMULTI && rxb->pkt_type == PACKET_MULTICAST) ||358 (port_priv->flags & IFF_BROADCAST && rxb->pkt_type == PACKET_BROADCAST))359 rxb->offload_fwd_mark = port_priv->priv->forwarding;360 361 netif_rx(rxb);362 363 port_priv->rx_bytes += frame_size - ADIN1110_FRAME_HEADER_LEN;364 port_priv->rx_packets++;365 366 return 0;367}368 369static int adin1110_write_fifo(struct adin1110_port_priv *port_priv,370 struct sk_buff *txb)371{372 struct adin1110_priv *priv = port_priv->priv;373 u32 header_len = ADIN1110_WR_HEADER_LEN;374 __be16 frame_header;375 int padding = 0;376 int padded_len;377 int round_len;378 int ret;379 380 /* Pad frame to 64 byte length,381 * MAC nor PHY will otherwise add the382 * required padding.383 * The FEC will be added by the MAC internally.384 */385 if (txb->len + ADIN1110_FEC_LEN < 64)386 padding = 64 - (txb->len + ADIN1110_FEC_LEN);387 388 padded_len = txb->len + padding + ADIN1110_FRAME_HEADER_LEN;389 390 round_len = adin1110_round_len(padded_len);391 if (round_len < 0)392 return round_len;393 394 ret = adin1110_write_reg(priv, ADIN1110_TX_FSIZE, padded_len);395 if (ret < 0)396 return ret;397 398 memset(priv->data, 0, round_len + ADIN1110_WR_HEADER_LEN);399 400 priv->data[0] = ADIN1110_CD | ADIN1110_WRITE;401 priv->data[0] |= FIELD_GET(GENMASK(12, 8), ADIN1110_TX);402 priv->data[1] = FIELD_GET(GENMASK(7, 0), ADIN1110_TX);403 if (priv->append_crc) {404 priv->data[2] = adin1110_crc_data(&priv->data[0], 2);405 header_len++;406 }407 408 /* mention the port on which to send the frame in the frame header */409 frame_header = cpu_to_be16(port_priv->nr);410 memcpy(&priv->data[header_len], &frame_header,411 ADIN1110_FRAME_HEADER_LEN);412 413 memcpy(&priv->data[header_len + ADIN1110_FRAME_HEADER_LEN],414 txb->data, txb->len);415 416 ret = spi_write(priv->spidev, &priv->data[0], round_len + header_len);417 if (ret < 0)418 return ret;419 420 port_priv->tx_bytes += txb->len;421 port_priv->tx_packets++;422 423 return 0;424}425 426static int adin1110_read_mdio_acc(struct adin1110_priv *priv)427{428 u32 val;429 int ret;430 431 mutex_lock(&priv->lock);432 ret = adin1110_read_reg(priv, ADIN1110_MDIOACC, &val);433 mutex_unlock(&priv->lock);434 if (ret < 0)435 return 0;436 437 return val;438}439 440static int adin1110_mdio_read(struct mii_bus *bus, int phy_id, int reg)441{442 struct adin1110_priv *priv = bus->priv;443 u32 val = 0;444 int ret;445 446 if (mdio_phy_id_is_c45(phy_id))447 return -EOPNOTSUPP;448 449 val |= FIELD_PREP(ADIN1110_MDIO_OP, ADIN1110_MDIO_OP_RD);450 val |= FIELD_PREP(ADIN1110_MDIO_ST, 0x1);451 val |= FIELD_PREP(ADIN1110_MDIO_PRTAD, phy_id);452 val |= FIELD_PREP(ADIN1110_MDIO_DEVAD, reg);453 454 /* write the clause 22 read command to the chip */455 mutex_lock(&priv->lock);456 ret = adin1110_write_reg(priv, ADIN1110_MDIOACC, val);457 mutex_unlock(&priv->lock);458 if (ret < 0)459 return ret;460 461 /* ADIN1110_MDIO_TRDONE BIT of the ADIN1110_MDIOACC462 * register is set when the read is done.463 * After the transaction is done, ADIN1110_MDIO_DATA464 * bitfield of ADIN1110_MDIOACC register will contain465 * the requested register value.466 */467 ret = readx_poll_timeout_atomic(adin1110_read_mdio_acc, priv, val,468 (val & ADIN1110_MDIO_TRDONE),469 100, 30000);470 if (ret < 0)471 return ret;472 473 return (val & ADIN1110_MDIO_DATA);474}475 476static int adin1110_mdio_write(struct mii_bus *bus, int phy_id,477 int reg, u16 reg_val)478{479 struct adin1110_priv *priv = bus->priv;480 u32 val = 0;481 int ret;482 483 if (mdio_phy_id_is_c45(phy_id))484 return -EOPNOTSUPP;485 486 val |= FIELD_PREP(ADIN1110_MDIO_OP, ADIN1110_MDIO_OP_WR);487 val |= FIELD_PREP(ADIN1110_MDIO_ST, 0x1);488 val |= FIELD_PREP(ADIN1110_MDIO_PRTAD, phy_id);489 val |= FIELD_PREP(ADIN1110_MDIO_DEVAD, reg);490 val |= FIELD_PREP(ADIN1110_MDIO_DATA, reg_val);491 492 /* write the clause 22 write command to the chip */493 mutex_lock(&priv->lock);494 ret = adin1110_write_reg(priv, ADIN1110_MDIOACC, val);495 mutex_unlock(&priv->lock);496 if (ret < 0)497 return ret;498 499 return readx_poll_timeout_atomic(adin1110_read_mdio_acc, priv, val,500 (val & ADIN1110_MDIO_TRDONE),501 100, 30000);502}503 504/* ADIN1110 MAC-PHY contains an ADIN1100 PHY.505 * ADIN2111 MAC-PHY contains two ADIN1100 PHYs.506 * By registering a new MDIO bus we allow the PAL to discover507 * the encapsulated PHY and probe the ADIN1100 driver.508 */509static int adin1110_register_mdiobus(struct adin1110_priv *priv,510 struct device *dev)511{512 struct mii_bus *mii_bus;513 int ret;514 515 mii_bus = devm_mdiobus_alloc(dev);516 if (!mii_bus)517 return -ENOMEM;518 519 snprintf(priv->mii_bus_name, MII_BUS_ID_SIZE, "%s-%u",520 priv->cfg->name, spi_get_chipselect(priv->spidev, 0));521 522 mii_bus->name = priv->mii_bus_name;523 mii_bus->read = adin1110_mdio_read;524 mii_bus->write = adin1110_mdio_write;525 mii_bus->priv = priv;526 mii_bus->parent = dev;527 mii_bus->phy_mask = ~((u32)GENMASK(2, 0));528 snprintf(mii_bus->id, MII_BUS_ID_SIZE, "%s", dev_name(dev));529 530 ret = devm_mdiobus_register(dev, mii_bus);531 if (ret)532 return ret;533 534 priv->mii_bus = mii_bus;535 536 return 0;537}538 539static bool adin1110_port_rx_ready(struct adin1110_port_priv *port_priv,540 u32 status)541{542 if (!netif_oper_up(port_priv->netdev))543 return false;544 545 if (!port_priv->nr)546 return !!(status & ADIN1110_RX_RDY);547 else548 return !!(status & ADIN2111_P2_RX_RDY);549}550 551static void adin1110_read_frames(struct adin1110_port_priv *port_priv,552 unsigned int budget)553{554 struct adin1110_priv *priv = port_priv->priv;555 u32 status1;556 int ret;557 558 while (budget) {559 ret = adin1110_read_reg(priv, ADIN1110_STATUS1, &status1);560 if (ret < 0)561 return;562 563 if (!adin1110_port_rx_ready(port_priv, status1))564 break;565 566 ret = adin1110_read_fifo(port_priv);567 if (ret < 0)568 return;569 570 budget--;571 }572}573 574static void adin1110_wake_queues(struct adin1110_priv *priv)575{576 int i;577 578 for (i = 0; i < priv->cfg->ports_nr; i++)579 netif_wake_queue(priv->ports[i]->netdev);580}581 582static irqreturn_t adin1110_irq(int irq, void *p)583{584 struct adin1110_priv *priv = p;585 u32 status1;586 u32 val;587 int ret;588 int i;589 590 mutex_lock(&priv->lock);591 592 ret = adin1110_read_reg(priv, ADIN1110_STATUS1, &status1);593 if (ret < 0)594 goto out;595 596 if (priv->append_crc && (status1 & ADIN1110_SPI_ERR))597 dev_warn_ratelimited(&priv->spidev->dev,598 "SPI CRC error on write.\n");599 600 ret = adin1110_read_reg(priv, ADIN1110_TX_SPACE, &val);601 if (ret < 0)602 goto out;603 604 /* TX FIFO space is expressed in half-words */605 priv->tx_space = 2 * val;606 607 for (i = 0; i < priv->cfg->ports_nr; i++) {608 if (adin1110_port_rx_ready(priv->ports[i], status1))609 adin1110_read_frames(priv->ports[i],610 ADIN1110_MAX_FRAMES_READ);611 }612 613 /* clear IRQ sources */614 adin1110_write_reg(priv, ADIN1110_STATUS0, ADIN1110_CLEAR_STATUS0);615 adin1110_write_reg(priv, ADIN1110_STATUS1, priv->irq_mask);616 617out:618 mutex_unlock(&priv->lock);619 620 if (priv->tx_space > 0 && ret >= 0)621 adin1110_wake_queues(priv);622 623 return IRQ_HANDLED;624}625 626/* ADIN1110 can filter up to 16 MAC addresses, mac_nr here is the slot used */627static int adin1110_write_mac_address(struct adin1110_port_priv *port_priv,628 int mac_nr, const u8 *addr,629 u8 *mask, u32 port_rules)630{631 struct adin1110_priv *priv = port_priv->priv;632 u32 offset = mac_nr * 2;633 u32 port_rules_mask;634 int ret;635 u32 val;636 637 if (!port_priv->nr)638 port_rules_mask = ADIN1110_MAC_ADDR_APPLY2PORT;639 else640 port_rules_mask = ADIN2111_MAC_ADDR_APPLY2PORT2;641 642 if (port_rules & port_rules_mask)643 port_rules_mask |= ADIN1110_MAC_ADDR_TO_HOST | ADIN2111_MAC_ADDR_TO_OTHER_PORT;644 645 port_rules_mask |= GENMASK(15, 0);646 val = port_rules | get_unaligned_be16(&addr[0]);647 ret = adin1110_set_bits(priv, ADIN1110_MAC_ADDR_FILTER_UPR + offset,648 port_rules_mask, val);649 if (ret < 0)650 return ret;651 652 val = get_unaligned_be32(&addr[2]);653 ret = adin1110_write_reg(priv,654 ADIN1110_MAC_ADDR_FILTER_LWR + offset, val);655 if (ret < 0)656 return ret;657 658 /* Only the first two MAC address slots support masking. */659 if (mac_nr < ADIN_MAC_P1_ADDR_SLOT) {660 val = get_unaligned_be16(&mask[0]);661 ret = adin1110_write_reg(priv,662 ADIN1110_MAC_ADDR_MASK_UPR + offset,663 val);664 if (ret < 0)665 return ret;666 667 val = get_unaligned_be32(&mask[2]);668 return adin1110_write_reg(priv,669 ADIN1110_MAC_ADDR_MASK_LWR + offset,670 val);671 }672 673 return 0;674}675 676static int adin1110_clear_mac_address(struct adin1110_priv *priv, int mac_nr)677{678 u32 offset = mac_nr * 2;679 int ret;680 681 ret = adin1110_write_reg(priv, ADIN1110_MAC_ADDR_FILTER_UPR + offset, 0);682 if (ret < 0)683 return ret;684 685 ret = adin1110_write_reg(priv, ADIN1110_MAC_ADDR_FILTER_LWR + offset, 0);686 if (ret < 0)687 return ret;688 689 /* only the first two MAC address slots are maskable */690 if (mac_nr <= 1) {691 ret = adin1110_write_reg(priv, ADIN1110_MAC_ADDR_MASK_UPR + offset, 0);692 if (ret < 0)693 return ret;694 695 ret = adin1110_write_reg(priv, ADIN1110_MAC_ADDR_MASK_LWR + offset, 0);696 }697 698 return ret;699}700 701static u32 adin1110_port_rules(struct adin1110_port_priv *port_priv,702 bool fw_to_host,703 bool fw_to_other_port)704{705 u32 port_rules = 0;706 707 if (!port_priv->nr)708 port_rules |= ADIN1110_MAC_ADDR_APPLY2PORT;709 else710 port_rules |= ADIN2111_MAC_ADDR_APPLY2PORT2;711 712 if (fw_to_host)713 port_rules |= ADIN1110_MAC_ADDR_TO_HOST;714 715 if (fw_to_other_port && port_priv->priv->forwarding)716 port_rules |= ADIN2111_MAC_ADDR_TO_OTHER_PORT;717 718 return port_rules;719}720 721static int adin1110_multicast_filter(struct adin1110_port_priv *port_priv,722 int mac_nr, bool accept_multicast)723{724 u8 mask[ETH_ALEN] = {0};725 u8 mac[ETH_ALEN] = {0};726 u32 port_rules = 0;727 728 mask[0] = BIT(0);729 mac[0] = BIT(0);730 731 if (accept_multicast && port_priv->state == BR_STATE_FORWARDING)732 port_rules = adin1110_port_rules(port_priv, true, true);733 734 return adin1110_write_mac_address(port_priv, mac_nr, mac,735 mask, port_rules);736}737 738static int adin1110_broadcasts_filter(struct adin1110_port_priv *port_priv,739 int mac_nr, bool accept_broadcast)740{741 u32 port_rules = 0;742 u8 mask[ETH_ALEN];743 744 eth_broadcast_addr(mask);745 746 if (accept_broadcast && port_priv->state == BR_STATE_FORWARDING)747 port_rules = adin1110_port_rules(port_priv, true, true);748 749 return adin1110_write_mac_address(port_priv, mac_nr, mask,750 mask, port_rules);751}752 753static int adin1110_set_mac_address(struct net_device *netdev,754 const unsigned char *dev_addr)755{756 struct adin1110_port_priv *port_priv = netdev_priv(netdev);757 u8 mask[ETH_ALEN];758 u32 port_rules;759 u32 mac_slot;760 761 if (!is_valid_ether_addr(dev_addr))762 return -EADDRNOTAVAIL;763 764 eth_hw_addr_set(netdev, dev_addr);765 eth_broadcast_addr(mask);766 767 mac_slot = (!port_priv->nr) ? ADIN_MAC_P1_ADDR_SLOT : ADIN_MAC_P2_ADDR_SLOT;768 port_rules = adin1110_port_rules(port_priv, true, false);769 770 return adin1110_write_mac_address(port_priv, mac_slot, netdev->dev_addr,771 mask, port_rules);772}773 774static int adin1110_ndo_set_mac_address(struct net_device *netdev, void *addr)775{776 struct sockaddr *sa = addr;777 int ret;778 779 ret = eth_prepare_mac_addr_change(netdev, addr);780 if (ret < 0)781 return ret;782 783 return adin1110_set_mac_address(netdev, sa->sa_data);784}785 786static int adin1110_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)787{788 if (!netif_running(netdev))789 return -EINVAL;790 791 return phy_do_ioctl(netdev, rq, cmd);792}793 794static int adin1110_set_promisc_mode(struct adin1110_port_priv *port_priv,795 bool promisc)796{797 struct adin1110_priv *priv = port_priv->priv;798 u32 mask;799 800 if (port_priv->state != BR_STATE_FORWARDING)801 promisc = false;802 803 if (!port_priv->nr)804 mask = ADIN1110_FWD_UNK2HOST;805 else806 mask = ADIN2111_P2_FWD_UNK2HOST;807 808 return adin1110_set_bits(priv, ADIN1110_CONFIG2,809 mask, promisc ? mask : 0);810}811 812static int adin1110_setup_rx_mode(struct adin1110_port_priv *port_priv)813{814 int ret;815 816 ret = adin1110_set_promisc_mode(port_priv,817 !!(port_priv->flags & IFF_PROMISC));818 if (ret < 0)819 return ret;820 821 ret = adin1110_multicast_filter(port_priv, ADIN_MAC_MULTICAST_ADDR_SLOT,822 !!(port_priv->flags & IFF_ALLMULTI));823 if (ret < 0)824 return ret;825 826 ret = adin1110_broadcasts_filter(port_priv,827 ADIN_MAC_BROADCAST_ADDR_SLOT,828 !!(port_priv->flags & IFF_BROADCAST));829 if (ret < 0)830 return ret;831 832 return adin1110_set_bits(port_priv->priv, ADIN1110_CONFIG1,833 ADIN1110_CONFIG1_SYNC, ADIN1110_CONFIG1_SYNC);834}835 836static bool adin1110_can_offload_forwarding(struct adin1110_priv *priv)837{838 int i;839 840 if (priv->cfg->id != ADIN2111_MAC)841 return false;842 843 /* Can't enable forwarding if ports do not belong to the same bridge */844 if (priv->ports[0]->bridge != priv->ports[1]->bridge || !priv->ports[0]->bridge)845 return false;846 847 /* Can't enable forwarding if there is a port848 * that has been blocked by STP.849 */850 for (i = 0; i < priv->cfg->ports_nr; i++) {851 if (priv->ports[i]->state != BR_STATE_FORWARDING)852 return false;853 }854 855 return true;856}857 858static void adin1110_rx_mode_work(struct work_struct *work)859{860 struct adin1110_port_priv *port_priv;861 struct adin1110_priv *priv;862 863 port_priv = container_of(work, struct adin1110_port_priv, rx_mode_work);864 priv = port_priv->priv;865 866 mutex_lock(&priv->lock);867 adin1110_setup_rx_mode(port_priv);868 mutex_unlock(&priv->lock);869}870 871static void adin1110_set_rx_mode(struct net_device *dev)872{873 struct adin1110_port_priv *port_priv = netdev_priv(dev);874 struct adin1110_priv *priv = port_priv->priv;875 876 spin_lock(&priv->state_lock);877 878 port_priv->flags = dev->flags;879 schedule_work(&port_priv->rx_mode_work);880 881 spin_unlock(&priv->state_lock);882}883 884static int adin1110_net_open(struct net_device *net_dev)885{886 struct adin1110_port_priv *port_priv = netdev_priv(net_dev);887 struct adin1110_priv *priv = port_priv->priv;888 u32 val;889 int ret;890 891 mutex_lock(&priv->lock);892 893 /* Configure MAC to compute and append the FCS itself. */894 ret = adin1110_write_reg(priv, ADIN1110_CONFIG2, ADIN1110_CRC_APPEND);895 if (ret < 0)896 goto out;897 898 val = ADIN1110_TX_RDY_IRQ | ADIN1110_RX_RDY_IRQ | ADIN1110_SPI_ERR_IRQ;899 if (priv->cfg->id == ADIN2111_MAC)900 val |= ADIN2111_RX_RDY_IRQ;901 902 priv->irq_mask = val;903 ret = adin1110_write_reg(priv, ADIN1110_IMASK1, ~val);904 if (ret < 0) {905 netdev_err(net_dev, "Failed to enable chip IRQs: %d\n", ret);906 goto out;907 }908 909 ret = adin1110_read_reg(priv, ADIN1110_TX_SPACE, &val);910 if (ret < 0) {911 netdev_err(net_dev, "Failed to read TX FIFO space: %d\n", ret);912 goto out;913 }914 915 priv->tx_space = 2 * val;916 917 port_priv->state = BR_STATE_FORWARDING;918 ret = adin1110_set_mac_address(net_dev, net_dev->dev_addr);919 if (ret < 0) {920 netdev_err(net_dev, "Could not set MAC address: %pM, %d\n",921 net_dev->dev_addr, ret);922 goto out;923 }924 925 ret = adin1110_set_bits(priv, ADIN1110_CONFIG1, ADIN1110_CONFIG1_SYNC,926 ADIN1110_CONFIG1_SYNC);927 928out:929 mutex_unlock(&priv->lock);930 931 if (ret < 0)932 return ret;933 934 phy_start(port_priv->phydev);935 936 netif_start_queue(net_dev);937 938 return 0;939}940 941static int adin1110_net_stop(struct net_device *net_dev)942{943 struct adin1110_port_priv *port_priv = netdev_priv(net_dev);944 struct adin1110_priv *priv = port_priv->priv;945 u32 mask;946 int ret;947 948 mask = !port_priv->nr ? ADIN2111_RX_RDY_IRQ : ADIN1110_RX_RDY_IRQ;949 950 /* Disable RX RDY IRQs */951 mutex_lock(&priv->lock);952 ret = adin1110_set_bits(priv, ADIN1110_IMASK1, mask, mask);953 mutex_unlock(&priv->lock);954 if (ret < 0)955 return ret;956 957 netif_stop_queue(port_priv->netdev);958 flush_work(&port_priv->tx_work);959 phy_stop(port_priv->phydev);960 961 return 0;962}963 964static void adin1110_tx_work(struct work_struct *work)965{966 struct adin1110_port_priv *port_priv;967 struct adin1110_priv *priv;968 struct sk_buff *txb;969 int ret;970 971 port_priv = container_of(work, struct adin1110_port_priv, tx_work);972 priv = port_priv->priv;973 974 mutex_lock(&priv->lock);975 976 while ((txb = skb_dequeue(&port_priv->txq))) {977 ret = adin1110_write_fifo(port_priv, txb);978 if (ret < 0)979 dev_err_ratelimited(&priv->spidev->dev,980 "Frame write error: %d\n", ret);981 982 dev_kfree_skb(txb);983 }984 985 mutex_unlock(&priv->lock);986}987 988static netdev_tx_t adin1110_start_xmit(struct sk_buff *skb, struct net_device *dev)989{990 struct adin1110_port_priv *port_priv = netdev_priv(dev);991 struct adin1110_priv *priv = port_priv->priv;992 netdev_tx_t netdev_ret = NETDEV_TX_OK;993 u32 tx_space_needed;994 995 tx_space_needed = skb->len + ADIN1110_FRAME_HEADER_LEN + ADIN1110_INTERNAL_SIZE_HEADER_LEN;996 if (tx_space_needed > priv->tx_space) {997 netif_stop_queue(dev);998 netdev_ret = NETDEV_TX_BUSY;999 } else {1000 priv->tx_space -= tx_space_needed;1001 skb_queue_tail(&port_priv->txq, skb);1002 }1003 1004 schedule_work(&port_priv->tx_work);1005 1006 return netdev_ret;1007}1008 1009static void adin1110_ndo_get_stats64(struct net_device *dev,1010 struct rtnl_link_stats64 *storage)1011{1012 struct adin1110_port_priv *port_priv = netdev_priv(dev);1013 1014 storage->rx_packets = port_priv->rx_packets;1015 storage->tx_packets = port_priv->tx_packets;1016 1017 storage->rx_bytes = port_priv->rx_bytes;1018 storage->tx_bytes = port_priv->tx_bytes;1019}1020 1021static int adin1110_port_get_port_parent_id(struct net_device *dev,1022 struct netdev_phys_item_id *ppid)1023{1024 struct adin1110_port_priv *port_priv = netdev_priv(dev);1025 struct adin1110_priv *priv = port_priv->priv;1026 1027 ppid->id_len = strnlen(priv->mii_bus_name, MAX_PHYS_ITEM_ID_LEN);1028 memcpy(ppid->id, priv->mii_bus_name, ppid->id_len);1029 1030 return 0;1031}1032 1033static int adin1110_ndo_get_phys_port_name(struct net_device *dev,1034 char *name, size_t len)1035{1036 struct adin1110_port_priv *port_priv = netdev_priv(dev);1037 int err;1038 1039 err = snprintf(name, len, "p%d", port_priv->nr);1040 if (err >= len)1041 return -EINVAL;1042 1043 return 0;1044}1045 1046static const struct net_device_ops adin1110_netdev_ops = {1047 .ndo_open = adin1110_net_open,1048 .ndo_stop = adin1110_net_stop,1049 .ndo_eth_ioctl = adin1110_ioctl,1050 .ndo_start_xmit = adin1110_start_xmit,1051 .ndo_set_mac_address = adin1110_ndo_set_mac_address,1052 .ndo_set_rx_mode = adin1110_set_rx_mode,1053 .ndo_validate_addr = eth_validate_addr,1054 .ndo_get_stats64 = adin1110_ndo_get_stats64,1055 .ndo_get_port_parent_id = adin1110_port_get_port_parent_id,1056 .ndo_get_phys_port_name = adin1110_ndo_get_phys_port_name,1057};1058 1059static void adin1110_get_drvinfo(struct net_device *dev,1060 struct ethtool_drvinfo *di)1061{1062 strscpy(di->driver, "ADIN1110", sizeof(di->driver));1063 strscpy(di->bus_info, dev_name(dev->dev.parent), sizeof(di->bus_info));1064}1065 1066static const struct ethtool_ops adin1110_ethtool_ops = {1067 .get_drvinfo = adin1110_get_drvinfo,1068 .get_link = ethtool_op_get_link,1069 .get_link_ksettings = phy_ethtool_get_link_ksettings,1070 .set_link_ksettings = phy_ethtool_set_link_ksettings,1071};1072 1073static void adin1110_adjust_link(struct net_device *dev)1074{1075 struct phy_device *phydev = dev->phydev;1076 1077 if (!phydev->link)1078 phy_print_status(phydev);1079}1080 1081/* PHY ID is stored in the MAC registers too,1082 * check spi connection by reading it.1083 */1084static int adin1110_check_spi(struct adin1110_priv *priv)1085{1086 struct gpio_desc *reset_gpio;1087 int ret;1088 u32 val;1089 1090 reset_gpio = devm_gpiod_get_optional(&priv->spidev->dev, "reset",1091 GPIOD_OUT_LOW);1092 if (reset_gpio) {1093 /* MISO pin is used for internal configuration, can't have1094 * anyone else disturbing the SDO line.1095 */1096 spi_bus_lock(priv->spidev->controller);1097 1098 gpiod_set_value(reset_gpio, 1);1099 fsleep(10000);1100 gpiod_set_value(reset_gpio, 0);1101 1102 /* Need to wait 90 ms before interacting with1103 * the MAC after a HW reset.1104 */1105 fsleep(90000);1106 1107 spi_bus_unlock(priv->spidev->controller);1108 }1109 1110 ret = adin1110_read_reg(priv, ADIN1110_PHY_ID, &val);1111 if (ret < 0)1112 return ret;1113 1114 if (val != priv->cfg->phy_id_val) {1115 dev_err(&priv->spidev->dev, "PHY ID expected: %x, read: %x\n",1116 priv->cfg->phy_id_val, val);1117 return -EIO;1118 }1119 1120 return 0;1121}1122 1123static int adin1110_hw_forwarding(struct adin1110_priv *priv, bool enable)1124{1125 int ret;1126 int i;1127 1128 priv->forwarding = enable;1129 1130 if (!priv->forwarding) {1131 for (i = ADIN_MAC_FDB_ADDR_SLOT; i < ADIN_MAC_MAX_ADDR_SLOTS; i++) {1132 ret = adin1110_clear_mac_address(priv, i);1133 if (ret < 0)1134 return ret;1135 }1136 }1137 1138 /* Forwarding is optimised when MAC runs in Cut Through mode. */1139 ret = adin1110_set_bits(priv, ADIN1110_CONFIG2,1140 ADIN2111_PORT_CUT_THRU_EN,1141 priv->forwarding ? ADIN2111_PORT_CUT_THRU_EN : 0);1142 if (ret < 0)1143 return ret;1144 1145 for (i = 0; i < priv->cfg->ports_nr; i++) {1146 ret = adin1110_setup_rx_mode(priv->ports[i]);1147 if (ret < 0)1148 return ret;1149 }1150 1151 return ret;1152}1153 1154static int adin1110_port_bridge_join(struct adin1110_port_priv *port_priv,1155 struct net_device *bridge)1156{1157 struct adin1110_priv *priv = port_priv->priv;1158 int ret;1159 1160 port_priv->bridge = bridge;1161 1162 if (adin1110_can_offload_forwarding(priv)) {1163 mutex_lock(&priv->lock);1164 ret = adin1110_hw_forwarding(priv, true);1165 mutex_unlock(&priv->lock);1166 1167 if (ret < 0)1168 return ret;1169 }1170 1171 return adin1110_set_mac_address(port_priv->netdev, bridge->dev_addr);1172}1173 1174static int adin1110_port_bridge_leave(struct adin1110_port_priv *port_priv,1175 struct net_device *bridge)1176{1177 struct adin1110_priv *priv = port_priv->priv;1178 int ret;1179 1180 port_priv->bridge = NULL;1181 1182 mutex_lock(&priv->lock);1183 ret = adin1110_hw_forwarding(priv, false);1184 mutex_unlock(&priv->lock);1185 1186 return ret;1187}1188 1189static bool adin1110_port_dev_check(const struct net_device *dev)1190{1191 return dev->netdev_ops == &adin1110_netdev_ops;1192}1193 1194static int adin1110_netdevice_event(struct notifier_block *unused,1195 unsigned long event, void *ptr)1196{1197 struct net_device *dev = netdev_notifier_info_to_dev(ptr);1198 struct adin1110_port_priv *port_priv = netdev_priv(dev);1199 struct netdev_notifier_changeupper_info *info = ptr;1200 int ret = 0;1201 1202 if (!adin1110_port_dev_check(dev))1203 return NOTIFY_DONE;1204 1205 switch (event) {1206 case NETDEV_CHANGEUPPER:1207 if (netif_is_bridge_master(info->upper_dev)) {1208 if (info->linking)1209 ret = adin1110_port_bridge_join(port_priv, info->upper_dev);1210 else1211 ret = adin1110_port_bridge_leave(port_priv, info->upper_dev);1212 }1213 break;1214 default:1215 break;1216 }1217 1218 return notifier_from_errno(ret);1219}1220 1221static struct notifier_block adin1110_netdevice_nb = {1222 .notifier_call = adin1110_netdevice_event,1223};1224 1225static void adin1110_disconnect_phy(void *data)1226{1227 phy_disconnect(data);1228}1229 1230static int adin1110_port_set_forwarding_state(struct adin1110_port_priv *port_priv)1231{1232 struct adin1110_priv *priv = port_priv->priv;1233 int ret;1234 1235 port_priv->state = BR_STATE_FORWARDING;1236 1237 mutex_lock(&priv->lock);1238 ret = adin1110_set_mac_address(port_priv->netdev,1239 port_priv->netdev->dev_addr);1240 if (ret < 0)1241 goto out;1242 1243 if (adin1110_can_offload_forwarding(priv))1244 ret = adin1110_hw_forwarding(priv, true);1245 else1246 ret = adin1110_setup_rx_mode(port_priv);1247out:1248 mutex_unlock(&priv->lock);1249 1250 return ret;1251}1252 1253static int adin1110_port_set_blocking_state(struct adin1110_port_priv *port_priv)1254{1255 u8 mac[ETH_ALEN] = {0x01, 0x80, 0xC2, 0x00, 0x00, 0x00};1256 struct adin1110_priv *priv = port_priv->priv;1257 u8 mask[ETH_ALEN];1258 u32 port_rules;1259 int mac_slot;1260 int ret;1261 1262 port_priv->state = BR_STATE_BLOCKING;1263 1264 mutex_lock(&priv->lock);1265 1266 mac_slot = (!port_priv->nr) ? ADIN_MAC_P1_ADDR_SLOT : ADIN_MAC_P2_ADDR_SLOT;1267 ret = adin1110_clear_mac_address(priv, mac_slot);1268 if (ret < 0)1269 goto out;1270 1271 ret = adin1110_hw_forwarding(priv, false);1272 if (ret < 0)1273 goto out;1274 1275 /* Allow only BPDUs to be passed to the CPU */1276 eth_broadcast_addr(mask);1277 port_rules = adin1110_port_rules(port_priv, true, false);1278 ret = adin1110_write_mac_address(port_priv, mac_slot, mac,1279 mask, port_rules);1280out:1281 mutex_unlock(&priv->lock);1282 1283 return ret;1284}1285 1286/* ADIN1110/2111 does not have any native STP support.1287 * Listen for bridge core state changes and1288 * allow all frames to pass or only the BPDUs.1289 */1290static int adin1110_port_attr_stp_state_set(struct adin1110_port_priv *port_priv,1291 u8 state)1292{1293 switch (state) {1294 case BR_STATE_FORWARDING:1295 return adin1110_port_set_forwarding_state(port_priv);1296 case BR_STATE_LEARNING:1297 case BR_STATE_LISTENING:1298 case BR_STATE_DISABLED:1299 case BR_STATE_BLOCKING:1300 return adin1110_port_set_blocking_state(port_priv);1301 default:1302 return -EINVAL;1303 }1304}1305 1306static int adin1110_port_attr_set(struct net_device *dev, const void *ctx,1307 const struct switchdev_attr *attr,1308 struct netlink_ext_ack *extack)1309{1310 struct adin1110_port_priv *port_priv = netdev_priv(dev);1311 1312 switch (attr->id) {1313 case SWITCHDEV_ATTR_ID_PORT_STP_STATE:1314 return adin1110_port_attr_stp_state_set(port_priv,1315 attr->u.stp_state);1316 default:1317 return -EOPNOTSUPP;1318 }1319}1320 1321static int adin1110_switchdev_blocking_event(struct notifier_block *unused,1322 unsigned long event,1323 void *ptr)1324{1325 struct net_device *netdev = switchdev_notifier_info_to_dev(ptr);1326 int ret;1327 1328 if (event == SWITCHDEV_PORT_ATTR_SET) {1329 ret = switchdev_handle_port_attr_set(netdev, ptr,1330 adin1110_port_dev_check,1331 adin1110_port_attr_set);1332 1333 return notifier_from_errno(ret);1334 }1335 1336 return NOTIFY_DONE;1337}1338 1339static struct notifier_block adin1110_switchdev_blocking_notifier = {1340 .notifier_call = adin1110_switchdev_blocking_event,1341};1342 1343static void adin1110_fdb_offload_notify(struct net_device *netdev,1344 struct switchdev_notifier_fdb_info *rcv)1345{1346 struct switchdev_notifier_fdb_info info = {};1347 1348 info.addr = rcv->addr;1349 info.vid = rcv->vid;1350 info.offloaded = true;1351 call_switchdev_notifiers(SWITCHDEV_FDB_OFFLOADED,1352 netdev, &info.info, NULL);1353}1354 1355static int adin1110_fdb_add(struct adin1110_port_priv *port_priv,1356 struct switchdev_notifier_fdb_info *fdb)1357{1358 struct adin1110_priv *priv = port_priv->priv;1359 struct adin1110_port_priv *other_port;1360 u8 mask[ETH_ALEN];1361 u32 port_rules;1362 int mac_nr;1363 u32 val;1364 int ret;1365 1366 netdev_dbg(port_priv->netdev,1367 "DEBUG: %s: MACID = %pM vid = %u flags = %u %u -- port %d\n",1368 __func__, fdb->addr, fdb->vid, fdb->added_by_user,1369 fdb->offloaded, port_priv->nr);1370 1371 if (!priv->forwarding)1372 return 0;1373 1374 if (fdb->is_local)1375 return -EINVAL;1376 1377 /* Find free FDB slot on device. */1378 for (mac_nr = ADIN_MAC_FDB_ADDR_SLOT; mac_nr < ADIN_MAC_MAX_ADDR_SLOTS; mac_nr++) {1379 ret = adin1110_read_reg(priv, ADIN1110_MAC_ADDR_FILTER_UPR + (mac_nr * 2), &val);1380 if (ret < 0)1381 return ret;1382 if (!val)1383 break;1384 }1385 1386 if (mac_nr == ADIN_MAC_MAX_ADDR_SLOTS)1387 return -ENOMEM;1388 1389 other_port = priv->ports[!port_priv->nr];1390 port_rules = adin1110_port_rules(other_port, false, true);1391 eth_broadcast_addr(mask);1392 1393 return adin1110_write_mac_address(other_port, mac_nr, (u8 *)fdb->addr,1394 mask, port_rules);1395}1396 1397static int adin1110_read_mac(struct adin1110_priv *priv, int mac_nr, u8 *addr)1398{1399 u32 val;1400 int ret;1401 1402 ret = adin1110_read_reg(priv, ADIN1110_MAC_ADDR_FILTER_UPR + (mac_nr * 2), &val);1403 if (ret < 0)1404 return ret;1405 1406 put_unaligned_be16(val, addr);1407 1408 ret = adin1110_read_reg(priv, ADIN1110_MAC_ADDR_FILTER_LWR + (mac_nr * 2), &val);1409 if (ret < 0)1410 return ret;1411 1412 put_unaligned_be32(val, addr + 2);1413 1414 return 0;1415}1416 1417static int adin1110_fdb_del(struct adin1110_port_priv *port_priv,1418 struct switchdev_notifier_fdb_info *fdb)1419{1420 struct adin1110_priv *priv = port_priv->priv;1421 u8 addr[ETH_ALEN];1422 int mac_nr;1423 int ret;1424 1425 netdev_dbg(port_priv->netdev,1426 "DEBUG: %s: MACID = %pM vid = %u flags = %u %u -- port %d\n",1427 __func__, fdb->addr, fdb->vid, fdb->added_by_user,1428 fdb->offloaded, port_priv->nr);1429 1430 if (fdb->is_local)1431 return -EINVAL;1432 1433 for (mac_nr = ADIN_MAC_FDB_ADDR_SLOT; mac_nr < ADIN_MAC_MAX_ADDR_SLOTS; mac_nr++) {1434 ret = adin1110_read_mac(priv, mac_nr, addr);1435 if (ret < 0)1436 return ret;1437 1438 if (ether_addr_equal(addr, fdb->addr)) {1439 ret = adin1110_clear_mac_address(priv, mac_nr);1440 if (ret < 0)1441 return ret;1442 }1443 }1444 1445 return 0;1446}1447 1448static void adin1110_switchdev_event_work(struct work_struct *work)1449{1450 struct adin1110_switchdev_event_work *switchdev_work;1451 struct adin1110_port_priv *port_priv;1452 int ret;1453 1454 switchdev_work = container_of(work, struct adin1110_switchdev_event_work, work);1455 port_priv = switchdev_work->port_priv;1456 1457 mutex_lock(&port_priv->priv->lock);1458 1459 switch (switchdev_work->event) {1460 case SWITCHDEV_FDB_ADD_TO_DEVICE:1461 ret = adin1110_fdb_add(port_priv, &switchdev_work->fdb_info);1462 if (!ret)1463 adin1110_fdb_offload_notify(port_priv->netdev,1464 &switchdev_work->fdb_info);1465 break;1466 case SWITCHDEV_FDB_DEL_TO_DEVICE:1467 adin1110_fdb_del(port_priv, &switchdev_work->fdb_info);1468 break;1469 default:1470 break;1471 }1472 1473 mutex_unlock(&port_priv->priv->lock);1474 1475 kfree(switchdev_work->fdb_info.addr);1476 kfree(switchdev_work);1477 dev_put(port_priv->netdev);1478}1479 1480/* called under rcu_read_lock() */1481static int adin1110_switchdev_event(struct notifier_block *unused,1482 unsigned long event, void *ptr)1483{1484 struct net_device *netdev = switchdev_notifier_info_to_dev(ptr);1485 struct adin1110_port_priv *port_priv = netdev_priv(netdev);1486 struct adin1110_switchdev_event_work *switchdev_work;1487 struct switchdev_notifier_fdb_info *fdb_info = ptr;1488 1489 if (!adin1110_port_dev_check(netdev))1490 return NOTIFY_DONE;1491 1492 switchdev_work = kzalloc(sizeof(*switchdev_work), GFP_ATOMIC);1493 if (WARN_ON(!switchdev_work))1494 return NOTIFY_BAD;1495 1496 INIT_WORK(&switchdev_work->work, adin1110_switchdev_event_work);1497 switchdev_work->port_priv = port_priv;1498 switchdev_work->event = event;1499 1500 switch (event) {1501 case SWITCHDEV_FDB_ADD_TO_DEVICE:1502 case SWITCHDEV_FDB_DEL_TO_DEVICE:1503 memcpy(&switchdev_work->fdb_info, ptr,1504 sizeof(switchdev_work->fdb_info));1505 switchdev_work->fdb_info.addr = kzalloc(ETH_ALEN, GFP_ATOMIC);1506 1507 if (!switchdev_work->fdb_info.addr)1508 goto err_addr_alloc;1509 1510 ether_addr_copy((u8 *)switchdev_work->fdb_info.addr,1511 fdb_info->addr);1512 dev_hold(netdev);1513 break;1514 default:1515 kfree(switchdev_work);1516 return NOTIFY_DONE;1517 }1518 1519 queue_work(system_long_wq, &switchdev_work->work);1520 1521 return NOTIFY_DONE;1522 1523err_addr_alloc:1524 kfree(switchdev_work);1525 return NOTIFY_BAD;1526}1527 1528static struct notifier_block adin1110_switchdev_notifier = {1529 .notifier_call = adin1110_switchdev_event,1530};1531 1532static void adin1110_unregister_notifiers(void)1533{1534 unregister_switchdev_blocking_notifier(&adin1110_switchdev_blocking_notifier);1535 unregister_switchdev_notifier(&adin1110_switchdev_notifier);1536 unregister_netdevice_notifier(&adin1110_netdevice_nb);1537}1538 1539static int adin1110_setup_notifiers(void)1540{1541 int ret;1542 1543 ret = register_netdevice_notifier(&adin1110_netdevice_nb);1544 if (ret < 0)1545 return ret;1546 1547 ret = register_switchdev_notifier(&adin1110_switchdev_notifier);1548 if (ret < 0)1549 goto err_netdev;1550 1551 ret = register_switchdev_blocking_notifier(&adin1110_switchdev_blocking_notifier);1552 if (ret < 0)1553 goto err_sdev;1554 1555 return 0;1556 1557err_sdev:1558 unregister_switchdev_notifier(&adin1110_switchdev_notifier);1559 1560err_netdev:1561 unregister_netdevice_notifier(&adin1110_netdevice_nb);1562 1563 return ret;1564}1565 1566static int adin1110_probe_netdevs(struct adin1110_priv *priv)1567{1568 struct device *dev = &priv->spidev->dev;1569 struct adin1110_port_priv *port_priv;1570 struct net_device *netdev;1571 int ret;1572 int i;1573 1574 for (i = 0; i < priv->cfg->ports_nr; i++) {1575 netdev = devm_alloc_etherdev(dev, sizeof(*port_priv));1576 if (!netdev)1577 return -ENOMEM;1578 1579 port_priv = netdev_priv(netdev);1580 port_priv->netdev = netdev;1581 port_priv->priv = priv;1582 port_priv->cfg = priv->cfg;1583 port_priv->nr = i;1584 priv->ports[i] = port_priv;1585 SET_NETDEV_DEV(netdev, dev);1586 1587 ret = device_get_ethdev_address(dev, netdev);1588 if (ret < 0)1589 return ret;1590 1591 netdev->irq = priv->spidev->irq;1592 INIT_WORK(&port_priv->tx_work, adin1110_tx_work);1593 INIT_WORK(&port_priv->rx_mode_work, adin1110_rx_mode_work);1594 skb_queue_head_init(&port_priv->txq);1595 1596 netif_carrier_off(netdev);1597 1598 netdev->if_port = IF_PORT_10BASET;1599 netdev->netdev_ops = &adin1110_netdev_ops;1600 netdev->ethtool_ops = &adin1110_ethtool_ops;1601 netdev->priv_flags |= IFF_UNICAST_FLT;1602 netdev->netns_local = true;1603 1604 port_priv->phydev = get_phy_device(priv->mii_bus, i + 1, false);1605 if (IS_ERR(port_priv->phydev)) {1606 netdev_err(netdev, "Could not find PHY with device address: %d.\n", i);1607 return PTR_ERR(port_priv->phydev);1608 }1609 1610 port_priv->phydev = phy_connect(netdev,1611 phydev_name(port_priv->phydev),1612 adin1110_adjust_link,1613 PHY_INTERFACE_MODE_INTERNAL);1614 if (IS_ERR(port_priv->phydev)) {1615 netdev_err(netdev, "Could not connect PHY with device address: %d.\n", i);1616 return PTR_ERR(port_priv->phydev);1617 }1618 1619 ret = devm_add_action_or_reset(dev, adin1110_disconnect_phy,1620 port_priv->phydev);1621 if (ret < 0)1622 return ret;1623 }1624 1625 /* ADIN1110 INT_N pin will be used to signal the host */1626 ret = devm_request_threaded_irq(dev, priv->spidev->irq, NULL,1627 adin1110_irq,1628 IRQF_TRIGGER_LOW | IRQF_ONESHOT,1629 dev_name(dev), priv);1630 if (ret < 0)1631 return ret;1632 1633 for (i = 0; i < priv->cfg->ports_nr; i++) {1634 ret = devm_register_netdev(dev, priv->ports[i]->netdev);1635 if (ret < 0) {1636 dev_err(dev, "Failed to register network device.\n");1637 return ret;1638 }1639 }1640 1641 return 0;1642}1643 1644static int adin1110_probe(struct spi_device *spi)1645{1646 const struct spi_device_id *dev_id = spi_get_device_id(spi);1647 struct device *dev = &spi->dev;1648 struct adin1110_priv *priv;1649 int ret;1650 1651 priv = devm_kzalloc(dev, sizeof(struct adin1110_priv), GFP_KERNEL);1652 if (!priv)1653 return -ENOMEM;1654 1655 priv->spidev = spi;1656 priv->cfg = &adin1110_cfgs[dev_id->driver_data];1657 spi->bits_per_word = 8;1658 spi->mode = SPI_MODE_0;1659 1660 mutex_init(&priv->lock);1661 spin_lock_init(&priv->state_lock);1662 1663 /* use of CRC on control and data transactions is pin dependent */1664 priv->append_crc = device_property_read_bool(dev, "adi,spi-crc");1665 if (priv->append_crc)1666 crc8_populate_msb(adin1110_crc_table, 0x7);1667 1668 ret = adin1110_check_spi(priv);1669 if (ret < 0) {1670 dev_err(dev, "Probe SPI Read check failed: %d\n", ret);1671 return ret;1672 }1673 1674 ret = adin1110_write_reg(priv, ADIN1110_RESET, ADIN1110_SWRESET);1675 if (ret < 0)1676 return ret;1677 1678 ret = adin1110_register_mdiobus(priv, dev);1679 if (ret < 0) {1680 dev_err(dev, "Could not register MDIO bus %d\n", ret);1681 return ret;1682 }1683 1684 return adin1110_probe_netdevs(priv);1685}1686 1687static const struct of_device_id adin1110_match_table[] = {1688 { .compatible = "adi,adin1110" },1689 { .compatible = "adi,adin2111" },1690 { }1691};1692MODULE_DEVICE_TABLE(of, adin1110_match_table);1693 1694static const struct spi_device_id adin1110_spi_id[] = {1695 { .name = "adin1110", .driver_data = ADIN1110_MAC },1696 { .name = "adin2111", .driver_data = ADIN2111_MAC },1697 { }1698};1699MODULE_DEVICE_TABLE(spi, adin1110_spi_id);1700 1701static struct spi_driver adin1110_driver = {1702 .driver = {1703 .name = "adin1110",1704 .of_match_table = adin1110_match_table,1705 },1706 .probe = adin1110_probe,1707 .id_table = adin1110_spi_id,1708};1709 1710static int __init adin1110_driver_init(void)1711{1712 int ret;1713 1714 ret = adin1110_setup_notifiers();1715 if (ret < 0)1716 return ret;1717 1718 ret = spi_register_driver(&adin1110_driver);1719 if (ret < 0) {1720 adin1110_unregister_notifiers();1721 return ret;1722 }1723 1724 return 0;1725}1726 1727static void __exit adin1110_exit(void)1728{1729 adin1110_unregister_notifiers();1730 spi_unregister_driver(&adin1110_driver);1731}1732module_init(adin1110_driver_init);1733module_exit(adin1110_exit);1734 1735MODULE_DESCRIPTION("ADIN1110 Network driver");1736MODULE_AUTHOR("Alexandru Tachici <alexandru.tachici@analog.com>");1737MODULE_LICENSE("Dual BSD/GPL");1738