usb_ethernet.c revision 184610
1184610Salfred/* $FreeBSD: head/sys/dev/usb2/ethernet/usb2_ethernet.c 184610 2008-11-04 02:31:03Z alfred $ */ 2184610Salfred/*- 3184610Salfred * Copyright (c) 2008 Hans Petter Selasky. All rights reserved. 4184610Salfred * 5184610Salfred * Redistribution and use in source and binary forms, with or without 6184610Salfred * modification, are permitted provided that the following conditions 7184610Salfred * are met: 8184610Salfred * 1. Redistributions of source code must retain the above copyright 9184610Salfred * notice, this list of conditions and the following disclaimer. 10184610Salfred * 2. Redistributions in binary form must reproduce the above copyright 11184610Salfred * notice, this list of conditions and the following disclaimer in the 12184610Salfred * documentation and/or other materials provided with the distribution. 13184610Salfred * 14184610Salfred * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15184610Salfred * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16184610Salfred * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17184610Salfred * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18184610Salfred * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19184610Salfred * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20184610Salfred * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21184610Salfred * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22184610Salfred * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23184610Salfred * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24184610Salfred * SUCH DAMAGE. 25184610Salfred */ 26184610Salfred 27184610Salfred#include <dev/usb2/core/usb2_core.h> 28184610Salfred#include <dev/usb2/ethernet/usb2_ethernet.h> 29184610Salfred 30184610SalfredMODULE_VERSION(usb2_ethernet, 1); 31184610SalfredMODULE_DEPEND(usb2_ethernet, usb2_core, 1, 1, 1); 32184610Salfred 33184610Salfred/*------------------------------------------------------------------------* 34184610Salfred * usb2_ether_get_mbuf - get a new ethernet aligned mbuf 35184610Salfred *------------------------------------------------------------------------*/ 36184610Salfredstruct mbuf * 37184610Salfredusb2_ether_get_mbuf(void) 38184610Salfred{ 39184610Salfred struct mbuf *m; 40184610Salfred 41184610Salfred m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); 42184610Salfred if (m) { 43184610Salfred m->m_len = m->m_pkthdr.len = MCLBYTES; 44184610Salfred m_adj(m, ETHER_ALIGN); 45184610Salfred } 46184610Salfred return (m); 47184610Salfred} 48184610Salfred 49184610Salfred/*------------------------------------------------------------------------* 50184610Salfred * usb2_ether_cc - common ethernet config copy 51184610Salfred *------------------------------------------------------------------------*/ 52184610Salfredvoid 53184610Salfredusb2_ether_cc(struct ifnet *ifp, usb2_ether_mchash_t *fhash, 54184610Salfred struct usb2_ether_cc *cc) 55184610Salfred{ 56184610Salfred struct ifmultiaddr *ifma; 57184610Salfred uint8_t i; 58184610Salfred 59184610Salfred if (ifp == NULL) { 60184610Salfred /* Nothing to do */ 61184610Salfred return; 62184610Salfred } 63184610Salfred /* Copy interface flags */ 64184610Salfred 65184610Salfred cc->if_flags = ifp->if_flags; 66184610Salfred 67184610Salfred /* Copy link layer address */ 68184610Salfred 69184610Salfred for (i = 0; i != ETHER_ADDR_LEN; i++) { 70184610Salfred cc->if_lladdr[i] = IF_LLADDR(ifp)[i]; 71184610Salfred } 72184610Salfred 73184610Salfred /* Check hash filter disable bits */ 74184610Salfred 75184610Salfred if ((ifp->if_flags & IFF_ALLMULTI) || 76184610Salfred (ifp->if_flags & IFF_PROMISC)) { 77184610Salfred 78184610Salfred memset(cc->if_hash, 0xFF, sizeof(cc->if_hash)); 79184610Salfred 80184610Salfred } else if (fhash) { 81184610Salfred 82184610Salfred /* Compute hash bits for multicast filter */ 83184610Salfred 84184610Salfred IF_ADDR_LOCK(ifp); 85184610Salfred TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 86184610Salfred if (ifma->ifma_addr->sa_family != AF_LINK) { 87184610Salfred continue; 88184610Salfred } 89184610Salfred fhash(cc, LLADDR((struct sockaddr_dl *) 90184610Salfred (ifma->ifma_addr))); 91184610Salfred } 92184610Salfred IF_ADDR_UNLOCK(ifp); 93184610Salfred 94184610Salfred /* Compute hash bits for broadcast address */ 95184610Salfred 96184610Salfred if (ifp->if_flags & IFF_BROADCAST) { 97184610Salfred fhash(cc, ifp->if_broadcastaddr); 98184610Salfred } 99184610Salfred } 100184610Salfred return; 101184610Salfred} 102