hc
2024-01-05 071106ecf68c401173c58808b1cf5f68cc50d390
kernel/drivers/net/ethernet/rocker/rocker_main.c
....@@ -1,12 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * drivers/net/ethernet/rocker/rocker.c - Rocker switch device driver
34 * Copyright (c) 2014-2016 Jiri Pirko <jiri@mellanox.com>
45 * Copyright (c) 2014 Scott Feldman <sfeldma@gmail.com>
5
- *
6
- * This program is free software; you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License as published by
8
- * the Free Software Foundation; either version 2 of the License, or
9
- * (at your option) any later version.
106 */
117
128 #include <linux/kernel.h>
....@@ -204,9 +200,9 @@
204200 buf = alloc + offset;
205201 expect = buf + ROCKER_TEST_DMA_BUF_SIZE;
206202
207
- dma_handle = pci_map_single(pdev, buf, ROCKER_TEST_DMA_BUF_SIZE,
208
- PCI_DMA_BIDIRECTIONAL);
209
- if (pci_dma_mapping_error(pdev, dma_handle)) {
203
+ dma_handle = dma_map_single(&pdev->dev, buf, ROCKER_TEST_DMA_BUF_SIZE,
204
+ DMA_BIDIRECTIONAL);
205
+ if (dma_mapping_error(&pdev->dev, dma_handle)) {
210206 err = -EIO;
211207 goto free_alloc;
212208 }
....@@ -238,8 +234,8 @@
238234 goto unmap;
239235
240236 unmap:
241
- pci_unmap_single(pdev, dma_handle, ROCKER_TEST_DMA_BUF_SIZE,
242
- PCI_DMA_BIDIRECTIONAL);
237
+ dma_unmap_single(&pdev->dev, dma_handle, ROCKER_TEST_DMA_BUF_SIZE,
238
+ DMA_BIDIRECTIONAL);
243239 free_alloc:
244240 kfree(alloc);
245241
....@@ -371,7 +367,7 @@
371367 static struct rocker_desc_info *
372368 rocker_desc_head_get(const struct rocker_dma_ring_info *info)
373369 {
374
- static struct rocker_desc_info *desc_info;
370
+ struct rocker_desc_info *desc_info;
375371 u32 head = __pos_inc(info->head, info->size);
376372
377373 desc_info = &info->desc_info[info->head];
....@@ -402,7 +398,7 @@
402398 static struct rocker_desc_info *
403399 rocker_desc_tail_get(struct rocker_dma_ring_info *info)
404400 {
405
- static struct rocker_desc_info *desc_info;
401
+ struct rocker_desc_info *desc_info;
406402
407403 if (info->tail == info->head)
408404 return NULL; /* nothing to be done between head and tail */
....@@ -445,9 +441,9 @@
445441 if (!info->desc_info)
446442 return -ENOMEM;
447443
448
- info->desc = pci_alloc_consistent(rocker->pdev,
449
- info->size * sizeof(*info->desc),
450
- &info->mapaddr);
444
+ info->desc = dma_alloc_coherent(&rocker->pdev->dev,
445
+ info->size * sizeof(*info->desc),
446
+ &info->mapaddr, GFP_KERNEL);
451447 if (!info->desc) {
452448 kfree(info->desc_info);
453449 return -ENOMEM;
....@@ -469,9 +465,9 @@
469465 {
470466 rocker_write64(rocker, DMA_DESC_ADDR(info->type), 0);
471467
472
- pci_free_consistent(rocker->pdev,
473
- info->size * sizeof(struct rocker_desc),
474
- info->desc, info->mapaddr);
468
+ dma_free_coherent(&rocker->pdev->dev,
469
+ info->size * sizeof(struct rocker_desc), info->desc,
470
+ info->mapaddr);
475471 kfree(info->desc_info);
476472 }
477473
....@@ -510,8 +506,9 @@
510506 goto rollback;
511507 }
512508
513
- dma_handle = pci_map_single(pdev, buf, buf_size, direction);
514
- if (pci_dma_mapping_error(pdev, dma_handle)) {
509
+ dma_handle = dma_map_single(&pdev->dev, buf, buf_size,
510
+ direction);
511
+ if (dma_mapping_error(&pdev->dev, dma_handle)) {
515512 kfree(buf);
516513 err = -EIO;
517514 goto rollback;
....@@ -530,7 +527,8 @@
530527 for (i--; i >= 0; i--) {
531528 const struct rocker_desc_info *desc_info = &info->desc_info[i];
532529
533
- pci_unmap_single(pdev, dma_unmap_addr(desc_info, mapaddr),
530
+ dma_unmap_single(&pdev->dev,
531
+ dma_unmap_addr(desc_info, mapaddr),
534532 desc_info->data_size, direction);
535533 kfree(desc_info->data);
536534 }
....@@ -550,7 +548,8 @@
550548
551549 desc->buf_addr = 0;
552550 desc->buf_size = 0;
553
- pci_unmap_single(pdev, dma_unmap_addr(desc_info, mapaddr),
551
+ dma_unmap_single(&pdev->dev,
552
+ dma_unmap_addr(desc_info, mapaddr),
554553 desc_info->data_size, direction);
555554 kfree(desc_info->data);
556555 }
....@@ -619,7 +618,7 @@
619618 spin_lock_init(&rocker->cmd_ring_lock);
620619
621620 err = rocker_dma_ring_bufs_alloc(rocker, &rocker->cmd_ring,
622
- PCI_DMA_BIDIRECTIONAL, PAGE_SIZE);
621
+ DMA_BIDIRECTIONAL, PAGE_SIZE);
623622 if (err) {
624623 dev_err(&pdev->dev, "failed to alloc command dma ring buffers\n");
625624 goto err_dma_cmd_ring_bufs_alloc;
....@@ -640,7 +639,7 @@
640639 }
641640
642641 err = rocker_dma_ring_bufs_alloc(rocker, &rocker->event_ring,
643
- PCI_DMA_FROMDEVICE, PAGE_SIZE);
642
+ DMA_FROM_DEVICE, PAGE_SIZE);
644643 if (err) {
645644 dev_err(&pdev->dev, "failed to alloc event dma ring buffers\n");
646645 goto err_dma_event_ring_bufs_alloc;
....@@ -654,7 +653,7 @@
654653 rocker_dma_cmd_ring_waits_free(rocker);
655654 err_dma_cmd_ring_waits_alloc:
656655 rocker_dma_ring_bufs_free(rocker, &rocker->cmd_ring,
657
- PCI_DMA_BIDIRECTIONAL);
656
+ DMA_BIDIRECTIONAL);
658657 err_dma_cmd_ring_bufs_alloc:
659658 rocker_dma_ring_destroy(rocker, &rocker->cmd_ring);
660659 return err;
....@@ -663,11 +662,11 @@
663662 static void rocker_dma_rings_fini(struct rocker *rocker)
664663 {
665664 rocker_dma_ring_bufs_free(rocker, &rocker->event_ring,
666
- PCI_DMA_BIDIRECTIONAL);
665
+ DMA_BIDIRECTIONAL);
667666 rocker_dma_ring_destroy(rocker, &rocker->event_ring);
668667 rocker_dma_cmd_ring_waits_free(rocker);
669668 rocker_dma_ring_bufs_free(rocker, &rocker->cmd_ring,
670
- PCI_DMA_BIDIRECTIONAL);
669
+ DMA_BIDIRECTIONAL);
671670 rocker_dma_ring_destroy(rocker, &rocker->cmd_ring);
672671 }
673672
....@@ -679,9 +678,9 @@
679678 struct pci_dev *pdev = rocker->pdev;
680679 dma_addr_t dma_handle;
681680
682
- dma_handle = pci_map_single(pdev, skb->data, buf_len,
683
- PCI_DMA_FROMDEVICE);
684
- if (pci_dma_mapping_error(pdev, dma_handle))
681
+ dma_handle = dma_map_single(&pdev->dev, skb->data, buf_len,
682
+ DMA_FROM_DEVICE);
683
+ if (dma_mapping_error(&pdev->dev, dma_handle))
685684 return -EIO;
686685 if (rocker_tlv_put_u64(desc_info, ROCKER_TLV_RX_FRAG_ADDR, dma_handle))
687686 goto tlv_put_failure;
....@@ -690,7 +689,7 @@
690689 return 0;
691690
692691 tlv_put_failure:
693
- pci_unmap_single(pdev, dma_handle, buf_len, PCI_DMA_FROMDEVICE);
692
+ dma_unmap_single(&pdev->dev, dma_handle, buf_len, DMA_FROM_DEVICE);
694693 desc_info->tlv_size = 0;
695694 return -EMSGSIZE;
696695 }
....@@ -738,7 +737,7 @@
738737 return;
739738 dma_handle = rocker_tlv_get_u64(attrs[ROCKER_TLV_RX_FRAG_ADDR]);
740739 len = rocker_tlv_get_u16(attrs[ROCKER_TLV_RX_FRAG_MAX_LEN]);
741
- pci_unmap_single(pdev, dma_handle, len, PCI_DMA_FROMDEVICE);
740
+ dma_unmap_single(&pdev->dev, dma_handle, len, DMA_FROM_DEVICE);
742741 }
743742
744743 static void rocker_dma_rx_ring_skb_free(const struct rocker *rocker,
....@@ -800,7 +799,7 @@
800799 }
801800
802801 err = rocker_dma_ring_bufs_alloc(rocker, &rocker_port->tx_ring,
803
- PCI_DMA_TODEVICE,
802
+ DMA_TO_DEVICE,
804803 ROCKER_DMA_TX_DESC_SIZE);
805804 if (err) {
806805 netdev_err(rocker_port->dev, "failed to alloc tx dma ring buffers\n");
....@@ -817,7 +816,7 @@
817816 }
818817
819818 err = rocker_dma_ring_bufs_alloc(rocker, &rocker_port->rx_ring,
820
- PCI_DMA_BIDIRECTIONAL,
819
+ DMA_BIDIRECTIONAL,
821820 ROCKER_DMA_RX_DESC_SIZE);
822821 if (err) {
823822 netdev_err(rocker_port->dev, "failed to alloc rx dma ring buffers\n");
....@@ -835,12 +834,12 @@
835834
836835 err_dma_rx_ring_skbs_alloc:
837836 rocker_dma_ring_bufs_free(rocker, &rocker_port->rx_ring,
838
- PCI_DMA_BIDIRECTIONAL);
837
+ DMA_BIDIRECTIONAL);
839838 err_dma_rx_ring_bufs_alloc:
840839 rocker_dma_ring_destroy(rocker, &rocker_port->rx_ring);
841840 err_dma_rx_ring_create:
842841 rocker_dma_ring_bufs_free(rocker, &rocker_port->tx_ring,
843
- PCI_DMA_TODEVICE);
842
+ DMA_TO_DEVICE);
844843 err_dma_tx_ring_bufs_alloc:
845844 rocker_dma_ring_destroy(rocker, &rocker_port->tx_ring);
846845 return err;
....@@ -852,10 +851,10 @@
852851
853852 rocker_dma_rx_ring_skbs_free(rocker_port);
854853 rocker_dma_ring_bufs_free(rocker, &rocker_port->rx_ring,
855
- PCI_DMA_BIDIRECTIONAL);
854
+ DMA_BIDIRECTIONAL);
856855 rocker_dma_ring_destroy(rocker, &rocker_port->rx_ring);
857856 rocker_dma_ring_bufs_free(rocker, &rocker_port->tx_ring,
858
- PCI_DMA_TODEVICE);
857
+ DMA_TO_DEVICE);
859858 rocker_dma_ring_destroy(rocker, &rocker_port->tx_ring);
860859 }
861860
....@@ -1566,6 +1565,43 @@
15661565 }
15671566
15681567 static int
1568
+rocker_world_port_attr_bridge_flags_support_get(const struct rocker_port *
1569
+ rocker_port,
1570
+ unsigned long *
1571
+ p_brport_flags_support)
1572
+{
1573
+ struct rocker_world_ops *wops = rocker_port->rocker->wops;
1574
+
1575
+ if (!wops->port_attr_bridge_flags_support_get)
1576
+ return -EOPNOTSUPP;
1577
+ return wops->port_attr_bridge_flags_support_get(rocker_port,
1578
+ p_brport_flags_support);
1579
+}
1580
+
1581
+static int
1582
+rocker_world_port_attr_pre_bridge_flags_set(struct rocker_port *rocker_port,
1583
+ unsigned long brport_flags,
1584
+ struct switchdev_trans *trans)
1585
+{
1586
+ struct rocker_world_ops *wops = rocker_port->rocker->wops;
1587
+ unsigned long brport_flags_s;
1588
+ int err;
1589
+
1590
+ if (!wops->port_attr_bridge_flags_set)
1591
+ return -EOPNOTSUPP;
1592
+
1593
+ err = rocker_world_port_attr_bridge_flags_support_get(rocker_port,
1594
+ &brport_flags_s);
1595
+ if (err)
1596
+ return err;
1597
+
1598
+ if (brport_flags & ~brport_flags_s)
1599
+ return -EINVAL;
1600
+
1601
+ return 0;
1602
+}
1603
+
1604
+static int
15691605 rocker_world_port_attr_bridge_flags_set(struct rocker_port *rocker_port,
15701606 unsigned long brport_flags,
15711607 struct switchdev_trans *trans)
....@@ -1580,31 +1616,6 @@
15801616
15811617 return wops->port_attr_bridge_flags_set(rocker_port, brport_flags,
15821618 trans);
1583
-}
1584
-
1585
-static int
1586
-rocker_world_port_attr_bridge_flags_get(const struct rocker_port *rocker_port,
1587
- unsigned long *p_brport_flags)
1588
-{
1589
- struct rocker_world_ops *wops = rocker_port->rocker->wops;
1590
-
1591
- if (!wops->port_attr_bridge_flags_get)
1592
- return -EOPNOTSUPP;
1593
- return wops->port_attr_bridge_flags_get(rocker_port, p_brport_flags);
1594
-}
1595
-
1596
-static int
1597
-rocker_world_port_attr_bridge_flags_support_get(const struct rocker_port *
1598
- rocker_port,
1599
- unsigned long *
1600
- p_brport_flags_support)
1601
-{
1602
- struct rocker_world_ops *wops = rocker_port->rocker->wops;
1603
-
1604
- if (!wops->port_attr_bridge_flags_support_get)
1605
- return -EOPNOTSUPP;
1606
- return wops->port_attr_bridge_flags_support_get(rocker_port,
1607
- p_brport_flags_support);
16081619 }
16091620
16101621 static int
....@@ -1631,9 +1642,6 @@
16311642 struct switchdev_trans *trans)
16321643 {
16331644 struct rocker_world_ops *wops = rocker_port->rocker->wops;
1634
-
1635
- if (netif_is_bridge_master(vlan->obj.orig_dev))
1636
- return -EOPNOTSUPP;
16371645
16381646 if (!wops->port_obj_vlan_add)
16391647 return -EOPNOTSUPP;
....@@ -1853,7 +1861,7 @@
18531861 continue;
18541862 dma_handle = rocker_tlv_get_u64(frag_attrs[ROCKER_TLV_TX_FRAG_ATTR_ADDR]);
18551863 len = rocker_tlv_get_u16(frag_attrs[ROCKER_TLV_TX_FRAG_ATTR_LEN]);
1856
- pci_unmap_single(pdev, dma_handle, len, DMA_TO_DEVICE);
1864
+ dma_unmap_single(&pdev->dev, dma_handle, len, DMA_TO_DEVICE);
18571865 }
18581866 }
18591867
....@@ -1866,8 +1874,8 @@
18661874 dma_addr_t dma_handle;
18671875 struct rocker_tlv *frag;
18681876
1869
- dma_handle = pci_map_single(pdev, buf, buf_len, DMA_TO_DEVICE);
1870
- if (unlikely(pci_dma_mapping_error(pdev, dma_handle))) {
1877
+ dma_handle = dma_map_single(&pdev->dev, buf, buf_len, DMA_TO_DEVICE);
1878
+ if (unlikely(dma_mapping_error(&pdev->dev, dma_handle))) {
18711879 if (net_ratelimit())
18721880 netdev_err(rocker_port->dev, "failed to dma map tx frag\n");
18731881 return -EIO;
....@@ -1887,7 +1895,7 @@
18871895 nest_cancel:
18881896 rocker_tlv_nest_cancel(desc_info, frag);
18891897 unmap_frag:
1890
- pci_unmap_single(pdev, dma_handle, buf_len, DMA_TO_DEVICE);
1898
+ dma_unmap_single(&pdev->dev, dma_handle, buf_len, DMA_TO_DEVICE);
18911899 return -EMSGSIZE;
18921900 }
18931901
....@@ -2029,6 +2037,18 @@
20292037 err);
20302038 }
20312039
2040
+static int rocker_port_get_port_parent_id(struct net_device *dev,
2041
+ struct netdev_phys_item_id *ppid)
2042
+{
2043
+ const struct rocker_port *rocker_port = netdev_priv(dev);
2044
+ const struct rocker *rocker = rocker_port->rocker;
2045
+
2046
+ ppid->id_len = sizeof(rocker->hw.id);
2047
+ memcpy(&ppid->id, &rocker->hw.id, ppid->id_len);
2048
+
2049
+ return 0;
2050
+}
2051
+
20322052 static const struct net_device_ops rocker_port_netdev_ops = {
20332053 .ndo_open = rocker_port_open,
20342054 .ndo_stop = rocker_port_stop,
....@@ -2038,38 +2058,12 @@
20382058 .ndo_get_phys_port_name = rocker_port_get_phys_port_name,
20392059 .ndo_change_proto_down = rocker_port_change_proto_down,
20402060 .ndo_neigh_destroy = rocker_port_neigh_destroy,
2061
+ .ndo_get_port_parent_id = rocker_port_get_port_parent_id,
20412062 };
20422063
20432064 /********************
20442065 * swdev interface
20452066 ********************/
2046
-
2047
-static int rocker_port_attr_get(struct net_device *dev,
2048
- struct switchdev_attr *attr)
2049
-{
2050
- const struct rocker_port *rocker_port = netdev_priv(dev);
2051
- const struct rocker *rocker = rocker_port->rocker;
2052
- int err = 0;
2053
-
2054
- switch (attr->id) {
2055
- case SWITCHDEV_ATTR_ID_PORT_PARENT_ID:
2056
- attr->u.ppid.id_len = sizeof(rocker->hw.id);
2057
- memcpy(&attr->u.ppid.id, &rocker->hw.id, attr->u.ppid.id_len);
2058
- break;
2059
- case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
2060
- err = rocker_world_port_attr_bridge_flags_get(rocker_port,
2061
- &attr->u.brport_flags);
2062
- break;
2063
- case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS_SUPPORT:
2064
- err = rocker_world_port_attr_bridge_flags_support_get(rocker_port,
2065
- &attr->u.brport_flags_support);
2066
- break;
2067
- default:
2068
- return -EOPNOTSUPP;
2069
- }
2070
-
2071
- return err;
2072
-}
20732067
20742068 static int rocker_port_attr_set(struct net_device *dev,
20752069 const struct switchdev_attr *attr,
....@@ -2083,6 +2077,11 @@
20832077 err = rocker_world_port_attr_stp_state_set(rocker_port,
20842078 attr->u.stp_state,
20852079 trans);
2080
+ break;
2081
+ case SWITCHDEV_ATTR_ID_PORT_PRE_BRIDGE_FLAGS:
2082
+ err = rocker_world_port_attr_pre_bridge_flags_set(rocker_port,
2083
+ attr->u.brport_flags,
2084
+ trans);
20862085 break;
20872086 case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
20882087 err = rocker_world_port_attr_bridge_flags_set(rocker_port,
....@@ -2142,13 +2141,6 @@
21422141 return err;
21432142 }
21442143
2145
-static const struct switchdev_ops rocker_port_switchdev_ops = {
2146
- .switchdev_port_attr_get = rocker_port_attr_get,
2147
- .switchdev_port_attr_set = rocker_port_attr_set,
2148
- .switchdev_port_obj_add = rocker_port_obj_add,
2149
- .switchdev_port_obj_del = rocker_port_obj_del,
2150
-};
2151
-
21522144 struct rocker_fib_event_work {
21532145 struct work_struct work;
21542146 union {
....@@ -2170,7 +2162,7 @@
21702162 /* Protect internal structures from changes */
21712163 rtnl_lock();
21722164 switch (fib_work->event) {
2173
- case FIB_EVENT_ENTRY_ADD:
2165
+ case FIB_EVENT_ENTRY_REPLACE:
21742166 err = rocker_world_fib4_add(rocker, &fib_work->fen_info);
21752167 if (err)
21762168 rocker_world_fib4_abort(rocker);
....@@ -2180,7 +2172,7 @@
21802172 rocker_world_fib4_del(rocker, &fib_work->fen_info);
21812173 fib_info_put(fib_work->fen_info.fi);
21822174 break;
2183
- case FIB_EVENT_RULE_ADD: /* fall through */
2175
+ case FIB_EVENT_RULE_ADD:
21842176 case FIB_EVENT_RULE_DEL:
21852177 rule = fib_work->fr_info.rule;
21862178 if (!fib4_rule_default(rule))
....@@ -2212,15 +2204,30 @@
22122204 fib_work->event = event;
22132205
22142206 switch (event) {
2215
- case FIB_EVENT_ENTRY_ADD: /* fall through */
2207
+ case FIB_EVENT_ENTRY_REPLACE:
22162208 case FIB_EVENT_ENTRY_DEL:
2209
+ if (info->family == AF_INET) {
2210
+ struct fib_entry_notifier_info *fen_info = ptr;
2211
+
2212
+ if (fen_info->fi->fib_nh_is_v6) {
2213
+ NL_SET_ERR_MSG_MOD(info->extack, "IPv6 gateway with IPv4 route is not supported");
2214
+ kfree(fib_work);
2215
+ return notifier_from_errno(-EINVAL);
2216
+ }
2217
+ if (fen_info->fi->nh) {
2218
+ NL_SET_ERR_MSG_MOD(info->extack, "IPv4 route with nexthop objects is not supported");
2219
+ kfree(fib_work);
2220
+ return notifier_from_errno(-EINVAL);
2221
+ }
2222
+ }
2223
+
22172224 memcpy(&fib_work->fen_info, ptr, sizeof(fib_work->fen_info));
22182225 /* Take referece on fib_info to prevent it from being
22192226 * freed while work is queued. Release it afterwards.
22202227 */
22212228 fib_info_hold(fib_work->fen_info.fi);
22222229 break;
2223
- case FIB_EVENT_RULE_ADD: /* fall through */
2230
+ case FIB_EVENT_RULE_ADD:
22242231 case FIB_EVENT_RULE_DEL:
22252232 memcpy(&fib_work->fr_info, ptr, sizeof(fib_work->fr_info));
22262233 fib_rule_get(fib_work->fr_info.rule);
....@@ -2602,7 +2609,6 @@
26022609 rocker_port_dev_addr_init(rocker_port);
26032610 dev->netdev_ops = &rocker_port_netdev_ops;
26042611 dev->ethtool_ops = &rocker_port_ethtool_ops;
2605
- dev->switchdev_ops = &rocker_port_switchdev_ops;
26062612 netif_tx_napi_add(dev, &rocker_port->napi_tx, rocker_port_poll_tx,
26072613 NAPI_POLL_WEIGHT);
26082614 netif_napi_add(dev, &rocker_port->napi_rx, rocker_port_poll_rx,
....@@ -2713,6 +2719,19 @@
27132719 return dev->netdev_ops == &rocker_port_netdev_ops;
27142720 }
27152721
2722
+static int
2723
+rocker_switchdev_port_attr_set_event(struct net_device *netdev,
2724
+ struct switchdev_notifier_port_attr_info *port_attr_info)
2725
+{
2726
+ int err;
2727
+
2728
+ err = rocker_port_attr_set(netdev, port_attr_info->attr,
2729
+ port_attr_info->trans);
2730
+
2731
+ port_attr_info->handled = true;
2732
+ return notifier_from_errno(err);
2733
+}
2734
+
27162735 struct rocker_switchdev_event_work {
27172736 struct work_struct work;
27182737 struct switchdev_notifier_fdb_info fdb_info;
....@@ -2728,8 +2747,9 @@
27282747
27292748 info.addr = recv_info->addr;
27302749 info.vid = recv_info->vid;
2750
+ info.offloaded = true;
27312751 call_switchdev_notifiers(SWITCHDEV_FDB_OFFLOADED,
2732
- rocker_port->dev, &info.info);
2752
+ rocker_port->dev, &info.info, NULL);
27332753 }
27342754
27352755 static void rocker_switchdev_event_work(struct work_struct *work)
....@@ -2781,6 +2801,9 @@
27812801 if (!rocker_port_dev_check(dev))
27822802 return NOTIFY_DONE;
27832803
2804
+ if (event == SWITCHDEV_PORT_ATTR_SET)
2805
+ return rocker_switchdev_port_attr_set_event(dev, ptr);
2806
+
27842807 rocker_port = netdev_priv(dev);
27852808 switchdev_work = kzalloc(sizeof(*switchdev_work), GFP_ATOMIC);
27862809 if (WARN_ON(!switchdev_work))
....@@ -2791,11 +2814,16 @@
27912814 switchdev_work->event = event;
27922815
27932816 switch (event) {
2794
- case SWITCHDEV_FDB_ADD_TO_DEVICE: /* fall through */
2817
+ case SWITCHDEV_FDB_ADD_TO_DEVICE:
27952818 case SWITCHDEV_FDB_DEL_TO_DEVICE:
27962819 memcpy(&switchdev_work->fdb_info, ptr,
27972820 sizeof(switchdev_work->fdb_info));
27982821 switchdev_work->fdb_info.addr = kzalloc(ETH_ALEN, GFP_ATOMIC);
2822
+ if (unlikely(!switchdev_work->fdb_info.addr)) {
2823
+ kfree(switchdev_work);
2824
+ return NOTIFY_BAD;
2825
+ }
2826
+
27992827 ether_addr_copy((u8 *)switchdev_work->fdb_info.addr,
28002828 fdb_info->addr);
28012829 /* Take a reference on the rocker device */
....@@ -2811,12 +2839,56 @@
28112839 return NOTIFY_DONE;
28122840 }
28132841
2842
+static int
2843
+rocker_switchdev_port_obj_event(unsigned long event, struct net_device *netdev,
2844
+ struct switchdev_notifier_port_obj_info *port_obj_info)
2845
+{
2846
+ int err = -EOPNOTSUPP;
2847
+
2848
+ switch (event) {
2849
+ case SWITCHDEV_PORT_OBJ_ADD:
2850
+ err = rocker_port_obj_add(netdev, port_obj_info->obj,
2851
+ port_obj_info->trans);
2852
+ break;
2853
+ case SWITCHDEV_PORT_OBJ_DEL:
2854
+ err = rocker_port_obj_del(netdev, port_obj_info->obj);
2855
+ break;
2856
+ }
2857
+
2858
+ port_obj_info->handled = true;
2859
+ return notifier_from_errno(err);
2860
+}
2861
+
2862
+static int rocker_switchdev_blocking_event(struct notifier_block *unused,
2863
+ unsigned long event, void *ptr)
2864
+{
2865
+ struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
2866
+
2867
+ if (!rocker_port_dev_check(dev))
2868
+ return NOTIFY_DONE;
2869
+
2870
+ switch (event) {
2871
+ case SWITCHDEV_PORT_OBJ_ADD:
2872
+ case SWITCHDEV_PORT_OBJ_DEL:
2873
+ return rocker_switchdev_port_obj_event(event, dev, ptr);
2874
+ case SWITCHDEV_PORT_ATTR_SET:
2875
+ return rocker_switchdev_port_attr_set_event(dev, ptr);
2876
+ }
2877
+
2878
+ return NOTIFY_DONE;
2879
+}
2880
+
28142881 static struct notifier_block rocker_switchdev_notifier = {
28152882 .notifier_call = rocker_switchdev_event,
28162883 };
28172884
2885
+static struct notifier_block rocker_switchdev_blocking_notifier = {
2886
+ .notifier_call = rocker_switchdev_blocking_event,
2887
+};
2888
+
28182889 static int rocker_probe(struct pci_dev *pdev, const struct pci_device_id *id)
28192890 {
2891
+ struct notifier_block *nb;
28202892 struct rocker *rocker;
28212893 int err;
28222894
....@@ -2836,17 +2908,17 @@
28362908 goto err_pci_request_regions;
28372909 }
28382910
2839
- err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
2911
+ err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
28402912 if (!err) {
2841
- err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
2913
+ err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
28422914 if (err) {
2843
- dev_err(&pdev->dev, "pci_set_consistent_dma_mask failed\n");
2915
+ dev_err(&pdev->dev, "dma_set_coherent_mask failed\n");
28442916 goto err_pci_set_dma_mask;
28452917 }
28462918 } else {
2847
- err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
2919
+ err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
28482920 if (err) {
2849
- dev_err(&pdev->dev, "pci_set_dma_mask failed\n");
2921
+ dev_err(&pdev->dev, "dma_set_mask failed\n");
28502922 goto err_pci_set_dma_mask;
28512923 }
28522924 }
....@@ -2922,7 +2994,7 @@
29222994 * the device, so no need to pass a callback.
29232995 */
29242996 rocker->fib_nb.notifier_call = rocker_router_fib_event;
2925
- err = register_fib_notifier(&rocker->fib_nb, NULL);
2997
+ err = register_fib_notifier(&init_net, &rocker->fib_nb, NULL, NULL);
29262998 if (err)
29272999 goto err_register_fib_notifier;
29283000
....@@ -2932,6 +3004,13 @@
29323004 goto err_register_switchdev_notifier;
29333005 }
29343006
3007
+ nb = &rocker_switchdev_blocking_notifier;
3008
+ err = register_switchdev_blocking_notifier(nb);
3009
+ if (err) {
3010
+ dev_err(&pdev->dev, "Failed to register switchdev blocking notifier\n");
3011
+ goto err_register_switchdev_blocking_notifier;
3012
+ }
3013
+
29353014 rocker->hw.id = rocker_read64(rocker, SWITCH_ID);
29363015
29373016 dev_info(&pdev->dev, "Rocker switch with id %*phN\n",
....@@ -2939,8 +3018,10 @@
29393018
29403019 return 0;
29413020
3021
+err_register_switchdev_blocking_notifier:
3022
+ unregister_switchdev_notifier(&rocker_switchdev_notifier);
29423023 err_register_switchdev_notifier:
2943
- unregister_fib_notifier(&rocker->fib_nb);
3024
+ unregister_fib_notifier(&init_net, &rocker->fib_nb);
29443025 err_register_fib_notifier:
29453026 rocker_remove_ports(rocker);
29463027 err_probe_ports:
....@@ -2970,9 +3051,13 @@
29703051 static void rocker_remove(struct pci_dev *pdev)
29713052 {
29723053 struct rocker *rocker = pci_get_drvdata(pdev);
3054
+ struct notifier_block *nb;
3055
+
3056
+ nb = &rocker_switchdev_blocking_notifier;
3057
+ unregister_switchdev_blocking_notifier(nb);
29733058
29743059 unregister_switchdev_notifier(&rocker_switchdev_notifier);
2975
- unregister_fib_notifier(&rocker->fib_nb);
3060
+ unregister_fib_notifier(&init_net, &rocker->fib_nb);
29763061 rocker_remove_ports(rocker);
29773062 rocker_write32(rocker, CONTROL, ROCKER_CONTROL_RESET);
29783063 destroy_workqueue(rocker->rocker_owq);
....@@ -3017,9 +3102,10 @@
30173102 struct rocker_port *port;
30183103 };
30193104
3020
-static int rocker_lower_dev_walk(struct net_device *lower_dev, void *_data)
3105
+static int rocker_lower_dev_walk(struct net_device *lower_dev,
3106
+ struct netdev_nested_priv *priv)
30213107 {
3022
- struct rocker_walk_data *data = _data;
3108
+ struct rocker_walk_data *data = (struct rocker_walk_data *)priv->data;
30233109 int ret = 0;
30243110
30253111 if (rocker_port_dev_check_under(lower_dev, data->rocker)) {
....@@ -3033,6 +3119,7 @@
30333119 struct rocker_port *rocker_port_dev_lower_find(struct net_device *dev,
30343120 struct rocker *rocker)
30353121 {
3122
+ struct netdev_nested_priv priv;
30363123 struct rocker_walk_data data;
30373124
30383125 if (rocker_port_dev_check_under(dev, rocker))
....@@ -3040,7 +3127,8 @@
30403127
30413128 data.rocker = rocker;
30423129 data.port = NULL;
3043
- netdev_walk_all_lower_dev(dev, rocker_lower_dev_walk, &data);
3130
+ priv.data = (void *)&data;
3131
+ netdev_walk_all_lower_dev(dev, rocker_lower_dev_walk, &priv);
30443132
30453133 return data.port;
30463134 }