sfe.c revision d67944fbe3fa0b31893a7116a09b0718eecf6078
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * sfe.c : DP83815/DP83816/SiS900 Fast Ethernet MAC driver for Solaris
23d366e350386ec109bfa9b2cf91225729a1a26bduboff * Copyright (c) 2002-2008 Masayuki Murayama. All rights reserved.
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * Redistribution and use in source and binary forms, with or without
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * modification, are permitted provided that the following conditions are met:
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * 1. Redistributions of source code must retain the above copyright notice,
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * this list of conditions and the following disclaimer.
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * 2. Redistributions in binary form must reproduce the above copyright notice,
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * this list of conditions and the following disclaimer in the documentation
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * and/or other materials provided with the distribution.
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * 3. Neither the name of the author nor the names of its contributors may be
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * used to endorse or promote products derived from this software without
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * specific prior written permission.
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
d67944fbe3fa0b31893a7116a09b0718eecf6078Scott Rotondo/* Avoid undefined symbol for non IA architectures */
53560dfa94d868e9016a1b90f971fb538dc2009aSherry Moore * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
193974072f41a843678abf5f61979c748687e66bSherry Moore * Use is subject to license terms.
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * System Header files.
53560dfa94d868e9016a1b90f971fb538dc2009aSherry Moorechar ident[] = "sis900/dp83815 driver v" "2.6.1t30os";
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff/* Debugging support */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff#define DPRINTF(n, args) if (sfe_debug > (n)) cmn_err args
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * Useful macros and typedefs
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * Our configuration
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff (ISR_DPERR | ISR_SSERR | ISR_RMABT | ISR_RTABT | ISR_RXSOVR | \
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff/* special PHY registers for SIS900 */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff#define SFE_DESC_SIZE 16 /* including pads rounding up to power of 2 */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * Supported chips
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * Chip dependent MAC state
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* misc HW information */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * Hardware information
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff { 0x100b, 0x0020, "DP83815/83816", CHIPTYPE_DP83815, },
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff#define CHIPTABLESIZE (sizeof (sfe_chiptbl)/sizeof (struct chip_info))
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff/* ======================================================== */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff/* mii operations */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboffstatic uint16_t sfe_mii_read_dp83815(struct gem_dev *, uint_t);
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboffstatic uint16_t sfe_mii_read_sis900(struct gem_dev *, uint_t);
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboffstatic void sfe_mii_write_dp83815(struct gem_dev *, uint_t, uint16_t);
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboffstatic void sfe_mii_write_sis900(struct gem_dev *, uint_t, uint16_t);
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff/* nic operations */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboffstatic int sfe_set_rx_filter_dp83815(struct gem_dev *);
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboffstatic int sfe_set_rx_filter_sis900(struct gem_dev *);
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff/* descriptor operations */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboffstatic int sfe_tx_desc_write(struct gem_dev *dp, int slot,
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff ddi_dma_cookie_t *dmacookie, int frags, uint64_t flags);
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboffstatic void sfe_tx_start(struct gem_dev *dp, int startslot, int nslot);
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboffstatic void sfe_rx_desc_write(struct gem_dev *dp, int slot,
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboffstatic uint_t sfe_tx_desc_stat(struct gem_dev *dp, int slot, int ndesc);
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboffstatic uint64_t sfe_rx_desc_stat(struct gem_dev *dp, int slot, int ndesc);
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboffstatic void sfe_tx_desc_init(struct gem_dev *dp, int slot);
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboffstatic void sfe_rx_desc_init(struct gem_dev *dp, int slot);
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboffstatic void sfe_tx_desc_clean(struct gem_dev *dp, int slot);
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboffstatic void sfe_rx_desc_clean(struct gem_dev *dp, int slot);
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff/* interrupt handler */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff/* ======================================================== */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff/* mapping attributes */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff/* Data access requirements. */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff/* On sparc, Buffers should be native endian for speed */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff 0, /* dma_attr_addr_lo */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff 0 /* dma_attr_flags */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff 0 /* dma_attr_flags */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff/* ======================================================== */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * HW manipulation routines
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff/* ======================================================== */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* ensure de-assert chip select */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* assert chip select */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff for (i = 8; i >= 0; i--) {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* make command */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* send 1 bit */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff for (i = 0; i < 16; i++) {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* Get 1 bit */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff ret = (ret << 1) | ((INL(dp, EROMAR) >> EROMAR_EEDO_SHIFT) & 1);
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff#define BITSET(p, ix, v) (p)[(ix)/8] |= ((v) ? 1 : 0) << ((ix) & 0x7)
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff DPRINTF(4, (CE_CONT, CONS "%s: %s: called", dp->name, __func__));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* first of all, clear MAC address buffer */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* get bit 0 */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* get bit 1 - 16 */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff for (i = 0; i < 16; i++) {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* get bit 17 - 32 */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff for (i = 0; i < 16; i++) {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* get bit 33 - 47 */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff for (i = 0; i < 15; i++) {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboffsfe_search_pci_dev_subr(dev_info_t *cur_node, int vendor_id, int device_id)
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* check brothers */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* found */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* check children */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff } while ((cur_node = ddi_get_next_sibling(cur_node)) != NULL);
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* not found */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff return (sfe_search_pci_dev_subr(ddi_root_node(), vendor_id, device_id));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* this is not IA architecture */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff if ((isa_bridge = sfe_search_pci_dev(0x1039, 0x8)) == NULL) {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff cmn_err(CE_WARN, "%s: failed to find isa-bridge pci1039,8",
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff if (pci_config_setup(isa_bridge, &isa_handle) != DDI_SUCCESS) {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* enable to access CMOS RAM */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff for (i = 0; i < ETHERADDRL; i++) {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* disable to access CMOS RAM */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff DPRINTF(2, (CE_CONT, CONS "%s: %s: called", dp->name, __func__));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* disable packet filtering before reading filter */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* load MAC addr from filter data register */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff (RFADDR_MAC_SIS900 + (i/2)) << RFCR_RFADDR_SHIFT_SIS900);
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff dp->dev_addr.ether_addr_octet[i+1] = (uint8_t)(v >> 8);
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* re-enable packet filtering */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* rise request signal to access EEPROM */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff for (i = 0; (INL(dp, MEAR) & EROMAR_EEGNT) == 0; i++) {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff if (i > 200) {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* failed to acquire eeprom */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* release EEPROM */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff DPRINTF(4, (CE_CONT, CONS "%s: %s called", dp->name, __func__));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* invalidate mac addr cache */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* inhibit interrupt */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff for (i = 0; done != (ISR_TXRCMP | ISR_RXRCMP); i++) {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff if (i > 1000) {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff cmn_err(CE_WARN, "%s: chip reset timeout", dp->name);
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* Configuration register: enable PCI parity */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* what is this ? */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff DPRINTF(4, (CE_CONT, CONS "%s: %s called", dp->name, __func__));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* invalidate mac addr cache */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* inhibit interrupts */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff if (i > 100) {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff cmn_err(CE_WARN, "!%s: chip reset timeout", dp->name);
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff DPRINTF(0, (CE_CONT, "!%s: chip reset in %duS", dp->name, i*10));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* Configuration register: enable PCI parity */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* Configuration register: have been set up in sfe_chip_reset */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* PCI test control register: do nothing */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* Interrupt status register : do nothing */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* Interrupt mask register: clear, but leave lp->our_intr_bits */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* Enhanced PHY Access register (sis900): do nothing */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* Transmit Descriptor Pointer register: base addr of TX ring */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* Receive descriptor pointer register: base addr of RX ring */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboffsfe_rxfilter_dump(struct gem_dev *dp, int start, int end)
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff cmn_err(CE_CONT, "!%s: rx filter ram dump:", dp->name);
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff for (j = 0; j < WORDS_PER_LINE; j++) {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff cmn_err(CE_CONT, "!0x%02x: 0x%04x 0x%04x 0x%04x 0x%04x",
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff DPRINTF(1, (CE_CONT, CONS "%s: %s: called, mc_count:%d, mode:0x%b",
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff dp->name, __func__, dp->mc_count, dp->rxmode, RXMODE_BITS));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "!%s: adding mcast(%d) %02x:%02x:%02x:%02x:%02x:%02x",
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* disable rx filter */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * Set Receive filter control register
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* all broadcast, all multicast, all physical */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff } else if ((dp->rxmode & RXMODE_ALLMULTI) || dp->mc_count > 16*32/2) {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* all broadcast, all multicast, physical for the chip */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * Use multicast hash table,
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * accept all broadcast and physical for the chip.
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff mode = RFCR_AAB | RFCR_MHEN_DP83815 | RFCR_APM_DP83815;
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * Use pattern mach filter for multicast address,
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * accept all broadcast and physical for the chip
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* need to enable corresponding pattern registers */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "!%s: mac %02x:%02x:%02x:%02x:%02x:%02x"
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff " cache %02x:%02x:%02x:%02x:%02x:%02x",
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff dp->name, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * XXX - need to *disable* rx filter to load mac address for
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * the chip. otherwise, we cannot setup rxfilter correctly.
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* setup perfect match register for my station address */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* clear pattern ram */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* setup multicast address into pattern match registers */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* setup pattern count registers */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* Load Multicast hash table */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff for (i = 0; i < 32; i++) {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* for DP83815, index is in byte */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* Set rx filter mode and enable rx filter */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff DPRINTF(4, (CE_CONT, CONS "%s: %s: called", dp->name, __func__));
915ebf8da9f4ef3e7b2e34dd367f64d358a628d9Alan Duboff /* disable rx filter */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * determine hardware hash table size in word.
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff if (lp->revid >= SIS635A_900_REV || lp->revid == SIS900B_900_REV) {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* Set Receive filter control register */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* all broadcast, all multicast, all physical */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* all broadcast, all multicast, physical for the chip */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* all broadcast, physical for the chip */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* make hash table */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* Disable Rx filter and load mac address */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* For sis900, index is in word */
915ebf8da9f4ef3e7b2e34dd367f64d358a628d9Alan Duboff OUTLINL(dp, RFDR, (mac[i*2+1] << 8) | mac[i*2]);
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* Load Multicast hash table */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff for (i = 0; i < hash_size; i++) {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* For sis900, index is in word */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff (RFADDR_MULTICAST_SIS900 + i) << RFCR_RFADDR_SHIFT_SIS900);
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* Load rx filter mode and enable rx filter */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff DPRINTF(4, (CE_CONT, CONS "%s: %s: called", dp->name, __func__));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * setup interrupt mask, which shouldn't include ISR_TOK
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * to improve performance.
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* enable interrupt */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* Kick RX */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * Stop nic core gracefully.
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff DPRINTF(4, (CE_CONT, CONS "%s: %s: called", dp->name, __func__));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * Although we inhibit interrupt here, we don't clear soft copy of
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * interrupt mask to avoid bogus interrupts.
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* stop TX and RX immediately */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff for (i = 0; done != (ISR_RXRCMP | ISR_TXRCMP); i++) {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff if (i > 1000) {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * As gem layer will call sfe_reset_chip(),
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * we don't neet to reset futher
53560dfa94d868e9016a1b90f971fb538dc2009aSherry Moore * Stop nic core gracefully for quiesce
53560dfa94d868e9016a1b90f971fb538dc2009aSherry Moore * Although we inhibit interrupt here, we don't clear soft copy of
53560dfa94d868e9016a1b90f971fb538dc2009aSherry Moore * interrupt mask to avoid bogus interrupts.
53560dfa94d868e9016a1b90f971fb538dc2009aSherry Moore /* stop TX and RX immediately */
53560dfa94d868e9016a1b90f971fb538dc2009aSherry Moore for (i = 0; done != (ISR_RXRCMP | ISR_TXRCMP); i++) {
53560dfa94d868e9016a1b90f971fb538dc2009aSherry Moore if (i > 1000) {
53560dfa94d868e9016a1b90f971fb538dc2009aSherry Moore * As gem layer will call sfe_reset_chip(),
53560dfa94d868e9016a1b90f971fb538dc2009aSherry Moore * we don't neet to reset futher
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * Setup media mode
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboffsfe_mxdma_value[] = { 512, 4, 8, 16, 32, 64, 128, 256, };
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* choose 512 */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff return (0);
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff return (i);
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff DPRINTF(2, (CE_CONT, CONS "%s: %s: %s duplex, %d Mbps",
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff dp->full_duplex ? "full" : "half", gem_speed_value[dp->speed]));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* initialize txcfg and rxcfg */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* select txmxdma and rxmxdma, maxmum burst length */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * sis900 built-in cores:
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * max burst length must be fixed to 64
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * sis900 pci chipset:
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * the vendor recommended to fix max burst length
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * NS dp83815/816:
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * use user defined or default for tx/rx max burst length
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* tx high water mark */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff lp->tx_drain_threshold = ROUNDUP2(dp->txthr, TXCFG_FIFO_UNIT);
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* determine tx_fill_threshold accroding drain threshold */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff TXFIFOSIZE - lp->tx_drain_threshold - TXCFG_FIFO_UNIT;
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* tune txmxdma not to exceed tx_fill_threshold */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff for (; ; ) {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* normalize txmxdma requested */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* select new txmxdma */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* encode rxmxdma, maxmum burst length for rx */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* receive starting threshold - it have only 5bit-wide field */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff val = ROUNDUP2(max(dp->rxthr, ETHERMIN), RXCFG_FIFO_UNIT);
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff min(val, (RXCFG_DRTH >> RXCFG_DRTH_SHIFT) * RXCFG_FIFO_UNIT);
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "%s: %s: tx: drain:%d(rest %d) fill:%d mxdma:%d,"
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff " rx: drain:%d mxdma:%d",
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff lp->tx_drain_threshold, TXFIFOSIZE - lp->tx_drain_threshold,
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff txcfg |= ((lp->tx_fill_threshold/TXCFG_FIFO_UNIT) << TXCFG_FLTH_SHIFT)
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff rxcfg |= ((lp->rx_drain_threshold/RXCFG_FIFO_UNIT) << RXCFG_DRTH_SHIFT);
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff DPRINTF(0, (CE_CONT, CONS "%s: %s: txcfg:%b rxcfg:%b",
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* Flow control */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* do nothing */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * descriptor manipulations
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff ddi_dma_cookie_t *dmacookie, int frags, uint64_t flags)
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff CONS "%s: time:%d %s seqnum: %d, slot %d, frags: %d flags: %llx",
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff for (i = 0; i < frags; i++) {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff i, dmacookie[i].dmac_address, dmacookie[i].dmac_size);
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * write tx descriptor in reversed order.
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboffsfe_tx_start(struct gem_dev *dp, int start_slot, int nslot)
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff tdp = (void *)&dp->tx_ring[SFE_DESC_SIZE * start_slot];
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff gem_tx_desc_dma_sync(dp, start_slot, 1, DDI_DMA_SYNC_FORDEV);
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * Let the Transmit Buffer Manager Fill state machine active.
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "%s: %s seqnum: %d, slot %d, frags: %d",
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff dp->name, __func__, dp->rx_active_tail, slot, frags);
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff for (i = 0; i < frags; i++) {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff cmn_err(CE_CONT, CONS " frag: %d addr: 0x%llx, len: 0x%lx",
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff i, dmacookie[i].dmac_address, dmacookie[i].dmac_size);
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* for the last slot of the packet */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboffsfe_tx_desc_stat(struct gem_dev *dp, int slot, int ndesc)
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* check status of the last descriptor */
23d366e350386ec109bfa9b2cf91225729a1a26bduboff &dp->tx_ring[SFE_DESC_SIZE * SLOT(slot + ndesc - 1, tx_ring_size)];
23d366e350386ec109bfa9b2cf91225729a1a26bduboff * Don't use LE_32() directly to refer tdp->d_cmdsts.
23d366e350386ec109bfa9b2cf91225729a1a26bduboff * It is not atomic for big endian cpus.
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff DPRINTF(2, (CE_CONT, CONS "%s: time:%ld %s: slot:%d, status:0x%b",
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * not yet transmitted
23d366e350386ec109bfa9b2cf91225729a1a26bduboff /* workaround for tx hang */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff return (0);
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* XXX - the hardware problem but don't panic the system */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* avoid lint bug for %b format string including 32nd bit */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "%s: tx status bits incorrect: slot:%d, status:0x%x",
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff delay = (ddi_get_lbolt() - dp->tx_buf_head->txb_stime) * 10;
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff DPRINTF(0, (CE_NOTE, "%s: tx deferred %d mS: slot %d",
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff ((struct sfe_desc *)((void *)
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * collect statistics
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* failed to transmit the packet */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff DPRINTF(0, (CE_CONT, CONS "%s: Transmit error, Tx status %b",
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff } else if ((!dp->full_duplex) && (status & CMDSTS_EC)) {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff } else /* (cols > 1) */ {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboffsfe_rx_desc_stat(struct gem_dev *dp, int slot, int ndesc)
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* Dont read ISR because we cannot ack only to rx interrupt. */
23d366e350386ec109bfa9b2cf91225729a1a26bduboff * Don't use LE_32() directly to refer rdp->d_cmdsts.
23d366e350386ec109bfa9b2cf91225729a1a26bduboff * It is not atomic for big endian cpus.
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff DPRINTF(2, (CE_CONT, CONS "%s: time:%ld %s: slot:%d, status:0x%b",
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * No more received packets because
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * this buffer is owned by NIC.
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff return (0);
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff (CMDSTS_RXA | CMDSTS_RXO | CMDSTS_LONG | CMDSTS_RUNT | \
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * Packet with error received
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "received, buffer status: %b",
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* collect statistics information */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * this packet was received without errors
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* don't clear d_link field, which have a valid pointer */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* make a link to this from the previous descriptor */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff here = ((uint32_t)dp->tx_ring_dma) + SFE_DESC_SIZE*slot;
23d366e350386ec109bfa9b2cf91225729a1a26bduboff &dp->tx_ring[SFE_DESC_SIZE * SLOT(slot - 1, tx_ring_size)];
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* don't clear d_link field, which have a valid pointer */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* make a link to this from the previous descriptor */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff here = ((uint32_t)dp->rx_ring_dma) + SFE_DESC_SIZE*slot;
23d366e350386ec109bfa9b2cf91225729a1a26bduboff &dp->rx_ring[SFE_DESC_SIZE * SLOT(slot - 1, rx_ring_size)];
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * Device depend interrupt handler
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* read reason and clear interrupt */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* we are not the interrupt source */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff CONS "%s: time:%ld %s:called: isr:0x%b rx_active_head: %d",
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* the device is going to stop */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff if (isr & (ISR_RXSOVR | ISR_RXORN | ISR_RXIDLE | ISR_RXERR |
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* no need restart rx */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * Make RXDP points the head of receive
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * buffer list.
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* Restart the receive engine */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* need to reclaim tx buffers */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * XXX - tx error statistics will be counted in
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * sfe_tx_desc_stat() and no need to restart tx on errors.
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff if (isr & (ISR_DPERR | ISR_SSERR | ISR_RMABT | ISR_RTABT)) {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff/* ======================================================== */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * HW depend MII routine
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff/* ======================================================== */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * MII routines for NS DP83815
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* do nothing */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboffsfe_mii_read_dp83815(struct gem_dev *dp, uint_t offset)
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff return ((uint16_t)INL(dp, MII_REGS_BASE + offset*4));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboffsfe_mii_write_dp83815(struct gem_dev *dp, uint_t offset, uint16_t val)
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff DPRINTF(0, (CE_CONT, CONS "%s: srr:0x%04x %04x %04x %04x %04x %04x",
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * NS datasheet says that DP83815CVNG needs following
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * registers to be patched for optimizing its performance.
23d366e350386ec109bfa9b2cf91225729a1a26bduboff * A report said that CRC errors on RX disappeared
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * with the patch.
23d366e350386ec109bfa9b2cf91225729a1a26bduboff } else if (((srr ^ SRR_REV_DP83815DVNG) & 0xff00) == 0 ||
23d366e350386ec109bfa9b2cf91225729a1a26bduboff * Additional packets for later chipset
23d366e350386ec109bfa9b2cf91225729a1a26bduboff /* try external phy first */
23d366e350386ec109bfa9b2cf91225729a1a26bduboff DPRINTF(0, (CE_CONT, CONS "%s: %s: trying external phy",
23d366e350386ec109bfa9b2cf91225729a1a26bduboff /* switch to internal phy */
23d366e350386ec109bfa9b2cf91225729a1a26bduboff DPRINTF(0, (CE_CONT, CONS "%s: %s: switching to internal phy",
23d366e350386ec109bfa9b2cf91225729a1a26bduboff drv_usecwait(100); /* keep to assert RST bit for a while */
23d366e350386ec109bfa9b2cf91225729a1a26bduboff /* wait for PHY reset */
23d366e350386ec109bfa9b2cf91225729a1a26bduboff /* select internal phy */
23d366e350386ec109bfa9b2cf91225729a1a26bduboff /* select external phy */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * MII routines for SiS900
23d366e350386ec109bfa9b2cf91225729a1a26bduboff#define MDIO_DELAY(dp) {(void) INL(dp, MEAR); (void) INL(dp, MEAR); }
23d366e350386ec109bfa9b2cf91225729a1a26bduboff /* send 32 ONE's to make MII line idle */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff for (i = 0; i < 32; i++) {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* Do chip depend setup */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* workaround for ICS1893 PHY */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * SiS 630E has bugs on default values
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * of PHY registers
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* turn around cycle */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* get response from PHY */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* terminate response cycle */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff for (i = 16; i > 0; i--) {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff ret = (ret << 1) | ((INL(dp, MEAR) >> MEAR_MDIO_SHIFT) & 1);
23d366e350386ec109bfa9b2cf91225729a1a26bduboff /* send two idle(Z) bits to terminate the read cycle */
23d366e350386ec109bfa9b2cf91225729a1a26bduboff for (i = 0; i < 2; i++) {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboffsfe_mii_write_sis900(struct gem_dev *dp, uint_t reg, uint16_t val)
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff for (i = 31; i >= 0; i--) {
23d366e350386ec109bfa9b2cf91225729a1a26bduboff /* send two idle(Z) bits to terminate the write cycle. */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff for (i = 0; i < 2; i++) {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff if (!(rev == SIS630E_900_REV || rev == SIS630EA1_900_REV ||
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff rev == SIS630A_900_REV || rev == SIS630ET_900_REV)) {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* it doesn't have a internal PHY */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff gem_mii_write(dp, MII_RESV, (0x2200 | reg14h) & 0xBFFF);
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff eq_value = (0x00f8 & gem_mii_read(dp, MII_RESV)) >> 3;
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff eq_value = (0x00f8 & gem_mii_read(dp, MII_RESV)) >> 3;
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* for 630E, rule to determine the equalizer value */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff if (rev == SIS630E_900_REV || rev == SIS630EA1_900_REV ||
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* for 630B0&B1, rule to determine the equalizer value */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* write equalizer value and setting */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff reg14h = (gem_mii_read(dp, MII_RESV) & ~0x4000) | 0x2000;
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff/* ======================================================== */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * OS depend (device driver) routine
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff/* ======================================================== */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* sis630E */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* 630S, 630EA1, 630ET, 635A */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* sis962 or later */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* sis900 */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff if (rev == SIS630E_900_REV || rev == SIS630EA1_900_REV ||
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * read host bridge revision
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff if ((bridge = sfe_search_pci_dev(0x1039, 0x630)) == NULL) {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "%s: cannot find host bridge (pci1039,630)",
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff if (pci_config_setup(bridge, &bridge_handle) != DDI_SUCCESS) {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff DPRINTF(4, (CE_CONT, CONS "!%s: %s called", dp->name, __func__));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* setup chip-depend get_mac_address function */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* read MAC address */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "!%s: %s: failed to get factory mac address"
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff " please specify a mac address in sfe.conf",
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff const char *drv_name;
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff DPRINTF(3, (CE_CONT, CONS "%s%d: sfeattach: called", drv_name, unit));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * Common codes after power-up
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff if (pci_config_setup(dip, &conf_handle) != DDI_SUCCESS) {
23d366e350386ec109bfa9b2cf91225729a1a26bduboff iline = pci_config_get32(conf_handle, PCI_CONF_ILINE);
23d366e350386ec109bfa9b2cf91225729a1a26bduboff latim = pci_config_get8(conf_handle, PCI_CONF_LATENCY_TIMER);
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff for (i = 0, p = sfe_chiptbl; i < CHIPTABLESIZE; i++, p++) {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* found */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* Not found */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "%s%d: sfe_attach: wrong PCI venid/devid (0x%x, 0x%x)",
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* ensure D0 mode */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff (void) gem_pci_set_power_state(dip, conf_handle, PCI_PMCSR_D0);
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * Map in the device registers.
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff (sfe_use_pcimemspace && p->chip_type == CHIPTYPE_DP83815)
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "%s%d: ddi_regs_map_setup failed",
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * construct gem configuration
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff (void) sprintf(gcp->gc_name, "%s%d", drv_name, unit);
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* consistency on tx and rx */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* map attributes */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* dma attributes */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff gcp->gc_dma_attr_txbuf.dma_attr_align = gcp->gc_tx_buf_align+1;
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff gcp->gc_dma_attr_txbuf.dma_attr_sgllen = gcp->gc_tx_max_frags;
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff gcp->gc_dma_attr_rxbuf.dma_attr_align = gcp->gc_rx_buf_align+1;
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff gcp->gc_dma_attr_rxbuf.dma_attr_sgllen = gcp->gc_rx_max_frags;
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* time out parameters */
23d366e350386ec109bfa9b2cf91225729a1a26bduboff /* workaround for tx hang */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* MII timeout parameters */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff gcp->gc_mii_reset_timeout = MII_RESET_TIMEOUT; /* 1 sec */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* setting for general PHY */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff gcp->gc_mii_linkdown_timeout_action = MII_ACTION_RESET;
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* I/O methods */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* mac operation */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* descriptor operation */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* mii operations */
53560dfa94d868e9016a1b90f971fb538dc2009aSherry Moore * quiesce(9E) entry point.
53560dfa94d868e9016a1b90f971fb538dc2009aSherry Moore * This function is called when the system is single-threaded at high
53560dfa94d868e9016a1b90f971fb538dc2009aSherry Moore * PIL with preemption disabled. Therefore, this function must not be
53560dfa94d868e9016a1b90f971fb538dc2009aSherry Moore * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure.
53560dfa94d868e9016a1b90f971fb538dc2009aSherry Moore * DDI_FAILURE indicates an error condition and should almost never happen.
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff/* ======================================================== */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * OS depend (loadable streams driver) routine
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff/* ======================================================== */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboffDDI_DEFINE_STREAM_OPS(sfe_ops, nulldev, nulldev, sfeattach, sfedetach,
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff &mod_driverops, /* Type of module. This one is a driver */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff/* ======================================================== */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * Loadable module support
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff/* ======================================================== */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * _fini : done