Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
0002 /* Copyright (c) 2019-2020 Marvell International Ltd. All rights reserved */
0003 
0004 #include <linux/etherdevice.h>
0005 #include <linux/jiffies.h>
0006 #include <linux/list.h>
0007 #include <linux/module.h>
0008 #include <linux/netdev_features.h>
0009 #include <linux/of.h>
0010 #include <linux/of_net.h>
0011 #include <linux/if_vlan.h>
0012 #include <linux/phylink.h>
0013 
0014 #include "prestera.h"
0015 #include "prestera_hw.h"
0016 #include "prestera_acl.h"
0017 #include "prestera_flow.h"
0018 #include "prestera_span.h"
0019 #include "prestera_rxtx.h"
0020 #include "prestera_devlink.h"
0021 #include "prestera_ethtool.h"
0022 #include "prestera_counter.h"
0023 #include "prestera_switchdev.h"
0024 
0025 #define PRESTERA_MTU_DEFAULT    1536
0026 
0027 #define PRESTERA_STATS_DELAY_MS 1000
0028 
0029 #define PRESTERA_MAC_ADDR_NUM_MAX   255
0030 
0031 static struct workqueue_struct *prestera_wq;
0032 static struct workqueue_struct *prestera_owq;
0033 
0034 void prestera_queue_work(struct work_struct *work)
0035 {
0036     queue_work(prestera_owq, work);
0037 }
0038 
0039 int prestera_port_learning_set(struct prestera_port *port, bool learn)
0040 {
0041     return prestera_hw_port_learning_set(port, learn);
0042 }
0043 
0044 int prestera_port_uc_flood_set(struct prestera_port *port, bool flood)
0045 {
0046     return prestera_hw_port_uc_flood_set(port, flood);
0047 }
0048 
0049 int prestera_port_mc_flood_set(struct prestera_port *port, bool flood)
0050 {
0051     return prestera_hw_port_mc_flood_set(port, flood);
0052 }
0053 
0054 int prestera_port_pvid_set(struct prestera_port *port, u16 vid)
0055 {
0056     enum prestera_accept_frm_type frm_type;
0057     int err;
0058 
0059     frm_type = PRESTERA_ACCEPT_FRAME_TYPE_TAGGED;
0060 
0061     if (vid) {
0062         err = prestera_hw_vlan_port_vid_set(port, vid);
0063         if (err)
0064             return err;
0065 
0066         frm_type = PRESTERA_ACCEPT_FRAME_TYPE_ALL;
0067     }
0068 
0069     err = prestera_hw_port_accept_frm_type(port, frm_type);
0070     if (err && frm_type == PRESTERA_ACCEPT_FRAME_TYPE_ALL)
0071         prestera_hw_vlan_port_vid_set(port, port->pvid);
0072 
0073     port->pvid = vid;
0074     return 0;
0075 }
0076 
0077 struct prestera_port *prestera_port_find_by_hwid(struct prestera_switch *sw,
0078                          u32 dev_id, u32 hw_id)
0079 {
0080     struct prestera_port *port = NULL, *tmp;
0081 
0082     read_lock(&sw->port_list_lock);
0083     list_for_each_entry(tmp, &sw->port_list, list) {
0084         if (tmp->dev_id == dev_id && tmp->hw_id == hw_id) {
0085             port = tmp;
0086             break;
0087         }
0088     }
0089     read_unlock(&sw->port_list_lock);
0090 
0091     return port;
0092 }
0093 
0094 struct prestera_port *prestera_find_port(struct prestera_switch *sw, u32 id)
0095 {
0096     struct prestera_port *port = NULL, *tmp;
0097 
0098     read_lock(&sw->port_list_lock);
0099     list_for_each_entry(tmp, &sw->port_list, list) {
0100         if (tmp->id == id) {
0101             port = tmp;
0102             break;
0103         }
0104     }
0105     read_unlock(&sw->port_list_lock);
0106 
0107     return port;
0108 }
0109 
0110 struct prestera_switch *prestera_switch_get(struct net_device *dev)
0111 {
0112     struct prestera_port *port;
0113 
0114     port = prestera_port_dev_lower_find(dev);
0115     return port ? port->sw : NULL;
0116 }
0117 
0118 int prestera_port_cfg_mac_read(struct prestera_port *port,
0119                    struct prestera_port_mac_config *cfg)
0120 {
0121     *cfg = port->cfg_mac;
0122     return 0;
0123 }
0124 
0125 int prestera_port_cfg_mac_write(struct prestera_port *port,
0126                 struct prestera_port_mac_config *cfg)
0127 {
0128     int err;
0129 
0130     err = prestera_hw_port_mac_mode_set(port, cfg->admin,
0131                         cfg->mode, cfg->inband, cfg->speed,
0132                         cfg->duplex, cfg->fec);
0133     if (err)
0134         return err;
0135 
0136     port->cfg_mac = *cfg;
0137     return 0;
0138 }
0139 
0140 static int prestera_port_open(struct net_device *dev)
0141 {
0142     struct prestera_port *port = netdev_priv(dev);
0143     struct prestera_port_mac_config cfg_mac;
0144     int err = 0;
0145 
0146     if (port->phy_link) {
0147         phylink_start(port->phy_link);
0148     } else {
0149         if (port->caps.transceiver == PRESTERA_PORT_TCVR_SFP) {
0150             err = prestera_port_cfg_mac_read(port, &cfg_mac);
0151             if (!err) {
0152                 cfg_mac.admin = true;
0153                 err = prestera_port_cfg_mac_write(port,
0154                                   &cfg_mac);
0155             }
0156         } else {
0157             port->cfg_phy.admin = true;
0158             err = prestera_hw_port_phy_mode_set(port, true,
0159                                 port->autoneg,
0160                                 port->cfg_phy.mode,
0161                                 port->adver_link_modes,
0162                                 port->cfg_phy.mdix);
0163         }
0164     }
0165 
0166     netif_start_queue(dev);
0167 
0168     return err;
0169 }
0170 
0171 static int prestera_port_close(struct net_device *dev)
0172 {
0173     struct prestera_port *port = netdev_priv(dev);
0174     struct prestera_port_mac_config cfg_mac;
0175     int err = 0;
0176 
0177     netif_stop_queue(dev);
0178 
0179     if (port->phy_link) {
0180         phylink_stop(port->phy_link);
0181         phylink_disconnect_phy(port->phy_link);
0182         err = prestera_port_cfg_mac_read(port, &cfg_mac);
0183         if (!err) {
0184             cfg_mac.admin = false;
0185             prestera_port_cfg_mac_write(port, &cfg_mac);
0186         }
0187     } else {
0188         if (port->caps.transceiver == PRESTERA_PORT_TCVR_SFP) {
0189             err = prestera_port_cfg_mac_read(port, &cfg_mac);
0190             if (!err) {
0191                 cfg_mac.admin = false;
0192                 prestera_port_cfg_mac_write(port, &cfg_mac);
0193             }
0194         } else {
0195             port->cfg_phy.admin = false;
0196             err = prestera_hw_port_phy_mode_set(port, false, port->autoneg,
0197                                 port->cfg_phy.mode,
0198                                 port->adver_link_modes,
0199                                 port->cfg_phy.mdix);
0200         }
0201     }
0202 
0203     return err;
0204 }
0205 
0206 static void
0207 prestera_port_mac_state_cache_read(struct prestera_port *port,
0208                    struct prestera_port_mac_state *state)
0209 {
0210     spin_lock(&port->state_mac_lock);
0211     *state = port->state_mac;
0212     spin_unlock(&port->state_mac_lock);
0213 }
0214 
0215 static void
0216 prestera_port_mac_state_cache_write(struct prestera_port *port,
0217                     struct prestera_port_mac_state *state)
0218 {
0219     spin_lock(&port->state_mac_lock);
0220     port->state_mac = *state;
0221     spin_unlock(&port->state_mac_lock);
0222 }
0223 
0224 static struct prestera_port *prestera_pcs_to_port(struct phylink_pcs *pcs)
0225 {
0226     return container_of(pcs, struct prestera_port, phylink_pcs);
0227 }
0228 
0229 static void prestera_mac_config(struct phylink_config *config,
0230                 unsigned int an_mode,
0231                 const struct phylink_link_state *state)
0232 {
0233 }
0234 
0235 static void prestera_mac_link_down(struct phylink_config *config,
0236                    unsigned int mode, phy_interface_t interface)
0237 {
0238     struct net_device *ndev = to_net_dev(config->dev);
0239     struct prestera_port *port = netdev_priv(ndev);
0240     struct prestera_port_mac_state state_mac;
0241 
0242     /* Invalidate. Parameters will update on next link event. */
0243     memset(&state_mac, 0, sizeof(state_mac));
0244     state_mac.valid = false;
0245     prestera_port_mac_state_cache_write(port, &state_mac);
0246 }
0247 
0248 static void prestera_mac_link_up(struct phylink_config *config,
0249                  struct phy_device *phy,
0250                  unsigned int mode, phy_interface_t interface,
0251                  int speed, int duplex,
0252                  bool tx_pause, bool rx_pause)
0253 {
0254 }
0255 
0256 static struct phylink_pcs *
0257 prestera_mac_select_pcs(struct phylink_config *config,
0258             phy_interface_t interface)
0259 {
0260     struct net_device *dev = to_net_dev(config->dev);
0261     struct prestera_port *port = netdev_priv(dev);
0262 
0263     return &port->phylink_pcs;
0264 }
0265 
0266 static void prestera_pcs_get_state(struct phylink_pcs *pcs,
0267                    struct phylink_link_state *state)
0268 {
0269     struct prestera_port *port = container_of(pcs, struct prestera_port,
0270                           phylink_pcs);
0271     struct prestera_port_mac_state smac;
0272 
0273     prestera_port_mac_state_cache_read(port, &smac);
0274 
0275     if (smac.valid) {
0276         state->link = smac.oper ? 1 : 0;
0277         /* AN is completed, when port is up */
0278         state->an_complete = (smac.oper && port->autoneg) ? 1 : 0;
0279         state->speed = smac.speed;
0280         state->duplex = smac.duplex;
0281     } else {
0282         state->link = 0;
0283         state->an_complete = 0;
0284     }
0285 }
0286 
0287 static int prestera_pcs_config(struct phylink_pcs *pcs,
0288                    unsigned int mode,
0289                    phy_interface_t interface,
0290                    const unsigned long *advertising,
0291                    bool permit_pause_to_mac)
0292 {
0293     struct prestera_port *port = prestera_pcs_to_port(pcs);
0294     struct prestera_port_mac_config cfg_mac;
0295     int err;
0296 
0297     err = prestera_port_cfg_mac_read(port, &cfg_mac);
0298     if (err)
0299         return err;
0300 
0301     cfg_mac.admin = true;
0302     cfg_mac.fec = PRESTERA_PORT_FEC_OFF;
0303 
0304     switch (interface) {
0305     case PHY_INTERFACE_MODE_10GBASER:
0306         cfg_mac.speed = SPEED_10000;
0307         cfg_mac.inband = 0;
0308         cfg_mac.mode = PRESTERA_MAC_MODE_SR_LR;
0309         break;
0310     case PHY_INTERFACE_MODE_2500BASEX:
0311         cfg_mac.speed = SPEED_2500;
0312         cfg_mac.duplex = DUPLEX_FULL;
0313         cfg_mac.inband = test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
0314                       advertising);
0315         cfg_mac.mode = PRESTERA_MAC_MODE_SGMII;
0316         break;
0317     case PHY_INTERFACE_MODE_SGMII:
0318         cfg_mac.inband = 1;
0319         cfg_mac.mode = PRESTERA_MAC_MODE_SGMII;
0320         break;
0321     case PHY_INTERFACE_MODE_1000BASEX:
0322     default:
0323         cfg_mac.speed = SPEED_1000;
0324         cfg_mac.duplex = DUPLEX_FULL;
0325         cfg_mac.inband = test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
0326                       advertising);
0327         cfg_mac.mode = PRESTERA_MAC_MODE_1000BASE_X;
0328         break;
0329     }
0330 
0331     err = prestera_port_cfg_mac_write(port, &cfg_mac);
0332     if (err)
0333         return err;
0334 
0335     return 0;
0336 }
0337 
0338 static void prestera_pcs_an_restart(struct phylink_pcs *pcs)
0339 {
0340     /* TODO: add 1000basex AN restart support
0341      * (Currently FW has no support for 1000baseX AN restart, but it will in the future,
0342      * so as for now the function would stay empty.)
0343      */
0344 }
0345 
0346 static const struct phylink_mac_ops prestera_mac_ops = {
0347     .validate = phylink_generic_validate,
0348     .mac_select_pcs = prestera_mac_select_pcs,
0349     .mac_config = prestera_mac_config,
0350     .mac_link_down = prestera_mac_link_down,
0351     .mac_link_up = prestera_mac_link_up,
0352 };
0353 
0354 static const struct phylink_pcs_ops prestera_pcs_ops = {
0355     .pcs_get_state = prestera_pcs_get_state,
0356     .pcs_config = prestera_pcs_config,
0357     .pcs_an_restart = prestera_pcs_an_restart,
0358 };
0359 
0360 static int prestera_port_sfp_bind(struct prestera_port *port)
0361 {
0362     struct prestera_switch *sw = port->sw;
0363     struct device_node *ports, *node;
0364     struct fwnode_handle *fwnode;
0365     struct phylink *phy_link;
0366     int err;
0367 
0368     if (!sw->np)
0369         return 0;
0370 
0371     of_node_get(sw->np);
0372     ports = of_find_node_by_name(sw->np, "ports");
0373 
0374     for_each_child_of_node(ports, node) {
0375         int num;
0376 
0377         err = of_property_read_u32(node, "prestera,port-num", &num);
0378         if (err) {
0379             dev_err(sw->dev->dev,
0380                 "device node %pOF has no valid reg property: %d\n",
0381                 node, err);
0382             goto out;
0383         }
0384 
0385         if (port->fp_id != num)
0386             continue;
0387 
0388         port->phylink_pcs.ops = &prestera_pcs_ops;
0389 
0390         port->phy_config.dev = &port->dev->dev;
0391         port->phy_config.type = PHYLINK_NETDEV;
0392 
0393         fwnode = of_fwnode_handle(node);
0394 
0395         __set_bit(PHY_INTERFACE_MODE_10GBASER,
0396               port->phy_config.supported_interfaces);
0397         __set_bit(PHY_INTERFACE_MODE_2500BASEX,
0398               port->phy_config.supported_interfaces);
0399         __set_bit(PHY_INTERFACE_MODE_SGMII,
0400               port->phy_config.supported_interfaces);
0401         __set_bit(PHY_INTERFACE_MODE_1000BASEX,
0402               port->phy_config.supported_interfaces);
0403 
0404         port->phy_config.mac_capabilities =
0405             MAC_1000 | MAC_2500FD | MAC_10000FD;
0406 
0407         phy_link = phylink_create(&port->phy_config, fwnode,
0408                       PHY_INTERFACE_MODE_INTERNAL,
0409                       &prestera_mac_ops);
0410         if (IS_ERR(phy_link)) {
0411             netdev_err(port->dev, "failed to create phylink\n");
0412             err = PTR_ERR(phy_link);
0413             goto out;
0414         }
0415 
0416         port->phy_link = phy_link;
0417         break;
0418     }
0419 
0420 out:
0421     of_node_put(node);
0422     of_node_put(ports);
0423     return err;
0424 }
0425 
0426 static int prestera_port_sfp_unbind(struct prestera_port *port)
0427 {
0428     if (port->phy_link)
0429         phylink_destroy(port->phy_link);
0430 
0431     return 0;
0432 }
0433 
0434 static netdev_tx_t prestera_port_xmit(struct sk_buff *skb,
0435                       struct net_device *dev)
0436 {
0437     return prestera_rxtx_xmit(netdev_priv(dev), skb);
0438 }
0439 
0440 int prestera_is_valid_mac_addr(struct prestera_port *port, const u8 *addr)
0441 {
0442     if (!is_valid_ether_addr(addr))
0443         return -EADDRNOTAVAIL;
0444 
0445     /* firmware requires that port's MAC address contains first 5 bytes
0446      * of the base MAC address
0447      */
0448     if (memcmp(port->sw->base_mac, addr, ETH_ALEN - 1))
0449         return -EINVAL;
0450 
0451     return 0;
0452 }
0453 
0454 static int prestera_port_set_mac_address(struct net_device *dev, void *p)
0455 {
0456     struct prestera_port *port = netdev_priv(dev);
0457     struct sockaddr *addr = p;
0458     int err;
0459 
0460     err = prestera_is_valid_mac_addr(port, addr->sa_data);
0461     if (err)
0462         return err;
0463 
0464     err = prestera_hw_port_mac_set(port, addr->sa_data);
0465     if (err)
0466         return err;
0467 
0468     eth_hw_addr_set(dev, addr->sa_data);
0469 
0470     return 0;
0471 }
0472 
0473 static int prestera_port_change_mtu(struct net_device *dev, int mtu)
0474 {
0475     struct prestera_port *port = netdev_priv(dev);
0476     int err;
0477 
0478     err = prestera_hw_port_mtu_set(port, mtu);
0479     if (err)
0480         return err;
0481 
0482     dev->mtu = mtu;
0483 
0484     return 0;
0485 }
0486 
0487 static void prestera_port_get_stats64(struct net_device *dev,
0488                       struct rtnl_link_stats64 *stats)
0489 {
0490     struct prestera_port *port = netdev_priv(dev);
0491     struct prestera_port_stats *port_stats = &port->cached_hw_stats.stats;
0492 
0493     stats->rx_packets = port_stats->broadcast_frames_received +
0494                 port_stats->multicast_frames_received +
0495                 port_stats->unicast_frames_received;
0496 
0497     stats->tx_packets = port_stats->broadcast_frames_sent +
0498                 port_stats->multicast_frames_sent +
0499                 port_stats->unicast_frames_sent;
0500 
0501     stats->rx_bytes = port_stats->good_octets_received;
0502 
0503     stats->tx_bytes = port_stats->good_octets_sent;
0504 
0505     stats->rx_errors = port_stats->rx_error_frame_received;
0506     stats->tx_errors = port_stats->mac_trans_error;
0507 
0508     stats->rx_dropped = port_stats->buffer_overrun;
0509     stats->tx_dropped = 0;
0510 
0511     stats->multicast = port_stats->multicast_frames_received;
0512     stats->collisions = port_stats->excessive_collision;
0513 
0514     stats->rx_crc_errors = port_stats->bad_crc;
0515 }
0516 
0517 static void prestera_port_get_hw_stats(struct prestera_port *port)
0518 {
0519     prestera_hw_port_stats_get(port, &port->cached_hw_stats.stats);
0520 }
0521 
0522 static void prestera_port_stats_update(struct work_struct *work)
0523 {
0524     struct prestera_port *port =
0525         container_of(work, struct prestera_port,
0526                  cached_hw_stats.caching_dw.work);
0527 
0528     prestera_port_get_hw_stats(port);
0529 
0530     queue_delayed_work(prestera_wq, &port->cached_hw_stats.caching_dw,
0531                msecs_to_jiffies(PRESTERA_STATS_DELAY_MS));
0532 }
0533 
0534 static int prestera_port_setup_tc(struct net_device *dev,
0535                   enum tc_setup_type type,
0536                   void *type_data)
0537 {
0538     struct prestera_port *port = netdev_priv(dev);
0539 
0540     switch (type) {
0541     case TC_SETUP_BLOCK:
0542         return prestera_flow_block_setup(port, type_data);
0543     default:
0544         return -EOPNOTSUPP;
0545     }
0546 }
0547 
0548 static const struct net_device_ops prestera_netdev_ops = {
0549     .ndo_open = prestera_port_open,
0550     .ndo_stop = prestera_port_close,
0551     .ndo_start_xmit = prestera_port_xmit,
0552     .ndo_setup_tc = prestera_port_setup_tc,
0553     .ndo_change_mtu = prestera_port_change_mtu,
0554     .ndo_get_stats64 = prestera_port_get_stats64,
0555     .ndo_set_mac_address = prestera_port_set_mac_address,
0556     .ndo_get_devlink_port = prestera_devlink_get_port,
0557 };
0558 
0559 int prestera_port_autoneg_set(struct prestera_port *port, u64 link_modes)
0560 {
0561     int err;
0562 
0563     if (port->autoneg && port->adver_link_modes == link_modes)
0564         return 0;
0565 
0566     err = prestera_hw_port_phy_mode_set(port, port->cfg_phy.admin,
0567                         true, 0, link_modes,
0568                         port->cfg_phy.mdix);
0569     if (err)
0570         return err;
0571 
0572     port->adver_fec = BIT(PRESTERA_PORT_FEC_OFF);
0573     port->adver_link_modes = link_modes;
0574     port->cfg_phy.mode = 0;
0575     port->autoneg = true;
0576 
0577     return 0;
0578 }
0579 
0580 static void prestera_port_list_add(struct prestera_port *port)
0581 {
0582     write_lock(&port->sw->port_list_lock);
0583     list_add(&port->list, &port->sw->port_list);
0584     write_unlock(&port->sw->port_list_lock);
0585 }
0586 
0587 static void prestera_port_list_del(struct prestera_port *port)
0588 {
0589     write_lock(&port->sw->port_list_lock);
0590     list_del(&port->list);
0591     write_unlock(&port->sw->port_list_lock);
0592 }
0593 
0594 static int prestera_port_create(struct prestera_switch *sw, u32 id)
0595 {
0596     struct prestera_port_mac_config cfg_mac;
0597     struct prestera_port *port;
0598     struct net_device *dev;
0599     int err;
0600 
0601     dev = alloc_etherdev(sizeof(*port));
0602     if (!dev)
0603         return -ENOMEM;
0604 
0605     port = netdev_priv(dev);
0606 
0607     INIT_LIST_HEAD(&port->vlans_list);
0608     port->pvid = PRESTERA_DEFAULT_VID;
0609     port->lag = NULL;
0610     port->dev = dev;
0611     port->id = id;
0612     port->sw = sw;
0613 
0614     spin_lock_init(&port->state_mac_lock);
0615 
0616     err = prestera_hw_port_info_get(port, &port->dev_id, &port->hw_id,
0617                     &port->fp_id);
0618     if (err) {
0619         dev_err(prestera_dev(sw), "Failed to get port(%u) info\n", id);
0620         goto err_port_info_get;
0621     }
0622 
0623     err = prestera_devlink_port_register(port);
0624     if (err)
0625         goto err_dl_port_register;
0626 
0627     dev->features |= NETIF_F_NETNS_LOCAL | NETIF_F_HW_TC;
0628     dev->netdev_ops = &prestera_netdev_ops;
0629     dev->ethtool_ops = &prestera_ethtool_ops;
0630     SET_NETDEV_DEV(dev, sw->dev->dev);
0631 
0632     if (port->caps.transceiver != PRESTERA_PORT_TCVR_SFP)
0633         netif_carrier_off(dev);
0634 
0635     dev->mtu = min_t(unsigned int, sw->mtu_max, PRESTERA_MTU_DEFAULT);
0636     dev->min_mtu = sw->mtu_min;
0637     dev->max_mtu = sw->mtu_max;
0638 
0639     err = prestera_hw_port_mtu_set(port, dev->mtu);
0640     if (err) {
0641         dev_err(prestera_dev(sw), "Failed to set port(%u) mtu(%d)\n",
0642             id, dev->mtu);
0643         goto err_port_init;
0644     }
0645 
0646     if (port->fp_id >= PRESTERA_MAC_ADDR_NUM_MAX) {
0647         err = -EINVAL;
0648         goto err_port_init;
0649     }
0650 
0651     eth_hw_addr_gen(dev, sw->base_mac, port->fp_id);
0652     /* firmware requires that port's MAC address consist of the first
0653      * 5 bytes of the base MAC address
0654      */
0655     if (memcmp(dev->dev_addr, sw->base_mac, ETH_ALEN - 1)) {
0656         dev_warn(prestera_dev(sw), "Port MAC address wraps for port(%u)\n", id);
0657         dev_addr_mod(dev, 0, sw->base_mac, ETH_ALEN - 1);
0658     }
0659 
0660     err = prestera_hw_port_mac_set(port, dev->dev_addr);
0661     if (err) {
0662         dev_err(prestera_dev(sw), "Failed to set port(%u) mac addr\n", id);
0663         goto err_port_init;
0664     }
0665 
0666     err = prestera_hw_port_cap_get(port, &port->caps);
0667     if (err) {
0668         dev_err(prestera_dev(sw), "Failed to get port(%u) caps\n", id);
0669         goto err_port_init;
0670     }
0671 
0672     port->adver_link_modes = port->caps.supp_link_modes;
0673     port->adver_fec = 0;
0674     port->autoneg = true;
0675 
0676     /* initialize config mac */
0677     if (port->caps.transceiver != PRESTERA_PORT_TCVR_SFP) {
0678         cfg_mac.admin = true;
0679         cfg_mac.mode = PRESTERA_MAC_MODE_INTERNAL;
0680     } else {
0681         cfg_mac.admin = false;
0682         cfg_mac.mode = PRESTERA_MAC_MODE_MAX;
0683     }
0684     cfg_mac.inband = 0;
0685     cfg_mac.speed = 0;
0686     cfg_mac.duplex = DUPLEX_UNKNOWN;
0687     cfg_mac.fec = PRESTERA_PORT_FEC_OFF;
0688 
0689     err = prestera_port_cfg_mac_write(port, &cfg_mac);
0690     if (err) {
0691         dev_err(prestera_dev(sw),
0692             "Failed to set port(%u) mac mode\n", id);
0693         goto err_port_init;
0694     }
0695 
0696     /* initialize config phy (if this is inegral) */
0697     if (port->caps.transceiver != PRESTERA_PORT_TCVR_SFP) {
0698         port->cfg_phy.mdix = ETH_TP_MDI_AUTO;
0699         port->cfg_phy.admin = false;
0700         err = prestera_hw_port_phy_mode_set(port,
0701                             port->cfg_phy.admin,
0702                             false, 0, 0,
0703                             port->cfg_phy.mdix);
0704         if (err) {
0705             dev_err(prestera_dev(sw),
0706                 "Failed to set port(%u) phy mode\n", id);
0707             goto err_port_init;
0708         }
0709     }
0710 
0711     err = prestera_rxtx_port_init(port);
0712     if (err)
0713         goto err_port_init;
0714 
0715     INIT_DELAYED_WORK(&port->cached_hw_stats.caching_dw,
0716               &prestera_port_stats_update);
0717 
0718     prestera_port_list_add(port);
0719 
0720     err = register_netdev(dev);
0721     if (err)
0722         goto err_register_netdev;
0723 
0724     prestera_devlink_port_set(port);
0725 
0726     err = prestera_port_sfp_bind(port);
0727     if (err)
0728         goto err_sfp_bind;
0729 
0730     return 0;
0731 
0732 err_sfp_bind:
0733 err_register_netdev:
0734     prestera_port_list_del(port);
0735 err_port_init:
0736     prestera_devlink_port_unregister(port);
0737 err_dl_port_register:
0738 err_port_info_get:
0739     free_netdev(dev);
0740     return err;
0741 }
0742 
0743 static void prestera_port_destroy(struct prestera_port *port)
0744 {
0745     struct net_device *dev = port->dev;
0746 
0747     cancel_delayed_work_sync(&port->cached_hw_stats.caching_dw);
0748     prestera_devlink_port_clear(port);
0749     unregister_netdev(dev);
0750     prestera_port_list_del(port);
0751     prestera_devlink_port_unregister(port);
0752     free_netdev(dev);
0753 }
0754 
0755 static void prestera_destroy_ports(struct prestera_switch *sw)
0756 {
0757     struct prestera_port *port, *tmp;
0758 
0759     list_for_each_entry_safe(port, tmp, &sw->port_list, list)
0760         prestera_port_destroy(port);
0761 }
0762 
0763 static int prestera_create_ports(struct prestera_switch *sw)
0764 {
0765     struct prestera_port *port, *tmp;
0766     u32 port_idx;
0767     int err;
0768 
0769     for (port_idx = 0; port_idx < sw->port_count; port_idx++) {
0770         err = prestera_port_create(sw, port_idx);
0771         if (err)
0772             goto err_port_create;
0773     }
0774 
0775     return 0;
0776 
0777 err_port_create:
0778     list_for_each_entry_safe(port, tmp, &sw->port_list, list) {
0779         prestera_port_sfp_unbind(port);
0780         prestera_port_destroy(port);
0781     }
0782 
0783     return err;
0784 }
0785 
0786 static void prestera_port_handle_event(struct prestera_switch *sw,
0787                        struct prestera_event *evt, void *arg)
0788 {
0789     struct prestera_port_mac_state smac;
0790     struct prestera_port_event *pevt;
0791     struct delayed_work *caching_dw;
0792     struct prestera_port *port;
0793 
0794     if (evt->id == PRESTERA_PORT_EVENT_MAC_STATE_CHANGED) {
0795         pevt = &evt->port_evt;
0796         port = prestera_find_port(sw, pevt->port_id);
0797         if (!port || !port->dev)
0798             return;
0799 
0800         caching_dw = &port->cached_hw_stats.caching_dw;
0801 
0802         if (port->phy_link) {
0803             memset(&smac, 0, sizeof(smac));
0804             smac.valid = true;
0805             smac.oper = pevt->data.mac.oper;
0806             if (smac.oper) {
0807                 smac.mode = pevt->data.mac.mode;
0808                 smac.speed = pevt->data.mac.speed;
0809                 smac.duplex = pevt->data.mac.duplex;
0810                 smac.fc = pevt->data.mac.fc;
0811                 smac.fec = pevt->data.mac.fec;
0812                 phylink_mac_change(port->phy_link, true);
0813             } else {
0814                 phylink_mac_change(port->phy_link, false);
0815             }
0816             prestera_port_mac_state_cache_write(port, &smac);
0817         }
0818 
0819         if (port->state_mac.oper) {
0820             if (!port->phy_link)
0821                 netif_carrier_on(port->dev);
0822 
0823             if (!delayed_work_pending(caching_dw))
0824                 queue_delayed_work(prestera_wq, caching_dw, 0);
0825         } else if (netif_running(port->dev) &&
0826                netif_carrier_ok(port->dev)) {
0827             if (!port->phy_link)
0828                 netif_carrier_off(port->dev);
0829 
0830             if (delayed_work_pending(caching_dw))
0831                 cancel_delayed_work(caching_dw);
0832         }
0833     }
0834 }
0835 
0836 static int prestera_event_handlers_register(struct prestera_switch *sw)
0837 {
0838     return prestera_hw_event_handler_register(sw, PRESTERA_EVENT_TYPE_PORT,
0839                           prestera_port_handle_event,
0840                           NULL);
0841 }
0842 
0843 static void prestera_event_handlers_unregister(struct prestera_switch *sw)
0844 {
0845     prestera_hw_event_handler_unregister(sw, PRESTERA_EVENT_TYPE_PORT,
0846                          prestera_port_handle_event);
0847 }
0848 
0849 static int prestera_switch_set_base_mac_addr(struct prestera_switch *sw)
0850 {
0851     struct device_node *base_mac_np;
0852     int ret = 0;
0853 
0854     if (sw->np) {
0855         base_mac_np = of_parse_phandle(sw->np, "base-mac-provider", 0);
0856         if (base_mac_np) {
0857             ret = of_get_mac_address(base_mac_np, sw->base_mac);
0858             of_node_put(base_mac_np);
0859         }
0860     }
0861 
0862     if (!is_valid_ether_addr(sw->base_mac) || ret) {
0863         eth_random_addr(sw->base_mac);
0864         dev_info(prestera_dev(sw), "using random base mac address\n");
0865     }
0866 
0867     return prestera_hw_switch_mac_set(sw, sw->base_mac);
0868 }
0869 
0870 struct prestera_lag *prestera_lag_by_id(struct prestera_switch *sw, u16 id)
0871 {
0872     return id < sw->lag_max ? &sw->lags[id] : NULL;
0873 }
0874 
0875 static struct prestera_lag *prestera_lag_by_dev(struct prestera_switch *sw,
0876                         struct net_device *dev)
0877 {
0878     struct prestera_lag *lag;
0879     u16 id;
0880 
0881     for (id = 0; id < sw->lag_max; id++) {
0882         lag = &sw->lags[id];
0883         if (lag->dev == dev)
0884             return lag;
0885     }
0886 
0887     return NULL;
0888 }
0889 
0890 int prestera_lag_id(struct prestera_switch *sw,
0891             struct net_device *lag_dev, u16 *lag_id)
0892 {
0893     struct prestera_lag *lag;
0894     int free_id = -1;
0895     int id;
0896 
0897     for (id = 0; id < sw->lag_max; id++) {
0898         lag = prestera_lag_by_id(sw, id);
0899         if (lag->member_count) {
0900             if (lag->dev == lag_dev) {
0901                 *lag_id = id;
0902                 return 0;
0903             }
0904         } else if (free_id < 0) {
0905             free_id = id;
0906         }
0907     }
0908     if (free_id < 0)
0909         return -ENOSPC;
0910     *lag_id = free_id;
0911     return 0;
0912 }
0913 
0914 static struct prestera_lag *prestera_lag_create(struct prestera_switch *sw,
0915                         struct net_device *lag_dev)
0916 {
0917     struct prestera_lag *lag = NULL;
0918     u16 id;
0919 
0920     for (id = 0; id < sw->lag_max; id++) {
0921         lag = &sw->lags[id];
0922         if (!lag->dev)
0923             break;
0924     }
0925     if (lag) {
0926         INIT_LIST_HEAD(&lag->members);
0927         lag->dev = lag_dev;
0928     }
0929 
0930     return lag;
0931 }
0932 
0933 static void prestera_lag_destroy(struct prestera_switch *sw,
0934                  struct prestera_lag *lag)
0935 {
0936     WARN_ON(!list_empty(&lag->members));
0937     lag->member_count = 0;
0938     lag->dev = NULL;
0939 }
0940 
0941 static int prestera_lag_port_add(struct prestera_port *port,
0942                  struct net_device *lag_dev)
0943 {
0944     struct prestera_switch *sw = port->sw;
0945     struct prestera_lag *lag;
0946     int err;
0947 
0948     lag = prestera_lag_by_dev(sw, lag_dev);
0949     if (!lag) {
0950         lag = prestera_lag_create(sw, lag_dev);
0951         if (!lag)
0952             return -ENOSPC;
0953     }
0954 
0955     if (lag->member_count >= sw->lag_member_max)
0956         return -ENOSPC;
0957 
0958     err = prestera_hw_lag_member_add(port, lag->lag_id);
0959     if (err) {
0960         if (!lag->member_count)
0961             prestera_lag_destroy(sw, lag);
0962         return err;
0963     }
0964 
0965     list_add(&port->lag_member, &lag->members);
0966     lag->member_count++;
0967     port->lag = lag;
0968 
0969     return 0;
0970 }
0971 
0972 static int prestera_lag_port_del(struct prestera_port *port)
0973 {
0974     struct prestera_switch *sw = port->sw;
0975     struct prestera_lag *lag = port->lag;
0976     int err;
0977 
0978     if (!lag || !lag->member_count)
0979         return -EINVAL;
0980 
0981     err = prestera_hw_lag_member_del(port, lag->lag_id);
0982     if (err)
0983         return err;
0984 
0985     list_del(&port->lag_member);
0986     lag->member_count--;
0987     port->lag = NULL;
0988 
0989     if (netif_is_bridge_port(lag->dev)) {
0990         struct net_device *br_dev;
0991 
0992         br_dev = netdev_master_upper_dev_get(lag->dev);
0993 
0994         prestera_bridge_port_leave(br_dev, port);
0995     }
0996 
0997     if (!lag->member_count)
0998         prestera_lag_destroy(sw, lag);
0999 
1000     return 0;
1001 }
1002 
1003 bool prestera_port_is_lag_member(const struct prestera_port *port)
1004 {
1005     return !!port->lag;
1006 }
1007 
1008 u16 prestera_port_lag_id(const struct prestera_port *port)
1009 {
1010     return port->lag->lag_id;
1011 }
1012 
1013 static int prestera_lag_init(struct prestera_switch *sw)
1014 {
1015     u16 id;
1016 
1017     sw->lags = kcalloc(sw->lag_max, sizeof(*sw->lags), GFP_KERNEL);
1018     if (!sw->lags)
1019         return -ENOMEM;
1020 
1021     for (id = 0; id < sw->lag_max; id++)
1022         sw->lags[id].lag_id = id;
1023 
1024     return 0;
1025 }
1026 
1027 static void prestera_lag_fini(struct prestera_switch *sw)
1028 {
1029     u8 idx;
1030 
1031     for (idx = 0; idx < sw->lag_max; idx++)
1032         WARN_ON(sw->lags[idx].member_count);
1033 
1034     kfree(sw->lags);
1035 }
1036 
1037 bool prestera_netdev_check(const struct net_device *dev)
1038 {
1039     return dev->netdev_ops == &prestera_netdev_ops;
1040 }
1041 
1042 static int prestera_lower_dev_walk(struct net_device *dev,
1043                    struct netdev_nested_priv *priv)
1044 {
1045     struct prestera_port **pport = (struct prestera_port **)priv->data;
1046 
1047     if (prestera_netdev_check(dev)) {
1048         *pport = netdev_priv(dev);
1049         return 1;
1050     }
1051 
1052     return 0;
1053 }
1054 
1055 struct prestera_port *prestera_port_dev_lower_find(struct net_device *dev)
1056 {
1057     struct prestera_port *port = NULL;
1058     struct netdev_nested_priv priv = {
1059         .data = (void *)&port,
1060     };
1061 
1062     if (prestera_netdev_check(dev))
1063         return netdev_priv(dev);
1064 
1065     netdev_walk_all_lower_dev(dev, prestera_lower_dev_walk, &priv);
1066 
1067     return port;
1068 }
1069 
1070 static int prestera_netdev_port_lower_event(struct net_device *dev,
1071                         unsigned long event, void *ptr)
1072 {
1073     struct netdev_notifier_changelowerstate_info *info = ptr;
1074     struct netdev_lag_lower_state_info *lower_state_info;
1075     struct prestera_port *port = netdev_priv(dev);
1076     bool enabled;
1077 
1078     if (!netif_is_lag_port(dev))
1079         return 0;
1080     if (!prestera_port_is_lag_member(port))
1081         return 0;
1082 
1083     lower_state_info = info->lower_state_info;
1084     enabled = lower_state_info->link_up && lower_state_info->tx_enabled;
1085 
1086     return prestera_hw_lag_member_enable(port, port->lag->lag_id, enabled);
1087 }
1088 
1089 static bool prestera_lag_master_check(struct net_device *lag_dev,
1090                       struct netdev_lag_upper_info *info,
1091                       struct netlink_ext_ack *ext_ack)
1092 {
1093     if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH) {
1094         NL_SET_ERR_MSG_MOD(ext_ack, "Unsupported LAG Tx type");
1095         return false;
1096     }
1097 
1098     return true;
1099 }
1100 
1101 static int prestera_netdev_port_event(struct net_device *lower,
1102                       struct net_device *dev,
1103                       unsigned long event, void *ptr)
1104 {
1105     struct netdev_notifier_info *info = ptr;
1106     struct netdev_notifier_changeupper_info *cu_info;
1107     struct prestera_port *port = netdev_priv(dev);
1108     struct netlink_ext_ack *extack;
1109     struct net_device *upper;
1110 
1111     extack = netdev_notifier_info_to_extack(info);
1112     cu_info = container_of(info,
1113                    struct netdev_notifier_changeupper_info,
1114                    info);
1115 
1116     switch (event) {
1117     case NETDEV_PRECHANGEUPPER:
1118         upper = cu_info->upper_dev;
1119         if (!netif_is_bridge_master(upper) &&
1120             !netif_is_lag_master(upper)) {
1121             NL_SET_ERR_MSG_MOD(extack, "Unknown upper device type");
1122             return -EINVAL;
1123         }
1124 
1125         if (!cu_info->linking)
1126             break;
1127 
1128         if (netdev_has_any_upper_dev(upper)) {
1129             NL_SET_ERR_MSG_MOD(extack, "Upper device is already enslaved");
1130             return -EINVAL;
1131         }
1132 
1133         if (netif_is_lag_master(upper) &&
1134             !prestera_lag_master_check(upper, cu_info->upper_info, extack))
1135             return -EOPNOTSUPP;
1136         if (netif_is_lag_master(upper) && vlan_uses_dev(dev)) {
1137             NL_SET_ERR_MSG_MOD(extack,
1138                        "Master device is a LAG master and port has a VLAN");
1139             return -EINVAL;
1140         }
1141         if (netif_is_lag_port(dev) && is_vlan_dev(upper) &&
1142             !netif_is_lag_master(vlan_dev_real_dev(upper))) {
1143             NL_SET_ERR_MSG_MOD(extack,
1144                        "Can not put a VLAN on a LAG port");
1145             return -EINVAL;
1146         }
1147         break;
1148 
1149     case NETDEV_CHANGEUPPER:
1150         upper = cu_info->upper_dev;
1151         if (netif_is_bridge_master(upper)) {
1152             if (cu_info->linking)
1153                 return prestera_bridge_port_join(upper, port,
1154                                  extack);
1155             else
1156                 prestera_bridge_port_leave(upper, port);
1157         } else if (netif_is_lag_master(upper)) {
1158             if (cu_info->linking)
1159                 return prestera_lag_port_add(port, upper);
1160             else
1161                 prestera_lag_port_del(port);
1162         }
1163         break;
1164 
1165     case NETDEV_CHANGELOWERSTATE:
1166         return prestera_netdev_port_lower_event(dev, event, ptr);
1167     }
1168 
1169     return 0;
1170 }
1171 
1172 static int prestera_netdevice_lag_event(struct net_device *lag_dev,
1173                     unsigned long event, void *ptr)
1174 {
1175     struct net_device *dev;
1176     struct list_head *iter;
1177     int err;
1178 
1179     netdev_for_each_lower_dev(lag_dev, dev, iter) {
1180         if (prestera_netdev_check(dev)) {
1181             err = prestera_netdev_port_event(lag_dev, dev, event,
1182                              ptr);
1183             if (err)
1184                 return err;
1185         }
1186     }
1187 
1188     return 0;
1189 }
1190 
1191 static int prestera_netdev_event_handler(struct notifier_block *nb,
1192                      unsigned long event, void *ptr)
1193 {
1194     struct net_device *dev = netdev_notifier_info_to_dev(ptr);
1195     int err = 0;
1196 
1197     if (prestera_netdev_check(dev))
1198         err = prestera_netdev_port_event(dev, dev, event, ptr);
1199     else if (netif_is_lag_master(dev))
1200         err = prestera_netdevice_lag_event(dev, event, ptr);
1201 
1202     return notifier_from_errno(err);
1203 }
1204 
1205 struct prestera_mdb_entry *
1206 prestera_mdb_entry_create(struct prestera_switch *sw,
1207               const unsigned char *addr, u16 vid)
1208 {
1209     struct prestera_flood_domain *flood_domain;
1210     struct prestera_mdb_entry *mdb_entry;
1211 
1212     mdb_entry = kzalloc(sizeof(*mdb_entry), GFP_KERNEL);
1213     if (!mdb_entry)
1214         goto err_mdb_alloc;
1215 
1216     flood_domain = prestera_flood_domain_create(sw);
1217     if (!flood_domain)
1218         goto err_flood_domain_create;
1219 
1220     mdb_entry->sw = sw;
1221     mdb_entry->vid = vid;
1222     mdb_entry->flood_domain = flood_domain;
1223     ether_addr_copy(mdb_entry->addr, addr);
1224 
1225     if (prestera_hw_mdb_create(mdb_entry))
1226         goto err_mdb_hw_create;
1227 
1228     return mdb_entry;
1229 
1230 err_mdb_hw_create:
1231     prestera_flood_domain_destroy(flood_domain);
1232 err_flood_domain_create:
1233     kfree(mdb_entry);
1234 err_mdb_alloc:
1235     return NULL;
1236 }
1237 
1238 void prestera_mdb_entry_destroy(struct prestera_mdb_entry *mdb_entry)
1239 {
1240     prestera_hw_mdb_destroy(mdb_entry);
1241     prestera_flood_domain_destroy(mdb_entry->flood_domain);
1242     kfree(mdb_entry);
1243 }
1244 
1245 struct prestera_flood_domain *
1246 prestera_flood_domain_create(struct prestera_switch *sw)
1247 {
1248     struct prestera_flood_domain *domain;
1249 
1250     domain = kzalloc(sizeof(*domain), GFP_KERNEL);
1251     if (!domain)
1252         return NULL;
1253 
1254     domain->sw = sw;
1255 
1256     if (prestera_hw_flood_domain_create(domain)) {
1257         kfree(domain);
1258         return NULL;
1259     }
1260 
1261     INIT_LIST_HEAD(&domain->flood_domain_port_list);
1262 
1263     return domain;
1264 }
1265 
1266 void prestera_flood_domain_destroy(struct prestera_flood_domain *flood_domain)
1267 {
1268     WARN_ON(!list_empty(&flood_domain->flood_domain_port_list));
1269     WARN_ON_ONCE(prestera_hw_flood_domain_destroy(flood_domain));
1270     kfree(flood_domain);
1271 }
1272 
1273 int
1274 prestera_flood_domain_port_create(struct prestera_flood_domain *flood_domain,
1275                   struct net_device *dev,
1276                   u16 vid)
1277 {
1278     struct prestera_flood_domain_port *flood_domain_port;
1279     bool is_first_port_in_list = false;
1280     int err;
1281 
1282     flood_domain_port = kzalloc(sizeof(*flood_domain_port), GFP_KERNEL);
1283     if (!flood_domain_port) {
1284         err = -ENOMEM;
1285         goto err_port_alloc;
1286     }
1287 
1288     flood_domain_port->vid = vid;
1289 
1290     if (list_empty(&flood_domain->flood_domain_port_list))
1291         is_first_port_in_list = true;
1292 
1293     list_add(&flood_domain_port->flood_domain_port_node,
1294          &flood_domain->flood_domain_port_list);
1295 
1296     flood_domain_port->flood_domain = flood_domain;
1297     flood_domain_port->dev = dev;
1298 
1299     if (!is_first_port_in_list) {
1300         err = prestera_hw_flood_domain_ports_reset(flood_domain);
1301         if (err)
1302             goto err_prestera_mdb_port_create_hw;
1303     }
1304 
1305     err = prestera_hw_flood_domain_ports_set(flood_domain);
1306     if (err)
1307         goto err_prestera_mdb_port_create_hw;
1308 
1309     return 0;
1310 
1311 err_prestera_mdb_port_create_hw:
1312     list_del(&flood_domain_port->flood_domain_port_node);
1313     kfree(flood_domain_port);
1314 err_port_alloc:
1315     return err;
1316 }
1317 
1318 void
1319 prestera_flood_domain_port_destroy(struct prestera_flood_domain_port *port)
1320 {
1321     struct prestera_flood_domain *flood_domain = port->flood_domain;
1322 
1323     list_del(&port->flood_domain_port_node);
1324 
1325     WARN_ON_ONCE(prestera_hw_flood_domain_ports_reset(flood_domain));
1326 
1327     if (!list_empty(&flood_domain->flood_domain_port_list))
1328         WARN_ON_ONCE(prestera_hw_flood_domain_ports_set(flood_domain));
1329 
1330     kfree(port);
1331 }
1332 
1333 struct prestera_flood_domain_port *
1334 prestera_flood_domain_port_find(struct prestera_flood_domain *flood_domain,
1335                 struct net_device *dev, u16 vid)
1336 {
1337     struct prestera_flood_domain_port *flood_domain_port;
1338 
1339     list_for_each_entry(flood_domain_port,
1340                 &flood_domain->flood_domain_port_list,
1341                 flood_domain_port_node)
1342         if (flood_domain_port->dev == dev &&
1343             vid == flood_domain_port->vid)
1344             return flood_domain_port;
1345 
1346     return NULL;
1347 }
1348 
1349 static int prestera_netdev_event_handler_register(struct prestera_switch *sw)
1350 {
1351     sw->netdev_nb.notifier_call = prestera_netdev_event_handler;
1352 
1353     return register_netdevice_notifier(&sw->netdev_nb);
1354 }
1355 
1356 static void prestera_netdev_event_handler_unregister(struct prestera_switch *sw)
1357 {
1358     unregister_netdevice_notifier(&sw->netdev_nb);
1359 }
1360 
1361 static int prestera_switch_init(struct prestera_switch *sw)
1362 {
1363     int err;
1364 
1365     sw->np = of_find_compatible_node(NULL, NULL, "marvell,prestera");
1366 
1367     err = prestera_hw_switch_init(sw);
1368     if (err) {
1369         dev_err(prestera_dev(sw), "Failed to init Switch device\n");
1370         return err;
1371     }
1372 
1373     rwlock_init(&sw->port_list_lock);
1374     INIT_LIST_HEAD(&sw->port_list);
1375 
1376     err = prestera_switch_set_base_mac_addr(sw);
1377     if (err)
1378         return err;
1379 
1380     err = prestera_netdev_event_handler_register(sw);
1381     if (err)
1382         return err;
1383 
1384     err = prestera_router_init(sw);
1385     if (err)
1386         goto err_router_init;
1387 
1388     err = prestera_switchdev_init(sw);
1389     if (err)
1390         goto err_swdev_register;
1391 
1392     err = prestera_rxtx_switch_init(sw);
1393     if (err)
1394         goto err_rxtx_register;
1395 
1396     err = prestera_event_handlers_register(sw);
1397     if (err)
1398         goto err_handlers_register;
1399 
1400     err = prestera_counter_init(sw);
1401     if (err)
1402         goto err_counter_init;
1403 
1404     err = prestera_acl_init(sw);
1405     if (err)
1406         goto err_acl_init;
1407 
1408     err = prestera_span_init(sw);
1409     if (err)
1410         goto err_span_init;
1411 
1412     err = prestera_devlink_traps_register(sw);
1413     if (err)
1414         goto err_dl_register;
1415 
1416     err = prestera_lag_init(sw);
1417     if (err)
1418         goto err_lag_init;
1419 
1420     err = prestera_create_ports(sw);
1421     if (err)
1422         goto err_ports_create;
1423 
1424     prestera_devlink_register(sw);
1425     return 0;
1426 
1427 err_ports_create:
1428     prestera_lag_fini(sw);
1429 err_lag_init:
1430     prestera_devlink_traps_unregister(sw);
1431 err_dl_register:
1432     prestera_span_fini(sw);
1433 err_span_init:
1434     prestera_acl_fini(sw);
1435 err_acl_init:
1436     prestera_counter_fini(sw);
1437 err_counter_init:
1438     prestera_event_handlers_unregister(sw);
1439 err_handlers_register:
1440     prestera_rxtx_switch_fini(sw);
1441 err_rxtx_register:
1442     prestera_switchdev_fini(sw);
1443 err_swdev_register:
1444     prestera_router_fini(sw);
1445 err_router_init:
1446     prestera_netdev_event_handler_unregister(sw);
1447     prestera_hw_switch_fini(sw);
1448 
1449     return err;
1450 }
1451 
1452 static void prestera_switch_fini(struct prestera_switch *sw)
1453 {
1454     prestera_devlink_unregister(sw);
1455     prestera_destroy_ports(sw);
1456     prestera_lag_fini(sw);
1457     prestera_devlink_traps_unregister(sw);
1458     prestera_span_fini(sw);
1459     prestera_acl_fini(sw);
1460     prestera_counter_fini(sw);
1461     prestera_event_handlers_unregister(sw);
1462     prestera_rxtx_switch_fini(sw);
1463     prestera_switchdev_fini(sw);
1464     prestera_router_fini(sw);
1465     prestera_netdev_event_handler_unregister(sw);
1466     prestera_hw_switch_fini(sw);
1467     of_node_put(sw->np);
1468 }
1469 
1470 int prestera_device_register(struct prestera_device *dev)
1471 {
1472     struct prestera_switch *sw;
1473     int err;
1474 
1475     sw = prestera_devlink_alloc(dev);
1476     if (!sw)
1477         return -ENOMEM;
1478 
1479     dev->priv = sw;
1480     sw->dev = dev;
1481 
1482     err = prestera_switch_init(sw);
1483     if (err) {
1484         prestera_devlink_free(sw);
1485         return err;
1486     }
1487 
1488     return 0;
1489 }
1490 EXPORT_SYMBOL(prestera_device_register);
1491 
1492 void prestera_device_unregister(struct prestera_device *dev)
1493 {
1494     struct prestera_switch *sw = dev->priv;
1495 
1496     prestera_switch_fini(sw);
1497     prestera_devlink_free(sw);
1498 }
1499 EXPORT_SYMBOL(prestera_device_unregister);
1500 
1501 static int __init prestera_module_init(void)
1502 {
1503     prestera_wq = alloc_workqueue("prestera", 0, 0);
1504     if (!prestera_wq)
1505         return -ENOMEM;
1506 
1507     prestera_owq = alloc_ordered_workqueue("prestera_ordered", 0);
1508     if (!prestera_owq) {
1509         destroy_workqueue(prestera_wq);
1510         return -ENOMEM;
1511     }
1512 
1513     return 0;
1514 }
1515 
1516 static void __exit prestera_module_exit(void)
1517 {
1518     destroy_workqueue(prestera_wq);
1519     destroy_workqueue(prestera_owq);
1520 }
1521 
1522 module_init(prestera_module_init);
1523 module_exit(prestera_module_exit);
1524 
1525 MODULE_LICENSE("Dual BSD/GPL");
1526 MODULE_DESCRIPTION("Marvell Prestera switch driver");