aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWingMan Kwok2015-02-05 15:37:56 -0600
committerReece R. Pollack2015-02-16 16:30:33 -0600
commitef81aae96229138c4babefd7b0a0743d25b83ab5 (patch)
tree8e1d392e62c994bb70a3f9a47661c916cad9e349 /drivers/net/ethernet/ti/keystone_ethss2.c
parentf5782c377771aec1cf4ee5c045fcf1a06161425a (diff)
downloadlinux-ef81aae96229138c4babefd7b0a0743d25b83ab5.tar.gz
linux-ef81aae96229138c4babefd7b0a0743d25b83ab5.tar.xz
linux-ef81aae96229138c4babefd7b0a0743d25b83ab5.zip
net: keystone: k2e k2l changes paired with k2hk
This patch pairs some changes made for k2hk in two commits before but not on k2e and k2l. Original k2hk commit logs: net: keystone: Don't re-initialize CPSW host port and ALE Prior to this patch, every time an interface was brought up the CPSW host port and a number of ALE configurations were re- initialized. This is unnecessary and interferes with some uses of the CPSW by DSPs. This patch causes the CPSW host port and ALE to be configured only when the first interface on the CPSW is brought up. Note that if all of the interfaces on the CPSW are brought down, the clocks driving the CPSW (and other parts of the NetCP) are shut off for power consumption, which is assumed to cause a loss of configuration. Thus the CPSW must be re-initialized when the first interface is brought back up. net: keystone: Clean up network interface shutdown This patch also asserts SGMII RTRESET during shutdown to avoid having the hardware wedge when shutting down with high incoming traffic rates. This is cleared when the interface is brought back up. Signed-off-by: WingMan Kwok <w-kwok2@ti.com>
Diffstat (limited to 'drivers/net/ethernet/ti/keystone_ethss2.c')
-rw-r--r--drivers/net/ethernet/ti/keystone_ethss2.c114
1 files changed, 61 insertions, 53 deletions
diff --git a/drivers/net/ethernet/ti/keystone_ethss2.c b/drivers/net/ethernet/ti/keystone_ethss2.c
index 7ff7363575f..f334bdb3ab5 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];
@@ -2540,8 +2540,7 @@ static int cpsw2_port_reset(struct cpsw2_slave *slave)
2540 /* Wait for the bit to clear */ 2540 /* Wait for the bit to clear */
2541 for (i = 0; i < DEVICE_EMACSL_RESET_POLL_COUNT; i++) { 2541 for (i = 0; i < DEVICE_EMACSL_RESET_POLL_COUNT; i++) {
2542 v = readl(&slave->regs->soft_reset); 2542 v = readl(&slave->regs->soft_reset);
2543 if ((v & SOFT_RESET_MASK) != 2543 if ((v & SOFT_RESET_MASK) != SOFT_RESET)
2544 SOFT_RESET)
2545 return 0; 2544 return 0;
2546 } 2545 }
2547 2546
@@ -2563,13 +2562,19 @@ static void cpsw2_port_config(struct cpsw2_slave *slave, int max_rx_len)
2563 &slave->regs->mac_control); 2562 &slave->regs->mac_control);
2564} 2563}
2565 2564
2566static void cpsw2_slave_stop(struct cpsw2_slave *slave, struct cpsw2_priv *priv) 2565static void cpsw2_slave_stop(struct cpsw2_slave *slave,
2566 struct cpsw2_intf *cpsw_intf)
2567{ 2567{
2568 struct cpsw2_priv *cpsw_dev = cpsw_intf->cpsw_priv;
2569
2568 /* disable forwarding */ 2570 /* disable forwarding */
2569 if (slave->ale) 2571 if (slave->ale)
2570 cpsw_ale_control_set(slave->ale, slave->port_num, 2572 cpsw_ale_control_set(slave->ale, slave->port_num,
2571 ALE_PORT_STATE, ALE_PORT_STATE_DISABLE); 2573 ALE_PORT_STATE, ALE_PORT_STATE_DISABLE);
2572 2574
2575 keystone_sgmii_rtreset(SGMII2_BASE(slave->slave_num),
2576 slave->slave_num, true);
2577
2573 cpsw2_port_reset(slave); 2578 cpsw2_port_reset(slave);
2574 2579
2575 if (!slave->phy) 2580 if (!slave->phy)
@@ -2606,6 +2611,9 @@ static void cpsw2_slave_open(struct cpsw2_slave *slave,
2606 2611
2607 cpsw2_port_reset(slave); 2612 cpsw2_port_reset(slave);
2608 2613
2614 keystone_sgmii_rtreset(SGMII2_BASE(slave->slave_num),
2615 slave->slave_num, false);
2616
2609 cpsw2_port_config(slave, cpsw_dev->rx_packet_max); 2617 cpsw2_port_config(slave, cpsw_dev->rx_packet_max);
2610 2618
2611 cpsw2_set_slave_mac(slave, cpsw_intf); 2619 cpsw2_set_slave_mac(slave, cpsw_intf);
@@ -2647,43 +2655,62 @@ static void cpsw2_slave_open(struct cpsw2_slave *slave,
2647 } 2655 }
2648} 2656}
2649 2657
2650static void cpsw2_init_host_port(struct cpsw2_priv *priv, 2658static int cpsw2_init_ale(struct cpsw2_priv *cpsw_dev)
2651 struct cpsw2_intf *cpsw_intf)
2652{ 2659{
2653 int bypass_en = 1; 2660 struct cpsw_ale_params ale_params;
2654 2661
2655 /* Max length register */ 2662 memset(&ale_params, 0, sizeof(ale_params));
2656 writel(MAX_SIZE_STREAM_BUFFER, 2663
2657 &priv->host_port_regs->rx_maxlen); 2664 ale_params.dev = cpsw_dev->dev;
2665 ale_params.ale_regs = (void *)((u32)cpsw_dev->ale_reg);
2666 ale_params.ale_ageout = cpsw_dev->ale_ageout;
2667 ale_params.ale_entries = cpsw_dev->ale_entries;
2668 ale_params.ale_ports = cpsw_dev->ale_ports;
2669
2670 cpsw_dev->ale = cpsw_ale_create(&ale_params);
2671 if (!cpsw_dev->ale) {
2672 dev_err(cpsw_dev->dev,
2673 "error initializing ale engine\n");
2674 return -ENODEV;
2675 }
2658 2676
2659 if (priv->ale_refcnt == 1) 2677 dev_info(cpsw_dev->dev, "Created a cpsw ale engine\n");
2660 cpsw_ale_start(priv->ale);
2661 2678
2662 if (!priv->multi_if) 2679 cpsw_ale_start(cpsw_dev->ale);
2663 bypass_en = 0;
2664 2680
2665 cpsw_ale_control_set(priv->ale, 0, ALE_BYPASS, bypass_en); 2681 cpsw_ale_control_set(cpsw_dev->ale, 0,
2682 ALE_BYPASS, cpsw_dev->multi_if ? 1 : 0);
2666 2683
2667 cpsw_ale_control_set(priv->ale, 0, ALE_NO_PORT_VLAN, 1); 2684 cpsw_ale_control_set(cpsw_dev->ale, 0, ALE_NO_PORT_VLAN, 1);
2668 2685
2669 cpsw_ale_control_set(priv->ale, priv->host_port, 2686 cpsw_ale_control_set(cpsw_dev->ale, cpsw_dev->host_port,
2670 ALE_PORT_STATE, ALE_PORT_STATE_FORWARD); 2687 ALE_PORT_STATE, ALE_PORT_STATE_FORWARD);
2671 2688
2672 cpsw_ale_control_set(priv->ale, 0, 2689 cpsw_ale_control_set(cpsw_dev->ale, 0,
2673 ALE_PORT_UNKNOWN_VLAN_MEMBER_1R4, 2690 ALE_PORT_UNKNOWN_VLAN_MEMBER_1R4,
2674 CPSW2_MASK_ALL_PORTS(priv->num_slaves + 1)); 2691 CPSW2_MASK_ALL_PORTS(cpsw_dev->num_slaves + 1));
2675 2692
2676 cpsw_ale_control_set(priv->ale, 0, 2693 cpsw_ale_control_set(cpsw_dev->ale, 0,
2677 ALE_PORT_UNKNOWN_MCAST_FLOOD_1R4, 2694 ALE_PORT_UNKNOWN_MCAST_FLOOD_1R4,
2678 CPSW2_MASK_PHYS_PORTS(priv->num_slaves + 1)); 2695 CPSW2_MASK_PHYS_PORTS(cpsw_dev->num_slaves + 1));
2679 2696
2680 cpsw_ale_control_set(priv->ale, 0, 2697 cpsw_ale_control_set(cpsw_dev->ale, 0,
2681 ALE_PORT_UNKNOWN_REG_MCAST_FLOOD_1R4, 2698 ALE_PORT_UNKNOWN_REG_MCAST_FLOOD_1R4,
2682 CPSW2_MASK_ALL_PORTS(priv->num_slaves + 1)); 2699 CPSW2_MASK_ALL_PORTS(cpsw_dev->num_slaves + 1));
2683 2700
2684 cpsw_ale_control_set(priv->ale, 0, 2701 cpsw_ale_control_set(cpsw_dev->ale, 0,
2685 ALE_PORT_UNTAGGED_EGRESS_1R4, 2702 ALE_PORT_UNTAGGED_EGRESS_1R4,
2686 CPSW2_MASK_ALL_PORTS(priv->num_slaves + 1)); 2703 CPSW2_MASK_ALL_PORTS(cpsw_dev->num_slaves + 1));
2704
2705 return 0;
2706}
2707
2708static void cpsw2_init_host_port(struct cpsw2_priv *priv)
2709{
2710 /* Max length register */
2711 writel(MAX_SIZE_STREAM_BUFFER,
2712 &priv->host_port_regs->rx_maxlen);
2713
2687} 2714}
2688 2715
2689static void cpsw2_slave_init(struct cpsw2_slave *slave, struct cpsw2_priv *priv) 2716static void cpsw2_slave_init(struct cpsw2_slave *slave, struct cpsw2_priv *priv)
@@ -3377,7 +3404,6 @@ static int cpsw2_open(void *intf_priv, struct net_device *ndev)
3377 struct cpsw2_intf *cpsw_intf = intf_priv; 3404 struct cpsw2_intf *cpsw_intf = intf_priv;
3378 struct cpsw2_priv *cpsw_dev = cpsw_intf->cpsw_priv; 3405 struct cpsw2_priv *cpsw_dev = cpsw_intf->cpsw_priv;
3379 struct netcp_priv *netcp = netdev_priv(ndev); 3406 struct netcp_priv *netcp = netdev_priv(ndev);
3380 struct cpsw_ale_params ale_params;
3381 int ret = 0; 3407 int ret = 0;
3382 u32 reg; 3408 u32 reg;
3383 3409
@@ -3413,38 +3439,23 @@ static int cpsw2_open(void *intf_priv, struct net_device *ndev)
3413 cpsw_intf->tx_pipe.dma_channel, 3439 cpsw_intf->tx_pipe.dma_channel,
3414 cpsw_intf->tx_pipe.dma_psflags); 3440 cpsw_intf->tx_pipe.dma_psflags);
3415 3441
3416 cpsw_dev->ale_refcnt++; 3442 if (atomic_inc_return(&cpsw_dev->ale_refcnt) == 1) {
3417 if (cpsw_dev->ale_refcnt == 1) { 3443 ret = cpsw2_init_ale(cpsw_dev);
3418 memset(&ale_params, 0, sizeof(ale_params)); 3444 if (ret < 0) {
3419 3445 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; 3446 goto ale_fail;
3433 } else 3447 }
3434 dev_info(cpsw_dev->dev, "Created a cpsw ale engine\n"); 3448 cpsw2_init_host_port(cpsw_dev);
3435 } 3449 }
3436 3450
3437 for_each_slave(cpsw_intf, cpsw2_slave_init, cpsw_dev); 3451 for_each_slave(cpsw_intf, cpsw2_slave_init, cpsw_dev);
3438 3452
3439 for_each_slave(cpsw_intf, cpsw2_slave_stop, cpsw_dev); 3453 for_each_slave(cpsw_intf, cpsw2_slave_stop, cpsw_intf);
3440 3454
3441 /* Serdes init */ 3455 /* Serdes init */
3442 if (cpsw_dev->init_serdes_at_probe == 0) 3456 if (cpsw_dev->init_serdes_at_probe == 0)
3443 cpsw2_serdes_init(cpsw_dev); 3457 cpsw2_serdes_init(cpsw_dev);
3444 3458
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 */ 3459 /* disable priority elevation and enable statistics on all ports */
3449 writel(0, &cpsw_dev->regs->ptype); 3460 writel(0, &cpsw_dev->regs->ptype);
3450 3461
@@ -3499,11 +3510,10 @@ static int cpsw2_close(void *intf_priv, struct net_device *ndev)
3499 3510
3500 del_timer_sync(&cpsw_intf->timer); 3511 del_timer_sync(&cpsw_intf->timer);
3501 3512
3502 cpsw_dev->ale_refcnt--; 3513 if (atomic_dec_return(&cpsw_dev->ale_refcnt) == 0)
3503 if (!cpsw_dev->ale_refcnt)
3504 cpsw_ale_stop(cpsw_dev->ale); 3514 cpsw_ale_stop(cpsw_dev->ale);
3505 3515
3506 for_each_slave(cpsw_intf, cpsw2_slave_stop, cpsw_dev); 3516 for_each_slave(cpsw_intf, cpsw2_slave_stop, cpsw_intf);
3507 3517
3508 if (!cpsw_dev->force_no_hwtstamp) 3518 if (!cpsw_dev->force_no_hwtstamp)
3509 netcp_unregister_rxhook(netcp, CPSW2_RXHOOK_ORDER, 3519 netcp_unregister_rxhook(netcp, CPSW2_RXHOOK_ORDER,
@@ -4057,8 +4067,6 @@ static int cpsw2_attach(void *inst_priv, struct net_device *ndev,
4057 netcp_txpipe_init(&cpsw_intf->tx_pipe, netdev_priv(ndev), 4067 netcp_txpipe_init(&cpsw_intf->tx_pipe, netdev_priv(ndev),
4058 cpsw_intf->tx_chan_name, cpsw_intf->tx_queue_depth); 4068 cpsw_intf->tx_chan_name, cpsw_intf->tx_queue_depth);
4059 4069
4060 cpsw_intf->tx_pipe.dma_psflags = netcp->cpsw_port;
4061
4062 SET_ETHTOOL_OPS(ndev, &keystone_ethtool_ops); 4070 SET_ETHTOOL_OPS(ndev, &keystone_ethtool_ops);
4063 4071
4064 list_add(&cpsw_intf->cpsw_intf_list, &cpsw_dev->cpsw_intf_head); 4072 list_add(&cpsw_intf->cpsw_intf_list, &cpsw_dev->cpsw_intf_head);