aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWingMan Kwok2015-03-09 12:12:20 -0500
committerWingMan Kwok2015-03-10 09:20:04 -0500
commite55b702ba52b4e43073cb33a7a4a95c1d55ddb53 (patch)
tree5b2dc6fc4320f86cdd85ffad794a5f2043653237 /drivers/net/ethernet/ti/keystone_ethss2.c
parent428364b2077d7738c0b8a7897fe519a54b42d692 (diff)
downloadlinux-e55b702ba52b4e43073cb33a7a4a95c1d55ddb53.tar.gz
linux-e55b702ba52b4e43073cb33a7a4a95c1d55ddb53.tar.xz
linux-e55b702ba52b4e43073cb33a7a4a95c1d55ddb53.zip
net: keystone: clean up slave port configurations
In multi-if mode: When MDIO/PHY is enabled, carrier on/off is reported to upper layer by the phy state machine, hence cpsw driver needs to report carrier on/off when the link interface type is other than MAC-to-PHY. Also, in the MAC-to-PHY case, in addition to checking the sgmii link status register, cpsw driver needs to check the bit that corresponds to the phy connected to the slave port in the phy link state variable in netcp in order to conclude the sgmii link status. Only when both of these two statuses show an up state can the cpsw driver conclude the link is up. Before this patch, it checks the aggregated value of the phy link state variable. In the case of MAC-to-MAC, the cpsw driver is responsible to report the carrier on/off status to upper layers. 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.c72
1 files changed, 43 insertions, 29 deletions
diff --git a/drivers/net/ethernet/ti/keystone_ethss2.c b/drivers/net/ethernet/ti/keystone_ethss2.c
index 5f2c64f56c4..b0f701f5289 100644
--- a/drivers/net/ethernet/ti/keystone_ethss2.c
+++ b/drivers/net/ethernet/ti/keystone_ethss2.c
@@ -60,6 +60,9 @@
60#define MACSL_RX_ENABLE_CSF BIT(23) 60#define MACSL_RX_ENABLE_CSF BIT(23)
61#define MACSL_RX_ENABLE_EXT_CTL BIT(18) 61#define MACSL_RX_ENABLE_EXT_CTL BIT(18)
62#define MACSL_ENABLE BIT(5) 62#define MACSL_ENABLE BIT(5)
63#define MACSL_DEFAULT_CONFIG (MACSL_ENABLE |\
64 MACSL_RX_ENABLE_EXT_CTL |\
65 MACSL_RX_ENABLE_CSF)
63#define GMACSL_RET_WARN_RESET_INCOMPLETE -2 66#define GMACSL_RET_WARN_RESET_INCOMPLETE -2
64 67
65#define CPSW2_NUM_PORTS 9 68#define CPSW2_NUM_PORTS 9
@@ -157,7 +160,7 @@
157 160
158#define MAX_SLAVES (CPSW2_NUM_PORTS - 1) 161#define MAX_SLAVES (CPSW2_NUM_PORTS - 1)
159 162
160/* s: 0-based slave_port */ 163/* s: 0-based slave_num */
161#define SGMII2_BASE(s) (((s) < 2) ? cpsw_dev->sgmii_port_regs : \ 164#define SGMII2_BASE(s) (((s) < 2) ? cpsw_dev->sgmii_port_regs : \
162 cpsw_dev->sgmii_port_regs + SGMII_REGS_SIZE * 2) 165 cpsw_dev->sgmii_port_regs + SGMII_REGS_SIZE * 2)
163 166
@@ -179,6 +182,9 @@ struct cpts2_port_ts_ctl {
179 u8 ts_mcast_type; 182 u8 ts_mcast_type;
180}; 183};
181 184
185/* slave_num: 0-based
186 * port_num: 1-based
187 */
182struct cpsw2_slave { 188struct cpsw2_slave {
183 struct cpsw2_slave_regs __iomem *regs; 189 struct cpsw2_slave_regs __iomem *regs;
184 int slave_num; 190 int slave_num;
@@ -897,6 +903,8 @@ struct cpsw2_priv {
897 struct serdes serdes; 903 struct serdes serdes;
898}; 904};
899 905
906/* slave_port: 0-based (currently relevant only in multi_if mode)
907 */
900struct cpsw2_intf { 908struct cpsw2_intf {
901 struct net_device *ndev; 909 struct net_device *ndev;
902 struct device *dev; 910 struct device *dev;
@@ -912,7 +920,7 @@ struct cpsw2_intf {
912 u32 multi_if; 920 u32 multi_if;
913 struct list_head cpsw_intf_list; 921 struct list_head cpsw_intf_list;
914 struct timer_list timer; 922 struct timer_list timer;
915 u32 sgmii_link; 923 u32 link_state;
916}; 924};
917 925
918struct cpsw2_attribute { 926struct cpsw2_attribute {
@@ -2484,8 +2492,7 @@ static void _cpsw2_adjust_link(struct cpsw2_slave *slave, bool *link)
2484 2492
2485 if (phy->link) { 2493 if (phy->link) {
2486 mac_control = slave->mac_control; 2494 mac_control = slave->mac_control;
2487 mac_control |= MACSL_ENABLE | MACSL_RX_ENABLE_EXT_CTL | 2495 mac_control |= MACSL_DEFAULT_CONFIG;
2488 MACSL_RX_ENABLE_CSF;
2489 /* enable forwarding */ 2496 /* enable forwarding */
2490 cpsw_ale_control_set(slave->ale, slave_port, 2497 cpsw_ale_control_set(slave->ale, slave_port,
2491 ALE_PORT_STATE, ALE_PORT_STATE_FORWARD); 2498 ALE_PORT_STATE, ALE_PORT_STATE_FORWARD);
@@ -2520,9 +2527,9 @@ static void cpsw2_adjust_link(struct net_device *n_dev, void *context)
2520 _cpsw2_adjust_link(slave, &link); 2527 _cpsw2_adjust_link(slave, &link);
2521 2528
2522 if (link) 2529 if (link)
2523 netcp->link_state |= BIT(slave->slave_num); 2530 netcp->phy_link_state_mask |= BIT(slave->slave_num);
2524 else 2531 else
2525 netcp->link_state &= ~BIT(slave->slave_num); 2532 netcp->phy_link_state_mask &= ~BIT(slave->slave_num);
2526} 2533}
2527 2534
2528/* 2535/*
@@ -2555,10 +2562,10 @@ static void cpsw2_port_config(struct cpsw2_slave *slave, int max_rx_len)
2555 if (max_rx_len > MAX_SIZE_STREAM_BUFFER) 2562 if (max_rx_len > MAX_SIZE_STREAM_BUFFER)
2556 max_rx_len = MAX_SIZE_STREAM_BUFFER; 2563 max_rx_len = MAX_SIZE_STREAM_BUFFER;
2557 2564
2558 writel(max_rx_len, &slave->regs->rx_maxlen); 2565 slave->mac_control = MACSL_DEFAULT_CONFIG;
2559 2566
2560 writel(MACSL_ENABLE | MACSL_RX_ENABLE_EXT_CTL | MACSL_RX_ENABLE_CSF, 2567 writel(max_rx_len, &slave->regs->rx_maxlen);
2561 &slave->regs->mac_control); 2568 writel(slave->mac_control, &slave->regs->mac_control);
2562} 2569}
2563 2570
2564static void cpsw2_slave_stop(struct cpsw2_slave *slave, 2571static void cpsw2_slave_stop(struct cpsw2_slave *slave,
@@ -2588,12 +2595,14 @@ static void cpsw2_slave_link(struct cpsw2_slave *slave,
2588 struct cpsw2_intf *cpsw_intf) 2595 struct cpsw2_intf *cpsw_intf)
2589{ 2596{
2590 struct netcp_priv *netcp = netdev_priv(cpsw_intf->ndev); 2597 struct netcp_priv *netcp = netdev_priv(cpsw_intf->ndev);
2598 int sn = slave->slave_num;
2591 2599
2592 if (slave->link_interface == SGMII_LINK_MAC_PHY) { 2600 if (slave->link_interface == SGMII_LINK_MAC_PHY) {
2593 if (netcp->link_state) 2601 /* check only the bit in phy_link_state_mask
2594 cpsw_intf->sgmii_link |= BIT(slave->slave_num); 2602 * that corresponds to the slave
2595 else 2603 */
2596 cpsw_intf->sgmii_link &= ~BIT(slave->slave_num); 2604 if (!(netcp->phy_link_state_mask & BIT(sn)))
2605 cpsw_intf->link_state &= ~BIT(sn);
2597 } 2606 }
2598} 2607}
2599 2608
@@ -2617,9 +2626,6 @@ static void cpsw2_slave_open(struct cpsw2_slave *slave,
2617 2626
2618 cpsw2_set_slave_mac(slave, cpsw_intf); 2627 cpsw2_set_slave_mac(slave, cpsw_intf);
2619 2628
2620 slave->mac_control = MACSL_ENABLE | MACSL_RX_ENABLE_EXT_CTL |
2621 MACSL_RX_ENABLE_CSF;
2622
2623 /* this slave port here is 1 based */ 2629 /* this slave port here is 1 based */
2624 slave_port = cpsw2_get_slave_port(cpsw_dev, slave->slave_num); 2630 slave_port = cpsw2_get_slave_port(cpsw_dev, slave->slave_num);
2625 2631
@@ -3002,10 +3008,10 @@ static void cpsw2_timer(unsigned long arg)
3002 struct cpsw2_priv *cpsw_dev = cpsw_intf->cpsw_priv; 3008 struct cpsw2_priv *cpsw_dev = cpsw_intf->cpsw_priv;
3003 u32 sp = cpsw_intf->slave_port; 3009 u32 sp = cpsw_intf->slave_port;
3004 u32 ns = cpsw_intf->num_slaves; 3010 u32 ns = cpsw_intf->num_slaves;
3005 u32 sgmii_link; 3011 u32 link_state;
3006 3012
3007 if (cpsw_dev->multi_if) 3013 if (cpsw_dev->multi_if)
3008 sgmii_link = keystone_sgmii_get_port_link(SGMII2_BASE(sp), sp); 3014 link_state = keystone_sgmii_get_port_link(SGMII2_BASE(sp), sp);
3009 else { 3015 else {
3010 /* Single interface mode. Link is up if any one slave 3016 /* Single interface mode. Link is up if any one slave
3011 * port is up. It assumes slave port always starts from 3017 * port is up. It assumes slave port always starts from
@@ -3013,27 +3019,35 @@ static void cpsw2_timer(unsigned long arg)
3013 */ 3019 */
3014 3020
3015 /* slave port (port > 2) status */ 3021 /* slave port (port > 2) status */
3016 sgmii_link = keystone_sgmii_link_status(SGMII2_BASE(2), 3022 link_state = keystone_sgmii_link_status(SGMII2_BASE(2),
3017 max_t(u32, ns, 2) - 2); 3023 max_t(u32, ns, 2) - 2);
3018 3024
3019 sgmii_link <<= 2; 3025 link_state <<= 2;
3020 3026
3021 /* slave port 0, 1 status */ 3027 /* slave port 0, 1 status */
3022 sgmii_link |= keystone_sgmii_link_status(SGMII2_BASE(0), 3028 link_state |= keystone_sgmii_link_status(SGMII2_BASE(0),
3023 min_t(u32, ns, 2)); 3029 min_t(u32, ns, 2));
3024 } 3030 }
3025 cpsw_intf->sgmii_link = sgmii_link; 3031 cpsw_intf->link_state = link_state;
3026 3032
3033 /* if MAC-to-PHY, check phy link status also
3034 * to conclude the intf link's status
3035 */
3027 for_each_slave(cpsw_intf, cpsw2_slave_link, cpsw_intf); 3036 for_each_slave(cpsw_intf, cpsw2_slave_link, cpsw_intf);
3028 3037
3029 /* FIXME: Don't aggregate link statuses in multi-interface case */ 3038 /* Is this the right logic?
3030 if (cpsw_intf->sgmii_link) { 3039 * multi_if & MAC_PHY: phy state machine already reported carrier
3031 /* link ON */ 3040 * multi_if & !MAC_PHY: report carrier
3032 if (!netif_carrier_ok(cpsw_intf->ndev)) 3041 * !multi_if: any one slave up means intf is up, reporting carrier
3042 * here corrects what phy state machine (if it exists)
3043 * might have reported.
3044 */
3045 if (!cpsw_dev->multi_if ||
3046 (cpsw_dev->multi_if &&
3047 cpsw_intf->slaves->link_interface != SGMII_LINK_MAC_PHY)) {
3048 if (cpsw_intf->link_state)
3033 netif_carrier_on(cpsw_intf->ndev); 3049 netif_carrier_on(cpsw_intf->ndev);
3034 } else { 3050 else
3035 /* link OFF */
3036 if (netif_carrier_ok(cpsw_intf->ndev))
3037 netif_carrier_off(cpsw_intf->ndev); 3051 netif_carrier_off(cpsw_intf->ndev);
3038 } 3052 }
3039 3053