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
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>
-rw-r--r--drivers/net/ethernet/ti/keystone_ethss.c71
-rw-r--r--drivers/net/ethernet/ti/keystone_ethss2.c72
-rw-r--r--drivers/net/ethernet/ti/keystone_net.h2
-rw-r--r--drivers/net/ethernet/ti/keystone_xgess.c79
4 files changed, 134 insertions, 90 deletions
diff --git a/drivers/net/ethernet/ti/keystone_ethss.c b/drivers/net/ethernet/ti/keystone_ethss.c
index e2aebf708dc..1e18fa4d27e 100644
--- a/drivers/net/ethernet/ti/keystone_ethss.c
+++ b/drivers/net/ethernet/ti/keystone_ethss.c
@@ -63,6 +63,9 @@
63#define MACSL_RX_ENABLE_CSF BIT(23) 63#define MACSL_RX_ENABLE_CSF BIT(23)
64#define MACSL_RX_ENABLE_EXT_CTL BIT(18) 64#define MACSL_RX_ENABLE_EXT_CTL BIT(18)
65#define MACSL_ENABLE BIT(5) 65#define MACSL_ENABLE BIT(5)
66#define MACSL_DEFAULT_CONFIG (MACSL_ENABLE |\
67 MACSL_RX_ENABLE_EXT_CTL |\
68 MACSL_RX_ENABLE_CSF)
66#define GMACSL_RET_WARN_RESET_INCOMPLETE -2 69#define GMACSL_RET_WARN_RESET_INCOMPLETE -2
67 70
68#define CPSW_NUM_PORTS 5 71#define CPSW_NUM_PORTS 5
@@ -154,7 +157,7 @@
154 157
155#define MAX_SLAVES 4 158#define MAX_SLAVES 4
156 159
157/* s: 0-based slave_port */ 160/* s: 0-based slave_num */
158#define SGMII_BASE(s) \ 161#define SGMII_BASE(s) \
159 (((s) < 2) ? cpsw_dev->sgmii_port_regs : cpsw_dev->sgmii_port34_regs) 162 (((s) < 2) ? cpsw_dev->sgmii_port_regs : cpsw_dev->sgmii_port34_regs)
160 163
@@ -169,6 +172,9 @@ struct cpts_port_ts_ctl {
169 u8 ts_mcast_type; 172 u8 ts_mcast_type;
170}; 173};
171 174
175/* slave_num: 0-based
176 * port_num: 1-based
177 */
172struct cpsw_slave { 178struct cpsw_slave {
173 struct cpsw_slave_regs __iomem *regs; 179 struct cpsw_slave_regs __iomem *regs;
174 struct cpsw_sliver_regs __iomem *sliver; 180 struct cpsw_sliver_regs __iomem *sliver;
@@ -549,6 +555,8 @@ struct cpsw_priv {
549 struct serdes serdes; 555 struct serdes serdes;
550}; 556};
551 557
558/* slave_port: 0-based (currently relevant only in multi_if mode)
559*/
552struct cpsw_intf { 560struct cpsw_intf {
553 struct net_device *ndev; 561 struct net_device *ndev;
554 struct device *dev; 562 struct device *dev;
@@ -564,7 +572,7 @@ struct cpsw_intf {
564 u32 multi_if; 572 u32 multi_if;
565 struct list_head cpsw_intf_list; 573 struct list_head cpsw_intf_list;
566 struct timer_list timer; 574 struct timer_list timer;
567 u32 sgmii_link; 575 u32 link_state;
568}; 576};
569 577
570static struct cpsw_priv *global_priv; /* FIXME: REMOVE THIS!! */ 578static struct cpsw_priv *global_priv; /* FIXME: REMOVE THIS!! */
@@ -2101,8 +2109,7 @@ static void _cpsw_adjust_link(struct cpsw_slave *slave, bool *link)
2101 2109
2102 if (phy->link) { 2110 if (phy->link) {
2103 mac_control = slave->mac_control; 2111 mac_control = slave->mac_control;
2104 mac_control |= MACSL_ENABLE | MACSL_RX_ENABLE_EXT_CTL | 2112 mac_control |= MACSL_DEFAULT_CONFIG;
2105 MACSL_RX_ENABLE_CSF;
2106 /* enable forwarding */ 2113 /* enable forwarding */
2107 cpsw_ale_control_set(slave->ale, slave_port, 2114 cpsw_ale_control_set(slave->ale, slave_port,
2108 ALE_PORT_STATE, ALE_PORT_STATE_FORWARD); 2115 ALE_PORT_STATE, ALE_PORT_STATE_FORWARD);
@@ -2137,9 +2144,9 @@ static void cpsw_adjust_link(struct net_device *n_dev, void *context)
2137 _cpsw_adjust_link(slave, &link); 2144 _cpsw_adjust_link(slave, &link);
2138 2145
2139 if (link) 2146 if (link)
2140 netcp->link_state |= BIT(slave->slave_num); 2147 netcp->phy_link_state_mask |= BIT(slave->slave_num);
2141 else 2148 else
2142 netcp->link_state &= ~BIT(slave->slave_num); 2149 netcp->phy_link_state_mask &= ~BIT(slave->slave_num);
2143} 2150}
2144 2151
2145/* 2152/*
@@ -2174,11 +2181,12 @@ static void cpsw_port_config(struct cpsw_slave *slave, int max_rx_len)
2174 if (max_rx_len > MAX_SIZE_STREAM_BUFFER) 2181 if (max_rx_len > MAX_SIZE_STREAM_BUFFER)
2175 max_rx_len = MAX_SIZE_STREAM_BUFFER; 2182 max_rx_len = MAX_SIZE_STREAM_BUFFER;
2176 2183
2184 slave->mac_control = MACSL_DEFAULT_CONFIG;
2185
2177 __raw_writel(max_rx_len, &slave->sliver->rx_maxlen); 2186 __raw_writel(max_rx_len, &slave->sliver->rx_maxlen);
2178 2187
2179 __iowmb(); 2188 __iowmb();
2180 __raw_writel(MACSL_ENABLE | MACSL_RX_ENABLE_EXT_CTL | 2189 __raw_writel(slave->mac_control, &slave->sliver->mac_control);
2181 MACSL_RX_ENABLE_CSF, &slave->sliver->mac_control);
2182} 2190}
2183 2191
2184static void cpsw_slave_stop(struct cpsw_slave *slave, 2192static void cpsw_slave_stop(struct cpsw_slave *slave,
@@ -2213,12 +2221,14 @@ static void cpsw_slave_link(struct cpsw_slave *slave,
2213 struct cpsw_intf *cpsw_intf) 2221 struct cpsw_intf *cpsw_intf)
2214{ 2222{
2215 struct netcp_priv *netcp = netdev_priv(cpsw_intf->ndev); 2223 struct netcp_priv *netcp = netdev_priv(cpsw_intf->ndev);
2224 int sn = slave->slave_num;
2216 2225
2217 if (slave->link_interface == SGMII_LINK_MAC_PHY) { 2226 if (slave->link_interface == SGMII_LINK_MAC_PHY) {
2218 if (netcp->link_state) 2227 /* check only the bit in phy_link_state_mask
2219 cpsw_intf->sgmii_link |= BIT(slave->slave_num); 2228 * that corresponds to the slave
2220 else 2229 */
2221 cpsw_intf->sgmii_link &= ~BIT(slave->slave_num); 2230 if (!(netcp->phy_link_state_mask & BIT(sn)))
2231 cpsw_intf->link_state &= ~BIT(sn);
2222 } 2232 }
2223} 2233}
2224 2234
@@ -2247,9 +2257,6 @@ static void cpsw_slave_open(struct cpsw_slave *slave,
2247 2257
2248 cpsw_set_slave_mac(slave, cpsw_intf); 2258 cpsw_set_slave_mac(slave, cpsw_intf);
2249 2259
2250 slave->mac_control = MACSL_ENABLE | MACSL_RX_ENABLE_EXT_CTL |
2251 MACSL_RX_ENABLE_CSF;
2252
2253 /* this slave port here is 1 based */ 2260 /* this slave port here is 1 based */
2254 slave_port = cpsw_get_slave_port(priv, slave->slave_num); 2261 slave_port = cpsw_get_slave_port(priv, slave->slave_num);
2255 2262
@@ -2639,10 +2646,10 @@ static void cpsw_timer(unsigned long arg)
2639 struct cpsw_priv *cpsw_dev = cpsw_intf->cpsw_priv; 2646 struct cpsw_priv *cpsw_dev = cpsw_intf->cpsw_priv;
2640 u32 sp = cpsw_intf->slave_port; 2647 u32 sp = cpsw_intf->slave_port;
2641 u32 ns = cpsw_intf->num_slaves; 2648 u32 ns = cpsw_intf->num_slaves;
2642 u32 sgmii_link; 2649 u32 link_state;
2643 2650
2644 if (cpsw_dev->multi_if) 2651 if (cpsw_dev->multi_if)
2645 sgmii_link = keystone_sgmii_get_port_link(SGMII_BASE(sp), sp); 2652 link_state = keystone_sgmii_get_port_link(SGMII_BASE(sp), sp);
2646 else { 2653 else {
2647 /* Single interface mode. Link is up if any one slave 2654 /* Single interface mode. Link is up if any one slave
2648 * port is up. It assumes slave port always starts from 2655 * port is up. It assumes slave port always starts from
@@ -2650,28 +2657,36 @@ static void cpsw_timer(unsigned long arg)
2650 */ 2657 */
2651 2658
2652 /* slave port 2, 3 status */ 2659 /* slave port 2, 3 status */
2653 sgmii_link = keystone_sgmii_link_status(SGMII_BASE(2), 2660 link_state = keystone_sgmii_link_status(SGMII_BASE(2),
2654 max_t(u32, ns, 2) - 2); 2661 max_t(u32, ns, 2) - 2);
2655 2662
2656 sgmii_link <<= 2; 2663 link_state <<= 2;
2657 2664
2658 /* slave port 0, 1 status */ 2665 /* slave port 0, 1 status */
2659 sgmii_link |= keystone_sgmii_link_status(SGMII_BASE(0), 2666 link_state |= keystone_sgmii_link_status(SGMII_BASE(0),
2660 min_t(u32, ns, 2)); 2667 min_t(u32, ns, 2));
2661 } 2668 }
2662 2669
2663 cpsw_intf->sgmii_link = sgmii_link; 2670 cpsw_intf->link_state = link_state;
2664 2671
2672 /* if MAC-to-PHY, check phy link status also
2673 * to conclude the intf link's status
2674 */
2665 for_each_slave(cpsw_intf, cpsw_slave_link, cpsw_intf); 2675 for_each_slave(cpsw_intf, cpsw_slave_link, cpsw_intf);
2666 2676
2667 /* FIXME: Don't aggregate link statuses in multi-interface case */ 2677 /* Is this the right logic?
2668 if (cpsw_intf->sgmii_link) { 2678 * multi_if & MAC_PHY: phy state machine already reported carrier
2669 /* link ON */ 2679 * multi_if & !MAC_PHY: report carrier
2670 if (!netif_carrier_ok(cpsw_intf->ndev)) 2680 * !multi_if: any one slave up means intf is up, reporting carrier
2681 * here corrects what phy state machine (if it exists)
2682 * might have reported.
2683 */
2684 if (!cpsw_dev->multi_if ||
2685 (cpsw_dev->multi_if &&
2686 cpsw_intf->slaves->link_interface != SGMII_LINK_MAC_PHY)) {
2687 if (cpsw_intf->link_state)
2671 netif_carrier_on(cpsw_intf->ndev); 2688 netif_carrier_on(cpsw_intf->ndev);
2672 } else { 2689 else
2673 /* link OFF */
2674 if (netif_carrier_ok(cpsw_intf->ndev))
2675 netif_carrier_off(cpsw_intf->ndev); 2690 netif_carrier_off(cpsw_intf->ndev);
2676 } 2691 }
2677 2692
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
diff --git a/drivers/net/ethernet/ti/keystone_net.h b/drivers/net/ethernet/ti/keystone_net.h
index 050b7e81260..307db180a23 100644
--- a/drivers/net/ethernet/ti/keystone_net.h
+++ b/drivers/net/ethernet/ti/keystone_net.h
@@ -131,7 +131,7 @@ struct netcp_priv {
131 spinlock_t lock; 131 spinlock_t lock;
132 int rx_packet_max; 132 int rx_packet_max;
133 const char *rx_chan_name; 133 const char *rx_chan_name;
134 u32 link_state; 134 u32 phy_link_state_mask;
135 struct list_head module_head; 135 struct list_head module_head;
136 struct list_head interface_list; 136 struct list_head interface_list;
137 struct list_head addr_list; 137 struct list_head addr_list;
diff --git a/drivers/net/ethernet/ti/keystone_xgess.c b/drivers/net/ethernet/ti/keystone_xgess.c
index a09de9044d2..0af8126a11e 100644
--- a/drivers/net/ethernet/ti/keystone_xgess.c
+++ b/drivers/net/ethernet/ti/keystone_xgess.c
@@ -69,6 +69,11 @@
69 (MACSL_XGMII_ENABLE | MACSL_XGIG_MODE) : \ 69 (MACSL_XGMII_ENABLE | MACSL_XGIG_MODE) : \
70 MACSL_GMII_ENABLE) 70 MACSL_GMII_ENABLE)
71 71
72#define MACSL_DEFAULT_CONFIG(s) \
73 (MACSL_SIG_ENABLE((s)) | \
74 MACSL_RX_ENABLE_EXT_CTL | \
75 MACSL_RX_ENABLE_CSF)
76
72#define CPSW_NUM_PORTS 3 77#define CPSW_NUM_PORTS 3
73#define CPSW_CTL_P0_ENABLE BIT(2) 78#define CPSW_CTL_P0_ENABLE BIT(2)
74#define CPSW_CTL_VLAN_AWARE BIT(1) 79#define CPSW_CTL_VLAN_AWARE BIT(1)
@@ -85,6 +90,9 @@
85#define HOST_TX_PRI_MAP_DEFAULT 0x00000000 90#define HOST_TX_PRI_MAP_DEFAULT 0x00000000
86#define MAX_SIZE_STREAM_BUFFER 9504 91#define MAX_SIZE_STREAM_BUFFER 9504
87 92
93/* slave_num: 0-based
94 * port_num: 1-based
95 */
88struct cpswx_slave { 96struct cpswx_slave {
89 struct cpswx_slave_regs __iomem *regs; 97 struct cpswx_slave_regs __iomem *regs;
90 struct cpswx_sliver_regs __iomem *sliver; 98 struct cpswx_sliver_regs __iomem *sliver;
@@ -303,6 +311,8 @@ struct cpswx_priv {
303 struct device_node *serdes; 311 struct device_node *serdes;
304}; 312};
305 313
314/* slave_port: 0-based (currently relevant only in multi_if mode)
315*/
306struct cpswx_intf { 316struct cpswx_intf {
307 struct net_device *ndev; 317 struct net_device *ndev;
308 struct device *dev; 318 struct device *dev;
@@ -318,7 +328,7 @@ struct cpswx_intf {
318 u32 multi_if; 328 u32 multi_if;
319 struct list_head cpsw_intf_list; 329 struct list_head cpsw_intf_list;
320 struct timer_list timer; 330 struct timer_list timer;
321 u32 sgmii_link; 331 u32 link_state;
322}; 332};
323 333
324/* 334/*
@@ -1524,9 +1534,7 @@ static void _cpsw_adjust_link(struct cpswx_slave *slave, bool *link)
1524 1534
1525 if (phy->link) { 1535 if (phy->link) {
1526 mac_control = slave->mac_control; 1536 mac_control = slave->mac_control;
1527 mac_control |= MACSL_SIG_ENABLE(slave) | 1537 mac_control |= MACSL_DEFAULT_CONFIG(slave);
1528 MACSL_RX_ENABLE_EXT_CTL |
1529 MACSL_RX_ENABLE_CSF;
1530 /* enable forwarding */ 1538 /* enable forwarding */
1531 cpsw_ale_control_set(slave->ale, slave_port, 1539 cpsw_ale_control_set(slave->ale, slave_port,
1532 ALE_PORT_STATE, ALE_PORT_STATE_FORWARD); 1540 ALE_PORT_STATE, ALE_PORT_STATE_FORWARD);
@@ -1561,9 +1569,9 @@ static void cpsw_adjust_link(struct net_device *n_dev, void *context)
1561 _cpsw_adjust_link(slave, &link); 1569 _cpsw_adjust_link(slave, &link);
1562 1570
1563 if (link) 1571 if (link)
1564 netcp->link_state |= BIT(slave->slave_num); 1572 netcp->phy_link_state_mask |= BIT(slave->slave_num);
1565 else 1573 else
1566 netcp->link_state &= ~BIT(slave->slave_num); 1574 netcp->phy_link_state_mask &= ~BIT(slave->slave_num);
1567} 1575}
1568 1576
1569/* 1577/*
@@ -1595,17 +1603,15 @@ static int cpsw_port_reset(struct cpswx_slave *slave)
1595 */ 1603 */
1596static void cpsw_port_config(struct cpswx_slave *slave, int max_rx_len) 1604static void cpsw_port_config(struct cpswx_slave *slave, int max_rx_len)
1597{ 1605{
1598 u32 mac_control;
1599
1600 if (max_rx_len > MAX_SIZE_STREAM_BUFFER) 1606 if (max_rx_len > MAX_SIZE_STREAM_BUFFER)
1601 max_rx_len = MAX_SIZE_STREAM_BUFFER; 1607 max_rx_len = MAX_SIZE_STREAM_BUFFER;
1602 1608
1609 slave->mac_control = MACSL_DEFAULT_CONFIG(slave);
1610
1603 __raw_writel(max_rx_len, &slave->sliver->rx_maxlen); 1611 __raw_writel(max_rx_len, &slave->sliver->rx_maxlen);
1604 1612
1605 mac_control = (MACSL_SIG_ENABLE(slave) | 1613 __iowmb();
1606 MACSL_RX_ENABLE_EXT_CTL | 1614 __raw_writel(slave->mac_control, &slave->sliver->mac_control);
1607 MACSL_RX_ENABLE_CSF);
1608 __raw_writel(mac_control, &slave->sliver->mac_control);
1609} 1615}
1610 1616
1611static void cpsw_slave_stop(struct cpswx_slave *slave, struct cpswx_priv *priv) 1617static void cpsw_slave_stop(struct cpswx_slave *slave, struct cpswx_priv *priv)
@@ -1624,15 +1630,17 @@ static void cpsw_slave_link(struct cpswx_slave *slave,
1624 struct cpswx_intf *cpsw_intf) 1630 struct cpswx_intf *cpsw_intf)
1625{ 1631{
1626 struct netcp_priv *netcp = netdev_priv(cpsw_intf->ndev); 1632 struct netcp_priv *netcp = netdev_priv(cpsw_intf->ndev);
1633 int sn = slave->slave_num;
1627 1634
1628 if ((slave->link_interface == SGMII_LINK_MAC_PHY) || 1635 if ((slave->link_interface == SGMII_LINK_MAC_PHY) ||
1629 (slave->link_interface == XGMII_LINK_MAC_PHY)) { 1636 (slave->link_interface == XGMII_LINK_MAC_PHY)) {
1630 if (netcp->link_state) 1637 /* check only the bit in phy_link_state_mask
1631 cpsw_intf->sgmii_link |= BIT(slave->slave_num); 1638 * that corresponds to the slave
1632 else 1639 */
1633 cpsw_intf->sgmii_link &= ~BIT(slave->slave_num); 1640 if (!(netcp->phy_link_state_mask & BIT(sn)))
1641 cpsw_intf->link_state &= ~BIT(sn);
1634 } else if (slave->link_interface == XGMII_LINK_MAC_MAC_FORCED) 1642 } else if (slave->link_interface == XGMII_LINK_MAC_MAC_FORCED)
1635 cpsw_intf->sgmii_link |= BIT(slave->slave_num); 1643 cpsw_intf->link_state |= BIT(slave->slave_num);
1636} 1644}
1637 1645
1638static void cpsw_slave_open(struct cpswx_slave *slave, 1646static void cpsw_slave_open(struct cpswx_slave *slave,
@@ -1661,9 +1669,6 @@ static void cpsw_slave_open(struct cpswx_slave *slave,
1661 1669
1662 cpsw_set_slave_mac(slave, cpsw_intf); 1670 cpsw_set_slave_mac(slave, cpsw_intf);
1663 1671
1664 slave->mac_control = MACSL_SIG_ENABLE(slave) | MACSL_RX_ENABLE_EXT_CTL |
1665 MACSL_RX_ENABLE_CSF;
1666
1667 slave_port = cpsw_get_slave_port(priv, slave->slave_num); 1672 slave_port = cpsw_get_slave_port(priv, slave->slave_num);
1668 1673
1669 slave->port_num = slave_port; 1674 slave->port_num = slave_port;
@@ -1884,34 +1889,44 @@ static void cpswx_timer(unsigned long arg)
1884 struct cpswx_priv *cpsw_dev = cpsw_intf->cpsw_priv; 1889 struct cpswx_priv *cpsw_dev = cpsw_intf->cpsw_priv;
1885 1890
1886 /* 1891 /*
1887 * if the slave's link_interface is not XGMII, sgmii_link bit 1892 * if the slave's link_interface is not XGMII, link_state bit
1888 * will not be set 1893 * will not be set
1889 */ 1894 */
1890 if (cpsw_dev->multi_if) 1895 if (cpsw_dev->multi_if)
1891 cpsw_intf->sgmii_link = 1896 cpsw_intf->link_state =
1892 keystone_sgmii_get_port_link(cpsw_dev->sgmii_port_regs, 1897 keystone_sgmii_get_port_link(cpsw_dev->sgmii_port_regs,
1893 cpsw_intf->slave_port); 1898 cpsw_intf->slave_port);
1894 else 1899 else
1895 cpsw_intf->sgmii_link = 1900 cpsw_intf->link_state =
1896 keystone_sgmii_link_status(cpsw_dev->sgmii_port_regs, 1901 keystone_sgmii_link_status(cpsw_dev->sgmii_port_regs,
1897 cpsw_intf->num_slaves); 1902 cpsw_intf->num_slaves);
1898 1903
1904 /* if MAC-to-PHY, check phy link status also
1905 * to conclude the intf link's status
1906 */
1899 for_each_slave(cpsw_intf, cpsw_slave_link, cpsw_intf); 1907 for_each_slave(cpsw_intf, cpsw_slave_link, cpsw_intf);
1900 1908
1901 /* FIXME: Don't aggregate link statuses in multi-interface case */ 1909 /* Is this the right logic?
1902 if (cpsw_intf->sgmii_link) { 1910 * multi_if & MAC_PHY: phy state machine already reported carrier
1903 /* link ON */ 1911 * multi_if & !MAC_PHY: report carrier
1904 if (!netif_carrier_ok(cpsw_intf->ndev)) 1912 * !multi_if: any one slave up means intf is up, reporting carrier
1913 * here corrects what phy state machine (if it exists)
1914 * might have reported.
1915 */
1916 if (!cpsw_dev->multi_if ||
1917 (cpsw_dev->multi_if &&
1918 (cpsw_intf->slaves->link_interface != SGMII_LINK_MAC_PHY) &&
1919 (cpsw_intf->slaves->link_interface != XGMII_LINK_MAC_PHY))) {
1920 if (cpsw_intf->link_state)
1905 netif_carrier_on(cpsw_intf->ndev); 1921 netif_carrier_on(cpsw_intf->ndev);
1906 } else { 1922 else
1907 /* link OFF */
1908 if (netif_carrier_ok(cpsw_intf->ndev))
1909 netif_carrier_off(cpsw_intf->ndev); 1923 netif_carrier_off(cpsw_intf->ndev);
1910 } 1924 }
1911 1925
1912 spin_lock_bh(&cpsw_dev->hw_stats_lock); 1926 /* A timer runs as a BH, no need to block them */
1927 spin_lock(&cpsw_dev->hw_stats_lock);
1913 cpswx_update_stats(cpsw_dev, NULL); 1928 cpswx_update_stats(cpsw_dev, NULL);
1914 spin_unlock_bh(&cpsw_dev->hw_stats_lock); 1929 spin_unlock(&cpsw_dev->hw_stats_lock);
1915 1930
1916 cpsw_intf->timer.expires = jiffies + (HZ/10); 1931 cpsw_intf->timer.expires = jiffies + (HZ/10);
1917 add_timer(&cpsw_intf->timer); 1932 add_timer(&cpsw_intf->timer);