diff options
Diffstat (limited to 'drivers/net/ethernet/marvell/mv643xx_eth.c')
-rw-r--r-- | drivers/net/ethernet/marvell/mv643xx_eth.c | 42 |
1 files changed, 31 insertions, 11 deletions
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c index c8950da60e6b..04d901d0ff63 100644 --- a/drivers/net/ethernet/marvell/mv643xx_eth.c +++ b/drivers/net/ethernet/marvell/mv643xx_eth.c | |||
@@ -57,6 +57,7 @@ | |||
57 | #include <linux/types.h> | 57 | #include <linux/types.h> |
58 | #include <linux/inet_lro.h> | 58 | #include <linux/inet_lro.h> |
59 | #include <linux/slab.h> | 59 | #include <linux/slab.h> |
60 | #include <linux/clk.h> | ||
60 | 61 | ||
61 | static char mv643xx_eth_driver_name[] = "mv643xx_eth"; | 62 | static char mv643xx_eth_driver_name[] = "mv643xx_eth"; |
62 | static char mv643xx_eth_driver_version[] = "1.4"; | 63 | static char mv643xx_eth_driver_version[] = "1.4"; |
@@ -289,10 +290,10 @@ struct mv643xx_eth_shared_private { | |||
289 | /* | 290 | /* |
290 | * Hardware-specific parameters. | 291 | * Hardware-specific parameters. |
291 | */ | 292 | */ |
292 | unsigned int t_clk; | ||
293 | int extended_rx_coal_limit; | 293 | int extended_rx_coal_limit; |
294 | int tx_bw_control; | 294 | int tx_bw_control; |
295 | int tx_csum_limit; | 295 | int tx_csum_limit; |
296 | |||
296 | }; | 297 | }; |
297 | 298 | ||
298 | #define TX_BW_CONTROL_ABSENT 0 | 299 | #define TX_BW_CONTROL_ABSENT 0 |
@@ -431,6 +432,12 @@ struct mv643xx_eth_private { | |||
431 | int tx_desc_sram_size; | 432 | int tx_desc_sram_size; |
432 | int txq_count; | 433 | int txq_count; |
433 | struct tx_queue txq[8]; | 434 | struct tx_queue txq[8]; |
435 | |||
436 | /* | ||
437 | * Hardware-specific parameters. | ||
438 | */ | ||
439 | struct clk *clk; | ||
440 | unsigned int t_clk; | ||
434 | }; | 441 | }; |
435 | 442 | ||
436 | 443 | ||
@@ -1010,7 +1017,7 @@ static void tx_set_rate(struct mv643xx_eth_private *mp, int rate, int burst) | |||
1010 | int mtu; | 1017 | int mtu; |
1011 | int bucket_size; | 1018 | int bucket_size; |
1012 | 1019 | ||
1013 | token_rate = ((rate / 1000) * 64) / (mp->shared->t_clk / 1000); | 1020 | token_rate = ((rate / 1000) * 64) / (mp->t_clk / 1000); |
1014 | if (token_rate > 1023) | 1021 | if (token_rate > 1023) |
1015 | token_rate = 1023; | 1022 | token_rate = 1023; |
1016 | 1023 | ||
@@ -1042,7 +1049,7 @@ static void txq_set_rate(struct tx_queue *txq, int rate, int burst) | |||
1042 | int token_rate; | 1049 | int token_rate; |
1043 | int bucket_size; | 1050 | int bucket_size; |
1044 | 1051 | ||
1045 | token_rate = ((rate / 1000) * 64) / (mp->shared->t_clk / 1000); | 1052 | token_rate = ((rate / 1000) * 64) / (mp->t_clk / 1000); |
1046 | if (token_rate > 1023) | 1053 | if (token_rate > 1023) |
1047 | token_rate = 1023; | 1054 | token_rate = 1023; |
1048 | 1055 | ||
@@ -1309,7 +1316,7 @@ static unsigned int get_rx_coal(struct mv643xx_eth_private *mp) | |||
1309 | temp = (val & 0x003fff00) >> 8; | 1316 | temp = (val & 0x003fff00) >> 8; |
1310 | 1317 | ||
1311 | temp *= 64000000; | 1318 | temp *= 64000000; |
1312 | do_div(temp, mp->shared->t_clk); | 1319 | do_div(temp, mp->t_clk); |
1313 | 1320 | ||
1314 | return (unsigned int)temp; | 1321 | return (unsigned int)temp; |
1315 | } | 1322 | } |
@@ -1319,7 +1326,7 @@ static void set_rx_coal(struct mv643xx_eth_private *mp, unsigned int usec) | |||
1319 | u64 temp; | 1326 | u64 temp; |
1320 | u32 val; | 1327 | u32 val; |
1321 | 1328 | ||
1322 | temp = (u64)usec * mp->shared->t_clk; | 1329 | temp = (u64)usec * mp->t_clk; |
1323 | temp += 31999999; | 1330 | temp += 31999999; |
1324 | do_div(temp, 64000000); | 1331 | do_div(temp, 64000000); |
1325 | 1332 | ||
@@ -1345,7 +1352,7 @@ static unsigned int get_tx_coal(struct mv643xx_eth_private *mp) | |||
1345 | 1352 | ||
1346 | temp = (rdlp(mp, TX_FIFO_URGENT_THRESHOLD) & 0x3fff0) >> 4; | 1353 | temp = (rdlp(mp, TX_FIFO_URGENT_THRESHOLD) & 0x3fff0) >> 4; |
1347 | temp *= 64000000; | 1354 | temp *= 64000000; |
1348 | do_div(temp, mp->shared->t_clk); | 1355 | do_div(temp, mp->t_clk); |
1349 | 1356 | ||
1350 | return (unsigned int)temp; | 1357 | return (unsigned int)temp; |
1351 | } | 1358 | } |
@@ -1354,7 +1361,7 @@ static void set_tx_coal(struct mv643xx_eth_private *mp, unsigned int usec) | |||
1354 | { | 1361 | { |
1355 | u64 temp; | 1362 | u64 temp; |
1356 | 1363 | ||
1357 | temp = (u64)usec * mp->shared->t_clk; | 1364 | temp = (u64)usec * mp->t_clk; |
1358 | temp += 31999999; | 1365 | temp += 31999999; |
1359 | do_div(temp, 64000000); | 1366 | do_div(temp, 64000000); |
1360 | 1367 | ||
@@ -2663,10 +2670,6 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev) | |||
2663 | if (dram) | 2670 | if (dram) |
2664 | mv643xx_eth_conf_mbus_windows(msp, dram); | 2671 | mv643xx_eth_conf_mbus_windows(msp, dram); |
2665 | 2672 | ||
2666 | /* | ||
2667 | * Detect hardware parameters. | ||
2668 | */ | ||
2669 | msp->t_clk = (pd != NULL && pd->t_clk != 0) ? pd->t_clk : 133000000; | ||
2670 | msp->tx_csum_limit = (pd != NULL && pd->tx_csum_limit) ? | 2673 | msp->tx_csum_limit = (pd != NULL && pd->tx_csum_limit) ? |
2671 | pd->tx_csum_limit : 9 * 1024; | 2674 | pd->tx_csum_limit : 9 * 1024; |
2672 | infer_hw_params(msp); | 2675 | infer_hw_params(msp); |
@@ -2891,6 +2894,18 @@ static int mv643xx_eth_probe(struct platform_device *pdev) | |||
2891 | 2894 | ||
2892 | mp->dev = dev; | 2895 | mp->dev = dev; |
2893 | 2896 | ||
2897 | /* | ||
2898 | * Get the clk rate, if there is one, otherwise use the default. | ||
2899 | */ | ||
2900 | mp->clk = clk_get(&pdev->dev, (pdev->id ? "1" : "0")); | ||
2901 | if (!IS_ERR(mp->clk)) { | ||
2902 | clk_prepare_enable(mp->clk); | ||
2903 | mp->t_clk = clk_get_rate(mp->clk); | ||
2904 | } else { | ||
2905 | mp->t_clk = 133000000; | ||
2906 | printk(KERN_WARNING "Unable to get clock"); | ||
2907 | } | ||
2908 | |||
2894 | set_params(mp, pd); | 2909 | set_params(mp, pd); |
2895 | netif_set_real_num_tx_queues(dev, mp->txq_count); | 2910 | netif_set_real_num_tx_queues(dev, mp->txq_count); |
2896 | netif_set_real_num_rx_queues(dev, mp->rxq_count); | 2911 | netif_set_real_num_rx_queues(dev, mp->rxq_count); |
@@ -2979,6 +2994,11 @@ static int mv643xx_eth_remove(struct platform_device *pdev) | |||
2979 | if (mp->phy != NULL) | 2994 | if (mp->phy != NULL) |
2980 | phy_detach(mp->phy); | 2995 | phy_detach(mp->phy); |
2981 | cancel_work_sync(&mp->tx_timeout_task); | 2996 | cancel_work_sync(&mp->tx_timeout_task); |
2997 | |||
2998 | if (!IS_ERR(mp->clk)) { | ||
2999 | clk_disable_unprepare(mp->clk); | ||
3000 | clk_put(mp->clk); | ||
3001 | } | ||
2982 | free_netdev(mp->dev); | 3002 | free_netdev(mp->dev); |
2983 | 3003 | ||
2984 | platform_set_drvdata(pdev, NULL); | 3004 | platform_set_drvdata(pdev, NULL); |