*** /usr/src/sys.current/dev/ic/wi.c	Thu Jun 13 23:11:49 2002
--- wi.c	Thu Jun 20 19:45:48 2002
***************
*** 75,80 ****
--- 75,81 ----
  #define WI_HERMES_AUTOINC_WAR	/* Work around data write autoinc bug. */
  #define WI_HERMES_STATS_WAR	/* Work around stats counter bug. */
  
+ #include "opt_inet.h"
  #include "bpfilter.h"
  
  #include <sys/param.h>
***************
*** 89,98 ****
--- 90,105 ----
  
  #include <net/if.h>
  #include <net/if_dl.h>
+ #include <net/if_types.h>
  #include <net/if_media.h>
  #include <net/if_ether.h>
  #include <net/if_ieee80211.h>
  
+ #ifdef INET
+ #include <netinet/in.h>
+ #include <netinet/if_inarp.h>
+ #endif
+ 
  #if NBPFILTER > 0
  #include <net/bpf.h>
  #include <net/bpfdesc.h>
***************
*** 105,110 ****
--- 112,118 ----
  #include <dev/ic/wivar.h>
  
  static void wi_reset		__P((struct wi_softc *));
+ static int wi_ether_ioctl	__P((struct ifnet *, u_long, caddr_t));
  static int wi_ioctl		__P((struct ifnet *, u_long, caddr_t));
  static void wi_start		__P((struct ifnet *));
  static void wi_watchdog		__P((struct ifnet *));
***************
*** 229,236 ****
--- 237,246 ----
  	ifp->if_start = wi_start;
  	ifp->if_ioctl = wi_ioctl;
  	ifp->if_watchdog = wi_watchdog;
+ #if 0 /* for NetBSD 1.5.3 */
  	ifp->if_init = wi_init;
  	ifp->if_stop = wi_stop;
+ #endif
  	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
  #ifdef IFF_NOTRAILERS
  	ifp->if_flags |= IFF_NOTRAILERS;
***************
*** 310,315 ****
--- 320,329 ----
  
  	ifp->if_baudrate = IF_Mbps(2);
  
+ #if NBPFILTER > 0
+ 	bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
+ #endif
+ 
  	/* Attach is successful. */
  	sc->sc_attached = 1;
  
***************
*** 1443,1448 ****
--- 1457,1542 ----
  	return (error);
  }
  
+ /*
+  * Common ioctls for Ethernet interfaces.  Note, we must be
+  * called at splnet().
+  */
+ static int
+ wi_ether_ioctl(ifp, cmd, data)
+ 	struct ifnet *ifp;
+ 	u_long cmd;
+ 	caddr_t data;
+ {
+ 	struct ifreq *ifr = (struct ifreq *)data;
+ 	struct ifaddr *ifa = (struct ifaddr *)data;
+ 	int error = 0;
+ 
+ 	switch (cmd) {
+ 	case SIOCSIFADDR:
+ 		ifp->if_flags |= IFF_UP;
+ 		switch (ifa->ifa_addr->sa_family) {
+ 		case AF_LINK:
+ 		{
+ 			struct sockaddr_dl *sdl =
+ 			    (struct sockaddr_dl *) ifa->ifa_addr;
+ 
+ 			if (sdl->sdl_type != IFT_ETHER ||
+ 			    sdl->sdl_alen != ifp->if_addrlen) {
+ 				error = EINVAL;
+ 				break;
+ 			}
+ 
+ 			memcpy(LLADDR(ifp->if_sadl), LLADDR(sdl),
+ 			    ifp->if_addrlen);
+ 
+ 			/* Set new address. */
+ 			error = wi_init(ifp);
+ 			break;
+ 		}
+ #ifdef INET
+ 		case AF_INET:
+ 			if ((ifp->if_flags & IFF_RUNNING) == 0 &&
+ 			    (error = wi_init(ifp)) != 0) {
+ 				break;
+ 			}
+ 			arp_ifinit(ifp, ifa);
+ 			break;
+ #endif /* INET */
+ 		default:
+ 			if ((ifp->if_flags & IFF_RUNNING) == 0)
+ 				error = wi_init(ifp);
+ 			break;
+ 		}
+ 		break;
+ 
+ 	case SIOCGIFADDR:
+ 		memcpy(((struct sockaddr *)&ifr->ifr_data)->sa_data,
+ 		    LLADDR(ifp->if_sadl), ETHER_ADDR_LEN);
+ 		break;
+ 
+ 	case SIOCSIFMTU:
+ 	{
+ 		int maxmtu;
+ 		maxmtu = ETHERMTU;
+ 
+ 		if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > maxmtu)
+ 			error = EINVAL;
+ 		else {
+ 			ifp->if_mtu = ifr->ifr_mtu;
+ 
+ 			/* Make sure the device notices the MTU change. */
+ 			if (ifp->if_flags & IFF_UP)
+ 				error = wi_init(ifp);
+                 }
+ 		break;
+ 	}
+ 	default:
+ 		error = ENOTTY;
+ 	}
+ 
+ 	return (error);
+ }
+ 
  static int
  wi_ioctl(ifp, command, data)
  	struct ifnet		*ifp;
***************
*** 1467,1473 ****
  	case SIOCSIFADDR:
  	case SIOCGIFADDR:
  	case SIOCSIFMTU:
! 		error = ether_ioctl(ifp, command, data);
  		break;
  	case SIOCSIFFLAGS:
  		if (ifp->if_flags & IFF_UP) {
--- 1561,1567 ----
  	case SIOCSIFADDR:
  	case SIOCGIFADDR:
  	case SIOCSIFMTU:
! 		error = wi_ether_ioctl(ifp, command, data);
  		break;
  	case SIOCSIFFLAGS:
  		if (ifp->if_flags & IFF_UP) {
***************
*** 2124,2129 ****
--- 2218,2226 ----
  	/* Delete all remaining media. */
  	ifmedia_delete_instance(&sc->sc_media, IFM_INST_ANY);
  
+ #if NBPFILTER > 0
+ 	bpfdetach(ifp);
+ #endif
  	ether_ifdetach(ifp);
  	if_detach(ifp);
  	if (sc->sc_enabled) {
