diff options
| -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) |
