summaryrefslogtreecommitdiffstats
path: root/sys/dev/an
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2001-05-26 09:27:08 +0000
committerphk <phk@FreeBSD.org>2001-05-26 09:27:08 +0000
commit1aacce7a450370feff7a5e098c12e915e4f731f8 (patch)
treea706c2fc726d426b9f75667c81d6227ef2f9ea18 /sys/dev/an
parent2072a71f0e5186928f3cb8cfac61fe8199029442 (diff)
downloadFreeBSD-src-1aacce7a450370feff7a5e098c12e915e4f731f8.zip
FreeBSD-src-1aacce7a450370feff7a5e098c12e915e4f731f8.tar.gz
Currently, each wireless networking driver has it's own control program
despite the fact that most people want to set exactly the same settings regardless of which card they have. It has been repeatidly suggested that this configuration should be done via ifconfig. This patch implements the required functionality in ifconfig and add support to the wi and an drivers. It also provides partial, untested support for the awi driver. PR: 25577 Submitted by: Brooks Davis <brooks@one-eyed-alien.net>
Diffstat (limited to 'sys/dev/an')
-rw-r--r--sys/dev/an/if_aironet_ieee.h2
-rw-r--r--sys/dev/an/if_an.c500
-rw-r--r--sys/dev/an/if_an_isa.c2
-rw-r--r--sys/dev/an/if_an_pccard.c2
-rw-r--r--sys/dev/an/if_an_pci.c2
-rw-r--r--sys/dev/an/if_anreg.h5
6 files changed, 508 insertions, 5 deletions
diff --git a/sys/dev/an/if_aironet_ieee.h b/sys/dev/an/if_aironet_ieee.h
index bcbd32f..a1eeb26 100644
--- a/sys/dev/an/if_aironet_ieee.h
+++ b/sys/dev/an/if_aironet_ieee.h
@@ -336,6 +336,7 @@ struct an_ltv_genconfig {
u_int8_t an_magic_packet_ctl; /* 0x99 */
u_int16_t an_rsvd9;
};
+#endif
#define AN_OPMODE_IBSS_ADHOC 0x0000
#define AN_OPMODE_INFRASTRUCTURE_STATION 0x0001
@@ -395,6 +396,7 @@ struct an_ltv_genconfig {
#define AN_HOME_NETWORK 0x0001
#define AN_HOME_INSTALL_AP 0x0002
+#ifndef _KERNEL
struct an_ltv_ssidlist {
u_int16_t an_len;
u_int16_t an_type;
diff --git a/sys/dev/an/if_an.c b/sys/dev/an/if_an.c
index 2b38284..c7843e6 100644
--- a/sys/dev/an/if_an.c
+++ b/sys/dev/an/if_an.c
@@ -113,6 +113,8 @@
#include <net/ethernet.h>
#include <net/if_dl.h>
#include <net/if_types.h>
+#include <net/if_ieee80211.h>
+#include <net/if_media.h>
#ifdef INET
#include <netinet/in.h>
@@ -160,6 +162,9 @@ static void an_cache_store __P((struct an_softc *, struct ether_header *,
struct mbuf *, unsigned short));
#endif
+static int an_media_change __P((struct ifnet *));
+static void an_media_status __P((struct ifnet *, struct ifmediareq *));
+
/*
* We probe for an Aironet 4500/4800 card by attempting to
* read the default SSID list. On reset, the first entry in
@@ -380,6 +385,31 @@ int an_attach(sc, unit, flags)
sc->an_tx_rate = 0;
bzero((char *)&sc->an_stats, sizeof(sc->an_stats));
+ ifmedia_init(&sc->an_ifmedia, 0, an_media_change, an_media_status);
+#define ADD(m, c) ifmedia_add(&sc->an_ifmedia, (m), (c), NULL)
+ ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1,
+ IFM_IEEE80211_ADHOC, 0), 0);
+ ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1, 0, 0), 0);
+ ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2,
+ IFM_IEEE80211_ADHOC, 0), 0);
+ ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, 0, 0), 0);
+ if(sc->an_caps.an_rates[2] == AN_RATE_5_5MBPS) {
+ ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5,
+ IFM_IEEE80211_ADHOC, 0), 0);
+ ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5, 0, 0), 0);
+ }
+ if(sc->an_caps.an_rates[3] == AN_RATE_11MBPS) {
+ ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11,
+ IFM_IEEE80211_ADHOC, 0), 0);
+ ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, 0, 0), 0);
+ }
+ ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO,
+ IFM_IEEE80211_ADHOC, 0), 0);
+ ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 0, 0), 0);
+#undef ADD
+ ifmedia_set(&sc->an_ifmedia, IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO,
+ 0, 0));
+
/*
* Call MI attach routine.
*/
@@ -713,10 +743,10 @@ static int an_read_record(sc, ltv)
* room to hold all of the returned data).
*/
len = CSR_READ_2(sc, AN_DATA1);
- if (len > ltv->an_len) {
+ if (len > (ltv->an_len - 2)) {
printf("an%d: record length mismatch -- expected %d, "
- "got %d\n", sc->an_unit, ltv->an_len, len);
- return(ENOSPC);
+ "got %d\n", sc->an_unit, (ltv->an_len - 2), len);
+ len = (ltv->an_len - 2);
}
ltv->an_len = len;
@@ -981,14 +1011,29 @@ static int an_ioctl(ifp, command, data)
caddr_t data;
{
int error = 0;
+ int len;
+ int i;
struct an_softc *sc;
struct an_req areq;
struct ifreq *ifr;
struct proc *p = curproc;
+ struct ieee80211req *ireq;
+ u_int8_t tmpstr[IEEE80211_NWID_LEN*2];
+ u_int8_t *tmpptr;
+ struct an_ltv_genconfig *config;
+ struct an_ltv_key *key;
+ struct an_ltv_status *status;
+ struct an_ltv_ssidlist *ssids;
sc = ifp->if_softc;
AN_LOCK(sc);
ifr = (struct ifreq *)data;
+ ireq = (struct ieee80211req *)data;
+
+ config = (struct an_ltv_genconfig *)&areq;
+ key = (struct an_ltv_key *)&areq;
+ status = (struct an_ltv_status *)&areq;
+ ssids = (struct an_ltv_ssidlist *)&areq;
if (sc->an_gone) {
error = ENODEV;
@@ -1020,6 +1065,10 @@ static int an_ioctl(ifp, command, data)
sc->an_if_flags = ifp->if_flags;
error = 0;
break;
+ case SIOCSIFMEDIA:
+ case SIOCGIFMEDIA:
+ error = ifmedia_ioctl(ifp, ifr, &sc->an_ifmedia, command);
+ break;
case SIOCADDMULTI:
case SIOCDELMULTI:
/* The Aironet has no multicast filter. */
@@ -1059,6 +1108,369 @@ static int an_ioctl(ifp, command, data)
break;
an_setdef(sc, &areq);
break;
+ case SIOCG80211:
+ areq.an_len = sizeof(areq);
+ switch(ireq->i_type) {
+ case IEEE80211_IOC_SSID:
+ if(ireq->i_val == -1) {
+ areq.an_type = AN_RID_STATUS;
+ if (an_read_record(sc,
+ (struct an_ltv_gen *)&areq)) {
+ error = EINVAL;
+ break;
+ }
+ len = status->an_ssidlen;
+ tmpptr = status->an_ssid;
+ } else if(ireq->i_val >= 0) {
+ areq.an_type = AN_RID_SSIDLIST;
+ if (an_read_record(sc,
+ (struct an_ltv_gen *)&areq)) {
+ error = EINVAL;
+ break;
+ }
+ if(ireq->i_val == 0) {
+ len = ssids->an_ssid1_len;
+ tmpptr = ssids->an_ssid1;
+ } else if(ireq->i_val == 1) {
+ len = ssids->an_ssid2_len;
+ tmpptr = ssids->an_ssid3;
+ } else if(ireq->i_val == 1) {
+ len = ssids->an_ssid3_len;
+ tmpptr = ssids->an_ssid3;
+ } else {
+ error = EINVAL;
+ break;
+ }
+ } else {
+ error = EINVAL;
+ break;
+ }
+ if(len > IEEE80211_NWID_LEN) {
+ error = EINVAL;
+ break;
+ }
+ ireq->i_len = len;
+ bzero(tmpstr, IEEE80211_NWID_LEN);
+ bcopy(tmpptr, tmpstr, len);
+ error = copyout(tmpstr, ireq->i_data,
+ IEEE80211_NWID_LEN);
+ break;
+ case IEEE80211_IOC_NUMSSIDS:
+ ireq->i_val = 3;
+ break;
+ case IEEE80211_IOC_WEP:
+ areq.an_type = AN_RID_ACTUALCFG;
+ if (an_read_record(sc,
+ (struct an_ltv_gen *)&areq)) {
+ error = EINVAL;
+ break;
+ }
+ if(config->an_authtype & AN_AUTHTYPE_PRIVACY_IN_USE) {
+ if(config->an_authtype &
+ AN_AUTHTYPE_ALLOW_UNENCRYPTED)
+ ireq->i_val = IEEE80211_WEP_MIXED;
+ else
+ ireq->i_val = IEEE80211_WEP_ON;
+
+ } else {
+ ireq->i_val = IEEE80211_WEP_OFF;
+ }
+ break;
+ case IEEE80211_IOC_WEPKEY:
+ /*
+ * XXX: I'm not entierly convinced this is
+ * correct, but it's what is implemented in
+ * ancontrol so it will have to do until we get
+ * access to actual Cisco code.
+ */
+ if(ireq->i_val < 0 || ireq->i_val > 7) {
+ error = EINVAL;
+ break;
+ }
+ len = 0;
+ if(ireq->i_val < 4) {
+ areq.an_type = AN_RID_WEP_TEMP;
+ for(i=0; i<4; i++) {
+ areq.an_len = sizeof(areq);
+ if (an_read_record(sc,
+ (struct an_ltv_gen *)&areq)) {
+ error = EINVAL;
+ break;
+ }
+ len = key->klen;
+ if(i == ireq->i_val)
+ break;
+ /* Required to get next entry */
+ areq.an_type = AN_RID_WEP_PERM;
+ }
+ if(error)
+ break;
+ }
+ /* We aren't allowed to read the value of the
+ * key from the card so we just output zeros
+ * like we would if we could read the card, but
+ * denied the user access.
+ */
+ bzero(tmpstr, len);
+ ireq->i_len = len;
+ error = copyout(tmpstr, ireq->i_data, len);
+ break;
+ case IEEE80211_IOC_NUMWEPKEYS:
+ ireq->i_val = 8;
+ break;
+ case IEEE80211_IOC_WEPTXKEY:
+ areq.an_type = AN_RID_WEP_PERM;
+ key->kindex = 0xffff;
+ if (an_read_record(sc,
+ (struct an_ltv_gen *)&areq)) {
+ error = EINVAL;
+ break;
+ }
+ ireq->i_val = key->mac[0];
+ break;
+ case IEEE80211_IOC_AUTHMODE:
+ areq.an_type = AN_RID_ACTUALCFG;
+ if (an_read_record(sc,
+ (struct an_ltv_gen *)&areq)) {
+ error = EINVAL;
+ break;
+ }
+ if ((config->an_authtype & AN_AUTHTYPE_MASK) ==
+ AN_AUTHTYPE_NONE) {
+ ireq->i_val = IEEE80211_AUTH_NONE;
+ } else if ((config->an_authtype & AN_AUTHTYPE_MASK) ==
+ AN_AUTHTYPE_OPEN) {
+ ireq->i_val = IEEE80211_AUTH_OPEN;
+ } else if ((config->an_authtype & AN_AUTHTYPE_MASK) ==
+ AN_AUTHTYPE_SHAREDKEY) {
+ ireq->i_val = IEEE80211_AUTH_SHARED;
+ } else
+ error = EINVAL;
+ break;
+ case IEEE80211_IOC_STATIONNAME:
+ areq.an_type = AN_RID_ACTUALCFG;
+ if (an_read_record(sc,
+ (struct an_ltv_gen *)&areq)) {
+ error = EINVAL;
+ break;
+ }
+ ireq->i_len = sizeof(config->an_nodename);
+ tmpptr = config->an_nodename;
+ bzero(tmpstr, IEEE80211_NWID_LEN);
+ bcopy(tmpptr, tmpstr, ireq->i_len);
+ error = copyout(tmpstr, ireq->i_data,
+ IEEE80211_NWID_LEN);
+ break;
+ case IEEE80211_IOC_CHANNEL:
+ areq.an_type = AN_RID_STATUS;
+ if (an_read_record(sc,
+ (struct an_ltv_gen *)&areq)) {
+ error = EINVAL;
+ break;
+ }
+ ireq->i_val = status->an_cur_channel;
+ break;
+ case IEEE80211_IOC_POWERSAVE:
+ areq.an_type = AN_RID_ACTUALCFG;
+ if (an_read_record(sc,
+ (struct an_ltv_gen *)&areq)) {
+ error = EINVAL;
+ break;
+ }
+ if(config->an_psave_mode == AN_PSAVE_NONE) {
+ ireq->i_val = IEEE80211_POWERSAVE_OFF;
+ } else if(config->an_psave_mode == AN_PSAVE_CAM) {
+ ireq->i_val = IEEE80211_POWERSAVE_CAM;
+ } else if(config->an_psave_mode == AN_PSAVE_PSP) {
+ ireq->i_val = IEEE80211_POWERSAVE_PSP;
+ } else if(config->an_psave_mode == AN_PSAVE_PSP_CAM) {
+ ireq->i_val = IEEE80211_POWERSAVE_PSP_CAM;
+ } else
+ error = EINVAL;
+ break;
+ case IEEE80211_IOC_POWERSAVESLEEP:
+ areq.an_type = AN_RID_ACTUALCFG;
+ if (an_read_record(sc,
+ (struct an_ltv_gen *)&areq)) {
+ error = EINVAL;
+ break;
+ }
+ ireq->i_val = config->an_listen_interval;
+ break;
+ }
+ break;
+ case SIOCS80211:
+ if ((error = suser(p)))
+ goto out;
+ areq.an_len = sizeof(areq);
+ /*
+ * We need a config structure for everything but the WEP
+ * key management and SSIDs so we get it now so avoid
+ * duplicating this code every time.
+ */
+ if (ireq->i_type != IEEE80211_IOC_SSID &&
+ ireq->i_type != IEEE80211_IOC_WEPKEY &&
+ ireq->i_type != IEEE80211_IOC_WEPTXKEY) {
+ areq.an_type = AN_RID_GENCONFIG;
+ if (an_read_record(sc,
+ (struct an_ltv_gen *)&areq)) {
+ error = EINVAL;
+ break;
+ }
+ }
+ switch(ireq->i_type) {
+ case IEEE80211_IOC_SSID:
+ areq.an_type = AN_RID_SSIDLIST;
+ if (an_read_record(sc,
+ (struct an_ltv_gen *)&areq)) {
+ error = EINVAL;
+ break;
+ }
+ if(ireq->i_len > IEEE80211_NWID_LEN) {
+ error = EINVAL;
+ break;
+ }
+ switch (ireq->i_val) {
+ case 0:
+ error = copyin(ireq->i_data,
+ ssids->an_ssid1, ireq->i_len);
+ ssids->an_ssid1_len = ireq->i_len;
+ break;
+ case 1:
+ error = copyin(ireq->i_data,
+ ssids->an_ssid2, ireq->i_len);
+ ssids->an_ssid2_len = ireq->i_len;
+ break;
+ case 2:
+ error = copyin(ireq->i_data,
+ ssids->an_ssid3, ireq->i_len);
+ ssids->an_ssid3_len = ireq->i_len;
+ break;
+ default:
+ error = EINVAL;
+ break;
+ }
+ break;
+ case IEEE80211_IOC_WEP:
+ switch (ireq->i_val) {
+ case IEEE80211_WEP_OFF:
+ config->an_authtype &=
+ ~(AN_AUTHTYPE_PRIVACY_IN_USE |
+ AN_AUTHTYPE_ALLOW_UNENCRYPTED);
+ break;
+ case IEEE80211_WEP_ON:
+ config->an_authtype |=
+ AN_AUTHTYPE_PRIVACY_IN_USE;
+ config->an_authtype &=
+ ~AN_AUTHTYPE_ALLOW_UNENCRYPTED;
+ break;
+ case IEEE80211_WEP_MIXED:
+ config->an_authtype |=
+ AN_AUTHTYPE_PRIVACY_IN_USE |
+ AN_AUTHTYPE_ALLOW_UNENCRYPTED;
+ break;
+ default:
+ error = EINVAL;
+ break;
+ }
+ break;
+ case IEEE80211_IOC_WEPKEY:
+ if (ireq->i_val < 0 || ireq->i_val > 7 ||
+ ireq->i_len > 13) {
+ error = EINVAL;
+ break;
+ }
+ error = copyin(ireq->i_data, tmpstr, 13);
+ if(error)
+ break;
+ bzero(&areq, sizeof(struct an_ltv_key));
+ areq.an_len = sizeof(struct an_ltv_key);
+ key->mac[0] = 1; /* The others are 0. */
+ key->kindex = ireq->i_val % 4;
+ if(ireq->i_val < 4)
+ areq.an_type = AN_RID_WEP_TEMP;
+ else
+ areq.an_type = AN_RID_WEP_PERM;
+ key->klen = ireq->i_len;
+ bcopy(tmpstr, key->key, key->klen);
+ break;
+ case IEEE80211_IOC_WEPTXKEY:
+ if(ireq->i_val < 0 || ireq->i_val > 3) {
+ error = EINVAL;
+ break;
+ }
+ bzero(&areq, sizeof(struct an_ltv_key));
+ areq.an_len = sizeof(struct an_ltv_key);
+ areq.an_type = AN_RID_WEP_PERM;
+ key->kindex = 0xffff;
+ key->mac[0] = ireq->i_val;
+ break;
+ case IEEE80211_IOC_AUTHMODE:
+ switch (ireq->i_val) {
+ case IEEE80211_AUTH_NONE:
+ config->an_authtype = AN_AUTHTYPE_NONE |
+ (config->an_authtype & ~AN_AUTHTYPE_MASK);
+ break;
+ case IEEE80211_AUTH_OPEN:
+ config->an_authtype = AN_AUTHTYPE_OPEN |
+ (config->an_authtype & ~AN_AUTHTYPE_MASK);
+ break;
+ case IEEE80211_AUTH_SHARED:
+ config->an_authtype = AN_AUTHTYPE_SHAREDKEY |
+ (config->an_authtype & ~AN_AUTHTYPE_MASK);
+ break;
+ default:
+ error = EINVAL;
+ }
+ break;
+ case IEEE80211_IOC_STATIONNAME:
+ if(ireq->i_len > 16) {
+ error = EINVAL;
+ break;
+ }
+ bzero(config->an_nodename, 16);
+ error = copyin(ireq->i_data,
+ config->an_nodename, ireq->i_len);
+ break;
+ case IEEE80211_IOC_CHANNEL:
+ /*
+ * The actual range is 1-14, but if you set it
+ * to 0 you get the default so we let that work
+ * too.
+ */
+ if (ireq->i_val < 0 || ireq->i_val >14) {
+ error = EINVAL;
+ break;
+ }
+ config->an_ds_channel = ireq->i_val;
+ break;
+ case IEEE80211_IOC_POWERSAVE:
+ switch (ireq->i_val) {
+ case IEEE80211_POWERSAVE_OFF:
+ config->an_psave_mode = AN_PSAVE_NONE;
+ break;
+ case IEEE80211_POWERSAVE_CAM:
+ config->an_psave_mode = AN_PSAVE_CAM;
+ break;
+ case IEEE80211_POWERSAVE_PSP:
+ config->an_psave_mode = AN_PSAVE_PSP;
+ break;
+ case IEEE80211_POWERSAVE_PSP_CAM:
+ config->an_psave_mode = AN_PSAVE_PSP_CAM;
+ break;
+ default:
+ error = EINVAL;
+ break;
+ }
+ break;
+ case IEEE80211_IOC_POWERSAVESLEEP:
+ config->an_listen_interval = ireq->i_val;
+ break;
+ }
+
+ if (!error)
+ an_setdef(sc, &areq);
+ break;
default:
error = EINVAL;
break;
@@ -1416,6 +1828,7 @@ void an_cache_store (sc, eh, m, rx_quality)
static int cache_slot = 0; /* use this cache entry */
static int wrapindex = 0; /* next "free" cache entry */
int saanp=0;
+ int sig, noise;
/* filters:
* 1. ip only
@@ -1523,3 +1936,84 @@ void an_cache_store (sc, eh, m, rx_quality)
return;
}
#endif
+
+static int an_media_change(ifp)
+ struct ifnet *ifp;
+{
+ struct an_softc *sc = ifp->if_softc;
+ int otype = sc->an_config.an_opmode;
+ int orate = sc->an_tx_rate;
+
+ if ((sc->an_ifmedia.ifm_cur->ifm_media & IFM_IEEE80211_ADHOC) != 0)
+ sc->an_config.an_opmode = AN_OPMODE_IBSS_ADHOC;
+ else
+ sc->an_config.an_opmode = AN_OPMODE_INFRASTRUCTURE_STATION;
+
+ switch (IFM_SUBTYPE(sc->an_ifmedia.ifm_cur->ifm_media)) {
+ case IFM_IEEE80211_DS1:
+ sc->an_tx_rate = AN_RATE_1MBPS;
+ break;
+ case IFM_IEEE80211_DS2:
+ sc->an_tx_rate = AN_RATE_2MBPS;
+ break;
+ case IFM_IEEE80211_DS5:
+ sc->an_tx_rate = AN_RATE_5_5MBPS;
+ break;
+ case IFM_IEEE80211_DS11:
+ sc->an_tx_rate = AN_RATE_11MBPS;
+ break;
+ case IFM_AUTO:
+ sc->an_tx_rate = 0;
+ break;
+ }
+
+ if (otype != sc->an_config.an_opmode ||
+ orate != sc->an_tx_rate)
+ an_init(sc);
+
+ return(0);
+}
+
+static void an_media_status(ifp, imr)
+ struct ifnet *ifp;
+ struct ifmediareq *imr;
+{
+ struct an_ltv_status status;
+ struct an_softc *sc = ifp->if_softc;
+
+ status.an_len = sizeof(status);
+ status.an_type = AN_RID_STATUS;
+ if (an_read_record(sc, (struct an_ltv_gen *)&status)) {
+ /* If the status read fails, just lie. */
+ imr->ifm_active = sc->an_ifmedia.ifm_cur->ifm_media;
+ imr->ifm_status = IFM_AVALID|IFM_ACTIVE;
+ }
+
+ if(sc->an_tx_rate == 0) {
+ imr->ifm_active = IFM_IEEE80211|IFM_AUTO;
+ if (sc->an_config.an_opmode == AN_OPMODE_IBSS_ADHOC)
+ imr->ifm_active |= IFM_IEEE80211_ADHOC;
+ switch(status.an_current_tx_rate) {
+ case AN_RATE_1MBPS:
+ imr->ifm_active |= IFM_IEEE80211_DS1;
+ break;
+ case AN_RATE_2MBPS:
+ imr->ifm_active |= IFM_IEEE80211_DS2;
+ break;
+ case AN_RATE_5_5MBPS:
+ imr->ifm_active |= IFM_IEEE80211_DS5;
+ break;
+ case AN_RATE_11MBPS:
+ imr->ifm_active |= IFM_IEEE80211_DS11;
+ break;
+ }
+ } else {
+ imr->ifm_active = sc->an_ifmedia.ifm_cur->ifm_media;
+ }
+
+ imr->ifm_status = IFM_AVALID;
+ if (sc->an_config.an_opmode == AN_OPMODE_IBSS_ADHOC)
+ imr->ifm_status |= IFM_ACTIVE;
+ else if (status.an_opmode & AN_STATUS_OPMODE_ASSOCIATED)
+ imr->ifm_status |= IFM_ACTIVE;
+}
diff --git a/sys/dev/an/if_an_isa.c b/sys/dev/an/if_an_isa.c
index 29e6c28..8ece54d 100644
--- a/sys/dev/an/if_an_isa.c
+++ b/sys/dev/an/if_an_isa.c
@@ -63,6 +63,7 @@
#include <net/ethernet.h>
#include <net/if_dl.h>
#include <net/if_types.h>
+#include <net/if_media.h>
#include <isa/isavar.h>
#include <isa/pnpvar.h>
@@ -137,6 +138,7 @@ an_detach_isa(device_t dev)
struct ifnet *ifp = &sc->arpcom.ac_if;
an_stop(sc);
+ ifmedia_removeall(&sc->an_ifmedia);
ether_ifdetach(ifp, ETHER_BPF_SUPPORTED);
bus_teardown_intr(dev, sc->irq_res, sc->irq_handle);
an_release_resources(dev);
diff --git a/sys/dev/an/if_an_pccard.c b/sys/dev/an/if_an_pccard.c
index ebb7803..dc91b0f 100644
--- a/sys/dev/an/if_an_pccard.c
+++ b/sys/dev/an/if_an_pccard.c
@@ -64,6 +64,7 @@
#include <net/ethernet.h>
#include <net/if_dl.h>
#include <net/if_types.h>
+#include <net/if_media.h>
#ifndef lint
static const char rcsid[] =
@@ -111,6 +112,7 @@ an_pccard_detach(device_t dev)
return(0);
}
an_stop(sc);
+ ifmedia_removeall(&sc->an_ifmedia);
ifp->if_flags &= ~IFF_RUNNING;
ether_ifdetach(ifp, ETHER_BPF_SUPPORTED);
sc->an_gone = 1;
diff --git a/sys/dev/an/if_an_pci.c b/sys/dev/an/if_an_pci.c
index bde0f3d..47099e8 100644
--- a/sys/dev/an/if_an_pci.c
+++ b/sys/dev/an/if_an_pci.c
@@ -76,6 +76,7 @@
#include <net/if_arp.h>
#include <net/ethernet.h>
#include <net/if_dl.h>
+#include <net/if_media.h>
#include <pci/pcireg.h>
#include <pci/pcivar.h>
@@ -195,6 +196,7 @@ an_detach_pci(device_t dev)
struct ifnet *ifp = &sc->arpcom.ac_if;
an_stop(sc);
+ ifmedia_removeall(&sc->an_ifmedia);
ether_ifdetach(ifp, ETHER_BPF_SUPPORTED);
bus_teardown_intr(dev, sc->irq_res, sc->irq_handle);
an_release_resources(dev);
diff --git a/sys/dev/an/if_anreg.h b/sys/dev/an/if_anreg.h
index 844d480..e86e354 100644
--- a/sys/dev/an/if_anreg.h
+++ b/sys/dev/an/if_anreg.h
@@ -34,8 +34,8 @@
#define AN_TIMEOUT 65536
-/* Default network name: ANY */
-#define AN_DEFAULT_NETNAME "ANY"
+/* Default network name: <empty string> */
+#define AN_DEFAULT_NETNAME ""
/* The nodename must be less than 16 bytes */
#define AN_DEFAULT_NODENAME "FreeBSD"
@@ -846,6 +846,7 @@ struct an_softc {
struct callout_handle an_stat_ch;
struct mtx an_mtx;
device_t an_dev;
+ struct ifmedia an_ifmedia;
};
#define AN_LOCK(_sc) mtx_lock(&(_sc)->an_mtx)
OpenPOWER on IntegriCloud