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:
Bill Paul 2000-01-13 20:13:58 +00:00
parent d7127837a2
commit 4f0a6f0403
6 changed files with 128 additions and 59 deletions

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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 *));

View file

@ -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 } }
};

View file

@ -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