Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Texas Instruments switchdev Driver
0004  *
0005  * Copyright (C) 2019 Texas Instruments
0006  *
0007  */
0008 
0009 #include <linux/etherdevice.h>
0010 #include <linux/if_bridge.h>
0011 #include <linux/netdevice.h>
0012 #include <linux/workqueue.h>
0013 #include <net/switchdev.h>
0014 
0015 #include "cpsw.h"
0016 #include "cpsw_ale.h"
0017 #include "cpsw_priv.h"
0018 #include "cpsw_switchdev.h"
0019 
0020 struct cpsw_switchdev_event_work {
0021     struct work_struct work;
0022     struct switchdev_notifier_fdb_info fdb_info;
0023     struct cpsw_priv *priv;
0024     unsigned long event;
0025 };
0026 
0027 static int cpsw_port_stp_state_set(struct cpsw_priv *priv, u8 state)
0028 {
0029     struct cpsw_common *cpsw = priv->cpsw;
0030     u8 cpsw_state;
0031     int ret = 0;
0032 
0033     switch (state) {
0034     case BR_STATE_FORWARDING:
0035         cpsw_state = ALE_PORT_STATE_FORWARD;
0036         break;
0037     case BR_STATE_LEARNING:
0038         cpsw_state = ALE_PORT_STATE_LEARN;
0039         break;
0040     case BR_STATE_DISABLED:
0041         cpsw_state = ALE_PORT_STATE_DISABLE;
0042         break;
0043     case BR_STATE_LISTENING:
0044     case BR_STATE_BLOCKING:
0045         cpsw_state = ALE_PORT_STATE_BLOCK;
0046         break;
0047     default:
0048         return -EOPNOTSUPP;
0049     }
0050 
0051     ret = cpsw_ale_control_set(cpsw->ale, priv->emac_port,
0052                    ALE_PORT_STATE, cpsw_state);
0053     dev_dbg(priv->dev, "ale state: %u\n", cpsw_state);
0054 
0055     return ret;
0056 }
0057 
0058 static int cpsw_port_attr_br_flags_set(struct cpsw_priv *priv,
0059                        struct net_device *orig_dev,
0060                        struct switchdev_brport_flags flags)
0061 {
0062     struct cpsw_common *cpsw = priv->cpsw;
0063 
0064     if (flags.mask & BR_MCAST_FLOOD) {
0065         bool unreg_mcast_add = false;
0066 
0067         if (flags.val & BR_MCAST_FLOOD)
0068             unreg_mcast_add = true;
0069 
0070         dev_dbg(priv->dev, "BR_MCAST_FLOOD: %d port %u\n",
0071             unreg_mcast_add, priv->emac_port);
0072 
0073         cpsw_ale_set_unreg_mcast(cpsw->ale, BIT(priv->emac_port),
0074                      unreg_mcast_add);
0075     }
0076 
0077     return 0;
0078 }
0079 
0080 static int cpsw_port_attr_br_flags_pre_set(struct net_device *netdev,
0081                        struct switchdev_brport_flags flags)
0082 {
0083     if (flags.mask & ~(BR_LEARNING | BR_MCAST_FLOOD))
0084         return -EINVAL;
0085 
0086     return 0;
0087 }
0088 
0089 static int cpsw_port_attr_set(struct net_device *ndev, const void *ctx,
0090                   const struct switchdev_attr *attr,
0091                   struct netlink_ext_ack *extack)
0092 {
0093     struct cpsw_priv *priv = netdev_priv(ndev);
0094     int ret;
0095 
0096     dev_dbg(priv->dev, "attr: id %u port: %u\n", attr->id, priv->emac_port);
0097 
0098     switch (attr->id) {
0099     case SWITCHDEV_ATTR_ID_PORT_PRE_BRIDGE_FLAGS:
0100         ret = cpsw_port_attr_br_flags_pre_set(ndev,
0101                               attr->u.brport_flags);
0102         break;
0103     case SWITCHDEV_ATTR_ID_PORT_STP_STATE:
0104         ret = cpsw_port_stp_state_set(priv, attr->u.stp_state);
0105         dev_dbg(priv->dev, "stp state: %u\n", attr->u.stp_state);
0106         break;
0107     case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
0108         ret = cpsw_port_attr_br_flags_set(priv, attr->orig_dev,
0109                           attr->u.brport_flags);
0110         break;
0111     default:
0112         ret = -EOPNOTSUPP;
0113         break;
0114     }
0115 
0116     return ret;
0117 }
0118 
0119 static u16 cpsw_get_pvid(struct cpsw_priv *priv)
0120 {
0121     struct cpsw_common *cpsw = priv->cpsw;
0122     u32 __iomem *port_vlan_reg;
0123     u32 pvid;
0124 
0125     if (priv->emac_port) {
0126         int reg = CPSW2_PORT_VLAN;
0127 
0128         if (cpsw->version == CPSW_VERSION_1)
0129             reg = CPSW1_PORT_VLAN;
0130         pvid = slave_read(cpsw->slaves + (priv->emac_port - 1), reg);
0131     } else {
0132         port_vlan_reg = &cpsw->host_port_regs->port_vlan;
0133         pvid = readl(port_vlan_reg);
0134     }
0135 
0136     pvid = pvid & 0xfff;
0137 
0138     return pvid;
0139 }
0140 
0141 static void cpsw_set_pvid(struct cpsw_priv *priv, u16 vid, bool cfi, u32 cos)
0142 {
0143     struct cpsw_common *cpsw = priv->cpsw;
0144     void __iomem *port_vlan_reg;
0145     u32 pvid;
0146 
0147     pvid = vid;
0148     pvid |= cfi ? BIT(12) : 0;
0149     pvid |= (cos & 0x7) << 13;
0150 
0151     if (priv->emac_port) {
0152         int reg = CPSW2_PORT_VLAN;
0153 
0154         if (cpsw->version == CPSW_VERSION_1)
0155             reg = CPSW1_PORT_VLAN;
0156         /* no barrier */
0157         slave_write(cpsw->slaves + (priv->emac_port - 1), pvid, reg);
0158     } else {
0159         /* CPU port */
0160         port_vlan_reg = &cpsw->host_port_regs->port_vlan;
0161         writel(pvid, port_vlan_reg);
0162     }
0163 }
0164 
0165 static int cpsw_port_vlan_add(struct cpsw_priv *priv, bool untag, bool pvid,
0166                   u16 vid, struct net_device *orig_dev)
0167 {
0168     bool cpu_port = netif_is_bridge_master(orig_dev);
0169     struct cpsw_common *cpsw = priv->cpsw;
0170     int unreg_mcast_mask = 0;
0171     int reg_mcast_mask = 0;
0172     int untag_mask = 0;
0173     int port_mask;
0174     int ret = 0;
0175     u32 flags;
0176 
0177     if (cpu_port) {
0178         port_mask = BIT(HOST_PORT_NUM);
0179         flags = orig_dev->flags;
0180         unreg_mcast_mask = port_mask;
0181     } else {
0182         port_mask = BIT(priv->emac_port);
0183         flags = priv->ndev->flags;
0184     }
0185 
0186     if (flags & IFF_MULTICAST)
0187         reg_mcast_mask = port_mask;
0188 
0189     if (untag)
0190         untag_mask = port_mask;
0191 
0192     ret = cpsw_ale_vlan_add_modify(cpsw->ale, vid, port_mask, untag_mask,
0193                        reg_mcast_mask, unreg_mcast_mask);
0194     if (ret) {
0195         dev_err(priv->dev, "Unable to add vlan\n");
0196         return ret;
0197     }
0198 
0199     if (cpu_port)
0200         cpsw_ale_add_ucast(cpsw->ale, priv->mac_addr,
0201                    HOST_PORT_NUM, ALE_VLAN, vid);
0202     if (!pvid)
0203         return ret;
0204 
0205     cpsw_set_pvid(priv, vid, 0, 0);
0206 
0207     dev_dbg(priv->dev, "VID add: %s: vid:%u ports:%X\n",
0208         priv->ndev->name, vid, port_mask);
0209     return ret;
0210 }
0211 
0212 static int cpsw_port_vlan_del(struct cpsw_priv *priv, u16 vid,
0213                   struct net_device *orig_dev)
0214 {
0215     bool cpu_port = netif_is_bridge_master(orig_dev);
0216     struct cpsw_common *cpsw = priv->cpsw;
0217     int port_mask;
0218     int ret = 0;
0219 
0220     if (cpu_port)
0221         port_mask = BIT(HOST_PORT_NUM);
0222     else
0223         port_mask = BIT(priv->emac_port);
0224 
0225     ret = cpsw_ale_vlan_del_modify(cpsw->ale, vid, port_mask);
0226     if (ret != 0)
0227         return ret;
0228 
0229     /* We don't care for the return value here, error is returned only if
0230      * the unicast entry is not present
0231      */
0232     if (cpu_port)
0233         cpsw_ale_del_ucast(cpsw->ale, priv->mac_addr,
0234                    HOST_PORT_NUM, ALE_VLAN, vid);
0235 
0236     if (vid == cpsw_get_pvid(priv))
0237         cpsw_set_pvid(priv, 0, 0, 0);
0238 
0239     /* We don't care for the return value here, error is returned only if
0240      * the multicast entry is not present
0241      */
0242     cpsw_ale_del_mcast(cpsw->ale, priv->ndev->broadcast,
0243                port_mask, ALE_VLAN, vid);
0244     dev_dbg(priv->dev, "VID del: %s: vid:%u ports:%X\n",
0245         priv->ndev->name, vid, port_mask);
0246 
0247     return ret;
0248 }
0249 
0250 static int cpsw_port_vlans_add(struct cpsw_priv *priv,
0251                    const struct switchdev_obj_port_vlan *vlan)
0252 {
0253     bool untag = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
0254     struct net_device *orig_dev = vlan->obj.orig_dev;
0255     bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
0256 
0257     dev_dbg(priv->dev, "VID add: %s: vid:%u flags:%X\n",
0258         priv->ndev->name, vlan->vid, vlan->flags);
0259 
0260     return cpsw_port_vlan_add(priv, untag, pvid, vlan->vid, orig_dev);
0261 }
0262 
0263 static int cpsw_port_mdb_add(struct cpsw_priv *priv,
0264                  struct switchdev_obj_port_mdb *mdb)
0265 
0266 {
0267     struct net_device *orig_dev = mdb->obj.orig_dev;
0268     bool cpu_port = netif_is_bridge_master(orig_dev);
0269     struct cpsw_common *cpsw = priv->cpsw;
0270     int port_mask;
0271     int err;
0272 
0273     if (cpu_port)
0274         port_mask = BIT(HOST_PORT_NUM);
0275     else
0276         port_mask = BIT(priv->emac_port);
0277 
0278     err = cpsw_ale_add_mcast(cpsw->ale, mdb->addr, port_mask,
0279                  ALE_VLAN, mdb->vid, 0);
0280     dev_dbg(priv->dev, "MDB add: %s: vid %u:%pM  ports: %X\n",
0281         priv->ndev->name, mdb->vid, mdb->addr, port_mask);
0282 
0283     return err;
0284 }
0285 
0286 static int cpsw_port_mdb_del(struct cpsw_priv *priv,
0287                  struct switchdev_obj_port_mdb *mdb)
0288 
0289 {
0290     struct net_device *orig_dev = mdb->obj.orig_dev;
0291     bool cpu_port = netif_is_bridge_master(orig_dev);
0292     struct cpsw_common *cpsw = priv->cpsw;
0293     int del_mask;
0294     int err;
0295 
0296     if (cpu_port)
0297         del_mask = BIT(HOST_PORT_NUM);
0298     else
0299         del_mask = BIT(priv->emac_port);
0300 
0301     err = cpsw_ale_del_mcast(cpsw->ale, mdb->addr, del_mask,
0302                  ALE_VLAN, mdb->vid);
0303     dev_dbg(priv->dev, "MDB del: %s: vid %u:%pM  ports: %X\n",
0304         priv->ndev->name, mdb->vid, mdb->addr, del_mask);
0305 
0306     return err;
0307 }
0308 
0309 static int cpsw_port_obj_add(struct net_device *ndev, const void *ctx,
0310                  const struct switchdev_obj *obj,
0311                  struct netlink_ext_ack *extack)
0312 {
0313     struct switchdev_obj_port_vlan *vlan = SWITCHDEV_OBJ_PORT_VLAN(obj);
0314     struct switchdev_obj_port_mdb *mdb = SWITCHDEV_OBJ_PORT_MDB(obj);
0315     struct cpsw_priv *priv = netdev_priv(ndev);
0316     int err = 0;
0317 
0318     dev_dbg(priv->dev, "obj_add: id %u port: %u\n",
0319         obj->id, priv->emac_port);
0320 
0321     switch (obj->id) {
0322     case SWITCHDEV_OBJ_ID_PORT_VLAN:
0323         err = cpsw_port_vlans_add(priv, vlan);
0324         break;
0325     case SWITCHDEV_OBJ_ID_PORT_MDB:
0326     case SWITCHDEV_OBJ_ID_HOST_MDB:
0327         err = cpsw_port_mdb_add(priv, mdb);
0328         break;
0329     default:
0330         err = -EOPNOTSUPP;
0331         break;
0332     }
0333 
0334     return err;
0335 }
0336 
0337 static int cpsw_port_obj_del(struct net_device *ndev, const void *ctx,
0338                  const struct switchdev_obj *obj)
0339 {
0340     struct switchdev_obj_port_vlan *vlan = SWITCHDEV_OBJ_PORT_VLAN(obj);
0341     struct switchdev_obj_port_mdb *mdb = SWITCHDEV_OBJ_PORT_MDB(obj);
0342     struct cpsw_priv *priv = netdev_priv(ndev);
0343     int err = 0;
0344 
0345     dev_dbg(priv->dev, "obj_del: id %u port: %u\n",
0346         obj->id, priv->emac_port);
0347 
0348     switch (obj->id) {
0349     case SWITCHDEV_OBJ_ID_PORT_VLAN:
0350         err = cpsw_port_vlan_del(priv, vlan->vid, vlan->obj.orig_dev);
0351         break;
0352     case SWITCHDEV_OBJ_ID_PORT_MDB:
0353     case SWITCHDEV_OBJ_ID_HOST_MDB:
0354         err = cpsw_port_mdb_del(priv, mdb);
0355         break;
0356     default:
0357         err = -EOPNOTSUPP;
0358         break;
0359     }
0360 
0361     return err;
0362 }
0363 
0364 static void cpsw_fdb_offload_notify(struct net_device *ndev,
0365                     struct switchdev_notifier_fdb_info *rcv)
0366 {
0367     struct switchdev_notifier_fdb_info info = {};
0368 
0369     info.addr = rcv->addr;
0370     info.vid = rcv->vid;
0371     info.offloaded = true;
0372     call_switchdev_notifiers(SWITCHDEV_FDB_OFFLOADED,
0373                  ndev, &info.info, NULL);
0374 }
0375 
0376 static void cpsw_switchdev_event_work(struct work_struct *work)
0377 {
0378     struct cpsw_switchdev_event_work *switchdev_work =
0379         container_of(work, struct cpsw_switchdev_event_work, work);
0380     struct cpsw_priv *priv = switchdev_work->priv;
0381     struct switchdev_notifier_fdb_info *fdb;
0382     struct cpsw_common *cpsw = priv->cpsw;
0383     int port = priv->emac_port;
0384 
0385     rtnl_lock();
0386     switch (switchdev_work->event) {
0387     case SWITCHDEV_FDB_ADD_TO_DEVICE:
0388         fdb = &switchdev_work->fdb_info;
0389 
0390         dev_dbg(cpsw->dev, "cpsw_fdb_add: MACID = %pM vid = %u flags = %u %u -- port %d\n",
0391             fdb->addr, fdb->vid, fdb->added_by_user,
0392             fdb->offloaded, port);
0393 
0394         if (!fdb->added_by_user || fdb->is_local)
0395             break;
0396         if (memcmp(priv->mac_addr, (u8 *)fdb->addr, ETH_ALEN) == 0)
0397             port = HOST_PORT_NUM;
0398 
0399         cpsw_ale_add_ucast(cpsw->ale, (u8 *)fdb->addr, port,
0400                    fdb->vid ? ALE_VLAN : 0, fdb->vid);
0401         cpsw_fdb_offload_notify(priv->ndev, fdb);
0402         break;
0403     case SWITCHDEV_FDB_DEL_TO_DEVICE:
0404         fdb = &switchdev_work->fdb_info;
0405 
0406         dev_dbg(cpsw->dev, "cpsw_fdb_del: MACID = %pM vid = %u flags = %u %u -- port %d\n",
0407             fdb->addr, fdb->vid, fdb->added_by_user,
0408             fdb->offloaded, port);
0409 
0410         if (!fdb->added_by_user || fdb->is_local)
0411             break;
0412         if (memcmp(priv->mac_addr, (u8 *)fdb->addr, ETH_ALEN) == 0)
0413             port = HOST_PORT_NUM;
0414 
0415         cpsw_ale_del_ucast(cpsw->ale, (u8 *)fdb->addr, port,
0416                    fdb->vid ? ALE_VLAN : 0, fdb->vid);
0417         break;
0418     default:
0419         break;
0420     }
0421     rtnl_unlock();
0422 
0423     kfree(switchdev_work->fdb_info.addr);
0424     kfree(switchdev_work);
0425     dev_put(priv->ndev);
0426 }
0427 
0428 /* called under rcu_read_lock() */
0429 static int cpsw_switchdev_event(struct notifier_block *unused,
0430                 unsigned long event, void *ptr)
0431 {
0432     struct net_device *ndev = switchdev_notifier_info_to_dev(ptr);
0433     struct switchdev_notifier_fdb_info *fdb_info = ptr;
0434     struct cpsw_switchdev_event_work *switchdev_work;
0435     struct cpsw_priv *priv = netdev_priv(ndev);
0436     int err;
0437 
0438     if (event == SWITCHDEV_PORT_ATTR_SET) {
0439         err = switchdev_handle_port_attr_set(ndev, ptr,
0440                              cpsw_port_dev_check,
0441                              cpsw_port_attr_set);
0442         return notifier_from_errno(err);
0443     }
0444 
0445     if (!cpsw_port_dev_check(ndev))
0446         return NOTIFY_DONE;
0447 
0448     switchdev_work = kzalloc(sizeof(*switchdev_work), GFP_ATOMIC);
0449     if (WARN_ON(!switchdev_work))
0450         return NOTIFY_BAD;
0451 
0452     INIT_WORK(&switchdev_work->work, cpsw_switchdev_event_work);
0453     switchdev_work->priv = priv;
0454     switchdev_work->event = event;
0455 
0456     switch (event) {
0457     case SWITCHDEV_FDB_ADD_TO_DEVICE:
0458     case SWITCHDEV_FDB_DEL_TO_DEVICE:
0459         memcpy(&switchdev_work->fdb_info, ptr,
0460                sizeof(switchdev_work->fdb_info));
0461         switchdev_work->fdb_info.addr = kzalloc(ETH_ALEN, GFP_ATOMIC);
0462         if (!switchdev_work->fdb_info.addr)
0463             goto err_addr_alloc;
0464         ether_addr_copy((u8 *)switchdev_work->fdb_info.addr,
0465                 fdb_info->addr);
0466         dev_hold(ndev);
0467         break;
0468     default:
0469         kfree(switchdev_work);
0470         return NOTIFY_DONE;
0471     }
0472 
0473     queue_work(system_long_wq, &switchdev_work->work);
0474 
0475     return NOTIFY_DONE;
0476 
0477 err_addr_alloc:
0478     kfree(switchdev_work);
0479     return NOTIFY_BAD;
0480 }
0481 
0482 static struct notifier_block cpsw_switchdev_notifier = {
0483     .notifier_call = cpsw_switchdev_event,
0484 };
0485 
0486 static int cpsw_switchdev_blocking_event(struct notifier_block *unused,
0487                      unsigned long event, void *ptr)
0488 {
0489     struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
0490     int err;
0491 
0492     switch (event) {
0493     case SWITCHDEV_PORT_OBJ_ADD:
0494         err = switchdev_handle_port_obj_add(dev, ptr,
0495                             cpsw_port_dev_check,
0496                             cpsw_port_obj_add);
0497         return notifier_from_errno(err);
0498     case SWITCHDEV_PORT_OBJ_DEL:
0499         err = switchdev_handle_port_obj_del(dev, ptr,
0500                             cpsw_port_dev_check,
0501                             cpsw_port_obj_del);
0502         return notifier_from_errno(err);
0503     case SWITCHDEV_PORT_ATTR_SET:
0504         err = switchdev_handle_port_attr_set(dev, ptr,
0505                              cpsw_port_dev_check,
0506                              cpsw_port_attr_set);
0507         return notifier_from_errno(err);
0508     default:
0509         break;
0510     }
0511 
0512     return NOTIFY_DONE;
0513 }
0514 
0515 static struct notifier_block cpsw_switchdev_bl_notifier = {
0516     .notifier_call = cpsw_switchdev_blocking_event,
0517 };
0518 
0519 int cpsw_switchdev_register_notifiers(struct cpsw_common *cpsw)
0520 {
0521     int ret = 0;
0522 
0523     ret = register_switchdev_notifier(&cpsw_switchdev_notifier);
0524     if (ret) {
0525         dev_err(cpsw->dev, "register switchdev notifier fail ret:%d\n",
0526             ret);
0527         return ret;
0528     }
0529 
0530     ret = register_switchdev_blocking_notifier(&cpsw_switchdev_bl_notifier);
0531     if (ret) {
0532         dev_err(cpsw->dev, "register switchdev blocking notifier ret:%d\n",
0533             ret);
0534         unregister_switchdev_notifier(&cpsw_switchdev_notifier);
0535     }
0536 
0537     return ret;
0538 }
0539 
0540 void cpsw_switchdev_unregister_notifiers(struct cpsw_common *cpsw)
0541 {
0542     unregister_switchdev_blocking_notifier(&cpsw_switchdev_bl_notifier);
0543     unregister_switchdev_notifier(&cpsw_switchdev_notifier);
0544 }