mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
Bunch of updates:
- Add vendor/device ID for Corega USB-T ethernet adapter to necessary places so that it will work with the kue driver. - Add vendor/device ID for CATC Netmate devices for driver to be added soon. - Get really crazy about netisr stuff: avoid doing any mbuf allocations or deallocations at splbio/splusb. - Fix if_aue driver so that it works with LinkSys USB100TX: you need to flip the GPIO bits just the right way to put the PHY in the right mode.
This commit is contained in:
parent
d7127837a2
commit
4f0a6f0403
6 changed files with 128 additions and 59 deletions
|
|
@ -121,6 +121,8 @@ static struct aue_type aue_devs[] = {
|
|||
{ 0, 0, NULL }
|
||||
};
|
||||
|
||||
static struct usb_qdat aue_qdat;
|
||||
|
||||
static int aue_match __P((device_t));
|
||||
static int aue_attach __P((device_t));
|
||||
static int aue_detach __P((device_t));
|
||||
|
|
@ -137,6 +139,7 @@ static void aue_rxeof __P((usbd_xfer_handle,
|
|||
static void aue_txeof __P((usbd_xfer_handle,
|
||||
usbd_private_handle, usbd_status));
|
||||
static void aue_tick __P((void *));
|
||||
static void aue_rxstart __P((struct ifnet *));
|
||||
static void aue_start __P((struct ifnet *));
|
||||
static int aue_ioctl __P((struct ifnet *, u_long, caddr_t));
|
||||
static void aue_init __P((void *));
|
||||
|
|
@ -534,11 +537,24 @@ static void aue_reset(sc)
|
|||
* in reset until we flip on the GPIO outputs. Make sure
|
||||
* to set the GPIO pins high so that the PHY(s) will
|
||||
* be enabled.
|
||||
*
|
||||
* Note: We force all of the GPIO pins low first, *then*
|
||||
* enable the ones we want.
|
||||
*/
|
||||
csr_write_1(sc, AUE_GPIO0, AUE_GPIO_OUT0|AUE_GPIO_SEL0);
|
||||
csr_write_1(sc, AUE_GPIO0, AUE_GPIO_OUT0|AUE_GPIO_SEL0|AUE_GPIO_SEL1);
|
||||
|
||||
/* Grrr. LinkSys has to be different from everyone else. */
|
||||
if (sc->aue_info->aue_vid == USB_VENDOR_LINKSYS &&
|
||||
sc->aue_info->aue_did == USB_PRODUCT_LINKSYS_USB100TX) {
|
||||
csr_write_1(sc, AUE_GPIO0, AUE_GPIO_SEL0|AUE_GPIO_SEL1);
|
||||
csr_write_1(sc, AUE_GPIO0, AUE_GPIO_SEL0|AUE_GPIO_SEL1|
|
||||
AUE_GPIO_OUT0);
|
||||
}
|
||||
|
||||
/* Wait a little while for the chip to get its brains in order. */
|
||||
DELAY(1000);
|
||||
DELAY(10000);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -553,6 +569,8 @@ USB_MATCH(aue)
|
|||
if (!uaa->iface)
|
||||
return(UMATCH_NONE);
|
||||
|
||||
printf("vendor: %x device %x\n", uaa->vendor, uaa->product);
|
||||
|
||||
t = aue_devs;
|
||||
while(t->aue_name != NULL) {
|
||||
if (uaa->vendor == t->aue_vid &&
|
||||
|
|
@ -675,6 +693,9 @@ USB_ATTACH(aue)
|
|||
USB_ATTACH_ERROR_RETURN;
|
||||
}
|
||||
|
||||
aue_qdat.ifp = ifp;
|
||||
aue_qdat.if_rxstart = aue_rxstart;
|
||||
|
||||
/*
|
||||
* Call MI attach routines.
|
||||
*/
|
||||
|
|
@ -849,6 +870,29 @@ static void aue_intr(xfer, priv, status)
|
|||
return;
|
||||
}
|
||||
|
||||
static void aue_rxstart(ifp)
|
||||
struct ifnet *ifp;
|
||||
{
|
||||
struct aue_softc *sc;
|
||||
struct aue_chain *c;
|
||||
|
||||
sc = ifp->if_softc;
|
||||
c = &sc->aue_cdata.aue_rx_chain[sc->aue_cdata.aue_rx_prod];
|
||||
|
||||
if (aue_newbuf(sc, c, NULL) == ENOBUFS) {
|
||||
ifp->if_ierrors++;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Setup new transfer. */
|
||||
usbd_setup_xfer(c->aue_xfer, sc->aue_ep[AUE_ENDPT_RX],
|
||||
c, mtod(c->aue_mbuf, char *), AUE_BUFSZ, USBD_SHORT_XFER_OK,
|
||||
USBD_NO_TIMEOUT, aue_rxeof);
|
||||
usbd_transfer(c->aue_xfer);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* A frame has been uploaded: pass the resulting mbuf chain up to
|
||||
* the higher level protocols.
|
||||
|
|
@ -869,7 +913,6 @@ static void aue_rxeof(xfer, priv, status)
|
|||
{
|
||||
struct aue_softc *sc;
|
||||
struct aue_chain *c;
|
||||
struct ether_header *eh;
|
||||
struct mbuf *m;
|
||||
struct ifnet *ifp;
|
||||
int total_len = 0;
|
||||
|
|
@ -936,44 +979,22 @@ static void aue_rxeof(xfer, priv, status)
|
|||
|
||||
/* No errors; receive the packet. */
|
||||
total_len -= (4 + ETHER_CRC_LEN);
|
||||
if (aue_newbuf(sc, c, NULL) == ENOBUFS) {
|
||||
ifp->if_ierrors++;
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
||||
ifp->if_ipackets++;
|
||||
eh = mtod(m, struct ether_header *);
|
||||
m->m_pkthdr.rcvif = ifp;
|
||||
m->m_pkthdr.rcvif = (struct ifnet *)&aue_qdat;
|
||||
m->m_pkthdr.len = m->m_len = total_len;
|
||||
|
||||
/*
|
||||
* Handle BPF listeners. Let the BPF user see the packet, but
|
||||
* don't pass it up to the ether_input() layer unless it's
|
||||
* a broadcast packet, multicast packet, matches our ethernet
|
||||
* address or the interface is in promiscuous mode.
|
||||
*/
|
||||
if (ifp->if_bpf) {
|
||||
bpf_mtap(ifp, m);
|
||||
if (ifp->if_flags & IFF_PROMISC &&
|
||||
(bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr,
|
||||
ETHER_ADDR_LEN) && !(eh->ether_dhost[0] & 1))) {
|
||||
m_freem(m);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/* Put the packet on the special USB input queue. */
|
||||
usb_ether_input(m);
|
||||
|
||||
done:
|
||||
|
||||
#ifdef foo
|
||||
/* Setup new transfer. */
|
||||
usbd_setup_xfer(xfer, sc->aue_ep[AUE_ENDPT_RX],
|
||||
c, mtod(c->aue_mbuf, char *), AUE_CUTOFF, USBD_SHORT_XFER_OK,
|
||||
USBD_NO_TIMEOUT, aue_rxeof);
|
||||
usbd_transfer(xfer);
|
||||
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -119,6 +119,8 @@ static struct kue_type kue_devs[] = {
|
|||
"KLSI USB ethernet" },
|
||||
{ USB_VENDOR_3COM, USB_PRODUCT_3COM_3C19250,
|
||||
"KLSI USB ethernet" },
|
||||
{ USB_VENDOR_COREGA, USB_PRODUCT_COREGA_USB_T,
|
||||
"KLSI USB ethernet" },
|
||||
{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650C,
|
||||
"KLSI USB ethernet" },
|
||||
{ USB_VENDOR_SMC, USB_PRODUCT_SMC_2102USB,
|
||||
|
|
@ -126,6 +128,8 @@ static struct kue_type kue_devs[] = {
|
|||
{ 0, 0, NULL }
|
||||
};
|
||||
|
||||
static struct usb_qdat kue_qdat;
|
||||
|
||||
static int kue_match __P((device_t));
|
||||
static int kue_attach __P((device_t));
|
||||
static int kue_detach __P((device_t));
|
||||
|
|
@ -140,6 +144,7 @@ static void kue_rxeof __P((usbd_xfer_handle,
|
|||
static void kue_txeof __P((usbd_xfer_handle,
|
||||
usbd_private_handle, usbd_status));
|
||||
static void kue_start __P((struct ifnet *));
|
||||
static void kue_rxstart __P((struct ifnet *));
|
||||
static int kue_ioctl __P((struct ifnet *, u_long, caddr_t));
|
||||
static void kue_init __P((void *));
|
||||
static void kue_stop __P((struct kue_softc *));
|
||||
|
|
@ -503,6 +508,9 @@ USB_ATTACH(kue)
|
|||
ifp->if_baudrate = 10000000;
|
||||
ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
|
||||
|
||||
kue_qdat.ifp = ifp;
|
||||
kue_qdat.if_rxstart = kue_rxstart;
|
||||
|
||||
/*
|
||||
* Call MI attach routines.
|
||||
*/
|
||||
|
|
@ -632,6 +640,29 @@ static int kue_tx_list_init(sc)
|
|||
return(0);
|
||||
}
|
||||
|
||||
static void kue_rxstart(ifp)
|
||||
struct ifnet *ifp;
|
||||
{
|
||||
struct kue_softc *sc;
|
||||
struct kue_chain *c;
|
||||
|
||||
sc = ifp->if_softc;
|
||||
c = &sc->kue_cdata.kue_rx_chain[sc->kue_cdata.kue_rx_prod];
|
||||
|
||||
if (kue_newbuf(sc, c, NULL) == ENOBUFS) {
|
||||
ifp->if_ierrors++;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Setup new transfer. */
|
||||
usbd_setup_xfer(c->kue_xfer, sc->kue_ep[KUE_ENDPT_RX],
|
||||
c, mtod(c->kue_mbuf, char *), KUE_BUFSZ, USBD_SHORT_XFER_OK,
|
||||
USBD_NO_TIMEOUT, kue_rxeof);
|
||||
usbd_transfer(c->kue_xfer);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* A frame has been uploaded: pass the resulting mbuf chain up to
|
||||
* the higher level protocols.
|
||||
|
|
@ -643,7 +674,6 @@ static void kue_rxeof(xfer, priv, status)
|
|||
{
|
||||
struct kue_softc *sc;
|
||||
struct kue_chain *c;
|
||||
struct ether_header *eh;
|
||||
struct mbuf *m;
|
||||
struct ifnet *ifp;
|
||||
int total_len = 0;
|
||||
|
|
@ -668,51 +698,29 @@ static void kue_rxeof(xfer, priv, status)
|
|||
|
||||
usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
|
||||
m = c->kue_mbuf;
|
||||
if (total_len <= 1)
|
||||
goto done;
|
||||
if (total_len <= 1) {
|
||||
usbd_setup_xfer(c->kue_xfer, sc->kue_ep[KUE_ENDPT_RX],
|
||||
c, mtod(c->kue_mbuf, char *), KUE_BUFSZ, USBD_SHORT_XFER_OK,
|
||||
USBD_NO_TIMEOUT, kue_rxeof);
|
||||
usbd_transfer(c->kue_xfer);
|
||||
return;
|
||||
}
|
||||
|
||||
len = *mtod(m, u_int16_t *);
|
||||
m_adj(m, sizeof(u_int16_t));
|
||||
|
||||
/* No errors; receive the packet. */
|
||||
total_len = len;
|
||||
if (kue_newbuf(sc, c, NULL) == ENOBUFS) {
|
||||
ifp->if_ierrors++;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ifp->if_ipackets++;
|
||||
eh = mtod(m, struct ether_header *);
|
||||
m->m_pkthdr.rcvif = ifp;
|
||||
m->m_pkthdr.rcvif = (struct ifnet *)&kue_qdat;
|
||||
m->m_pkthdr.len = m->m_len = total_len;
|
||||
|
||||
/*
|
||||
* Handle BPF listeners. Let the BPF user see the packet, but
|
||||
* don't pass it up to the ether_input() layer unless it's
|
||||
* a broadcast packet, multicast packet, matches our ethernet
|
||||
* address or the interface is in promiscuous mode.
|
||||
*/
|
||||
if (ifp->if_bpf) {
|
||||
bpf_mtap(ifp, m);
|
||||
if (ifp->if_flags & IFF_PROMISC &&
|
||||
(bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr,
|
||||
ETHER_ADDR_LEN) && !(eh->ether_dhost[0] & 1))) {
|
||||
m_freem(m);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/* Put the packet on the special USB input queue. */
|
||||
usb_ether_input(m);
|
||||
|
||||
done:
|
||||
|
||||
/* Setup new transfer. */
|
||||
usbd_setup_xfer(xfer, sc->kue_ep[KUE_ENDPT_RX],
|
||||
c, mtod(c->kue_mbuf, char *), KUE_BUFSZ, USBD_SHORT_XFER_OK,
|
||||
USBD_NO_TIMEOUT, kue_rxeof);
|
||||
usbd_transfer(xfer);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@
|
|||
#include <net/if_arp.h>
|
||||
#include <net/ethernet.h>
|
||||
#include <net/netisr.h>
|
||||
#include <net/bpf.h>
|
||||
|
||||
#include <dev/usb/usb.h>
|
||||
#include <dev/usb/usb_ethersubr.h>
|
||||
|
|
@ -86,6 +87,7 @@ static void usbintr()
|
|||
{
|
||||
struct ether_header *eh;
|
||||
struct mbuf *m;
|
||||
struct usb_qdat *q;
|
||||
struct ifnet *ifp;
|
||||
struct usb_ifent *e;
|
||||
int s;
|
||||
|
|
@ -98,9 +100,32 @@ static void usbintr()
|
|||
if (m == NULL)
|
||||
break;
|
||||
eh = mtod(m, struct ether_header *);
|
||||
q = (struct usb_qdat *)m->m_pkthdr.rcvif;
|
||||
ifp = q->ifp;
|
||||
m->m_pkthdr.rcvif = ifp;
|
||||
/*
|
||||
* Handle BPF listeners. Let the BPF user see the packet, but
|
||||
* don't pass it up to the ether_input() layer unless it's
|
||||
* a broadcast packet, multicast packet, matches our ethernet
|
||||
* address or the interface is in promiscuous mode.
|
||||
*/
|
||||
if (ifp->if_bpf) {
|
||||
bpf_mtap(ifp, m);
|
||||
if (ifp->if_flags & IFF_PROMISC &&
|
||||
(bcmp(eh->ether_dhost,
|
||||
((struct arpcom *)ifp->if_softc)->ac_enaddr,
|
||||
ETHER_ADDR_LEN) && !(eh->ether_dhost[0] & 1))) {
|
||||
m_freem(m);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
m_adj(m, sizeof(struct ether_header));
|
||||
ifp = m->m_pkthdr.rcvif;
|
||||
ether_input(ifp, eh, m);
|
||||
done:
|
||||
|
||||
/* Re-arm the receiver */
|
||||
(*q->if_rxstart)(ifp);
|
||||
if (ifp->if_snd.ifq_head != NULL)
|
||||
(*ifp->if_start)(ifp);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,11 @@
|
|||
#define NETISR_USB 25
|
||||
#endif
|
||||
|
||||
struct usb_qdat {
|
||||
struct ifnet *ifp;
|
||||
void (*if_rxstart) __P((struct ifnet *));
|
||||
};
|
||||
|
||||
void usb_register_netisr __P((void));
|
||||
void usb_ether_input __P((struct mbuf *));
|
||||
void usb_tx_done __P((struct ifnet *));
|
||||
|
|
|
|||
|
|
@ -78,6 +78,8 @@ static struct usbd_quirk_entry {
|
|||
UQ_NO_TSLEEP }},
|
||||
{ USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_E45, 0x002, { UQ_NO_STRINGS|
|
||||
UQ_NO_TSLEEP }},
|
||||
{ USB_VENDOR_COREGA, USB_PRODUCT_COREGA_USB_T, 0x002, { UQ_NO_STRINGS|
|
||||
UQ_NO_TSLEEP }},
|
||||
{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650C, 0x002, { UQ_NO_STRINGS|
|
||||
UQ_NO_TSLEEP }},
|
||||
{ USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_SERIAL1, 0x101, { UQ_NO_STRINGS }},
|
||||
|
|
@ -93,6 +95,8 @@ static struct usbd_quirk_entry {
|
|||
{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX_PNA,0x101, { UQ_NO_TSLEEP }},
|
||||
{ USB_VENDOR_SMC, USB_PRODUCT_SMC_2202USB, 0x101, { UQ_NO_TSLEEP }},
|
||||
{ USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB100TX,0x101, { UQ_NO_TSLEEP }},
|
||||
{ USB_VENDOR_CATC, USB_PRODUCT_CATC_NETMATE, 0x220, { UQ_NO_TSLEEP }},
|
||||
{ USB_VENDOR_CATC, USB_PRODUCT_CATC_NETMATE2, 0x220, { UQ_NO_TSLEEP }},
|
||||
{ 0, 0, 0, { 0 } }
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ vendor SMC 0x0707 Standard Microsystems Corp
|
|||
vendor MIDIMAN 0x0763 Midiman
|
||||
vendor SANDISK 0x0781 SanDisk Corp
|
||||
vendor ADMTEK 0x07a6 ADMtek Inc.
|
||||
vendor COREGA 0x07aa Corega
|
||||
vendor SIIG 0x07cc SIIG
|
||||
vendor HANDSPRING 0x082d Handspring Inc.
|
||||
vendor ACTIVEWIRE 0x0854 ActiveWire Inc.
|
||||
|
|
@ -147,6 +148,8 @@ product MELCO LUATX 0x0001 LU-ATX Ethernet adapter
|
|||
|
||||
/* CATC products */
|
||||
product CATC ANDROMEDA 0x1237 Andromeda hub
|
||||
product CATC NETMATE 0x000a Netmate ethernet adapter
|
||||
product CATC NETMATE2 0x000c Netmate2 ethernet adapter
|
||||
product CATC CHIEF 0x000d USB Chief Bus & Protocol Analyzer
|
||||
|
||||
/* Gravis products */
|
||||
|
|
@ -357,6 +360,9 @@ product SANDISK IMAGEMATE 0x0001 USB ImageMate
|
|||
/* ADMtek products */
|
||||
product ADMTEK PEGASUS 0x0986 AN986 USB Ethernet adapter
|
||||
|
||||
/* Corega products */
|
||||
product COREGA USB_T 0x0001 USB ethernet adapter
|
||||
|
||||
/* SIIG products */
|
||||
product SIIG DIGIFILMREADER 0x0004 DigiFilm-Combo Reader
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue