Beispiel #1
0
static void
octm_init(void *arg)
{
	struct ifnet *ifp;
	struct octm_softc *sc;
	cvmx_mgmt_port_netdevice_flags_t flags;
	uint64_t mac;

	sc = arg;
	ifp = sc->sc_ifp;

	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
		cvmx_mgmt_port_disable(sc->sc_port);

		ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
	}

	/*
	 * NB:
	 * MAC must be set before allmulti and promisc below, as
	 * cvmx_mgmt_port_set_mac will always enable the CAM, and turning on
	 * promiscuous mode only works with the CAM disabled.
	 */
	mac = 0;
	memcpy((u_int8_t *)&mac + 2, IF_LLADDR(ifp), 6);
	cvmx_mgmt_port_set_mac(sc->sc_port, mac);

	/*
	 * This is done unconditionally, rather than only if sc_flags have
	 * changed because of set_mac's effect on the CAM noted above.
	 */
	flags = 0;
	if ((ifp->if_flags & IFF_ALLMULTI) != 0)
		flags |= CVMX_IFF_ALLMULTI;
	if ((ifp->if_flags & IFF_PROMISC) != 0)
		flags |= CVMX_IFF_PROMISC;
	cvmx_mgmt_port_set_multicast_list(sc->sc_port, flags);

	/* XXX link state?  */

	if ((ifp->if_flags & IFF_UP) != 0)
		cvmx_mgmt_port_enable(sc->sc_port);

	ifp->if_drv_flags |= IFF_DRV_RUNNING;
	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
}
Beispiel #2
0
static void
octm_init(void *arg)
{
	struct ifnet *ifp;
	struct octm_softc *sc;
	cvmx_mgmt_port_netdevice_flags_t flags;
	uint64_t mac;

	sc = arg;
	ifp = sc->sc_ifp;

	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
		cvmx_mgmt_port_disable(sc->sc_port);

		ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
	}

	if (((ifp->if_flags ^ sc->sc_flags) & (IFF_ALLMULTI | IFF_MULTICAST | IFF_PROMISC)) != 0) {
		flags = 0;
		if ((ifp->if_flags & IFF_ALLMULTI) != 0)
			flags |= CVMX_IFF_ALLMULTI;
		if ((ifp->if_flags & IFF_PROMISC) != 0)
			flags |= CVMX_IFF_PROMISC;
		cvmx_mgmt_port_set_multicast_list(sc->sc_port, flags);
	}

	mac = 0;
	memcpy((u_int8_t *)&mac + 2, IF_LLADDR(ifp), 6);
	cvmx_mgmt_port_set_mac(sc->sc_port, mac);

	/* XXX link state?  */

	if ((ifp->if_flags & IFF_UP) != 0)
		cvmx_mgmt_port_enable(sc->sc_port);

	ifp->if_drv_flags |= IFF_DRV_RUNNING;
	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
}
Beispiel #3
0
static int
octm_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
{
	struct octm_softc *sc;
	struct ifreq *ifr;
#ifdef INET
	struct ifaddr *ifa;
#endif
	int error;

	sc = ifp->if_softc;
	ifr = (struct ifreq *)data;
#ifdef INET
	ifa = (struct ifaddr *)data;
#endif

	switch (cmd) {
	case SIOCSIFADDR:
#ifdef INET
		/*
		 * Avoid reinitialization unless it's necessary.
		 */
		if (ifa->ifa_addr->sa_family == AF_INET) {
			ifp->if_flags |= IFF_UP;
			if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
				octm_init(sc);
			arp_ifinit(ifp, ifa);

			return (0);
		}
#endif
		error = ether_ioctl(ifp, cmd, data);
		if (error != 0)
			return (error);
		return (0);

	case SIOCSIFFLAGS:
		if (ifp->if_flags == sc->sc_flags)
			return (0);
		if ((ifp->if_flags & IFF_UP) != 0) {
			octm_init(sc);
		} else {
			if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
				cvmx_mgmt_port_disable(sc->sc_port);

				ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
			}
		}
		sc->sc_flags = ifp->if_flags;
		return (0);
	
	case SIOCSIFCAP:
		/*
		 * Just change the capabilities in software, currently none
		 * require reprogramming hardware, they just toggle whether we
		 * make use of already-present facilities in software.
		 */
		ifp->if_capenable = ifr->ifr_reqcap;
		return (0);

	case SIOCSIFMTU:
		cvmx_mgmt_port_set_max_packet_size(sc->sc_port, ifr->ifr_mtu + ifp->if_data.ifi_hdrlen);
		return (0);

	case SIOCSIFMEDIA:
	case SIOCGIFMEDIA:
		error = ifmedia_ioctl(ifp, ifr, &sc->sc_ifmedia, cmd);
		if (error != 0)
			return (error);
		return (0);
	
	default:
		error = ether_ioctl(ifp, cmd, data);
		if (error != 0)
			return (error);
		return (0);
	}
}