diff options
author | WingMan Kwok | 2015-03-10 09:23:42 -0500 |
---|---|---|
committer | WingMan Kwok | 2015-03-10 09:23:42 -0500 |
commit | d7f10aaee5f44bf9ef3a990f0e13584c44aef795 (patch) | |
tree | 24e6f0b6f5ce40427711b29ffbb7dbce952bcfad | |
parent | efeb259be8f0a91d6ea48f8f905bd1f590510360 (diff) | |
parent | 3e81277598fad80c185a1c2aa52952047409046e (diff) | |
download | linux-master-rt.tar.gz linux-master-rt.tar.xz linux-master-rt.zip |
Merge branch '24-drivers-net' into master-rtmaster-rt
-rw-r--r-- | drivers/net/ethernet/ti/keystone_ethss.c | 87 | ||||
-rw-r--r-- | drivers/net/ethernet/ti/keystone_ethss2.c | 396 | ||||
-rw-r--r-- | drivers/net/ethernet/ti/keystone_net.h | 5 | ||||
-rw-r--r-- | drivers/net/ethernet/ti/keystone_net_core.c | 110 | ||||
-rw-r--r-- | drivers/net/ethernet/ti/keystone_pa.c | 9 | ||||
-rw-r--r-- | drivers/net/ethernet/ti/keystone_pa2.c | 9 | ||||
-rw-r--r-- | drivers/net/ethernet/ti/keystone_sgmii.c | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/ti/keystone_xgess.c | 88 |
8 files changed, 555 insertions, 152 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 | */ | ||
172 | struct cpsw_slave { | 181 | struct 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 | */ | ||
552 | struct cpsw_intf { | 564 | struct 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 | ||
570 | static struct cpsw_priv *global_priv; /* FIXME: REMOVE THIS!! */ | 582 | static 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 | ||
2184 | static void cpsw_slave_stop(struct cpsw_slave *slave, | 2196 | static 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 | ||
3083 | ale_fail: | 3109 | ale_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 | ||
diff --git a/drivers/net/ethernet/ti/keystone_ethss2.c b/drivers/net/ethernet/ti/keystone_ethss2.c index 5f2c64f56c4..77cf57c5512 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,10 +160,13 @@ | |||
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 | ||
167 | #define IS_SGMII_MAC_PHY(i) \ | ||
168 | (((i) == SGMII_LINK_MAC_PHY) || ((i) == SGMII_LINK_MAC_PHY_MASTER)) | ||
169 | |||
164 | 170 | ||
165 | /* CPSW Statistics register map size */ | 171 | /* CPSW Statistics register map size */ |
166 | #define CPSW2_STATS_REGS_SIZE 0x200 | 172 | #define CPSW2_STATS_REGS_SIZE 0x200 |
@@ -179,6 +185,9 @@ struct cpts2_port_ts_ctl { | |||
179 | u8 ts_mcast_type; | 185 | u8 ts_mcast_type; |
180 | }; | 186 | }; |
181 | 187 | ||
188 | /* slave_num: 0-based | ||
189 | * port_num: 1-based | ||
190 | */ | ||
182 | struct cpsw2_slave { | 191 | struct cpsw2_slave { |
183 | struct cpsw2_slave_regs __iomem *regs; | 192 | struct cpsw2_slave_regs __iomem *regs; |
184 | int slave_num; | 193 | int slave_num; |
@@ -348,9 +357,50 @@ struct cpsw2_hw_stats { | |||
348 | u32 ale_rate_limit_drop; | 357 | u32 ale_rate_limit_drop; |
349 | u32 ale_vid_ingress_drop; | 358 | u32 ale_vid_ingress_drop; |
350 | u32 ale_da_eq_sa_drop; | 359 | u32 ale_da_eq_sa_drop; |
351 | u32 ale_block_drop; | 360 | u32 rsvd0[3]; |
352 | u32 ale_secure_drop; | 361 | u32 ale_unknown_ucast; |
353 | u32 ale_auth_drop; | 362 | u32 ale_unknown_ucast_bytes; |
363 | u32 ale_unknown_mcast; | ||
364 | u32 ale_unknown_mcast_bytes; | ||
365 | u32 ale_unknown_bcast; | ||
366 | u32 ale_unknown_bcast_bytes; | ||
367 | u32 ale_pol_match; | ||
368 | u32 ale_pol_match_red; | ||
369 | u32 ale_pol_match_yellow; | ||
370 | u32 rsvd1[44]; | ||
371 | u32 tx_mem_protect_err; | ||
372 | u32 tx_pri0; | ||
373 | u32 tx_pri1; | ||
374 | u32 tx_pri2; | ||
375 | u32 tx_pri3; | ||
376 | u32 tx_pri4; | ||
377 | u32 tx_pri5; | ||
378 | u32 tx_pri6; | ||
379 | u32 tx_pri7; | ||
380 | u32 tx_pri0_bcnt; | ||
381 | u32 tx_pri1_bcnt; | ||
382 | u32 tx_pri2_bcnt; | ||
383 | u32 tx_pri3_bcnt; | ||
384 | u32 tx_pri4_bcnt; | ||
385 | u32 tx_pri5_bcnt; | ||
386 | u32 tx_pri6_bcnt; | ||
387 | u32 tx_pri7_bcnt; | ||
388 | u32 tx_pri0_drop; | ||
389 | u32 tx_pri1_drop; | ||
390 | u32 tx_pri2_drop; | ||
391 | u32 tx_pri3_drop; | ||
392 | u32 tx_pri4_drop; | ||
393 | u32 tx_pri5_drop; | ||
394 | u32 tx_pri6_drop; | ||
395 | u32 tx_pri7_drop; | ||
396 | u32 tx_pri0_drop_bcnt; | ||
397 | u32 tx_pri1_drop_bcnt; | ||
398 | u32 tx_pri2_drop_bcnt; | ||
399 | u32 tx_pri3_drop_bcnt; | ||
400 | u32 tx_pri4_drop_bcnt; | ||
401 | u32 tx_pri5_drop_bcnt; | ||
402 | u32 tx_pri6_drop_bcnt; | ||
403 | u32 tx_pri7_drop_bcnt; | ||
354 | }; | 404 | }; |
355 | 405 | ||
356 | /* Offset 0x3e000 */ | 406 | /* Offset 0x3e000 */ |
@@ -486,9 +536,32 @@ static const struct netcp2_ethtool_stat et_stats[] = { | |||
486 | {CPSW2_STATS0_INFO(ale_rate_limit_drop)}, | 536 | {CPSW2_STATS0_INFO(ale_rate_limit_drop)}, |
487 | {CPSW2_STATS0_INFO(ale_vid_ingress_drop)}, | 537 | {CPSW2_STATS0_INFO(ale_vid_ingress_drop)}, |
488 | {CPSW2_STATS0_INFO(ale_da_eq_sa_drop)}, | 538 | {CPSW2_STATS0_INFO(ale_da_eq_sa_drop)}, |
489 | {CPSW2_STATS0_INFO(ale_block_drop)}, | 539 | {CPSW2_STATS0_INFO(ale_unknown_ucast)}, |
490 | {CPSW2_STATS0_INFO(ale_secure_drop)}, | 540 | {CPSW2_STATS0_INFO(ale_unknown_ucast_bytes)}, |
491 | {CPSW2_STATS0_INFO(ale_auth_drop)}, | 541 | {CPSW2_STATS0_INFO(ale_unknown_mcast)}, |
542 | {CPSW2_STATS0_INFO(ale_unknown_mcast_bytes)}, | ||
543 | {CPSW2_STATS0_INFO(ale_unknown_bcast)}, | ||
544 | {CPSW2_STATS0_INFO(ale_unknown_bcast_bytes)}, | ||
545 | {CPSW2_STATS0_INFO(ale_pol_match)}, | ||
546 | {CPSW2_STATS0_INFO(ale_pol_match_red)}, | ||
547 | {CPSW2_STATS0_INFO(ale_pol_match_yellow)}, | ||
548 | {CPSW2_STATS0_INFO(tx_mem_protect_err)}, | ||
549 | {CPSW2_STATS0_INFO(tx_pri0_drop)}, | ||
550 | {CPSW2_STATS0_INFO(tx_pri1_drop)}, | ||
551 | {CPSW2_STATS0_INFO(tx_pri2_drop)}, | ||
552 | {CPSW2_STATS0_INFO(tx_pri3_drop)}, | ||
553 | {CPSW2_STATS0_INFO(tx_pri4_drop)}, | ||
554 | {CPSW2_STATS0_INFO(tx_pri5_drop)}, | ||
555 | {CPSW2_STATS0_INFO(tx_pri6_drop)}, | ||
556 | {CPSW2_STATS0_INFO(tx_pri7_drop)}, | ||
557 | {CPSW2_STATS0_INFO(tx_pri0_drop_bcnt)}, | ||
558 | {CPSW2_STATS0_INFO(tx_pri1_drop_bcnt)}, | ||
559 | {CPSW2_STATS0_INFO(tx_pri2_drop_bcnt)}, | ||
560 | {CPSW2_STATS0_INFO(tx_pri3_drop_bcnt)}, | ||
561 | {CPSW2_STATS0_INFO(tx_pri4_drop_bcnt)}, | ||
562 | {CPSW2_STATS0_INFO(tx_pri5_drop_bcnt)}, | ||
563 | {CPSW2_STATS0_INFO(tx_pri6_drop_bcnt)}, | ||
564 | {CPSW2_STATS0_INFO(tx_pri7_drop_bcnt)}, | ||
492 | /* CPSW module 1 */ | 565 | /* CPSW module 1 */ |
493 | {CPSW2_STATS1_INFO(rx_good_frames)}, | 566 | {CPSW2_STATS1_INFO(rx_good_frames)}, |
494 | {CPSW2_STATS1_INFO(rx_broadcast_frames)}, | 567 | {CPSW2_STATS1_INFO(rx_broadcast_frames)}, |
@@ -529,9 +602,32 @@ static const struct netcp2_ethtool_stat et_stats[] = { | |||
529 | {CPSW2_STATS1_INFO(ale_rate_limit_drop)}, | 602 | {CPSW2_STATS1_INFO(ale_rate_limit_drop)}, |
530 | {CPSW2_STATS1_INFO(ale_vid_ingress_drop)}, | 603 | {CPSW2_STATS1_INFO(ale_vid_ingress_drop)}, |
531 | {CPSW2_STATS1_INFO(ale_da_eq_sa_drop)}, | 604 | {CPSW2_STATS1_INFO(ale_da_eq_sa_drop)}, |
532 | {CPSW2_STATS1_INFO(ale_block_drop)}, | 605 | {CPSW2_STATS1_INFO(ale_unknown_ucast)}, |
533 | {CPSW2_STATS1_INFO(ale_secure_drop)}, | 606 | {CPSW2_STATS1_INFO(ale_unknown_ucast_bytes)}, |
534 | {CPSW2_STATS1_INFO(ale_auth_drop)}, | 607 | {CPSW2_STATS1_INFO(ale_unknown_mcast)}, |
608 | {CPSW2_STATS1_INFO(ale_unknown_mcast_bytes)}, | ||
609 | {CPSW2_STATS1_INFO(ale_unknown_bcast)}, | ||
610 | {CPSW2_STATS1_INFO(ale_unknown_bcast_bytes)}, | ||
611 | {CPSW2_STATS1_INFO(ale_pol_match)}, | ||
612 | {CPSW2_STATS1_INFO(ale_pol_match_red)}, | ||
613 | {CPSW2_STATS1_INFO(ale_pol_match_yellow)}, | ||
614 | {CPSW2_STATS1_INFO(tx_mem_protect_err)}, | ||
615 | {CPSW2_STATS1_INFO(tx_pri0_drop)}, | ||
616 | {CPSW2_STATS1_INFO(tx_pri1_drop)}, | ||
617 | {CPSW2_STATS1_INFO(tx_pri2_drop)}, | ||
618 | {CPSW2_STATS1_INFO(tx_pri3_drop)}, | ||
619 | {CPSW2_STATS1_INFO(tx_pri4_drop)}, | ||
620 | {CPSW2_STATS1_INFO(tx_pri5_drop)}, | ||
621 | {CPSW2_STATS1_INFO(tx_pri6_drop)}, | ||
622 | {CPSW2_STATS1_INFO(tx_pri7_drop)}, | ||
623 | {CPSW2_STATS1_INFO(tx_pri0_drop_bcnt)}, | ||
624 | {CPSW2_STATS1_INFO(tx_pri1_drop_bcnt)}, | ||
625 | {CPSW2_STATS1_INFO(tx_pri2_drop_bcnt)}, | ||
626 | {CPSW2_STATS1_INFO(tx_pri3_drop_bcnt)}, | ||
627 | {CPSW2_STATS1_INFO(tx_pri4_drop_bcnt)}, | ||
628 | {CPSW2_STATS1_INFO(tx_pri5_drop_bcnt)}, | ||
629 | {CPSW2_STATS1_INFO(tx_pri6_drop_bcnt)}, | ||
630 | {CPSW2_STATS1_INFO(tx_pri7_drop_bcnt)}, | ||
535 | /* CPSW module 2 */ | 631 | /* CPSW module 2 */ |
536 | {CPSW2_STATS2_INFO(rx_good_frames)}, | 632 | {CPSW2_STATS2_INFO(rx_good_frames)}, |
537 | {CPSW2_STATS2_INFO(rx_broadcast_frames)}, | 633 | {CPSW2_STATS2_INFO(rx_broadcast_frames)}, |
@@ -572,9 +668,32 @@ static const struct netcp2_ethtool_stat et_stats[] = { | |||
572 | {CPSW2_STATS2_INFO(ale_rate_limit_drop)}, | 668 | {CPSW2_STATS2_INFO(ale_rate_limit_drop)}, |
573 | {CPSW2_STATS2_INFO(ale_vid_ingress_drop)}, | 669 | {CPSW2_STATS2_INFO(ale_vid_ingress_drop)}, |
574 | {CPSW2_STATS2_INFO(ale_da_eq_sa_drop)}, | 670 | {CPSW2_STATS2_INFO(ale_da_eq_sa_drop)}, |
575 | {CPSW2_STATS2_INFO(ale_block_drop)}, | 671 | {CPSW2_STATS2_INFO(ale_unknown_ucast)}, |
576 | {CPSW2_STATS2_INFO(ale_secure_drop)}, | 672 | {CPSW2_STATS2_INFO(ale_unknown_ucast_bytes)}, |
577 | {CPSW2_STATS2_INFO(ale_auth_drop)}, | 673 | {CPSW2_STATS2_INFO(ale_unknown_mcast)}, |
674 | {CPSW2_STATS2_INFO(ale_unknown_mcast_bytes)}, | ||
675 | {CPSW2_STATS2_INFO(ale_unknown_bcast)}, | ||
676 | {CPSW2_STATS2_INFO(ale_unknown_bcast_bytes)}, | ||
677 | {CPSW2_STATS2_INFO(ale_pol_match)}, | ||
678 | {CPSW2_STATS2_INFO(ale_pol_match_red)}, | ||
679 | {CPSW2_STATS2_INFO(ale_pol_match_yellow)}, | ||
680 | {CPSW2_STATS2_INFO(tx_mem_protect_err)}, | ||
681 | {CPSW2_STATS2_INFO(tx_pri0_drop)}, | ||
682 | {CPSW2_STATS2_INFO(tx_pri1_drop)}, | ||
683 | {CPSW2_STATS2_INFO(tx_pri2_drop)}, | ||
684 | {CPSW2_STATS2_INFO(tx_pri3_drop)}, | ||
685 | {CPSW2_STATS2_INFO(tx_pri4_drop)}, | ||
686 | {CPSW2_STATS2_INFO(tx_pri5_drop)}, | ||
687 | {CPSW2_STATS2_INFO(tx_pri6_drop)}, | ||
688 | {CPSW2_STATS2_INFO(tx_pri7_drop)}, | ||
689 | {CPSW2_STATS2_INFO(tx_pri0_drop_bcnt)}, | ||
690 | {CPSW2_STATS2_INFO(tx_pri1_drop_bcnt)}, | ||
691 | {CPSW2_STATS2_INFO(tx_pri2_drop_bcnt)}, | ||
692 | {CPSW2_STATS2_INFO(tx_pri3_drop_bcnt)}, | ||
693 | {CPSW2_STATS2_INFO(tx_pri4_drop_bcnt)}, | ||
694 | {CPSW2_STATS2_INFO(tx_pri5_drop_bcnt)}, | ||
695 | {CPSW2_STATS2_INFO(tx_pri6_drop_bcnt)}, | ||
696 | {CPSW2_STATS2_INFO(tx_pri7_drop_bcnt)}, | ||
578 | /* CPSW module 3 */ | 697 | /* CPSW module 3 */ |
579 | {CPSW2_STATS3_INFO(rx_good_frames)}, | 698 | {CPSW2_STATS3_INFO(rx_good_frames)}, |
580 | {CPSW2_STATS3_INFO(rx_broadcast_frames)}, | 699 | {CPSW2_STATS3_INFO(rx_broadcast_frames)}, |
@@ -615,9 +734,32 @@ static const struct netcp2_ethtool_stat et_stats[] = { | |||
615 | {CPSW2_STATS3_INFO(ale_rate_limit_drop)}, | 734 | {CPSW2_STATS3_INFO(ale_rate_limit_drop)}, |
616 | {CPSW2_STATS3_INFO(ale_vid_ingress_drop)}, | 735 | {CPSW2_STATS3_INFO(ale_vid_ingress_drop)}, |
617 | {CPSW2_STATS3_INFO(ale_da_eq_sa_drop)}, | 736 | {CPSW2_STATS3_INFO(ale_da_eq_sa_drop)}, |
618 | {CPSW2_STATS3_INFO(ale_block_drop)}, | 737 | {CPSW2_STATS3_INFO(ale_unknown_ucast)}, |
619 | {CPSW2_STATS3_INFO(ale_secure_drop)}, | 738 | {CPSW2_STATS3_INFO(ale_unknown_ucast_bytes)}, |
620 | {CPSW2_STATS3_INFO(ale_auth_drop)}, | 739 | {CPSW2_STATS3_INFO(ale_unknown_mcast)}, |
740 | {CPSW2_STATS3_INFO(ale_unknown_mcast_bytes)}, | ||
741 | {CPSW2_STATS3_INFO(ale_unknown_bcast)}, | ||
742 | {CPSW2_STATS3_INFO(ale_unknown_bcast_bytes)}, | ||
743 | {CPSW2_STATS3_INFO(ale_pol_match)}, | ||
744 | {CPSW2_STATS3_INFO(ale_pol_match_red)}, | ||
745 | {CPSW2_STATS3_INFO(ale_pol_match_yellow)}, | ||
746 | {CPSW2_STATS3_INFO(tx_mem_protect_err)}, | ||
747 | {CPSW2_STATS3_INFO(tx_pri0_drop)}, | ||
748 | {CPSW2_STATS3_INFO(tx_pri1_drop)}, | ||
749 | {CPSW2_STATS3_INFO(tx_pri2_drop)}, | ||
750 | {CPSW2_STATS3_INFO(tx_pri3_drop)}, | ||
751 | {CPSW2_STATS3_INFO(tx_pri4_drop)}, | ||
752 | {CPSW2_STATS3_INFO(tx_pri5_drop)}, | ||
753 | {CPSW2_STATS3_INFO(tx_pri6_drop)}, | ||
754 | {CPSW2_STATS3_INFO(tx_pri7_drop)}, | ||
755 | {CPSW2_STATS3_INFO(tx_pri0_drop_bcnt)}, | ||
756 | {CPSW2_STATS3_INFO(tx_pri1_drop_bcnt)}, | ||
757 | {CPSW2_STATS3_INFO(tx_pri2_drop_bcnt)}, | ||
758 | {CPSW2_STATS3_INFO(tx_pri3_drop_bcnt)}, | ||
759 | {CPSW2_STATS3_INFO(tx_pri4_drop_bcnt)}, | ||
760 | {CPSW2_STATS3_INFO(tx_pri5_drop_bcnt)}, | ||
761 | {CPSW2_STATS3_INFO(tx_pri6_drop_bcnt)}, | ||
762 | {CPSW2_STATS3_INFO(tx_pri7_drop_bcnt)}, | ||
621 | /* CPSW module 4 */ | 763 | /* CPSW module 4 */ |
622 | {CPSW2_STATS4_INFO(rx_good_frames)}, | 764 | {CPSW2_STATS4_INFO(rx_good_frames)}, |
623 | {CPSW2_STATS4_INFO(rx_broadcast_frames)}, | 765 | {CPSW2_STATS4_INFO(rx_broadcast_frames)}, |
@@ -658,9 +800,32 @@ static const struct netcp2_ethtool_stat et_stats[] = { | |||
658 | {CPSW2_STATS4_INFO(ale_rate_limit_drop)}, | 800 | {CPSW2_STATS4_INFO(ale_rate_limit_drop)}, |
659 | {CPSW2_STATS4_INFO(ale_vid_ingress_drop)}, | 801 | {CPSW2_STATS4_INFO(ale_vid_ingress_drop)}, |
660 | {CPSW2_STATS4_INFO(ale_da_eq_sa_drop)}, | 802 | {CPSW2_STATS4_INFO(ale_da_eq_sa_drop)}, |
661 | {CPSW2_STATS4_INFO(ale_block_drop)}, | 803 | {CPSW2_STATS4_INFO(ale_unknown_ucast)}, |
662 | {CPSW2_STATS4_INFO(ale_secure_drop)}, | 804 | {CPSW2_STATS4_INFO(ale_unknown_ucast_bytes)}, |
663 | {CPSW2_STATS4_INFO(ale_auth_drop)}, | 805 | {CPSW2_STATS4_INFO(ale_unknown_mcast)}, |
806 | {CPSW2_STATS4_INFO(ale_unknown_mcast_bytes)}, | ||
807 | {CPSW2_STATS4_INFO(ale_unknown_bcast)}, | ||
808 | {CPSW2_STATS4_INFO(ale_unknown_bcast_bytes)}, | ||
809 | {CPSW2_STATS4_INFO(ale_pol_match)}, | ||
810 | {CPSW2_STATS4_INFO(ale_pol_match_red)}, | ||
811 | {CPSW2_STATS4_INFO(ale_pol_match_yellow)}, | ||
812 | {CPSW2_STATS4_INFO(tx_mem_protect_err)}, | ||
813 | {CPSW2_STATS4_INFO(tx_pri0_drop)}, | ||
814 | {CPSW2_STATS4_INFO(tx_pri1_drop)}, | ||
815 | {CPSW2_STATS4_INFO(tx_pri2_drop)}, | ||
816 | {CPSW2_STATS4_INFO(tx_pri3_drop)}, | ||
817 | {CPSW2_STATS4_INFO(tx_pri4_drop)}, | ||
818 | {CPSW2_STATS4_INFO(tx_pri5_drop)}, | ||
819 | {CPSW2_STATS4_INFO(tx_pri6_drop)}, | ||
820 | {CPSW2_STATS4_INFO(tx_pri7_drop)}, | ||
821 | {CPSW2_STATS4_INFO(tx_pri0_drop_bcnt)}, | ||
822 | {CPSW2_STATS4_INFO(tx_pri1_drop_bcnt)}, | ||
823 | {CPSW2_STATS4_INFO(tx_pri2_drop_bcnt)}, | ||
824 | {CPSW2_STATS4_INFO(tx_pri3_drop_bcnt)}, | ||
825 | {CPSW2_STATS4_INFO(tx_pri4_drop_bcnt)}, | ||
826 | {CPSW2_STATS4_INFO(tx_pri5_drop_bcnt)}, | ||
827 | {CPSW2_STATS4_INFO(tx_pri6_drop_bcnt)}, | ||
828 | {CPSW2_STATS4_INFO(tx_pri7_drop_bcnt)}, | ||
664 | /* CPSW module 5 */ | 829 | /* CPSW module 5 */ |
665 | {CPSW2_STATS5_INFO(rx_good_frames)}, | 830 | {CPSW2_STATS5_INFO(rx_good_frames)}, |
666 | {CPSW2_STATS5_INFO(rx_broadcast_frames)}, | 831 | {CPSW2_STATS5_INFO(rx_broadcast_frames)}, |
@@ -701,9 +866,32 @@ static const struct netcp2_ethtool_stat et_stats[] = { | |||
701 | {CPSW2_STATS5_INFO(ale_rate_limit_drop)}, | 866 | {CPSW2_STATS5_INFO(ale_rate_limit_drop)}, |
702 | {CPSW2_STATS5_INFO(ale_vid_ingress_drop)}, | 867 | {CPSW2_STATS5_INFO(ale_vid_ingress_drop)}, |
703 | {CPSW2_STATS5_INFO(ale_da_eq_sa_drop)}, | 868 | {CPSW2_STATS5_INFO(ale_da_eq_sa_drop)}, |
704 | {CPSW2_STATS5_INFO(ale_block_drop)}, | 869 | {CPSW2_STATS5_INFO(ale_unknown_ucast)}, |
705 | {CPSW2_STATS5_INFO(ale_secure_drop)}, | 870 | {CPSW2_STATS5_INFO(ale_unknown_ucast_bytes)}, |
706 | {CPSW2_STATS5_INFO(ale_auth_drop)}, | 871 | {CPSW2_STATS5_INFO(ale_unknown_mcast)}, |
872 | {CPSW2_STATS5_INFO(ale_unknown_mcast_bytes)}, | ||
873 | {CPSW2_STATS5_INFO(ale_unknown_bcast)}, | ||
874 | {CPSW2_STATS5_INFO(ale_unknown_bcast_bytes)}, | ||
875 | {CPSW2_STATS5_INFO(ale_pol_match)}, | ||
876 | {CPSW2_STATS5_INFO(ale_pol_match_red)}, | ||
877 | {CPSW2_STATS5_INFO(ale_pol_match_yellow)}, | ||
878 | {CPSW2_STATS5_INFO(tx_mem_protect_err)}, | ||
879 | {CPSW2_STATS5_INFO(tx_pri0_drop)}, | ||
880 | {CPSW2_STATS5_INFO(tx_pri1_drop)}, | ||
881 | {CPSW2_STATS5_INFO(tx_pri2_drop)}, | ||
882 | {CPSW2_STATS5_INFO(tx_pri3_drop)}, | ||
883 | {CPSW2_STATS5_INFO(tx_pri4_drop)}, | ||
884 | {CPSW2_STATS5_INFO(tx_pri5_drop)}, | ||
885 | {CPSW2_STATS5_INFO(tx_pri6_drop)}, | ||
886 | {CPSW2_STATS5_INFO(tx_pri7_drop)}, | ||
887 | {CPSW2_STATS5_INFO(tx_pri0_drop_bcnt)}, | ||
888 | {CPSW2_STATS5_INFO(tx_pri1_drop_bcnt)}, | ||
889 | {CPSW2_STATS5_INFO(tx_pri2_drop_bcnt)}, | ||
890 | {CPSW2_STATS5_INFO(tx_pri3_drop_bcnt)}, | ||
891 | {CPSW2_STATS5_INFO(tx_pri4_drop_bcnt)}, | ||
892 | {CPSW2_STATS5_INFO(tx_pri5_drop_bcnt)}, | ||
893 | {CPSW2_STATS5_INFO(tx_pri6_drop_bcnt)}, | ||
894 | {CPSW2_STATS5_INFO(tx_pri7_drop_bcnt)}, | ||
707 | /* CPSW module 6 */ | 895 | /* CPSW module 6 */ |
708 | {CPSW2_STATS6_INFO(rx_good_frames)}, | 896 | {CPSW2_STATS6_INFO(rx_good_frames)}, |
709 | {CPSW2_STATS6_INFO(rx_broadcast_frames)}, | 897 | {CPSW2_STATS6_INFO(rx_broadcast_frames)}, |
@@ -744,9 +932,32 @@ static const struct netcp2_ethtool_stat et_stats[] = { | |||
744 | {CPSW2_STATS6_INFO(ale_rate_limit_drop)}, | 932 | {CPSW2_STATS6_INFO(ale_rate_limit_drop)}, |
745 | {CPSW2_STATS6_INFO(ale_vid_ingress_drop)}, | 933 | {CPSW2_STATS6_INFO(ale_vid_ingress_drop)}, |
746 | {CPSW2_STATS6_INFO(ale_da_eq_sa_drop)}, | 934 | {CPSW2_STATS6_INFO(ale_da_eq_sa_drop)}, |
747 | {CPSW2_STATS6_INFO(ale_block_drop)}, | 935 | {CPSW2_STATS6_INFO(ale_unknown_ucast)}, |
748 | {CPSW2_STATS6_INFO(ale_secure_drop)}, | 936 | {CPSW2_STATS6_INFO(ale_unknown_ucast_bytes)}, |
749 | {CPSW2_STATS6_INFO(ale_auth_drop)}, | 937 | {CPSW2_STATS6_INFO(ale_unknown_mcast)}, |
938 | {CPSW2_STATS6_INFO(ale_unknown_mcast_bytes)}, | ||
939 | {CPSW2_STATS6_INFO(ale_unknown_bcast)}, | ||
940 | {CPSW2_STATS6_INFO(ale_unknown_bcast_bytes)}, | ||
941 | {CPSW2_STATS6_INFO(ale_pol_match)}, | ||
942 | {CPSW2_STATS6_INFO(ale_pol_match_red)}, | ||
943 | {CPSW2_STATS6_INFO(ale_pol_match_yellow)}, | ||
944 | {CPSW2_STATS6_INFO(tx_mem_protect_err)}, | ||
945 | {CPSW2_STATS6_INFO(tx_pri0_drop)}, | ||
946 | {CPSW2_STATS6_INFO(tx_pri1_drop)}, | ||
947 | {CPSW2_STATS6_INFO(tx_pri2_drop)}, | ||
948 | {CPSW2_STATS6_INFO(tx_pri3_drop)}, | ||
949 | {CPSW2_STATS6_INFO(tx_pri4_drop)}, | ||
950 | {CPSW2_STATS6_INFO(tx_pri5_drop)}, | ||
951 | {CPSW2_STATS6_INFO(tx_pri6_drop)}, | ||
952 | {CPSW2_STATS6_INFO(tx_pri7_drop)}, | ||
953 | {CPSW2_STATS6_INFO(tx_pri0_drop_bcnt)}, | ||
954 | {CPSW2_STATS6_INFO(tx_pri1_drop_bcnt)}, | ||
955 | {CPSW2_STATS6_INFO(tx_pri2_drop_bcnt)}, | ||
956 | {CPSW2_STATS6_INFO(tx_pri3_drop_bcnt)}, | ||
957 | {CPSW2_STATS6_INFO(tx_pri4_drop_bcnt)}, | ||
958 | {CPSW2_STATS6_INFO(tx_pri5_drop_bcnt)}, | ||
959 | {CPSW2_STATS6_INFO(tx_pri6_drop_bcnt)}, | ||
960 | {CPSW2_STATS6_INFO(tx_pri7_drop_bcnt)}, | ||
750 | /* CPSW module 7 */ | 961 | /* CPSW module 7 */ |
751 | {CPSW2_STATS7_INFO(rx_good_frames)}, | 962 | {CPSW2_STATS7_INFO(rx_good_frames)}, |
752 | {CPSW2_STATS7_INFO(rx_broadcast_frames)}, | 963 | {CPSW2_STATS7_INFO(rx_broadcast_frames)}, |
@@ -787,9 +998,32 @@ static const struct netcp2_ethtool_stat et_stats[] = { | |||
787 | {CPSW2_STATS7_INFO(ale_rate_limit_drop)}, | 998 | {CPSW2_STATS7_INFO(ale_rate_limit_drop)}, |
788 | {CPSW2_STATS7_INFO(ale_vid_ingress_drop)}, | 999 | {CPSW2_STATS7_INFO(ale_vid_ingress_drop)}, |
789 | {CPSW2_STATS7_INFO(ale_da_eq_sa_drop)}, | 1000 | {CPSW2_STATS7_INFO(ale_da_eq_sa_drop)}, |
790 | {CPSW2_STATS7_INFO(ale_block_drop)}, | 1001 | {CPSW2_STATS7_INFO(ale_unknown_ucast)}, |
791 | {CPSW2_STATS7_INFO(ale_secure_drop)}, | 1002 | {CPSW2_STATS7_INFO(ale_unknown_ucast_bytes)}, |
792 | {CPSW2_STATS7_INFO(ale_auth_drop)}, | 1003 | {CPSW2_STATS7_INFO(ale_unknown_mcast)}, |
1004 | {CPSW2_STATS7_INFO(ale_unknown_mcast_bytes)}, | ||
1005 | {CPSW2_STATS7_INFO(ale_unknown_bcast)}, | ||
1006 | {CPSW2_STATS7_INFO(ale_unknown_bcast_bytes)}, | ||
1007 | {CPSW2_STATS7_INFO(ale_pol_match)}, | ||
1008 | {CPSW2_STATS7_INFO(ale_pol_match_red)}, | ||
1009 | {CPSW2_STATS7_INFO(ale_pol_match_yellow)}, | ||
1010 | {CPSW2_STATS7_INFO(tx_mem_protect_err)}, | ||
1011 | {CPSW2_STATS7_INFO(tx_pri0_drop)}, | ||
1012 | {CPSW2_STATS7_INFO(tx_pri1_drop)}, | ||
1013 | {CPSW2_STATS7_INFO(tx_pri2_drop)}, | ||
1014 | {CPSW2_STATS7_INFO(tx_pri3_drop)}, | ||
1015 | {CPSW2_STATS7_INFO(tx_pri4_drop)}, | ||
1016 | {CPSW2_STATS7_INFO(tx_pri5_drop)}, | ||
1017 | {CPSW2_STATS7_INFO(tx_pri6_drop)}, | ||
1018 | {CPSW2_STATS7_INFO(tx_pri7_drop)}, | ||
1019 | {CPSW2_STATS7_INFO(tx_pri0_drop_bcnt)}, | ||
1020 | {CPSW2_STATS7_INFO(tx_pri1_drop_bcnt)}, | ||
1021 | {CPSW2_STATS7_INFO(tx_pri2_drop_bcnt)}, | ||
1022 | {CPSW2_STATS7_INFO(tx_pri3_drop_bcnt)}, | ||
1023 | {CPSW2_STATS7_INFO(tx_pri4_drop_bcnt)}, | ||
1024 | {CPSW2_STATS7_INFO(tx_pri5_drop_bcnt)}, | ||
1025 | {CPSW2_STATS7_INFO(tx_pri6_drop_bcnt)}, | ||
1026 | {CPSW2_STATS7_INFO(tx_pri7_drop_bcnt)}, | ||
793 | /* CPSW module 8 */ | 1027 | /* CPSW module 8 */ |
794 | {CPSW2_STATS8_INFO(rx_good_frames)}, | 1028 | {CPSW2_STATS8_INFO(rx_good_frames)}, |
795 | {CPSW2_STATS8_INFO(rx_broadcast_frames)}, | 1029 | {CPSW2_STATS8_INFO(rx_broadcast_frames)}, |
@@ -830,9 +1064,32 @@ static const struct netcp2_ethtool_stat et_stats[] = { | |||
830 | {CPSW2_STATS8_INFO(ale_rate_limit_drop)}, | 1064 | {CPSW2_STATS8_INFO(ale_rate_limit_drop)}, |
831 | {CPSW2_STATS8_INFO(ale_vid_ingress_drop)}, | 1065 | {CPSW2_STATS8_INFO(ale_vid_ingress_drop)}, |
832 | {CPSW2_STATS8_INFO(ale_da_eq_sa_drop)}, | 1066 | {CPSW2_STATS8_INFO(ale_da_eq_sa_drop)}, |
833 | {CPSW2_STATS8_INFO(ale_block_drop)}, | 1067 | {CPSW2_STATS8_INFO(ale_unknown_ucast)}, |
834 | {CPSW2_STATS8_INFO(ale_secure_drop)}, | 1068 | {CPSW2_STATS8_INFO(ale_unknown_ucast_bytes)}, |
835 | {CPSW2_STATS8_INFO(ale_auth_drop)}, | 1069 | {CPSW2_STATS8_INFO(ale_unknown_mcast)}, |
1070 | {CPSW2_STATS8_INFO(ale_unknown_mcast_bytes)}, | ||
1071 | {CPSW2_STATS8_INFO(ale_unknown_bcast)}, | ||
1072 | {CPSW2_STATS8_INFO(ale_unknown_bcast_bytes)}, | ||
1073 | {CPSW2_STATS8_INFO(ale_pol_match)}, | ||
1074 | {CPSW2_STATS8_INFO(ale_pol_match_red)}, | ||
1075 | {CPSW2_STATS8_INFO(ale_pol_match_yellow)}, | ||
1076 | {CPSW2_STATS8_INFO(tx_mem_protect_err)}, | ||
1077 | {CPSW2_STATS8_INFO(tx_pri0_drop)}, | ||
1078 | {CPSW2_STATS8_INFO(tx_pri1_drop)}, | ||
1079 | {CPSW2_STATS8_INFO(tx_pri2_drop)}, | ||
1080 | {CPSW2_STATS8_INFO(tx_pri3_drop)}, | ||
1081 | {CPSW2_STATS8_INFO(tx_pri4_drop)}, | ||
1082 | {CPSW2_STATS8_INFO(tx_pri5_drop)}, | ||
1083 | {CPSW2_STATS8_INFO(tx_pri6_drop)}, | ||
1084 | {CPSW2_STATS8_INFO(tx_pri7_drop)}, | ||
1085 | {CPSW2_STATS8_INFO(tx_pri0_drop_bcnt)}, | ||
1086 | {CPSW2_STATS8_INFO(tx_pri1_drop_bcnt)}, | ||
1087 | {CPSW2_STATS8_INFO(tx_pri2_drop_bcnt)}, | ||
1088 | {CPSW2_STATS8_INFO(tx_pri3_drop_bcnt)}, | ||
1089 | {CPSW2_STATS8_INFO(tx_pri4_drop_bcnt)}, | ||
1090 | {CPSW2_STATS8_INFO(tx_pri5_drop_bcnt)}, | ||
1091 | {CPSW2_STATS8_INFO(tx_pri6_drop_bcnt)}, | ||
1092 | {CPSW2_STATS8_INFO(tx_pri7_drop_bcnt)}, | ||
836 | }; | 1093 | }; |
837 | 1094 | ||
838 | #define ETHTOOL_PORT_STATS_NUM (ARRAY_SIZE(et_stats)/CPSW2_NUM_PORTS) | 1095 | #define ETHTOOL_PORT_STATS_NUM (ARRAY_SIZE(et_stats)/CPSW2_NUM_PORTS) |
@@ -895,8 +1152,11 @@ struct cpsw2_priv { | |||
895 | u32 num_serdes; | 1152 | u32 num_serdes; |
896 | u32 serdes_lanes; | 1153 | u32 serdes_lanes; |
897 | struct serdes serdes; | 1154 | struct serdes serdes; |
1155 | u32 opened; | ||
898 | }; | 1156 | }; |
899 | 1157 | ||
1158 | /* slave_port: 0-based (currently relevant only in multi_if mode) | ||
1159 | */ | ||
900 | struct cpsw2_intf { | 1160 | struct cpsw2_intf { |
901 | struct net_device *ndev; | 1161 | struct net_device *ndev; |
902 | struct device *dev; | 1162 | struct device *dev; |
@@ -912,7 +1172,7 @@ struct cpsw2_intf { | |||
912 | u32 multi_if; | 1172 | u32 multi_if; |
913 | struct list_head cpsw_intf_list; | 1173 | struct list_head cpsw_intf_list; |
914 | struct timer_list timer; | 1174 | struct timer_list timer; |
915 | u32 sgmii_link; | 1175 | u32 link_state; |
916 | }; | 1176 | }; |
917 | 1177 | ||
918 | struct cpsw2_attribute { | 1178 | struct cpsw2_attribute { |
@@ -2484,8 +2744,7 @@ static void _cpsw2_adjust_link(struct cpsw2_slave *slave, bool *link) | |||
2484 | 2744 | ||
2485 | if (phy->link) { | 2745 | if (phy->link) { |
2486 | mac_control = slave->mac_control; | 2746 | mac_control = slave->mac_control; |
2487 | mac_control |= MACSL_ENABLE | MACSL_RX_ENABLE_EXT_CTL | | 2747 | mac_control |= MACSL_DEFAULT_CONFIG; |
2488 | MACSL_RX_ENABLE_CSF; | ||
2489 | /* enable forwarding */ | 2748 | /* enable forwarding */ |
2490 | cpsw_ale_control_set(slave->ale, slave_port, | 2749 | cpsw_ale_control_set(slave->ale, slave_port, |
2491 | ALE_PORT_STATE, ALE_PORT_STATE_FORWARD); | 2750 | ALE_PORT_STATE, ALE_PORT_STATE_FORWARD); |
@@ -2520,9 +2779,9 @@ static void cpsw2_adjust_link(struct net_device *n_dev, void *context) | |||
2520 | _cpsw2_adjust_link(slave, &link); | 2779 | _cpsw2_adjust_link(slave, &link); |
2521 | 2780 | ||
2522 | if (link) | 2781 | if (link) |
2523 | netcp->link_state |= BIT(slave->slave_num); | 2782 | netcp->phy_link_state_mask |= BIT(slave->slave_num); |
2524 | else | 2783 | else |
2525 | netcp->link_state &= ~BIT(slave->slave_num); | 2784 | netcp->phy_link_state_mask &= ~BIT(slave->slave_num); |
2526 | } | 2785 | } |
2527 | 2786 | ||
2528 | /* | 2787 | /* |
@@ -2555,10 +2814,10 @@ static void cpsw2_port_config(struct cpsw2_slave *slave, int max_rx_len) | |||
2555 | if (max_rx_len > MAX_SIZE_STREAM_BUFFER) | 2814 | if (max_rx_len > MAX_SIZE_STREAM_BUFFER) |
2556 | max_rx_len = MAX_SIZE_STREAM_BUFFER; | 2815 | max_rx_len = MAX_SIZE_STREAM_BUFFER; |
2557 | 2816 | ||
2558 | writel(max_rx_len, &slave->regs->rx_maxlen); | 2817 | slave->mac_control = MACSL_DEFAULT_CONFIG; |
2559 | 2818 | ||
2560 | writel(MACSL_ENABLE | MACSL_RX_ENABLE_EXT_CTL | MACSL_RX_ENABLE_CSF, | 2819 | writel(max_rx_len, &slave->regs->rx_maxlen); |
2561 | &slave->regs->mac_control); | 2820 | writel(slave->mac_control, &slave->regs->mac_control); |
2562 | } | 2821 | } |
2563 | 2822 | ||
2564 | static void cpsw2_slave_stop(struct cpsw2_slave *slave, | 2823 | static void cpsw2_slave_stop(struct cpsw2_slave *slave, |
@@ -2588,12 +2847,14 @@ static void cpsw2_slave_link(struct cpsw2_slave *slave, | |||
2588 | struct cpsw2_intf *cpsw_intf) | 2847 | struct cpsw2_intf *cpsw_intf) |
2589 | { | 2848 | { |
2590 | struct netcp_priv *netcp = netdev_priv(cpsw_intf->ndev); | 2849 | struct netcp_priv *netcp = netdev_priv(cpsw_intf->ndev); |
2850 | int sn = slave->slave_num; | ||
2591 | 2851 | ||
2592 | if (slave->link_interface == SGMII_LINK_MAC_PHY) { | 2852 | if (IS_SGMII_MAC_PHY(slave->link_interface)) { |
2593 | if (netcp->link_state) | 2853 | /* check only the bit in phy_link_state_mask |
2594 | cpsw_intf->sgmii_link |= BIT(slave->slave_num); | 2854 | * that corresponds to the slave |
2595 | else | 2855 | */ |
2596 | cpsw_intf->sgmii_link &= ~BIT(slave->slave_num); | 2856 | if (!(netcp->phy_link_state_mask & BIT(sn))) |
2857 | cpsw_intf->link_state &= ~BIT(sn); | ||
2597 | } | 2858 | } |
2598 | } | 2859 | } |
2599 | 2860 | ||
@@ -2617,9 +2878,6 @@ static void cpsw2_slave_open(struct cpsw2_slave *slave, | |||
2617 | 2878 | ||
2618 | cpsw2_set_slave_mac(slave, cpsw_intf); | 2879 | cpsw2_set_slave_mac(slave, cpsw_intf); |
2619 | 2880 | ||
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 */ | 2881 | /* this slave port here is 1 based */ |
2624 | slave_port = cpsw2_get_slave_port(cpsw_dev, slave->slave_num); | 2882 | slave_port = cpsw2_get_slave_port(cpsw_dev, slave->slave_num); |
2625 | 2883 | ||
@@ -2634,7 +2892,7 @@ static void cpsw2_slave_open(struct cpsw2_slave *slave, | |||
2634 | cpsw_ale_add_mcast(cpsw_dev->ale, cpsw_intf->ndev->broadcast, | 2892 | cpsw_ale_add_mcast(cpsw_dev->ale, cpsw_intf->ndev->broadcast, |
2635 | 1 << slave_port, 0, 0, ALE_MCAST_FWD_2); | 2893 | 1 << slave_port, 0, 0, ALE_MCAST_FWD_2); |
2636 | 2894 | ||
2637 | if (slave->link_interface == SGMII_LINK_MAC_PHY) { | 2895 | if (IS_SGMII_MAC_PHY(slave->link_interface)) { |
2638 | slave->phy = of_phy_connect(cpsw_intf->ndev, | 2896 | slave->phy = of_phy_connect(cpsw_intf->ndev, |
2639 | cpsw_intf->phy_node, | 2897 | cpsw_intf->phy_node, |
2640 | &cpsw2_adjust_link, 0, | 2898 | &cpsw2_adjust_link, 0, |
@@ -2756,6 +3014,9 @@ static int cpsw2_add_addr(void *intf_priv, struct netcp_addr *naddr) | |||
2756 | struct cpsw2_intf *cpsw_intf = intf_priv; | 3014 | struct cpsw2_intf *cpsw_intf = intf_priv; |
2757 | struct cpsw2_priv *cpsw_dev = cpsw_intf->cpsw_priv; | 3015 | struct cpsw2_priv *cpsw_dev = cpsw_intf->cpsw_priv; |
2758 | 3016 | ||
3017 | if (!cpsw_dev->opened) | ||
3018 | return -ENXIO; | ||
3019 | |||
2759 | dev_dbg(cpsw_dev->dev, "ethss adding address %pM, type %d\n", | 3020 | dev_dbg(cpsw_dev->dev, "ethss adding address %pM, type %d\n", |
2760 | naddr->addr, naddr->type); | 3021 | naddr->addr, naddr->type); |
2761 | 3022 | ||
@@ -2782,6 +3043,9 @@ static int cpsw2_del_addr(void *intf_priv, struct netcp_addr *naddr) | |||
2782 | struct cpsw2_intf *cpsw_intf = intf_priv; | 3043 | struct cpsw2_intf *cpsw_intf = intf_priv; |
2783 | struct cpsw2_priv *cpsw_dev = cpsw_intf->cpsw_priv; | 3044 | struct cpsw2_priv *cpsw_dev = cpsw_intf->cpsw_priv; |
2784 | 3045 | ||
3046 | if (!cpsw_dev->opened) | ||
3047 | return -ENXIO; | ||
3048 | |||
2785 | dev_dbg(cpsw_dev->dev, "ethss deleting address %pM, type %d\n", | 3049 | dev_dbg(cpsw_dev->dev, "ethss deleting address %pM, type %d\n", |
2786 | naddr->addr, naddr->type); | 3050 | naddr->addr, naddr->type); |
2787 | 3051 | ||
@@ -3002,10 +3266,10 @@ static void cpsw2_timer(unsigned long arg) | |||
3002 | struct cpsw2_priv *cpsw_dev = cpsw_intf->cpsw_priv; | 3266 | struct cpsw2_priv *cpsw_dev = cpsw_intf->cpsw_priv; |
3003 | u32 sp = cpsw_intf->slave_port; | 3267 | u32 sp = cpsw_intf->slave_port; |
3004 | u32 ns = cpsw_intf->num_slaves; | 3268 | u32 ns = cpsw_intf->num_slaves; |
3005 | u32 sgmii_link; | 3269 | u32 link_state; |
3006 | 3270 | ||
3007 | if (cpsw_dev->multi_if) | 3271 | if (cpsw_dev->multi_if) |
3008 | sgmii_link = keystone_sgmii_get_port_link(SGMII2_BASE(sp), sp); | 3272 | link_state = keystone_sgmii_get_port_link(SGMII2_BASE(sp), sp); |
3009 | else { | 3273 | else { |
3010 | /* Single interface mode. Link is up if any one slave | 3274 | /* Single interface mode. Link is up if any one slave |
3011 | * port is up. It assumes slave port always starts from | 3275 | * port is up. It assumes slave port always starts from |
@@ -3013,27 +3277,35 @@ static void cpsw2_timer(unsigned long arg) | |||
3013 | */ | 3277 | */ |
3014 | 3278 | ||
3015 | /* slave port (port > 2) status */ | 3279 | /* slave port (port > 2) status */ |
3016 | sgmii_link = keystone_sgmii_link_status(SGMII2_BASE(2), | 3280 | link_state = keystone_sgmii_link_status(SGMII2_BASE(2), |
3017 | max_t(u32, ns, 2) - 2); | 3281 | max_t(u32, ns, 2) - 2); |
3018 | 3282 | ||
3019 | sgmii_link <<= 2; | 3283 | link_state <<= 2; |
3020 | 3284 | ||
3021 | /* slave port 0, 1 status */ | 3285 | /* slave port 0, 1 status */ |
3022 | sgmii_link |= keystone_sgmii_link_status(SGMII2_BASE(0), | 3286 | link_state |= keystone_sgmii_link_status(SGMII2_BASE(0), |
3023 | min_t(u32, ns, 2)); | 3287 | min_t(u32, ns, 2)); |
3024 | } | 3288 | } |
3025 | cpsw_intf->sgmii_link = sgmii_link; | 3289 | cpsw_intf->link_state = link_state; |
3026 | 3290 | ||
3291 | /* if MAC-to-PHY, check phy link status also | ||
3292 | * to conclude the intf link's status | ||
3293 | */ | ||
3027 | for_each_slave(cpsw_intf, cpsw2_slave_link, cpsw_intf); | 3294 | for_each_slave(cpsw_intf, cpsw2_slave_link, cpsw_intf); |
3028 | 3295 | ||
3029 | /* FIXME: Don't aggregate link statuses in multi-interface case */ | 3296 | /* Is this the right logic? |
3030 | if (cpsw_intf->sgmii_link) { | 3297 | * multi_if & MAC_PHY: phy state machine already reported carrier |
3031 | /* link ON */ | 3298 | * multi_if & !MAC_PHY: report carrier |
3032 | if (!netif_carrier_ok(cpsw_intf->ndev)) | 3299 | * !multi_if: any one slave up means intf is up, reporting carrier |
3300 | * here corrects what phy state machine (if it exists) | ||
3301 | * might have reported. | ||
3302 | */ | ||
3303 | if (!cpsw_dev->multi_if || | ||
3304 | (cpsw_dev->multi_if && | ||
3305 | !IS_SGMII_MAC_PHY(cpsw_intf->slaves->link_interface))) { | ||
3306 | if (cpsw_intf->link_state) | ||
3033 | netif_carrier_on(cpsw_intf->ndev); | 3307 | netif_carrier_on(cpsw_intf->ndev); |
3034 | } else { | 3308 | else |
3035 | /* link OFF */ | ||
3036 | if (netif_carrier_ok(cpsw_intf->ndev)) | ||
3037 | netif_carrier_off(cpsw_intf->ndev); | 3309 | netif_carrier_off(cpsw_intf->ndev); |
3038 | } | 3310 | } |
3039 | 3311 | ||
@@ -3439,6 +3711,7 @@ static int cpsw2_open(void *intf_priv, struct net_device *ndev) | |||
3439 | PSTREAM_ROUTE_GLOBAL_DMA); | 3711 | PSTREAM_ROUTE_GLOBAL_DMA); |
3440 | 3712 | ||
3441 | cpsw2_register_cpts(cpsw_dev); | 3713 | cpsw2_register_cpts(cpsw_dev); |
3714 | cpsw_dev->opened = 1; | ||
3442 | return 0; | 3715 | return 0; |
3443 | 3716 | ||
3444 | ale_fail: | 3717 | ale_fail: |
@@ -3478,6 +3751,7 @@ static int cpsw2_close(void *intf_priv, struct net_device *ndev) | |||
3478 | clk_put(cpsw_dev->cpgmac); | 3751 | clk_put(cpsw_dev->cpgmac); |
3479 | 3752 | ||
3480 | cpsw2_unregister_cpts(cpsw_dev); | 3753 | cpsw2_unregister_cpts(cpsw_dev); |
3754 | cpsw_dev->opened = 0; | ||
3481 | return 0; | 3755 | return 0; |
3482 | } | 3756 | } |
3483 | 3757 | ||
diff --git a/drivers/net/ethernet/ti/keystone_net.h b/drivers/net/ethernet/ti/keystone_net.h index 050b7e81260..c6f62687da8 100644 --- a/drivers/net/ethernet/ti/keystone_net.h +++ b/drivers/net/ethernet/ti/keystone_net.h | |||
@@ -34,6 +34,9 @@ | |||
34 | #define SGMII_LINK_MAC_MAC_FORCED 2 | 34 | #define SGMII_LINK_MAC_MAC_FORCED 2 |
35 | #define SGMII_LINK_MAC_FIBER 3 | 35 | #define SGMII_LINK_MAC_FIBER 3 |
36 | #define SGMII_LINK_MAC_PHY_NO_MDIO 4 | 36 | #define SGMII_LINK_MAC_PHY_NO_MDIO 4 |
37 | #define SGMII_LINK_MAC_PHY_MASTER 5 | ||
38 | #define SGMII_LINK_MAC_PHY_MASTER_NO_MDIO 6 | ||
39 | #define SGMII_LINK_MAC_MAC_AN_SLAVE 7 | ||
37 | #define XGMII_LINK_MAC_PHY 10 | 40 | #define XGMII_LINK_MAC_PHY 10 |
38 | #define XGMII_LINK_MAC_MAC_FORCED 11 | 41 | #define XGMII_LINK_MAC_MAC_FORCED 11 |
39 | 42 | ||
@@ -131,7 +134,7 @@ struct netcp_priv { | |||
131 | spinlock_t lock; | 134 | spinlock_t lock; |
132 | int rx_packet_max; | 135 | int rx_packet_max; |
133 | const char *rx_chan_name; | 136 | const char *rx_chan_name; |
134 | u32 link_state; | 137 | u32 phy_link_state_mask; |
135 | struct list_head module_head; | 138 | struct list_head module_head; |
136 | struct list_head interface_list; | 139 | struct list_head interface_list; |
137 | struct list_head addr_list; | 140 | struct list_head addr_list; |
diff --git a/drivers/net/ethernet/ti/keystone_net_core.c b/drivers/net/ethernet/ti/keystone_net_core.c index ae5098aa09c..4d53d59ef8a 100644 --- a/drivers/net/ethernet/ti/keystone_net_core.c +++ b/drivers/net/ethernet/ti/keystone_net_core.c | |||
@@ -1464,65 +1464,85 @@ static void netcp_addr_clear_mark(struct netcp_priv *netcp) | |||
1464 | naddr->flags = 0; | 1464 | naddr->flags = 0; |
1465 | } | 1465 | } |
1466 | 1466 | ||
1467 | static void netcp_addr_add_mark(struct netcp_priv *netcp, const u8 *addr, | 1467 | static struct netcp_addr * |
1468 | enum netcp_addr_type type) | 1468 | netcp_addr_add_mark(struct netcp_priv *netcp, const u8 *addr, |
1469 | enum netcp_addr_type type) | ||
1469 | { | 1470 | { |
1470 | struct netcp_addr *naddr; | 1471 | struct netcp_addr *naddr; |
1471 | 1472 | ||
1472 | naddr = netcp_addr_find(netcp, addr, type); | 1473 | naddr = netcp_addr_find(netcp, addr, type); |
1473 | if (naddr) { | 1474 | if (naddr) { |
1474 | naddr->flags |= ADDR_VALID; | 1475 | naddr->flags |= ADDR_VALID; |
1475 | return; | 1476 | return naddr; |
1476 | } | 1477 | } |
1477 | 1478 | ||
1478 | naddr = netcp_addr_add(netcp, addr, type); | 1479 | naddr = netcp_addr_add(netcp, addr, type); |
1479 | if (!WARN_ON(!naddr)) | 1480 | if (!WARN_ON(!naddr)) |
1480 | naddr->flags |= ADDR_NEW; | 1481 | naddr->flags |= ADDR_NEW; |
1482 | |||
1483 | return naddr; | ||
1481 | } | 1484 | } |
1482 | 1485 | ||
1483 | static void netcp_addr_sweep_del(struct netcp_priv *netcp) | 1486 | static void netcp_mod_del_addr(struct netcp_priv *netcp, |
1487 | struct netcp_addr *naddr) | ||
1484 | { | 1488 | { |
1485 | struct netcp_addr *naddr, *tmp; | ||
1486 | struct netcp_intf_modpriv *priv; | 1489 | struct netcp_intf_modpriv *priv; |
1487 | struct netcp_module *module; | 1490 | struct netcp_module *module; |
1488 | int error; | 1491 | |
1492 | dev_dbg(netcp->dev, "deleting address %pM, type %x\n", | ||
1493 | naddr->addr, naddr->type); | ||
1494 | for_each_module(netcp, priv) { | ||
1495 | module = priv->netcp_module; | ||
1496 | if (!module->del_addr) | ||
1497 | continue; | ||
1498 | module->del_addr(priv->module_priv, naddr); | ||
1499 | } | ||
1500 | } | ||
1501 | |||
1502 | static void netcp_addr_sweep_del(struct netcp_priv *netcp) | ||
1503 | { | ||
1504 | struct netcp_addr *naddr, *tmp; | ||
1489 | 1505 | ||
1490 | list_for_each_entry_safe(naddr, tmp, &netcp->addr_list, node) { | 1506 | list_for_each_entry_safe(naddr, tmp, &netcp->addr_list, node) { |
1491 | if (naddr->flags & (ADDR_VALID | ADDR_NEW)) | 1507 | if (naddr->flags & (ADDR_VALID | ADDR_NEW)) |
1492 | continue; | 1508 | continue; |
1493 | dev_dbg(netcp->dev, "deleting address %pM, type %x\n", | 1509 | netcp_mod_del_addr(netcp, naddr); |
1494 | naddr->addr, naddr->type); | ||
1495 | for_each_module(netcp, priv) { | ||
1496 | module = priv->netcp_module; | ||
1497 | if (!module->del_addr) | ||
1498 | continue; | ||
1499 | error = module->del_addr(priv->module_priv, | ||
1500 | naddr); | ||
1501 | WARN_ON(error); | ||
1502 | } | ||
1503 | netcp_addr_del(naddr); | 1510 | netcp_addr_del(naddr); |
1504 | } | 1511 | } |
1505 | } | 1512 | } |
1506 | 1513 | ||
1507 | static void netcp_addr_sweep_add(struct netcp_priv *netcp) | 1514 | static int netcp_mod_add_addr(struct netcp_priv *netcp, |
1515 | struct netcp_addr *naddr) | ||
1508 | { | 1516 | { |
1509 | struct netcp_addr *naddr, *tmp; | ||
1510 | struct netcp_intf_modpriv *priv; | 1517 | struct netcp_intf_modpriv *priv; |
1511 | struct netcp_module *module; | 1518 | struct netcp_module *module; |
1512 | int error; | 1519 | int error; |
1513 | 1520 | ||
1521 | dev_dbg(netcp->dev, "adding address %pM, type %x\n", | ||
1522 | naddr->addr, naddr->type); | ||
1523 | for_each_module(netcp, priv) { | ||
1524 | module = priv->netcp_module; | ||
1525 | if (!module->add_addr) | ||
1526 | continue; | ||
1527 | error = module->add_addr(priv->module_priv, naddr); | ||
1528 | if (error) | ||
1529 | break; | ||
1530 | } | ||
1531 | |||
1532 | if (error) | ||
1533 | netcp_mod_del_addr(netcp, naddr); | ||
1534 | |||
1535 | return error; | ||
1536 | } | ||
1537 | |||
1538 | static void netcp_addr_sweep_add(struct netcp_priv *netcp) | ||
1539 | { | ||
1540 | struct netcp_addr *naddr, *tmp; | ||
1541 | |||
1514 | list_for_each_entry_safe(naddr, tmp, &netcp->addr_list, node) { | 1542 | list_for_each_entry_safe(naddr, tmp, &netcp->addr_list, node) { |
1515 | if (!(naddr->flags & ADDR_NEW)) | 1543 | if (!(naddr->flags & ADDR_NEW)) |
1516 | continue; | 1544 | continue; |
1517 | dev_dbg(netcp->dev, "adding address %pM, type %x\n", | 1545 | netcp_mod_add_addr(netcp, naddr); |
1518 | naddr->addr, naddr->type); | ||
1519 | for_each_module(netcp, priv) { | ||
1520 | module = priv->netcp_module; | ||
1521 | if (!module->add_addr) | ||
1522 | continue; | ||
1523 | error = module->add_addr(priv->module_priv, naddr); | ||
1524 | WARN_ON(error); | ||
1525 | } | ||
1526 | } | 1546 | } |
1527 | } | 1547 | } |
1528 | 1548 | ||
@@ -1772,6 +1792,38 @@ static int netcp_ndo_change_mtu(struct net_device *ndev, int new_mtu) | |||
1772 | return 0; | 1792 | return 0; |
1773 | } | 1793 | } |
1774 | 1794 | ||
1795 | static int netcp_ndo_set_mac_address(struct net_device *ndev, void *p) | ||
1796 | { | ||
1797 | struct netcp_priv *netcp = netdev_priv(ndev); | ||
1798 | struct netcp_addr *naddr; | ||
1799 | int ret; | ||
1800 | |||
1801 | ret = eth_mac_addr(ndev, p); | ||
1802 | if (ret) { | ||
1803 | dev_info(netcp->dev, "set mac addr %pM failed (%d).\n", | ||
1804 | ((struct sockaddr *)p)->sa_data, ret); | ||
1805 | goto done; | ||
1806 | } | ||
1807 | |||
1808 | naddr = netcp_addr_add_mark(netcp, ndev->dev_addr, ADDR_DEV); | ||
1809 | if (!naddr) { | ||
1810 | ret = -ENOMEM; | ||
1811 | goto done; | ||
1812 | } | ||
1813 | if (naddr->flags & ADDR_VALID) | ||
1814 | goto done; | ||
1815 | |||
1816 | ret = netcp_mod_add_addr(netcp, naddr); | ||
1817 | if (ret) { | ||
1818 | /* lower modules are not ready yet */ | ||
1819 | netcp_addr_del(naddr); | ||
1820 | ret = 0; | ||
1821 | } | ||
1822 | |||
1823 | done: | ||
1824 | return ret; | ||
1825 | } | ||
1826 | |||
1775 | static void netcp_ndo_tx_timeout(struct net_device *ndev) | 1827 | static void netcp_ndo_tx_timeout(struct net_device *ndev) |
1776 | { | 1828 | { |
1777 | struct netcp_priv *netcp = netdev_priv(ndev); | 1829 | struct netcp_priv *netcp = netdev_priv(ndev); |
@@ -1948,7 +2000,7 @@ static const struct net_device_ops netcp_netdev_ops = { | |||
1948 | .ndo_do_ioctl = netcp_ndo_ioctl, | 2000 | .ndo_do_ioctl = netcp_ndo_ioctl, |
1949 | .ndo_get_stats64 = netcp_get_stats, | 2001 | .ndo_get_stats64 = netcp_get_stats, |
1950 | .ndo_change_mtu = netcp_ndo_change_mtu, | 2002 | .ndo_change_mtu = netcp_ndo_change_mtu, |
1951 | .ndo_set_mac_address = eth_mac_addr, | 2003 | .ndo_set_mac_address = netcp_ndo_set_mac_address, |
1952 | .ndo_validate_addr = eth_validate_addr, | 2004 | .ndo_validate_addr = eth_validate_addr, |
1953 | .ndo_vlan_rx_add_vid = netcp_rx_add_vid, | 2005 | .ndo_vlan_rx_add_vid = netcp_rx_add_vid, |
1954 | .ndo_vlan_rx_kill_vid = netcp_rx_kill_vid, | 2006 | .ndo_vlan_rx_kill_vid = netcp_rx_kill_vid, |
@@ -2000,6 +2052,8 @@ int netcp_create_interface(struct netcp_device *netcp_device, | |||
2000 | NETIF_F_SG| | 2052 | NETIF_F_SG| |
2001 | NETIF_F_FRAGLIST; | 2053 | NETIF_F_FRAGLIST; |
2002 | 2054 | ||
2055 | ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE; | ||
2056 | |||
2003 | netcp = netdev_priv(ndev); | 2057 | netcp = netdev_priv(ndev); |
2004 | spin_lock_init(&netcp->lock); | 2058 | spin_lock_init(&netcp->lock); |
2005 | INIT_LIST_HEAD(&netcp->module_head); | 2059 | INIT_LIST_HEAD(&netcp->module_head); |
diff --git a/drivers/net/ethernet/ti/keystone_pa.c b/drivers/net/ethernet/ti/keystone_pa.c index 5b4875f3e78..620ed16a053 100644 --- a/drivers/net/ethernet/ti/keystone_pa.c +++ b/drivers/net/ethernet/ti/keystone_pa.c | |||
@@ -301,6 +301,7 @@ struct pa_device { | |||
301 | u32 ip_lut_size; | 301 | u32 ip_lut_size; |
302 | netdev_features_t netif_features; | 302 | netdev_features_t netif_features; |
303 | const char *pdsp_fw[DEVICE_PA_NUM_PDSPS]; | 303 | const char *pdsp_fw[DEVICE_PA_NUM_PDSPS]; |
304 | u32 opened; | ||
304 | }; | 305 | }; |
305 | 306 | ||
306 | #define pa_from_module(data) container_of(data, struct pa_device, module) | 307 | #define pa_from_module(data) container_of(data, struct pa_device, module) |
@@ -2095,6 +2096,7 @@ static int pa_close(void *intf_priv, struct net_device *ndev) | |||
2095 | pa_dev->clk = NULL; | 2096 | pa_dev->clk = NULL; |
2096 | } | 2097 | } |
2097 | 2098 | ||
2099 | pa_dev->opened = 0; | ||
2098 | mutex_unlock(&pa_modules_lock); | 2100 | mutex_unlock(&pa_modules_lock); |
2099 | return 0; | 2101 | return 0; |
2100 | } | 2102 | } |
@@ -2336,6 +2338,7 @@ static int pa_open(void *intf_priv, struct net_device *ndev) | |||
2336 | netcp_register_rxhook(netcp_priv, pa_dev->rxhook_order, | 2338 | netcp_register_rxhook(netcp_priv, pa_dev->rxhook_order, |
2337 | pa_rx_hook, intf_priv); | 2339 | pa_rx_hook, intf_priv); |
2338 | 2340 | ||
2341 | pa_dev->opened = 1; | ||
2339 | return 0; | 2342 | return 0; |
2340 | 2343 | ||
2341 | fail: | 2344 | fail: |
@@ -2355,6 +2358,9 @@ int pa_add_addr(void *intf_priv, struct netcp_addr *naddr) | |||
2355 | int idx, error; | 2358 | int idx, error; |
2356 | const u8 *addr; | 2359 | const u8 *addr; |
2357 | 2360 | ||
2361 | if (!pa_dev->opened) | ||
2362 | return -ENXIO; | ||
2363 | |||
2358 | for (idx = 0; idx < count; idx++) { | 2364 | for (idx = 0; idx < count; idx++) { |
2359 | entries[idx] = pa_lut_alloc(pa_dev, PA_LUT_MAC, | 2365 | entries[idx] = pa_lut_alloc(pa_dev, PA_LUT_MAC, |
2360 | naddr->type == ADDR_ANY); | 2366 | naddr->type == ADDR_ANY); |
@@ -2409,6 +2415,9 @@ static int pa_del_addr(void *intf_priv, struct netcp_addr *naddr) | |||
2409 | struct pa_lut_entry *entry; | 2415 | struct pa_lut_entry *entry; |
2410 | int idx; | 2416 | int idx; |
2411 | 2417 | ||
2418 | if (!pa_dev->opened) | ||
2419 | return -ENXIO; | ||
2420 | |||
2412 | for (idx = 0; idx < pa_dev->lut_size; idx++) { | 2421 | for (idx = 0; idx < pa_dev->lut_size; idx++) { |
2413 | entry = pa_dev->lut + idx; | 2422 | entry = pa_dev->lut + idx; |
2414 | if (!entry->valid || !entry->in_use || entry->u.naddr != naddr) | 2423 | if (!entry->valid || !entry->in_use || entry->u.naddr != naddr) |
diff --git a/drivers/net/ethernet/ti/keystone_pa2.c b/drivers/net/ethernet/ti/keystone_pa2.c index caca6ff3006..3d642714ec9 100644 --- a/drivers/net/ethernet/ti/keystone_pa2.c +++ b/drivers/net/ethernet/ti/keystone_pa2.c | |||
@@ -1065,6 +1065,7 @@ struct pa2_device { | |||
1065 | u32 lut_size; | 1065 | u32 lut_size; |
1066 | 1066 | ||
1067 | const char *pdsp_fw[PA2_NUM_PDSPS]; | 1067 | const char *pdsp_fw[PA2_NUM_PDSPS]; |
1068 | u32 opened; | ||
1068 | }; | 1069 | }; |
1069 | 1070 | ||
1070 | #define pa2_from_module(data) container_of(data, struct pa2_device, module) | 1071 | #define pa2_from_module(data) container_of(data, struct pa2_device, module) |
@@ -2413,6 +2414,7 @@ static int pa2_close(void *intf_priv, struct net_device *ndev) | |||
2413 | pa_dev->clk = NULL; | 2414 | pa_dev->clk = NULL; |
2414 | } | 2415 | } |
2415 | 2416 | ||
2417 | pa_dev->opened = 0; | ||
2416 | mutex_unlock(&pa2_modules_lock); | 2418 | mutex_unlock(&pa2_modules_lock); |
2417 | return 0; | 2419 | return 0; |
2418 | } | 2420 | } |
@@ -2611,6 +2613,7 @@ static int pa2_open(void *intf_priv, struct net_device *ndev) | |||
2611 | netcp_register_txhook(netcp_priv, pa_dev->txhook_softcsum, | 2613 | netcp_register_txhook(netcp_priv, pa_dev->txhook_softcsum, |
2612 | pa2_txhook_softcsum, intf_priv); | 2614 | pa2_txhook_softcsum, intf_priv); |
2613 | 2615 | ||
2616 | pa_dev->opened = 1; | ||
2614 | return 0; | 2617 | return 0; |
2615 | 2618 | ||
2616 | fail: | 2619 | fail: |
@@ -2662,6 +2665,9 @@ static int pa2_add_addr(void *intf_priv, struct netcp_addr *naddr) | |||
2662 | int idx, error; | 2665 | int idx, error; |
2663 | const u8 *addr; | 2666 | const u8 *addr; |
2664 | 2667 | ||
2668 | if (!pa_dev->opened) | ||
2669 | return -ENXIO; | ||
2670 | |||
2665 | for (idx = 0; idx < count; idx++) { | 2671 | for (idx = 0; idx < count; idx++) { |
2666 | entries[idx] = pa2_lut_alloc(pa_dev, naddr->type == ADDR_ANY); | 2672 | entries[idx] = pa2_lut_alloc(pa_dev, naddr->type == ADDR_ANY); |
2667 | if (!entries[idx]) | 2673 | if (!entries[idx]) |
@@ -2715,6 +2721,9 @@ static int pa2_del_addr(void *intf_priv, struct netcp_addr *naddr) | |||
2715 | struct pa2_lut_entry *entry; | 2721 | struct pa2_lut_entry *entry; |
2716 | int idx; | 2722 | int idx; |
2717 | 2723 | ||
2724 | if (!pa_dev->opened) | ||
2725 | return -ENXIO; | ||
2726 | |||
2718 | for (idx = 0; idx < pa_dev->lut_size; idx++) { | 2727 | for (idx = 0; idx < pa_dev->lut_size; idx++) { |
2719 | entry = pa_dev->lut + idx; | 2728 | entry = pa_dev->lut + idx; |
2720 | if (!entry->valid || !entry->in_use || entry->naddr != naddr) | 2729 | if (!entry->valid || !entry->in_use || entry->naddr != naddr) |
diff --git a/drivers/net/ethernet/ti/keystone_sgmii.c b/drivers/net/ethernet/ti/keystone_sgmii.c index 5591ea55d81..8d0538fb503 100644 --- a/drivers/net/ethernet/ti/keystone_sgmii.c +++ b/drivers/net/ethernet/ti/keystone_sgmii.c | |||
@@ -137,6 +137,8 @@ int keystone_sgmii_config(void __iomem *sgmii_ofs, | |||
137 | u32 control; | 137 | u32 control; |
138 | 138 | ||
139 | switch (interface) { | 139 | switch (interface) { |
140 | case SGMII_LINK_MAC_PHY_MASTER: | ||
141 | case SGMII_LINK_MAC_PHY_MASTER_NO_MDIO: | ||
140 | case SGMII_LINK_MAC_MAC_AUTONEG: | 142 | case SGMII_LINK_MAC_MAC_AUTONEG: |
141 | mr_adv_ability = 0x9801; | 143 | mr_adv_ability = 0x9801; |
142 | control = 0x21; | 144 | control = 0x21; |
@@ -144,6 +146,7 @@ int keystone_sgmii_config(void __iomem *sgmii_ofs, | |||
144 | 146 | ||
145 | case SGMII_LINK_MAC_PHY: | 147 | case SGMII_LINK_MAC_PHY: |
146 | case SGMII_LINK_MAC_PHY_NO_MDIO: | 148 | case SGMII_LINK_MAC_PHY_NO_MDIO: |
149 | case SGMII_LINK_MAC_MAC_AN_SLAVE: | ||
147 | mr_adv_ability = 1; | 150 | mr_adv_ability = 1; |
148 | control = 1; | 151 | control = 1; |
149 | break; | 152 | break; |
diff --git a/drivers/net/ethernet/ti/keystone_xgess.c b/drivers/net/ethernet/ti/keystone_xgess.c index a09de9044d2..a84d5d78623 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 | */ | ||
88 | struct cpswx_slave { | 96 | struct 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; |
@@ -301,8 +309,11 @@ struct cpswx_priv { | |||
301 | struct kobject stats_kobj; | 309 | struct kobject stats_kobj; |
302 | spinlock_t hw_stats_lock; | 310 | spinlock_t hw_stats_lock; |
303 | struct device_node *serdes; | 311 | struct device_node *serdes; |
312 | u32 opened; | ||
304 | }; | 313 | }; |
305 | 314 | ||
315 | /* slave_port: 0-based (currently relevant only in multi_if mode) | ||
316 | */ | ||
306 | struct cpswx_intf { | 317 | struct cpswx_intf { |
307 | struct net_device *ndev; | 318 | struct net_device *ndev; |
308 | struct device *dev; | 319 | struct device *dev; |
@@ -318,7 +329,7 @@ struct cpswx_intf { | |||
318 | u32 multi_if; | 329 | u32 multi_if; |
319 | struct list_head cpsw_intf_list; | 330 | struct list_head cpsw_intf_list; |
320 | struct timer_list timer; | 331 | struct timer_list timer; |
321 | u32 sgmii_link; | 332 | u32 link_state; |
322 | }; | 333 | }; |
323 | 334 | ||
324 | /* | 335 | /* |
@@ -1524,9 +1535,7 @@ static void _cpsw_adjust_link(struct cpswx_slave *slave, bool *link) | |||
1524 | 1535 | ||
1525 | if (phy->link) { | 1536 | if (phy->link) { |
1526 | mac_control = slave->mac_control; | 1537 | mac_control = slave->mac_control; |
1527 | mac_control |= MACSL_SIG_ENABLE(slave) | | 1538 | mac_control |= MACSL_DEFAULT_CONFIG(slave); |
1528 | MACSL_RX_ENABLE_EXT_CTL | | ||
1529 | MACSL_RX_ENABLE_CSF; | ||
1530 | /* enable forwarding */ | 1539 | /* enable forwarding */ |
1531 | cpsw_ale_control_set(slave->ale, slave_port, | 1540 | cpsw_ale_control_set(slave->ale, slave_port, |
1532 | ALE_PORT_STATE, ALE_PORT_STATE_FORWARD); | 1541 | ALE_PORT_STATE, ALE_PORT_STATE_FORWARD); |
@@ -1561,9 +1570,9 @@ static void cpsw_adjust_link(struct net_device *n_dev, void *context) | |||
1561 | _cpsw_adjust_link(slave, &link); | 1570 | _cpsw_adjust_link(slave, &link); |
1562 | 1571 | ||
1563 | if (link) | 1572 | if (link) |
1564 | netcp->link_state |= BIT(slave->slave_num); | 1573 | netcp->phy_link_state_mask |= BIT(slave->slave_num); |
1565 | else | 1574 | else |
1566 | netcp->link_state &= ~BIT(slave->slave_num); | 1575 | netcp->phy_link_state_mask &= ~BIT(slave->slave_num); |
1567 | } | 1576 | } |
1568 | 1577 | ||
1569 | /* | 1578 | /* |
@@ -1595,17 +1604,15 @@ static int cpsw_port_reset(struct cpswx_slave *slave) | |||
1595 | */ | 1604 | */ |
1596 | static void cpsw_port_config(struct cpswx_slave *slave, int max_rx_len) | 1605 | static void cpsw_port_config(struct cpswx_slave *slave, int max_rx_len) |
1597 | { | 1606 | { |
1598 | u32 mac_control; | ||
1599 | |||
1600 | if (max_rx_len > MAX_SIZE_STREAM_BUFFER) | 1607 | if (max_rx_len > MAX_SIZE_STREAM_BUFFER) |
1601 | max_rx_len = MAX_SIZE_STREAM_BUFFER; | 1608 | max_rx_len = MAX_SIZE_STREAM_BUFFER; |
1602 | 1609 | ||
1610 | slave->mac_control = MACSL_DEFAULT_CONFIG(slave); | ||
1611 | |||
1603 | __raw_writel(max_rx_len, &slave->sliver->rx_maxlen); | 1612 | __raw_writel(max_rx_len, &slave->sliver->rx_maxlen); |
1604 | 1613 | ||
1605 | mac_control = (MACSL_SIG_ENABLE(slave) | | 1614 | __iowmb(); |
1606 | MACSL_RX_ENABLE_EXT_CTL | | 1615 | __raw_writel(slave->mac_control, &slave->sliver->mac_control); |
1607 | MACSL_RX_ENABLE_CSF); | ||
1608 | __raw_writel(mac_control, &slave->sliver->mac_control); | ||
1609 | } | 1616 | } |
1610 | 1617 | ||
1611 | static void cpsw_slave_stop(struct cpswx_slave *slave, struct cpswx_priv *priv) | 1618 | static void cpsw_slave_stop(struct cpswx_slave *slave, struct cpswx_priv *priv) |
@@ -1624,15 +1631,17 @@ static void cpsw_slave_link(struct cpswx_slave *slave, | |||
1624 | struct cpswx_intf *cpsw_intf) | 1631 | struct cpswx_intf *cpsw_intf) |
1625 | { | 1632 | { |
1626 | struct netcp_priv *netcp = netdev_priv(cpsw_intf->ndev); | 1633 | struct netcp_priv *netcp = netdev_priv(cpsw_intf->ndev); |
1634 | int sn = slave->slave_num; | ||
1627 | 1635 | ||
1628 | if ((slave->link_interface == SGMII_LINK_MAC_PHY) || | 1636 | if ((slave->link_interface == SGMII_LINK_MAC_PHY) || |
1629 | (slave->link_interface == XGMII_LINK_MAC_PHY)) { | 1637 | (slave->link_interface == XGMII_LINK_MAC_PHY)) { |
1630 | if (netcp->link_state) | 1638 | /* check only the bit in phy_link_state_mask |
1631 | cpsw_intf->sgmii_link |= BIT(slave->slave_num); | 1639 | * that corresponds to the slave |
1632 | else | 1640 | */ |
1633 | cpsw_intf->sgmii_link &= ~BIT(slave->slave_num); | 1641 | if (!(netcp->phy_link_state_mask & BIT(sn))) |
1642 | cpsw_intf->link_state &= ~BIT(sn); | ||
1634 | } else if (slave->link_interface == XGMII_LINK_MAC_MAC_FORCED) | 1643 | } else if (slave->link_interface == XGMII_LINK_MAC_MAC_FORCED) |
1635 | cpsw_intf->sgmii_link |= BIT(slave->slave_num); | 1644 | cpsw_intf->link_state |= BIT(slave->slave_num); |
1636 | } | 1645 | } |
1637 | 1646 | ||
1638 | static void cpsw_slave_open(struct cpswx_slave *slave, | 1647 | static void cpsw_slave_open(struct cpswx_slave *slave, |
@@ -1661,9 +1670,6 @@ static void cpsw_slave_open(struct cpswx_slave *slave, | |||
1661 | 1670 | ||
1662 | cpsw_set_slave_mac(slave, cpsw_intf); | 1671 | cpsw_set_slave_mac(slave, cpsw_intf); |
1663 | 1672 | ||
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); | 1673 | slave_port = cpsw_get_slave_port(priv, slave->slave_num); |
1668 | 1674 | ||
1669 | slave->port_num = slave_port; | 1675 | slave->port_num = slave_port; |
@@ -1814,6 +1820,9 @@ static int cpswx_add_addr(void *intf_priv, struct netcp_addr *naddr) | |||
1814 | struct cpswx_intf *cpsw_intf = intf_priv; | 1820 | struct cpswx_intf *cpsw_intf = intf_priv; |
1815 | struct cpswx_priv *cpsw_dev = cpsw_intf->cpsw_priv; | 1821 | struct cpswx_priv *cpsw_dev = cpsw_intf->cpsw_priv; |
1816 | 1822 | ||
1823 | if (!cpsw_dev->opened) | ||
1824 | return -ENXIO; | ||
1825 | |||
1817 | dev_dbg(cpsw_dev->dev, "xgess adding address %pM, type %d\n", | 1826 | dev_dbg(cpsw_dev->dev, "xgess adding address %pM, type %d\n", |
1818 | naddr->addr, naddr->type); | 1827 | naddr->addr, naddr->type); |
1819 | 1828 | ||
@@ -1840,6 +1849,9 @@ static int cpswx_del_addr(void *intf_priv, struct netcp_addr *naddr) | |||
1840 | struct cpswx_intf *cpsw_intf = intf_priv; | 1849 | struct cpswx_intf *cpsw_intf = intf_priv; |
1841 | struct cpswx_priv *cpsw_dev = cpsw_intf->cpsw_priv; | 1850 | struct cpswx_priv *cpsw_dev = cpsw_intf->cpsw_priv; |
1842 | 1851 | ||
1852 | if (!cpsw_dev->opened) | ||
1853 | return -ENXIO; | ||
1854 | |||
1843 | dev_dbg(cpsw_dev->dev, "xgess deleting address %pM, type %d\n", | 1855 | dev_dbg(cpsw_dev->dev, "xgess deleting address %pM, type %d\n", |
1844 | naddr->addr, naddr->type); | 1856 | naddr->addr, naddr->type); |
1845 | 1857 | ||
@@ -1884,34 +1896,44 @@ static void cpswx_timer(unsigned long arg) | |||
1884 | struct cpswx_priv *cpsw_dev = cpsw_intf->cpsw_priv; | 1896 | struct cpswx_priv *cpsw_dev = cpsw_intf->cpsw_priv; |
1885 | 1897 | ||
1886 | /* | 1898 | /* |
1887 | * if the slave's link_interface is not XGMII, sgmii_link bit | 1899 | * if the slave's link_interface is not XGMII, link_state bit |
1888 | * will not be set | 1900 | * will not be set |
1889 | */ | 1901 | */ |
1890 | if (cpsw_dev->multi_if) | 1902 | if (cpsw_dev->multi_if) |
1891 | cpsw_intf->sgmii_link = | 1903 | cpsw_intf->link_state = |
1892 | keystone_sgmii_get_port_link(cpsw_dev->sgmii_port_regs, | 1904 | keystone_sgmii_get_port_link(cpsw_dev->sgmii_port_regs, |
1893 | cpsw_intf->slave_port); | 1905 | cpsw_intf->slave_port); |
1894 | else | 1906 | else |
1895 | cpsw_intf->sgmii_link = | 1907 | cpsw_intf->link_state = |
1896 | keystone_sgmii_link_status(cpsw_dev->sgmii_port_regs, | 1908 | keystone_sgmii_link_status(cpsw_dev->sgmii_port_regs, |
1897 | cpsw_intf->num_slaves); | 1909 | cpsw_intf->num_slaves); |
1898 | 1910 | ||
1911 | /* if MAC-to-PHY, check phy link status also | ||
1912 | * to conclude the intf link's status | ||
1913 | */ | ||
1899 | for_each_slave(cpsw_intf, cpsw_slave_link, cpsw_intf); | 1914 | for_each_slave(cpsw_intf, cpsw_slave_link, cpsw_intf); |
1900 | 1915 | ||
1901 | /* FIXME: Don't aggregate link statuses in multi-interface case */ | 1916 | /* Is this the right logic? |
1902 | if (cpsw_intf->sgmii_link) { | 1917 | * multi_if & MAC_PHY: phy state machine already reported carrier |
1903 | /* link ON */ | 1918 | * multi_if & !MAC_PHY: report carrier |
1904 | if (!netif_carrier_ok(cpsw_intf->ndev)) | 1919 | * !multi_if: any one slave up means intf is up, reporting carrier |
1920 | * here corrects what phy state machine (if it exists) | ||
1921 | * might have reported. | ||
1922 | */ | ||
1923 | if (!cpsw_dev->multi_if || | ||
1924 | (cpsw_dev->multi_if && | ||
1925 | (cpsw_intf->slaves->link_interface != SGMII_LINK_MAC_PHY) && | ||
1926 | (cpsw_intf->slaves->link_interface != XGMII_LINK_MAC_PHY))) { | ||
1927 | if (cpsw_intf->link_state) | ||
1905 | netif_carrier_on(cpsw_intf->ndev); | 1928 | netif_carrier_on(cpsw_intf->ndev); |
1906 | } else { | 1929 | else |
1907 | /* link OFF */ | ||
1908 | if (netif_carrier_ok(cpsw_intf->ndev)) | ||
1909 | netif_carrier_off(cpsw_intf->ndev); | 1930 | netif_carrier_off(cpsw_intf->ndev); |
1910 | } | 1931 | } |
1911 | 1932 | ||
1912 | spin_lock_bh(&cpsw_dev->hw_stats_lock); | 1933 | /* A timer runs as a BH, no need to block them */ |
1934 | spin_lock(&cpsw_dev->hw_stats_lock); | ||
1913 | cpswx_update_stats(cpsw_dev, NULL); | 1935 | cpswx_update_stats(cpsw_dev, NULL); |
1914 | spin_unlock_bh(&cpsw_dev->hw_stats_lock); | 1936 | spin_unlock(&cpsw_dev->hw_stats_lock); |
1915 | 1937 | ||
1916 | cpsw_intf->timer.expires = jiffies + (HZ/10); | 1938 | cpsw_intf->timer.expires = jiffies + (HZ/10); |
1917 | add_timer(&cpsw_intf->timer); | 1939 | add_timer(&cpsw_intf->timer); |
@@ -2017,6 +2039,7 @@ static int cpswx_open(void *intf_mod_priv, struct net_device *ndev) | |||
2017 | PSTREAM_ROUTE_DMA); | 2039 | PSTREAM_ROUTE_DMA); |
2018 | #endif | 2040 | #endif |
2019 | 2041 | ||
2042 | cpsw_dev->opened = 1; | ||
2020 | return 0; | 2043 | return 0; |
2021 | 2044 | ||
2022 | ale_fail: | 2045 | ale_fail: |
@@ -2051,6 +2074,7 @@ static int cpswx_close(void *intf_modpriv, struct net_device *ndev) | |||
2051 | clk_disable_unprepare(cpsw_dev->clk); | 2074 | clk_disable_unprepare(cpsw_dev->clk); |
2052 | clk_put(cpsw_dev->clk); | 2075 | clk_put(cpsw_dev->clk); |
2053 | 2076 | ||
2077 | cpsw_dev->opened = 0; | ||
2054 | return 0; | 2078 | return 0; |
2055 | } | 2079 | } |
2056 | 2080 | ||