mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-11 01:00:57 +00:00
Merge branch 'siocghwtstamp' of git://git.kernel.org/pub/scm/linux/kernel/git/bwh/sfc-next
Ben Hutchings says: ==================== SIOCGHWTSTAMP ioctl 1. Add the SIOCGHWTSTAMP ioctl and update the timestamping documentation. 2. Implement SIOCGHWTSTAMP in most drivers that support SIOCSHWTSTAMP. 3. Add a test program to exercise SIOC{G,S}HWTSTAMP. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
426e1fa31e
23 changed files with 423 additions and 100 deletions
|
@ -85,7 +85,7 @@ Filled in if SOF_TIMESTAMPING_SYS_HARDWARE is set. Requires support
|
||||||
by the network device and will be empty without that support.
|
by the network device and will be empty without that support.
|
||||||
|
|
||||||
|
|
||||||
SIOCSHWTSTAMP:
|
SIOCSHWTSTAMP, SIOCGHWTSTAMP:
|
||||||
|
|
||||||
Hardware time stamping must also be initialized for each device driver
|
Hardware time stamping must also be initialized for each device driver
|
||||||
that is expected to do hardware time stamping. The parameter is defined in
|
that is expected to do hardware time stamping. The parameter is defined in
|
||||||
|
@ -115,6 +115,10 @@ Only a processes with admin rights may change the configuration. User
|
||||||
space is responsible to ensure that multiple processes don't interfere
|
space is responsible to ensure that multiple processes don't interfere
|
||||||
with each other and that the settings are reset.
|
with each other and that the settings are reset.
|
||||||
|
|
||||||
|
Any process can read the actual configuration by passing this
|
||||||
|
structure to ioctl(SIOCGHWTSTAMP) in the same way. However, this has
|
||||||
|
not been implemented in all drivers.
|
||||||
|
|
||||||
/* possible values for hwtstamp_config->tx_type */
|
/* possible values for hwtstamp_config->tx_type */
|
||||||
enum {
|
enum {
|
||||||
/*
|
/*
|
||||||
|
@ -157,7 +161,8 @@ DEVICE IMPLEMENTATION
|
||||||
|
|
||||||
A driver which supports hardware time stamping must support the
|
A driver which supports hardware time stamping must support the
|
||||||
SIOCSHWTSTAMP ioctl and update the supplied struct hwtstamp_config with
|
SIOCSHWTSTAMP ioctl and update the supplied struct hwtstamp_config with
|
||||||
the actual values as described in the section on SIOCSHWTSTAMP.
|
the actual values as described in the section on SIOCSHWTSTAMP. It
|
||||||
|
should also support SIOCGHWTSTAMP.
|
||||||
|
|
||||||
Time stamps for received packets must be stored in the skb. To get a pointer
|
Time stamps for received packets must be stored in the skb. To get a pointer
|
||||||
to the shared time stamp structure of the skb call skb_hwtstamps(). Then
|
to the shared time stamp structure of the skb call skb_hwtstamps(). Then
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
timestamping
|
timestamping
|
||||||
|
hwtstamp_config
|
||||||
|
|
|
@ -2,12 +2,13 @@
|
||||||
obj- := dummy.o
|
obj- := dummy.o
|
||||||
|
|
||||||
# List of programs to build
|
# List of programs to build
|
||||||
hostprogs-y := timestamping
|
hostprogs-y := timestamping hwtstamp_config
|
||||||
|
|
||||||
# Tell kbuild to always build the programs
|
# Tell kbuild to always build the programs
|
||||||
always := $(hostprogs-y)
|
always := $(hostprogs-y)
|
||||||
|
|
||||||
HOSTCFLAGS_timestamping.o += -I$(objtree)/usr/include
|
HOSTCFLAGS_timestamping.o += -I$(objtree)/usr/include
|
||||||
|
HOSTCFLAGS_hwtstamp_config.o += -I$(objtree)/usr/include
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f timestamping
|
rm -f timestamping hwtstamp_config
|
||||||
|
|
134
Documentation/networking/timestamping/hwtstamp_config.c
Normal file
134
Documentation/networking/timestamping/hwtstamp_config.c
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
/* Test program for SIOC{G,S}HWTSTAMP
|
||||||
|
* Copyright 2013 Solarflare Communications
|
||||||
|
* Author: Ben Hutchings
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
|
#include <linux/if.h>
|
||||||
|
#include <linux/net_tstamp.h>
|
||||||
|
#include <linux/sockios.h>
|
||||||
|
|
||||||
|
static int
|
||||||
|
lookup_value(const char **names, int size, const char *name)
|
||||||
|
{
|
||||||
|
int value;
|
||||||
|
|
||||||
|
for (value = 0; value < size; value++)
|
||||||
|
if (names[value] && strcasecmp(names[value], name) == 0)
|
||||||
|
return value;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
lookup_name(const char **names, int size, int value)
|
||||||
|
{
|
||||||
|
return (value >= 0 && value < size) ? names[value] : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void list_names(FILE *f, const char **names, int size)
|
||||||
|
{
|
||||||
|
int value;
|
||||||
|
|
||||||
|
for (value = 0; value < size; value++)
|
||||||
|
if (names[value])
|
||||||
|
fprintf(f, " %s\n", names[value]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *tx_types[] = {
|
||||||
|
#define TX_TYPE(name) [HWTSTAMP_TX_ ## name] = #name
|
||||||
|
TX_TYPE(OFF),
|
||||||
|
TX_TYPE(ON),
|
||||||
|
TX_TYPE(ONESTEP_SYNC)
|
||||||
|
#undef TX_TYPE
|
||||||
|
};
|
||||||
|
#define N_TX_TYPES ((int)(sizeof(tx_types) / sizeof(tx_types[0])))
|
||||||
|
|
||||||
|
static const char *rx_filters[] = {
|
||||||
|
#define RX_FILTER(name) [HWTSTAMP_FILTER_ ## name] = #name
|
||||||
|
RX_FILTER(NONE),
|
||||||
|
RX_FILTER(ALL),
|
||||||
|
RX_FILTER(SOME),
|
||||||
|
RX_FILTER(PTP_V1_L4_EVENT),
|
||||||
|
RX_FILTER(PTP_V1_L4_SYNC),
|
||||||
|
RX_FILTER(PTP_V1_L4_DELAY_REQ),
|
||||||
|
RX_FILTER(PTP_V2_L4_EVENT),
|
||||||
|
RX_FILTER(PTP_V2_L4_SYNC),
|
||||||
|
RX_FILTER(PTP_V2_L4_DELAY_REQ),
|
||||||
|
RX_FILTER(PTP_V2_L2_EVENT),
|
||||||
|
RX_FILTER(PTP_V2_L2_SYNC),
|
||||||
|
RX_FILTER(PTP_V2_L2_DELAY_REQ),
|
||||||
|
RX_FILTER(PTP_V2_EVENT),
|
||||||
|
RX_FILTER(PTP_V2_SYNC),
|
||||||
|
RX_FILTER(PTP_V2_DELAY_REQ),
|
||||||
|
#undef RX_FILTER
|
||||||
|
};
|
||||||
|
#define N_RX_FILTERS ((int)(sizeof(rx_filters) / sizeof(rx_filters[0])))
|
||||||
|
|
||||||
|
static void usage(void)
|
||||||
|
{
|
||||||
|
fputs("Usage: hwtstamp_config if_name [tx_type rx_filter]\n"
|
||||||
|
"tx_type is any of (case-insensitive):\n",
|
||||||
|
stderr);
|
||||||
|
list_names(stderr, tx_types, N_TX_TYPES);
|
||||||
|
fputs("rx_filter is any of (case-insensitive):\n", stderr);
|
||||||
|
list_names(stderr, rx_filters, N_RX_FILTERS);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
struct ifreq ifr;
|
||||||
|
struct hwtstamp_config config;
|
||||||
|
const char *name;
|
||||||
|
int sock;
|
||||||
|
|
||||||
|
if ((argc != 2 && argc != 4) || (strlen(argv[1]) >= IFNAMSIZ)) {
|
||||||
|
usage();
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc == 4) {
|
||||||
|
config.flags = 0;
|
||||||
|
config.tx_type = lookup_value(tx_types, N_TX_TYPES, argv[2]);
|
||||||
|
config.rx_filter = lookup_value(rx_filters, N_RX_FILTERS, argv[3]);
|
||||||
|
if (config.tx_type < 0 || config.rx_filter < 0) {
|
||||||
|
usage();
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
if (sock < 0) {
|
||||||
|
perror("socket");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(ifr.ifr_name, argv[1]);
|
||||||
|
ifr.ifr_data = (caddr_t)&config;
|
||||||
|
|
||||||
|
if (ioctl(sock, (argc == 2) ? SIOCGHWTSTAMP : SIOCSHWTSTAMP, &ifr)) {
|
||||||
|
perror("ioctl");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("flags = %#x\n", config.flags);
|
||||||
|
name = lookup_name(tx_types, N_TX_TYPES, config.tx_type);
|
||||||
|
if (name)
|
||||||
|
printf("tx_type = %s\n", name);
|
||||||
|
else
|
||||||
|
printf("tx_type = %d\n", config.tx_type);
|
||||||
|
name = lookup_name(rx_filters, N_RX_FILTERS, config.rx_filter);
|
||||||
|
if (name)
|
||||||
|
printf("rx_filter = %s\n", name);
|
||||||
|
else
|
||||||
|
printf("rx_filter = %d\n", config.rx_filter);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -667,8 +667,8 @@ static u32 bfin_select_phc_clock(u32 input_clk, unsigned int *shift_result)
|
||||||
return 1000000000UL / ppn;
|
return 1000000000UL / ppn;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bfin_mac_hwtstamp_ioctl(struct net_device *netdev,
|
static int bfin_mac_hwtstamp_set(struct net_device *netdev,
|
||||||
struct ifreq *ifr, int cmd)
|
struct ifreq *ifr)
|
||||||
{
|
{
|
||||||
struct hwtstamp_config config;
|
struct hwtstamp_config config;
|
||||||
struct bfin_mac_local *lp = netdev_priv(netdev);
|
struct bfin_mac_local *lp = netdev_priv(netdev);
|
||||||
|
@ -824,6 +824,16 @@ static int bfin_mac_hwtstamp_ioctl(struct net_device *netdev,
|
||||||
-EFAULT : 0;
|
-EFAULT : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int bfin_mac_hwtstamp_get(struct net_device *netdev,
|
||||||
|
struct ifreq *ifr)
|
||||||
|
{
|
||||||
|
struct bfin_mac_local *lp = netdev_priv(netdev);
|
||||||
|
|
||||||
|
return copy_to_user(ifr->ifr_data, &lp->stamp_cfg,
|
||||||
|
sizeof(lp->stamp_cfg)) ?
|
||||||
|
-EFAULT : 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void bfin_tx_hwtstamp(struct net_device *netdev, struct sk_buff *skb)
|
static void bfin_tx_hwtstamp(struct net_device *netdev, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct bfin_mac_local *lp = netdev_priv(netdev);
|
struct bfin_mac_local *lp = netdev_priv(netdev);
|
||||||
|
@ -1062,7 +1072,8 @@ static void bfin_phc_release(struct bfin_mac_local *lp)
|
||||||
#else
|
#else
|
||||||
# define bfin_mac_hwtstamp_is_none(cfg) 0
|
# define bfin_mac_hwtstamp_is_none(cfg) 0
|
||||||
# define bfin_mac_hwtstamp_init(dev)
|
# define bfin_mac_hwtstamp_init(dev)
|
||||||
# define bfin_mac_hwtstamp_ioctl(dev, ifr, cmd) (-EOPNOTSUPP)
|
# define bfin_mac_hwtstamp_set(dev, ifr) (-EOPNOTSUPP)
|
||||||
|
# define bfin_mac_hwtstamp_get(dev, ifr) (-EOPNOTSUPP)
|
||||||
# define bfin_rx_hwtstamp(dev, skb)
|
# define bfin_rx_hwtstamp(dev, skb)
|
||||||
# define bfin_tx_hwtstamp(dev, skb)
|
# define bfin_tx_hwtstamp(dev, skb)
|
||||||
# define bfin_phc_init(netdev, dev) 0
|
# define bfin_phc_init(netdev, dev) 0
|
||||||
|
@ -1496,7 +1507,9 @@ static int bfin_mac_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case SIOCSHWTSTAMP:
|
case SIOCSHWTSTAMP:
|
||||||
return bfin_mac_hwtstamp_ioctl(netdev, ifr, cmd);
|
return bfin_mac_hwtstamp_set(netdev, ifr);
|
||||||
|
case SIOCGHWTSTAMP:
|
||||||
|
return bfin_mac_hwtstamp_get(netdev, ifr);
|
||||||
default:
|
default:
|
||||||
if (lp->phydev)
|
if (lp->phydev)
|
||||||
return phy_mii_ioctl(lp->phydev, ifr, cmd);
|
return phy_mii_ioctl(lp->phydev, ifr, cmd);
|
||||||
|
|
|
@ -13594,14 +13594,13 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tg3_hwtstamp_ioctl(struct net_device *dev,
|
static int tg3_hwtstamp_set(struct net_device *dev, struct ifreq *ifr)
|
||||||
struct ifreq *ifr, int cmd)
|
|
||||||
{
|
{
|
||||||
struct tg3 *tp = netdev_priv(dev);
|
struct tg3 *tp = netdev_priv(dev);
|
||||||
struct hwtstamp_config stmpconf;
|
struct hwtstamp_config stmpconf;
|
||||||
|
|
||||||
if (!tg3_flag(tp, PTP_CAPABLE))
|
if (!tg3_flag(tp, PTP_CAPABLE))
|
||||||
return -EINVAL;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
if (copy_from_user(&stmpconf, ifr->ifr_data, sizeof(stmpconf)))
|
if (copy_from_user(&stmpconf, ifr->ifr_data, sizeof(stmpconf)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
@ -13682,6 +13681,67 @@ static int tg3_hwtstamp_ioctl(struct net_device *dev,
|
||||||
-EFAULT : 0;
|
-EFAULT : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int tg3_hwtstamp_get(struct net_device *dev, struct ifreq *ifr)
|
||||||
|
{
|
||||||
|
struct tg3 *tp = netdev_priv(dev);
|
||||||
|
struct hwtstamp_config stmpconf;
|
||||||
|
|
||||||
|
if (!tg3_flag(tp, PTP_CAPABLE))
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
stmpconf.flags = 0;
|
||||||
|
stmpconf.tx_type = (tg3_flag(tp, TX_TSTAMP_EN) ?
|
||||||
|
HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF);
|
||||||
|
|
||||||
|
switch (tp->rxptpctl) {
|
||||||
|
case 0:
|
||||||
|
stmpconf.rx_filter = HWTSTAMP_FILTER_NONE;
|
||||||
|
break;
|
||||||
|
case TG3_RX_PTP_CTL_RX_PTP_V1_EN | TG3_RX_PTP_CTL_ALL_V1_EVENTS:
|
||||||
|
stmpconf.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT;
|
||||||
|
break;
|
||||||
|
case TG3_RX_PTP_CTL_RX_PTP_V1_EN | TG3_RX_PTP_CTL_SYNC_EVNT:
|
||||||
|
stmpconf.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_SYNC;
|
||||||
|
break;
|
||||||
|
case TG3_RX_PTP_CTL_RX_PTP_V1_EN | TG3_RX_PTP_CTL_DELAY_REQ:
|
||||||
|
stmpconf.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ;
|
||||||
|
break;
|
||||||
|
case TG3_RX_PTP_CTL_RX_PTP_V2_EN | TG3_RX_PTP_CTL_ALL_V2_EVENTS:
|
||||||
|
stmpconf.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
|
||||||
|
break;
|
||||||
|
case TG3_RX_PTP_CTL_RX_PTP_V2_L2_EN | TG3_RX_PTP_CTL_ALL_V2_EVENTS:
|
||||||
|
stmpconf.rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT;
|
||||||
|
break;
|
||||||
|
case TG3_RX_PTP_CTL_RX_PTP_V2_L4_EN | TG3_RX_PTP_CTL_ALL_V2_EVENTS:
|
||||||
|
stmpconf.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT;
|
||||||
|
break;
|
||||||
|
case TG3_RX_PTP_CTL_RX_PTP_V2_EN | TG3_RX_PTP_CTL_SYNC_EVNT:
|
||||||
|
stmpconf.rx_filter = HWTSTAMP_FILTER_PTP_V2_SYNC;
|
||||||
|
break;
|
||||||
|
case TG3_RX_PTP_CTL_RX_PTP_V2_L2_EN | TG3_RX_PTP_CTL_SYNC_EVNT:
|
||||||
|
stmpconf.rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_SYNC;
|
||||||
|
break;
|
||||||
|
case TG3_RX_PTP_CTL_RX_PTP_V2_L4_EN | TG3_RX_PTP_CTL_SYNC_EVNT:
|
||||||
|
stmpconf.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_SYNC;
|
||||||
|
break;
|
||||||
|
case TG3_RX_PTP_CTL_RX_PTP_V2_EN | TG3_RX_PTP_CTL_DELAY_REQ:
|
||||||
|
stmpconf.rx_filter = HWTSTAMP_FILTER_PTP_V2_DELAY_REQ;
|
||||||
|
break;
|
||||||
|
case TG3_RX_PTP_CTL_RX_PTP_V2_L2_EN | TG3_RX_PTP_CTL_DELAY_REQ:
|
||||||
|
stmpconf.rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ;
|
||||||
|
break;
|
||||||
|
case TG3_RX_PTP_CTL_RX_PTP_V2_L4_EN | TG3_RX_PTP_CTL_DELAY_REQ:
|
||||||
|
stmpconf.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
WARN_ON_ONCE(1);
|
||||||
|
return -ERANGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return copy_to_user(ifr->ifr_data, &stmpconf, sizeof(stmpconf)) ?
|
||||||
|
-EFAULT : 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
||||||
{
|
{
|
||||||
struct mii_ioctl_data *data = if_mii(ifr);
|
struct mii_ioctl_data *data = if_mii(ifr);
|
||||||
|
@ -13735,7 +13795,10 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
case SIOCSHWTSTAMP:
|
case SIOCSHWTSTAMP:
|
||||||
return tg3_hwtstamp_ioctl(dev, ifr, cmd);
|
return tg3_hwtstamp_set(dev, ifr);
|
||||||
|
|
||||||
|
case SIOCGHWTSTAMP:
|
||||||
|
return tg3_hwtstamp_get(dev, ifr);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* do nothing */
|
/* do nothing */
|
||||||
|
|
|
@ -339,7 +339,8 @@ struct fec_enet_private {
|
||||||
|
|
||||||
void fec_ptp_init(struct platform_device *pdev);
|
void fec_ptp_init(struct platform_device *pdev);
|
||||||
void fec_ptp_start_cyclecounter(struct net_device *ndev);
|
void fec_ptp_start_cyclecounter(struct net_device *ndev);
|
||||||
int fec_ptp_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd);
|
int fec_ptp_set(struct net_device *ndev, struct ifreq *ifr);
|
||||||
|
int fec_ptp_get(struct net_device *ndev, struct ifreq *ifr);
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
#endif /* FEC_H */
|
#endif /* FEC_H */
|
||||||
|
|
|
@ -1683,8 +1683,12 @@ static int fec_enet_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
|
||||||
if (!phydev)
|
if (!phydev)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
if (cmd == SIOCSHWTSTAMP && fep->bufdesc_ex)
|
if (fep->bufdesc_ex) {
|
||||||
return fec_ptp_ioctl(ndev, rq, cmd);
|
if (cmd == SIOCSHWTSTAMP)
|
||||||
|
return fec_ptp_set(ndev, rq);
|
||||||
|
if (cmd == SIOCGHWTSTAMP)
|
||||||
|
return fec_ptp_get(ndev, rq);
|
||||||
|
}
|
||||||
|
|
||||||
return phy_mii_ioctl(phydev, rq, cmd);
|
return phy_mii_ioctl(phydev, rq, cmd);
|
||||||
}
|
}
|
||||||
|
|
|
@ -274,7 +274,7 @@ static int fec_ptp_enable(struct ptp_clock_info *ptp,
|
||||||
* @ifreq: ioctl data
|
* @ifreq: ioctl data
|
||||||
* @cmd: particular ioctl requested
|
* @cmd: particular ioctl requested
|
||||||
*/
|
*/
|
||||||
int fec_ptp_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd)
|
int fec_ptp_set(struct net_device *ndev, struct ifreq *ifr)
|
||||||
{
|
{
|
||||||
struct fec_enet_private *fep = netdev_priv(ndev);
|
struct fec_enet_private *fep = netdev_priv(ndev);
|
||||||
|
|
||||||
|
@ -321,6 +321,20 @@ int fec_ptp_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd)
|
||||||
-EFAULT : 0;
|
-EFAULT : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int fec_ptp_get(struct net_device *ndev, struct ifreq *ifr)
|
||||||
|
{
|
||||||
|
struct fec_enet_private *fep = netdev_priv(ndev);
|
||||||
|
struct hwtstamp_config config;
|
||||||
|
|
||||||
|
config.flags = 0;
|
||||||
|
config.tx_type = fep->hwts_tx_en ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
|
||||||
|
config.rx_filter = (fep->hwts_rx_en ?
|
||||||
|
HWTSTAMP_FILTER_ALL : HWTSTAMP_FILTER_NONE);
|
||||||
|
|
||||||
|
return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
|
||||||
|
-EFAULT : 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fec_time_keep - call timecounter_read every second to avoid timer overrun
|
* fec_time_keep - call timecounter_read every second to avoid timer overrun
|
||||||
* because ENET just support 32bit counter, will timeout in 4s
|
* because ENET just support 32bit counter, will timeout in 4s
|
||||||
|
|
|
@ -795,8 +795,7 @@ err_grp_init:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gfar_hwtstamp_ioctl(struct net_device *netdev,
|
static int gfar_hwtstamp_set(struct net_device *netdev, struct ifreq *ifr)
|
||||||
struct ifreq *ifr, int cmd)
|
|
||||||
{
|
{
|
||||||
struct hwtstamp_config config;
|
struct hwtstamp_config config;
|
||||||
struct gfar_private *priv = netdev_priv(netdev);
|
struct gfar_private *priv = netdev_priv(netdev);
|
||||||
|
@ -845,7 +844,20 @@ static int gfar_hwtstamp_ioctl(struct net_device *netdev,
|
||||||
-EFAULT : 0;
|
-EFAULT : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ioctl MII Interface */
|
static int gfar_hwtstamp_get(struct net_device *netdev, struct ifreq *ifr)
|
||||||
|
{
|
||||||
|
struct hwtstamp_config config;
|
||||||
|
struct gfar_private *priv = netdev_priv(netdev);
|
||||||
|
|
||||||
|
config.flags = 0;
|
||||||
|
config.tx_type = priv->hwts_tx_en ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
|
||||||
|
config.rx_filter = (priv->hwts_rx_en ?
|
||||||
|
HWTSTAMP_FILTER_ALL : HWTSTAMP_FILTER_NONE);
|
||||||
|
|
||||||
|
return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
|
||||||
|
-EFAULT : 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int gfar_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
|
static int gfar_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
|
||||||
{
|
{
|
||||||
struct gfar_private *priv = netdev_priv(dev);
|
struct gfar_private *priv = netdev_priv(dev);
|
||||||
|
@ -854,7 +866,9 @@ static int gfar_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (cmd == SIOCSHWTSTAMP)
|
if (cmd == SIOCSHWTSTAMP)
|
||||||
return gfar_hwtstamp_ioctl(dev, rq, cmd);
|
return gfar_hwtstamp_set(dev, rq);
|
||||||
|
if (cmd == SIOCGHWTSTAMP)
|
||||||
|
return gfar_hwtstamp_get(dev, rq);
|
||||||
|
|
||||||
if (!priv->phydev)
|
if (!priv->phydev)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
|
@ -5790,7 +5790,7 @@ static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
|
||||||
* specified. Matching the kind of event packet is not supported, with the
|
* specified. Matching the kind of event packet is not supported, with the
|
||||||
* exception of "all V2 events regardless of level 2 or 4".
|
* exception of "all V2 events regardless of level 2 or 4".
|
||||||
**/
|
**/
|
||||||
static int e1000e_hwtstamp_ioctl(struct net_device *netdev, struct ifreq *ifr)
|
static int e1000e_hwtstamp_set(struct net_device *netdev, struct ifreq *ifr)
|
||||||
{
|
{
|
||||||
struct e1000_adapter *adapter = netdev_priv(netdev);
|
struct e1000_adapter *adapter = netdev_priv(netdev);
|
||||||
struct hwtstamp_config config;
|
struct hwtstamp_config config;
|
||||||
|
@ -5825,6 +5825,14 @@ static int e1000e_hwtstamp_ioctl(struct net_device *netdev, struct ifreq *ifr)
|
||||||
sizeof(config)) ? -EFAULT : 0;
|
sizeof(config)) ? -EFAULT : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int e1000e_hwtstamp_get(struct net_device *netdev, struct ifreq *ifr)
|
||||||
|
{
|
||||||
|
struct e1000_adapter *adapter = netdev_priv(netdev);
|
||||||
|
|
||||||
|
return copy_to_user(ifr->ifr_data, &adapter->hwtstamp_config,
|
||||||
|
sizeof(adapter->hwtstamp_config)) ? -EFAULT : 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
|
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
|
||||||
{
|
{
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
|
@ -5833,7 +5841,9 @@ static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
|
||||||
case SIOCSMIIREG:
|
case SIOCSMIIREG:
|
||||||
return e1000_mii_ioctl(netdev, ifr, cmd);
|
return e1000_mii_ioctl(netdev, ifr, cmd);
|
||||||
case SIOCSHWTSTAMP:
|
case SIOCSHWTSTAMP:
|
||||||
return e1000e_hwtstamp_ioctl(netdev, ifr);
|
return e1000e_hwtstamp_set(netdev, ifr);
|
||||||
|
case SIOCGHWTSTAMP:
|
||||||
|
return e1000e_hwtstamp_get(netdev, ifr);
|
||||||
default:
|
default:
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2025,7 +2025,7 @@ static int mlx4_en_change_mtu(struct net_device *dev, int new_mtu)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mlx4_en_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)
|
static int mlx4_en_hwtstamp_set(struct net_device *dev, struct ifreq *ifr)
|
||||||
{
|
{
|
||||||
struct mlx4_en_priv *priv = netdev_priv(dev);
|
struct mlx4_en_priv *priv = netdev_priv(dev);
|
||||||
struct mlx4_en_dev *mdev = priv->mdev;
|
struct mlx4_en_dev *mdev = priv->mdev;
|
||||||
|
@ -2084,11 +2084,21 @@ static int mlx4_en_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)
|
||||||
sizeof(config)) ? -EFAULT : 0;
|
sizeof(config)) ? -EFAULT : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int mlx4_en_hwtstamp_get(struct net_device *dev, struct ifreq *ifr)
|
||||||
|
{
|
||||||
|
struct mlx4_en_priv *priv = netdev_priv(dev);
|
||||||
|
|
||||||
|
return copy_to_user(ifr->ifr_data, &priv->hwtstamp_config,
|
||||||
|
sizeof(priv->hwtstamp_config)) ? -EFAULT : 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int mlx4_en_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
static int mlx4_en_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
||||||
{
|
{
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case SIOCSHWTSTAMP:
|
case SIOCSHWTSTAMP:
|
||||||
return mlx4_en_hwtstamp_ioctl(dev, ifr);
|
return mlx4_en_hwtstamp_set(dev, ifr);
|
||||||
|
case SIOCGHWTSTAMP:
|
||||||
|
return mlx4_en_hwtstamp_get(dev, ifr);
|
||||||
default:
|
default:
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3189,7 +3189,7 @@ static enum vxge_hw_status vxge_timestamp_config(struct __vxge_hw_device *devh)
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vxge_hwtstamp_ioctl(struct vxgedev *vdev, void __user *data)
|
static int vxge_hwtstamp_set(struct vxgedev *vdev, void __user *data)
|
||||||
{
|
{
|
||||||
struct hwtstamp_config config;
|
struct hwtstamp_config config;
|
||||||
int i;
|
int i;
|
||||||
|
@ -3250,6 +3250,21 @@ static int vxge_hwtstamp_ioctl(struct vxgedev *vdev, void __user *data)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int vxge_hwtstamp_get(struct vxgedev *vdev, void __user *data)
|
||||||
|
{
|
||||||
|
struct hwtstamp_config config;
|
||||||
|
|
||||||
|
config.flags = 0;
|
||||||
|
config.tx_type = HWTSTAMP_TX_OFF;
|
||||||
|
config.rx_filter = (vdev->rx_hwts ?
|
||||||
|
HWTSTAMP_FILTER_ALL : HWTSTAMP_FILTER_NONE);
|
||||||
|
|
||||||
|
if (copy_to_user(data, &config, sizeof(config)))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* vxge_ioctl
|
* vxge_ioctl
|
||||||
* @dev: Device pointer.
|
* @dev: Device pointer.
|
||||||
|
@ -3263,19 +3278,15 @@ static int vxge_hwtstamp_ioctl(struct vxgedev *vdev, void __user *data)
|
||||||
static int vxge_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
|
static int vxge_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
|
||||||
{
|
{
|
||||||
struct vxgedev *vdev = netdev_priv(dev);
|
struct vxgedev *vdev = netdev_priv(dev);
|
||||||
int ret;
|
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case SIOCSHWTSTAMP:
|
case SIOCSHWTSTAMP:
|
||||||
ret = vxge_hwtstamp_ioctl(vdev, rq->ifr_data);
|
return vxge_hwtstamp_set(vdev, rq->ifr_data);
|
||||||
if (ret)
|
case SIOCGHWTSTAMP:
|
||||||
return ret;
|
return vxge_hwtstamp_get(vdev, rq->ifr_data);
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1847,7 +1847,9 @@ static int efx_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd)
|
||||||
struct mii_ioctl_data *data = if_mii(ifr);
|
struct mii_ioctl_data *data = if_mii(ifr);
|
||||||
|
|
||||||
if (cmd == SIOCSHWTSTAMP)
|
if (cmd == SIOCSHWTSTAMP)
|
||||||
return efx_ptp_ioctl(efx, ifr, cmd);
|
return efx_ptp_set_ts_config(efx, ifr);
|
||||||
|
if (cmd == SIOCGHWTSTAMP)
|
||||||
|
return efx_ptp_get_ts_config(efx, ifr);
|
||||||
|
|
||||||
/* Convert phy_id from older PRTAD/DEVAD format */
|
/* Convert phy_id from older PRTAD/DEVAD format */
|
||||||
if ((cmd == SIOCGMIIREG || cmd == SIOCSMIIREG) &&
|
if ((cmd == SIOCGMIIREG || cmd == SIOCSMIIREG) &&
|
||||||
|
|
|
@ -555,7 +555,8 @@ int efx_sriov_set_vf_spoofchk(struct net_device *net_dev, int vf,
|
||||||
|
|
||||||
struct ethtool_ts_info;
|
struct ethtool_ts_info;
|
||||||
void efx_ptp_probe(struct efx_nic *efx);
|
void efx_ptp_probe(struct efx_nic *efx);
|
||||||
int efx_ptp_ioctl(struct efx_nic *efx, struct ifreq *ifr, int cmd);
|
int efx_ptp_set_ts_config(struct efx_nic *efx, struct ifreq *ifr);
|
||||||
|
int efx_ptp_get_ts_config(struct efx_nic *efx, struct ifreq *ifr);
|
||||||
void efx_ptp_get_ts_info(struct efx_nic *efx, struct ethtool_ts_info *ts_info);
|
void efx_ptp_get_ts_info(struct efx_nic *efx, struct ethtool_ts_info *ts_info);
|
||||||
bool efx_ptp_is_ptp_tx(struct efx_nic *efx, struct sk_buff *skb);
|
bool efx_ptp_is_ptp_tx(struct efx_nic *efx, struct sk_buff *skb);
|
||||||
int efx_ptp_tx(struct efx_nic *efx, struct sk_buff *skb);
|
int efx_ptp_tx(struct efx_nic *efx, struct sk_buff *skb);
|
||||||
|
|
|
@ -1231,7 +1231,7 @@ void efx_ptp_get_ts_info(struct efx_nic *efx, struct ethtool_ts_info *ts_info)
|
||||||
1 << HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ);
|
1 << HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ);
|
||||||
}
|
}
|
||||||
|
|
||||||
int efx_ptp_ioctl(struct efx_nic *efx, struct ifreq *ifr, int cmd)
|
int efx_ptp_set_ts_config(struct efx_nic *efx, struct ifreq *ifr)
|
||||||
{
|
{
|
||||||
struct hwtstamp_config config;
|
struct hwtstamp_config config;
|
||||||
int rc;
|
int rc;
|
||||||
|
@ -1251,6 +1251,15 @@ int efx_ptp_ioctl(struct efx_nic *efx, struct ifreq *ifr, int cmd)
|
||||||
? -EFAULT : 0;
|
? -EFAULT : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int efx_ptp_get_ts_config(struct efx_nic *efx, struct ifreq *ifr)
|
||||||
|
{
|
||||||
|
if (!efx->ptp_data)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
return copy_to_user(ifr->ifr_data, &efx->ptp_data->config,
|
||||||
|
sizeof(efx->ptp_data->config)) ? -EFAULT : 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void ptp_event_failure(struct efx_nic *efx, int expected_frag_len)
|
static void ptp_event_failure(struct efx_nic *efx, int expected_frag_len)
|
||||||
{
|
{
|
||||||
struct efx_ptp_data *ptp = efx->ptp_data;
|
struct efx_ptp_data *ptp = efx->ptp_data;
|
||||||
|
|
|
@ -1322,7 +1322,7 @@ static void cpsw_hwtstamp_v2(struct cpsw_priv *priv)
|
||||||
__raw_writel(ETH_P_1588, &priv->regs->ts_ltype);
|
__raw_writel(ETH_P_1588, &priv->regs->ts_ltype);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cpsw_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)
|
static int cpsw_hwtstamp_set(struct net_device *dev, struct ifreq *ifr)
|
||||||
{
|
{
|
||||||
struct cpsw_priv *priv = netdev_priv(dev);
|
struct cpsw_priv *priv = netdev_priv(dev);
|
||||||
struct cpts *cpts = priv->cpts;
|
struct cpts *cpts = priv->cpts;
|
||||||
|
@ -1383,6 +1383,24 @@ static int cpsw_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)
|
||||||
return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
|
return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int cpsw_hwtstamp_get(struct net_device *dev, struct ifreq *ifr)
|
||||||
|
{
|
||||||
|
struct cpsw_priv *priv = netdev_priv(dev);
|
||||||
|
struct cpts *cpts = priv->cpts;
|
||||||
|
struct hwtstamp_config cfg;
|
||||||
|
|
||||||
|
if (priv->version != CPSW_VERSION_1 &&
|
||||||
|
priv->version != CPSW_VERSION_2)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
cfg.flags = 0;
|
||||||
|
cfg.tx_type = cpts->tx_enable ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
|
||||||
|
cfg.rx_filter = (cpts->rx_enable ?
|
||||||
|
HWTSTAMP_FILTER_PTP_V2_EVENT : HWTSTAMP_FILTER_NONE);
|
||||||
|
|
||||||
|
return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /*CONFIG_TI_CPTS*/
|
#endif /*CONFIG_TI_CPTS*/
|
||||||
|
|
||||||
static int cpsw_ndo_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
|
static int cpsw_ndo_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
|
||||||
|
@ -1397,7 +1415,9 @@ static int cpsw_ndo_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
#ifdef CONFIG_TI_CPTS
|
#ifdef CONFIG_TI_CPTS
|
||||||
case SIOCSHWTSTAMP:
|
case SIOCSHWTSTAMP:
|
||||||
return cpsw_hwtstamp_ioctl(dev, req);
|
return cpsw_hwtstamp_set(dev, req);
|
||||||
|
case SIOCGHWTSTAMP:
|
||||||
|
return cpsw_hwtstamp_get(dev, req);
|
||||||
#endif
|
#endif
|
||||||
case SIOCGMIIPHY:
|
case SIOCGMIIPHY:
|
||||||
data->phy_id = priv->slaves[slave_no].phy->addr;
|
data->phy_id = priv->slaves[slave_no].phy->addr;
|
||||||
|
|
|
@ -481,8 +481,7 @@ static void tile_tx_timestamp(struct sk_buff *skb, int instance)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Use ioctl() to enable or disable TX or RX timestamping. */
|
/* Use ioctl() to enable or disable TX or RX timestamping. */
|
||||||
static int tile_hwtstamp_ioctl(struct net_device *dev, struct ifreq *rq,
|
static int tile_hwtstamp_set(struct net_device *dev, struct ifreq *rq)
|
||||||
int cmd)
|
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_PTP_1588_CLOCK_TILEGX
|
#ifdef CONFIG_PTP_1588_CLOCK_TILEGX
|
||||||
struct hwtstamp_config config;
|
struct hwtstamp_config config;
|
||||||
|
@ -535,6 +534,21 @@ static int tile_hwtstamp_ioctl(struct net_device *dev, struct ifreq *rq,
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int tile_hwtstamp_get(struct net_device *dev, struct ifreq *rq)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_PTP_1588_CLOCK_TILEGX
|
||||||
|
struct tile_net_priv *priv = netdev_priv(dev);
|
||||||
|
|
||||||
|
if (copy_to_user(rq->ifr_data, &priv->stamp_cfg,
|
||||||
|
sizeof(priv->stamp_cfg)))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static inline bool filter_packet(struct net_device *dev, void *buf)
|
static inline bool filter_packet(struct net_device *dev, void *buf)
|
||||||
{
|
{
|
||||||
/* Filter packets received before we're up. */
|
/* Filter packets received before we're up. */
|
||||||
|
@ -2098,7 +2112,9 @@ static void tile_net_tx_timeout(struct net_device *dev)
|
||||||
static int tile_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
|
static int tile_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
|
||||||
{
|
{
|
||||||
if (cmd == SIOCSHWTSTAMP)
|
if (cmd == SIOCSHWTSTAMP)
|
||||||
return tile_hwtstamp_ioctl(dev, rq, cmd);
|
return tile_hwtstamp_set(dev, rq);
|
||||||
|
if (cmd == SIOCGHWTSTAMP)
|
||||||
|
return tile_hwtstamp_get(dev, rq);
|
||||||
|
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
|
@ -373,7 +373,7 @@ static void ixp_tx_timestamp(struct port *port, struct sk_buff *skb)
|
||||||
__raw_writel(TX_SNAPSHOT_LOCKED, ®s->channel[ch].ch_event);
|
__raw_writel(TX_SNAPSHOT_LOCKED, ®s->channel[ch].ch_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hwtstamp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
|
static int hwtstamp_set(struct net_device *netdev, struct ifreq *ifr)
|
||||||
{
|
{
|
||||||
struct hwtstamp_config cfg;
|
struct hwtstamp_config cfg;
|
||||||
struct ixp46x_ts_regs *regs;
|
struct ixp46x_ts_regs *regs;
|
||||||
|
@ -417,6 +417,32 @@ static int hwtstamp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
|
||||||
return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
|
return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int hwtstamp_get(struct net_device *netdev, struct ifreq *ifr)
|
||||||
|
{
|
||||||
|
struct hwtstamp_config cfg;
|
||||||
|
struct port *port = netdev_priv(netdev);
|
||||||
|
|
||||||
|
cfg.flags = 0;
|
||||||
|
cfg.tx_type = port->hwts_tx_en ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
|
||||||
|
|
||||||
|
switch (port->hwts_rx_en) {
|
||||||
|
case 0:
|
||||||
|
cfg.rx_filter = HWTSTAMP_FILTER_NONE;
|
||||||
|
break;
|
||||||
|
case PTP_SLAVE_MODE:
|
||||||
|
cfg.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_SYNC;
|
||||||
|
break;
|
||||||
|
case PTP_MASTER_MODE:
|
||||||
|
cfg.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
WARN_ON_ONCE(1);
|
||||||
|
return -ERANGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int ixp4xx_mdio_cmd(struct mii_bus *bus, int phy_id, int location,
|
static int ixp4xx_mdio_cmd(struct mii_bus *bus, int phy_id, int location,
|
||||||
int write, u16 cmd)
|
int write, u16 cmd)
|
||||||
{
|
{
|
||||||
|
@ -959,8 +985,12 @@ static int eth_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
|
||||||
if (!netif_running(dev))
|
if (!netif_running(dev))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (cpu_is_ixp46x() && cmd == SIOCSHWTSTAMP)
|
if (cpu_is_ixp46x()) {
|
||||||
return hwtstamp_ioctl(dev, req, cmd);
|
if (cmd == SIOCSHWTSTAMP)
|
||||||
|
return hwtstamp_set(dev, req);
|
||||||
|
if (cmd == SIOCGHWTSTAMP)
|
||||||
|
return hwtstamp_get(dev, req);
|
||||||
|
}
|
||||||
|
|
||||||
return phy_mii_ioctl(port->phydev, req, cmd);
|
return phy_mii_ioctl(port->phydev, req, cmd);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,17 +26,17 @@ enum {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct hwtstamp_config - %SIOCSHWTSTAMP parameter
|
* struct hwtstamp_config - %SIOCGHWTSTAMP and %SIOCSHWTSTAMP parameter
|
||||||
*
|
*
|
||||||
* @flags: no flags defined right now, must be zero
|
* @flags: no flags defined right now, must be zero for %SIOCSHWTSTAMP
|
||||||
* @tx_type: one of HWTSTAMP_TX_*
|
* @tx_type: one of HWTSTAMP_TX_*
|
||||||
* @rx_type: one of one of HWTSTAMP_FILTER_*
|
* @rx_filter: one of HWTSTAMP_FILTER_*
|
||||||
*
|
*
|
||||||
* %SIOCSHWTSTAMP expects a &struct ifreq with a ifr_data pointer to
|
* %SIOCGHWTSTAMP and %SIOCSHWTSTAMP expect a &struct ifreq with a
|
||||||
* this structure. dev_ifsioc() in the kernel takes care of the
|
* ifr_data pointer to this structure. For %SIOCSHWTSTAMP, if the
|
||||||
* translation between 32 bit userspace and 64 bit kernel. The
|
* driver or hardware does not support the requested @rx_filter value,
|
||||||
* structure is intentionally chosen so that it has the same layout on
|
* the driver may use a more general filter mode. In this case
|
||||||
* 32 and 64 bit systems, don't break this!
|
* @rx_filter will indicate the actual mode on return.
|
||||||
*/
|
*/
|
||||||
struct hwtstamp_config {
|
struct hwtstamp_config {
|
||||||
int flags;
|
int flags;
|
||||||
|
|
|
@ -125,7 +125,8 @@
|
||||||
#define SIOCBRDELIF 0x89a3 /* remove interface from bridge */
|
#define SIOCBRDELIF 0x89a3 /* remove interface from bridge */
|
||||||
|
|
||||||
/* hardware time stamping: parameters in linux/net_tstamp.h */
|
/* hardware time stamping: parameters in linux/net_tstamp.h */
|
||||||
#define SIOCSHWTSTAMP 0x89b0
|
#define SIOCSHWTSTAMP 0x89b0 /* set and get config */
|
||||||
|
#define SIOCGHWTSTAMP 0x89b1 /* get config */
|
||||||
|
|
||||||
/* Device private ioctl calls */
|
/* Device private ioctl calls */
|
||||||
|
|
||||||
|
|
|
@ -327,6 +327,7 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, unsigned int cmd)
|
||||||
cmd == SIOCBRADDIF ||
|
cmd == SIOCBRADDIF ||
|
||||||
cmd == SIOCBRDELIF ||
|
cmd == SIOCBRDELIF ||
|
||||||
cmd == SIOCSHWTSTAMP ||
|
cmd == SIOCSHWTSTAMP ||
|
||||||
|
cmd == SIOCGHWTSTAMP ||
|
||||||
cmd == SIOCWANDEV) {
|
cmd == SIOCWANDEV) {
|
||||||
err = -EOPNOTSUPP;
|
err = -EOPNOTSUPP;
|
||||||
if (ops->ndo_do_ioctl) {
|
if (ops->ndo_do_ioctl) {
|
||||||
|
@ -546,6 +547,7 @@ int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg)
|
||||||
*/
|
*/
|
||||||
default:
|
default:
|
||||||
if (cmd == SIOCWANDEV ||
|
if (cmd == SIOCWANDEV ||
|
||||||
|
cmd == SIOCGHWTSTAMP ||
|
||||||
(cmd >= SIOCDEVPRIVATE &&
|
(cmd >= SIOCDEVPRIVATE &&
|
||||||
cmd <= SIOCDEVPRIVATE + 15)) {
|
cmd <= SIOCDEVPRIVATE + 15)) {
|
||||||
dev_load(net, ifr.ifr_name);
|
dev_load(net, ifr.ifr_name);
|
||||||
|
|
57
net/socket.c
57
net/socket.c
|
@ -2968,11 +2968,8 @@ static int bond_ioctl(struct net *net, unsigned int cmd,
|
||||||
struct compat_ifreq __user *ifr32)
|
struct compat_ifreq __user *ifr32)
|
||||||
{
|
{
|
||||||
struct ifreq kifr;
|
struct ifreq kifr;
|
||||||
struct ifreq __user *uifr;
|
|
||||||
mm_segment_t old_fs;
|
mm_segment_t old_fs;
|
||||||
int err;
|
int err;
|
||||||
u32 data;
|
|
||||||
void __user *datap;
|
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case SIOCBONDENSLAVE:
|
case SIOCBONDENSLAVE:
|
||||||
|
@ -2989,26 +2986,13 @@ static int bond_ioctl(struct net *net, unsigned int cmd,
|
||||||
set_fs(old_fs);
|
set_fs(old_fs);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
case SIOCBONDSLAVEINFOQUERY:
|
|
||||||
case SIOCBONDINFOQUERY:
|
|
||||||
uifr = compat_alloc_user_space(sizeof(*uifr));
|
|
||||||
if (copy_in_user(&uifr->ifr_name, &ifr32->ifr_name, IFNAMSIZ))
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
if (get_user(data, &ifr32->ifr_ifru.ifru_data))
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
datap = compat_ptr(data);
|
|
||||||
if (put_user(datap, &uifr->ifr_ifru.ifru_data))
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
return dev_ioctl(net, cmd, uifr);
|
|
||||||
default:
|
default:
|
||||||
return -ENOIOCTLCMD;
|
return -ENOIOCTLCMD;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int siocdevprivate_ioctl(struct net *net, unsigned int cmd,
|
/* Handle ioctls that use ifreq::ifr_data and just need struct ifreq converted */
|
||||||
|
static int compat_ifr_data_ioctl(struct net *net, unsigned int cmd,
|
||||||
struct compat_ifreq __user *u_ifreq32)
|
struct compat_ifreq __user *u_ifreq32)
|
||||||
{
|
{
|
||||||
struct ifreq __user *u_ifreq64;
|
struct ifreq __user *u_ifreq64;
|
||||||
|
@ -3019,19 +3003,16 @@ static int siocdevprivate_ioctl(struct net *net, unsigned int cmd,
|
||||||
if (copy_from_user(&tmp_buf[0], &(u_ifreq32->ifr_ifrn.ifrn_name[0]),
|
if (copy_from_user(&tmp_buf[0], &(u_ifreq32->ifr_ifrn.ifrn_name[0]),
|
||||||
IFNAMSIZ))
|
IFNAMSIZ))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (__get_user(data32, &u_ifreq32->ifr_ifru.ifru_data))
|
if (get_user(data32, &u_ifreq32->ifr_ifru.ifru_data))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
data64 = compat_ptr(data32);
|
data64 = compat_ptr(data32);
|
||||||
|
|
||||||
u_ifreq64 = compat_alloc_user_space(sizeof(*u_ifreq64));
|
u_ifreq64 = compat_alloc_user_space(sizeof(*u_ifreq64));
|
||||||
|
|
||||||
/* Don't check these user accesses, just let that get trapped
|
|
||||||
* in the ioctl handler instead.
|
|
||||||
*/
|
|
||||||
if (copy_to_user(&u_ifreq64->ifr_ifrn.ifrn_name[0], &tmp_buf[0],
|
if (copy_to_user(&u_ifreq64->ifr_ifrn.ifrn_name[0], &tmp_buf[0],
|
||||||
IFNAMSIZ))
|
IFNAMSIZ))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (__put_user(data64, &u_ifreq64->ifr_ifru.ifru_data))
|
if (put_user(data64, &u_ifreq64->ifr_ifru.ifru_data))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
return dev_ioctl(net, cmd, u_ifreq64);
|
return dev_ioctl(net, cmd, u_ifreq64);
|
||||||
|
@ -3111,27 +3092,6 @@ static int compat_sioc_ifmap(struct net *net, unsigned int cmd,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int compat_siocshwtstamp(struct net *net, struct compat_ifreq __user *uifr32)
|
|
||||||
{
|
|
||||||
void __user *uptr;
|
|
||||||
compat_uptr_t uptr32;
|
|
||||||
struct ifreq __user *uifr;
|
|
||||||
|
|
||||||
uifr = compat_alloc_user_space(sizeof(*uifr));
|
|
||||||
if (copy_in_user(uifr, uifr32, sizeof(struct compat_ifreq)))
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
if (get_user(uptr32, &uifr32->ifr_data))
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
uptr = compat_ptr(uptr32);
|
|
||||||
|
|
||||||
if (put_user(uptr, &uifr->ifr_data))
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
return dev_ioctl(net, SIOCSHWTSTAMP, uifr);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct rtentry32 {
|
struct rtentry32 {
|
||||||
u32 rt_pad1;
|
u32 rt_pad1;
|
||||||
struct sockaddr rt_dst; /* target address */
|
struct sockaddr rt_dst; /* target address */
|
||||||
|
@ -3243,7 +3203,7 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
|
||||||
struct net *net = sock_net(sk);
|
struct net *net = sock_net(sk);
|
||||||
|
|
||||||
if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15))
|
if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15))
|
||||||
return siocdevprivate_ioctl(net, cmd, argp);
|
return compat_ifr_data_ioctl(net, cmd, argp);
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case SIOCSIFBR:
|
case SIOCSIFBR:
|
||||||
|
@ -3263,8 +3223,6 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
|
||||||
case SIOCBONDENSLAVE:
|
case SIOCBONDENSLAVE:
|
||||||
case SIOCBONDRELEASE:
|
case SIOCBONDRELEASE:
|
||||||
case SIOCBONDSETHWADDR:
|
case SIOCBONDSETHWADDR:
|
||||||
case SIOCBONDSLAVEINFOQUERY:
|
|
||||||
case SIOCBONDINFOQUERY:
|
|
||||||
case SIOCBONDCHANGEACTIVE:
|
case SIOCBONDCHANGEACTIVE:
|
||||||
return bond_ioctl(net, cmd, argp);
|
return bond_ioctl(net, cmd, argp);
|
||||||
case SIOCADDRT:
|
case SIOCADDRT:
|
||||||
|
@ -3274,8 +3232,11 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
|
||||||
return do_siocgstamp(net, sock, cmd, argp);
|
return do_siocgstamp(net, sock, cmd, argp);
|
||||||
case SIOCGSTAMPNS:
|
case SIOCGSTAMPNS:
|
||||||
return do_siocgstampns(net, sock, cmd, argp);
|
return do_siocgstampns(net, sock, cmd, argp);
|
||||||
|
case SIOCBONDSLAVEINFOQUERY:
|
||||||
|
case SIOCBONDINFOQUERY:
|
||||||
case SIOCSHWTSTAMP:
|
case SIOCSHWTSTAMP:
|
||||||
return compat_siocshwtstamp(net, argp);
|
case SIOCGHWTSTAMP:
|
||||||
|
return compat_ifr_data_ioctl(net, cmd, argp);
|
||||||
|
|
||||||
case FIOSETOWN:
|
case FIOSETOWN:
|
||||||
case SIOCSPGRP:
|
case SIOCSPGRP:
|
||||||
|
|
Loading…
Add table
Reference in a new issue