Add SIOCSETHERCAP. It's used to change ec_capenable.
This commit is contained in:
parent
a39cc4efa6
commit
7b54e0066d
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: ether.c,v 1.2 2012/11/01 13:43:23 pgoyette Exp $ */
|
/* $NetBSD: ether.c,v 1.3 2018/12/21 08:58:08 msaitoh Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1983, 1993
|
* Copyright (c) 1983, 1993
|
||||||
|
@ -31,7 +31,7 @@
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
__RCSID("$NetBSD: ether.c,v 1.2 2012/11/01 13:43:23 pgoyette Exp $");
|
__RCSID("$NetBSD: ether.c,v 1.3 2018/12/21 08:58:08 msaitoh Exp $");
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
@ -40,6 +40,7 @@ __RCSID("$NetBSD: ether.c,v 1.2 2012/11/01 13:43:23 pgoyette Exp $");
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <net/if_ether.h>
|
#include <net/if_ether.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
@ -55,11 +56,99 @@ __RCSID("$NetBSD: ether.c,v 1.2 2012/11/01 13:43:23 pgoyette Exp $");
|
||||||
|
|
||||||
static void ether_status(prop_dictionary_t, prop_dictionary_t);
|
static void ether_status(prop_dictionary_t, prop_dictionary_t);
|
||||||
static void ether_constructor(void) __attribute__((constructor));
|
static void ether_constructor(void) __attribute__((constructor));
|
||||||
|
static int setethercaps(prop_dictionary_t, prop_dictionary_t);
|
||||||
|
|
||||||
static status_func_t status;
|
static status_func_t status;
|
||||||
|
static cmdloop_branch_t branch;
|
||||||
|
|
||||||
#define MAX_PRINT_LEN 55
|
#define MAX_PRINT_LEN 55
|
||||||
|
|
||||||
|
static const struct kwinst ethercapskw[] = {
|
||||||
|
#if 0 /* notyet */
|
||||||
|
IFKW("vlan-hwfilter", ETHERCAP_VLAN_HWFILTER)
|
||||||
|
#endif
|
||||||
|
IFKW("eee", ETHERCAP_EEE)
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pkw ethercaps = PKW_INITIALIZER(ðercaps, "ethercaps", setethercaps,
|
||||||
|
"ethercap", ethercapskw, __arraycount(ethercapskw),
|
||||||
|
&command_root.pb_parser);
|
||||||
|
|
||||||
|
void
|
||||||
|
do_setethercaps(prop_dictionary_t env)
|
||||||
|
{
|
||||||
|
struct eccapreq eccr;
|
||||||
|
prop_data_t d;
|
||||||
|
|
||||||
|
d = (prop_data_t )prop_dictionary_get(env, "ethercaps");
|
||||||
|
if (d == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
assert(sizeof(eccr) == prop_data_size(d));
|
||||||
|
|
||||||
|
memcpy(&eccr, prop_data_data_nocopy(d), sizeof(eccr));
|
||||||
|
if (direct_ioctl(env, SIOCSETHERCAP, &eccr) == -1)
|
||||||
|
err(EXIT_FAILURE, "SIOCSETHERCAP");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
getethercaps(prop_dictionary_t env, prop_dictionary_t oenv,
|
||||||
|
struct eccapreq *oeccr)
|
||||||
|
{
|
||||||
|
bool rc;
|
||||||
|
struct eccapreq eccr;
|
||||||
|
const struct eccapreq *tmpeccr;
|
||||||
|
prop_data_t capdata;
|
||||||
|
|
||||||
|
capdata = (prop_data_t)prop_dictionary_get(env, "ethercaps");
|
||||||
|
|
||||||
|
if (capdata != NULL) {
|
||||||
|
tmpeccr = prop_data_data_nocopy(capdata);
|
||||||
|
*oeccr = *tmpeccr;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)direct_ioctl(env, SIOCGETHERCAP, &eccr);
|
||||||
|
*oeccr = eccr;
|
||||||
|
|
||||||
|
capdata = prop_data_create_data(&eccr, sizeof(eccr));
|
||||||
|
|
||||||
|
rc = prop_dictionary_set(oenv, "ethercaps", capdata);
|
||||||
|
|
||||||
|
prop_object_release((prop_object_t)capdata);
|
||||||
|
|
||||||
|
return rc ? 0 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
setethercaps(prop_dictionary_t env, prop_dictionary_t oenv)
|
||||||
|
{
|
||||||
|
int64_t ethercap;
|
||||||
|
bool rc;
|
||||||
|
prop_data_t capdata;
|
||||||
|
struct eccapreq eccr;
|
||||||
|
|
||||||
|
rc = prop_dictionary_get_int64(env, "ethercap", ðercap);
|
||||||
|
assert(rc);
|
||||||
|
|
||||||
|
if (getethercaps(env, oenv, &eccr) == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (ethercap < 0) {
|
||||||
|
ethercap = -ethercap;
|
||||||
|
eccr.eccr_capenable &= ~ethercap;
|
||||||
|
} else
|
||||||
|
eccr.eccr_capenable |= ethercap;
|
||||||
|
|
||||||
|
if ((capdata = prop_data_create_data(&eccr, sizeof(eccr))) == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
rc = prop_dictionary_set(oenv, "ethercaps", capdata);
|
||||||
|
prop_object_release((prop_object_t)capdata);
|
||||||
|
|
||||||
|
return rc ? 0 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ether_status(prop_dictionary_t env, prop_dictionary_t oenv)
|
ether_status(prop_dictionary_t env, prop_dictionary_t oenv)
|
||||||
{
|
{
|
||||||
|
@ -94,6 +183,8 @@ static void
|
||||||
ether_constructor(void)
|
ether_constructor(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
cmdloop_branch_init(&branch, ðercaps.pk_parser);
|
||||||
|
register_cmdloop_branch(&branch);
|
||||||
status_func_init(&status, ether_status);
|
status_func_init(&status, ether_status);
|
||||||
register_status(&status);
|
register_status(&status);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: extern.h,v 1.14 2009/08/07 18:53:37 dyoung Exp $ */
|
/* $NetBSD: extern.h,v 1.15 2018/12/21 08:58:08 msaitoh Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1983, 1993
|
* Copyright (c) 1983, 1993
|
||||||
|
@ -87,6 +87,7 @@ int register_status(status_func_t *);
|
||||||
int register_usage(usage_func_t *);
|
int register_usage(usage_func_t *);
|
||||||
int register_flag(int);
|
int register_flag(int);
|
||||||
bool get_flag(int);
|
bool get_flag(int);
|
||||||
|
void do_setethercaps(prop_dictionary_t);
|
||||||
|
|
||||||
extern bool lflag, Nflag, vflag, zflag;
|
extern bool lflag, Nflag, vflag, zflag;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: ifconfig.c,v 1.237 2018/11/15 04:36:46 ozaki-r Exp $ */
|
/* $NetBSD: ifconfig.c,v 1.238 2018/12/21 08:58:08 msaitoh Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1997, 1998, 2000 The NetBSD Foundation, Inc.
|
* Copyright (c) 1997, 1998, 2000 The NetBSD Foundation, Inc.
|
||||||
|
@ -63,7 +63,7 @@
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
__COPYRIGHT("@(#) Copyright (c) 1983, 1993\
|
__COPYRIGHT("@(#) Copyright (c) 1983, 1993\
|
||||||
The Regents of the University of California. All rights reserved.");
|
The Regents of the University of California. All rights reserved.");
|
||||||
__RCSID("$NetBSD: ifconfig.c,v 1.237 2018/11/15 04:36:46 ozaki-r Exp $");
|
__RCSID("$NetBSD: ifconfig.c,v 1.238 2018/12/21 08:58:08 msaitoh Exp $");
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
@ -799,6 +799,7 @@ main(int argc, char **argv)
|
||||||
|
|
||||||
do_setifpreference(env);
|
do_setifpreference(env);
|
||||||
do_setifcaps(env);
|
do_setifcaps(env);
|
||||||
|
do_setethercaps(env);
|
||||||
|
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: if.c,v 1.442 2018/12/12 01:46:47 rin Exp $ */
|
/* $NetBSD: if.c,v 1.443 2018/12/21 08:58:08 msaitoh Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1999, 2000, 2001, 2008 The NetBSD Foundation, Inc.
|
* Copyright (c) 1999, 2000, 2001, 2008 The NetBSD Foundation, Inc.
|
||||||
|
@ -90,7 +90,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.442 2018/12/12 01:46:47 rin Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.443 2018/12/21 08:58:08 msaitoh Exp $");
|
||||||
|
|
||||||
#if defined(_KERNEL_OPT)
|
#if defined(_KERNEL_OPT)
|
||||||
#include "opt_inet.h"
|
#include "opt_inet.h"
|
||||||
|
@ -3230,6 +3230,7 @@ doifioctl(struct socket *so, u_long cmd, void *data, struct lwp *l)
|
||||||
case SIOCSLIFPHYADDR:
|
case SIOCSLIFPHYADDR:
|
||||||
case SIOCADDMULTI:
|
case SIOCADDMULTI:
|
||||||
case SIOCDELMULTI:
|
case SIOCDELMULTI:
|
||||||
|
case SIOCSETHERCAP:
|
||||||
case SIOCSIFMEDIA:
|
case SIOCSIFMEDIA:
|
||||||
case SIOCSDRVSPEC:
|
case SIOCSDRVSPEC:
|
||||||
case SIOCG80211:
|
case SIOCG80211:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: if_ethersubr.c,v 1.271 2018/11/15 10:23:56 maxv Exp $ */
|
/* $NetBSD: if_ethersubr.c,v 1.272 2018/12/21 08:58:08 msaitoh Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||||
|
@ -61,7 +61,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.271 2018/11/15 10:23:56 maxv Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.272 2018/12/21 08:58:08 msaitoh Exp $");
|
||||||
|
|
||||||
#ifdef _KERNEL_OPT
|
#ifdef _KERNEL_OPT
|
||||||
#include "opt_inet.h"
|
#include "opt_inet.h"
|
||||||
|
@ -1372,6 +1372,48 @@ ether_set_ifflags_cb(struct ethercom *ec, ether_cb_t cb)
|
||||||
ec->ec_ifflags_cb = cb;
|
ec->ec_ifflags_cb = cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ether_ioctl_reinit(struct ethercom *ec)
|
||||||
|
{
|
||||||
|
struct ifnet *ifp = &ec->ec_if;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
|
||||||
|
case IFF_RUNNING:
|
||||||
|
/*
|
||||||
|
* If interface is marked down and it is running,
|
||||||
|
* then stop and disable it.
|
||||||
|
*/
|
||||||
|
(*ifp->if_stop)(ifp, 1);
|
||||||
|
break;
|
||||||
|
case IFF_UP:
|
||||||
|
/*
|
||||||
|
* If interface is marked up and it is stopped, then
|
||||||
|
* start it.
|
||||||
|
*/
|
||||||
|
return (*ifp->if_init)(ifp);
|
||||||
|
case IFF_UP | IFF_RUNNING:
|
||||||
|
error = 0;
|
||||||
|
if (ec->ec_ifflags_cb != NULL) {
|
||||||
|
error = (*ec->ec_ifflags_cb)(ec);
|
||||||
|
if (error == ENETRESET) {
|
||||||
|
/*
|
||||||
|
* Reset the interface to pick up
|
||||||
|
* changes in any other flags that
|
||||||
|
* affect the hardware state.
|
||||||
|
*/
|
||||||
|
return (*ifp->if_init)(ifp);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
error = (*ifp->if_init)(ifp);
|
||||||
|
return error;
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Common ioctls for Ethernet interfaces. Note, we must be
|
* Common ioctls for Ethernet interfaces. Note, we must be
|
||||||
* called at splnet().
|
* called at splnet().
|
||||||
|
@ -1379,7 +1421,7 @@ ether_set_ifflags_cb(struct ethercom *ec, ether_cb_t cb)
|
||||||
int
|
int
|
||||||
ether_ioctl(struct ifnet *ifp, u_long cmd, void *data)
|
ether_ioctl(struct ifnet *ifp, u_long cmd, void *data)
|
||||||
{
|
{
|
||||||
struct ethercom *ec = (void *) ifp;
|
struct ethercom *ec = (void *)ifp;
|
||||||
struct eccapreq *eccr;
|
struct eccapreq *eccr;
|
||||||
struct ifreq *ifr = (struct ifreq *)data;
|
struct ifreq *ifr = (struct ifreq *)data;
|
||||||
struct if_laddrreq *iflr = data;
|
struct if_laddrreq *iflr = data;
|
||||||
|
@ -1428,44 +1470,25 @@ ether_ioctl(struct ifnet *ifp, u_long cmd, void *data)
|
||||||
case SIOCSIFFLAGS:
|
case SIOCSIFFLAGS:
|
||||||
if ((error = ifioctl_common(ifp, cmd, data)) != 0)
|
if ((error = ifioctl_common(ifp, cmd, data)) != 0)
|
||||||
return error;
|
return error;
|
||||||
switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
|
return ether_ioctl_reinit(ec);
|
||||||
case IFF_RUNNING:
|
|
||||||
/*
|
|
||||||
* If interface is marked down and it is running,
|
|
||||||
* then stop and disable it.
|
|
||||||
*/
|
|
||||||
(*ifp->if_stop)(ifp, 1);
|
|
||||||
break;
|
|
||||||
case IFF_UP:
|
|
||||||
/*
|
|
||||||
* If interface is marked up and it is stopped, then
|
|
||||||
* start it.
|
|
||||||
*/
|
|
||||||
return (*ifp->if_init)(ifp);
|
|
||||||
case IFF_UP | IFF_RUNNING:
|
|
||||||
error = 0;
|
|
||||||
if (ec->ec_ifflags_cb != NULL) {
|
|
||||||
error = (*ec->ec_ifflags_cb)(ec);
|
|
||||||
if (error == ENETRESET) {
|
|
||||||
/*
|
|
||||||
* Reset the interface to pick up
|
|
||||||
* changes in any other flags that
|
|
||||||
* affect the hardware state.
|
|
||||||
*/
|
|
||||||
return (*ifp->if_init)(ifp);
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
error = (*ifp->if_init)(ifp);
|
|
||||||
return error;
|
|
||||||
case 0:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
case SIOCGETHERCAP:
|
case SIOCGETHERCAP:
|
||||||
eccr = (struct eccapreq *)data;
|
eccr = (struct eccapreq *)data;
|
||||||
eccr->eccr_capabilities = ec->ec_capabilities;
|
eccr->eccr_capabilities = ec->ec_capabilities;
|
||||||
eccr->eccr_capenable = ec->ec_capenable;
|
eccr->eccr_capenable = ec->ec_capenable;
|
||||||
return 0;
|
return 0;
|
||||||
|
case SIOCSETHERCAP:
|
||||||
|
eccr = (struct eccapreq *)data;
|
||||||
|
if ((eccr->eccr_capenable & ~ec->ec_capabilities) != 0)
|
||||||
|
return EINVAL;
|
||||||
|
if (eccr->eccr_capenable == ec->ec_capenable)
|
||||||
|
return 0;
|
||||||
|
#if 0 /* notyet */
|
||||||
|
ec->ec_capenable = (ec->ec_capenable & ETHERCAP_CANTCHANGE)
|
||||||
|
| (eccr->eccr_capenable & ~ETHERCAP_CANTCHANGE);
|
||||||
|
#else
|
||||||
|
ec->ec_capenable = eccr->eccr_capenable;
|
||||||
|
#endif
|
||||||
|
return ether_ioctl_reinit(ec);
|
||||||
case SIOCADDMULTI:
|
case SIOCADDMULTI:
|
||||||
return ether_addmulti(ifreq_getaddr(cmd, ifr), ec);
|
return ether_addmulti(ifreq_getaddr(cmd, ifr), ec);
|
||||||
case SIOCDELMULTI:
|
case SIOCDELMULTI:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: sockio.h,v 1.35 2018/08/01 23:35:32 rjs Exp $ */
|
/* $NetBSD: sockio.h,v 1.36 2018/12/21 08:58:08 msaitoh Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1982, 1986, 1990, 1993, 1994
|
* Copyright (c) 1982, 1986, 1990, 1993, 1994
|
||||||
|
@ -141,6 +141,7 @@
|
||||||
|
|
||||||
#define SIOCGETHERCAP _IOWR('i', 139, struct eccapreq) /* get ethercap */
|
#define SIOCGETHERCAP _IOWR('i', 139, struct eccapreq) /* get ethercap */
|
||||||
#define SIOCGIFINDEX _IOWR('i', 140, struct ifreq) /* get ifnet index */
|
#define SIOCGIFINDEX _IOWR('i', 140, struct ifreq) /* get ifnet index */
|
||||||
|
#define SIOCSETHERCAP _IOW('i', 141, struct eccapreq) /* set ethercap */
|
||||||
|
|
||||||
#define SIOCGUMBINFO _IOWR('i', 190, struct ifreq) /* get MBIM info */
|
#define SIOCGUMBINFO _IOWR('i', 190, struct ifreq) /* get MBIM info */
|
||||||
#define SIOCSUMBPARAM _IOW('i', 191, struct ifreq) /* set MBIM param */
|
#define SIOCSUMBPARAM _IOW('i', 191, struct ifreq) /* set MBIM param */
|
||||||
|
|
Loading…
Reference in New Issue