aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/ti/keystone_ethss.c')
-rw-r--r--drivers/net/ethernet/ti/keystone_ethss.c87
1 files changed, 57 insertions, 30 deletions
diff --git a/drivers/net/ethernet/ti/keystone_ethss.c b/drivers/net/ethernet/ti/keystone_ethss.c
index e2aebf708dc..dc0ed03df54 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,10 +157,13 @@
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
164#define IS_SGMII_MAC_PHY(i) \
165 (((i) == SGMII_LINK_MAC_PHY) || ((i) == SGMII_LINK_MAC_PHY_MASTER))
166
161/* CPSW SERDES */ 167/* CPSW SERDES */
162#define CPSW_SERDES_MAX_NUM 1 168#define CPSW_SERDES_MAX_NUM 1
163#define CPSW_LANE_NUM_PER_SERDES 4 169#define CPSW_LANE_NUM_PER_SERDES 4
@@ -169,6 +175,9 @@ struct cpts_port_ts_ctl {
169 u8 ts_mcast_type; 175 u8 ts_mcast_type;
170}; 176};
171 177
178/* slave_num: 0-based
179 * port_num: 1-based
180 */
172struct cpsw_slave { 181struct cpsw_slave {
173 struct cpsw_slave_regs __iomem *regs; 182 struct cpsw_slave_regs __iomem *regs;
174 struct cpsw_sliver_regs __iomem *sliver; 183 struct cpsw_sliver_regs __iomem *sliver;
@@ -547,8 +556,11 @@ struct cpsw_priv {
547 u32 num_serdes; 556 u32 num_serdes;
548 u32 serdes_lanes; 557 u32 serdes_lanes;
549 struct serdes serdes; 558 struct serdes serdes;
559 u32 opened;
550}; 560};
551 561
562/* slave_port: 0-based (currently relevant only in multi_if mode)
563*/
552struct cpsw_intf { 564struct cpsw_intf {
553 struct net_device *ndev; 565 struct net_device *ndev;
554 struct device *dev; 566 struct device *dev;
@@ -564,7 +576,7 @@ struct cpsw_intf {
564 u32 multi_if; 576 u32 multi_if;
565 struct list_head cpsw_intf_list; 577 struct list_head cpsw_intf_list;
566 struct timer_list timer; 578 struct timer_list timer;
567 u32 sgmii_link; 579 u32 link_state;
568}; 580};
569 581
570static struct cpsw_priv *global_priv; /* FIXME: REMOVE THIS!! */ 582static struct cpsw_priv *global_priv; /* FIXME: REMOVE THIS!! */
@@ -2101,8 +2113,7 @@ static void _cpsw_adjust_link(struct cpsw_slave *slave, bool *link)
2101 2113
2102 if (phy->link) { 2114 if (phy->link) {
2103 mac_control = slave->mac_control; 2115 mac_control = slave->mac_control;
2104 mac_control |= MACSL_ENABLE | MACSL_RX_ENABLE_EXT_CTL | 2116 mac_control |= MACSL_DEFAULT_CONFIG;
2105 MACSL_RX_ENABLE_CSF;
2106 /* enable forwarding */ 2117 /* enable forwarding */
2107 cpsw_ale_control_set(slave->ale, slave_port, 2118 cpsw_ale_control_set(slave->ale, slave_port,
2108 ALE_PORT_STATE, ALE_PORT_STATE_FORWARD); 2119 ALE_PORT_STATE, ALE_PORT_STATE_FORWARD);
@@ -2137,9 +2148,9 @@ static void cpsw_adjust_link(struct net_device *n_dev, void *context)
2137 _cpsw_adjust_link(slave, &link); 2148 _cpsw_adjust_link(slave, &link);
2138 2149
2139 if (link) 2150 if (link)
2140 netcp->link_state |= BIT(slave->slave_num); 2151 netcp->phy_link_state_mask |= BIT(slave->slave_num);
2141 else 2152 else
2142 netcp->link_state &= ~BIT(slave->slave_num); 2153 netcp->phy_link_state_mask &= ~BIT(slave->slave_num);
2143} 2154}
2144 2155
2145/* 2156/*
@@ -2174,11 +2185,12 @@ static void cpsw_port_config(struct cpsw_slave *slave, int max_rx_len)
2174 if (max_rx_len > MAX_SIZE_STREAM_BUFFER) 2185 if (max_rx_len > MAX_SIZE_STREAM_BUFFER)
2175 max_rx_len = MAX_SIZE_STREAM_BUFFER; 2186 max_rx_len = MAX_SIZE_STREAM_BUFFER;
2176 2187
2188 slave->mac_control = MACSL_DEFAULT_CONFIG;
2189
2177 __raw_writel(max_rx_len, &slave->sliver->rx_maxlen); 2190 __raw_writel(max_rx_len, &slave->sliver->rx_maxlen);
2178 2191
2179 __iowmb(); 2192 __iowmb();
2180 __raw_writel(MACSL_ENABLE | MACSL_RX_ENABLE_EXT_CTL | 2193 __raw_writel(slave->mac_control, &slave->sliver->mac_control);
2181 MACSL_RX_ENABLE_CSF, &slave->sliver->mac_control);
2182} 2194}
2183 2195
2184static void cpsw_slave_stop(struct cpsw_slave *slave, 2196static void cpsw_slave_stop(struct cpsw_slave *slave,
@@ -2213,12 +2225,14 @@ static void cpsw_slave_link(struct cpsw_slave *slave,
2213 struct cpsw_intf *cpsw_intf) 2225 struct cpsw_intf *cpsw_intf)
2214{ 2226{
2215 struct netcp_priv *netcp = netdev_priv(cpsw_intf->ndev); 2227 struct netcp_priv *netcp = netdev_priv(cpsw_intf->ndev);
2228 int sn = slave->slave_num;
2216 2229
2217 if (slave->link_interface == SGMII_LINK_MAC_PHY) { 2230 if (IS_SGMII_MAC_PHY(slave->link_interface)) {
2218 if (netcp->link_state) 2231 /* check only the bit in phy_link_state_mask
2219 cpsw_intf->sgmii_link |= BIT(slave->slave_num); 2232 * that corresponds to the slave
2220 else 2233 */
2221 cpsw_intf->sgmii_link &= ~BIT(slave->slave_num); 2234 if (!(netcp->phy_link_state_mask & BIT(sn)))
2235 cpsw_intf->link_state &= ~BIT(sn);
2222 } 2236 }
2223} 2237}
2224 2238
@@ -2247,9 +2261,6 @@ static void cpsw_slave_open(struct cpsw_slave *slave,
2247 2261
2248 cpsw_set_slave_mac(slave, cpsw_intf); 2262 cpsw_set_slave_mac(slave, cpsw_intf);
2249 2263
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 */ 2264 /* this slave port here is 1 based */
2254 slave_port = cpsw_get_slave_port(priv, slave->slave_num); 2265 slave_port = cpsw_get_slave_port(priv, slave->slave_num);
2255 2266
@@ -2264,7 +2275,7 @@ static void cpsw_slave_open(struct cpsw_slave *slave,
2264 cpsw_ale_add_mcast(priv->ale, cpsw_intf->ndev->broadcast, 2275 cpsw_ale_add_mcast(priv->ale, cpsw_intf->ndev->broadcast,
2265 1 << slave_port, 0, 0, ALE_MCAST_FWD_2); 2276 1 << slave_port, 0, 0, ALE_MCAST_FWD_2);
2266 2277
2267 if (slave->link_interface == SGMII_LINK_MAC_PHY) { 2278 if (IS_SGMII_MAC_PHY(slave->link_interface)) {
2268 slave->phy = of_phy_connect(cpsw_intf->ndev, 2279 slave->phy = of_phy_connect(cpsw_intf->ndev,
2269 cpsw_intf->phy_node, 2280 cpsw_intf->phy_node,
2270 &cpsw_adjust_link, 0, 2281 &cpsw_adjust_link, 0,
@@ -2393,6 +2404,9 @@ int cpsw_add_addr(void *intf_priv, struct netcp_addr *naddr)
2393 struct cpsw_intf *cpsw_intf = intf_priv; 2404 struct cpsw_intf *cpsw_intf = intf_priv;
2394 struct cpsw_priv *cpsw_dev = cpsw_intf->cpsw_priv; 2405 struct cpsw_priv *cpsw_dev = cpsw_intf->cpsw_priv;
2395 2406
2407 if (!cpsw_dev->opened)
2408 return -ENXIO;
2409
2396 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",
2397 naddr->addr, naddr->type); 2411 naddr->addr, naddr->type);
2398 2412
@@ -2419,6 +2433,9 @@ int cpsw_del_addr(void *intf_priv, struct netcp_addr *naddr)
2419 struct cpsw_intf *cpsw_intf = intf_priv; 2433 struct cpsw_intf *cpsw_intf = intf_priv;
2420 struct cpsw_priv *cpsw_dev = cpsw_intf->cpsw_priv; 2434 struct cpsw_priv *cpsw_dev = cpsw_intf->cpsw_priv;
2421 2435
2436 if (!cpsw_dev->opened)
2437 return -ENXIO;
2438
2422 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",
2423 naddr->addr, naddr->type); 2440 naddr->addr, naddr->type);
2424 2441
@@ -2639,10 +2656,10 @@ static void cpsw_timer(unsigned long arg)
2639 struct cpsw_priv *cpsw_dev = cpsw_intf->cpsw_priv; 2656 struct cpsw_priv *cpsw_dev = cpsw_intf->cpsw_priv;
2640 u32 sp = cpsw_intf->slave_port; 2657 u32 sp = cpsw_intf->slave_port;
2641 u32 ns = cpsw_intf->num_slaves; 2658 u32 ns = cpsw_intf->num_slaves;
2642 u32 sgmii_link; 2659 u32 link_state;
2643 2660
2644 if (cpsw_dev->multi_if) 2661 if (cpsw_dev->multi_if)
2645 sgmii_link = keystone_sgmii_get_port_link(SGMII_BASE(sp), sp); 2662 link_state = keystone_sgmii_get_port_link(SGMII_BASE(sp), sp);
2646 else { 2663 else {
2647 /* Single interface mode. Link is up if any one slave 2664 /* Single interface mode. Link is up if any one slave
2648 * port is up. It assumes slave port always starts from 2665 * port is up. It assumes slave port always starts from
@@ -2650,28 +2667,36 @@ static void cpsw_timer(unsigned long arg)
2650 */ 2667 */
2651 2668
2652 /* slave port 2, 3 status */ 2669 /* slave port 2, 3 status */
2653 sgmii_link = keystone_sgmii_link_status(SGMII_BASE(2), 2670 link_state = keystone_sgmii_link_status(SGMII_BASE(2),
2654 max_t(u32, ns, 2) - 2); 2671 max_t(u32, ns, 2) - 2);
2655 2672
2656 sgmii_link <<= 2; 2673 link_state <<= 2;
2657 2674
2658 /* slave port 0, 1 status */ 2675 /* slave port 0, 1 status */
2659 sgmii_link |= keystone_sgmii_link_status(SGMII_BASE(0), 2676 link_state |= keystone_sgmii_link_status(SGMII_BASE(0),
2660 min_t(u32, ns, 2)); 2677 min_t(u32, ns, 2));
2661 } 2678 }
2662 2679
2663 cpsw_intf->sgmii_link = sgmii_link; 2680 cpsw_intf->link_state = link_state;
2664 2681
2682 /* if MAC-to-PHY, check phy link status also
2683 * to conclude the intf link's status
2684 */
2665 for_each_slave(cpsw_intf, cpsw_slave_link, cpsw_intf); 2685 for_each_slave(cpsw_intf, cpsw_slave_link, cpsw_intf);
2666 2686
2667 /* FIXME: Don't aggregate link statuses in multi-interface case */ 2687 /* Is this the right logic?
2668 if (cpsw_intf->sgmii_link) { 2688 * multi_if & MAC_PHY: phy state machine already reported carrier
2669 /* link ON */ 2689 * multi_if & !MAC_PHY: report carrier
2670 if (!netif_carrier_ok(cpsw_intf->ndev)) 2690 * !multi_if: any one slave up means intf is up, reporting carrier
2691 * here corrects what phy state machine (if it exists)
2692 * might have reported.
2693 */
2694 if (!cpsw_dev->multi_if ||
2695 (cpsw_dev->multi_if &&
2696 !IS_SGMII_MAC_PHY(cpsw_intf->slaves->link_interface))) {
2697 if (cpsw_intf->link_state)
2671 netif_carrier_on(cpsw_intf->ndev); 2698 netif_carrier_on(cpsw_intf->ndev);
2672 } else { 2699 else
2673 /* link OFF */
2674 if (netif_carrier_ok(cpsw_intf->ndev))
2675 netif_carrier_off(cpsw_intf->ndev); 2700 netif_carrier_off(cpsw_intf->ndev);
2676 } 2701 }
2677 2702
@@ -3078,6 +3103,7 @@ static int cpsw_open(void *intf_priv, struct net_device *ndev)
3078 PSTREAM_ROUTE_DMA); 3103 PSTREAM_ROUTE_DMA);
3079 3104
3080 cpsw_register_cpts(cpsw_dev); 3105 cpsw_register_cpts(cpsw_dev);
3106 cpsw_dev->opened = 1;
3081 return 0; 3107 return 0;
3082 3108
3083ale_fail: 3109ale_fail:
@@ -3117,6 +3143,7 @@ static int cpsw_close(void *intf_priv, struct net_device *ndev)
3117 clk_put(cpsw_dev->cpgmac); 3143 clk_put(cpsw_dev->cpgmac);
3118 3144
3119 cpsw_unregister_cpts(cpsw_dev); 3145 cpsw_unregister_cpts(cpsw_dev);
3146 cpsw_dev->opened = 0;
3120 return 0; 3147 return 0;
3121} 3148}
3122 3149