diff options
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r-- | drivers/net/ethernet/renesas/sh_eth.c | 64 | ||||
-rw-r--r-- | drivers/net/ethernet/renesas/sh_eth.h | 1 |
2 files changed, 36 insertions, 29 deletions
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index f9e30b87ecd5..b5db6b3f939f 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c | |||
@@ -2036,6 +2036,8 @@ static int sh_eth_open(struct net_device *ndev) | |||
2036 | if (ret) | 2036 | if (ret) |
2037 | goto out_free_irq; | 2037 | goto out_free_irq; |
2038 | 2038 | ||
2039 | mdp->is_opened = 1; | ||
2040 | |||
2039 | return ret; | 2041 | return ret; |
2040 | 2042 | ||
2041 | out_free_irq: | 2043 | out_free_irq: |
@@ -2125,6 +2127,36 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
2125 | return NETDEV_TX_OK; | 2127 | return NETDEV_TX_OK; |
2126 | } | 2128 | } |
2127 | 2129 | ||
2130 | static struct net_device_stats *sh_eth_get_stats(struct net_device *ndev) | ||
2131 | { | ||
2132 | struct sh_eth_private *mdp = netdev_priv(ndev); | ||
2133 | |||
2134 | if (sh_eth_is_rz_fast_ether(mdp)) | ||
2135 | return &ndev->stats; | ||
2136 | |||
2137 | if (!mdp->is_opened) | ||
2138 | return &ndev->stats; | ||
2139 | |||
2140 | ndev->stats.tx_dropped += sh_eth_read(ndev, TROCR); | ||
2141 | sh_eth_write(ndev, 0, TROCR); /* (write clear) */ | ||
2142 | ndev->stats.collisions += sh_eth_read(ndev, CDCR); | ||
2143 | sh_eth_write(ndev, 0, CDCR); /* (write clear) */ | ||
2144 | ndev->stats.tx_carrier_errors += sh_eth_read(ndev, LCCR); | ||
2145 | sh_eth_write(ndev, 0, LCCR); /* (write clear) */ | ||
2146 | |||
2147 | if (sh_eth_is_gether(mdp)) { | ||
2148 | ndev->stats.tx_carrier_errors += sh_eth_read(ndev, CERCR); | ||
2149 | sh_eth_write(ndev, 0, CERCR); /* (write clear) */ | ||
2150 | ndev->stats.tx_carrier_errors += sh_eth_read(ndev, CEECR); | ||
2151 | sh_eth_write(ndev, 0, CEECR); /* (write clear) */ | ||
2152 | } else { | ||
2153 | ndev->stats.tx_carrier_errors += sh_eth_read(ndev, CNDCR); | ||
2154 | sh_eth_write(ndev, 0, CNDCR); /* (write clear) */ | ||
2155 | } | ||
2156 | |||
2157 | return &ndev->stats; | ||
2158 | } | ||
2159 | |||
2128 | /* device close function */ | 2160 | /* device close function */ |
2129 | static int sh_eth_close(struct net_device *ndev) | 2161 | static int sh_eth_close(struct net_device *ndev) |
2130 | { | 2162 | { |
@@ -2139,6 +2171,7 @@ static int sh_eth_close(struct net_device *ndev) | |||
2139 | sh_eth_write(ndev, 0, EDTRR); | 2171 | sh_eth_write(ndev, 0, EDTRR); |
2140 | sh_eth_write(ndev, 0, EDRRR); | 2172 | sh_eth_write(ndev, 0, EDRRR); |
2141 | 2173 | ||
2174 | sh_eth_get_stats(ndev); | ||
2142 | /* PHY Disconnect */ | 2175 | /* PHY Disconnect */ |
2143 | if (mdp->phydev) { | 2176 | if (mdp->phydev) { |
2144 | phy_stop(mdp->phydev); | 2177 | phy_stop(mdp->phydev); |
@@ -2157,36 +2190,9 @@ static int sh_eth_close(struct net_device *ndev) | |||
2157 | 2190 | ||
2158 | pm_runtime_put_sync(&mdp->pdev->dev); | 2191 | pm_runtime_put_sync(&mdp->pdev->dev); |
2159 | 2192 | ||
2160 | return 0; | 2193 | mdp->is_opened = 0; |
2161 | } | ||
2162 | |||
2163 | static struct net_device_stats *sh_eth_get_stats(struct net_device *ndev) | ||
2164 | { | ||
2165 | struct sh_eth_private *mdp = netdev_priv(ndev); | ||
2166 | |||
2167 | if (sh_eth_is_rz_fast_ether(mdp)) | ||
2168 | return &ndev->stats; | ||
2169 | |||
2170 | pm_runtime_get_sync(&mdp->pdev->dev); | ||
2171 | |||
2172 | ndev->stats.tx_dropped += sh_eth_read(ndev, TROCR); | ||
2173 | sh_eth_write(ndev, 0, TROCR); /* (write clear) */ | ||
2174 | ndev->stats.collisions += sh_eth_read(ndev, CDCR); | ||
2175 | sh_eth_write(ndev, 0, CDCR); /* (write clear) */ | ||
2176 | ndev->stats.tx_carrier_errors += sh_eth_read(ndev, LCCR); | ||
2177 | sh_eth_write(ndev, 0, LCCR); /* (write clear) */ | ||
2178 | if (sh_eth_is_gether(mdp)) { | ||
2179 | ndev->stats.tx_carrier_errors += sh_eth_read(ndev, CERCR); | ||
2180 | sh_eth_write(ndev, 0, CERCR); /* (write clear) */ | ||
2181 | ndev->stats.tx_carrier_errors += sh_eth_read(ndev, CEECR); | ||
2182 | sh_eth_write(ndev, 0, CEECR); /* (write clear) */ | ||
2183 | } else { | ||
2184 | ndev->stats.tx_carrier_errors += sh_eth_read(ndev, CNDCR); | ||
2185 | sh_eth_write(ndev, 0, CNDCR); /* (write clear) */ | ||
2186 | } | ||
2187 | pm_runtime_put_sync(&mdp->pdev->dev); | ||
2188 | 2194 | ||
2189 | return &ndev->stats; | 2195 | return 0; |
2190 | } | 2196 | } |
2191 | 2197 | ||
2192 | /* ioctl to device function */ | 2198 | /* ioctl to device function */ |
diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h index 9fa93321d512..22301bf9c21d 100644 --- a/drivers/net/ethernet/renesas/sh_eth.h +++ b/drivers/net/ethernet/renesas/sh_eth.h | |||
@@ -522,6 +522,7 @@ struct sh_eth_private { | |||
522 | 522 | ||
523 | unsigned no_ether_link:1; | 523 | unsigned no_ether_link:1; |
524 | unsigned ether_link_active_low:1; | 524 | unsigned ether_link_active_low:1; |
525 | unsigned is_opened:1; | ||
525 | }; | 526 | }; |
526 | 527 | ||
527 | static inline void sh_eth_soft_swap(char *src, int len) | 528 | static inline void sh_eth_soft_swap(char *src, int len) |