diff options
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib.h | 6 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_ethtool.c | 46 |
2 files changed, 52 insertions, 0 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index 3524d65f2e57..73b2b176ad0e 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h | |||
@@ -242,6 +242,11 @@ struct ipoib_cm_dev_priv { | |||
242 | int num_frags; | 242 | int num_frags; |
243 | }; | 243 | }; |
244 | 244 | ||
245 | struct ipoib_ethtool_st { | ||
246 | u16 coalesce_usecs; | ||
247 | u16 max_coalesced_frames; | ||
248 | }; | ||
249 | |||
245 | /* | 250 | /* |
246 | * Device private locking: tx_lock protects members used in TX fast | 251 | * Device private locking: tx_lock protects members used in TX fast |
247 | * path (and we use LLTX so upper layers don't do extra locking). | 252 | * path (and we use LLTX so upper layers don't do extra locking). |
@@ -320,6 +325,7 @@ struct ipoib_dev_priv { | |||
320 | struct dentry *path_dentry; | 325 | struct dentry *path_dentry; |
321 | #endif | 326 | #endif |
322 | int hca_caps; | 327 | int hca_caps; |
328 | struct ipoib_ethtool_st ethtool; | ||
323 | }; | 329 | }; |
324 | 330 | ||
325 | struct ipoib_ah { | 331 | struct ipoib_ah { |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c b/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c index d46e6b7303b8..9a47428366c9 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c | |||
@@ -42,9 +42,55 @@ static void ipoib_get_drvinfo(struct net_device *netdev, | |||
42 | strncpy(drvinfo->driver, "ipoib", sizeof(drvinfo->driver) - 1); | 42 | strncpy(drvinfo->driver, "ipoib", sizeof(drvinfo->driver) - 1); |
43 | } | 43 | } |
44 | 44 | ||
45 | static int ipoib_get_coalesce(struct net_device *dev, | ||
46 | struct ethtool_coalesce *coal) | ||
47 | { | ||
48 | struct ipoib_dev_priv *priv = netdev_priv(dev); | ||
49 | |||
50 | coal->rx_coalesce_usecs = priv->ethtool.coalesce_usecs; | ||
51 | coal->tx_coalesce_usecs = priv->ethtool.coalesce_usecs; | ||
52 | coal->rx_max_coalesced_frames = priv->ethtool.max_coalesced_frames; | ||
53 | coal->tx_max_coalesced_frames = priv->ethtool.max_coalesced_frames; | ||
54 | |||
55 | return 0; | ||
56 | } | ||
57 | |||
58 | static int ipoib_set_coalesce(struct net_device *dev, | ||
59 | struct ethtool_coalesce *coal) | ||
60 | { | ||
61 | struct ipoib_dev_priv *priv = netdev_priv(dev); | ||
62 | int ret; | ||
63 | |||
64 | /* | ||
65 | * Since IPoIB uses a single CQ for both rx and tx, we assume | ||
66 | * that rx params dictate the configuration. These values are | ||
67 | * saved in the private data and returned when ipoib_get_coalesce() | ||
68 | * is called. | ||
69 | */ | ||
70 | if (coal->rx_coalesce_usecs > 0xffff || | ||
71 | coal->rx_max_coalesced_frames > 0xffff) | ||
72 | return -EINVAL; | ||
73 | |||
74 | ret = ib_modify_cq(priv->cq, coal->rx_max_coalesced_frames, | ||
75 | coal->rx_coalesce_usecs); | ||
76 | if (ret && ret != -ENOSYS) { | ||
77 | ipoib_warn(priv, "failed modifying CQ (%d)\n", ret); | ||
78 | return ret; | ||
79 | } | ||
80 | |||
81 | coal->tx_coalesce_usecs = coal->rx_coalesce_usecs; | ||
82 | coal->tx_max_coalesced_frames = coal->rx_max_coalesced_frames; | ||
83 | priv->ethtool.coalesce_usecs = coal->rx_coalesce_usecs; | ||
84 | priv->ethtool.max_coalesced_frames = coal->rx_max_coalesced_frames; | ||
85 | |||
86 | return 0; | ||
87 | } | ||
88 | |||
45 | static const struct ethtool_ops ipoib_ethtool_ops = { | 89 | static const struct ethtool_ops ipoib_ethtool_ops = { |
46 | .get_drvinfo = ipoib_get_drvinfo, | 90 | .get_drvinfo = ipoib_get_drvinfo, |
47 | .get_tso = ethtool_op_get_tso, | 91 | .get_tso = ethtool_op_get_tso, |
92 | .get_coalesce = ipoib_get_coalesce, | ||
93 | .set_coalesce = ipoib_set_coalesce, | ||
48 | }; | 94 | }; |
49 | 95 | ||
50 | void ipoib_set_ethtool_ops(struct net_device *dev) | 96 | void ipoib_set_ethtool_ops(struct net_device *dev) |