diff options
author | Amir Vadai <amirv@mellanox.com> | 2013-04-23 02:06:51 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-04-24 16:30:14 -0400 |
commit | b6c39bfcf1d7d6368b8c00081cc8e941041ff478 (patch) | |
tree | d30c1ecc0f3f625de964fd92a2030df556cdf017 /drivers/net/ethernet/mellanox | |
parent | eb0cabbd1bebbf41858ded768c9cad8840708447 (diff) |
net/mlx4_en: Add a service task
Add a service task to run tasks that needed to be executed periodically.
Currently the only task is a watchdog to catch NIC clock overflow, to make
timestamping accurate.
Will move the statistics task into this framework in a later patch.
Signed-off-by: Amir Vadai <amirv@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/mellanox')
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_clock.c | 19 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 24 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 4 |
3 files changed, 47 insertions, 0 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_clock.c b/drivers/net/ethernet/mellanox/mlx4/en_clock.c index 501c72f1fbeb..2f181219662e 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_clock.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_clock.c | |||
@@ -129,4 +129,23 @@ void mlx4_en_init_timestamp(struct mlx4_en_dev *mdev) | |||
129 | 129 | ||
130 | timecounter_init(&mdev->clock, &mdev->cycles, | 130 | timecounter_init(&mdev->clock, &mdev->cycles, |
131 | ktime_to_ns(ktime_get_real())); | 131 | ktime_to_ns(ktime_get_real())); |
132 | |||
133 | /* Calculate period in seconds to call the overflow watchdog - to make | ||
134 | * sure counter is checked at least once every wrap around. | ||
135 | */ | ||
136 | mdev->overflow_period = | ||
137 | (cyclecounter_cyc2ns(&mdev->cycles, | ||
138 | mdev->cycles.mask) / NSEC_PER_SEC / 2) | ||
139 | * HZ; | ||
140 | } | ||
141 | |||
142 | void mlx4_en_ptp_overflow_check(struct mlx4_en_dev *mdev) | ||
143 | { | ||
144 | bool timeout = time_is_before_jiffies(mdev->last_overflow_check + | ||
145 | mdev->overflow_period); | ||
146 | |||
147 | if (timeout) { | ||
148 | timecounter_read(&mdev->clock); | ||
149 | mdev->last_overflow_check = jiffies; | ||
150 | } | ||
132 | } | 151 | } |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 4cb9f3203973..f4f88b846020 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c | |||
@@ -1361,6 +1361,26 @@ static void mlx4_en_do_get_stats(struct work_struct *work) | |||
1361 | mutex_unlock(&mdev->state_lock); | 1361 | mutex_unlock(&mdev->state_lock); |
1362 | } | 1362 | } |
1363 | 1363 | ||
1364 | /* mlx4_en_service_task - Run service task for tasks that needed to be done | ||
1365 | * periodically | ||
1366 | */ | ||
1367 | static void mlx4_en_service_task(struct work_struct *work) | ||
1368 | { | ||
1369 | struct delayed_work *delay = to_delayed_work(work); | ||
1370 | struct mlx4_en_priv *priv = container_of(delay, struct mlx4_en_priv, | ||
1371 | service_task); | ||
1372 | struct mlx4_en_dev *mdev = priv->mdev; | ||
1373 | |||
1374 | mutex_lock(&mdev->state_lock); | ||
1375 | if (mdev->device_up) { | ||
1376 | mlx4_en_ptp_overflow_check(mdev); | ||
1377 | |||
1378 | queue_delayed_work(mdev->workqueue, &priv->service_task, | ||
1379 | SERVICE_TASK_DELAY); | ||
1380 | } | ||
1381 | mutex_unlock(&mdev->state_lock); | ||
1382 | } | ||
1383 | |||
1364 | static void mlx4_en_linkstate(struct work_struct *work) | 1384 | static void mlx4_en_linkstate(struct work_struct *work) |
1365 | { | 1385 | { |
1366 | struct mlx4_en_priv *priv = container_of(work, struct mlx4_en_priv, | 1386 | struct mlx4_en_priv *priv = container_of(work, struct mlx4_en_priv, |
@@ -1865,6 +1885,7 @@ void mlx4_en_destroy_netdev(struct net_device *dev) | |||
1865 | mlx4_free_hwq_res(mdev->dev, &priv->res, MLX4_EN_PAGE_SIZE); | 1885 | mlx4_free_hwq_res(mdev->dev, &priv->res, MLX4_EN_PAGE_SIZE); |
1866 | 1886 | ||
1867 | cancel_delayed_work(&priv->stats_task); | 1887 | cancel_delayed_work(&priv->stats_task); |
1888 | cancel_delayed_work(&priv->service_task); | ||
1868 | /* flush any pending task for this netdev */ | 1889 | /* flush any pending task for this netdev */ |
1869 | flush_workqueue(mdev->workqueue); | 1890 | flush_workqueue(mdev->workqueue); |
1870 | 1891 | ||
@@ -2084,6 +2105,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, | |||
2084 | INIT_WORK(&priv->watchdog_task, mlx4_en_restart); | 2105 | INIT_WORK(&priv->watchdog_task, mlx4_en_restart); |
2085 | INIT_WORK(&priv->linkstate_task, mlx4_en_linkstate); | 2106 | INIT_WORK(&priv->linkstate_task, mlx4_en_linkstate); |
2086 | INIT_DELAYED_WORK(&priv->stats_task, mlx4_en_do_get_stats); | 2107 | INIT_DELAYED_WORK(&priv->stats_task, mlx4_en_do_get_stats); |
2108 | INIT_DELAYED_WORK(&priv->service_task, mlx4_en_service_task); | ||
2087 | #ifdef CONFIG_MLX4_EN_DCB | 2109 | #ifdef CONFIG_MLX4_EN_DCB |
2088 | if (!mlx4_is_slave(priv->mdev->dev)) { | 2110 | if (!mlx4_is_slave(priv->mdev->dev)) { |
2089 | if (mdev->dev->caps.flags & MLX4_DEV_CAP_FLAG_SET_ETH_SCHED) { | 2111 | if (mdev->dev->caps.flags & MLX4_DEV_CAP_FLAG_SET_ETH_SCHED) { |
@@ -2206,6 +2228,8 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, | |||
2206 | } | 2228 | } |
2207 | mlx4_en_set_default_moderation(priv); | 2229 | mlx4_en_set_default_moderation(priv); |
2208 | queue_delayed_work(mdev->workqueue, &priv->stats_task, STATS_DELAY); | 2230 | queue_delayed_work(mdev->workqueue, &priv->stats_task, STATS_DELAY); |
2231 | queue_delayed_work(mdev->workqueue, &priv->service_task, | ||
2232 | SERVICE_TASK_DELAY); | ||
2209 | return 0; | 2233 | return 0; |
2210 | 2234 | ||
2211 | out: | 2235 | out: |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 85b0754ec8ac..b1d7657b2bf5 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | |||
@@ -78,6 +78,7 @@ | |||
78 | #define STAMP_SHIFT 31 | 78 | #define STAMP_SHIFT 31 |
79 | #define STAMP_VAL 0x7fffffff | 79 | #define STAMP_VAL 0x7fffffff |
80 | #define STATS_DELAY (HZ / 4) | 80 | #define STATS_DELAY (HZ / 4) |
81 | #define SERVICE_TASK_DELAY (HZ / 4) | ||
81 | #define MAX_NUM_OF_FS_RULES 256 | 82 | #define MAX_NUM_OF_FS_RULES 256 |
82 | 83 | ||
83 | #define MLX4_EN_FILTER_HASH_SHIFT 4 | 84 | #define MLX4_EN_FILTER_HASH_SHIFT 4 |
@@ -355,6 +356,7 @@ struct mlx4_en_dev { | |||
355 | struct cyclecounter cycles; | 356 | struct cyclecounter cycles; |
356 | struct timecounter clock; | 357 | struct timecounter clock; |
357 | unsigned long last_overflow_check; | 358 | unsigned long last_overflow_check; |
359 | unsigned long overflow_period; | ||
358 | }; | 360 | }; |
359 | 361 | ||
360 | 362 | ||
@@ -519,6 +521,7 @@ struct mlx4_en_priv { | |||
519 | struct work_struct watchdog_task; | 521 | struct work_struct watchdog_task; |
520 | struct work_struct linkstate_task; | 522 | struct work_struct linkstate_task; |
521 | struct delayed_work stats_task; | 523 | struct delayed_work stats_task; |
524 | struct delayed_work service_task; | ||
522 | struct mlx4_en_perf_stats pstats; | 525 | struct mlx4_en_perf_stats pstats; |
523 | struct mlx4_en_pkt_stats pkstats; | 526 | struct mlx4_en_pkt_stats pkstats; |
524 | struct mlx4_en_port_stats port_stats; | 527 | struct mlx4_en_port_stats port_stats; |
@@ -645,6 +648,7 @@ void mlx4_en_cleanup_filters(struct mlx4_en_priv *priv, | |||
645 | #define MLX4_EN_NUM_SELF_TEST 5 | 648 | #define MLX4_EN_NUM_SELF_TEST 5 |
646 | void mlx4_en_ex_selftest(struct net_device *dev, u32 *flags, u64 *buf); | 649 | void mlx4_en_ex_selftest(struct net_device *dev, u32 *flags, u64 *buf); |
647 | u64 mlx4_en_mac_to_u64(u8 *addr); | 650 | u64 mlx4_en_mac_to_u64(u8 *addr); |
651 | void mlx4_en_ptp_overflow_check(struct mlx4_en_dev *mdev); | ||
648 | 652 | ||
649 | /* | 653 | /* |
650 | * Functions for time stamping | 654 | * Functions for time stamping |