diff options
author | Reece R. Pollack | 2015-02-16 16:32:48 -0600 |
---|---|---|
committer | Reece R. Pollack | 2015-02-16 16:32:48 -0600 |
commit | 9bc93706b37c39c3a95593dc3d56773e9b7425ad (patch) | |
tree | c51c121f0656ea39417daaf21a0c619251aa3f18 /drivers | |
parent | b70b1c4c37a9780f6718ef722fb803012ad56c2d (diff) | |
parent | dadb6a5634a3ed8138f577e98715fbc378841b5a (diff) | |
download | linux-9bc93706b37c39c3a95593dc3d56773e9b7425ad.tar.gz linux-9bc93706b37c39c3a95593dc3d56773e9b7425ad.tar.xz linux-9bc93706b37c39c3a95593dc3d56773e9b7425ad.zip |
Merge branch 'master/rebuild/24-drivers-net' into master/master
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/ethernet/ti/keystone_ethss.c | 60 | ||||
-rw-r--r-- | drivers/net/ethernet/ti/keystone_ethss2.c | 173 | ||||
-rw-r--r-- | drivers/net/ethernet/ti/keystone_net_core.c | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/ti/keystone_pa.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/ti/keystone_pa2.c | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/ti/keystone_xgess.c | 153 |
6 files changed, 125 insertions, 268 deletions
diff --git a/drivers/net/ethernet/ti/keystone_ethss.c b/drivers/net/ethernet/ti/keystone_ethss.c index a6c55d22e2e..e2aebf708dc 100644 --- a/drivers/net/ethernet/ti/keystone_ethss.c +++ b/drivers/net/ethernet/ti/keystone_ethss.c | |||
@@ -565,7 +565,6 @@ struct cpsw_intf { | |||
565 | struct list_head cpsw_intf_list; | 565 | struct list_head cpsw_intf_list; |
566 | struct timer_list timer; | 566 | struct timer_list timer; |
567 | u32 sgmii_link; | 567 | u32 sgmii_link; |
568 | unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; | ||
569 | }; | 568 | }; |
570 | 569 | ||
571 | static struct cpsw_priv *global_priv; /* FIXME: REMOVE THIS!! */ | 570 | static struct cpsw_priv *global_priv; /* FIXME: REMOVE THIS!! */ |
@@ -2363,51 +2362,30 @@ static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv) | |||
2363 | static void cpsw_add_mcast_addr(struct cpsw_intf *cpsw_intf, u8 *addr) | 2362 | static void cpsw_add_mcast_addr(struct cpsw_intf *cpsw_intf, u8 *addr) |
2364 | { | 2363 | { |
2365 | struct cpsw_priv *cpsw_dev = cpsw_intf->cpsw_priv; | 2364 | struct cpsw_priv *cpsw_dev = cpsw_intf->cpsw_priv; |
2366 | u16 vlan_id; | ||
2367 | 2365 | ||
2368 | cpsw_ale_add_mcast(cpsw_dev->ale, addr, CPSW_MASK_ALL_PORTS, 0, 0, | 2366 | cpsw_ale_add_mcast(cpsw_dev->ale, addr, CPSW_MASK_ALL_PORTS, 0, 0, |
2369 | ALE_MCAST_FWD_2); | 2367 | ALE_MCAST_FWD_2); |
2370 | for_each_set_bit(vlan_id, cpsw_intf->active_vlans, VLAN_N_VID) { | ||
2371 | cpsw_ale_add_mcast(cpsw_dev->ale, addr, CPSW_MASK_ALL_PORTS, | ||
2372 | ALE_VLAN, vlan_id, ALE_MCAST_FWD_2); | ||
2373 | } | ||
2374 | } | 2368 | } |
2375 | 2369 | ||
2376 | static void cpsw_add_ucast_addr(struct cpsw_intf *cpsw_intf, u8 *addr) | 2370 | static void cpsw_add_ucast_addr(struct cpsw_intf *cpsw_intf, u8 *addr) |
2377 | { | 2371 | { |
2378 | struct cpsw_priv *cpsw_dev = cpsw_intf->cpsw_priv; | 2372 | struct cpsw_priv *cpsw_dev = cpsw_intf->cpsw_priv; |
2379 | u16 vlan_id; | ||
2380 | 2373 | ||
2381 | cpsw_ale_add_ucast(cpsw_dev->ale, addr, cpsw_dev->host_port, 0, 0); | 2374 | cpsw_ale_add_ucast(cpsw_dev->ale, addr, cpsw_dev->host_port, 0, 0); |
2382 | |||
2383 | for_each_set_bit(vlan_id, cpsw_intf->active_vlans, VLAN_N_VID) | ||
2384 | cpsw_ale_add_ucast(cpsw_dev->ale, addr, cpsw_dev->host_port, | ||
2385 | ALE_VLAN, vlan_id); | ||
2386 | } | 2375 | } |
2387 | 2376 | ||
2388 | static void cpsw_del_mcast_addr(struct cpsw_intf *cpsw_intf, u8 *addr) | 2377 | static void cpsw_del_mcast_addr(struct cpsw_intf *cpsw_intf, u8 *addr) |
2389 | { | 2378 | { |
2390 | struct cpsw_priv *cpsw_dev = cpsw_intf->cpsw_priv; | 2379 | struct cpsw_priv *cpsw_dev = cpsw_intf->cpsw_priv; |
2391 | u16 vlan_id; | ||
2392 | 2380 | ||
2393 | cpsw_ale_del_mcast(cpsw_dev->ale, addr, 0, 0, 0); | 2381 | cpsw_ale_del_mcast(cpsw_dev->ale, addr, 0, 0, 0); |
2394 | |||
2395 | for_each_set_bit(vlan_id, cpsw_intf->active_vlans, VLAN_N_VID) { | ||
2396 | cpsw_ale_del_mcast(cpsw_dev->ale, addr, 0, ALE_VLAN, vlan_id); | ||
2397 | } | ||
2398 | } | 2382 | } |
2399 | 2383 | ||
2400 | static void cpsw_del_ucast_addr(struct cpsw_intf *cpsw_intf, u8 *addr) | 2384 | static void cpsw_del_ucast_addr(struct cpsw_intf *cpsw_intf, u8 *addr) |
2401 | { | 2385 | { |
2402 | struct cpsw_priv *cpsw_dev = cpsw_intf->cpsw_priv; | 2386 | struct cpsw_priv *cpsw_dev = cpsw_intf->cpsw_priv; |
2403 | u16 vlan_id; | ||
2404 | 2387 | ||
2405 | cpsw_ale_del_ucast(cpsw_dev->ale, addr, cpsw_dev->host_port, 0, 0); | 2388 | cpsw_ale_del_ucast(cpsw_dev->ale, addr, cpsw_dev->host_port, 0, 0); |
2406 | |||
2407 | for_each_set_bit(vlan_id, cpsw_intf->active_vlans, VLAN_N_VID) { | ||
2408 | cpsw_ale_del_ucast(cpsw_dev->ale, addr, cpsw_dev->host_port, | ||
2409 | ALE_VLAN, vlan_id); | ||
2410 | } | ||
2411 | } | 2389 | } |
2412 | 2390 | ||
2413 | int cpsw_add_addr(void *intf_priv, struct netcp_addr *naddr) | 2391 | int cpsw_add_addr(void *intf_priv, struct netcp_addr *naddr) |
@@ -2462,32 +2440,6 @@ int cpsw_del_addr(void *intf_priv, struct netcp_addr *naddr) | |||
2462 | return 0; | 2440 | return 0; |
2463 | } | 2441 | } |
2464 | 2442 | ||
2465 | int cpsw_add_vid(void *intf_priv, int vid) | ||
2466 | { | ||
2467 | struct cpsw_intf *cpsw_intf = intf_priv; | ||
2468 | struct cpsw_priv *cpsw_dev = cpsw_intf->cpsw_priv; | ||
2469 | |||
2470 | set_bit(vid, cpsw_intf->active_vlans); | ||
2471 | |||
2472 | cpsw_ale_add_vlan(cpsw_dev->ale, vid, CPSW_MASK_ALL_PORTS, | ||
2473 | CPSW_MASK_NO_PORTS, | ||
2474 | CPSW_MASK_ALL_PORTS, CPSW_MASK_PHYS_PORTS); | ||
2475 | |||
2476 | return 0; | ||
2477 | } | ||
2478 | |||
2479 | int cpsw_del_vid(void *intf_priv, int vid) | ||
2480 | { | ||
2481 | struct cpsw_intf *cpsw_intf = intf_priv; | ||
2482 | struct cpsw_priv *cpsw_dev = cpsw_intf->cpsw_priv; | ||
2483 | |||
2484 | cpsw_ale_del_vlan(cpsw_dev->ale, vid, 0); | ||
2485 | |||
2486 | clear_bit(vid, cpsw_intf->active_vlans); | ||
2487 | |||
2488 | return 0; | ||
2489 | } | ||
2490 | |||
2491 | #ifdef CONFIG_TI_CPTS | 2443 | #ifdef CONFIG_TI_CPTS |
2492 | #define KEYSTONE_PTP_FILTER \ | 2444 | #define KEYSTONE_PTP_FILTER \ |
2493 | { \ | 2445 | { \ |
@@ -3146,11 +3098,13 @@ static int cpsw_close(void *intf_priv, struct net_device *ndev) | |||
3146 | 3098 | ||
3147 | del_timer_sync(&cpsw_intf->timer); | 3099 | del_timer_sync(&cpsw_intf->timer); |
3148 | 3100 | ||
3149 | if (atomic_dec_return(&cpsw_dev->ale_refcnt) == 0) | ||
3150 | cpsw_ale_stop(cpsw_dev->ale); | ||
3151 | |||
3152 | for_each_slave(cpsw_intf, cpsw_slave_stop, cpsw_intf); | 3101 | for_each_slave(cpsw_intf, cpsw_slave_stop, cpsw_intf); |
3153 | 3102 | ||
3103 | if (atomic_dec_return(&cpsw_dev->ale_refcnt) == 0) { | ||
3104 | cpsw_ale_destroy(cpsw_dev->ale); | ||
3105 | cpsw_dev->ale = NULL; | ||
3106 | } | ||
3107 | |||
3154 | if(!cpsw_dev->force_no_hwtstamp) | 3108 | if(!cpsw_dev->force_no_hwtstamp) |
3155 | netcp_unregister_rxhook(netcp, CPSW_RXHOOK_ORDER, | 3109 | netcp_unregister_rxhook(netcp, CPSW_RXHOOK_ORDER, |
3156 | cpsw_rx_hook, cpsw_intf); | 3110 | cpsw_rx_hook, cpsw_intf); |
@@ -3174,8 +3128,6 @@ static int cpsw_remove(struct netcp_device *netcp_device, void *inst_priv) | |||
3174 | 3128 | ||
3175 | of_node_put(cpsw_dev->interfaces); | 3129 | of_node_put(cpsw_dev->interfaces); |
3176 | 3130 | ||
3177 | cpsw_ale_destroy(cpsw_dev->ale); | ||
3178 | |||
3179 | list_for_each_entry_safe(cpsw_intf, tmp, &cpsw_dev->cpsw_intf_head, | 3131 | list_for_each_entry_safe(cpsw_intf, tmp, &cpsw_dev->cpsw_intf_head, |
3180 | cpsw_intf_list) { | 3132 | cpsw_intf_list) { |
3181 | netcp_delete_interface(netcp_device, cpsw_intf->ndev); | 3133 | netcp_delete_interface(netcp_device, cpsw_intf->ndev); |
@@ -3730,8 +3682,6 @@ static struct netcp_module cpsw_module = { | |||
3730 | .release = cpsw_release, | 3682 | .release = cpsw_release, |
3731 | .add_addr = cpsw_add_addr, | 3683 | .add_addr = cpsw_add_addr, |
3732 | .del_addr = cpsw_del_addr, | 3684 | .del_addr = cpsw_del_addr, |
3733 | .add_vid = cpsw_add_vid, | ||
3734 | .del_vid = cpsw_del_vid, | ||
3735 | .ioctl = cpsw_ioctl, | 3685 | .ioctl = cpsw_ioctl, |
3736 | }; | 3686 | }; |
3737 | 3687 | ||
diff --git a/drivers/net/ethernet/ti/keystone_ethss2.c b/drivers/net/ethernet/ti/keystone_ethss2.c index 7ff7363575f..5f2c64f56c4 100644 --- a/drivers/net/ethernet/ti/keystone_ethss2.c +++ b/drivers/net/ethernet/ti/keystone_ethss2.c | |||
@@ -866,7 +866,7 @@ struct cpsw2_priv { | |||
866 | void __iomem *sgmii_port_regs; | 866 | void __iomem *sgmii_port_regs; |
867 | 867 | ||
868 | struct cpsw_ale *ale; | 868 | struct cpsw_ale *ale; |
869 | u32 ale_refcnt; | 869 | atomic_t ale_refcnt; |
870 | 870 | ||
871 | u32 link[MAX_SLAVES]; | 871 | u32 link[MAX_SLAVES]; |
872 | struct device_node *phy_node[MAX_SLAVES]; | 872 | struct device_node *phy_node[MAX_SLAVES]; |
@@ -913,7 +913,6 @@ struct cpsw2_intf { | |||
913 | struct list_head cpsw_intf_list; | 913 | struct list_head cpsw_intf_list; |
914 | struct timer_list timer; | 914 | struct timer_list timer; |
915 | u32 sgmii_link; | 915 | u32 sgmii_link; |
916 | unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; | ||
917 | }; | 916 | }; |
918 | 917 | ||
919 | struct cpsw2_attribute { | 918 | struct cpsw2_attribute { |
@@ -2540,8 +2539,7 @@ static int cpsw2_port_reset(struct cpsw2_slave *slave) | |||
2540 | /* Wait for the bit to clear */ | 2539 | /* Wait for the bit to clear */ |
2541 | for (i = 0; i < DEVICE_EMACSL_RESET_POLL_COUNT; i++) { | 2540 | for (i = 0; i < DEVICE_EMACSL_RESET_POLL_COUNT; i++) { |
2542 | v = readl(&slave->regs->soft_reset); | 2541 | v = readl(&slave->regs->soft_reset); |
2543 | if ((v & SOFT_RESET_MASK) != | 2542 | if ((v & SOFT_RESET_MASK) != SOFT_RESET) |
2544 | SOFT_RESET) | ||
2545 | return 0; | 2543 | return 0; |
2546 | } | 2544 | } |
2547 | 2545 | ||
@@ -2563,13 +2561,19 @@ static void cpsw2_port_config(struct cpsw2_slave *slave, int max_rx_len) | |||
2563 | &slave->regs->mac_control); | 2561 | &slave->regs->mac_control); |
2564 | } | 2562 | } |
2565 | 2563 | ||
2566 | static void cpsw2_slave_stop(struct cpsw2_slave *slave, struct cpsw2_priv *priv) | 2564 | static void cpsw2_slave_stop(struct cpsw2_slave *slave, |
2565 | struct cpsw2_intf *cpsw_intf) | ||
2567 | { | 2566 | { |
2567 | struct cpsw2_priv *cpsw_dev = cpsw_intf->cpsw_priv; | ||
2568 | |||
2568 | /* disable forwarding */ | 2569 | /* disable forwarding */ |
2569 | if (slave->ale) | 2570 | if (slave->ale) |
2570 | cpsw_ale_control_set(slave->ale, slave->port_num, | 2571 | cpsw_ale_control_set(slave->ale, slave->port_num, |
2571 | ALE_PORT_STATE, ALE_PORT_STATE_DISABLE); | 2572 | ALE_PORT_STATE, ALE_PORT_STATE_DISABLE); |
2572 | 2573 | ||
2574 | keystone_sgmii_rtreset(SGMII2_BASE(slave->slave_num), | ||
2575 | slave->slave_num, true); | ||
2576 | |||
2573 | cpsw2_port_reset(slave); | 2577 | cpsw2_port_reset(slave); |
2574 | 2578 | ||
2575 | if (!slave->phy) | 2579 | if (!slave->phy) |
@@ -2606,6 +2610,9 @@ static void cpsw2_slave_open(struct cpsw2_slave *slave, | |||
2606 | 2610 | ||
2607 | cpsw2_port_reset(slave); | 2611 | cpsw2_port_reset(slave); |
2608 | 2612 | ||
2613 | keystone_sgmii_rtreset(SGMII2_BASE(slave->slave_num), | ||
2614 | slave->slave_num, false); | ||
2615 | |||
2609 | cpsw2_port_config(slave, cpsw_dev->rx_packet_max); | 2616 | cpsw2_port_config(slave, cpsw_dev->rx_packet_max); |
2610 | 2617 | ||
2611 | cpsw2_set_slave_mac(slave, cpsw_intf); | 2618 | cpsw2_set_slave_mac(slave, cpsw_intf); |
@@ -2647,43 +2654,62 @@ static void cpsw2_slave_open(struct cpsw2_slave *slave, | |||
2647 | } | 2654 | } |
2648 | } | 2655 | } |
2649 | 2656 | ||
2650 | static void cpsw2_init_host_port(struct cpsw2_priv *priv, | 2657 | static int cpsw2_init_ale(struct cpsw2_priv *cpsw_dev) |
2651 | struct cpsw2_intf *cpsw_intf) | ||
2652 | { | 2658 | { |
2653 | int bypass_en = 1; | 2659 | struct cpsw_ale_params ale_params; |
2654 | 2660 | ||
2655 | /* Max length register */ | 2661 | memset(&ale_params, 0, sizeof(ale_params)); |
2656 | writel(MAX_SIZE_STREAM_BUFFER, | ||
2657 | &priv->host_port_regs->rx_maxlen); | ||
2658 | 2662 | ||
2659 | if (priv->ale_refcnt == 1) | 2663 | ale_params.dev = cpsw_dev->dev; |
2660 | cpsw_ale_start(priv->ale); | 2664 | ale_params.ale_regs = (void *)((u32)cpsw_dev->ale_reg); |
2665 | ale_params.ale_ageout = cpsw_dev->ale_ageout; | ||
2666 | ale_params.ale_entries = cpsw_dev->ale_entries; | ||
2667 | ale_params.ale_ports = cpsw_dev->ale_ports; | ||
2661 | 2668 | ||
2662 | if (!priv->multi_if) | 2669 | cpsw_dev->ale = cpsw_ale_create(&ale_params); |
2663 | bypass_en = 0; | 2670 | if (!cpsw_dev->ale) { |
2671 | dev_err(cpsw_dev->dev, | ||
2672 | "error initializing ale engine\n"); | ||
2673 | return -ENODEV; | ||
2674 | } | ||
2664 | 2675 | ||
2665 | cpsw_ale_control_set(priv->ale, 0, ALE_BYPASS, bypass_en); | 2676 | dev_info(cpsw_dev->dev, "Created a cpsw ale engine\n"); |
2666 | 2677 | ||
2667 | cpsw_ale_control_set(priv->ale, 0, ALE_NO_PORT_VLAN, 1); | 2678 | cpsw_ale_start(cpsw_dev->ale); |
2668 | 2679 | ||
2669 | cpsw_ale_control_set(priv->ale, priv->host_port, | 2680 | cpsw_ale_control_set(cpsw_dev->ale, 0, |
2681 | ALE_BYPASS, cpsw_dev->multi_if ? 1 : 0); | ||
2682 | |||
2683 | cpsw_ale_control_set(cpsw_dev->ale, 0, ALE_NO_PORT_VLAN, 1); | ||
2684 | |||
2685 | cpsw_ale_control_set(cpsw_dev->ale, cpsw_dev->host_port, | ||
2670 | ALE_PORT_STATE, ALE_PORT_STATE_FORWARD); | 2686 | ALE_PORT_STATE, ALE_PORT_STATE_FORWARD); |
2671 | 2687 | ||
2672 | cpsw_ale_control_set(priv->ale, 0, | 2688 | cpsw_ale_control_set(cpsw_dev->ale, 0, |
2673 | ALE_PORT_UNKNOWN_VLAN_MEMBER_1R4, | 2689 | ALE_PORT_UNKNOWN_VLAN_MEMBER_1R4, |
2674 | CPSW2_MASK_ALL_PORTS(priv->num_slaves + 1)); | 2690 | CPSW2_MASK_ALL_PORTS(cpsw_dev->num_slaves + 1)); |
2675 | 2691 | ||
2676 | cpsw_ale_control_set(priv->ale, 0, | 2692 | cpsw_ale_control_set(cpsw_dev->ale, 0, |
2677 | ALE_PORT_UNKNOWN_MCAST_FLOOD_1R4, | 2693 | ALE_PORT_UNKNOWN_MCAST_FLOOD_1R4, |
2678 | CPSW2_MASK_PHYS_PORTS(priv->num_slaves + 1)); | 2694 | CPSW2_MASK_PHYS_PORTS(cpsw_dev->num_slaves + 1)); |
2679 | 2695 | ||
2680 | cpsw_ale_control_set(priv->ale, 0, | 2696 | cpsw_ale_control_set(cpsw_dev->ale, 0, |
2681 | ALE_PORT_UNKNOWN_REG_MCAST_FLOOD_1R4, | 2697 | ALE_PORT_UNKNOWN_REG_MCAST_FLOOD_1R4, |
2682 | CPSW2_MASK_ALL_PORTS(priv->num_slaves + 1)); | 2698 | CPSW2_MASK_ALL_PORTS(cpsw_dev->num_slaves + 1)); |
2683 | 2699 | ||
2684 | cpsw_ale_control_set(priv->ale, 0, | 2700 | cpsw_ale_control_set(cpsw_dev->ale, 0, |
2685 | ALE_PORT_UNTAGGED_EGRESS_1R4, | 2701 | ALE_PORT_UNTAGGED_EGRESS_1R4, |
2686 | CPSW2_MASK_ALL_PORTS(priv->num_slaves + 1)); | 2702 | CPSW2_MASK_ALL_PORTS(cpsw_dev->num_slaves + 1)); |
2703 | |||
2704 | return 0; | ||
2705 | } | ||
2706 | |||
2707 | static void cpsw2_init_host_port(struct cpsw2_priv *priv) | ||
2708 | { | ||
2709 | /* Max length register */ | ||
2710 | writel(MAX_SIZE_STREAM_BUFFER, | ||
2711 | &priv->host_port_regs->rx_maxlen); | ||
2712 | |||
2687 | } | 2713 | } |
2688 | 2714 | ||
2689 | static void cpsw2_slave_init(struct cpsw2_slave *slave, struct cpsw2_priv *priv) | 2715 | static void cpsw2_slave_init(struct cpsw2_slave *slave, struct cpsw2_priv *priv) |
@@ -2698,53 +2724,31 @@ static void cpsw2_slave_init(struct cpsw2_slave *slave, struct cpsw2_priv *priv) | |||
2698 | static void cpsw2_add_mcast_addr(struct cpsw2_intf *cpsw_intf, u8 *addr) | 2724 | static void cpsw2_add_mcast_addr(struct cpsw2_intf *cpsw_intf, u8 *addr) |
2699 | { | 2725 | { |
2700 | struct cpsw2_priv *cpsw_dev = cpsw_intf->cpsw_priv; | 2726 | struct cpsw2_priv *cpsw_dev = cpsw_intf->cpsw_priv; |
2701 | u16 vlan_id; | ||
2702 | 2727 | ||
2703 | cpsw_ale_add_mcast(cpsw_dev->ale, addr, | 2728 | cpsw_ale_add_mcast(cpsw_dev->ale, addr, |
2704 | CPSW2_MASK_ALL_PORTS(cpsw_dev->num_slaves + 1), 0, 0, | 2729 | CPSW2_MASK_ALL_PORTS(cpsw_dev->num_slaves + 1), 0, 0, |
2705 | ALE_MCAST_FWD_2); | 2730 | ALE_MCAST_FWD_2); |
2706 | for_each_set_bit(vlan_id, cpsw_intf->active_vlans, VLAN_N_VID) { | ||
2707 | cpsw_ale_add_mcast(cpsw_dev->ale, addr, | ||
2708 | CPSW2_MASK_ALL_PORTS(cpsw_dev->num_slaves + 1), | ||
2709 | ALE_VLAN, vlan_id, ALE_MCAST_FWD_2); | ||
2710 | } | ||
2711 | } | 2731 | } |
2712 | 2732 | ||
2713 | static void cpsw2_add_ucast_addr(struct cpsw2_intf *cpsw_intf, u8 *addr) | 2733 | static void cpsw2_add_ucast_addr(struct cpsw2_intf *cpsw_intf, u8 *addr) |
2714 | { | 2734 | { |
2715 | struct cpsw2_priv *cpsw_dev = cpsw_intf->cpsw_priv; | 2735 | struct cpsw2_priv *cpsw_dev = cpsw_intf->cpsw_priv; |
2716 | u16 vlan_id; | ||
2717 | 2736 | ||
2718 | cpsw_ale_add_ucast(cpsw_dev->ale, addr, cpsw_dev->host_port, 0, 0); | 2737 | cpsw_ale_add_ucast(cpsw_dev->ale, addr, cpsw_dev->host_port, 0, 0); |
2719 | |||
2720 | for_each_set_bit(vlan_id, cpsw_intf->active_vlans, VLAN_N_VID) | ||
2721 | cpsw_ale_add_ucast(cpsw_dev->ale, addr, cpsw_dev->host_port, | ||
2722 | ALE_VLAN, vlan_id); | ||
2723 | } | 2738 | } |
2724 | 2739 | ||
2725 | static void cpsw2_del_mcast_addr(struct cpsw2_intf *cpsw_intf, u8 *addr) | 2740 | static void cpsw2_del_mcast_addr(struct cpsw2_intf *cpsw_intf, u8 *addr) |
2726 | { | 2741 | { |
2727 | struct cpsw2_priv *cpsw_dev = cpsw_intf->cpsw_priv; | 2742 | struct cpsw2_priv *cpsw_dev = cpsw_intf->cpsw_priv; |
2728 | u16 vlan_id; | ||
2729 | 2743 | ||
2730 | cpsw_ale_del_mcast(cpsw_dev->ale, addr, 0, 0, 0); | 2744 | cpsw_ale_del_mcast(cpsw_dev->ale, addr, 0, 0, 0); |
2731 | |||
2732 | for_each_set_bit(vlan_id, cpsw_intf->active_vlans, VLAN_N_VID) { | ||
2733 | cpsw_ale_del_mcast(cpsw_dev->ale, addr, 0, ALE_VLAN, vlan_id); | ||
2734 | } | ||
2735 | } | 2745 | } |
2736 | 2746 | ||
2737 | static void cpsw2_del_ucast_addr(struct cpsw2_intf *cpsw_intf, u8 *addr) | 2747 | static void cpsw2_del_ucast_addr(struct cpsw2_intf *cpsw_intf, u8 *addr) |
2738 | { | 2748 | { |
2739 | struct cpsw2_priv *cpsw_dev = cpsw_intf->cpsw_priv; | 2749 | struct cpsw2_priv *cpsw_dev = cpsw_intf->cpsw_priv; |
2740 | u16 vlan_id; | ||
2741 | 2750 | ||
2742 | cpsw_ale_del_ucast(cpsw_dev->ale, addr, cpsw_dev->host_port, 0, 0); | 2751 | cpsw_ale_del_ucast(cpsw_dev->ale, addr, cpsw_dev->host_port, 0, 0); |
2743 | |||
2744 | for_each_set_bit(vlan_id, cpsw_intf->active_vlans, VLAN_N_VID) { | ||
2745 | cpsw_ale_del_ucast(cpsw_dev->ale, addr, cpsw_dev->host_port, | ||
2746 | ALE_VLAN, vlan_id); | ||
2747 | } | ||
2748 | } | 2752 | } |
2749 | 2753 | ||
2750 | static int cpsw2_add_addr(void *intf_priv, struct netcp_addr *naddr) | 2754 | static int cpsw2_add_addr(void *intf_priv, struct netcp_addr *naddr) |
@@ -2799,34 +2803,6 @@ static int cpsw2_del_addr(void *intf_priv, struct netcp_addr *naddr) | |||
2799 | return 0; | 2803 | return 0; |
2800 | } | 2804 | } |
2801 | 2805 | ||
2802 | static int cpsw2_add_vid(void *intf_priv, int vid) | ||
2803 | { | ||
2804 | struct cpsw2_intf *cpsw_intf = intf_priv; | ||
2805 | struct cpsw2_priv *cpsw_dev = cpsw_intf->cpsw_priv; | ||
2806 | |||
2807 | set_bit(vid, cpsw_intf->active_vlans); | ||
2808 | |||
2809 | cpsw_ale_add_vlan(cpsw_dev->ale, vid, | ||
2810 | CPSW2_MASK_ALL_PORTS(cpsw_dev->num_slaves + 1), | ||
2811 | CPSW2_MASK_NO_PORTS, | ||
2812 | CPSW2_MASK_ALL_PORTS(cpsw_dev->num_slaves + 1), | ||
2813 | CPSW2_MASK_PHYS_PORTS(cpsw_dev->num_slaves + 1)); | ||
2814 | |||
2815 | return 0; | ||
2816 | } | ||
2817 | |||
2818 | static int cpsw2_del_vid(void *intf_priv, int vid) | ||
2819 | { | ||
2820 | struct cpsw2_intf *cpsw_intf = intf_priv; | ||
2821 | struct cpsw2_priv *cpsw_dev = cpsw_intf->cpsw_priv; | ||
2822 | |||
2823 | cpsw_ale_del_vlan(cpsw_dev->ale, vid, 0); | ||
2824 | |||
2825 | clear_bit(vid, cpsw_intf->active_vlans); | ||
2826 | |||
2827 | return 0; | ||
2828 | } | ||
2829 | |||
2830 | #ifdef CONFIG_TI_CPTS | 2806 | #ifdef CONFIG_TI_CPTS |
2831 | #define KEYSTONE_PTP_FILTER2 \ | 2807 | #define KEYSTONE_PTP_FILTER2 \ |
2832 | { \ | 2808 | { \ |
@@ -3377,7 +3353,6 @@ static int cpsw2_open(void *intf_priv, struct net_device *ndev) | |||
3377 | struct cpsw2_intf *cpsw_intf = intf_priv; | 3353 | struct cpsw2_intf *cpsw_intf = intf_priv; |
3378 | struct cpsw2_priv *cpsw_dev = cpsw_intf->cpsw_priv; | 3354 | struct cpsw2_priv *cpsw_dev = cpsw_intf->cpsw_priv; |
3379 | struct netcp_priv *netcp = netdev_priv(ndev); | 3355 | struct netcp_priv *netcp = netdev_priv(ndev); |
3380 | struct cpsw_ale_params ale_params; | ||
3381 | int ret = 0; | 3356 | int ret = 0; |
3382 | u32 reg; | 3357 | u32 reg; |
3383 | 3358 | ||
@@ -3413,38 +3388,23 @@ static int cpsw2_open(void *intf_priv, struct net_device *ndev) | |||
3413 | cpsw_intf->tx_pipe.dma_channel, | 3388 | cpsw_intf->tx_pipe.dma_channel, |
3414 | cpsw_intf->tx_pipe.dma_psflags); | 3389 | cpsw_intf->tx_pipe.dma_psflags); |
3415 | 3390 | ||
3416 | cpsw_dev->ale_refcnt++; | 3391 | if (atomic_inc_return(&cpsw_dev->ale_refcnt) == 1) { |
3417 | if (cpsw_dev->ale_refcnt == 1) { | 3392 | ret = cpsw2_init_ale(cpsw_dev); |
3418 | memset(&ale_params, 0, sizeof(ale_params)); | 3393 | if (ret < 0) { |
3419 | 3394 | atomic_dec(&cpsw_dev->ale_refcnt); | |
3420 | ale_params.dev = cpsw_dev->dev; | ||
3421 | ale_params.ale_regs = (void *)\ | ||
3422 | ((u32)cpsw_dev->ale_reg); | ||
3423 | ale_params.ale_ageout = cpsw_dev->ale_ageout; | ||
3424 | ale_params.ale_entries = cpsw_dev->ale_entries; | ||
3425 | ale_params.ale_ports = cpsw_dev->ale_ports; | ||
3426 | |||
3427 | cpsw_dev->ale = cpsw_ale_create(&ale_params); | ||
3428 | if (!cpsw_dev->ale) { | ||
3429 | dev_err(cpsw_dev->dev, | ||
3430 | "error initializing ale engine\n"); | ||
3431 | ret = -ENODEV; | ||
3432 | goto ale_fail; | 3395 | goto ale_fail; |
3433 | } else | 3396 | } |
3434 | dev_info(cpsw_dev->dev, "Created a cpsw ale engine\n"); | 3397 | cpsw2_init_host_port(cpsw_dev); |
3435 | } | 3398 | } |
3436 | 3399 | ||
3437 | for_each_slave(cpsw_intf, cpsw2_slave_init, cpsw_dev); | 3400 | for_each_slave(cpsw_intf, cpsw2_slave_init, cpsw_dev); |
3438 | 3401 | ||
3439 | for_each_slave(cpsw_intf, cpsw2_slave_stop, cpsw_dev); | 3402 | for_each_slave(cpsw_intf, cpsw2_slave_stop, cpsw_intf); |
3440 | 3403 | ||
3441 | /* Serdes init */ | 3404 | /* Serdes init */ |
3442 | if (cpsw_dev->init_serdes_at_probe == 0) | 3405 | if (cpsw_dev->init_serdes_at_probe == 0) |
3443 | cpsw2_serdes_init(cpsw_dev); | 3406 | cpsw2_serdes_init(cpsw_dev); |
3444 | 3407 | ||
3445 | /* initialize host and slave ports */ | ||
3446 | cpsw2_init_host_port(cpsw_dev, cpsw_intf); | ||
3447 | |||
3448 | /* disable priority elevation and enable statistics on all ports */ | 3408 | /* disable priority elevation and enable statistics on all ports */ |
3449 | writel(0, &cpsw_dev->regs->ptype); | 3409 | writel(0, &cpsw_dev->regs->ptype); |
3450 | 3410 | ||
@@ -3499,11 +3459,12 @@ static int cpsw2_close(void *intf_priv, struct net_device *ndev) | |||
3499 | 3459 | ||
3500 | del_timer_sync(&cpsw_intf->timer); | 3460 | del_timer_sync(&cpsw_intf->timer); |
3501 | 3461 | ||
3502 | cpsw_dev->ale_refcnt--; | 3462 | for_each_slave(cpsw_intf, cpsw2_slave_stop, cpsw_intf); |
3503 | if (!cpsw_dev->ale_refcnt) | ||
3504 | cpsw_ale_stop(cpsw_dev->ale); | ||
3505 | 3463 | ||
3506 | for_each_slave(cpsw_intf, cpsw2_slave_stop, cpsw_dev); | 3464 | if (atomic_dec_return(&cpsw_dev->ale_refcnt) == 0) { |
3465 | cpsw_ale_destroy(cpsw_dev->ale); | ||
3466 | cpsw_dev->ale = NULL; | ||
3467 | } | ||
3507 | 3468 | ||
3508 | if (!cpsw_dev->force_no_hwtstamp) | 3469 | if (!cpsw_dev->force_no_hwtstamp) |
3509 | netcp_unregister_rxhook(netcp, CPSW2_RXHOOK_ORDER, | 3470 | netcp_unregister_rxhook(netcp, CPSW2_RXHOOK_ORDER, |
@@ -3528,8 +3489,6 @@ static int cpsw2_remove(struct netcp_device *netcp_device, void *inst_priv) | |||
3528 | 3489 | ||
3529 | of_node_put(cpsw_dev->interfaces); | 3490 | of_node_put(cpsw_dev->interfaces); |
3530 | 3491 | ||
3531 | cpsw_ale_destroy(cpsw_dev->ale); | ||
3532 | |||
3533 | list_for_each_entry_safe(cpsw_intf, tmp, &cpsw_dev->cpsw_intf_head, | 3492 | list_for_each_entry_safe(cpsw_intf, tmp, &cpsw_dev->cpsw_intf_head, |
3534 | cpsw_intf_list) { | 3493 | cpsw_intf_list) { |
3535 | netcp_delete_interface(netcp_device, cpsw_intf->ndev); | 3494 | netcp_delete_interface(netcp_device, cpsw_intf->ndev); |
@@ -4057,8 +4016,6 @@ static int cpsw2_attach(void *inst_priv, struct net_device *ndev, | |||
4057 | netcp_txpipe_init(&cpsw_intf->tx_pipe, netdev_priv(ndev), | 4016 | netcp_txpipe_init(&cpsw_intf->tx_pipe, netdev_priv(ndev), |
4058 | cpsw_intf->tx_chan_name, cpsw_intf->tx_queue_depth); | 4017 | cpsw_intf->tx_chan_name, cpsw_intf->tx_queue_depth); |
4059 | 4018 | ||
4060 | cpsw_intf->tx_pipe.dma_psflags = netcp->cpsw_port; | ||
4061 | |||
4062 | SET_ETHTOOL_OPS(ndev, &keystone_ethtool_ops); | 4019 | SET_ETHTOOL_OPS(ndev, &keystone_ethtool_ops); |
4063 | 4020 | ||
4064 | list_add(&cpsw_intf->cpsw_intf_list, &cpsw_dev->cpsw_intf_head); | 4021 | list_add(&cpsw_intf->cpsw_intf_list, &cpsw_dev->cpsw_intf_head); |
@@ -4093,8 +4050,6 @@ static struct netcp_module cpsw_module = { | |||
4093 | .release = cpsw2_release, | 4050 | .release = cpsw2_release, |
4094 | .add_addr = cpsw2_add_addr, | 4051 | .add_addr = cpsw2_add_addr, |
4095 | .del_addr = cpsw2_del_addr, | 4052 | .del_addr = cpsw2_del_addr, |
4096 | .add_vid = cpsw2_add_vid, | ||
4097 | .del_vid = cpsw2_del_vid, | ||
4098 | .ioctl = cpsw2_ioctl, | 4053 | .ioctl = cpsw2_ioctl, |
4099 | }; | 4054 | }; |
4100 | 4055 | ||
diff --git a/drivers/net/ethernet/ti/keystone_net_core.c b/drivers/net/ethernet/ti/keystone_net_core.c index 47efc9223d1..56c3493a72a 100644 --- a/drivers/net/ethernet/ti/keystone_net_core.c +++ b/drivers/net/ethernet/ti/keystone_net_core.c | |||
@@ -1752,7 +1752,7 @@ static int netcp_rx_add_vid(struct net_device *ndev, __be16 proto, u16 vid) | |||
1752 | unsigned long flags; | 1752 | unsigned long flags; |
1753 | int err = 0; | 1753 | int err = 0; |
1754 | 1754 | ||
1755 | dev_info(netcp->dev, "adding rx vlan id: %d\n", vid); | 1755 | dev_dbg(netcp->dev, "adding rx vlan id: %d\n", vid); |
1756 | 1756 | ||
1757 | spin_lock_irqsave(&netcp->lock, flags); | 1757 | spin_lock_irqsave(&netcp->lock, flags); |
1758 | 1758 | ||
@@ -1780,7 +1780,7 @@ static int netcp_rx_kill_vid(struct net_device *ndev, __be16 proto, u16 vid) | |||
1780 | struct netcp_module *module; | 1780 | struct netcp_module *module; |
1781 | int err = 0; | 1781 | int err = 0; |
1782 | 1782 | ||
1783 | dev_info(netcp->dev, "removing rx vlan id: %d\n", vid); | 1783 | dev_dbg(netcp->dev, "removing rx vlan id: %d\n", vid); |
1784 | 1784 | ||
1785 | for_each_module(netcp, intf_modpriv) { | 1785 | for_each_module(netcp, intf_modpriv) { |
1786 | module = intf_modpriv->netcp_module; | 1786 | module = intf_modpriv->netcp_module; |
diff --git a/drivers/net/ethernet/ti/keystone_pa.c b/drivers/net/ethernet/ti/keystone_pa.c index e208250574b..5b4875f3e78 100644 --- a/drivers/net/ethernet/ti/keystone_pa.c +++ b/drivers/net/ethernet/ti/keystone_pa.c | |||
@@ -2070,12 +2070,10 @@ static int pa_close(void *intf_priv, struct net_device *ndev) | |||
2070 | } | 2070 | } |
2071 | 2071 | ||
2072 | if (pa_dev->pdsp1_tx_channel) { | 2072 | if (pa_dev->pdsp1_tx_channel) { |
2073 | dmaengine_pause(pa_dev->pdsp1_tx_channel); | ||
2074 | dma_release_channel(pa_dev->pdsp1_tx_channel); | 2073 | dma_release_channel(pa_dev->pdsp1_tx_channel); |
2075 | pa_dev->pdsp1_tx_channel = NULL; | 2074 | pa_dev->pdsp1_tx_channel = NULL; |
2076 | } | 2075 | } |
2077 | if (pa_dev->pdsp0_tx_channel) { | 2076 | if (pa_dev->pdsp0_tx_channel) { |
2078 | dmaengine_pause(pa_dev->pdsp0_tx_channel); | ||
2079 | dma_release_channel(pa_dev->pdsp0_tx_channel); | 2077 | dma_release_channel(pa_dev->pdsp0_tx_channel); |
2080 | pa_dev->pdsp0_tx_channel = NULL; | 2078 | pa_dev->pdsp0_tx_channel = NULL; |
2081 | } | 2079 | } |
diff --git a/drivers/net/ethernet/ti/keystone_pa2.c b/drivers/net/ethernet/ti/keystone_pa2.c index aa9ac5ec2c0..caca6ff3006 100644 --- a/drivers/net/ethernet/ti/keystone_pa2.c +++ b/drivers/net/ethernet/ti/keystone_pa2.c | |||
@@ -2394,7 +2394,6 @@ static int pa2_close(void *intf_priv, struct net_device *ndev) | |||
2394 | */ | 2394 | */ |
2395 | 2395 | ||
2396 | if (pa_dev->pdsp0_tx_channel) { | 2396 | if (pa_dev->pdsp0_tx_channel) { |
2397 | dmaengine_pause(pa_dev->pdsp0_tx_channel); | ||
2398 | dma_release_channel(pa_dev->pdsp0_tx_channel); | 2397 | dma_release_channel(pa_dev->pdsp0_tx_channel); |
2399 | pa_dev->pdsp0_tx_channel = NULL; | 2398 | pa_dev->pdsp0_tx_channel = NULL; |
2400 | } | 2399 | } |
diff --git a/drivers/net/ethernet/ti/keystone_xgess.c b/drivers/net/ethernet/ti/keystone_xgess.c index 7c7c231b261..a09de9044d2 100644 --- a/drivers/net/ethernet/ti/keystone_xgess.c +++ b/drivers/net/ethernet/ti/keystone_xgess.c | |||
@@ -276,11 +276,11 @@ struct cpswx_priv { | |||
276 | struct cpswx_host_regs __iomem *host_port_regs; | 276 | struct cpswx_host_regs __iomem *host_port_regs; |
277 | struct cpswx_ale_regs __iomem *ale_reg; | 277 | struct cpswx_ale_regs __iomem *ale_reg; |
278 | 278 | ||
279 | void __iomem *sgmii_port_regs; | 279 | void __iomem *sgmii_port_regs; |
280 | void __iomem *pcsr_port_regs; | 280 | void __iomem *pcsr_port_regs; |
281 | 281 | ||
282 | struct cpsw_ale *ale; | 282 | struct cpsw_ale *ale; |
283 | u32 ale_refcnt; | 283 | atomic_t ale_refcnt; |
284 | 284 | ||
285 | u32 link[5]; | 285 | u32 link[5]; |
286 | struct device_node *phy_node[4]; | 286 | struct device_node *phy_node[4]; |
@@ -319,7 +319,6 @@ struct cpswx_intf { | |||
319 | struct list_head cpsw_intf_list; | 319 | struct list_head cpsw_intf_list; |
320 | struct timer_list timer; | 320 | struct timer_list timer; |
321 | u32 sgmii_link; | 321 | u32 sgmii_link; |
322 | unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; | ||
323 | }; | 322 | }; |
324 | 323 | ||
325 | /* | 324 | /* |
@@ -1710,47 +1709,66 @@ static void cpsw_slave_open(struct cpswx_slave *slave, | |||
1710 | } | 1709 | } |
1711 | } | 1710 | } |
1712 | 1711 | ||
1713 | static void cpsw_init_host_port(struct cpswx_priv *priv, | 1712 | static int cpsw_init_ale(struct cpswx_priv *cpsw_dev, |
1714 | struct cpswx_intf *cpsw_intf) | 1713 | struct cpswx_intf *cpsw_intf) |
1715 | { | 1714 | { |
1716 | int bypass_en = 1; | 1715 | struct cpsw_ale_params ale_params; |
1717 | 1716 | ||
1718 | /* Host Tx Pri */ | 1717 | memset(&ale_params, 0, sizeof(ale_params)); |
1719 | __raw_writel(HOST_TX_PRI_MAP_DEFAULT, | ||
1720 | &priv->host_port_regs->tx_pri_map); | ||
1721 | 1718 | ||
1722 | /* Max length register */ | 1719 | ale_params.dev = cpsw_dev->dev; |
1723 | __raw_writel(MAX_SIZE_STREAM_BUFFER, | 1720 | ale_params.ale_regs = (void *)((u32)cpsw_dev->ale_reg); |
1724 | &priv->host_port_regs->rx_maxlen); | 1721 | ale_params.ale_ageout = cpsw_dev->ale_ageout; |
1722 | ale_params.ale_entries = cpsw_dev->ale_entries; | ||
1723 | ale_params.ale_ports = cpsw_dev->ale_ports; | ||
1725 | 1724 | ||
1726 | if (priv->ale_refcnt == 1) | 1725 | cpsw_dev->ale = cpsw_ale_create(&ale_params); |
1727 | cpsw_ale_start(priv->ale); | 1726 | if (!cpsw_dev->ale) { |
1727 | dev_err(cpsw_dev->dev, "error initializing ale engine\n"); | ||
1728 | return -ENODEV; | ||
1729 | } | ||
1728 | 1730 | ||
1729 | if (!priv->multi_if) | 1731 | dev_info(cpsw_dev->dev, "Created a cpsw ale engine\n"); |
1730 | bypass_en = 0; | 1732 | |
1733 | cpsw_ale_start(cpsw_dev->ale); | ||
1731 | 1734 | ||
1732 | cpsw_ale_control_set(priv->ale, 0, ALE_BYPASS, bypass_en); | 1735 | cpsw_ale_control_set(cpsw_dev->ale, 0, ALE_BYPASS, |
1736 | cpsw_dev->multi_if ? 1 : 0); | ||
1733 | 1737 | ||
1734 | cpsw_ale_control_set(priv->ale, 0, ALE_NO_PORT_VLAN, 1); | 1738 | cpsw_ale_control_set(cpsw_dev->ale, 0, ALE_NO_PORT_VLAN, 1); |
1735 | 1739 | ||
1736 | cpsw_ale_control_set(priv->ale, priv->host_port, | 1740 | cpsw_ale_control_set(cpsw_dev->ale, cpsw_dev->host_port, |
1737 | ALE_PORT_STATE, ALE_PORT_STATE_FORWARD); | 1741 | ALE_PORT_STATE, ALE_PORT_STATE_FORWARD); |
1738 | 1742 | ||
1739 | cpsw_ale_control_set(priv->ale, 0, | 1743 | cpsw_ale_control_set(cpsw_dev->ale, 0, |
1740 | ALE_PORT_UNKNOWN_VLAN_MEMBER, | 1744 | ALE_PORT_UNKNOWN_VLAN_MEMBER, |
1741 | CPSW_MASK_ALL_PORTS); | 1745 | CPSW_MASK_ALL_PORTS); |
1742 | 1746 | ||
1743 | cpsw_ale_control_set(priv->ale, 0, | 1747 | cpsw_ale_control_set(cpsw_dev->ale, 0, |
1744 | ALE_PORT_UNKNOWN_MCAST_FLOOD, | 1748 | ALE_PORT_UNKNOWN_MCAST_FLOOD, |
1745 | CPSW_MASK_PHYS_PORTS); | 1749 | CPSW_MASK_PHYS_PORTS); |
1746 | 1750 | ||
1747 | cpsw_ale_control_set(priv->ale, 0, | 1751 | cpsw_ale_control_set(cpsw_dev->ale, 0, |
1748 | ALE_PORT_UNKNOWN_REG_MCAST_FLOOD, | 1752 | ALE_PORT_UNKNOWN_REG_MCAST_FLOOD, |
1749 | CPSW_MASK_ALL_PORTS); | 1753 | CPSW_MASK_ALL_PORTS); |
1750 | 1754 | ||
1751 | cpsw_ale_control_set(priv->ale, 0, | 1755 | cpsw_ale_control_set(cpsw_dev->ale, 0, |
1752 | ALE_PORT_UNTAGGED_EGRESS, | 1756 | ALE_PORT_UNTAGGED_EGRESS, |
1753 | CPSW_MASK_ALL_PORTS); | 1757 | CPSW_MASK_ALL_PORTS); |
1758 | |||
1759 | return 0; | ||
1760 | } | ||
1761 | |||
1762 | static void cpsw_init_host_port(struct cpswx_priv *priv, | ||
1763 | struct cpswx_intf *cpsw_intf) | ||
1764 | { | ||
1765 | /* Host Tx Pri */ | ||
1766 | __raw_writel(HOST_TX_PRI_MAP_DEFAULT, | ||
1767 | &priv->host_port_regs->tx_pri_map); | ||
1768 | |||
1769 | /* Max length register */ | ||
1770 | __raw_writel(MAX_SIZE_STREAM_BUFFER, | ||
1771 | &priv->host_port_regs->rx_maxlen); | ||
1754 | } | 1772 | } |
1755 | 1773 | ||
1756 | static void cpsw_slave_init(struct cpswx_slave *slave, struct cpswx_priv *priv) | 1774 | static void cpsw_slave_init(struct cpswx_slave *slave, struct cpswx_priv *priv) |
@@ -1765,51 +1783,30 @@ static void cpsw_slave_init(struct cpswx_slave *slave, struct cpswx_priv *priv) | |||
1765 | static void cpsw_add_mcast_addr(struct cpswx_intf *cpsw_intf, u8 *addr) | 1783 | static void cpsw_add_mcast_addr(struct cpswx_intf *cpsw_intf, u8 *addr) |
1766 | { | 1784 | { |
1767 | struct cpswx_priv *cpsw_dev = cpsw_intf->cpsw_priv; | 1785 | struct cpswx_priv *cpsw_dev = cpsw_intf->cpsw_priv; |
1768 | u16 vlan_id; | ||
1769 | 1786 | ||
1770 | cpsw_ale_add_mcast(cpsw_dev->ale, addr, CPSW_MASK_ALL_PORTS, 0, 0, | 1787 | cpsw_ale_add_mcast(cpsw_dev->ale, addr, CPSW_MASK_ALL_PORTS, 0, 0, |
1771 | ALE_MCAST_FWD_2); | 1788 | ALE_MCAST_FWD_2); |
1772 | for_each_set_bit(vlan_id, cpsw_intf->active_vlans, VLAN_N_VID) { | ||
1773 | cpsw_ale_add_mcast(cpsw_dev->ale, addr, CPSW_MASK_ALL_PORTS, | ||
1774 | ALE_VLAN, vlan_id, ALE_MCAST_FWD_2); | ||
1775 | } | ||
1776 | } | 1789 | } |
1777 | 1790 | ||
1778 | static void cpsw_add_ucast_addr(struct cpswx_intf *cpsw_intf, u8 *addr) | 1791 | static void cpsw_add_ucast_addr(struct cpswx_intf *cpsw_intf, u8 *addr) |
1779 | { | 1792 | { |
1780 | struct cpswx_priv *cpsw_dev = cpsw_intf->cpsw_priv; | 1793 | struct cpswx_priv *cpsw_dev = cpsw_intf->cpsw_priv; |
1781 | u16 vlan_id; | ||
1782 | 1794 | ||
1783 | cpsw_ale_add_ucast(cpsw_dev->ale, addr, cpsw_dev->host_port, 0, 0); | 1795 | cpsw_ale_add_ucast(cpsw_dev->ale, addr, cpsw_dev->host_port, 0, 0); |
1784 | |||
1785 | for_each_set_bit(vlan_id, cpsw_intf->active_vlans, VLAN_N_VID) | ||
1786 | cpsw_ale_add_ucast(cpsw_dev->ale, addr, cpsw_dev->host_port, | ||
1787 | ALE_VLAN, vlan_id); | ||
1788 | } | 1796 | } |
1789 | 1797 | ||
1790 | static void cpsw_del_mcast_addr(struct cpswx_intf *cpsw_intf, u8 *addr) | 1798 | static void cpsw_del_mcast_addr(struct cpswx_intf *cpsw_intf, u8 *addr) |
1791 | { | 1799 | { |
1792 | struct cpswx_priv *cpsw_dev = cpsw_intf->cpsw_priv; | 1800 | struct cpswx_priv *cpsw_dev = cpsw_intf->cpsw_priv; |
1793 | u16 vlan_id; | ||
1794 | 1801 | ||
1795 | cpsw_ale_del_mcast(cpsw_dev->ale, addr, 0, 0, 0); | 1802 | cpsw_ale_del_mcast(cpsw_dev->ale, addr, 0, 0, 0); |
1796 | |||
1797 | for_each_set_bit(vlan_id, cpsw_intf->active_vlans, VLAN_N_VID) { | ||
1798 | cpsw_ale_del_mcast(cpsw_dev->ale, addr, 0, ALE_VLAN, vlan_id); | ||
1799 | } | ||
1800 | } | 1803 | } |
1801 | 1804 | ||
1802 | static void cpsw_del_ucast_addr(struct cpswx_intf *cpsw_intf, u8 *addr) | 1805 | static void cpsw_del_ucast_addr(struct cpswx_intf *cpsw_intf, u8 *addr) |
1803 | { | 1806 | { |
1804 | struct cpswx_priv *cpsw_dev = cpsw_intf->cpsw_priv; | 1807 | struct cpswx_priv *cpsw_dev = cpsw_intf->cpsw_priv; |
1805 | u16 vlan_id; | ||
1806 | 1808 | ||
1807 | cpsw_ale_del_ucast(cpsw_dev->ale, addr, cpsw_dev->host_port, 0, 0); | 1809 | cpsw_ale_del_ucast(cpsw_dev->ale, addr, cpsw_dev->host_port, 0, 0); |
1808 | |||
1809 | for_each_set_bit(vlan_id, cpsw_intf->active_vlans, VLAN_N_VID) { | ||
1810 | cpsw_ale_del_ucast(cpsw_dev->ale, addr, cpsw_dev->host_port, | ||
1811 | ALE_VLAN, vlan_id); | ||
1812 | } | ||
1813 | } | 1810 | } |
1814 | 1811 | ||
1815 | static int cpswx_add_addr(void *intf_priv, struct netcp_addr *naddr) | 1812 | static int cpswx_add_addr(void *intf_priv, struct netcp_addr *naddr) |
@@ -1864,32 +1861,6 @@ static int cpswx_del_addr(void *intf_priv, struct netcp_addr *naddr) | |||
1864 | return 0; | 1861 | return 0; |
1865 | } | 1862 | } |
1866 | 1863 | ||
1867 | static int cpswx_add_vid(void *intf_priv, int vid) | ||
1868 | { | ||
1869 | struct cpswx_intf *cpsw_intf = intf_priv; | ||
1870 | struct cpswx_priv *cpsw_dev = cpsw_intf->cpsw_priv; | ||
1871 | |||
1872 | set_bit(vid, cpsw_intf->active_vlans); | ||
1873 | |||
1874 | cpsw_ale_add_vlan(cpsw_dev->ale, vid, CPSW_MASK_ALL_PORTS, | ||
1875 | CPSW_MASK_NO_PORTS, | ||
1876 | CPSW_MASK_ALL_PORTS, CPSW_MASK_PHYS_PORTS); | ||
1877 | |||
1878 | return 0; | ||
1879 | } | ||
1880 | |||
1881 | static int cpswx_del_vid(void *intf_priv, int vid) | ||
1882 | { | ||
1883 | struct cpswx_intf *cpsw_intf = intf_priv; | ||
1884 | struct cpswx_priv *cpsw_dev = cpsw_intf->cpsw_priv; | ||
1885 | |||
1886 | cpsw_ale_del_vlan(cpsw_dev->ale, vid, 0); | ||
1887 | |||
1888 | clear_bit(vid, cpsw_intf->active_vlans); | ||
1889 | |||
1890 | return 0; | ||
1891 | } | ||
1892 | |||
1893 | static int cpswx_ioctl(void *intf_priv, struct ifreq *req, int cmd) | 1864 | static int cpswx_ioctl(void *intf_priv, struct ifreq *req, int cmd) |
1894 | { | 1865 | { |
1895 | struct cpswx_intf *cpsw_intf = intf_priv; | 1866 | struct cpswx_intf *cpsw_intf = intf_priv; |
@@ -1963,7 +1934,6 @@ static int cpswx_open(void *intf_mod_priv, struct net_device *ndev) | |||
1963 | struct cpswx_intf *cpsw_intf = intf_mod_priv; | 1934 | struct cpswx_intf *cpsw_intf = intf_mod_priv; |
1964 | struct cpswx_priv *cpsw_dev = cpsw_intf->cpsw_priv; | 1935 | struct cpswx_priv *cpsw_dev = cpsw_intf->cpsw_priv; |
1965 | struct netcp_priv *netcp = netdev_priv(ndev); | 1936 | struct netcp_priv *netcp = netdev_priv(ndev); |
1966 | struct cpsw_ale_params ale_params; | ||
1967 | u32 xgmii_mode = 0; | 1937 | u32 xgmii_mode = 0; |
1968 | int ret = 0; | 1938 | int ret = 0; |
1969 | u32 reg, i; | 1939 | u32 reg, i; |
@@ -1997,23 +1967,14 @@ static int cpswx_open(void *intf_mod_priv, struct net_device *ndev) | |||
1997 | cpsw_intf->tx_pipe.dma_channel, | 1967 | cpsw_intf->tx_pipe.dma_channel, |
1998 | cpsw_intf->tx_pipe.dma_psflags); | 1968 | cpsw_intf->tx_pipe.dma_psflags); |
1999 | 1969 | ||
2000 | cpsw_dev->ale_refcnt++; | 1970 | /* initialize host and slave ports */ |
2001 | if (cpsw_dev->ale_refcnt == 1) { | 1971 | if (atomic_inc_return(&cpsw_dev->ale_refcnt) == 1) { |
2002 | memset(&ale_params, 0, sizeof(ale_params)); | 1972 | ret = cpsw_init_ale(cpsw_dev, cpsw_intf); |
2003 | 1973 | if (ret < 0) { | |
2004 | ale_params.dev = cpsw_dev->dev; | 1974 | atomic_dec(&cpsw_dev->ale_refcnt); |
2005 | ale_params.ale_regs = (void *)((u32)cpsw_dev->ale_reg); | ||
2006 | ale_params.ale_ageout = cpsw_dev->ale_ageout; | ||
2007 | ale_params.ale_entries = cpsw_dev->ale_entries; | ||
2008 | ale_params.ale_ports = cpsw_dev->ale_ports; | ||
2009 | |||
2010 | cpsw_dev->ale = cpsw_ale_create(&ale_params); | ||
2011 | if (!cpsw_dev->ale) { | ||
2012 | dev_err(cpsw_dev->dev, "error initializing ale engine\n"); | ||
2013 | ret = -ENODEV; | ||
2014 | goto ale_fail; | 1975 | goto ale_fail; |
2015 | } else | 1976 | } |
2016 | dev_info(cpsw_dev->dev, "Created a cpsw ale engine\n"); | 1977 | cpsw_init_host_port(cpsw_dev, cpsw_intf); |
2017 | } | 1978 | } |
2018 | 1979 | ||
2019 | for_each_slave(cpsw_intf, cpsw_slave_init, cpsw_dev); | 1980 | for_each_slave(cpsw_intf, cpsw_slave_init, cpsw_dev); |
@@ -2026,9 +1987,6 @@ static int cpswx_open(void *intf_mod_priv, struct net_device *ndev) | |||
2026 | xgmii_mode |= (1 << i); | 1987 | xgmii_mode |= (1 << i); |
2027 | __raw_writel(xgmii_mode, &cpsw_dev->ss_regs->control); | 1988 | __raw_writel(xgmii_mode, &cpsw_dev->ss_regs->control); |
2028 | 1989 | ||
2029 | /* initialize host and slave ports */ | ||
2030 | cpsw_init_host_port(cpsw_dev, cpsw_intf); | ||
2031 | |||
2032 | /* disable priority elevation and enable statistics on all ports */ | 1990 | /* disable priority elevation and enable statistics on all ports */ |
2033 | __raw_writel(0, &cpsw_dev->regs->ptype); | 1991 | __raw_writel(0, &cpsw_dev->regs->ptype); |
2034 | 1992 | ||
@@ -2079,12 +2037,13 @@ static int cpswx_close(void *intf_modpriv, struct net_device *ndev) | |||
2079 | 2037 | ||
2080 | del_timer_sync(&cpsw_intf->timer); | 2038 | del_timer_sync(&cpsw_intf->timer); |
2081 | 2039 | ||
2082 | cpsw_dev->ale_refcnt--; | ||
2083 | if (!cpsw_dev->ale_refcnt) | ||
2084 | cpsw_ale_stop(cpsw_dev->ale); | ||
2085 | |||
2086 | for_each_slave(cpsw_intf, cpsw_slave_stop, cpsw_dev); | 2040 | for_each_slave(cpsw_intf, cpsw_slave_stop, cpsw_dev); |
2087 | 2041 | ||
2042 | if (atomic_dec_return(&cpsw_dev->ale_refcnt) == 0) { | ||
2043 | cpsw_ale_destroy(cpsw_dev->ale); | ||
2044 | cpsw_dev->ale = NULL; | ||
2045 | } | ||
2046 | |||
2088 | netcp_unregister_txhook(netcp, CPSW_TXHOOK_ORDER, cpsw_tx_hook, | 2047 | netcp_unregister_txhook(netcp, CPSW_TXHOOK_ORDER, cpsw_tx_hook, |
2089 | cpsw_intf); | 2048 | cpsw_intf); |
2090 | netcp_txpipe_close(&cpsw_intf->tx_pipe); | 2049 | netcp_txpipe_close(&cpsw_intf->tx_pipe); |
@@ -2102,8 +2061,6 @@ static int cpswx_remove(struct netcp_device *netcp_device, void *inst_priv) | |||
2102 | 2061 | ||
2103 | of_node_put(cpsw_dev->interfaces); | 2062 | of_node_put(cpsw_dev->interfaces); |
2104 | 2063 | ||
2105 | cpsw_ale_destroy(cpsw_dev->ale); | ||
2106 | |||
2107 | list_for_each_entry_safe(cpsw_intf, tmp, &cpsw_dev->cpsw_intf_head, | 2064 | list_for_each_entry_safe(cpsw_intf, tmp, &cpsw_dev->cpsw_intf_head, |
2108 | cpsw_intf_list) { | 2065 | cpsw_intf_list) { |
2109 | netcp_delete_interface(netcp_device, cpsw_intf->ndev); | 2066 | netcp_delete_interface(netcp_device, cpsw_intf->ndev); |
@@ -2578,8 +2535,6 @@ static struct netcp_module cpsw_module = { | |||
2578 | .release = cpswx_release, | 2535 | .release = cpswx_release, |
2579 | .add_addr = cpswx_add_addr, | 2536 | .add_addr = cpswx_add_addr, |
2580 | .del_addr = cpswx_del_addr, | 2537 | .del_addr = cpswx_del_addr, |
2581 | .add_vid = cpswx_add_vid, | ||
2582 | .del_vid = cpswx_del_vid, | ||
2583 | .ioctl = cpswx_ioctl, | 2538 | .ioctl = cpswx_ioctl, |
2584 | }; | 2539 | }; |
2585 | 2540 | ||