diff options
author | Amir Vadai <amirv@mellanox.com> | 2013-04-23 02:06:49 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-04-24 16:30:14 -0400 |
commit | ec693d47010e8302e61e0bdf3f47496c5610641a (patch) | |
tree | 8fbcfe632cb618318dcb1c9a9050afd025462b0a /drivers/net/ethernet/mellanox/mlx4/en_netdev.c | |
parent | ddd8a6c12d7e494902a9435a9a7a543ef730b2d8 (diff) |
net/mlx4_en: Add HW timestamping (TS) support
The patch allows to enable/disable HW timestamping for incoming and/or
outgoing packets. It adds and initializes all structs and callbacks
needed by kernel TS API.
To enable/disable HW timestamping appropriate ioctl should be used.
Currently HWTSTAMP_FILTER_ALL/NONE and HWTSAMP_TX_ON/OFF only are
supported.
When enabling TS on receive flow - VLAN stripping will be disabled.
Also were made all relevant changes in RX/TX flows to consider TS request
and plant HW timestamps into relevant structures.
mlx4_ib was fixed to compile with new mlx4_cq_alloc() signature.
Signed-off-by: Eugenia Emantayev <eugenia@mellanox.com>
Signed-off-by: Amir Vadai <amirv@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlx4/en_netdev.c')
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index e7e27842d8d4..4cb9f3203973 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c | |||
@@ -1916,6 +1916,75 @@ static int mlx4_en_change_mtu(struct net_device *dev, int new_mtu) | |||
1916 | return 0; | 1916 | return 0; |
1917 | } | 1917 | } |
1918 | 1918 | ||
1919 | static int mlx4_en_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr) | ||
1920 | { | ||
1921 | struct mlx4_en_priv *priv = netdev_priv(dev); | ||
1922 | struct mlx4_en_dev *mdev = priv->mdev; | ||
1923 | struct hwtstamp_config config; | ||
1924 | |||
1925 | if (copy_from_user(&config, ifr->ifr_data, sizeof(config))) | ||
1926 | return -EFAULT; | ||
1927 | |||
1928 | /* reserved for future extensions */ | ||
1929 | if (config.flags) | ||
1930 | return -EINVAL; | ||
1931 | |||
1932 | /* device doesn't support time stamping */ | ||
1933 | if (!(mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_TS)) | ||
1934 | return -EINVAL; | ||
1935 | |||
1936 | /* TX HW timestamp */ | ||
1937 | switch (config.tx_type) { | ||
1938 | case HWTSTAMP_TX_OFF: | ||
1939 | case HWTSTAMP_TX_ON: | ||
1940 | break; | ||
1941 | default: | ||
1942 | return -ERANGE; | ||
1943 | } | ||
1944 | |||
1945 | /* RX HW timestamp */ | ||
1946 | switch (config.rx_filter) { | ||
1947 | case HWTSTAMP_FILTER_NONE: | ||
1948 | break; | ||
1949 | case HWTSTAMP_FILTER_ALL: | ||
1950 | case HWTSTAMP_FILTER_SOME: | ||
1951 | case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: | ||
1952 | case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: | ||
1953 | case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: | ||
1954 | case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: | ||
1955 | case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: | ||
1956 | case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: | ||
1957 | case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: | ||
1958 | case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: | ||
1959 | case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: | ||
1960 | case HWTSTAMP_FILTER_PTP_V2_EVENT: | ||
1961 | case HWTSTAMP_FILTER_PTP_V2_SYNC: | ||
1962 | case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: | ||
1963 | config.rx_filter = HWTSTAMP_FILTER_ALL; | ||
1964 | break; | ||
1965 | default: | ||
1966 | return -ERANGE; | ||
1967 | } | ||
1968 | |||
1969 | if (mlx4_en_timestamp_config(dev, config.tx_type, config.rx_filter)) { | ||
1970 | config.tx_type = HWTSTAMP_TX_OFF; | ||
1971 | config.rx_filter = HWTSTAMP_FILTER_NONE; | ||
1972 | } | ||
1973 | |||
1974 | return copy_to_user(ifr->ifr_data, &config, | ||
1975 | sizeof(config)) ? -EFAULT : 0; | ||
1976 | } | ||
1977 | |||
1978 | static int mlx4_en_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | ||
1979 | { | ||
1980 | switch (cmd) { | ||
1981 | case SIOCSHWTSTAMP: | ||
1982 | return mlx4_en_hwtstamp_ioctl(dev, ifr); | ||
1983 | default: | ||
1984 | return -EOPNOTSUPP; | ||
1985 | } | ||
1986 | } | ||
1987 | |||
1919 | static int mlx4_en_set_features(struct net_device *netdev, | 1988 | static int mlx4_en_set_features(struct net_device *netdev, |
1920 | netdev_features_t features) | 1989 | netdev_features_t features) |
1921 | { | 1990 | { |
@@ -1943,6 +2012,7 @@ static const struct net_device_ops mlx4_netdev_ops = { | |||
1943 | .ndo_set_mac_address = mlx4_en_set_mac, | 2012 | .ndo_set_mac_address = mlx4_en_set_mac, |
1944 | .ndo_validate_addr = eth_validate_addr, | 2013 | .ndo_validate_addr = eth_validate_addr, |
1945 | .ndo_change_mtu = mlx4_en_change_mtu, | 2014 | .ndo_change_mtu = mlx4_en_change_mtu, |
2015 | .ndo_do_ioctl = mlx4_en_ioctl, | ||
1946 | .ndo_tx_timeout = mlx4_en_tx_timeout, | 2016 | .ndo_tx_timeout = mlx4_en_tx_timeout, |
1947 | .ndo_vlan_rx_add_vid = mlx4_en_vlan_rx_add_vid, | 2017 | .ndo_vlan_rx_add_vid = mlx4_en_vlan_rx_add_vid, |
1948 | .ndo_vlan_rx_kill_vid = mlx4_en_vlan_rx_kill_vid, | 2018 | .ndo_vlan_rx_kill_vid = mlx4_en_vlan_rx_kill_vid, |
@@ -2054,6 +2124,11 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, | |||
2054 | spin_lock_init(&priv->filters_lock); | 2124 | spin_lock_init(&priv->filters_lock); |
2055 | #endif | 2125 | #endif |
2056 | 2126 | ||
2127 | /* Initialize time stamping config */ | ||
2128 | priv->hwtstamp_config.flags = 0; | ||
2129 | priv->hwtstamp_config.tx_type = HWTSTAMP_TX_OFF; | ||
2130 | priv->hwtstamp_config.rx_filter = HWTSTAMP_FILTER_NONE; | ||
2131 | |||
2057 | /* Allocate page for receive rings */ | 2132 | /* Allocate page for receive rings */ |
2058 | err = mlx4_alloc_hwq_res(mdev->dev, &priv->res, | 2133 | err = mlx4_alloc_hwq_res(mdev->dev, &priv->res, |
2059 | MLX4_EN_PAGE_SIZE, MLX4_EN_PAGE_SIZE); | 2134 | MLX4_EN_PAGE_SIZE, MLX4_EN_PAGE_SIZE); |