aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWingMan Kwok2015-02-27 15:53:19 -0600
committerWingMan Kwok2015-03-10 09:20:34 -0500
commitc376febd9ff9c0bc205cd4c9a719f5578ae4bd15 (patch)
tree0a2794db9abc3db7ba0e54b0bd3e04a1c824d3e7
parentefd468cfeeb35dbb843540d6bcc8c61231a054a7 (diff)
downloadlinux-c376febd9ff9c0bc205cd4c9a719f5578ae4bd15.tar.gz
linux-c376febd9ff9c0bc205cd4c9a719f5578ae4bd15.tar.xz
linux-c376febd9ff9c0bc205cd4c9a719f5578ae4bd15.zip
net: keystone: add support of setting hw address live
This patch adds support of setting hw address live. When doing so, the netcp needs to update the lower modules cpsw and pa to update their database accordingly, i.e. setting up their receive filters. Signed-off-by: WingMan Kwok <w-kwok2@ti.com>
-rw-r--r--drivers/net/ethernet/ti/keystone_ethss.c9
-rw-r--r--drivers/net/ethernet/ti/keystone_ethss2.c10
-rw-r--r--drivers/net/ethernet/ti/keystone_net_core.c110
-rw-r--r--drivers/net/ethernet/ti/keystone_pa.c9
-rw-r--r--drivers/net/ethernet/ti/keystone_pa2.c9
-rw-r--r--drivers/net/ethernet/ti/keystone_xgess.c9
6 files changed, 128 insertions, 28 deletions
diff --git a/drivers/net/ethernet/ti/keystone_ethss.c b/drivers/net/ethernet/ti/keystone_ethss.c
index 51a5bd7038e..dc0ed03df54 100644
--- a/drivers/net/ethernet/ti/keystone_ethss.c
+++ b/drivers/net/ethernet/ti/keystone_ethss.c
@@ -556,6 +556,7 @@ struct cpsw_priv {
556 u32 num_serdes; 556 u32 num_serdes;
557 u32 serdes_lanes; 557 u32 serdes_lanes;
558 struct serdes serdes; 558 struct serdes serdes;
559 u32 opened;
559}; 560};
560 561
561/* slave_port: 0-based (currently relevant only in multi_if mode) 562/* slave_port: 0-based (currently relevant only in multi_if mode)
@@ -2403,6 +2404,9 @@ int cpsw_add_addr(void *intf_priv, struct netcp_addr *naddr)
2403 struct cpsw_intf *cpsw_intf = intf_priv; 2404 struct cpsw_intf *cpsw_intf = intf_priv;
2404 struct cpsw_priv *cpsw_dev = cpsw_intf->cpsw_priv; 2405 struct cpsw_priv *cpsw_dev = cpsw_intf->cpsw_priv;
2405 2406
2407 if (!cpsw_dev->opened)
2408 return -ENXIO;
2409
2406 dev_dbg(cpsw_dev->dev, "ethss adding address %pM, type %d\n", 2410 dev_dbg(cpsw_dev->dev, "ethss adding address %pM, type %d\n",
2407 naddr->addr, naddr->type); 2411 naddr->addr, naddr->type);
2408 2412
@@ -2429,6 +2433,9 @@ int cpsw_del_addr(void *intf_priv, struct netcp_addr *naddr)
2429 struct cpsw_intf *cpsw_intf = intf_priv; 2433 struct cpsw_intf *cpsw_intf = intf_priv;
2430 struct cpsw_priv *cpsw_dev = cpsw_intf->cpsw_priv; 2434 struct cpsw_priv *cpsw_dev = cpsw_intf->cpsw_priv;
2431 2435
2436 if (!cpsw_dev->opened)
2437 return -ENXIO;
2438
2432 dev_dbg(cpsw_dev->dev, "ethss deleting address %pM, type %d\n", 2439 dev_dbg(cpsw_dev->dev, "ethss deleting address %pM, type %d\n",
2433 naddr->addr, naddr->type); 2440 naddr->addr, naddr->type);
2434 2441
@@ -3096,6 +3103,7 @@ static int cpsw_open(void *intf_priv, struct net_device *ndev)
3096 PSTREAM_ROUTE_DMA); 3103 PSTREAM_ROUTE_DMA);
3097 3104
3098 cpsw_register_cpts(cpsw_dev); 3105 cpsw_register_cpts(cpsw_dev);
3106 cpsw_dev->opened = 1;
3099 return 0; 3107 return 0;
3100 3108
3101ale_fail: 3109ale_fail:
@@ -3135,6 +3143,7 @@ static int cpsw_close(void *intf_priv, struct net_device *ndev)
3135 clk_put(cpsw_dev->cpgmac); 3143 clk_put(cpsw_dev->cpgmac);
3136 3144
3137 cpsw_unregister_cpts(cpsw_dev); 3145 cpsw_unregister_cpts(cpsw_dev);
3146 cpsw_dev->opened = 0;
3138 return 0; 3147 return 0;
3139} 3148}
3140 3149
diff --git a/drivers/net/ethernet/ti/keystone_ethss2.c b/drivers/net/ethernet/ti/keystone_ethss2.c
index e5fadee8c0f..feaf3b82840 100644
--- a/drivers/net/ethernet/ti/keystone_ethss2.c
+++ b/drivers/net/ethernet/ti/keystone_ethss2.c
@@ -167,6 +167,7 @@
167#define IS_SGMII_MAC_PHY(i) \ 167#define IS_SGMII_MAC_PHY(i) \
168 (((i) == SGMII_LINK_MAC_PHY) || ((i) == SGMII_LINK_MAC_PHY_MASTER)) 168 (((i) == SGMII_LINK_MAC_PHY) || ((i) == SGMII_LINK_MAC_PHY_MASTER))
169 169
170
170/* CPSW Statistics register map size */ 171/* CPSW Statistics register map size */
171#define CPSW2_STATS_REGS_SIZE 0x200 172#define CPSW2_STATS_REGS_SIZE 0x200
172 173
@@ -903,6 +904,7 @@ struct cpsw2_priv {
903 u32 num_serdes; 904 u32 num_serdes;
904 u32 serdes_lanes; 905 u32 serdes_lanes;
905 struct serdes serdes; 906 struct serdes serdes;
907 u32 opened;
906}; 908};
907 909
908/* slave_port: 0-based (currently relevant only in multi_if mode) 910/* slave_port: 0-based (currently relevant only in multi_if mode)
@@ -2764,6 +2766,9 @@ static int cpsw2_add_addr(void *intf_priv, struct netcp_addr *naddr)
2764 struct cpsw2_intf *cpsw_intf = intf_priv; 2766 struct cpsw2_intf *cpsw_intf = intf_priv;
2765 struct cpsw2_priv *cpsw_dev = cpsw_intf->cpsw_priv; 2767 struct cpsw2_priv *cpsw_dev = cpsw_intf->cpsw_priv;
2766 2768
2769 if (!cpsw_dev->opened)
2770 return -ENXIO;
2771
2767 dev_dbg(cpsw_dev->dev, "ethss adding address %pM, type %d\n", 2772 dev_dbg(cpsw_dev->dev, "ethss adding address %pM, type %d\n",
2768 naddr->addr, naddr->type); 2773 naddr->addr, naddr->type);
2769 2774
@@ -2790,6 +2795,9 @@ static int cpsw2_del_addr(void *intf_priv, struct netcp_addr *naddr)
2790 struct cpsw2_intf *cpsw_intf = intf_priv; 2795 struct cpsw2_intf *cpsw_intf = intf_priv;
2791 struct cpsw2_priv *cpsw_dev = cpsw_intf->cpsw_priv; 2796 struct cpsw2_priv *cpsw_dev = cpsw_intf->cpsw_priv;
2792 2797
2798 if (!cpsw_dev->opened)
2799 return -ENXIO;
2800
2793 dev_dbg(cpsw_dev->dev, "ethss deleting address %pM, type %d\n", 2801 dev_dbg(cpsw_dev->dev, "ethss deleting address %pM, type %d\n",
2794 naddr->addr, naddr->type); 2802 naddr->addr, naddr->type);
2795 2803
@@ -3455,6 +3463,7 @@ static int cpsw2_open(void *intf_priv, struct net_device *ndev)
3455 PSTREAM_ROUTE_GLOBAL_DMA); 3463 PSTREAM_ROUTE_GLOBAL_DMA);
3456 3464
3457 cpsw2_register_cpts(cpsw_dev); 3465 cpsw2_register_cpts(cpsw_dev);
3466 cpsw_dev->opened = 1;
3458 return 0; 3467 return 0;
3459 3468
3460ale_fail: 3469ale_fail:
@@ -3494,6 +3503,7 @@ static int cpsw2_close(void *intf_priv, struct net_device *ndev)
3494 clk_put(cpsw_dev->cpgmac); 3503 clk_put(cpsw_dev->cpgmac);
3495 3504
3496 cpsw2_unregister_cpts(cpsw_dev); 3505 cpsw2_unregister_cpts(cpsw_dev);
3506 cpsw_dev->opened = 0;
3497 return 0; 3507 return 0;
3498} 3508}
3499 3509
diff --git a/drivers/net/ethernet/ti/keystone_net_core.c b/drivers/net/ethernet/ti/keystone_net_core.c
index ae5098aa09c..4d53d59ef8a 100644
--- a/drivers/net/ethernet/ti/keystone_net_core.c
+++ b/drivers/net/ethernet/ti/keystone_net_core.c
@@ -1464,65 +1464,85 @@ static void netcp_addr_clear_mark(struct netcp_priv *netcp)
1464 naddr->flags = 0; 1464 naddr->flags = 0;
1465} 1465}
1466 1466
1467static void netcp_addr_add_mark(struct netcp_priv *netcp, const u8 *addr, 1467static struct netcp_addr *
1468 enum netcp_addr_type type) 1468netcp_addr_add_mark(struct netcp_priv *netcp, const u8 *addr,
1469 enum netcp_addr_type type)
1469{ 1470{
1470 struct netcp_addr *naddr; 1471 struct netcp_addr *naddr;
1471 1472
1472 naddr = netcp_addr_find(netcp, addr, type); 1473 naddr = netcp_addr_find(netcp, addr, type);
1473 if (naddr) { 1474 if (naddr) {
1474 naddr->flags |= ADDR_VALID; 1475 naddr->flags |= ADDR_VALID;
1475 return; 1476 return naddr;
1476 } 1477 }
1477 1478
1478 naddr = netcp_addr_add(netcp, addr, type); 1479 naddr = netcp_addr_add(netcp, addr, type);
1479 if (!WARN_ON(!naddr)) 1480 if (!WARN_ON(!naddr))
1480 naddr->flags |= ADDR_NEW; 1481 naddr->flags |= ADDR_NEW;
1482
1483 return naddr;
1481} 1484}
1482 1485
1483static void netcp_addr_sweep_del(struct netcp_priv *netcp) 1486static void netcp_mod_del_addr(struct netcp_priv *netcp,
1487 struct netcp_addr *naddr)
1484{ 1488{
1485 struct netcp_addr *naddr, *tmp;
1486 struct netcp_intf_modpriv *priv; 1489 struct netcp_intf_modpriv *priv;
1487 struct netcp_module *module; 1490 struct netcp_module *module;
1488 int error; 1491
1492 dev_dbg(netcp->dev, "deleting address %pM, type %x\n",
1493 naddr->addr, naddr->type);
1494 for_each_module(netcp, priv) {
1495 module = priv->netcp_module;
1496 if (!module->del_addr)
1497 continue;
1498 module->del_addr(priv->module_priv, naddr);
1499 }
1500}
1501
1502static void netcp_addr_sweep_del(struct netcp_priv *netcp)
1503{
1504 struct netcp_addr *naddr, *tmp;
1489 1505
1490 list_for_each_entry_safe(naddr, tmp, &netcp->addr_list, node) { 1506 list_for_each_entry_safe(naddr, tmp, &netcp->addr_list, node) {
1491 if (naddr->flags & (ADDR_VALID | ADDR_NEW)) 1507 if (naddr->flags & (ADDR_VALID | ADDR_NEW))
1492 continue; 1508 continue;
1493 dev_dbg(netcp->dev, "deleting address %pM, type %x\n", 1509 netcp_mod_del_addr(netcp, naddr);
1494 naddr->addr, naddr->type);
1495 for_each_module(netcp, priv) {
1496 module = priv->netcp_module;
1497 if (!module->del_addr)
1498 continue;
1499 error = module->del_addr(priv->module_priv,
1500 naddr);
1501 WARN_ON(error);
1502 }
1503 netcp_addr_del(naddr); 1510 netcp_addr_del(naddr);
1504 } 1511 }
1505} 1512}
1506 1513
1507static void netcp_addr_sweep_add(struct netcp_priv *netcp) 1514static int netcp_mod_add_addr(struct netcp_priv *netcp,
1515 struct netcp_addr *naddr)
1508{ 1516{
1509 struct netcp_addr *naddr, *tmp;
1510 struct netcp_intf_modpriv *priv; 1517 struct netcp_intf_modpriv *priv;
1511 struct netcp_module *module; 1518 struct netcp_module *module;
1512 int error; 1519 int error;
1513 1520
1521 dev_dbg(netcp->dev, "adding address %pM, type %x\n",
1522 naddr->addr, naddr->type);
1523 for_each_module(netcp, priv) {
1524 module = priv->netcp_module;
1525 if (!module->add_addr)
1526 continue;
1527 error = module->add_addr(priv->module_priv, naddr);
1528 if (error)
1529 break;
1530 }
1531
1532 if (error)
1533 netcp_mod_del_addr(netcp, naddr);
1534
1535 return error;
1536}
1537
1538static void netcp_addr_sweep_add(struct netcp_priv *netcp)
1539{
1540 struct netcp_addr *naddr, *tmp;
1541
1514 list_for_each_entry_safe(naddr, tmp, &netcp->addr_list, node) { 1542 list_for_each_entry_safe(naddr, tmp, &netcp->addr_list, node) {
1515 if (!(naddr->flags & ADDR_NEW)) 1543 if (!(naddr->flags & ADDR_NEW))
1516 continue; 1544 continue;
1517 dev_dbg(netcp->dev, "adding address %pM, type %x\n", 1545 netcp_mod_add_addr(netcp, naddr);
1518 naddr->addr, naddr->type);
1519 for_each_module(netcp, priv) {
1520 module = priv->netcp_module;
1521 if (!module->add_addr)
1522 continue;
1523 error = module->add_addr(priv->module_priv, naddr);
1524 WARN_ON(error);
1525 }
1526 } 1546 }
1527} 1547}
1528 1548
@@ -1772,6 +1792,38 @@ static int netcp_ndo_change_mtu(struct net_device *ndev, int new_mtu)
1772 return 0; 1792 return 0;
1773} 1793}
1774 1794
1795static int netcp_ndo_set_mac_address(struct net_device *ndev, void *p)
1796{
1797 struct netcp_priv *netcp = netdev_priv(ndev);
1798 struct netcp_addr *naddr;
1799 int ret;
1800
1801 ret = eth_mac_addr(ndev, p);
1802 if (ret) {
1803 dev_info(netcp->dev, "set mac addr %pM failed (%d).\n",
1804 ((struct sockaddr *)p)->sa_data, ret);
1805 goto done;
1806 }
1807
1808 naddr = netcp_addr_add_mark(netcp, ndev->dev_addr, ADDR_DEV);
1809 if (!naddr) {
1810 ret = -ENOMEM;
1811 goto done;
1812 }
1813 if (naddr->flags & ADDR_VALID)
1814 goto done;
1815
1816 ret = netcp_mod_add_addr(netcp, naddr);
1817 if (ret) {
1818 /* lower modules are not ready yet */
1819 netcp_addr_del(naddr);
1820 ret = 0;
1821 }
1822
1823done:
1824 return ret;
1825}
1826
1775static void netcp_ndo_tx_timeout(struct net_device *ndev) 1827static void netcp_ndo_tx_timeout(struct net_device *ndev)
1776{ 1828{
1777 struct netcp_priv *netcp = netdev_priv(ndev); 1829 struct netcp_priv *netcp = netdev_priv(ndev);
@@ -1948,7 +2000,7 @@ static const struct net_device_ops netcp_netdev_ops = {
1948 .ndo_do_ioctl = netcp_ndo_ioctl, 2000 .ndo_do_ioctl = netcp_ndo_ioctl,
1949 .ndo_get_stats64 = netcp_get_stats, 2001 .ndo_get_stats64 = netcp_get_stats,
1950 .ndo_change_mtu = netcp_ndo_change_mtu, 2002 .ndo_change_mtu = netcp_ndo_change_mtu,
1951 .ndo_set_mac_address = eth_mac_addr, 2003 .ndo_set_mac_address = netcp_ndo_set_mac_address,
1952 .ndo_validate_addr = eth_validate_addr, 2004 .ndo_validate_addr = eth_validate_addr,
1953 .ndo_vlan_rx_add_vid = netcp_rx_add_vid, 2005 .ndo_vlan_rx_add_vid = netcp_rx_add_vid,
1954 .ndo_vlan_rx_kill_vid = netcp_rx_kill_vid, 2006 .ndo_vlan_rx_kill_vid = netcp_rx_kill_vid,
@@ -2000,6 +2052,8 @@ int netcp_create_interface(struct netcp_device *netcp_device,
2000 NETIF_F_SG| 2052 NETIF_F_SG|
2001 NETIF_F_FRAGLIST; 2053 NETIF_F_FRAGLIST;
2002 2054
2055 ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
2056
2003 netcp = netdev_priv(ndev); 2057 netcp = netdev_priv(ndev);
2004 spin_lock_init(&netcp->lock); 2058 spin_lock_init(&netcp->lock);
2005 INIT_LIST_HEAD(&netcp->module_head); 2059 INIT_LIST_HEAD(&netcp->module_head);
diff --git a/drivers/net/ethernet/ti/keystone_pa.c b/drivers/net/ethernet/ti/keystone_pa.c
index 5b4875f3e78..620ed16a053 100644
--- a/drivers/net/ethernet/ti/keystone_pa.c
+++ b/drivers/net/ethernet/ti/keystone_pa.c
@@ -301,6 +301,7 @@ struct pa_device {
301 u32 ip_lut_size; 301 u32 ip_lut_size;
302 netdev_features_t netif_features; 302 netdev_features_t netif_features;
303 const char *pdsp_fw[DEVICE_PA_NUM_PDSPS]; 303 const char *pdsp_fw[DEVICE_PA_NUM_PDSPS];
304 u32 opened;
304}; 305};
305 306
306#define pa_from_module(data) container_of(data, struct pa_device, module) 307#define pa_from_module(data) container_of(data, struct pa_device, module)
@@ -2095,6 +2096,7 @@ static int pa_close(void *intf_priv, struct net_device *ndev)
2095 pa_dev->clk = NULL; 2096 pa_dev->clk = NULL;
2096 } 2097 }
2097 2098
2099 pa_dev->opened = 0;
2098 mutex_unlock(&pa_modules_lock); 2100 mutex_unlock(&pa_modules_lock);
2099 return 0; 2101 return 0;
2100} 2102}
@@ -2336,6 +2338,7 @@ static int pa_open(void *intf_priv, struct net_device *ndev)
2336 netcp_register_rxhook(netcp_priv, pa_dev->rxhook_order, 2338 netcp_register_rxhook(netcp_priv, pa_dev->rxhook_order,
2337 pa_rx_hook, intf_priv); 2339 pa_rx_hook, intf_priv);
2338 2340
2341 pa_dev->opened = 1;
2339 return 0; 2342 return 0;
2340 2343
2341fail: 2344fail:
@@ -2355,6 +2358,9 @@ int pa_add_addr(void *intf_priv, struct netcp_addr *naddr)
2355 int idx, error; 2358 int idx, error;
2356 const u8 *addr; 2359 const u8 *addr;
2357 2360
2361 if (!pa_dev->opened)
2362 return -ENXIO;
2363
2358 for (idx = 0; idx < count; idx++) { 2364 for (idx = 0; idx < count; idx++) {
2359 entries[idx] = pa_lut_alloc(pa_dev, PA_LUT_MAC, 2365 entries[idx] = pa_lut_alloc(pa_dev, PA_LUT_MAC,
2360 naddr->type == ADDR_ANY); 2366 naddr->type == ADDR_ANY);
@@ -2409,6 +2415,9 @@ static int pa_del_addr(void *intf_priv, struct netcp_addr *naddr)
2409 struct pa_lut_entry *entry; 2415 struct pa_lut_entry *entry;
2410 int idx; 2416 int idx;
2411 2417
2418 if (!pa_dev->opened)
2419 return -ENXIO;
2420
2412 for (idx = 0; idx < pa_dev->lut_size; idx++) { 2421 for (idx = 0; idx < pa_dev->lut_size; idx++) {
2413 entry = pa_dev->lut + idx; 2422 entry = pa_dev->lut + idx;
2414 if (!entry->valid || !entry->in_use || entry->u.naddr != naddr) 2423 if (!entry->valid || !entry->in_use || entry->u.naddr != naddr)
diff --git a/drivers/net/ethernet/ti/keystone_pa2.c b/drivers/net/ethernet/ti/keystone_pa2.c
index caca6ff3006..3d642714ec9 100644
--- a/drivers/net/ethernet/ti/keystone_pa2.c
+++ b/drivers/net/ethernet/ti/keystone_pa2.c
@@ -1065,6 +1065,7 @@ struct pa2_device {
1065 u32 lut_size; 1065 u32 lut_size;
1066 1066
1067 const char *pdsp_fw[PA2_NUM_PDSPS]; 1067 const char *pdsp_fw[PA2_NUM_PDSPS];
1068 u32 opened;
1068}; 1069};
1069 1070
1070#define pa2_from_module(data) container_of(data, struct pa2_device, module) 1071#define pa2_from_module(data) container_of(data, struct pa2_device, module)
@@ -2413,6 +2414,7 @@ static int pa2_close(void *intf_priv, struct net_device *ndev)
2413 pa_dev->clk = NULL; 2414 pa_dev->clk = NULL;
2414 } 2415 }
2415 2416
2417 pa_dev->opened = 0;
2416 mutex_unlock(&pa2_modules_lock); 2418 mutex_unlock(&pa2_modules_lock);
2417 return 0; 2419 return 0;
2418} 2420}
@@ -2611,6 +2613,7 @@ static int pa2_open(void *intf_priv, struct net_device *ndev)
2611 netcp_register_txhook(netcp_priv, pa_dev->txhook_softcsum, 2613 netcp_register_txhook(netcp_priv, pa_dev->txhook_softcsum,
2612 pa2_txhook_softcsum, intf_priv); 2614 pa2_txhook_softcsum, intf_priv);
2613 2615
2616 pa_dev->opened = 1;
2614 return 0; 2617 return 0;
2615 2618
2616fail: 2619fail:
@@ -2662,6 +2665,9 @@ static int pa2_add_addr(void *intf_priv, struct netcp_addr *naddr)
2662 int idx, error; 2665 int idx, error;
2663 const u8 *addr; 2666 const u8 *addr;
2664 2667
2668 if (!pa_dev->opened)
2669 return -ENXIO;
2670
2665 for (idx = 0; idx < count; idx++) { 2671 for (idx = 0; idx < count; idx++) {
2666 entries[idx] = pa2_lut_alloc(pa_dev, naddr->type == ADDR_ANY); 2672 entries[idx] = pa2_lut_alloc(pa_dev, naddr->type == ADDR_ANY);
2667 if (!entries[idx]) 2673 if (!entries[idx])
@@ -2715,6 +2721,9 @@ static int pa2_del_addr(void *intf_priv, struct netcp_addr *naddr)
2715 struct pa2_lut_entry *entry; 2721 struct pa2_lut_entry *entry;
2716 int idx; 2722 int idx;
2717 2723
2724 if (!pa_dev->opened)
2725 return -ENXIO;
2726
2718 for (idx = 0; idx < pa_dev->lut_size; idx++) { 2727 for (idx = 0; idx < pa_dev->lut_size; idx++) {
2719 entry = pa_dev->lut + idx; 2728 entry = pa_dev->lut + idx;
2720 if (!entry->valid || !entry->in_use || entry->naddr != naddr) 2729 if (!entry->valid || !entry->in_use || entry->naddr != naddr)
diff --git a/drivers/net/ethernet/ti/keystone_xgess.c b/drivers/net/ethernet/ti/keystone_xgess.c
index 0af8126a11e..a84d5d78623 100644
--- a/drivers/net/ethernet/ti/keystone_xgess.c
+++ b/drivers/net/ethernet/ti/keystone_xgess.c
@@ -309,6 +309,7 @@ struct cpswx_priv {
309 struct kobject stats_kobj; 309 struct kobject stats_kobj;
310 spinlock_t hw_stats_lock; 310 spinlock_t hw_stats_lock;
311 struct device_node *serdes; 311 struct device_node *serdes;
312 u32 opened;
312}; 313};
313 314
314/* slave_port: 0-based (currently relevant only in multi_if mode) 315/* slave_port: 0-based (currently relevant only in multi_if mode)
@@ -1819,6 +1820,9 @@ static int cpswx_add_addr(void *intf_priv, struct netcp_addr *naddr)
1819 struct cpswx_intf *cpsw_intf = intf_priv; 1820 struct cpswx_intf *cpsw_intf = intf_priv;
1820 struct cpswx_priv *cpsw_dev = cpsw_intf->cpsw_priv; 1821 struct cpswx_priv *cpsw_dev = cpsw_intf->cpsw_priv;
1821 1822
1823 if (!cpsw_dev->opened)
1824 return -ENXIO;
1825
1822 dev_dbg(cpsw_dev->dev, "xgess adding address %pM, type %d\n", 1826 dev_dbg(cpsw_dev->dev, "xgess adding address %pM, type %d\n",
1823 naddr->addr, naddr->type); 1827 naddr->addr, naddr->type);
1824 1828
@@ -1845,6 +1849,9 @@ static int cpswx_del_addr(void *intf_priv, struct netcp_addr *naddr)
1845 struct cpswx_intf *cpsw_intf = intf_priv; 1849 struct cpswx_intf *cpsw_intf = intf_priv;
1846 struct cpswx_priv *cpsw_dev = cpsw_intf->cpsw_priv; 1850 struct cpswx_priv *cpsw_dev = cpsw_intf->cpsw_priv;
1847 1851
1852 if (!cpsw_dev->opened)
1853 return -ENXIO;
1854
1848 dev_dbg(cpsw_dev->dev, "xgess deleting address %pM, type %d\n", 1855 dev_dbg(cpsw_dev->dev, "xgess deleting address %pM, type %d\n",
1849 naddr->addr, naddr->type); 1856 naddr->addr, naddr->type);
1850 1857
@@ -2032,6 +2039,7 @@ static int cpswx_open(void *intf_mod_priv, struct net_device *ndev)
2032 PSTREAM_ROUTE_DMA); 2039 PSTREAM_ROUTE_DMA);
2033#endif 2040#endif
2034 2041
2042 cpsw_dev->opened = 1;
2035 return 0; 2043 return 0;
2036 2044
2037ale_fail: 2045ale_fail:
@@ -2066,6 +2074,7 @@ static int cpswx_close(void *intf_modpriv, struct net_device *ndev)
2066 clk_disable_unprepare(cpsw_dev->clk); 2074 clk_disable_unprepare(cpsw_dev->clk);
2067 clk_put(cpsw_dev->clk); 2075 clk_put(cpsw_dev->clk);
2068 2076
2077 cpsw_dev->opened = 0;
2069 return 0; 2078 return 0;
2070} 2079}
2071 2080