1527 lines · c
1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.02/* Copyright (c) 2019-2020 Marvell International Ltd. All rights reserved */3 4#include <linux/etherdevice.h>5#include <linux/jiffies.h>6#include <linux/list.h>7#include <linux/module.h>8#include <linux/netdev_features.h>9#include <linux/of.h>10#include <linux/of_net.h>11#include <linux/if_vlan.h>12#include <linux/phylink.h>13 14#include "prestera.h"15#include "prestera_hw.h"16#include "prestera_acl.h"17#include "prestera_flow.h"18#include "prestera_span.h"19#include "prestera_rxtx.h"20#include "prestera_devlink.h"21#include "prestera_ethtool.h"22#include "prestera_counter.h"23#include "prestera_switchdev.h"24 25#define PRESTERA_MTU_DEFAULT 153626 27#define PRESTERA_STATS_DELAY_MS 100028 29#define PRESTERA_MAC_ADDR_NUM_MAX 25530 31static struct workqueue_struct *prestera_wq;32static struct workqueue_struct *prestera_owq;33 34void prestera_queue_work(struct work_struct *work)35{36 queue_work(prestera_owq, work);37}38 39void prestera_queue_delayed_work(struct delayed_work *work, unsigned long delay)40{41 queue_delayed_work(prestera_wq, work, delay);42}43 44void prestera_queue_drain(void)45{46 drain_workqueue(prestera_wq);47 drain_workqueue(prestera_owq);48}49 50int prestera_port_learning_set(struct prestera_port *port, bool learn)51{52 return prestera_hw_port_learning_set(port, learn);53}54 55int prestera_port_uc_flood_set(struct prestera_port *port, bool flood)56{57 return prestera_hw_port_uc_flood_set(port, flood);58}59 60int prestera_port_mc_flood_set(struct prestera_port *port, bool flood)61{62 return prestera_hw_port_mc_flood_set(port, flood);63}64 65int prestera_port_br_locked_set(struct prestera_port *port, bool br_locked)66{67 return prestera_hw_port_br_locked_set(port, br_locked);68}69 70int prestera_port_pvid_set(struct prestera_port *port, u16 vid)71{72 enum prestera_accept_frm_type frm_type;73 int err;74 75 frm_type = PRESTERA_ACCEPT_FRAME_TYPE_TAGGED;76 77 if (vid) {78 err = prestera_hw_vlan_port_vid_set(port, vid);79 if (err)80 return err;81 82 frm_type = PRESTERA_ACCEPT_FRAME_TYPE_ALL;83 }84 85 err = prestera_hw_port_accept_frm_type(port, frm_type);86 if (err && frm_type == PRESTERA_ACCEPT_FRAME_TYPE_ALL)87 prestera_hw_vlan_port_vid_set(port, port->pvid);88 89 port->pvid = vid;90 return 0;91}92 93struct prestera_port *prestera_port_find_by_hwid(struct prestera_switch *sw,94 u32 dev_id, u32 hw_id)95{96 struct prestera_port *port = NULL, *tmp;97 98 read_lock(&sw->port_list_lock);99 list_for_each_entry(tmp, &sw->port_list, list) {100 if (tmp->dev_id == dev_id && tmp->hw_id == hw_id) {101 port = tmp;102 break;103 }104 }105 read_unlock(&sw->port_list_lock);106 107 return port;108}109 110struct prestera_port *prestera_find_port(struct prestera_switch *sw, u32 id)111{112 struct prestera_port *port = NULL, *tmp;113 114 read_lock(&sw->port_list_lock);115 list_for_each_entry(tmp, &sw->port_list, list) {116 if (tmp->id == id) {117 port = tmp;118 break;119 }120 }121 read_unlock(&sw->port_list_lock);122 123 return port;124}125 126struct prestera_switch *prestera_switch_get(struct net_device *dev)127{128 struct prestera_port *port;129 130 port = prestera_port_dev_lower_find(dev);131 return port ? port->sw : NULL;132}133 134int prestera_port_cfg_mac_read(struct prestera_port *port,135 struct prestera_port_mac_config *cfg)136{137 *cfg = port->cfg_mac;138 return 0;139}140 141int prestera_port_cfg_mac_write(struct prestera_port *port,142 struct prestera_port_mac_config *cfg)143{144 int err;145 146 err = prestera_hw_port_mac_mode_set(port, cfg->admin,147 cfg->mode, cfg->inband, cfg->speed,148 cfg->duplex, cfg->fec);149 if (err)150 return err;151 152 port->cfg_mac = *cfg;153 return 0;154}155 156static int prestera_port_open(struct net_device *dev)157{158 struct prestera_port *port = netdev_priv(dev);159 struct prestera_port_mac_config cfg_mac;160 int err = 0;161 162 if (port->phy_link) {163 phylink_start(port->phy_link);164 } else {165 if (port->caps.transceiver == PRESTERA_PORT_TCVR_SFP) {166 err = prestera_port_cfg_mac_read(port, &cfg_mac);167 if (!err) {168 cfg_mac.admin = true;169 err = prestera_port_cfg_mac_write(port,170 &cfg_mac);171 }172 } else {173 port->cfg_phy.admin = true;174 err = prestera_hw_port_phy_mode_set(port, true,175 port->autoneg,176 port->cfg_phy.mode,177 port->adver_link_modes,178 port->cfg_phy.mdix);179 }180 }181 182 netif_start_queue(dev);183 184 return err;185}186 187static int prestera_port_close(struct net_device *dev)188{189 struct prestera_port *port = netdev_priv(dev);190 struct prestera_port_mac_config cfg_mac;191 int err = 0;192 193 netif_stop_queue(dev);194 195 if (port->phy_link) {196 phylink_stop(port->phy_link);197 phylink_disconnect_phy(port->phy_link);198 err = prestera_port_cfg_mac_read(port, &cfg_mac);199 if (!err) {200 cfg_mac.admin = false;201 prestera_port_cfg_mac_write(port, &cfg_mac);202 }203 } else {204 if (port->caps.transceiver == PRESTERA_PORT_TCVR_SFP) {205 err = prestera_port_cfg_mac_read(port, &cfg_mac);206 if (!err) {207 cfg_mac.admin = false;208 prestera_port_cfg_mac_write(port, &cfg_mac);209 }210 } else {211 port->cfg_phy.admin = false;212 err = prestera_hw_port_phy_mode_set(port, false, port->autoneg,213 port->cfg_phy.mode,214 port->adver_link_modes,215 port->cfg_phy.mdix);216 }217 }218 219 return err;220}221 222static void223prestera_port_mac_state_cache_read(struct prestera_port *port,224 struct prestera_port_mac_state *state)225{226 spin_lock(&port->state_mac_lock);227 *state = port->state_mac;228 spin_unlock(&port->state_mac_lock);229}230 231static void232prestera_port_mac_state_cache_write(struct prestera_port *port,233 struct prestera_port_mac_state *state)234{235 spin_lock(&port->state_mac_lock);236 port->state_mac = *state;237 spin_unlock(&port->state_mac_lock);238}239 240static struct prestera_port *prestera_pcs_to_port(struct phylink_pcs *pcs)241{242 return container_of(pcs, struct prestera_port, phylink_pcs);243}244 245static void prestera_mac_config(struct phylink_config *config,246 unsigned int an_mode,247 const struct phylink_link_state *state)248{249}250 251static void prestera_mac_link_down(struct phylink_config *config,252 unsigned int mode, phy_interface_t interface)253{254 struct net_device *ndev = to_net_dev(config->dev);255 struct prestera_port *port = netdev_priv(ndev);256 struct prestera_port_mac_state state_mac;257 258 /* Invalidate. Parameters will update on next link event. */259 memset(&state_mac, 0, sizeof(state_mac));260 state_mac.valid = false;261 prestera_port_mac_state_cache_write(port, &state_mac);262}263 264static void prestera_mac_link_up(struct phylink_config *config,265 struct phy_device *phy,266 unsigned int mode, phy_interface_t interface,267 int speed, int duplex,268 bool tx_pause, bool rx_pause)269{270}271 272static struct phylink_pcs *273prestera_mac_select_pcs(struct phylink_config *config,274 phy_interface_t interface)275{276 struct net_device *dev = to_net_dev(config->dev);277 struct prestera_port *port = netdev_priv(dev);278 279 return &port->phylink_pcs;280}281 282static void prestera_pcs_get_state(struct phylink_pcs *pcs,283 struct phylink_link_state *state)284{285 struct prestera_port *port = container_of(pcs, struct prestera_port,286 phylink_pcs);287 struct prestera_port_mac_state smac;288 289 prestera_port_mac_state_cache_read(port, &smac);290 291 if (smac.valid) {292 state->link = smac.oper ? 1 : 0;293 /* AN is completed, when port is up */294 state->an_complete = (smac.oper && port->autoneg) ? 1 : 0;295 state->speed = smac.speed;296 state->duplex = smac.duplex;297 } else {298 state->link = 0;299 state->an_complete = 0;300 }301}302 303static int prestera_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode,304 phy_interface_t interface,305 const unsigned long *advertising,306 bool permit_pause_to_mac)307{308 struct prestera_port *port = prestera_pcs_to_port(pcs);309 struct prestera_port_mac_config cfg_mac;310 int err;311 312 err = prestera_port_cfg_mac_read(port, &cfg_mac);313 if (err)314 return err;315 316 cfg_mac.admin = true;317 cfg_mac.fec = PRESTERA_PORT_FEC_OFF;318 cfg_mac.inband = neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED;319 320 switch (interface) {321 case PHY_INTERFACE_MODE_10GBASER:322 cfg_mac.speed = SPEED_10000;323 cfg_mac.mode = PRESTERA_MAC_MODE_SR_LR;324 break;325 case PHY_INTERFACE_MODE_2500BASEX:326 cfg_mac.speed = SPEED_2500;327 cfg_mac.duplex = DUPLEX_FULL;328 cfg_mac.mode = PRESTERA_MAC_MODE_SGMII;329 break;330 case PHY_INTERFACE_MODE_SGMII:331 cfg_mac.mode = PRESTERA_MAC_MODE_SGMII;332 break;333 case PHY_INTERFACE_MODE_1000BASEX:334 default:335 cfg_mac.speed = SPEED_1000;336 cfg_mac.duplex = DUPLEX_FULL;337 cfg_mac.mode = PRESTERA_MAC_MODE_1000BASE_X;338 break;339 }340 341 err = prestera_port_cfg_mac_write(port, &cfg_mac);342 if (err)343 return err;344 345 return 0;346}347 348static void prestera_pcs_an_restart(struct phylink_pcs *pcs)349{350 /* TODO: add 1000basex AN restart support351 * (Currently FW has no support for 1000baseX AN restart, but it will in the future,352 * so as for now the function would stay empty.)353 */354}355 356static const struct phylink_mac_ops prestera_mac_ops = {357 .mac_select_pcs = prestera_mac_select_pcs,358 .mac_config = prestera_mac_config,359 .mac_link_down = prestera_mac_link_down,360 .mac_link_up = prestera_mac_link_up,361};362 363static const struct phylink_pcs_ops prestera_pcs_ops = {364 .pcs_get_state = prestera_pcs_get_state,365 .pcs_config = prestera_pcs_config,366 .pcs_an_restart = prestera_pcs_an_restart,367};368 369static int prestera_port_sfp_bind(struct prestera_port *port)370{371 struct prestera_switch *sw = port->sw;372 struct device_node *ports, *node;373 struct fwnode_handle *fwnode;374 struct phylink *phy_link;375 int err;376 377 if (!sw->np)378 return 0;379 380 of_node_get(sw->np);381 ports = of_find_node_by_name(sw->np, "ports");382 383 for_each_child_of_node(ports, node) {384 int num;385 386 err = of_property_read_u32(node, "prestera,port-num", &num);387 if (err) {388 dev_err(sw->dev->dev,389 "device node %pOF has no valid reg property: %d\n",390 node, err);391 goto out;392 }393 394 if (port->fp_id != num)395 continue;396 397 port->phylink_pcs.ops = &prestera_pcs_ops;398 port->phylink_pcs.neg_mode = true;399 400 port->phy_config.dev = &port->dev->dev;401 port->phy_config.type = PHYLINK_NETDEV;402 403 fwnode = of_fwnode_handle(node);404 405 __set_bit(PHY_INTERFACE_MODE_10GBASER,406 port->phy_config.supported_interfaces);407 __set_bit(PHY_INTERFACE_MODE_2500BASEX,408 port->phy_config.supported_interfaces);409 __set_bit(PHY_INTERFACE_MODE_SGMII,410 port->phy_config.supported_interfaces);411 __set_bit(PHY_INTERFACE_MODE_1000BASEX,412 port->phy_config.supported_interfaces);413 414 port->phy_config.mac_capabilities =415 MAC_1000 | MAC_2500FD | MAC_10000FD;416 417 phy_link = phylink_create(&port->phy_config, fwnode,418 PHY_INTERFACE_MODE_INTERNAL,419 &prestera_mac_ops);420 if (IS_ERR(phy_link)) {421 netdev_err(port->dev, "failed to create phylink\n");422 err = PTR_ERR(phy_link);423 goto out;424 }425 426 port->phy_link = phy_link;427 break;428 }429 430out:431 of_node_put(node);432 of_node_put(ports);433 return err;434}435 436static int prestera_port_sfp_unbind(struct prestera_port *port)437{438 if (port->phy_link)439 phylink_destroy(port->phy_link);440 441 return 0;442}443 444static netdev_tx_t prestera_port_xmit(struct sk_buff *skb,445 struct net_device *dev)446{447 return prestera_rxtx_xmit(netdev_priv(dev), skb);448}449 450int prestera_is_valid_mac_addr(struct prestera_port *port, const u8 *addr)451{452 if (!is_valid_ether_addr(addr))453 return -EADDRNOTAVAIL;454 455 /* firmware requires that port's MAC address contains first 5 bytes456 * of the base MAC address457 */458 if (memcmp(port->sw->base_mac, addr, ETH_ALEN - 1))459 return -EINVAL;460 461 return 0;462}463 464static int prestera_port_set_mac_address(struct net_device *dev, void *p)465{466 struct prestera_port *port = netdev_priv(dev);467 struct sockaddr *addr = p;468 int err;469 470 err = prestera_is_valid_mac_addr(port, addr->sa_data);471 if (err)472 return err;473 474 err = prestera_hw_port_mac_set(port, addr->sa_data);475 if (err)476 return err;477 478 eth_hw_addr_set(dev, addr->sa_data);479 480 return 0;481}482 483static int prestera_port_change_mtu(struct net_device *dev, int mtu)484{485 struct prestera_port *port = netdev_priv(dev);486 int err;487 488 err = prestera_hw_port_mtu_set(port, mtu);489 if (err)490 return err;491 492 WRITE_ONCE(dev->mtu, mtu);493 494 return 0;495}496 497static void prestera_port_get_stats64(struct net_device *dev,498 struct rtnl_link_stats64 *stats)499{500 struct prestera_port *port = netdev_priv(dev);501 struct prestera_port_stats *port_stats = &port->cached_hw_stats.stats;502 503 stats->rx_packets = port_stats->broadcast_frames_received +504 port_stats->multicast_frames_received +505 port_stats->unicast_frames_received;506 507 stats->tx_packets = port_stats->broadcast_frames_sent +508 port_stats->multicast_frames_sent +509 port_stats->unicast_frames_sent;510 511 stats->rx_bytes = port_stats->good_octets_received;512 513 stats->tx_bytes = port_stats->good_octets_sent;514 515 stats->rx_errors = port_stats->rx_error_frame_received;516 stats->tx_errors = port_stats->mac_trans_error;517 518 stats->rx_dropped = port_stats->buffer_overrun;519 stats->tx_dropped = 0;520 521 stats->multicast = port_stats->multicast_frames_received;522 stats->collisions = port_stats->excessive_collision;523 524 stats->rx_crc_errors = port_stats->bad_crc;525}526 527static void prestera_port_get_hw_stats(struct prestera_port *port)528{529 prestera_hw_port_stats_get(port, &port->cached_hw_stats.stats);530}531 532static void prestera_port_stats_update(struct work_struct *work)533{534 struct prestera_port *port =535 container_of(work, struct prestera_port,536 cached_hw_stats.caching_dw.work);537 538 prestera_port_get_hw_stats(port);539 540 queue_delayed_work(prestera_wq, &port->cached_hw_stats.caching_dw,541 msecs_to_jiffies(PRESTERA_STATS_DELAY_MS));542}543 544static int prestera_port_setup_tc(struct net_device *dev,545 enum tc_setup_type type,546 void *type_data)547{548 struct prestera_port *port = netdev_priv(dev);549 550 switch (type) {551 case TC_SETUP_BLOCK:552 return prestera_flow_block_setup(port, type_data);553 default:554 return -EOPNOTSUPP;555 }556}557 558static const struct net_device_ops prestera_netdev_ops = {559 .ndo_open = prestera_port_open,560 .ndo_stop = prestera_port_close,561 .ndo_start_xmit = prestera_port_xmit,562 .ndo_setup_tc = prestera_port_setup_tc,563 .ndo_change_mtu = prestera_port_change_mtu,564 .ndo_get_stats64 = prestera_port_get_stats64,565 .ndo_set_mac_address = prestera_port_set_mac_address,566};567 568int prestera_port_autoneg_set(struct prestera_port *port, u64 link_modes)569{570 int err;571 572 if (port->autoneg && port->adver_link_modes == link_modes)573 return 0;574 575 err = prestera_hw_port_phy_mode_set(port, port->cfg_phy.admin,576 true, 0, link_modes,577 port->cfg_phy.mdix);578 if (err)579 return err;580 581 port->adver_fec = BIT(PRESTERA_PORT_FEC_OFF);582 port->adver_link_modes = link_modes;583 port->cfg_phy.mode = 0;584 port->autoneg = true;585 586 return 0;587}588 589static void prestera_port_list_add(struct prestera_port *port)590{591 write_lock(&port->sw->port_list_lock);592 list_add(&port->list, &port->sw->port_list);593 write_unlock(&port->sw->port_list_lock);594}595 596static void prestera_port_list_del(struct prestera_port *port)597{598 write_lock(&port->sw->port_list_lock);599 list_del(&port->list);600 write_unlock(&port->sw->port_list_lock);601}602 603static int prestera_port_create(struct prestera_switch *sw, u32 id)604{605 struct prestera_port_mac_config cfg_mac;606 struct prestera_port *port;607 struct net_device *dev;608 int err;609 610 dev = alloc_etherdev(sizeof(*port));611 if (!dev)612 return -ENOMEM;613 614 port = netdev_priv(dev);615 616 INIT_LIST_HEAD(&port->vlans_list);617 port->pvid = PRESTERA_DEFAULT_VID;618 port->lag = NULL;619 port->dev = dev;620 port->id = id;621 port->sw = sw;622 623 spin_lock_init(&port->state_mac_lock);624 625 err = prestera_hw_port_info_get(port, &port->dev_id, &port->hw_id,626 &port->fp_id);627 if (err) {628 dev_err(prestera_dev(sw), "Failed to get port(%u) info\n", id);629 goto err_port_info_get;630 }631 632 err = prestera_devlink_port_register(port);633 if (err)634 goto err_dl_port_register;635 636 dev->features |= NETIF_F_HW_TC;637 dev->netns_local = true;638 dev->netdev_ops = &prestera_netdev_ops;639 dev->ethtool_ops = &prestera_ethtool_ops;640 SET_NETDEV_DEV(dev, sw->dev->dev);641 SET_NETDEV_DEVLINK_PORT(dev, &port->dl_port);642 643 if (port->caps.transceiver != PRESTERA_PORT_TCVR_SFP)644 netif_carrier_off(dev);645 646 dev->mtu = min_t(unsigned int, sw->mtu_max, PRESTERA_MTU_DEFAULT);647 dev->min_mtu = sw->mtu_min;648 dev->max_mtu = sw->mtu_max;649 650 err = prestera_hw_port_mtu_set(port, dev->mtu);651 if (err) {652 dev_err(prestera_dev(sw), "Failed to set port(%u) mtu(%d)\n",653 id, dev->mtu);654 goto err_port_init;655 }656 657 if (port->fp_id >= PRESTERA_MAC_ADDR_NUM_MAX) {658 err = -EINVAL;659 goto err_port_init;660 }661 662 eth_hw_addr_gen(dev, sw->base_mac, port->fp_id);663 /* firmware requires that port's MAC address consist of the first664 * 5 bytes of the base MAC address665 */666 if (memcmp(dev->dev_addr, sw->base_mac, ETH_ALEN - 1)) {667 dev_warn(prestera_dev(sw), "Port MAC address wraps for port(%u)\n", id);668 dev_addr_mod(dev, 0, sw->base_mac, ETH_ALEN - 1);669 }670 671 err = prestera_hw_port_mac_set(port, dev->dev_addr);672 if (err) {673 dev_err(prestera_dev(sw), "Failed to set port(%u) mac addr\n", id);674 goto err_port_init;675 }676 677 err = prestera_hw_port_cap_get(port, &port->caps);678 if (err) {679 dev_err(prestera_dev(sw), "Failed to get port(%u) caps\n", id);680 goto err_port_init;681 }682 683 port->adver_link_modes = port->caps.supp_link_modes;684 port->adver_fec = 0;685 port->autoneg = true;686 687 /* initialize config mac */688 if (port->caps.transceiver != PRESTERA_PORT_TCVR_SFP) {689 cfg_mac.admin = true;690 cfg_mac.mode = PRESTERA_MAC_MODE_INTERNAL;691 } else {692 cfg_mac.admin = false;693 cfg_mac.mode = PRESTERA_MAC_MODE_MAX;694 }695 cfg_mac.inband = 0;696 cfg_mac.speed = 0;697 cfg_mac.duplex = DUPLEX_UNKNOWN;698 cfg_mac.fec = PRESTERA_PORT_FEC_OFF;699 700 err = prestera_port_cfg_mac_write(port, &cfg_mac);701 if (err) {702 dev_err(prestera_dev(sw),703 "Failed to set port(%u) mac mode\n", id);704 goto err_port_init;705 }706 707 /* initialize config phy (if this is inegral) */708 if (port->caps.transceiver != PRESTERA_PORT_TCVR_SFP) {709 port->cfg_phy.mdix = ETH_TP_MDI_AUTO;710 port->cfg_phy.admin = false;711 err = prestera_hw_port_phy_mode_set(port,712 port->cfg_phy.admin,713 false, 0, 0,714 port->cfg_phy.mdix);715 if (err) {716 dev_err(prestera_dev(sw),717 "Failed to set port(%u) phy mode\n", id);718 goto err_port_init;719 }720 }721 722 err = prestera_rxtx_port_init(port);723 if (err)724 goto err_port_init;725 726 INIT_DELAYED_WORK(&port->cached_hw_stats.caching_dw,727 &prestera_port_stats_update);728 729 prestera_port_list_add(port);730 731 err = register_netdev(dev);732 if (err)733 goto err_register_netdev;734 735 err = prestera_port_sfp_bind(port);736 if (err)737 goto err_sfp_bind;738 739 return 0;740 741err_sfp_bind:742 unregister_netdev(dev);743err_register_netdev:744 prestera_port_list_del(port);745err_port_init:746 prestera_devlink_port_unregister(port);747err_dl_port_register:748err_port_info_get:749 free_netdev(dev);750 return err;751}752 753static void prestera_port_destroy(struct prestera_port *port)754{755 struct net_device *dev = port->dev;756 757 cancel_delayed_work_sync(&port->cached_hw_stats.caching_dw);758 unregister_netdev(dev);759 prestera_port_list_del(port);760 prestera_devlink_port_unregister(port);761 free_netdev(dev);762}763 764static void prestera_destroy_ports(struct prestera_switch *sw)765{766 struct prestera_port *port, *tmp;767 768 list_for_each_entry_safe(port, tmp, &sw->port_list, list)769 prestera_port_destroy(port);770}771 772static int prestera_create_ports(struct prestera_switch *sw)773{774 struct prestera_port *port, *tmp;775 u32 port_idx;776 int err;777 778 for (port_idx = 0; port_idx < sw->port_count; port_idx++) {779 err = prestera_port_create(sw, port_idx);780 if (err)781 goto err_port_create;782 }783 784 return 0;785 786err_port_create:787 list_for_each_entry_safe(port, tmp, &sw->port_list, list) {788 prestera_port_sfp_unbind(port);789 prestera_port_destroy(port);790 }791 792 return err;793}794 795static void prestera_port_handle_event(struct prestera_switch *sw,796 struct prestera_event *evt, void *arg)797{798 struct prestera_port_mac_state smac;799 struct prestera_port_event *pevt;800 struct delayed_work *caching_dw;801 struct prestera_port *port;802 803 if (evt->id == PRESTERA_PORT_EVENT_MAC_STATE_CHANGED) {804 pevt = &evt->port_evt;805 port = prestera_find_port(sw, pevt->port_id);806 if (!port || !port->dev)807 return;808 809 caching_dw = &port->cached_hw_stats.caching_dw;810 811 memset(&smac, 0, sizeof(smac));812 smac.valid = true;813 smac.oper = pevt->data.mac.oper;814 if (smac.oper) {815 smac.mode = pevt->data.mac.mode;816 smac.speed = pevt->data.mac.speed;817 smac.duplex = pevt->data.mac.duplex;818 smac.fc = pevt->data.mac.fc;819 smac.fec = pevt->data.mac.fec;820 }821 prestera_port_mac_state_cache_write(port, &smac);822 823 if (port->state_mac.oper) {824 if (port->phy_link)825 phylink_pcs_change(&port->phylink_pcs, true);826 else827 netif_carrier_on(port->dev);828 829 if (!delayed_work_pending(caching_dw))830 queue_delayed_work(prestera_wq, caching_dw, 0);831 } else {832 if (port->phy_link)833 phylink_pcs_change(&port->phylink_pcs, false);834 else if (netif_running(port->dev) && netif_carrier_ok(port->dev))835 netif_carrier_off(port->dev);836 837 if (delayed_work_pending(caching_dw))838 cancel_delayed_work(caching_dw);839 }840 }841}842 843static int prestera_event_handlers_register(struct prestera_switch *sw)844{845 return prestera_hw_event_handler_register(sw, PRESTERA_EVENT_TYPE_PORT,846 prestera_port_handle_event,847 NULL);848}849 850static void prestera_event_handlers_unregister(struct prestera_switch *sw)851{852 prestera_hw_event_handler_unregister(sw, PRESTERA_EVENT_TYPE_PORT,853 prestera_port_handle_event);854}855 856static int prestera_switch_set_base_mac_addr(struct prestera_switch *sw)857{858 int ret;859 860 if (sw->np)861 ret = of_get_mac_address(sw->np, sw->base_mac);862 if (!is_valid_ether_addr(sw->base_mac) || ret) {863 eth_random_addr(sw->base_mac);864 dev_info(prestera_dev(sw), "using random base mac address\n");865 }866 867 return prestera_hw_switch_mac_set(sw, sw->base_mac);868}869 870struct prestera_lag *prestera_lag_by_id(struct prestera_switch *sw, u16 id)871{872 return id < sw->lag_max ? &sw->lags[id] : NULL;873}874 875static struct prestera_lag *prestera_lag_by_dev(struct prestera_switch *sw,876 struct net_device *dev)877{878 struct prestera_lag *lag;879 u16 id;880 881 for (id = 0; id < sw->lag_max; id++) {882 lag = &sw->lags[id];883 if (lag->dev == dev)884 return lag;885 }886 887 return NULL;888}889 890int prestera_lag_id(struct prestera_switch *sw,891 struct net_device *lag_dev, u16 *lag_id)892{893 struct prestera_lag *lag;894 int free_id = -1;895 int id;896 897 for (id = 0; id < sw->lag_max; id++) {898 lag = prestera_lag_by_id(sw, id);899 if (lag->member_count) {900 if (lag->dev == lag_dev) {901 *lag_id = id;902 return 0;903 }904 } else if (free_id < 0) {905 free_id = id;906 }907 }908 if (free_id < 0)909 return -ENOSPC;910 *lag_id = free_id;911 return 0;912}913 914static struct prestera_lag *prestera_lag_create(struct prestera_switch *sw,915 struct net_device *lag_dev)916{917 struct prestera_lag *lag = NULL;918 u16 id;919 920 for (id = 0; id < sw->lag_max; id++) {921 lag = &sw->lags[id];922 if (!lag->dev)923 break;924 }925 if (lag) {926 INIT_LIST_HEAD(&lag->members);927 lag->dev = lag_dev;928 }929 930 return lag;931}932 933static void prestera_lag_destroy(struct prestera_switch *sw,934 struct prestera_lag *lag)935{936 WARN_ON(!list_empty(&lag->members));937 lag->member_count = 0;938 lag->dev = NULL;939}940 941static int prestera_lag_port_add(struct prestera_port *port,942 struct net_device *lag_dev)943{944 struct prestera_switch *sw = port->sw;945 struct prestera_lag *lag;946 int err;947 948 lag = prestera_lag_by_dev(sw, lag_dev);949 if (!lag) {950 lag = prestera_lag_create(sw, lag_dev);951 if (!lag)952 return -ENOSPC;953 }954 955 if (lag->member_count >= sw->lag_member_max)956 return -ENOSPC;957 958 err = prestera_hw_lag_member_add(port, lag->lag_id);959 if (err) {960 if (!lag->member_count)961 prestera_lag_destroy(sw, lag);962 return err;963 }964 965 list_add(&port->lag_member, &lag->members);966 lag->member_count++;967 port->lag = lag;968 969 return 0;970}971 972static int prestera_lag_port_del(struct prestera_port *port)973{974 struct prestera_switch *sw = port->sw;975 struct prestera_lag *lag = port->lag;976 int err;977 978 if (!lag || !lag->member_count)979 return -EINVAL;980 981 err = prestera_hw_lag_member_del(port, lag->lag_id);982 if (err)983 return err;984 985 list_del(&port->lag_member);986 lag->member_count--;987 port->lag = NULL;988 989 if (netif_is_bridge_port(lag->dev)) {990 struct net_device *br_dev;991 992 br_dev = netdev_master_upper_dev_get(lag->dev);993 994 prestera_bridge_port_leave(br_dev, port);995 }996 997 if (!lag->member_count)998 prestera_lag_destroy(sw, lag);999 1000 return 0;1001}1002 1003bool prestera_port_is_lag_member(const struct prestera_port *port)1004{1005 return !!port->lag;1006}1007 1008u16 prestera_port_lag_id(const struct prestera_port *port)1009{1010 return port->lag->lag_id;1011}1012 1013static 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 1027static 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 1037bool prestera_netdev_check(const struct net_device *dev)1038{1039 return dev->netdev_ops == &prestera_netdev_ops;1040}1041 1042static 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 1055struct 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 1070static 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 1089static 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 1101static 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 else1156 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 else1161 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 1172static 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 1191static 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 1205struct prestera_mdb_entry *1206prestera_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 1230err_mdb_hw_create:1231 prestera_flood_domain_destroy(flood_domain);1232err_flood_domain_create:1233 kfree(mdb_entry);1234err_mdb_alloc:1235 return NULL;1236}1237 1238void 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 1245struct prestera_flood_domain *1246prestera_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 1266void 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 1273int1274prestera_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 1311err_prestera_mdb_port_create_hw:1312 list_del(&flood_domain_port->flood_domain_port_node);1313 kfree(flood_domain_port);1314err_port_alloc:1315 return err;1316}1317 1318void1319prestera_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 1333struct prestera_flood_domain_port *1334prestera_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 1349static 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 1356static void prestera_netdev_event_handler_unregister(struct prestera_switch *sw)1357{1358 unregister_netdevice_notifier(&sw->netdev_nb);1359}1360 1361static int prestera_switch_init(struct prestera_switch *sw)1362{1363 int err;1364 1365 sw->np = sw->dev->dev->of_node;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 1427err_ports_create:1428 prestera_lag_fini(sw);1429err_lag_init:1430 prestera_devlink_traps_unregister(sw);1431err_dl_register:1432 prestera_span_fini(sw);1433err_span_init:1434 prestera_acl_fini(sw);1435err_acl_init:1436 prestera_counter_fini(sw);1437err_counter_init:1438 prestera_event_handlers_unregister(sw);1439err_handlers_register:1440 prestera_rxtx_switch_fini(sw);1441err_rxtx_register:1442 prestera_switchdev_fini(sw);1443err_swdev_register:1444 prestera_router_fini(sw);1445err_router_init:1446 prestera_netdev_event_handler_unregister(sw);1447 prestera_hw_switch_fini(sw);1448 1449 return err;1450}1451 1452static 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 1470int 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}1490EXPORT_SYMBOL(prestera_device_register);1491 1492void 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}1499EXPORT_SYMBOL(prestera_device_unregister);1500 1501static 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 1516static void __exit prestera_module_exit(void)1517{1518 destroy_workqueue(prestera_wq);1519 destroy_workqueue(prestera_owq);1520}1521 1522module_init(prestera_module_init);1523module_exit(prestera_module_exit);1524 1525MODULE_LICENSE("Dual BSD/GPL");1526MODULE_DESCRIPTION("Marvell Prestera switch driver");1527