6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * axf_usbgem.c : ASIX AX88172/772 USB to Fast Ethernet Driver for Solaris
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * Copyright (c) 2004-2012 Masayuki Murayama. All rights reserved.
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * Redistribution and use in source and binary forms, with or without
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * modification, are permitted provided that the following conditions are met:
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * 1. Redistributions of source code must retain the above copyright notice,
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * this list of conditions and the following disclaimer.
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * 2. Redistributions in binary form must reproduce the above copyright notice,
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * this list of conditions and the following disclaimer in the documentation
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * and/or other materials provided with the distribution.
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * 3. Neither the name of the author nor the names of its contributors may be
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * used to endorse or promote products derived from this software without
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * specific prior written permission.
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi#pragma ident "@(#)axf_usbgem.c 1.3 12/02/09"
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * handle RXMODE_ENABLE in set_rx_filter()
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi/* ======================================================= */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * Solaris system header files and macros
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi/* minimum kernel headers for drivers */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi/* ethernet stuff */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi/* interface card depend stuff */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi/* hardware stuff */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchichar ident[] = "ax88x72 usbnic driver v" VERSION;
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * Useful macros
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi#define CHECK_AND_JUMP(err, label) if (err != USB_SUCCESS) goto label
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi#define LE16P(p) ((((uint8_t *)(p))[1] << 8) | ((uint8_t *)(p))[0])
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi (((struct axf_dev *)(dp)->private)->chip->type == CHIP_TYPE_AX88172)
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi (((struct axf_dev *)(dp)->private)->chip->type == CHIP_TYPE_AX88772)
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi#define DPRINTF(n, args) if (axf_debug > (n)) cmn_err args
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * Our configration for ax88172
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi/* timeouts */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * RX/TX buffer size
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * Local device definitions
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi#define GPIO_DEFAULT {0x00, 0x15}, {0, 0}, {0, 0}
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* Planex UE2-100TX, Hawking UF200, TrendNet TU2-ET100 */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * the default setting covers below:
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * gpio bit2 has to be 0 and gpio bit0 has to be 1
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi "Linksys USB200M",
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi "Netgear FA120",
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi "Intellinet, ST Lab USB Ethernet",
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi "Billionton Systems, USB2AR",
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi "ATEN UC210T",
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi "Buffalo LUA-U2-KTX",
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi "Sitecom LN-029 USB 2.0 10/100 Ethernet adapter",
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi "corega FEther USB2-TX",
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi "Surecom EP-1427X-2",
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi "goodway corp usb gwusb2e",
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi/* AX88772 and AX88178 */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi {0, 0}, {0, 0}, {0, 0},
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi "Linksys USB200M rev.2",
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi {0, 0}, {0, 0}, {0, 0},
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi "0Q0 cable ethernet",
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi {0, 0}, {0, 0}, {0, 0},
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi "DLink DUB E100 ver B1",
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi {0, 0}, {0, 0}, {0, 0},
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi "DLink DUB E100 ver B1(2)",
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi {0, 0}, {0, 0}, {0, 0},
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi "Apple Ethernet USB Adapter",
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi {0, 0}, {0, 0}, {0, 0},
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi "Linksys USB1000",
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi {0, 0}, {0, 0}, {0, 0},
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi {0, 0}, {0, 0}, {0, 0},
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi "I/O DATA ETG-US2",
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi {0, 0}, {0, 0}, {0, 0},
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi "Belkin F5D5055",
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* generic ax88772 must be the last entry */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* planex UE-200TX-G */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi {0, 0}, {0, 0}, {0, 0},
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi#define CHIPTABLESIZE (sizeof (chiptbl_88x7x) / sizeof (struct chip_info))
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * Misc HW information
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * private functions
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi/* mii operations */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchistatic uint16_t axf_mii_read(struct usbgem_dev *, uint_t, int *errp);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchistatic void axf_mii_write(struct usbgem_dev *, uint_t, uint16_t, int *errp);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi/* nic operations */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchistatic int axf_reset_chip(struct usbgem_dev *);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchistatic int axf_init_chip(struct usbgem_dev *);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchistatic int axf_start_chip(struct usbgem_dev *);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchistatic int axf_stop_chip(struct usbgem_dev *);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchistatic int axf_set_media(struct usbgem_dev *);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchistatic int axf_set_rx_filter(struct usbgem_dev *);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchistatic int axf_get_stats(struct usbgem_dev *);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchistatic void axf_interrupt(struct usbgem_dev *, mblk_t *);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi/* packet operations */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchistatic mblk_t *axf_tx_make_packet(struct usbgem_dev *, mblk_t *);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchistatic mblk_t *axf_rx_make_packet(struct usbgem_dev *, mblk_t *);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi/* =============================================================== */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * I/O functions
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi/* =============================================================== */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi/* BEGIN CSTYLED */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi#define OUT(dp, req, val, ix, len, buf, errp, label) \
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* bmRequestType */ USB_DEV_REQ_HOST_TO_DEV \
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi | USB_DEV_REQ_TYPE_VENDOR | USB_DEV_REQ_RCPT_DEV, \
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* size */ (len))) != USB_SUCCESS) goto label
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi#define IN(dp, req, val, ix, len, buf, errp, label) \
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* bmRequestType */ USB_DEV_REQ_DEV_TO_HOST \
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi | USB_DEV_REQ_TYPE_VENDOR | USB_DEV_REQ_RCPT_DEV, \
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* size */ (len))) != USB_SUCCESS) goto label
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi/* END CSTYLED */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi/* =============================================================== */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * Hardware manupilation
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi/* =============================================================== */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi DPRINTF(2, (CE_CONT, "!%s: %s: called", dp->name, __func__));
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi IN(dp, VCMD_READ_GPIO, 0, 0, 1, &val8, &err, usberr);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* reset MII PHY */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi lp->gpio = GPIO_RSE | GPIO_DATA2 | GPIO_EN2;
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi dp->mii_phy_addr == 16 ? 1 : 0, 0, 0, NULL, &err, usberr);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi SWRST_IPPD | SWRST_PRL, 0, 0, NULL, &err, usberr);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi dp->mii_phy_addr == 16 ? SWRST_IPRL : SWRST_PRTE,
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* there are no ways to reset nic */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi SWRST_RR | SWRST_RT, 0, 0, NULL, &err, usberr);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * Setup ax88172
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi DPRINTF(2, (CE_CONT, "!%s: %s: called", dp->name, __func__));
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* rx conrol register: read default value */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* clear rx control */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi OUT(dp, VCMD_WRITE_RXCTRL, 0, 0, 0, NULL, &err, usberr);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi IN(dp, VCMD_READ_RXCTRL, 0, 0, 2, buf, &err, usberr);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi DPRINTF(0, (CE_CONT, "!%s: %s: rcr(default):%b",
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* Media status register */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* write IPG0-2 registers */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi OUT(dp, VCMD_WRITE_IPG, lp->ipg[0], 0, 0, NULL, &err, usberr);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi OUT(dp, VCMD_WRITE_IPG1, lp->ipg[1], 0, 0, NULL, &err, usberr);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi OUT(dp, VCMD_WRITE_IPG2, lp->ipg[2], 0, 0, NULL, &err, usberr);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* enable Rx */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi OUT(dp, VCMD_WRITE_RXCTRL, lp->rcr, 0, 0, NULL, &err, usberr);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi err, err == USB_SUCCESS ? "success" : "error"));
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* enable Rx */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi OUT(dp, VCMD_WRITE_RXCTRL, lp->rcr, 0, 0, NULL, &err, usberr);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi err, err == USB_SUCCESS ? "success" : "error"));
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* Disable Rx */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi OUT(dp, VCMD_WRITE_RXCTRL, lp->rcr, 0, 0, NULL, &err, usberr);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * Restore factory mac address
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * if we have changed current mac address
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi ETHERADDRL, dp->cur_addr.ether_addr_octet, &err, usberr);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchiaxf_mcast_hash(struct usbgem_dev *dp, const uint8_t *addr)
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi return (usbgem_ether_crc_be(addr) >> (32 - 6));
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi DPRINTF(2, (CE_CONT, "!%s: %s: called, rxmode:%x",
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* set promiscuous mode before changing it. */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi lp->rcr | RCR_PRO, 0, 0, NULL, &err, usberr);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi lp->rcr &= ~(RCR_AP_88772 | RCR_AM | RCR_SEP | RCR_AMALL | RCR_PRO);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi mode = RCR_AB; /* accept broadcast packets */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* promiscious mode implies all multicast and all physical */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi } else if ((dp->rxmode & RXMODE_ALLMULTI) || dp->mc_count > 32) {
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* accept all multicast packets */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * make hash table to select interresting
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * multicast address only.
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi dp->cur_addr.ether_addr_octet, ETHERADDRL) != 0) {
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * we use promiscious mode instead of changing the
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * mac address in ax88172
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi ETHERADDRL, dp->cur_addr.ether_addr_octet, &err, usberr);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* set multicast hash table */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* need to set up multicast hash table */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* update rcr */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* verify rxctrl reg */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi IN(dp, VCMD_READ_RXCTRL, 0, 0, 2, buf, &err, usberr);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi cmn_err(CE_CONT, "!%s: %s: rcr:%b returned",
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi err, err == USB_SUCCESS ? "success" : "error"));
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi IN(dp, VCMD_READ_GPIO, 0, 0, 1, &gpio, &err, usberr);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi DPRINTF(0, (CE_CONT, "!%s: %s: called, gpio:%b",
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* setup speed */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi gpio |= lp->chip->gpio_speed[dp->speed == USBGEM_SPD_100 ? 1 : 0];
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* select duplex */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* select flow control */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi gpio |= lp->chip->gpio_duplex[dp->full_duplex ? 1 : 0];
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* update medium status register */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi OUT(dp, VCMD_WRITE_MEDIUM_STATUS, lp->msr, 0,
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* LED control required for some products */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi err, err == USB_SUCCESS ? "success" : "error"));
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * send/receive packet check
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchiaxf_tx_make_packet(struct usbgem_dev *dp, mblk_t *mp)
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi if (len >= ETHERMIN && mp->b_cont == NULL &&
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* use the mp "as is" */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * re-allocate the mp
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* minimum ethernet packet size of ETHERMIN */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi if (((pkt_size + header_size) & align_mask) == 0) {
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* padding is required in usb communication */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi if ((new = allocb(header_size + pkt_size + pad_size, 0)) == NULL) {
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* add a header */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* copy contents of the buffer */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi n = (uintptr_t)tp->b_wptr - (uintptr_t)tp->b_rptr;
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* add pads for ethernet packets */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi last_pos = new->b_rptr + header_size + pkt_size;
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* add a zero-length pad segment for usb communications */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* add a dummy header for zero-length packet */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* close the payload of the packet */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchiaxf_dump_packet(struct usbgem_dev *dp, uint8_t *bp, int n)
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi cmn_err(CE_CONT, "%02x %02x %02x %02x %02x %02x %02x %02x",
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi bp[0], bp[1], bp[2], bp[3], bp[4], bp[5], bp[6], bp[7]);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchiaxf_rx_make_packet(struct usbgem_dev *dp, mblk_t *mp)
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi rest = (uintptr_t)tp->b_wptr - (uintptr_t)tp->b_rptr;
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * the usb bulk-in frame doesn't include any valid
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * ethernet packets.
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* analyse the header of the received usb frame */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* test if the header is valid */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* discard whole the packet */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi "!%s: %s: corrupted header:%04x %04x",
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi "!%s: %s: incorrect pktsize:%d",
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* extract a ethernet packet from the bulk-in frame */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * skip a tailing pad byte if the packet
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * length is odd
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* no more vaild ethernet packets */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* allocate a mblk_t header for the next ethernet packet */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * MII Interfaces
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchiaxf_mii_read(struct usbgem_dev *dp, uint_t index, int *errp)
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi DPRINTF(4, (CE_CONT, "!%s: %s: called, ix:%d",
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* switch to software MII operation mode */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi OUT(dp, VCMD_SOFTWARE_MII_OP, 0, 0, 0, NULL, errp, usberr);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* Read MII register */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi IN(dp, VCMD_READ_MII_REG, dp->mii_phy_addr, index,
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* switch to hardware MII operation mode */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi OUT(dp, VCMD_HARDWARE_MII_OP, 0, 0, 0, NULL, errp, usberr);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi "!%s: %s: usberr(%d) detected", dp->name, __func__, *errp);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchiaxf_mii_write(struct usbgem_dev *dp, uint_t index, uint16_t val, int *errp)
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi DPRINTF(4, (CE_CONT, "!%s: %s called, reg:%x val:%x",
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* switch software MII operation mode */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi OUT(dp, VCMD_SOFTWARE_MII_OP, 0, 0, 0, NULL, errp, usberr);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* Write to the specified MII register */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi OUT(dp, VCMD_WRITE_MII_REG, dp->mii_phy_addr, index,
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* switch to hardware MII operation mode */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi OUT(dp, VCMD_HARDWARE_MII_OP, 0, 0, 0, NULL, errp, usberr);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchiaxf_interrupt(struct usbgem_dev *dp, mblk_t *mp)
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi "!%s: %s: size:%d, %02x %02x %02x %02x %02x %02x %02x %02x",
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi dp->name, __func__, mp->b_wptr - mp->b_rptr,
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi bp[0], bp[1], bp[2], bp[3], bp[4], bp[5], bp[6], bp[7]));
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi/* ======================================================== */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * OS depend (device driver DKI) routine
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi/* ======================================================== */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchiaxf_eeprom_dump(struct usbgem_dev *dp, int size)
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi cmn_err(CE_CONT, "!%s: eeprom dump:", dp->name);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi IN(dp, VCMD_READ_SROM, i + 0, 0, 2, w0, &err, usberr);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi IN(dp, VCMD_READ_SROM, i + 1, 0, 2, w1, &err, usberr);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi IN(dp, VCMD_READ_SROM, i + 2, 0, 2, w2, &err, usberr);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi IN(dp, VCMD_READ_SROM, i + 3, 0, 2, w3, &err, usberr);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi cmn_err(CE_CONT, "!0x%02x: 0x%04x 0x%04x 0x%04x 0x%04x",
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi DPRINTF(0, (CE_CONT, "!%s: %s enter", dp->name, __func__));
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * mac address in EEPROM has loaded to ID registers.
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi vcmd = AX88172(dp) ? VCMD_READ_NODE_ID : VCMD_READ_NODE_ID_88772;
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi ETHERADDRL, dp->dev_addr.ether_addr_octet, &err, usberr);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * setup IPG values
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * We cannot scan phy because the nic returns undefined
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * value, i.e. remained garbage, when MII phy is not at the
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * specified index.
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi if (lp->chip->vid == 0x07b8 && lp->chip->pid == 0x420a) {
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * restore the original phy address of brain
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * damaged Planex UE2-100TX
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi OUT(dp, VCMD_WRITE_SROM_ENABLE, 0, 0, 0, NULL, &err, usberr);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi OUT(dp, VCMD_WRITE_SROM, 0x11, 0xe004, 0, NULL, &err, usberr);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi OUT(dp, VCMD_WRITE_SROM_DISABLE, 0, 0, 0, NULL, &err, usberr);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi IN(dp, VCMD_READ_PHY_IDS, 0, 0, 2, &phys, &err, usberr);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi DPRINTF(0, (CE_CONT, "!%s: %s: phys_addr:%d %d",
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* use built-in phy */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* check max packet size in srom */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi IN(dp, VCMD_READ_SROM, 0x10, 0, 2, maxpktsize, &err, usberr);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi vlan_pktsize = ETHERMAX + ETHERFCSL + 4 /* VTAG_SIZE */;
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi "!%s: %s: max packet size in srom is too small, "
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi "changing %d -> %d, do power cycle for the device",
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* need to power off the device */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi IN(dp, VCMD_READ_GPIO, 0, 0, 1, &val8, &err, usberr);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi "!%s: %s: ipg 0x%02x 0x%02x 0x%02x, gpio 0x%b",
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi dp->name, __func__, lp->ipg[0], lp->ipg[1], lp->ipg[2],
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* fix rx buffer size */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi cmn_err(CE_WARN, "%s: %s: usb error detected (%d)",
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi DPRINTF(0, (CE_CONT, "!%s: %s: called", dp->name, __func__));
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* special probe routine for unreliable MII addr */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi for (i = 0; i < 32; i++) {
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi val = axf_mii_read(dp, MII_AN_ADVERT, &err);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi DPRINTF(0, (CE_CONT, "!%s: %s: index:%d, val %b != 0",
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi dp->name, __func__, i, val, MII_ABILITY_BITS));
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi axf_mii_write(dp, MII_AN_ADVERT, PROBE_PAT, &err);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi val = axf_mii_read(dp, MII_AN_ADVERT, &err);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi if ((val & MII_ABILITY_TECH) != PROBE_PAT) {
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi "index:%d, pat:%x != val:%b",
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi if (i == 32) {
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi cmn_err(CE_CONT, "!%s: %s: no mii phy found",
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi cmn_err(CE_CONT, "!%s: %s: i/o error while scanning phy",
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi DPRINTF(0, (CE_CONT, "!%s: %s: called", dp->name, __func__));
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * phy addr in srom is wrong, need to fix it
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi 0x11, LE16P(new_11th), 0, NULL, &err, usberr);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* XXX - read back, but it doesn't work, why? */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi cmn_err(CE_NOTE, "!%s: %s: phy addr in srom fixed: "
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi "%04x -> %04x",
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi "!%s: %s: failed to patch phy addr, "
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi "current: %04x",
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi DPRINTF(2, (CE_CONT, "!%s: %s: called", dp->name, __func__));
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* prepare to reset phy on the next reconnect or resume */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchiaxfattach(dev_info_t *dip, ddi_attach_cmd_t cmd)
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi DPRINTF(3, (CE_CONT, "!%s%d: %s: called, cmd:%d",
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * Check if the chip is supported.
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi vid = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi pid = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi revid = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi for (i = 0, p = chiptbl_88x7x; i < CHIPTABLESIZE; i++, p++) {
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi "(vid: 0x%04x, did: 0x%04x, revid: 0x%02x)",
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* Not found */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi cmn_err(CE_WARN, "!%s: %s: wrong usb venid/prodid (0x%x, 0x%x)",
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* assume 88772 */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * construct usbgem configration
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi ugcp = kmem_zalloc(sizeof (*ugcp), KM_SLEEP);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * softmac requires that ppa is the instance number
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * of the device, otherwise it hangs in seaching the device.
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi (void) sprintf(ugcp->usbgc_name, "%s%d", drv_name, unit);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* time out parameters */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi ugcp->usbgc_tx_timeout = USBGEM_TX_TIMEOUT;
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi ugcp->usbgc_tx_timeout_interval = USBGEM_TX_TIMEOUT_INTERVAL;
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* flow control */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * XXX - flow control caused link down frequently under
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * heavy traffic
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi ugcp->usbgc_flow_control = FLOW_CONTROL_RX_PAUSE;
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* MII timeout parameters */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi ugcp->usbgc_mii_link_watch_interval = ONESEC;
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi ugcp->usbgc_mii_an_watch_interval = ONESEC/5;
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi ugcp->usbgc_mii_reset_timeout = MII_RESET_TIMEOUT; /* 1 sec */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi ugcp->usbgc_mii_an_timeout = MII_AN_TIMEOUT; /* 5 sec */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi ugcp->usbgc_mii_linkdown_timeout = MII_LINKDOWN_TIMEOUT;
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi ugcp->usbgc_mii_linkdown_action = MII_ACTION_RSA;
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi ugcp->usbgc_mii_linkdown_timeout_action = MII_ACTION_RESET;
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi ugcp->usbgc_mii_hw_link_detection = B_TRUE;
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi ugcp->usbgc_mii_stop_mac_on_linkdown = B_FALSE;
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* I/O methods */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* mac operation */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi ugcp->usbgc_attach_chip = &axf_attach_chip;
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi ugcp->usbgc_multicast_hash = &axf_mcast_hash;
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi ugcp->usbgc_set_rx_filter = &axf_set_rx_filter;
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* packet operation */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi ugcp->usbgc_tx_make_packet = &axf_tx_make_packet;
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi ugcp->usbgc_rx_make_packet = &axf_rx_make_packet;
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi /* mii operations */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi ugcp->usbgc_mii_config = &usbgem_mii_config_default;
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi lp = kmem_zalloc(sizeof (struct axf_dev), KM_SLEEP);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi dp = usbgem_do_attach(dip, ugcp, lp, sizeof (struct axf_dev));
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchiaxfdetach(dev_info_t *dip, ddi_detach_cmd_t cmd)
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi/* ======================================================== */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * OS depend (loadable streams driver) routine
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi/* ======================================================== */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert MustacchiUSBGEM_STREAM_OPS(axf_ops, axfattach, axfdetach);
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi 0, /* mi_idnum */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi 0, /* mi_minpsz */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi 0, /* devo_refcnt */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi &mod_driverops, /* Type of module. This one is a driver */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi/* ======================================================== */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * _init : done
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi/* ======================================================== */
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi DPRINTF(2, (CE_CONT, "!axf: _init: called"));
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi * _fini : done
6716431ba7de213d5c318e58dc24c8a36da9b068Robert Mustacchi DPRINTF(2, (CE_CONT, "!axf: _fini: called"));