slave.c (db6da59cf27b5661ced03754ae0550f8914eda9e) slave.c (d06f925f13976ab82167c93467c70a337a0a3cda)
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * net/dsa/slave.c - Slave device handling
4 * Copyright (c) 2008-2009 Marvell Semiconductor
5 */
6
7#include <linux/list.h>
8#include <linux/etherdevice.h>

--- 13 unchanged lines hidden (view full) ---

22#include <net/dcbnl.h>
23#include <linux/netpoll.h>
24
25#include "dsa.h"
26#include "port.h"
27#include "master.h"
28#include "netlink.h"
29#include "slave.h"
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * net/dsa/slave.c - Slave device handling
4 * Copyright (c) 2008-2009 Marvell Semiconductor
5 */
6
7#include <linux/list.h>
8#include <linux/etherdevice.h>

--- 13 unchanged lines hidden (view full) ---

22#include <net/dcbnl.h>
23#include <linux/netpoll.h>
24
25#include "dsa.h"
26#include "port.h"
27#include "master.h"
28#include "netlink.h"
29#include "slave.h"
30#include "switch.h"
30#include "tag.h"
31
32struct dsa_switchdev_event_work {
33 struct net_device *dev;
34 struct net_device *orig_dev;
35 struct work_struct work;
36 unsigned long event;
37 /* Specific for SWITCHDEV_FDB_ADD_TO_DEVICE and

--- 118 unchanged lines hidden (view full) ---

156 ether_addr_copy(standalone_work->addr, addr);
157 standalone_work->vid = vid;
158
159 dsa_schedule_work(&standalone_work->work);
160
161 return 0;
162}
163
31#include "tag.h"
32
33struct dsa_switchdev_event_work {
34 struct net_device *dev;
35 struct net_device *orig_dev;
36 struct work_struct work;
37 unsigned long event;
38 /* Specific for SWITCHDEV_FDB_ADD_TO_DEVICE and

--- 118 unchanged lines hidden (view full) ---

157 ether_addr_copy(standalone_work->addr, addr);
158 standalone_work->vid = vid;
159
160 dsa_schedule_work(&standalone_work->work);
161
162 return 0;
163}
164
164static int dsa_slave_host_vlan_rx_filtering(struct net_device *vdev, int vid,
165 void *arg)
165static int dsa_slave_host_vlan_rx_filtering(void *arg, int vid)
166{
167 struct dsa_host_vlan_rx_filtering_ctx *ctx = arg;
168
169 return dsa_slave_schedule_standalone_work(ctx->dev, ctx->event,
170 ctx->addr, vid);
171}
172
166{
167 struct dsa_host_vlan_rx_filtering_ctx *ctx = arg;
168
169 return dsa_slave_schedule_standalone_work(ctx->dev, ctx->event,
170 ctx->addr, vid);
171}
172
173static int dsa_slave_vlan_for_each(struct net_device *dev,
174 int (*cb)(void *arg, int vid), void *arg)
175{
176 struct dsa_port *dp = dsa_slave_to_port(dev);
177 struct dsa_vlan *v;
178 int err;
179
180 lockdep_assert_held(&dev->addr_list_lock);
181
182 err = cb(arg, 0);
183 if (err)
184 return err;
185
186 list_for_each_entry(v, &dp->user_vlans, list) {
187 err = cb(arg, v->vid);
188 if (err)
189 return err;
190 }
191
192 return 0;
193}
194
173static int dsa_slave_sync_uc(struct net_device *dev,
174 const unsigned char *addr)
175{
176 struct net_device *master = dsa_slave_to_master(dev);
177 struct dsa_port *dp = dsa_slave_to_port(dev);
178 struct dsa_host_vlan_rx_filtering_ctx ctx = {
179 .dev = dev,
180 .addr = addr,
181 .event = DSA_UC_ADD,
182 };
195static int dsa_slave_sync_uc(struct net_device *dev,
196 const unsigned char *addr)
197{
198 struct net_device *master = dsa_slave_to_master(dev);
199 struct dsa_port *dp = dsa_slave_to_port(dev);
200 struct dsa_host_vlan_rx_filtering_ctx ctx = {
201 .dev = dev,
202 .addr = addr,
203 .event = DSA_UC_ADD,
204 };
183 int err;
184
185 dev_uc_add(master, addr);
186
187 if (!dsa_switch_supports_uc_filtering(dp->ds))
188 return 0;
189
205
206 dev_uc_add(master, addr);
207
208 if (!dsa_switch_supports_uc_filtering(dp->ds))
209 return 0;
210
190 err = dsa_slave_schedule_standalone_work(dev, DSA_UC_ADD, addr, 0);
191 if (err)
192 return err;
193
194 return vlan_for_each(dev, dsa_slave_host_vlan_rx_filtering, &ctx);
211 return dsa_slave_vlan_for_each(dev, dsa_slave_host_vlan_rx_filtering,
212 &ctx);
195}
196
197static int dsa_slave_unsync_uc(struct net_device *dev,
198 const unsigned char *addr)
199{
200 struct net_device *master = dsa_slave_to_master(dev);
201 struct dsa_port *dp = dsa_slave_to_port(dev);
202 struct dsa_host_vlan_rx_filtering_ctx ctx = {
203 .dev = dev,
204 .addr = addr,
205 .event = DSA_UC_DEL,
206 };
213}
214
215static int dsa_slave_unsync_uc(struct net_device *dev,
216 const unsigned char *addr)
217{
218 struct net_device *master = dsa_slave_to_master(dev);
219 struct dsa_port *dp = dsa_slave_to_port(dev);
220 struct dsa_host_vlan_rx_filtering_ctx ctx = {
221 .dev = dev,
222 .addr = addr,
223 .event = DSA_UC_DEL,
224 };
207 int err;
208
209 dev_uc_del(master, addr);
210
211 if (!dsa_switch_supports_uc_filtering(dp->ds))
212 return 0;
213
225
226 dev_uc_del(master, addr);
227
228 if (!dsa_switch_supports_uc_filtering(dp->ds))
229 return 0;
230
214 err = dsa_slave_schedule_standalone_work(dev, DSA_UC_DEL, addr, 0);
215 if (err)
216 return err;
217
218 return vlan_for_each(dev, dsa_slave_host_vlan_rx_filtering, &ctx);
231 return dsa_slave_vlan_for_each(dev, dsa_slave_host_vlan_rx_filtering,
232 &ctx);
219}
220
221static int dsa_slave_sync_mc(struct net_device *dev,
222 const unsigned char *addr)
223{
224 struct net_device *master = dsa_slave_to_master(dev);
225 struct dsa_port *dp = dsa_slave_to_port(dev);
226 struct dsa_host_vlan_rx_filtering_ctx ctx = {
227 .dev = dev,
228 .addr = addr,
229 .event = DSA_MC_ADD,
230 };
233}
234
235static int dsa_slave_sync_mc(struct net_device *dev,
236 const unsigned char *addr)
237{
238 struct net_device *master = dsa_slave_to_master(dev);
239 struct dsa_port *dp = dsa_slave_to_port(dev);
240 struct dsa_host_vlan_rx_filtering_ctx ctx = {
241 .dev = dev,
242 .addr = addr,
243 .event = DSA_MC_ADD,
244 };
231 int err;
232
233 dev_mc_add(master, addr);
234
235 if (!dsa_switch_supports_mc_filtering(dp->ds))
236 return 0;
237
245
246 dev_mc_add(master, addr);
247
248 if (!dsa_switch_supports_mc_filtering(dp->ds))
249 return 0;
250
238 err = dsa_slave_schedule_standalone_work(dev, DSA_MC_ADD, addr, 0);
239 if (err)
240 return err;
241
242 return vlan_for_each(dev, dsa_slave_host_vlan_rx_filtering, &ctx);
251 return dsa_slave_vlan_for_each(dev, dsa_slave_host_vlan_rx_filtering,
252 &ctx);
243}
244
245static int dsa_slave_unsync_mc(struct net_device *dev,
246 const unsigned char *addr)
247{
248 struct net_device *master = dsa_slave_to_master(dev);
249 struct dsa_port *dp = dsa_slave_to_port(dev);
250 struct dsa_host_vlan_rx_filtering_ctx ctx = {
251 .dev = dev,
252 .addr = addr,
253 .event = DSA_MC_DEL,
254 };
253}
254
255static int dsa_slave_unsync_mc(struct net_device *dev,
256 const unsigned char *addr)
257{
258 struct net_device *master = dsa_slave_to_master(dev);
259 struct dsa_port *dp = dsa_slave_to_port(dev);
260 struct dsa_host_vlan_rx_filtering_ctx ctx = {
261 .dev = dev,
262 .addr = addr,
263 .event = DSA_MC_DEL,
264 };
255 int err;
256
257 dev_mc_del(master, addr);
258
259 if (!dsa_switch_supports_mc_filtering(dp->ds))
260 return 0;
261
265
266 dev_mc_del(master, addr);
267
268 if (!dsa_switch_supports_mc_filtering(dp->ds))
269 return 0;
270
262 err = dsa_slave_schedule_standalone_work(dev, DSA_MC_DEL, addr, 0);
263 if (err)
264 return err;
265
266 return vlan_for_each(dev, dsa_slave_host_vlan_rx_filtering, &ctx);
271 return dsa_slave_vlan_for_each(dev, dsa_slave_host_vlan_rx_filtering,
272 &ctx);
267}
268
269void dsa_slave_sync_ha(struct net_device *dev)
270{
271 struct dsa_port *dp = dsa_slave_to_port(dev);
272 struct dsa_switch *ds = dp->ds;
273 struct netdev_hw_addr *ha;
274

--- 1479 unchanged lines hidden (view full) ---

1754 .obj.id = SWITCHDEV_OBJ_ID_PORT_VLAN,
1755 .vid = vid,
1756 /* This API only allows programming tagged, non-PVID VIDs */
1757 .flags = 0,
1758 };
1759 struct netlink_ext_ack extack = {0};
1760 struct dsa_switch *ds = dp->ds;
1761 struct netdev_hw_addr *ha;
273}
274
275void dsa_slave_sync_ha(struct net_device *dev)
276{
277 struct dsa_port *dp = dsa_slave_to_port(dev);
278 struct dsa_switch *ds = dp->ds;
279 struct netdev_hw_addr *ha;
280

--- 1479 unchanged lines hidden (view full) ---

1760 .obj.id = SWITCHDEV_OBJ_ID_PORT_VLAN,
1761 .vid = vid,
1762 /* This API only allows programming tagged, non-PVID VIDs */
1763 .flags = 0,
1764 };
1765 struct netlink_ext_ack extack = {0};
1766 struct dsa_switch *ds = dp->ds;
1767 struct netdev_hw_addr *ha;
1768 struct dsa_vlan *v;
1762 int ret;
1763
1764 /* User port... */
1765 ret = dsa_port_vlan_add(dp, &vlan, &extack);
1766 if (ret) {
1767 if (extack._msg)
1768 netdev_err(dev, "%s\n", extack._msg);
1769 return ret;

--- 7 unchanged lines hidden (view full) ---

1777 extack._msg);
1778 return ret;
1779 }
1780
1781 if (!dsa_switch_supports_uc_filtering(ds) &&
1782 !dsa_switch_supports_mc_filtering(ds))
1783 return 0;
1784
1769 int ret;
1770
1771 /* User port... */
1772 ret = dsa_port_vlan_add(dp, &vlan, &extack);
1773 if (ret) {
1774 if (extack._msg)
1775 netdev_err(dev, "%s\n", extack._msg);
1776 return ret;

--- 7 unchanged lines hidden (view full) ---

1784 extack._msg);
1785 return ret;
1786 }
1787
1788 if (!dsa_switch_supports_uc_filtering(ds) &&
1789 !dsa_switch_supports_mc_filtering(ds))
1790 return 0;
1791
1792 v = kzalloc(sizeof(*v), GFP_KERNEL);
1793 if (!v) {
1794 ret = -ENOMEM;
1795 goto rollback;
1796 }
1797
1785 netif_addr_lock_bh(dev);
1786
1798 netif_addr_lock_bh(dev);
1799
1800 v->vid = vid;
1801 list_add_tail(&v->list, &dp->user_vlans);
1802
1787 if (dsa_switch_supports_mc_filtering(ds)) {
1788 netdev_for_each_synced_mc_addr(ha, dev) {
1789 dsa_slave_schedule_standalone_work(dev, DSA_MC_ADD,
1790 ha->addr, vid);
1791 }
1792 }
1793
1794 if (dsa_switch_supports_uc_filtering(ds)) {
1795 netdev_for_each_synced_uc_addr(ha, dev) {
1796 dsa_slave_schedule_standalone_work(dev, DSA_UC_ADD,
1797 ha->addr, vid);
1798 }
1799 }
1800
1801 netif_addr_unlock_bh(dev);
1802
1803 dsa_flush_workqueue();
1804
1805 return 0;
1803 if (dsa_switch_supports_mc_filtering(ds)) {
1804 netdev_for_each_synced_mc_addr(ha, dev) {
1805 dsa_slave_schedule_standalone_work(dev, DSA_MC_ADD,
1806 ha->addr, vid);
1807 }
1808 }
1809
1810 if (dsa_switch_supports_uc_filtering(ds)) {
1811 netdev_for_each_synced_uc_addr(ha, dev) {
1812 dsa_slave_schedule_standalone_work(dev, DSA_UC_ADD,
1813 ha->addr, vid);
1814 }
1815 }
1816
1817 netif_addr_unlock_bh(dev);
1818
1819 dsa_flush_workqueue();
1820
1821 return 0;
1822
1823rollback:
1824 dsa_port_host_vlan_del(dp, &vlan);
1825 dsa_port_vlan_del(dp, &vlan);
1826
1827 return ret;
1806}
1807
1808static int dsa_slave_vlan_rx_kill_vid(struct net_device *dev, __be16 proto,
1809 u16 vid)
1810{
1811 struct dsa_port *dp = dsa_slave_to_port(dev);
1812 struct switchdev_obj_port_vlan vlan = {
1813 .vid = vid,
1814 /* This API only allows programming tagged, non-PVID VIDs */
1815 .flags = 0,
1816 };
1817 struct dsa_switch *ds = dp->ds;
1818 struct netdev_hw_addr *ha;
1828}
1829
1830static int dsa_slave_vlan_rx_kill_vid(struct net_device *dev, __be16 proto,
1831 u16 vid)
1832{
1833 struct dsa_port *dp = dsa_slave_to_port(dev);
1834 struct switchdev_obj_port_vlan vlan = {
1835 .vid = vid,
1836 /* This API only allows programming tagged, non-PVID VIDs */
1837 .flags = 0,
1838 };
1839 struct dsa_switch *ds = dp->ds;
1840 struct netdev_hw_addr *ha;
1841 struct dsa_vlan *v;
1819 int err;
1820
1821 err = dsa_port_vlan_del(dp, &vlan);
1822 if (err)
1823 return err;
1824
1825 err = dsa_port_host_vlan_del(dp, &vlan);
1826 if (err)
1827 return err;
1828
1829 if (!dsa_switch_supports_uc_filtering(ds) &&
1830 !dsa_switch_supports_mc_filtering(ds))
1831 return 0;
1832
1833 netif_addr_lock_bh(dev);
1834
1842 int err;
1843
1844 err = dsa_port_vlan_del(dp, &vlan);
1845 if (err)
1846 return err;
1847
1848 err = dsa_port_host_vlan_del(dp, &vlan);
1849 if (err)
1850 return err;
1851
1852 if (!dsa_switch_supports_uc_filtering(ds) &&
1853 !dsa_switch_supports_mc_filtering(ds))
1854 return 0;
1855
1856 netif_addr_lock_bh(dev);
1857
1858 v = dsa_vlan_find(&dp->user_vlans, &vlan);
1859 if (!v) {
1860 netif_addr_unlock_bh(dev);
1861 return -ENOENT;
1862 }
1863
1864 list_del(&v->list);
1865 kfree(v);
1866
1835 if (dsa_switch_supports_mc_filtering(ds)) {
1836 netdev_for_each_synced_mc_addr(ha, dev) {
1837 dsa_slave_schedule_standalone_work(dev, DSA_MC_DEL,
1838 ha->addr, vid);
1839 }
1840 }
1841
1842 if (dsa_switch_supports_uc_filtering(ds)) {

--- 1845 unchanged lines hidden ---
1867 if (dsa_switch_supports_mc_filtering(ds)) {
1868 netdev_for_each_synced_mc_addr(ha, dev) {
1869 dsa_slave_schedule_standalone_work(dev, DSA_MC_DEL,
1870 ha->addr, vid);
1871 }
1872 }
1873
1874 if (dsa_switch_supports_uc_filtering(ds)) {

--- 1845 unchanged lines hidden ---