Mercurial > illumos > illumos-gate
changeset 4404:a0cc4e7d9fb5
PSARC 2007/243 Eri Conversion To GLDv3
4891285 RFE to add debug kstat counter for promiscuous mode to eri driver
6490162 eri passes packets upstream before the stream is in the DL_IDLE state
6549493 convert eri to GLDv3
author | gd78059 |
---|---|
date | Thu, 07 Jun 2007 06:48:35 -0700 |
parents | 77da60925cac |
children | 6d1bc9962bf5 |
files | usr/src/uts/sparc/eri/Makefile usr/src/uts/sun/io/eri.c usr/src/uts/sun/sys/eri.h usr/src/uts/sun/sys/eri_common.h usr/src/uts/sun/sys/eri_mac.h usr/src/uts/sun/sys/eri_msg.h |
diffstat | 6 files changed, 1274 insertions(+), 4871 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/sparc/eri/Makefile Thu Jun 07 06:43:34 2007 -0700 +++ b/usr/src/uts/sparc/eri/Makefile Thu Jun 07 06:48:35 2007 -0700 @@ -23,7 +23,7 @@ # #ident "%Z%%M% %I% %E% SMI" # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # This makefile drives the production of the eri driver @@ -66,17 +66,7 @@ # Overrides. # CFLAGS += $(CCVERBOSE) - -# -# For now, disable these lint checks; maintainers should endeavor -# to investigate and remove these for maximum lint coverage. -# Please do not carry these forward to new Makefiles. -# -LINTTAGS += -erroff=E_BAD_PTR_CAST_ALIGN -LINTTAGS += -erroff=E_PTRDIFF_OVERFLOW -LINTTAGS += -erroff=E_ASSIGN_NARROW_CONV -LINTTAGS += -erroff=E_STATIC_UNUSED -LINTTAGS += -erroff=E_SUSPICIOUS_COMPARISON +LDFLAGS += -dy -N misc/mac -N drv/ip # # Default build targets.
--- a/usr/src/uts/sun/io/eri.c Thu Jun 07 06:43:34 2007 -0700 +++ b/usr/src/uts/sun/io/eri.c Thu Jun 07 06:48:35 2007 -0700 @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -35,7 +35,6 @@ #include <sys/stream.h> #include <sys/strlog.h> #include <sys/strsubr.h> -#include <sys/vtrace.h> #include <sys/kmem.h> #include <sys/crc32.h> #include <sys/ddi.h> @@ -45,12 +44,14 @@ #include <sys/cpu.h> #include <sys/kstat.h> #include <inet/common.h> -#include <sys/dlpi.h> #include <sys/pattr.h> #include <inet/mi.h> #include <inet/nd.h> #include <sys/ethernet.h> #include <sys/policy.h> +#include <sys/mac.h> +#include <sys/mac_ether.h> +#include <sys/dlpi.h> #include <sys/pci.h> @@ -71,42 +72,29 @@ * Entry points (man9e) */ static int eri_attach(dev_info_t *, ddi_attach_cmd_t); -static int eri_close(queue_t *); static int eri_detach(dev_info_t *, ddi_detach_cmd_t); -static uint_t eri_intr(); -static int eri_open(queue_t *, dev_t *, int, int, cred_t *); -#ifdef ERI_SERVICE_ROUTINE -static int eri_rsrv(queue_t *); -#endif -static int eri_wput(queue_t *, mblk_t *); -static int eri_wsrv(queue_t *); -static void eri_wenable(struct eri *); -static void eri_sendup(struct eri *, mblk_t *, struct eristr *(*)()); +static uint_t eri_intr(caddr_t); /* * I/O (Input/Output) Functions */ -static int eri_start(queue_t *, mblk_t *, struct eri *); -static void eri_read_dma(struct eri *, volatile struct rmd *, - volatile int, uint64_t flags); +static boolean_t eri_send_msg(struct eri *, mblk_t *); +static mblk_t *eri_read_dma(struct eri *, volatile struct rmd *, + volatile int, uint64_t flags); /* * Initialization Functions */ -static int eri_init(struct eri *); +static boolean_t eri_init(struct eri *); static int eri_allocthings(struct eri *); static int eri_init_xfer_params(struct eri *); static void eri_statinit(struct eri *); static int eri_burstsize(struct eri *); static void eri_setup_mac_address(struct eri *, dev_info_t *); -static char *eri_ether_sprintf(struct ether_addr *); static uint32_t eri_init_rx_channel(struct eri *); static void eri_init_rx(struct eri *); -#ifdef LATER_SPLIT_TX_RX -static void eri_init_tx_channel(struct eri *); -#endif static void eri_init_txmac(struct eri *); /* @@ -117,14 +105,11 @@ static int eri_stop(struct eri *); static void eri_uninit(struct eri *erip); static int eri_freebufs(struct eri *); -static uint_t eri_reclaim(struct eri *, uint32_t); +static boolean_t eri_reclaim(struct eri *, uint32_t); /* * Transceiver (xcvr) Functions */ -#ifdef XCVR -static int eri_init_xcvr_info(struct eri *, int); -#endif static int eri_new_xcvr(struct eri *); /* Initializes & detects xcvrs */ static int eri_reset_xcvr(struct eri *); @@ -135,8 +120,7 @@ static void eri_mif_poll(struct eri *, soft_mif_enable_t); static void eri_check_link(struct eri *); static uint32_t eri_check_link_noind(struct eri *); -static void eri_display_link_status(struct eri *); -static uint32_t eri_mif_check(struct eri *, uint16_t, uint16_t); +static link_state_t eri_mif_check(struct eri *, uint16_t, uint16_t); static void eri_mii_write(struct eri *, uint8_t, uint16_t); static uint32_t eri_mii_read(struct eri *, uint8_t, uint16_t *); @@ -159,8 +143,7 @@ /* * Hardening Functions */ -static void eri_fault_msg(char *, uint_t, struct eri *, uint_t, - msg_t, char *, ...); +static void eri_fault_msg(struct eri *, uint_t, msg_t, const char *, ...); /* * Misc Functions @@ -171,15 +154,6 @@ static void eri_start_timer(struct eri *erip, fptrv_t func, clock_t msec); static void eri_bb_force_idle(struct eri *); -static int eri_mcmatch(struct eristr *, struct ether_addr *); -static struct eristr *eri_paccept(struct eristr *, struct eri *, int, - struct ether_addr *); - -static struct eristr *eri_accept(struct eristr *, struct eri *, int, - struct ether_addr *); - -static mblk_t *eri_addudind(struct eri *, mblk_t *, struct ether_addr *, - struct ether_addr *, int, uint32_t); /* * Utility Functions @@ -188,7 +162,6 @@ static mblk_t *eri_allocb_sp(size_t size); static int eri_param_get(queue_t *q, mblk_t *mp, caddr_t cp); static int eri_param_set(queue_t *, mblk_t *, char *, caddr_t); -static long eri_strtol(char *, char **, int); /* * Functions to support ndd @@ -201,50 +174,41 @@ static int eri_nd_getset(queue_t *q, caddr_t nd_param, MBLKP mp); static void eri_param_cleanup(struct eri *); static int eri_param_register(struct eri *, param_t *, int); -static void eri_process_ndd_ioctl(queue_t *wq, mblk_t *mp, int cmd); - -static void eri_cable_down_msg(struct eri *); +static void eri_process_ndd_ioctl(struct eri *, queue_t *, mblk_t *, int); +static int eri_mk_mblk_tail_space(mblk_t *, mblk_t **, size_t); + + +static void eri_loopback(struct eri *, queue_t *, mblk_t *); + +static uint32_t eri_ladrf_bit(const uint8_t *); + /* - * DLPI Functions + * Nemo (GLDv3) Functions. */ - -static void eri_proto(queue_t *, mblk_t *); -static void eri_ioctl(queue_t *, mblk_t *); -static void eri_loopback(queue_t *, mblk_t *); -static void eri_mctl(queue_t *q, MBLKP mp); -static void eri_dodetach(struct eristr *); - -static void eri_dl_ioc_hdr_info(queue_t *, mblk_t *); - -static void eri_areq(queue_t *, mblk_t *); -static void eri_dreq(queue_t *, mblk_t *); -static void eri_breq(queue_t *, mblk_t *); -static void eri_ubreq(queue_t *, mblk_t *); -static void eri_ireq(queue_t *, mblk_t *); -static void eri_ponreq(queue_t *, mblk_t *); -static void eri_poffreq(queue_t *, mblk_t *); -static void eri_emreq(queue_t *, mblk_t *); -static void eri_dmreq(queue_t *, mblk_t *); -static void eri_pareq(queue_t *, mblk_t *); -static void eri_spareq(queue_t *, mblk_t *); -static void eri_udreq(queue_t *, mblk_t *); -static void eri_nreq(queue_t *, mblk_t *); -static void eri_dlcap_req(queue_t *, mblk_t *); -static mblk_t *eri_dlcap_all(queue_t *); -static void eri_dlcap_enable(queue_t *, mblk_t *); - -static void eri_notify_ind(struct eri *, uint32_t); -static void eri_send_notifications(struct eri *, uint32_t); - -static void eri_setipq(struct eri *); - -static uint32_t eri_ladrf_bit(struct ether_addr *addr); - -static void eri_process_ndd_ioctl(queue_t *wq, mblk_t *mp, int cmd); - -static int eri_mk_mblk_tail_space(mblk_t *, mblk_t **, size_t); - +static int eri_m_stat(void *, uint_t, uint64_t *); +static int eri_m_start(void *); +static void eri_m_stop(void *); +static int eri_m_promisc(void *, boolean_t); +static int eri_m_multicst(void *, boolean_t, const uint8_t *); +static int eri_m_unicst(void *, const uint8_t *); +static void eri_m_ioctl(void *, queue_t *, mblk_t *); +static boolean_t eri_m_getcapab(void *, mac_capab_t, void *); +static mblk_t *eri_m_tx(void *, mblk_t *); + +static mac_callbacks_t eri_m_callbacks = { + MC_IOCTL | MC_GETCAPAB, + eri_m_stat, + eri_m_start, + eri_m_stop, + eri_m_promisc, + eri_m_multicst, + eri_m_unicst, + eri_m_tx, + NULL, + eri_m_ioctl, + eri_m_getcapab +}; /* * Define PHY Vendors: Matches to IEEE @@ -263,99 +227,26 @@ #define FORCE_SPEED 1 /* - * link_up kstat variable states - */ -#define ERI_LINK_DOWN 0 -#define ERI_LINK_UP 1 - -/* - * States for kstat variable link_duplex - */ -#define ERI_UNKNOWN_DUPLEX 0 -#define ERI_HALF_DUPLEX 1 -#define ERI_FULL_DUPLEX 2 - -/* - * tcp and ip data structures used to grab some length - * and type information in eri_read_dma(). - */ -#ifdef ERI_RCV_CKSUM -typedef struct ip { - uint8_t ip_v:4; /* version */ - uint8_t ip_hl:4; /* header length */ - uint8_t ip_tos; /* type of service */ - int16_t ip_len; /* total length */ - uint16_t ip_id; /* identification */ - int16_t ip_off; /* fragment offset field */ - uint8_t ip_ttl; /* time to live */ - uint8_t ip_p; /* protocol */ - uint16_t ip_sum; /* checksum */ - uint32_t ip_src; /* src address */ - uint32_t ip_dst; /* dest address */ -} ip_t; - -typedef struct tcphdr { - uint16_t th_sport; /* source port */ - uint16_t th_dport; /* destination port */ - uint32_t th_seq; /* sequence number */ - uint32_t th_ack; /* acknowledgement number */ - uint8_t th_off:4, /* data offset */ - th_x2:4; /* (unused) */ - uint8_t th_flags; - uint16_t th_win; /* window */ - uint16_t th_sum; /* checksum */ - uint16_t th_urp; /* urgent pointer */ -} tcp_t; - -#endif - -/* * MIB II broadcast/multicast packets */ -#define IS_NOT_MULTICAST(ehp) \ - ((ehp->ether_dhost.ether_addr_octet[0] & 01) == 0) - -#define IS_BROADCAST(ehp) \ - (ether_cmp(&ehp->ether_dhost, ðerbroadcastaddr) == 0) -#define IS_MULTICAST(ehp) \ - ((ehp->ether_dhost.ether_addr_octet[0] & 01) == 1) -#define BUMP_InNUcast(erip, ehp) \ - if (IS_BROADCAST(ehp)) { \ + +#define IS_BROADCAST(pkt) (bcmp(pkt, ðerbroadcastaddr, ETHERADDRL) == 0) +#define IS_MULTICAST(pkt) ((pkt[0] & 01) == 1) + +#define BUMP_InNUcast(erip, pkt) \ + if (IS_BROADCAST(pkt)) { \ HSTAT(erip, brdcstrcv); \ - } else if (IS_MULTICAST(ehp)) { \ + } else if (IS_MULTICAST(pkt)) { \ HSTAT(erip, multircv); \ } -#define BUMP_OutNUcast(erip, ehp) \ - if (IS_BROADCAST(ehp)) { \ +#define BUMP_OutNUcast(erip, pkt) \ + if (IS_BROADCAST(pkt)) { \ HSTAT(erip, brdcstxmt); \ - } else if (IS_MULTICAST(ehp)) { \ + } else if (IS_MULTICAST(pkt)) { \ HSTAT(erip, multixmt); \ } - /* - * ERI 1.0 has a bug in which the last byte of the MAC address is - * ehp->ether_dhost.ether_addr_octet[5] - * not filtered thus accepting all the packets with the first five bytes - * match. Here we filter out the packets which are not intended for us. - * - * !(ehp->ether_dhost.ether_addr_octet[0] & 0x1) checks if the packet - * is not mutlicast. - * - * (ehp->ether_dhost.ether_addr_octet[1] & - * ehp->ether_dhost.ether_addr_octet[5]) != 0xff ), checks if the - * the packet could be a broadcast. If it were broadcast, both bytes - * would be 0xff. This could be never true for unicast because - * the vendor portion for Sun would 8:0:20. - */ - -#define INVALID_MAC_ADDRESS(erip, ehp) \ - (!(erip->flags & ERI_PROMISC) && \ - (IS_NOT_MULTICAST(ehp) && ~IS_BROADCAST(ehp) && \ - (erip->ouraddr.ether_addr_octet[5] != \ - ehp->ether_dhost.ether_addr_octet[5]))) - - #define NEXTTMDP(tbasep, tmdlimp, tmdp) (((tmdp) + 1) == tmdlimp \ ? tbasep : ((tmdp) + 1)) @@ -364,12 +255,8 @@ #ifdef ERI_RCV_CKSUM #define ERI_PROCESS_READ(erip, bp, sum) \ { \ - queue_t *ipq; \ t_uscalar_t type; \ - struct ether_header *ehp; \ - uint_t sb_flags; \ uint_t start_offset, end_offset; \ - ehp = (struct ether_header *)bp->b_rptr; \ \ *(bp->b_wptr) = 0; /* pad byte */ \ \ @@ -378,33 +265,15 @@ */ \ HSTAT(erip, ipackets64); \ HSTATN(erip, rbytes64, len); \ - BUMP_InNUcast(erip, ehp); \ - type = get_ether_type(ehp); \ - ipq = erip->ip4q; \ - if (type == ETHERTYPE_IPV6) \ - ipq = erip->ip6q; \ - if ((type == ETHERTYPE_IPV4 || type == ETHERTYPE_IPV6) && \ - (IS_NOT_MULTICAST(ehp)) && (ipq) && \ - (((ether_cmp(ehp, &erip->ouraddr) == 0) || \ - (ether_cmp(ehp, ðerbroadcastaddr) == 0)))) { \ - bp->b_rptr += ETHERHEADER_SIZE; \ + BUMP_InNUcast(erip, bp->b_rptr); \ + type = get_ether_type(bp->b_rptr); \ + if (type == ETHERTYPE_IP || type == ETHERTYPE_IPV6) { \ start_offset = 0; \ - end_offset = bp->b_wptr - bp->b_rptr; \ - sb_flags = ((struct eristr *)ipq->q_ptr)->sb_flags;\ - if ((sb_flags & ERI_SCKSUM) && \ - (sb_flags & ERI_SFAST)) { \ - (void) hcksum_assoc(bp, NULL, \ - NULL, start_offset, 0, \ - end_offset, sum, \ - HCK_PARTIALCKSUM, 0); \ - } \ - if (canputnext(ipq)) \ - (void) putnext(ipq, bp); \ - else { \ - freemsg(bp); \ - HSTAT(erip, nocanput); \ - HSTAT(erip, ierrors); \ - } \ + end_offset = bp->b_wptr - \ + (bp->b_rptr + ETHERHEADER_SIZE); \ + (void) hcksum_assoc(bp, NULL, NULL, \ + start_offset, 0, end_offset, sum, \ + HCK_PARTIALCKSUM, 0); \ } else { \ /* \ * Strip the PADS for 802.3 \ @@ -412,43 +281,27 @@ if (type <= ETHERMTU) \ bp->b_wptr = bp->b_rptr + \ ETHERHEADER_SIZE + type; \ - eri_sendup(erip, bp, eri_accept); \ } \ } #else #define ERI_PROCESS_READ(erip, bp) \ { \ - queue_t *ipq; \ t_uscalar_t type; \ - struct ether_header *ehp; \ - uint_t sb_flags; \ - ehp = (struct ether_header *)bp->b_rptr; \ - type = get_ether_type(ehp); \ - ipq = erip->ip4q; \ - if (type == ETHERTYPE_IPV6) \ - ipq = erip->ip6q; \ - if ((type == ETHERTYPE_IPV4 || type == ETHERTYPE_IPV6) && \ - (IS_NOT_MULTICAST(ehp)) && (ipq) && \ - (((ether_cmp(ehp, &erip->ouraddr) == 0) || \ - (ether_cmp(ehp, ðerbroadcastaddr) == 0)))) { \ - bp->b_rptr += ETHERHEADER_SIZE; \ - if (canputnext(ipq)) \ - (void) putnext(ipq, bp); \ - else { \ - freemsg(bp); \ - HSTAT(erip, nocanput); \ - HSTAT(erip, ierrors); \ - } \ - } else { \ - /* \ - * Strip the PADS for 802.3 \ - */ \ - if (type <= ETHERMTU) \ - bp->b_wptr = bp->b_rptr + \ - ETHERHEADER_SIZE + type; \ - eri_sendup(erip, bp, eri_accept); \ - } \ + type = get_ether_type(bp->b_rptr); \ + \ + /* \ + * update MIB II statistics \ + */ \ + HSTAT(erip, ipackets64); \ + HSTATN(erip, rbytes64, len); \ + BUMP_InNUcast(erip, bp->b_rptr); \ + /* \ + * Strip the PADS for 802.3 \ + */ \ + if (type <= ETHERMTU) \ + bp->b_wptr = bp->b_rptr + ETHERHEADER_SIZE + \ + type; \ } #endif /* ERI_RCV_CKSUM */ @@ -460,29 +313,10 @@ /* * Ethernet broadcast address definition. */ -static struct ether_addr etherbroadcastaddr = { +static uint8_t etherbroadcastaddr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; -#define ERI_SAPMATCH(sap, type, flags) ((sap == type)? 1 : \ - ((flags & ERI_SALLSAP)? 1 : \ - ((sap <= ETHERMTU) && (sap >= (t_uscalar_t)0) && \ - (type <= ETHERMTU))? 1 : 0)) - -/* - * Linked list of active (inuse) driver Streams. - */ -static struct eristr *eristrup = NULL; -static krwlock_t eristruplock; - -/* - * Single private "global" lock for the few rare conditions - * we want single-threaded. - */ -static kmutex_t erilock; -static kmutex_t eriwenlock; -static struct eri *eriup = NULL; - /* * The following variables are used for configuring various features */ @@ -678,7 +512,6 @@ static int eri_force_mlf = 0; /* to enable mif poll */ static int eri_phy_mintrans = 1; /* Lu3X31T mintrans algorithm */ -static int eri_hash_filter = 1; /* use hash filter vs group bit */ /* * For the MII interface, the External Transceiver is selected when present. * The following variable is used to select the Internal Transceiver even @@ -686,7 +519,6 @@ */ static int use_int_xcvr = 0; static int pace_size = 0; /* Do not use pacing for now */ -static int device = -1; static int eri_use_dvma_rx = 0; /* =1:use dvma */ static int eri_use_dvma_tx = 1; /* =1:use dvma */ @@ -720,198 +552,52 @@ /* ------------------------------------------------------------------------- */ static param_t param_arr[] = { - /* min max value name */ - { 0, 2, 2, "transceiver_inuse"}, - { 0, 1, 0, "link_status"}, - { 0, 1, 0, "link_speed"}, - { 0, 1, 0, "link_mode"}, - { 0, 255, 8, "ipg1"}, - { 0, 255, 4, "ipg2"}, - { 0, 1, 0, "use_int_xcvr"}, - { 0, 255, 0, "pace_size"}, - { 0, 1, 1, "adv_autoneg_cap"}, - { 0, 1, 1, "adv_100T4_cap"}, - { 0, 1, 1, "adv_100fdx_cap"}, - { 0, 1, 1, "adv_100hdx_cap"}, - { 0, 1, 1, "adv_10fdx_cap"}, - { 0, 1, 1, "adv_10hdx_cap"}, - { 0, 1, 1, "autoneg_cap"}, - { 0, 1, 1, "100T4_cap"}, - { 0, 1, 1, "100fdx_cap"}, - { 0, 1, 1, "100hdx_cap"}, - { 0, 1, 1, "10fdx_cap"}, - { 0, 1, 1, "10hdx_cap"}, - { 0, 1, 0, "lp_autoneg_cap"}, - { 0, 1, 0, "lp_100T4_cap"}, - { 0, 1, 0, "lp_100fdx_cap"}, - { 0, 1, 0, "lp_100hdx_cap"}, - { 0, 1, 0, "lp_10fdx_cap"}, - { 0, 1, 0, "lp_10hdx_cap"}, - { 0, 255, 0, "instance"}, - { 0, 1, 1, "lance_mode"}, - { 0, 31, 8, "ipg0"}, - { 0, 127, 6, "intr_blank_time"}, - { 0, 255, 8, "intr_blank_packets"}, - { 0, 1, 1, "serial-link"}, - { 0, 2, 1, "non-serial-link"}, - { 0, 1, 0, "select-link"}, - { 0, 1, 0, "default-link"}, - { 0, 2, 0, "link-in-use"}, - { 0, 1, 1, "adv_1000autoneg_cap"}, - { 0, 1, 1, "adv_1000fdx_cap"}, - { 0, 1, 1, "adv_1000hdx_cap"}, - { 0, 1, 1, "adv_asm_dir_cap"}, - { 0, 1, 1, "adv_pause_cap"}, - { 0, 1, 0, "1000autoneg_cap"}, - { 0, 1, 0, "1000fdx_cap"}, - { 0, 1, 0, "1000hdx_cap"}, - { 0, 1, 0, "asm_dir_cap"}, - { 0, 1, 0, "pause_cap"}, - { 0, 1, 0, "lp_1000autoneg_cap"}, - { 0, 1, 0, "lp_1000fdx_cap"}, - { 0, 1, 0, "lp_1000hdx_cap"}, - { 0, 1, 0, "lp_asm_dir_cap"}, - { 0, 1, 0, "lp_pause_cap"}, + /* min max value r/w/hidden+name */ + { 0, 2, 2, "-transceiver_inuse"}, + { 0, 1, 0, "-link_status"}, + { 0, 1, 0, "-link_speed"}, + { 0, 1, 0, "-link_mode"}, + { 0, 255, 8, "+ipg1"}, + { 0, 255, 4, "+ipg2"}, + { 0, 1, 0, "+use_int_xcvr"}, + { 0, 255, 0, "+pace_size"}, + { 0, 1, 1, "+adv_autoneg_cap"}, + { 0, 1, 1, "+adv_100T4_cap"}, + { 0, 1, 1, "+adv_100fdx_cap"}, + { 0, 1, 1, "+adv_100hdx_cap"}, + { 0, 1, 1, "+adv_10fdx_cap"}, + { 0, 1, 1, "+adv_10hdx_cap"}, + { 0, 1, 1, "-autoneg_cap"}, + { 0, 1, 1, "-100T4_cap"}, + { 0, 1, 1, "-100fdx_cap"}, + { 0, 1, 1, "-100hdx_cap"}, + { 0, 1, 1, "-10fdx_cap"}, + { 0, 1, 1, "-10hdx_cap"}, + { 0, 1, 0, "-lp_autoneg_cap"}, + { 0, 1, 0, "-lp_100T4_cap"}, + { 0, 1, 0, "-lp_100fdx_cap"}, + { 0, 1, 0, "-lp_100hdx_cap"}, + { 0, 1, 0, "-lp_10fdx_cap"}, + { 0, 1, 0, "-lp_10hdx_cap"}, + { 0, 1, 1, "+lance_mode"}, + { 0, 31, 8, "+ipg0"}, + { 0, 127, 6, "+intr_blank_time"}, + { 0, 255, 8, "+intr_blank_packets"}, + { 0, 1, 1, "!serial-link"}, + { 0, 2, 1, "!non-serial-link"}, + { 0, 1, 0, "%select-link"}, + { 0, 1, 0, "%default-link"}, + { 0, 2, 0, "!link-in-use"}, + { 0, 1, 1, "%adv_asm_dir_cap"}, + { 0, 1, 1, "%adv_pause_cap"}, + { 0, 1, 0, "!asm_dir_cap"}, + { 0, 1, 0, "!pause_cap"}, + { 0, 1, 0, "!lp_asm_dir_cap"}, + { 0, 1, 0, "!lp_pause_cap"}, }; -#define DISPLAY_PARAM 1 -#define DONT_DISPLAY 0 - - -static uint32_t param_display_mii[] = { -/* DISPLAY */ -DISPLAY_PARAM, /* transceiver_inuse */ -DISPLAY_PARAM, /* link_status */ -DISPLAY_PARAM, /* link_speed */ -DISPLAY_PARAM, /* link_mode */ -DISPLAY_PARAM, /* ipg1 */ -DISPLAY_PARAM, /* ipg2 */ -DISPLAY_PARAM, /* use_int_xcvr */ -DISPLAY_PARAM, /* pace_size */ -DISPLAY_PARAM, /* adv_autoneg_cap */ -DISPLAY_PARAM, /* adv_100T4_cap */ -DISPLAY_PARAM, /* adv_100fdx_cap */ -DISPLAY_PARAM, /* adv_100hdx_cap */ -DISPLAY_PARAM, /* adv_10fdx_cap */ -DISPLAY_PARAM, /* adv_10hdx_cap */ -DISPLAY_PARAM, /* autoneg_cap */ -DISPLAY_PARAM, /* 100T4_cap */ -DISPLAY_PARAM, /* 100fdx_cap */ -DISPLAY_PARAM, /* 100hdx_cap */ -DISPLAY_PARAM, /* 10fdx_cap */ -DISPLAY_PARAM, /* 10hdx_cap */ -DISPLAY_PARAM, /* lp_autoneg_cap */ -DISPLAY_PARAM, /* lp_100T4_cap */ -DISPLAY_PARAM, /* lp_100fdx_cap */ -DISPLAY_PARAM, /* lp_100hdx_cap */ -DISPLAY_PARAM, /* lp_10fdx_cap */ -DISPLAY_PARAM, /* lp_10hdx_cap */ -DISPLAY_PARAM, /* instance */ -DISPLAY_PARAM, /* lance_mode */ -DISPLAY_PARAM, /* ipg0 */ -DISPLAY_PARAM, /* intr_blank_time */ -DISPLAY_PARAM, /* intr_blank_packets */ -DONT_DISPLAY, /* serial-link */ -DONT_DISPLAY, /* non-serial-link */ -DONT_DISPLAY, /* select-link */ -DONT_DISPLAY, /* default-link */ -DONT_DISPLAY, /* link-in-use */ -DONT_DISPLAY, /* adv_1000autoneg_cap */ -DONT_DISPLAY, /* adv_1000fdx_cap */ -DONT_DISPLAY, /* adv_1000hdx_cap */ -DONT_DISPLAY, /* adv_asm_dir */ -DONT_DISPLAY, /* adv_pause */ -DONT_DISPLAY, /* 1000autoneg_cap */ -DONT_DISPLAY, /* 1000fdx_cap */ -DONT_DISPLAY, /* 1000hdx_cap */ -DONT_DISPLAY, /* asm_dir_cap */ -DONT_DISPLAY, /* pause_cap */ -DONT_DISPLAY, /* lp_1000autoneg_cap */ -DONT_DISPLAY, /* lp_1000fdx_cap */ -DONT_DISPLAY, /* lp_1000hdx_cap */ -DONT_DISPLAY, /* lp_asm_dir */ -DONT_DISPLAY, /* lp_pause */ -}; - - -static struct module_info eriinfo = { - ERI_IDNUM, /* mi_idnum */ - ERI_NAME, /* mi_idname */ - ERI_MINPSZ, /* mi_minpsz */ - ERI_MAXPSZ, /* mi_maxpsz */ - ERI_HIWAT, /* mi_hiwat */ - ERI_LOWAT /* mi_lowat */ -}; - -static struct qinit eri_rinit = { - NULL, /* qi_putp */ -#ifdef ERI_SERVICE_ROUTINE - eri_rsrv, /* qi_srvp */ -#else - NULL, /* qi_srvp */ -#endif - eri_open, /* qi_qopen */ - eri_close, /* qi_qclose */ - NULL, /* qi_qadmin */ - &eriinfo, /* qi_minfo */ - NULL /* qi_mstat */ -}; - -static struct qinit eri_winit = { - eri_wput, /* qi_putp */ - eri_wsrv, /* qi_srvp */ - NULL, /* qi_qopen */ - NULL, /* qi_qclose */ - NULL, /* qi_qadmin */ - &eriinfo, /* qi_minfo */ - NULL /* qi_mstat */ -}; - -static struct streamtab er_info = { - &eri_rinit, /* st_rdinit */ - &eri_winit, /* st_wrinit */ - NULL, /* st_muxrinit */ - NULL /* st_muxwrinit */ -}; - -static struct cb_ops cb_eri_ops = { - nodev, /* cb_open */ - nodev, /* cb_close */ - nodev, /* cb_strategy */ - nodev, /* cb_print */ - nodev, /* cb_dump */ - nodev, /* cb_read */ - nodev, /* cb_write */ - nodev, /* cb_ioctl */ - nodev, /* cb_devmap */ - nodev, /* cb_mmap */ - nodev, /* cb_segmap */ - nochpoll, /* cb_chpoll */ - ddi_prop_op, /* cb_prop_op */ - &er_info, /* cb_stream */ - D_MP | D_HOTPLUG, /* cb_flag */ - CB_REV, /* rev */ - nodev, /* int (*cb_aread() */ - nodev /* int (*cb_awrite() */ -}; - -static struct dev_ops eri_ops = { - DEVO_REV, /* devo_rev */ - 0, /* devo_refcnt */ - ddi_no_info, /* devo_getinfo */ - nulldev, /* devo_identify */ - nulldev, /* devo_probe */ - eri_attach, /* devo_attach */ - eri_detach, /* devo_detach */ - nodev, /* devo_reset */ - &cb_eri_ops, /* devo_cb_ops */ - (struct bus_ops *)NULL, /* devo_bus_ops */ - NULL /* devo_power */ -}; - -#ifndef lint -char _depends_on[] = "drv/ip"; -#endif +DDI_DEFINE_STREAM_OPS(eri_dev_ops, nulldev, nulldev, eri_attach, eri_detach, + nodev, NULL, D_MP, NULL); /* * This is the loadable module wrapper. @@ -923,8 +609,8 @@ */ static struct modldrv modldrv = { &mod_driverops, /* Type of module. This one is a driver */ - "10/100 Mb Ethernet Driver v%I% ", - &eri_ops, /* driver ops */ + "Sun RIO 10/100 Mb Ethernet", + &eri_dev_ops, /* driver ops */ }; static struct modlinkage modlinkage = { @@ -932,15 +618,6 @@ }; /* - * XXX Autoconfiguration lock: We want to initialize all the global - * locks at _init(). However, we do not have the cookie required which - * is returned in ddi_add_intr(), which in turn is usually called at attach - * time. - */ - -static kmutex_t eriautolock; - -/* * Hardware Independent Functions * New Section */ @@ -950,47 +627,29 @@ { int status; - mutex_init(&eriautolock, NULL, MUTEX_DRIVER, NULL); - - status = mod_install(&modlinkage); - if (status != 0) - mutex_destroy(&eriautolock); - - ERI_DEBUG_MSG2(NULL, MODCTL_MSG, - "_init status = 0x%X", status); + mac_init_ops(&eri_dev_ops, "eri"); + if ((status = mod_install(&modlinkage)) != 0) { + mac_fini_ops(&eri_dev_ops); + } return (status); } int _fini(void) { - int status; + int status; status = mod_remove(&modlinkage); - if (status != 0) - goto _fini_exit; - - mutex_destroy(&erilock); - mutex_destroy(&eriwenlock); - rw_destroy(&eristruplock); - mutex_destroy(&eriautolock); - -_fini_exit: - ERI_DEBUG_MSG2(NULL, MODCTL_MSG, - "_fini status = 0x%X", status); + if (status == 0) { + mac_fini_ops(&eri_dev_ops); + } return (status); } - int _info(struct modinfo *modinfop) { - int status; - - status = mod_info(&modlinkage, modinfop); - ERI_DEBUG_MSG2(NULL, MODCTL_MSG, - "_info status = 0x%X", status); - return (status); + return (mod_info(&modlinkage, modinfop)); } @@ -1002,15 +661,12 @@ static int eri_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) { - struct eri *erip; - static int once = 1; + struct eri *erip = NULL; + mac_register_t *macp = NULL; int regno; - - uint8_t mutex_inited = 0; - uint8_t intr_add = 0; - uint8_t minor_node_created = 0; - - ERI_DEBUG_MSG1(NULL, AUTOCONFIG_MSG, "eri_attach"); + boolean_t doinit; + boolean_t mutex_inited = B_FALSE; + boolean_t intr_add = B_FALSE; switch (cmd) { case DDI_ATTACH: @@ -1020,40 +676,29 @@ if ((erip = ddi_get_driver_private(dip)) == NULL) return (DDI_FAILURE); + mutex_enter(&erip->intrlock); erip->flags &= ~ERI_SUSPENDED; erip->init_macregs = 1; param_linkup = 0; - erip->stats.link_up = ERI_LINK_DOWN; + erip->stats.link_up = LINK_STATE_DOWN; erip->linkcheck = 0; - { - struct eristr *sqp; - int doeriinit = 0; - rw_enter(&eristruplock, RW_READER); - /* - * Do eri_init() only for active interface - */ - for (sqp = eristrup; sqp; sqp = sqp->sb_nextp) - if (sqp->sb_erip == erip) { - doeriinit = 1; - break; - } - - rw_exit(&eristruplock); - if (doeriinit) - (void) eri_init(erip); + + doinit = (erip->flags & ERI_STARTED) ? B_TRUE : B_FALSE; + mutex_exit(&erip->intrlock); + + if (doinit && !eri_init(erip)) { + return (DDI_FAILURE); } return (DDI_SUCCESS); default: - ERI_DEBUG_MSG1(NULL, DEFAULT_MSG, - attach_bad_cmd_msg); return (DDI_FAILURE); } /* * Allocate soft device data structure */ - erip = GETSTRUCT(struct eri, 1); + erip = kmem_zalloc(sizeof (struct eri), KM_SLEEP); /* * Initialize as many elements as possible. @@ -1062,9 +707,21 @@ erip->dip = dip; /* dip */ erip->instance = ddi_get_instance(dip); /* instance */ erip->flags = 0; - erip->promisc_cnt = 0; - erip->all_multi_cnt = 0; - erip->all_sap_cnt = 0; + erip->multi_refcnt = 0; + erip->promisc = B_FALSE; + + if ((macp = mac_alloc(MAC_VERSION)) == NULL) { + ERI_FAULT_MSG1(erip, SEVERITY_HIGH, ERI_VERB_MSG, + "mac_alloc failed"); + goto attach_fail; + } + macp->m_type_ident = MAC_PLUGIN_IDENT_ETHER; + macp->m_driver = erip; + macp->m_dip = dip; + macp->m_src_addr = erip->ouraddr; + macp->m_callbacks = &eri_m_callbacks; + macp->m_min_sdu = 0; + macp->m_max_sdu = ETHERMTU; /* * Map in the device registers. @@ -1079,18 +736,16 @@ if (ddi_dev_nregs(dip, ®no) != (DDI_SUCCESS)) { ERI_FAULT_MSG2(erip, SEVERITY_HIGH, ERI_VERB_MSG, - "ddi_dev_nregs failed, returned %d", regno); + "ddi_dev_nregs failed, returned %d", regno); goto attach_fail; } /* * Map the PCI config space */ - if (pci_config_setup(dip, &erip->pci_config_handle) != - DDI_SUCCESS) { + if (pci_config_setup(dip, &erip->pci_config_handle) != DDI_SUCCESS) { ERI_FAULT_MSG2(erip, SEVERITY_HIGH, ERI_VERB_MSG, - "%s pci_config_setup()", - config_space_fatal_msg); + "%s pci_config_setup()", config_space_fatal_msg); goto attach_fail; } @@ -1101,12 +756,9 @@ erip->dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC; erip->dev_attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC; - if (ddi_regs_map_setup(dip, 1, - (caddr_t *)&(erip->globregp), 0, 0, - &erip->dev_attr, &erip->globregh)) { - ERI_DEBUG_MSG1(erip, AUTOCONFIG_MSG, - mregs_4global_reg_fail_msg); - goto attach_fail; + if (ddi_regs_map_setup(dip, 1, (caddr_t *)&(erip->globregp), 0, 0, + &erip->dev_attr, &erip->globregh)) { + goto attach_fail; } erip->etxregh = erip->globregh; erip->erxregh = erip->globregh; @@ -1119,18 +771,16 @@ erip->mifregp = (void *)(((caddr_t)erip->globregp) + 0x6200); ERI_DEBUG_MSG4(erip, AUTOCONFIG_MSG, - "eri_attach: gloregp %p alias %X gintmask %X", - erip->globregp, GET_GLOBREG(status_alias), - GET_GLOBREG(intmask)); + "eri_attach: gloregp %p alias %X gintmask %X", + erip->globregp, GET_GLOBREG(status_alias), GET_GLOBREG(intmask)); /* * Map the software reset register. */ - if (ddi_regs_map_setup(dip, 1, - (caddr_t *)&(erip->sw_reset_reg), 0x1010, 4, - &erip->dev_attr, &erip->sw_reset_regh)) { + if (ddi_regs_map_setup(dip, 1, (caddr_t *)&(erip->sw_reset_reg), + 0x1010, 4, &erip->dev_attr, &erip->sw_reset_regh)) { ERI_FAULT_MSG1(erip, SEVERITY_MID, ERI_VERB_MSG, - mregs_4soft_reset_fail_msg); - goto attach_fail; + mregs_4soft_reset_fail_msg); + goto attach_fail; } /* @@ -1144,12 +794,11 @@ * set PCI latency timer register. */ pci_config_put8(erip->pci_config_handle, PCI_CONF_LATENCY_TIMER, - (uchar_t)eri_pci_latency_timer); + (uchar_t)eri_pci_latency_timer); ERI_DEBUG_MSG4(erip, AUTOCONFIG_MSG, - "eri_attach: gloregp %p alias %X gintmask %X", - erip->globregp, GET_GLOBREG(status_alias), - GET_GLOBREG(intmask)); + "eri_attach: globregp %p alias %X gintmask %X", + erip->globregp, GET_GLOBREG(status_alias), GET_GLOBREG(intmask)); if (ddi_intr_hilevel(dip, 0)) { ERI_FAULT_MSG1(erip, SEVERITY_NONE, ERI_VERB_MSG, @@ -1172,63 +821,27 @@ mutex_init(&erip->linklock, NULL, MUTEX_DRIVER, (void *)erip->cookie); mutex_init(&erip->xcvrlock, NULL, MUTEX_DRIVER, (void *)erip->cookie); -#ifdef XMIT_SERIAL_QUEUE - /* - * A syncq implementation. - */ - mutex_init(&erip->sqlock, NULL, MUTEX_DRIVER, (void *)erip->cookie); -#endif - mutex_inited = 1; + mutex_inited = B_TRUE; /* * Add interrupt to system */ - ERI_DEBUG_MSG1(erip, AUTOCONFIG_MSG, - "eri_att: add intr"); - if (ddi_add_intr(dip, 0, &erip->cookie, 0, eri_intr, - (caddr_t)erip) == DDI_SUCCESS) - intr_add = 1; + if (ddi_add_intr(dip, 0, &erip->cookie, 0, eri_intr, (caddr_t)erip) == + DDI_SUCCESS) + intr_add = B_TRUE; else { - ERI_DEBUG_MSG1(erip, AUTOCONFIG_MSG, - add_intr_fail_msg); goto attach_fail; } - ERI_DEBUG_MSG1(erip, AUTOCONFIG_MSG, - "eri_att: DONE: add intr"); /* * Set up the ethernet mac address. */ (void) eri_setup_mac_address(erip, dip); - /* - * Create the filesystem device node. - */ - if (ddi_create_minor_node(dip, "eri", S_IFCHR, erip->instance, - DDI_NT_NET, CLONE_DEV) == DDI_SUCCESS) - minor_node_created = 1; - else { - ERI_DEBUG_MSG1(erip, AUTOCONFIG_MSG, - create_minor_node_fail_msg); - goto attach_fail; - } - - mutex_enter(&eriautolock); - if (once) { - once = 0; - rw_init(&eristruplock, NULL, RW_DRIVER, (void *)erip->cookie); - mutex_init(&erilock, NULL, MUTEX_DRIVER, - (void *)erip->cookie); - mutex_init(&eriwenlock, NULL, MUTEX_DRIVER, - (void *)erip->cookie); - } - mutex_exit(&eriautolock); - if (eri_init_xfer_params(erip)) goto attach_fail; if (eri_burstsize(erip) == DDI_FAILURE) { - ERI_DEBUG_MSG1(erip, INIT_MSG, burst_size_msg); goto attach_fail; } @@ -1244,44 +857,28 @@ erip->stats.pmcap = ERI_PMCAP_NONE; if (pci_report_pmcap(dip, PCI_PM_IDLESPEED, (void *)4000) == - DDI_SUCCESS) + DDI_SUCCESS) erip->stats.pmcap = ERI_PMCAP_4MHZ; - ERI_DEBUG_MSG2(erip, AUTOCONFIG_MSG, - "eri_attach: PMCAP %d", erip->stats.pmcap); - - /* - * lock eri structure while manipulating link list of eri structs - */ - mutex_enter(&erilock); - erip->nextp = eriup; - eriup = erip; - mutex_exit(&erilock); - - ddi_report_dev(dip); - - ERI_DEBUG_MSG1(erip, EXIT_MSG, "eri_attach pass"); + if (mac_register(macp, &erip->mh) != 0) + goto attach_fail; + + mac_free(macp); + return (DDI_SUCCESS); attach_fail: if (erip->pci_config_handle) (void) pci_config_teardown(&erip->pci_config_handle); - if (minor_node_created) - ddi_remove_minor_node(dip, NULL); - if (mutex_inited) { mutex_destroy(&erip->xmitlock); mutex_destroy(&erip->intrlock); mutex_destroy(&erip->linklock); mutex_destroy(&erip->xcvrlock); -#ifdef XMIT_SERIAL_QUEUE - mutex_destroy(&erip->sqlock); -#endif } - ERI_FAULT_MSG1(erip, SEVERITY_NONE, ERI_VERB_MSG, - attach_fail_msg); + ERI_FAULT_MSG1(erip, SEVERITY_NONE, ERI_VERB_MSG, attach_fail_msg); if (intr_add) ddi_remove_intr(dip, 0, erip->cookie); @@ -1289,37 +886,24 @@ if (erip->globregh) ddi_regs_map_free(&erip->globregh); - erip->etxregh = NULL; - erip->erxregh = NULL; - erip->bmacregh = NULL; - erip->mifregh = NULL; - erip->globregh = NULL; - - if (erip) - kmem_free((caddr_t)erip, sizeof (*erip)); - - ERI_DEBUG_MSG1(NULL, EXIT_MSG, "eri_attach: !Success"); + if (macp != NULL) + mac_free(macp); + if (erip != NULL) + kmem_free(erip, sizeof (*erip)); + return (DDI_FAILURE); } static int eri_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) { - struct eri *erip, *eritmp, **eripp; + struct eri *erip; int i; - if (dip == NULL) { - ERI_DEBUG_MSG1(NULL, AUTOCONFIG_MSG, - "detach: dip == NULL"); - return (DDI_FAILURE); - } - if ((erip = ddi_get_driver_private(dip)) == NULL) { /* * No resources allocated. */ - ERI_DEBUG_MSG1(NULL, AUTOCONFIG_MSG, - "detach: !erip "); return (DDI_FAILURE); } @@ -1333,8 +917,6 @@ return (DDI_SUCCESS); default: - ERI_DEBUG_MSG1(erip, DEFAULT_MSG, - detach_bad_cmd_msg); return (DDI_FAILURE); } @@ -1343,13 +925,15 @@ return (DDI_FAILURE); } + if (mac_unregister(erip->mh) != 0) { + return (DDI_FAILURE); + } + /* * Make the device quiescent */ (void) eri_stop(erip); - ddi_remove_minor_node(dip, NULL); - /* * Remove instance of the intr */ @@ -1359,18 +943,6 @@ (void) pci_config_teardown(&erip->pci_config_handle); /* - * Remove erip from the linked list of device structures - */ - mutex_enter(&erilock); - for (eripp = &eriup; (eritmp = *eripp) != NULL; - eripp = &eritmp->nextp) - if (eritmp == erip) { - *eripp = eritmp->nextp; - break; - } - mutex_exit(&erilock); - - /* * Destroy all mutexes and data structures allocated during * attach time. */ @@ -1397,9 +969,6 @@ mutex_destroy(&erip->linklock); mutex_destroy(&erip->xcvrlock); -#ifdef XMIT_SERIAL_QUEUE - mutex_destroy(&erip->sqlock); -#endif if (erip->md_h) { if (ddi_dma_unbind_handle(erip->md_h) == DDI_FAILURE) @@ -1474,125 +1043,71 @@ static void eri_setup_mac_address(struct eri *erip, dev_info_t *dip) { - char *prop; - int prop_len = sizeof (int); - - erip->addrflags = 0; + uchar_t *prop; + char *uselocal; + unsigned prop_len; + uint32_t addrflags = 0; + struct ether_addr factaddr; /* * Check if it is an adapter with its own local mac address * If it is present, save it as the "factory-address" * for this adapter. */ - if (ddi_getlongprop(DDI_DEV_T_ANY, - dip, DDI_PROP_DONTPASS, "local-mac-address", - (caddr_t)&prop, &prop_len) == DDI_PROP_SUCCESS) { + if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, + "local-mac-address", &prop, &prop_len) == DDI_PROP_SUCCESS) { if (prop_len == ETHERADDRL) { - erip->addrflags = ERI_FACTADDR_PRESENT; - ether_bcopy((caddr_t)prop, &erip->factaddr); + addrflags = ERI_FACTADDR_PRESENT; + bcopy(prop, &factaddr, ETHERADDRL); ERI_FAULT_MSG2(erip, SEVERITY_NONE, ERI_VERB_MSG, - lether_addr_msg, - eri_ether_sprintf(&erip->factaddr)); + lether_addr_msg, ether_sprintf(&factaddr)); } - kmem_free(prop, prop_len); + ddi_prop_free(prop); } /* * Check if the adapter has published "mac-address" property. * If it is present, use it as the mac address for this device. */ - if (ddi_getlongprop(DDI_DEV_T_ANY, - dip, DDI_PROP_DONTPASS, "mac-address", - (caddr_t)&prop, &prop_len) == DDI_PROP_SUCCESS) { + if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, + "mac-address", &prop, &prop_len) == DDI_PROP_SUCCESS) { if (prop_len >= ETHERADDRL) { - ether_bcopy((caddr_t)prop, &erip->ouraddr); + bcopy(prop, erip->ouraddr, ETHERADDRL); kmem_free(prop, prop_len); return; } - kmem_free(prop, prop_len); + ddi_prop_free(prop); } - if (ddi_getlongprop(DDI_DEV_T_ANY, dip, 0, "local-mac-address?", - (caddr_t)&prop, &prop_len) == DDI_PROP_SUCCESS) { - if ((strncmp("true", prop, prop_len) == 0) && - (erip->addrflags & ERI_FACTADDR_PRESENT)) { - erip->addrflags |= ERI_FACTADDR_USE; - ether_bcopy(&erip->factaddr, &erip->ouraddr); - kmem_free(prop, prop_len); + if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, 0, "local-mac-address?", + &uselocal) == DDI_PROP_SUCCESS) { + if ((strcmp("true", uselocal) == 0) && + (addrflags & ERI_FACTADDR_PRESENT)) { + addrflags |= ERI_FACTADDR_USE; + bcopy(&factaddr, erip->ouraddr, ETHERADDRL); + ddi_prop_free(uselocal); ERI_FAULT_MSG1(erip, SEVERITY_NONE, ERI_VERB_MSG, - lmac_addr_msg); + lmac_addr_msg); return; } - kmem_free(prop, prop_len); + ddi_prop_free(uselocal); } /* * Get the system ethernet address. */ - (void) localetheraddr((struct ether_addr *)NULL, &erip->ouraddr); -} - -/* - * Convert Ethernet address to printable (loggable) representation. - */ -static char * -eri_ether_sprintf(struct ether_addr *addr) -{ - uint8_t *ap = (uint8_t *)addr; - int i; - static char etherbuf[18]; - char *cp = etherbuf; - static char digits[] = "0123456789abcdef"; - - for (i = 0; i < 6; i++) { - if (*ap > 0x0f) - *cp++ = digits[*ap >> 4]; - *cp++ = digits[*ap++ & 0xf]; - *cp++ = ':'; - } - *--cp = 0; - return (etherbuf); + (void) localetheraddr(NULL, &factaddr); + bcopy(&factaddr, erip->ouraddr, ETHERADDRL); } /* - * DLPI (Data Link Provider Interface) Functions - * New Section - */ -/* - * Our DL_INFO_ACK template. - */ -static dl_info_ack_t infoack = { - DL_INFO_ACK, /* dl_primitive */ - ETHERMTU, /* dl_max_sdu */ - 0, /* dl_min_sdu */ - ERI_ADDRL, /* dl_addr_length */ - DL_ETHER, /* dl_mac_type */ - 0, /* dl_reserved */ - 0, /* dl_current_state */ - -2, /* dl_sap_length */ - DL_CLDLS, /* dl_service_mode */ - 0, /* dl_qos_length */ - 0, /* dl_qos_offset */ - 0, /* dl_range_length */ - 0, /* dl_range_offset */ - DL_STYLE2, /* dl_provider_style */ - sizeof (dl_info_ack_t), /* dl_addr_offset */ - DL_VERSION_2, /* dl_version */ - ETHERADDRL, /* dl_brdcst_addr_length */ - sizeof (dl_info_ack_t) + ERI_ADDRL, /* dl_brdcst_addr_offset */ - 0 /* dl_growth */ -}; - - - -/* * Calculate the bit in the multicast address filter that selects the given * address. * Note: For ERI, the last 8-bits are used. */ static uint32_t -eri_ladrf_bit(struct ether_addr *addr) +eri_ladrf_bit(const uint8_t *addr) { uint32_t crc; @@ -1604,451 +1119,43 @@ return ((~crc) >> 24); } - -/* - * Assorted DLPI V2 routines. - */ - static void -eri_proto(queue_t *wq, mblk_t *mp) -{ - union DL_primitives *dlp; - struct eristr *sbp; - uint32_t prim; - - sbp = (struct eristr *)wq->q_ptr; - dlp = (union DL_primitives *)mp->b_rptr; - prim = dlp->dl_primitive; - - ERI_DEBUG_MSG1(NULL, PROTO_MSG, - "eri_proto Entered"); - mutex_enter(&sbp->sb_lock); - - switch (prim) { - case DL_UNITDATA_REQ: - eri_udreq(wq, mp); - break; - - case DL_ATTACH_REQ: - ERI_DEBUG_MSG1(NULL, PROTO_MSG, - "eri_proto : ATTACH_REQ"); - eri_areq(wq, mp); - break; - - case DL_DETACH_REQ: - eri_dreq(wq, mp); - break; - - case DL_BIND_REQ: - ERI_DEBUG_MSG1(NULL, PROTO_MSG, - "eri_proto : BIND_REQ"); - eri_breq(wq, mp); - break; - - case DL_UNBIND_REQ: - eri_ubreq(wq, mp); - break; - - case DL_INFO_REQ: - ERI_DEBUG_MSG1(NULL, PROTO_MSG, - "eri_proto : INFO_REQ"); - eri_ireq(wq, mp); - break; - - case DL_PROMISCON_REQ: - eri_ponreq(wq, mp); - break; - - case DL_PROMISCOFF_REQ: - eri_poffreq(wq, mp); - break; - - case DL_ENABMULTI_REQ: - eri_emreq(wq, mp); - break; - - case DL_DISABMULTI_REQ: - eri_dmreq(wq, mp); - break; - - case DL_PHYS_ADDR_REQ: - eri_pareq(wq, mp); - break; - - case DL_SET_PHYS_ADDR_REQ: - eri_spareq(wq, mp); - break; - - case DL_NOTIFY_REQ: - eri_nreq(wq, mp); - break; - - case DL_CAPABILITY_REQ: - eri_dlcap_req(wq, mp); - break; - - default: - dlerrorack(wq, mp, prim, DL_UNSUPPORTED, 0); - break; - } - mutex_exit(&sbp->sb_lock); -} - -/*ARGSUSED*/ -static int -eri_open(queue_t *rq, dev_t *devp, int flag, int sflag, cred_t *credp) +eri_m_ioctl(void *arg, queue_t *wq, mblk_t *mp) { - struct eristr *sbp; - struct eristr **prevsbp; - minor_t minordev; - int rc = 0; - - ASSERT(sflag != MODOPEN); - ERI_DEBUG_MSG1(NULL, INIT_MSG, - "eri_open Entered"); - - /* - * Serialize all driver open and closes. - */ - rw_enter(&eristruplock, RW_WRITER); - mutex_enter(&eriwenlock); - - /* - * Determine minor device number. - */ - prevsbp = &eristrup; - if (sflag == CLONEOPEN) { - minordev = 0; - for (; (sbp = *prevsbp) != NULL; prevsbp = &sbp->sb_nextp) { - if (minordev < sbp->sb_minor) - break; - minordev++; - } - *devp = makedevice(getmajor(*devp), minordev); - } else - minordev = getminor(*devp); - - if (rq->q_ptr) - goto done; - - sbp = GETSTRUCT(struct eristr, 1); - - ERI_DEBUG_MSG2(NULL, INIT_MSG, - "eri_open: sbp = %X\n", sbp); - - sbp->sb_minor = minordev; - sbp->sb_rq = rq; - sbp->sb_state = DL_UNATTACHED; - sbp->sb_sap = 0; - sbp->sb_flags = 0; - sbp->sb_erip = NULL; - - mutex_init(&sbp->sb_lock, NULL, MUTEX_DRIVER, (void *)0); - - /* - * Link new entry into the list of active entries. - */ - sbp->sb_nextp = *prevsbp; - *prevsbp = sbp; - - rq->q_ptr = WR(rq)->q_ptr = (char *)sbp; - - /* - * Disable automatic enabling of our write service procedure. - * We control this explicitly. - */ - noenable(WR(rq)); - -done: - mutex_exit(&eriwenlock); - rw_exit(&eristruplock); - - /* inform framework that we are a good citizen */ - (void) qassociate(rq, -1); - - qprocson(rq); - return (rc); -} - -static int -eri_close(queue_t *rq) -{ - struct eristr *sbp; - struct eristr **prevsbp; - - ASSERT(rq->q_ptr); - - qprocsoff(rq); - - sbp = (struct eristr *)rq->q_ptr; - - - /* - * Implicit detach Stream from interface. - */ - if (sbp->sb_erip) - eri_dodetach(sbp); - - /* dissociate queue */ - (void) qassociate(rq, -1); - - rw_enter(&eristruplock, RW_WRITER); - mutex_enter(&eriwenlock); + struct eri *erip = arg; + struct iocblk *iocp = (void *)mp->b_rptr; + int err; + + ASSERT(erip != NULL); /* - * Unlink the per-Stream entry from the active list and free it. + * Privilege checks. */ - for (prevsbp = &eristrup; (sbp = *prevsbp) != NULL; - prevsbp = &sbp->sb_nextp) - if (sbp == (struct eristr *)rq->q_ptr) - break; - ASSERT(sbp); - *prevsbp = sbp->sb_nextp; - - mutex_destroy(&sbp->sb_lock); - kmem_free((char *)sbp, sizeof (struct eristr)); - - rq->q_ptr = WR(rq)->q_ptr = NULL; - - mutex_exit(&eriwenlock); - rw_exit(&eristruplock); - return (0); -} - -/* - * Enqueue M_PROTO/M_PCPROTO (always) and M_DATA (sometimes) on the wq. - * - * Processing of some of the M_PROTO/M_PCPROTO msgs involves acquiring - * internal locks that are held across upstream putnext calls. - * Specifically there's the problem of eri_intr() holding eri_intrlock - * and eristruplock when it calls putnext() and that thread looping - * back around to call eri_wput() and, eventually, eri_init() to create a - * recursive lock panic. There are two obvious ways of solving this - * problem: (1) have eri_intr() do putq instead of putnext which provides - * the loopback "cutout" right at the rq, or (2) allow eri_intr() to putnext - * and put the loopback "cutout" around eri_proto(). We choose the latter - * for performance reasons. - * - * M_DATA messages are enqueued on the wq *only* when the xmit side - * is out of tbufs or tmds. Once the xmit resource is available again, - * wsrv() is enabled and tries to xmit all the messages on the wq. - */ -static int -eri_wsrv(queue_t *wq) -{ - mblk_t *mp; - struct eristr *sbp; - struct eri *erip; - - sbp = (struct eristr *)wq->q_ptr; - erip = sbp->sb_erip; - while (mp = getq(wq)) - switch (DB_TYPE(mp)) { - case M_DATA: - if (erip) { - if (eri_start(wq, mp, erip)) - goto done; - } else - freemsg(mp); - break; - - case M_PROTO: - case M_PCPROTO: - eri_proto(wq, mp); - break; - - default: - ASSERT(0); - break; + switch (iocp->ioc_cmd) { + case ERI_SET_LOOP_MODE: + case ERI_ND_SET: + err = secpolicy_net_config(iocp->ioc_cr, B_FALSE); + if (err != 0) { + miocnak(wq, mp, 0, err); + return; } -done: - return (0); -} - -#ifdef XMIT_SERIAL_QUEUE -static int -eri_wput_serialize(queue_t *wq, mblk_t *mp, struct eri *erip) -{ - - mblk_t *smp; - int refed; - int ret = 0; - - mutex_enter(&erip->sqlock); - if (erip->sqrefcnt) { - smp = mp; - mp = NULL; - refed = 0; - goto last; - } - erip->sqrefcnt++; -next: - refed = 1; - if (erip->sqfirst) { - /* - * Mblk chain on syncq, so just add ours, if any - * to the end and get the first one. - */ - smp = mp; - mp = erip->sqfirst; - if ((erip->sqfirst = mp->b_next) == NULL) - erip->sqlast = NULL; - else - mp->b_next = NULL; - } else - smp = NULL; - -last: - if (smp) { - /* - * Mblk chain to save, so just add it to - * the end of the sycnq. - */ - smp->b_next = NULL; - if (erip->sqlast) - erip->sqlast->b_next = smp; - else - erip->sqfirst = smp; - erip->sqlast = smp; - } - - if (mp == NULL) { - /* - * Nothing more todo ... - */ - if (refed) - erip->sqrefcnt--; - - mutex_exit(&erip->sqlock); - return (ret); - } - - mutex_exit(&erip->sqlock); - ret = eri_start(wq, mp, erip); - mp = NULL; - mutex_enter(&erip->sqlock); - goto next; -no_bwg: - HSTAT(erip, oerrors); - freemsg(mp); - return (0); -} - -#endif - - -static int -eri_wput(queue_t *wq, mblk_t *mp) -{ - struct eristr *sbp = (struct eristr *)wq->q_ptr; - struct eri *erip; - - switch (DB_TYPE(mp)) { - case M_DATA: /* "fastpath" */ - erip = sbp->sb_erip; - - if (((sbp->sb_flags & (ERI_SFAST | ERI_SRAW)) == 0) || - (sbp->sb_state != DL_IDLE) || - (erip == NULL)) { - merror(wq, mp, EPROTO); - break; - } - - /* - * If any msgs already enqueued or the interface will - * loop back up the message (due to ERI_PROMISC), then - * enqueue the msg. Otherwise just xmit it directly. - */ - if (wq->q_first) { - (void) putq(wq, mp); - erip->wantw = 1; - qenable(wq); - } else if (erip->flags & ERI_PROMISC) { - (void) putq(wq, mp); - qenable(wq); - } else -#ifdef XMIT_SERIAL_QUEUE - (void) eri_wput_serialize(wq, mp, erip); -#else - (void) eri_start(wq, mp, erip); -#endif - break; - - case M_PROTO: - case M_PCPROTO: - /* - * Break the association between the current thread - * and the thread that calls eri_proto() to resolve the - * problem of eri_intr() threads which loop back around - * to call eri_proto() and try to recursively acquire - * internal locks. - */ - (void) putq(wq, mp); - qenable(wq); - break; - - case M_IOCTL: - eri_ioctl(wq, mp); - break; - - case M_CTL: - eri_mctl(wq, mp); - break; - - case M_FLUSH: - if (*mp->b_rptr & FLUSHW) { - flushq(wq, FLUSHALL); - *mp->b_rptr &= ~FLUSHW; - } - - if (*mp->b_rptr & FLUSHR) { -#ifdef ERI_SERVICE_ROUTINE - flushq(RD(wq), FLUSHALL); -#endif - qreply(wq, mp); - } else - freemsg(mp); - break; - default: - freemsg(mp); break; } - return (0); -} - -static void -eri_ioctl(queue_t *wq, mblk_t *mp) -{ - struct iocblk *iocp = (struct iocblk *)mp->b_rptr; - struct eristr *sbp = (struct eristr *)wq->q_ptr; - struct eri *erip = sbp->sb_erip; - - ERI_DEBUG_MSG1(NULL, IOCTL_MSG, - "eri_ioctl Entered"); + switch (iocp->ioc_cmd) { - case DLIOCRAW: /* raw M_DATA mode */ - sbp = (struct eristr *)wq->q_ptr; - sbp->sb_flags |= ERI_SRAW; - miocack(wq, mp, 0, 0); - break; - - case DL_IOC_HDR_INFO: /* M_DATA "fastpath" info request */ - eri_dl_ioc_hdr_info(wq, mp); - break; - case ERI_ND_GET: case ERI_ND_SET: - eri_process_ndd_ioctl(wq, mp, iocp->ioc_cmd); + eri_process_ndd_ioctl(erip, wq, mp, iocp->ioc_cmd); break; case ERI_SET_LOOP_MODE: case ERI_GET_LOOP_MODE: - if (erip == NULL) - miocnak(wq, mp, 0, EPROTO); - else - eri_loopback(wq, mp); + /* + * XXX: Consider updating this to the new netlb ioctls. + */ + eri_loopback(erip, wq, mp); break; default: @@ -2056,78 +1163,60 @@ break; } - if (erip) - ASSERT(!MUTEX_HELD(&erip->linklock)); + ASSERT(!MUTEX_HELD(&erip->linklock)); } static void -eri_loopback(queue_t *wq, mblk_t *mp) +eri_loopback(struct eri *erip, queue_t *wq, mblk_t *mp) { - struct eristr *sbp = (struct eristr *)wq->q_ptr; - struct eri *erip = sbp->sb_erip; - struct iocblk *iocp = (struct iocblk *)mp->b_rptr; + struct iocblk *iocp = (void *)mp->b_rptr; loopback_t *al; - ERI_DEBUG_MSG1(NULL, LOOPBACK_MSG, - "eri_loopback Entered"); - - if (mp->b_cont == NULL || - MBLKL(mp->b_cont) < sizeof (loopback_t)) { + /*LINTED E_PTRDIFF_OVERFLOW*/ + if (mp->b_cont == NULL || MBLKL(mp->b_cont) < sizeof (loopback_t)) { miocnak(wq, mp, 0, EINVAL); return; } - al = (loopback_t *)mp->b_cont->b_rptr; + al = (void *)mp->b_cont->b_rptr; switch (iocp->ioc_cmd) { case ERI_SET_LOOP_MODE: - ERI_DEBUG_MSG1(erip, LOOPBACK_MSG, - "ERI_SET_LOOP_MODE\n"); switch (al->loopback) { case ERI_LOOPBACK_OFF: - ERI_DEBUG_MSG1(erip, LOOPBACK_MSG, - "ERI_LOOPBACK_OFF\n"); - sbp->sb_flags &= (~ERI_SMACLPBK & ~ERI_SSERLPBK); - erip->flags &= (~ERI_MACLOOPBACK & - ~ERI_SERLOOPBACK); + erip->flags &= (~ERI_MACLOOPBACK & ~ERI_SERLOOPBACK); /* force link status to go down */ param_linkup = 0; - erip->stats.link_up = ERI_LINK_DOWN; - erip->stats.link_duplex = ERI_UNKNOWN_DUPLEX; + erip->stats.link_up = LINK_STATE_DOWN; + erip->stats.link_duplex = LINK_DUPLEX_UNKNOWN; (void) eri_init(erip); break; case ERI_MAC_LOOPBACK_ON: - ERI_DEBUG_MSG1(erip, LOOPBACK_MSG, - "ERI_MAC_LOOPBACK_ON\n"); - sbp->sb_flags |= ERI_SMACLPBK; erip->flags |= ERI_MACLOOPBACK; + erip->flags &= ~ERI_SERLOOPBACK; param_linkup = 0; - erip->stats.link_up = ERI_LINK_DOWN; - erip->stats.link_duplex = ERI_UNKNOWN_DUPLEX; + erip->stats.link_up = LINK_STATE_DOWN; + erip->stats.link_duplex = LINK_DUPLEX_UNKNOWN; (void) eri_init(erip); break; case ERI_PCS_LOOPBACK_ON: - ERI_DEBUG_MSG1(erip, LOOPBACK_MSG, - "ERI_PCS_LOOPBACK_ON\n"); break; case ERI_SER_LOOPBACK_ON: - ERI_DEBUG_MSG1(erip, LOOPBACK_MSG, - "ERI_SER_LOOPBACK_ON\n"); - sbp->sb_flags |= ERI_SSERLPBK; erip->flags |= ERI_SERLOOPBACK; + erip->flags &= ~ERI_MACLOOPBACK; /* force link status to go down */ param_linkup = 0; - erip->stats.link_up = ERI_LINK_DOWN; - erip->stats.link_duplex = ERI_UNKNOWN_DUPLEX; + erip->stats.link_up = LINK_STATE_DOWN; + erip->stats.link_duplex = LINK_DUPLEX_UNKNOWN; (void) eri_init(erip); break; default: ERI_FAULT_MSG1(erip, SEVERITY_NONE, ERI_VERB_MSG, - loopback_val_default); + loopback_val_default); miocnak(wq, mp, 0, EINVAL); return; } @@ -2135,1193 +1224,309 @@ break; case ERI_GET_LOOP_MODE: - ERI_DEBUG_MSG1(erip, LOOPBACK_MSG, - "ERI_GET_LOOP_MODE\n"); - al->loopback = ERI_MAC_LOOPBACK_ON | - ERI_PCS_LOOPBACK_ON | - ERI_SER_LOOPBACK_ON; + al->loopback = ERI_MAC_LOOPBACK_ON | ERI_PCS_LOOPBACK_ON | + ERI_SER_LOOPBACK_ON; miocack(wq, mp, sizeof (loopback_t), 0); break; default: ERI_FAULT_MSG1(erip, SEVERITY_LOW, ERI_VERB_MSG, - loopback_cmd_default); + loopback_cmd_default); } } -/* - * M_DATA "fastpath" info request. - * Following the M_IOCTL mblk should come a DL_UNITDATA_REQ mblk. - * We ack with an M_IOCACK pointing to the original DL_UNITDATA_REQ mblk - * followed by an mblk containing the raw ethernet header corresponding - * to the destination address. Subsequently, we may receive M_DATA - * msgs which start with this header and may send up - * up M_DATA msgs with b_rptr pointing to a (uint32_t) group address - * indicator followed by the network-layer data (IP packet header). - * This is all selectable on a per-Stream basis. - */ -static void -eri_dl_ioc_hdr_info(queue_t *wq, mblk_t *mp) -{ - mblk_t *nmp; - struct eristr *sbp; - struct eridladdr *dlap; - dl_unitdata_req_t *dludp; - struct ether_header *headerp; - struct eri *erip; - t_uscalar_t off, len; - int error; - - sbp = (struct eristr *)wq->q_ptr; - erip = sbp->sb_erip; - if (erip == NULL) { - miocnak(wq, mp, 0, EINVAL); - return; - } - - error = miocpullup(mp, sizeof (dl_unitdata_req_t) + ERI_ADDRL); - if (error != 0) { - miocnak(wq, mp, 0, error); - return; - } - - /* - * Sanity check the DL_UNITDATA_REQ destination address - * offset and length values. - */ - dludp = (dl_unitdata_req_t *)mp->b_cont->b_rptr; - off = dludp->dl_dest_addr_offset; - len = dludp->dl_dest_addr_length; - if (dludp->dl_primitive != DL_UNITDATA_REQ || - !MBLKIN(mp->b_cont, off, len) || len != ERI_ADDRL) { - miocnak(wq, mp, 0, EINVAL); - return; - } - - dlap = (struct eridladdr *)(mp->b_cont->b_rptr + off); - - /* - * Allocate a new mblk to hold the ether header. - */ - if ((nmp = allocb(ETHERHEADER_SIZE, BPRI_MED)) == NULL) { - miocnak(wq, mp, 0, ENOMEM); - return; - } - nmp->b_wptr += ETHERHEADER_SIZE; - - /* - * Fill in the ether header. - */ - headerp = (struct ether_header *)nmp->b_rptr; - ether_bcopy(&dlap->dl_phys, &headerp->ether_dhost); - ether_bcopy(&erip->ouraddr, &headerp->ether_shost); - put_ether_type(headerp, dlap->dl_sap); - - /* - * Link new mblk in after the "request" mblks. - */ - linkb(mp, nmp); - - sbp->sb_flags |= ERI_SFAST; - miocack(wq, mp, msgsize(mp->b_cont), 0); -} - -/* ARGSUSED */ -static void -eri_mctl(queue_t *wq, mblk_t *mp) -{ - freemsg(mp); -} /* eri_mctl */ - -static void -eri_areq(queue_t *wq, mblk_t *mp) -{ - struct eristr *sbp; - union DL_primitives *dlp; - struct eri *erip = NULL; - t_uscalar_t ppa; - uint32_t promisc = 0; - uint32_t all_multi = 0; - uint32_t all_sap = 0; - int init = B_FALSE; - - sbp = (struct eristr *)wq->q_ptr; - dlp = (union DL_primitives *)mp->b_rptr; - - if (MBLKL(mp) < DL_ATTACH_REQ_SIZE) { - dlerrorack(wq, mp, DL_ATTACH_REQ, DL_BADPRIM, 0); - ERI_DEBUG_MSG1(NULL, PROTO_MSG, - "eri_areq: Bad REQ Size"); - return; - } - - if (sbp->sb_state != DL_UNATTACHED) { - dlerrorack(wq, mp, DL_ATTACH_REQ, DL_OUTSTATE, 0); - ERI_DEBUG_MSG1(NULL, PROTO_MSG, - "eri_areq: DL_OUTSTATE"); - return; - } - - /* - * Count the number of snoop/promisc modes. - */ - if (sbp->sb_flags & ERI_SALLPHYS) { - promisc++; - init = B_TRUE; - } - if (sbp->sb_flags & ERI_SALLSAP) { - all_sap++; - init = B_TRUE; - } - if (sbp->sb_flags & ERI_SALLMULTI) { - all_multi++; - init = B_TRUE; - } - - ppa = dlp->attach_req.dl_ppa; - - /* - * Valid ppa? - */ - if (ppa == -1 || qassociate(wq, ppa) != 0) { - dlerrorack(wq, mp, dlp->dl_primitive, DL_BADPPA, 0); - ERI_DEBUG_MSG1(NULL, PROTO_MSG, - "eri_areq: erip == NULL"); - return; - } - mutex_enter(&erilock); - for (erip = eriup; erip; erip = erip->nextp) - if (ppa == erip->instance) { - ERI_DEBUG_MSG1(erip, PROTO_MSG, - "got instance"); - break; - } - mutex_exit(&erilock); - ASSERT(erip != NULL); - - /* Set link to device and update our state. */ - sbp->sb_erip = erip; - sbp->sb_state = DL_UNBOUND; - - /* - * Has device been initialized? Do so if necessary. - * Also check if promiscuous mode is set via the ALLPHYS and - * ALLMULTI flags, for the stream. If so, initialize the - * interface. - */ - if ((erip->flags & ERI_RUNNING) == 0) { - if (eri_init(erip)) { - dlerrorack(wq, mp, dlp->dl_primitive, DL_INITFAILED, 0); - sbp->sb_erip = NULL; - sbp->sb_state = DL_UNATTACHED; - ERI_DEBUG_MSG1(NULL, PROTO_MSG, - "eri_areq: eri_init FAILED"); - (void) qassociate(wq, -1); - return; - } - - } else { - if (init) { - mutex_enter(&erip->intrlock); - erip->promisc_cnt += promisc; - erip->all_multi_cnt += all_multi; - erip->all_sap_cnt += all_sap; - /* - * Reinitialize rx mac - */ - eri_init_rx(erip); - mutex_exit(&erip->intrlock); - } - if (erip->promisc_cnt == 1) - eri_notify_ind(erip, DL_NOTE_PROMISC_ON_PHYS); - } - - dlokack(wq, mp, DL_ATTACH_REQ); - ERI_DEBUG_MSG1(NULL, PROTO_MSG, "eri_areq: Normal exit"); -} - -static void -eri_dreq(queue_t *wq, mblk_t *mp) -{ - struct eristr *sbp; - - sbp = (struct eristr *)wq->q_ptr; - if (MBLKL(mp) < DL_DETACH_REQ_SIZE) { - dlerrorack(wq, mp, DL_DETACH_REQ, DL_BADPRIM, 0); - return; - } - - if (sbp->sb_state != DL_UNBOUND) { - dlerrorack(wq, mp, DL_DETACH_REQ, DL_OUTSTATE, 0); - return; - } - - eri_dodetach(sbp); - - /* dissociate queue */ - (void) qassociate(wq, -1); - - dlokack(wq, mp, DL_DETACH_REQ); -} - -/* - * Detach a Stream from an interface. - */ -static void -eri_dodetach(struct eristr *sbp) +static int +eri_m_promisc(void *arg, boolean_t on) { - struct eristr *tsbp; - struct eri *erip; - int reinit = 0, i; - uint32_t promisc = 0; - uint32_t all_multi = 0; - uint32_t all_sap = 0; - - ASSERT(sbp->sb_erip); - - erip = sbp->sb_erip; - sbp->sb_erip = NULL; - - /* Disable promiscuous mode if on. */ - if (sbp->sb_flags & ERI_SALLPHYS) { - sbp->sb_flags &= ~ERI_SALLPHYS; - promisc++; - reinit = 1; - } - - /* Disable ALLSAP mode if on. */ - if (sbp->sb_flags & ERI_SALLSAP) { - sbp->sb_flags &= ~ERI_SALLSAP; - all_sap++; - } - - /* Disable ALLMULTI mode if on. */ - if (sbp->sb_flags & ERI_SALLMULTI) { - sbp->sb_flags &= ~ERI_SALLMULTI; - all_multi++; - reinit = 1; - } - - /* Disable MULTI mode if on. */ - if (sbp->sb_flags & ERI_SMULTI) { - sbp->sb_flags &= ~ERI_SMULTI; - reinit = 2; - } - - /* Disable any Multicast Addresses. */ - - for (i = 0; i < NMCHASH; i++) { - if (sbp->sb_mctab[i]) { - reinit = 2; - kmem_free(sbp->sb_mctab[i], sbp->sb_mcsize[i] * - sizeof (struct ether_addr)); - sbp->sb_mctab[i] = NULL; - } - sbp->sb_mccount[i] = sbp->sb_mcsize[i] = 0; - } - - for (i = 0; i < NMCFILTER_BITS/16; i++) - sbp->sb_ladrf[i] = 0; - - for (i = 0; i < NMCFILTER_BITS; i++) - sbp->sb_ladrf_refcnt[i] = 0; - - sbp->sb_state = DL_UNATTACHED; - - /* - * Detach from device structure. - * Uninit the device and update power management property - * when no other streams are attached to it. - */ - - rw_enter(&eristruplock, RW_READER); - - for (tsbp = eristrup; tsbp; tsbp = tsbp->sb_nextp) - if (tsbp->sb_erip == erip) - break; - - rw_exit(&eristruplock); - - if (tsbp == NULL) { - eri_uninit(erip); - } else if (reinit) { - boolean_t needind; - - mutex_enter(&erip->intrlock); - erip->promisc_cnt -= promisc; - erip->all_multi_cnt -= all_multi; - erip->all_sap_cnt -= all_sap; - if (erip->promisc_cnt == 0 || erip->all_multi_cnt == 0 || - reinit == 2) - eri_init_rx(erip); - needind = (erip->promisc_cnt == 0); - - mutex_exit(&erip->intrlock); - - if (needind) - eri_notify_ind(erip, DL_NOTE_PROMISC_OFF_PHYS); - } - eri_setipq(erip); -} - -static void -eri_breq(queue_t *wq, mblk_t *mp) -{ - struct eristr *sbp; - union DL_primitives *dlp; - struct eri *erip; - struct eridladdr eriaddr; - t_uscalar_t sap; - t_uscalar_t xidtest; - - sbp = (struct eristr *)wq->q_ptr; - - if (MBLKL(mp) < DL_BIND_REQ_SIZE) { - dlerrorack(wq, mp, DL_BIND_REQ, DL_BADPRIM, 0); - ERI_DEBUG_MSG1(NULL, PROTO_MSG, - "eri_breq: Bad REQ Size"); - return; - } - - if (sbp->sb_state != DL_UNBOUND) { - dlerrorack(wq, mp, DL_BIND_REQ, DL_OUTSTATE, 0); - ERI_DEBUG_MSG1(NULL, PROTO_MSG, - "eri_breq: Bad DL_OUTSTATE"); - return; - } - - dlp = (union DL_primitives *)mp->b_rptr; - erip = sbp->sb_erip; - sap = dlp->bind_req.dl_sap; - xidtest = dlp->bind_req.dl_xidtest_flg; - - ASSERT(erip); - - if (xidtest) { - dlerrorack(wq, mp, DL_BIND_REQ, DL_NOAUTO, 0); - ERI_DEBUG_MSG1(NULL, PROTO_MSG, - "eri_breq: Bad DL_NOAUTO"); - return; - } - - if (sap > ETHERTYPE_MAX) { - dlerrorack(wq, mp, dlp->dl_primitive, DL_BADSAP, 0); - ERI_DEBUG_MSG1(NULL, PROTO_MSG, - "eri_breq: DL_BADSAP"); - return; - } - - /* - * Save SAP value for this Stream and change state. - */ - sbp->sb_sap = sap; - sbp->sb_state = DL_IDLE; - - eriaddr.dl_sap = sap; - ether_bcopy(&erip->ouraddr, &eriaddr.dl_phys); - dlbindack(wq, mp, sap, &eriaddr, ERI_ADDRL, 0, 0); - - eri_setipq(erip); - -} - -static void -eri_ubreq(queue_t *wq, mblk_t *mp) -{ - struct eristr *sbp; - - sbp = (struct eristr *)wq->q_ptr; - - if (MBLKL(mp) < DL_UNBIND_REQ_SIZE) { - dlerrorack(wq, mp, DL_UNBIND_REQ, DL_BADPRIM, 0); - return; - } - - if (sbp->sb_state != DL_IDLE) { - dlerrorack(wq, mp, DL_UNBIND_REQ, DL_OUTSTATE, 0); - return; - } - - sbp->sb_state = DL_UNBOUND; - sbp->sb_sap = 0; - - dlokack(wq, mp, DL_UNBIND_REQ); - - eri_setipq(sbp->sb_erip); -} - -static void -eri_ireq(queue_t *wq, mblk_t *mp) -{ - struct eristr *sbp; - dl_info_ack_t *dlip; - struct eridladdr *dlap; - struct ether_addr *ep; - size_t size; - - sbp = (struct eristr *)wq->q_ptr; - - if (MBLKL(mp) < DL_INFO_REQ_SIZE) { - dlerrorack(wq, mp, DL_INFO_REQ, DL_BADPRIM, 0); - ERI_DEBUG_MSG1(NULL, PROTO_MSG, - "eri_ireq: < DL_INFO_REQ_SIZE"); - return; - } - - /* Exchange current msg for a DL_INFO_ACK. */ - size = sizeof (dl_info_ack_t) + ERI_ADDRL + ETHERADDRL; - mp = mexchange(wq, mp, size, M_PCPROTO, DL_INFO_ACK); - if (mp == NULL) { - ERI_DEBUG_MSG1(NULL, PROTO_MSG, - "eri_ireq: mp == NULL"); - return; - } - - /* Fill in the DL_INFO_ACK fields and reply. */ - dlip = (dl_info_ack_t *)mp->b_rptr; - *dlip = infoack; - dlip->dl_current_state = sbp->sb_state; - dlap = (struct eridladdr *)(mp->b_rptr + dlip->dl_addr_offset); - dlap->dl_sap = sbp->sb_sap; - - if (sbp->sb_erip) { - ether_bcopy(&sbp->sb_erip->ouraddr, &dlap->dl_phys); - ERI_DEBUG_MSG1(NULL, PROTO_MSG, - "eri_ireq: sbp->sb_erip"); - } else { - bzero((caddr_t)&dlap->dl_phys, ETHERADDRL); - ERI_DEBUG_MSG1(NULL, PROTO_MSG, - "eri_ireq: !sbp->sb_erip"); - } - - ep = (struct ether_addr *)(mp->b_rptr + dlip->dl_brdcst_addr_offset); - ether_bcopy(ðerbroadcastaddr, ep); - - qreply(wq, mp); -} - -static void -eri_ponreq(queue_t *wq, mblk_t *mp) -{ - struct eri *erip; - struct eristr *sbp; - int phy_flag = 0; - int sap_flag = 0; - int allmulti_flag = 0; - boolean_t needind; - - sbp = (struct eristr *)wq->q_ptr; - - if (MBLKL(mp) < DL_PROMISCON_REQ_SIZE) { - dlerrorack(wq, mp, DL_PROMISCON_REQ, DL_BADPRIM, 0); - return; - } - - /* - * Do not increment counter if already set. - */ - if (sbp->sb_flags & ERI_SALLPHYS) - phy_flag = 1; - if (sbp->sb_flags & ERI_SALLSAP) - sap_flag = 1; - if (sbp->sb_flags & ERI_SALLMULTI) - allmulti_flag = 1; - - switch (((dl_promiscon_req_t *)mp->b_rptr)->dl_level) { - case DL_PROMISC_PHYS: - sbp->sb_flags |= ERI_SALLPHYS; - break; - - case DL_PROMISC_SAP: - sbp->sb_flags |= ERI_SALLSAP; - break; - - case DL_PROMISC_MULTI: - sbp->sb_flags |= ERI_SALLMULTI; - break; - - default: - dlerrorack(wq, mp, DL_PROMISCON_REQ, DL_NOTSUPPORTED, 0); - return; - } - - erip = sbp->sb_erip; - if (erip) { - mutex_enter(&erip->intrlock); - if ((sbp->sb_flags & ERI_SALLPHYS) && (phy_flag == 0)) - erip->promisc_cnt++; - if ((sbp->sb_flags & ERI_SALLSAP) && (sap_flag == 0)) - erip->all_sap_cnt++; - if ((sbp->sb_flags & ERI_SALLMULTI) && (allmulti_flag == 0)) - erip->all_multi_cnt++; - if (erip->promisc_cnt == 1 || erip->all_multi_cnt == 1) { - eri_init_rx(sbp->sb_erip); - needind = B_TRUE; - } else { - needind = B_FALSE; - } - mutex_exit(&erip->intrlock); - if (needind) - eri_notify_ind(erip, DL_NOTE_PROMISC_ON_PHYS); - - eri_setipq(sbp->sb_erip); - } - dlokack(wq, mp, DL_PROMISCON_REQ); -} - -static void -eri_poffreq(queue_t *wq, mblk_t *mp) -{ - struct eri *erip; - struct eristr *sbp; - int flag; - - sbp = (struct eristr *)wq->q_ptr; - - if (MBLKL(mp) < DL_PROMISCOFF_REQ_SIZE) { - dlerrorack(wq, mp, DL_PROMISCOFF_REQ, DL_BADPRIM, 0); - return; - } - - switch (((dl_promiscoff_req_t *)mp->b_rptr)->dl_level) { - case DL_PROMISC_PHYS: - flag = ERI_SALLPHYS; - break; - - case DL_PROMISC_SAP: - flag = ERI_SALLSAP; - break; - - case DL_PROMISC_MULTI: - flag = ERI_SALLMULTI; - break; - - default: - dlerrorack(wq, mp, DL_PROMISCOFF_REQ, DL_NOTSUPPORTED, 0); - return; - } - - if ((sbp->sb_flags & flag) == 0) { - dlerrorack(wq, mp, DL_PROMISCOFF_REQ, DL_NOTENAB, 0); - return; - } - - sbp->sb_flags &= ~flag; - - erip = sbp->sb_erip; - if (erip) { - boolean_t needind; - - mutex_enter(&erip->intrlock); - if (flag == ERI_SALLPHYS) - erip->promisc_cnt--; - if (flag == ERI_SALLSAP) - erip->all_sap_cnt--; - if (flag == ERI_SALLMULTI) - erip->all_multi_cnt--; - if (((flag == ERI_SALLPHYS) && (erip->promisc_cnt == 0)) || - ((flag == ERI_SALLMULTI) && (erip->all_multi_cnt == 0))) { - eri_init_rx(sbp->sb_erip); - needind = (flag == ERI_SALLPHYS); - } else { - needind = B_FALSE; - } - mutex_exit(&erip->intrlock); - - if (needind) - eri_notify_ind(erip, DL_NOTE_PROMISC_OFF_PHYS); - - eri_setipq(sbp->sb_erip); - } - dlokack(wq, mp, DL_PROMISCOFF_REQ); + struct eri *erip = arg; + + mutex_enter(&erip->intrlock); + erip->promisc = on; + eri_init_rx(erip); + mutex_exit(&erip->intrlock); + return (0); } /* * This is to support unlimited number of members * in Multicast. */ -static void -eri_emreq(queue_t *wq, mblk_t *mp) +static int +eri_m_multicst(void *arg, boolean_t add, const uint8_t *mca) { - struct eristr *sbp; - union DL_primitives *dlp; - struct ether_addr *addrp; - t_uscalar_t off; - t_uscalar_t len; - uint32_t mchash; - struct ether_addr *mcbucket; - uint32_t ladrf_bit; - - sbp = (struct eristr *)wq->q_ptr; - if (MBLKL(mp) < DL_ENABMULTI_REQ_SIZE) { - dlerrorack(wq, mp, DL_ENABMULTI_REQ, DL_BADPRIM, 0); - return; - } - - if (sbp->sb_state == DL_UNATTACHED) { - dlerrorack(wq, mp, DL_ENABMULTI_REQ, DL_OUTSTATE, 0); - return; - } - - dlp = (union DL_primitives *)mp->b_rptr; - len = dlp->enabmulti_req.dl_addr_length; - off = dlp->enabmulti_req.dl_addr_offset; - addrp = (struct ether_addr *)(mp->b_rptr + off); - - if ((len != ETHERADDRL) || - !MBLKIN(mp, off, len) || - ((addrp->ether_addr_octet[0] & 01) == 0)) { - dlerrorack(wq, mp, DL_ENABMULTI_REQ, DL_BADADDR, 0); - return; - } - - /* - * Calculate hash value and bucket. - */ - - mchash = MCHASH(addrp); - mcbucket = sbp->sb_mctab[mchash]; - - /* - * Allocate hash bucket if it's not there. - */ - - if (mcbucket == NULL) { - sbp->sb_mctab[mchash] = mcbucket = - kmem_alloc(INIT_BUCKET_SIZE * - sizeof (struct ether_addr), - KM_SLEEP); - sbp->sb_mcsize[mchash] = INIT_BUCKET_SIZE; - } - - /* - * We no longer bother checking to see if the address is already - * in the table. We won't reinitialize the - * hardware, since we'll find the mc bit is already set. - */ - - /* - * Expand table if necessary. - */ - if (sbp->sb_mccount[mchash] >= sbp->sb_mcsize[mchash]) { - struct ether_addr *newbucket; - int newsize; - - newsize = sbp->sb_mcsize[mchash] * 2; - - newbucket = kmem_alloc(newsize * sizeof (struct ether_addr), - KM_SLEEP); - bcopy(mcbucket, newbucket, - sbp->sb_mcsize[mchash] * sizeof (struct ether_addr)); - kmem_free(mcbucket, sbp->sb_mcsize[mchash] * - sizeof (struct ether_addr)); - - sbp->sb_mctab[mchash] = mcbucket = newbucket; - sbp->sb_mcsize[mchash] = newsize; - } - - /* - * Add address to the table. - */ - mcbucket[sbp->sb_mccount[mchash]++] = *addrp; + struct eri *erip = arg; + uint32_t ladrf_bit; /* * If this address's bit was not already set in the local address * filter, add it and re-initialize the Hardware. */ - ladrf_bit = eri_ladrf_bit(addrp); - - if (sbp->sb_ladrf_refcnt[ladrf_bit] == 0) { - sbp->sb_ladrf[15-(ladrf_bit/16)] |= - 1 << (ladrf_bit % 16); - sbp->sb_flags |= ERI_SMULTI; - mutex_enter(&sbp->sb_erip->intrlock); - eri_init_rx(sbp->sb_erip); - mutex_exit(&sbp->sb_erip->intrlock); - } - sbp->sb_ladrf_refcnt[ladrf_bit]++; - - dlokack(wq, mp, DL_ENABMULTI_REQ); -} - -static void -eri_dmreq(queue_t *wq, mblk_t *mp) -{ - struct eristr *sbp; - union DL_primitives *dlp; - struct ether_addr *addrp; - t_uscalar_t off; - t_uscalar_t len; - int i; - uint32_t mchash; - struct ether_addr *mcbucket; - - sbp = (struct eristr *)wq->q_ptr; - if (MBLKL(mp) < DL_DISABMULTI_REQ_SIZE) { - dlerrorack(wq, mp, DL_DISABMULTI_REQ, DL_BADPRIM, 0); - return; - } - - if (sbp->sb_state == DL_UNATTACHED) { - dlerrorack(wq, mp, DL_DISABMULTI_REQ, DL_OUTSTATE, 0); - return; - } - - dlp = (union DL_primitives *)mp->b_rptr; - len = dlp->disabmulti_req.dl_addr_length; - off = dlp->disabmulti_req.dl_addr_offset; - addrp = (struct ether_addr *)(mp->b_rptr + off); - - if ((len != ETHERADDRL) || !MBLKIN(mp, off, len)) { - dlerrorack(wq, mp, DL_DISABMULTI_REQ, DL_BADADDR, 0); - return; - } - - /* - * Calculate hash value, get pointer to hash bucket for this address. - */ - - mchash = MCHASH(addrp); - mcbucket = sbp->sb_mctab[mchash]; - - /* - * Try and delete the address if we can find it. - */ - if (mcbucket) { - for (i = 0; i < sbp->sb_mccount[mchash]; i++) { - if (ether_cmp(addrp, &mcbucket[i]) == 0) { - uint32_t ladrf_bit; - - /* - * If there's more than one address in this - * bucket, delete the unwanted one by moving - * the last one in the list over top of it; - * otherwise, just free the bucket. - */ - if (sbp->sb_mccount[mchash] > 1) { - mcbucket[i] = - mcbucket[sbp->sb_mccount[mchash]-1]; - } else { - kmem_free(mcbucket, - sbp->sb_mcsize[mchash] * - sizeof (struct ether_addr)); - sbp->sb_mctab[mchash] = NULL; - } - sbp->sb_mccount[mchash]--; - - /* - * If this address's bit should no longer be - * set in the local address filter, clear it and - * re-initialize the Hardware - */ - - ladrf_bit = eri_ladrf_bit(addrp); - sbp->sb_ladrf_refcnt[ladrf_bit]--; - - if (sbp->sb_ladrf_refcnt[ladrf_bit] == 0) { - sbp->sb_ladrf[15-(ladrf_bit/16)] &= - ~(1 << (ladrf_bit % 16)); - mutex_enter(&sbp->sb_erip->intrlock); - eri_init_rx(sbp->sb_erip); - mutex_exit(&sbp->sb_erip->intrlock); - } - - dlokack(wq, mp, DL_DISABMULTI_REQ); - return; - } + ladrf_bit = eri_ladrf_bit(mca); + + mutex_enter(&erip->intrlock); + if (add) { + erip->ladrf_refcnt[ladrf_bit]++; + if (erip->ladrf_refcnt[ladrf_bit] == 1) { + LADRF_SET(erip, ladrf_bit); + erip->multi_refcnt++; + eri_init_rx(erip); + } + } else { + erip->ladrf_refcnt[ladrf_bit]--; + if (erip->ladrf_refcnt[ladrf_bit] == 0) { + LADRF_CLR(erip, ladrf_bit); + erip->multi_refcnt--; + eri_init_rx(erip); } } - dlerrorack(wq, mp, DL_DISABMULTI_REQ, DL_NOTENAB, 0); -} - -static void -eri_pareq(queue_t *wq, mblk_t *mp) -{ - struct eristr *sbp; - union DL_primitives *dlp; - uint32_t type; - struct eri *erip; - struct ether_addr addr; - - sbp = (struct eristr *)wq->q_ptr; - if (MBLKL(mp) < DL_PHYS_ADDR_REQ_SIZE) { - dlerrorack(wq, mp, DL_PHYS_ADDR_REQ, DL_BADPRIM, 0); - return; - } - - dlp = (union DL_primitives *)mp->b_rptr; - type = dlp->physaddr_req.dl_addr_type; - erip = sbp->sb_erip; - if (erip == NULL) { - dlerrorack(wq, mp, DL_PHYS_ADDR_REQ, DL_OUTSTATE, 0); - return; - } - - switch (type) { - case DL_FACT_PHYS_ADDR: - if (erip->addrflags & ERI_FACTADDR_PRESENT) - ether_bcopy(&erip->factaddr, &addr); - else - (void) localetheraddr((struct ether_addr *)NULL, &addr); - break; - - case DL_CURR_PHYS_ADDR: - ether_bcopy(&erip->ouraddr, &addr); - break; - - default: - dlerrorack(wq, mp, DL_PHYS_ADDR_REQ, DL_NOTSUPPORTED, 0); - return; - } - - dlphysaddrack(wq, mp, &addr, ETHERADDRL); + mutex_exit(&erip->intrlock); + return (0); } -static void -eri_spareq(queue_t *wq, mblk_t *mp) +static int +eri_m_unicst(void *arg, const uint8_t *macaddr) { - struct eristr *sbp; - union DL_primitives *dlp; - t_uscalar_t off; - t_uscalar_t len; - struct ether_addr *addrp; - struct eri *erip; - - sbp = (struct eristr *)wq->q_ptr; - - if (MBLKL(mp) < DL_SET_PHYS_ADDR_REQ_SIZE) { - dlerrorack(wq, mp, DL_SET_PHYS_ADDR_REQ, DL_BADPRIM, 0); - return; - } - - dlp = (union DL_primitives *)mp->b_rptr; - len = dlp->set_physaddr_req.dl_addr_length; - off = dlp->set_physaddr_req.dl_addr_offset; - - if (!MBLKIN(mp, off, len)) { - dlerrorack(wq, mp, DL_SET_PHYS_ADDR_REQ, DL_BADPRIM, 0); - return; - } - - addrp = (struct ether_addr *)(mp->b_rptr + off); - - /* - * Error if length of address isn't right or the address - * specified is a multicast or broadcast address. - */ - if ((len != ETHERADDRL) || - ((addrp->ether_addr_octet[0] & 01) == 1) || - (ether_cmp(addrp, ðerbroadcastaddr) == 0)) { - dlerrorack(wq, mp, DL_SET_PHYS_ADDR_REQ, DL_BADADDR, 0); - return; - } - - /* - * Error if this stream is not attached to a device. - */ - if ((erip = sbp->sb_erip) == NULL) { - dlerrorack(wq, mp, DL_SET_PHYS_ADDR_REQ, DL_OUTSTATE, 0); - return; - } + struct eri *erip = arg; /* * Set new interface local address and re-init device. * This is destructive to any other streams attached * to this device. */ - ether_bcopy(addrp, &erip->ouraddr); mutex_enter(&erip->intrlock); - eri_init_rx(sbp->sb_erip); + bcopy(macaddr, &erip->ouraddr, ETHERADDRL); + eri_init_rx(erip); mutex_exit(&erip->intrlock); - - dlokack(wq, mp, DL_SET_PHYS_ADDR_REQ); + return (0); } -static void -eri_udreq(queue_t *wq, mblk_t *mp) +/*ARGSUSED*/ +static boolean_t +eri_m_getcapab(void *arg, mac_capab_t cap, void *cap_data) { - struct eristr *sbp; - struct eri *erip; - dl_unitdata_req_t *dludp; - mblk_t *nmp; - struct eridladdr *dlap; - struct ether_header *headerp; - t_uscalar_t off, len, sap; - uint_t start_offset = 0; - uint_t stuff_offset = 0; - uint_t end_offset = 0; - uint_t value = 0; - uint_t flags = 0; - - sbp = (struct eristr *)wq->q_ptr; - erip = sbp->sb_erip; - if (sbp->sb_state != DL_IDLE) { - dlerrorack(wq, mp, DL_UNITDATA_REQ, DL_OUTSTATE, 0); - return; - } - - dludp = (dl_unitdata_req_t *)mp->b_rptr; - - off = dludp->dl_dest_addr_offset; - len = dludp->dl_dest_addr_length; - - /* - * Validate destination address format. - */ - if (!MBLKIN(mp, off, len) || (len != ERI_ADDRL)) { - dluderrorind(wq, mp, mp->b_rptr + off, len, DL_BADADDR, 0); - return; - } - - /* - * Error if no M_DATA follows. - */ - nmp = mp->b_cont; - if (nmp == NULL) { - dluderrorind(wq, mp, mp->b_rptr + off, len, DL_BADDATA, 0); - return; + switch (cap) { + case MAC_CAPAB_HCKSUM: { + uint32_t *hcksum_txflags = cap_data; + *hcksum_txflags = HCKSUM_INET_PARTIAL; + return (B_TRUE); } - - dlap = (struct eridladdr *)(mp->b_rptr + off); - - /* - * Create ethernet header by either prepending it onto the - * next mblk if possible, or reusing the M_PROTO block if not. - */ - if ((DB_REF(nmp) == 1) && - (MBLKHEAD(nmp) >= sizeof (struct ether_header)) && - (((uintptr_t)nmp->b_rptr & 0x1) == 0)) { - nmp->b_rptr -= sizeof (struct ether_header); - headerp = (struct ether_header *)nmp->b_rptr; - ether_bcopy(&dlap->dl_phys, &headerp->ether_dhost); - ether_bcopy(&erip->ouraddr, &headerp->ether_shost); - sap = (uint16_t)((((uchar_t *)(&dlap->dl_sap))[0] << 8) | - ((uchar_t *)(&dlap->dl_sap))[1]); - freeb(mp); - mp = nmp; - } else { - DB_TYPE(mp) = M_DATA; - headerp = (struct ether_header *)mp->b_rptr; - mp->b_wptr = mp->b_rptr + sizeof (struct ether_header); - ether_bcopy(&dlap->dl_phys, &headerp->ether_dhost); - ether_bcopy(&erip->ouraddr, &headerp->ether_shost); - sap = (uint16_t)((((uchar_t *)(&dlap->dl_sap))[0] << 8) | - ((uchar_t *)(&dlap->dl_sap))[1]); -#ifdef ERI_HWCSUM - if (sbp->sb_flags & ERI_SCKSUM) { - hcksum_retrieve(nmp, NULL, NULL, &start_offset, - &stuff_offset, &end_offset, &value, &flags); - - if (flags & HCK_PARTIALCKSUM) { - (void) hcksum_assoc(mp, NULL, NULL, - start_offset, stuff_offset, end_offset, - 0, flags, 0); - ERI_DEBUG_MSG1(erip, HWCSUM_MSG, - "eri_udreq: added new buffer\n"); - } - } -#endif /* ERI_HWCSUM */ + case MAC_CAPAB_POLL: + default: + return (B_FALSE); } - - /* - * In 802.3 mode, the driver looks at the - * sap field of the DL_BIND_REQ being 0 in addition to the destination - * sap field in the range [0-1500]. If either is true, then the driver - * computes the length of the message, not including initial M_PROTO - * mblk (message block), of all subsequent DL_UNITDATA_REQ messages and - * transmits 802.3 frames that have this value in the MAC frame header - * length field. - */ - if (sap <= ETHERMTU || (sbp->sb_sap == 0)) { - put_ether_type(headerp, - (msgsize(mp) - sizeof (struct ether_header))); - } else { - put_ether_type(headerp, sap); +} + +static int +eri_m_start(void *arg) +{ + struct eri *erip = arg; + + mutex_enter(&erip->intrlock); + erip->flags |= ERI_STARTED; + mutex_exit(&erip->intrlock); + + if (!eri_init(erip)) { + mutex_enter(&erip->intrlock); + erip->flags &= ~ERI_STARTED; + mutex_exit(&erip->intrlock); + return (EIO); } - (void) eri_start(wq, mp, erip); + return (0); } static void -eri_nreq(queue_t *wq, mblk_t *mp) +eri_m_stop(void *arg) { - struct eristr *sbp; - dl_notify_req_t *dlip; - dl_notify_ind_t *dlnip; - struct eri *erip = NULL; - mblk_t *nmp; - uint32_t dl_notification; - - if (MBLKL(mp) < DL_NOTIFY_REQ_SIZE) { - dlerrorack(wq, mp, DL_NOTIFY_REQ, DL_BADPRIM, 0); - return; - } - - dlip = (dl_notify_req_t *)mp->b_rptr; - - dl_notification = dlip->dl_notifications & (DL_NOTE_PROMISC_ON_PHYS | - DL_NOTE_PROMISC_OFF_PHYS | - DL_NOTE_LINK_DOWN | - DL_NOTE_LINK_UP | - DL_NOTE_SPEED); - - sbp = (struct eristr *)wq->q_ptr; - - if (sbp->sb_state != DL_IDLE) { - dlerrorack(wq, mp, DL_NOTIFY_REQ, DL_OUTSTATE, 0); - return; - } - - erip = sbp->sb_erip; - - sbp->sb_notifications |= dl_notification; - - dlip->dl_notifications = DL_NOTE_PROMISC_ON_PHYS | - DL_NOTE_PROMISC_OFF_PHYS | - DL_NOTE_LINK_DOWN | - DL_NOTE_LINK_UP | - DL_NOTE_SPEED; - - dlip->dl_primitive = DL_NOTIFY_ACK; - mp->b_wptr = mp->b_rptr + DL_NOTIFY_ACK_SIZE; - qreply(wq, mp); - - while (dl_notification) { - if ((nmp = allocb(DL_NOTIFY_IND_SIZE, BPRI_HI)) == NULL) - break; - nmp->b_datap->db_type = M_PROTO; - dlnip = (dl_notify_ind_t *)nmp->b_rptr; - dlnip->dl_primitive = DL_NOTIFY_IND; - dlnip->dl_notification = 0; - dlnip->dl_data = 0; - dlnip->dl_addr_length = 0; - dlnip->dl_addr_offset = 0; - if (dl_notification & DL_NOTE_PROMISC_ON_PHYS) { - dl_notification &= ~DL_NOTE_PROMISC_ON_PHYS; - if (erip->promisc_cnt) - dlnip->dl_notification = - DL_NOTE_PROMISC_ON_PHYS; - } else if (dl_notification & DL_NOTE_PROMISC_OFF_PHYS) { - dl_notification &= ~DL_NOTE_PROMISC_OFF_PHYS; - if (erip->promisc_cnt == 0) - dlnip->dl_notification = - DL_NOTE_PROMISC_OFF_PHYS; - } else if (dl_notification & DL_NOTE_LINK_DOWN) { - dl_notification &= ~DL_NOTE_LINK_DOWN; - if (!param_linkup) - dlnip->dl_notification = DL_NOTE_LINK_DOWN; - } else if (dl_notification & DL_NOTE_LINK_UP) { - dl_notification &= ~DL_NOTE_LINK_UP; - if (param_linkup) - dlnip->dl_notification = DL_NOTE_LINK_UP; - } else if (dl_notification & DL_NOTE_SPEED) { - dl_notification &= ~DL_NOTE_SPEED; - dlnip->dl_data = erip->stats.ifspeed * 1000; - dlnip->dl_notification = DL_NOTE_SPEED; - } - if (dlnip->dl_notification) { - nmp->b_wptr = nmp->b_rptr + DL_NOTIFY_IND_SIZE; - qreply(wq, nmp); - } else - freemsg(nmp); - } + struct eri *erip = arg; + + mutex_enter(&erip->intrlock); + erip->flags &= ~ERI_STARTED; + mutex_exit(&erip->intrlock); + eri_uninit(erip); } -static void -eri_notify_ind(struct eri *erip, uint32_t notification) +static int +eri_m_stat(void *arg, uint_t stat, uint64_t *val) { - struct eristr *sbp; - mblk_t *mp; - dl_notify_ind_t *dlnip; - - for (sbp = eristrup; sbp; sbp = sbp->sb_nextp) { - if (sbp->sb_erip != erip) - continue; - if (notification & sbp->sb_notifications) { - if ((mp = allocb(DL_NOTIFY_IND_SIZE, BPRI_HI)) - == NULL) { - HSTAT(erip, allocbfail); - break; - } - mp->b_datap->db_type = M_PROTO; - dlnip = (dl_notify_ind_t *)mp->b_rptr; - dlnip->dl_primitive = DL_NOTIFY_IND; - dlnip->dl_notification = notification; - if (notification == DL_NOTE_SPEED) - dlnip->dl_data = erip->stats.ifspeed * 1000; - else - dlnip->dl_data = 0; - dlnip->dl_addr_length = 0; - dlnip->dl_addr_offset = 0; - mp->b_wptr = mp->b_rptr + DL_NOTIFY_IND_SIZE; - qreply(WR(sbp->sb_rq), mp); - } + struct eri *erip = arg; + struct stats *esp; + boolean_t macupdate = B_FALSE; + + esp = &erip->stats; + + mutex_enter(&erip->xmitlock); + if ((erip->flags & ERI_RUNNING) && (erip->flags & ERI_TXINIT)) { + erip->tx_completion = + GET_ETXREG(tx_completion) & ETX_COMPLETION_MASK; + macupdate |= eri_reclaim(erip, erip->tx_completion); } -} - -static void -eri_send_notifications(struct eri *erip, uint32_t linkflags) -{ - if (linkflags & DL_NOTE_LINK_DOWN) { - eri_notify_ind(erip, DL_NOTE_LINK_DOWN); + mutex_exit(&erip->xmitlock); + if (macupdate) + mac_tx_update(erip->mh); + + eri_savecntrs(erip); + + switch (stat) { + case MAC_STAT_IFSPEED: + *val = esp->ifspeed * 1000000ULL; + break; + case MAC_STAT_MULTIRCV: + *val = esp->multircv; + break; + case MAC_STAT_BRDCSTRCV: + *val = esp->brdcstrcv; + break; + case MAC_STAT_IPACKETS: + *val = esp->ipackets64; + break; + case MAC_STAT_RBYTES: + *val = esp->rbytes64; + break; + case MAC_STAT_OBYTES: + *val = esp->obytes64; + break; + case MAC_STAT_OPACKETS: + *val = esp->opackets64; + break; + case MAC_STAT_IERRORS: + *val = esp->ierrors; + break; + case MAC_STAT_OERRORS: + *val = esp->oerrors; + break; + case MAC_STAT_MULTIXMT: + *val = esp->multixmt; + break; + case MAC_STAT_BRDCSTXMT: + *val = esp->brdcstxmt; + break; + case MAC_STAT_NORCVBUF: + *val = esp->norcvbuf; + break; + case MAC_STAT_NOXMTBUF: + *val = esp->noxmtbuf; + break; + case MAC_STAT_UNDERFLOWS: + *val = esp->txmac_urun; + break; + case MAC_STAT_OVERFLOWS: + *val = esp->rx_overflow; + break; + case MAC_STAT_COLLISIONS: + *val = esp->collisions; + break; + case ETHER_STAT_ALIGN_ERRORS: + *val = esp->rx_align_err; + break; + case ETHER_STAT_FCS_ERRORS: + *val = esp->rx_crc_err; + break; + case ETHER_STAT_EX_COLLISIONS: + *val = esp->excessive_coll; + break; + case ETHER_STAT_TX_LATE_COLLISIONS: + *val = esp->late_coll; + break; + case ETHER_STAT_FIRST_COLLISIONS: + *val = esp->first_coll; + break; + case ETHER_STAT_LINK_DUPLEX: + *val = esp->link_duplex; + break; + case ETHER_STAT_TOOLONG_ERRORS: + *val = esp->rx_toolong_pkts; + break; + case ETHER_STAT_TOOSHORT_ERRORS: + *val = esp->rx_runt; + break; + + case ETHER_STAT_XCVR_ADDR: + *val = erip->phyad; + break; + + case ETHER_STAT_XCVR_INUSE: + *val = XCVR_100X; /* should always be 100X for now */ + break; + + case ETHER_STAT_CAP_100FDX: + *val = param_bmsr_100fdx; + break; + case ETHER_STAT_CAP_100HDX: + *val = param_bmsr_100hdx; + break; + case ETHER_STAT_CAP_10FDX: + *val = param_bmsr_10fdx; + break; + case ETHER_STAT_CAP_10HDX: + *val = param_bmsr_10hdx; + break; + case ETHER_STAT_CAP_AUTONEG: + *val = param_bmsr_ancap; + break; + case ETHER_STAT_CAP_ASMPAUSE: + *val = param_bmsr_asm_dir; + break; + case ETHER_STAT_CAP_PAUSE: + *val = param_bmsr_pause; + break; + case ETHER_STAT_ADV_CAP_100FDX: + *val = param_anar_100fdx; + break; + case ETHER_STAT_ADV_CAP_100HDX: + *val = param_anar_100hdx; + break; + case ETHER_STAT_ADV_CAP_10FDX: + *val = param_anar_10fdx; + break; + case ETHER_STAT_ADV_CAP_10HDX: + *val = param_anar_10hdx; + break; + case ETHER_STAT_ADV_CAP_AUTONEG: + *val = param_autoneg; + break; + case ETHER_STAT_ADV_CAP_ASMPAUSE: + *val = param_anar_asm_dir; + break; + case ETHER_STAT_ADV_CAP_PAUSE: + *val = param_anar_pause; + break; + case ETHER_STAT_LP_CAP_100FDX: + *val = param_anlpar_100fdx; + break; + case ETHER_STAT_LP_CAP_100HDX: + *val = param_anlpar_100hdx; + break; + case ETHER_STAT_LP_CAP_10FDX: + *val = param_anlpar_10fdx; + break; + case ETHER_STAT_LP_CAP_10HDX: + *val = param_anlpar_10hdx; + break; + case ETHER_STAT_LP_CAP_AUTONEG: + *val = param_aner_lpancap; + break; + case ETHER_STAT_LP_CAP_ASMPAUSE: + *val = param_anlpar_pauseTX; + break; + case ETHER_STAT_LP_CAP_PAUSE: + *val = param_anlpar_pauseRX; + break; + case ETHER_STAT_LINK_PAUSE: + *val = esp->pausing; + break; + case ETHER_STAT_LINK_ASMPAUSE: + *val = param_anar_asm_dir && + param_anlpar_pauseTX && + (param_anar_pause != param_anlpar_pauseRX); + break; + case ETHER_STAT_LINK_AUTONEG: + *val = param_autoneg && param_aner_lpancap; + break; } - if (linkflags & DL_NOTE_LINK_UP) { - eri_notify_ind(erip, DL_NOTE_LINK_UP); - eri_notify_ind(erip, DL_NOTE_SPEED); - } + return (0); } /* - * Set or clear the device ipq pointer. - * XXX Assumes IPv4 and IPv6 are ERIFAST. - */ -static void -eri_setipq(struct eri *erip) -{ - struct eristr *sbp; - int ok4 = 1; - int ok6 = 1; - queue_t *ip4q = NULL; - queue_t *ip6q = NULL; - - rw_enter(&eristruplock, RW_READER); - - for (sbp = eristrup; sbp; sbp = sbp->sb_nextp) { - if (sbp->sb_erip == erip) { - if (sbp->sb_flags & (ERI_SALLPHYS|ERI_SALLSAP)) { - ok4 = 0; - ok6 = 0; - break; - } - if (sbp->sb_sap == ETHERTYPE_IPV4) { - if (ip4q == NULL) - ip4q = sbp->sb_rq; - else - ok4 = 0; - } - if (sbp->sb_sap == ETHERTYPE_IPV6) { - if (ip6q == NULL) - ip6q = sbp->sb_rq; - else - ok6 = 0; - } - } - } - - if (ok4) - erip->ip4q = ip4q; - else - erip->ip4q = NULL; - - if (ok6) - erip->ip6q = ip6q; - else - erip->ip6q = NULL; - - rw_exit(&eristruplock); -} - - -/* * Hardware Functions * New Section */ @@ -3334,12 +1539,7 @@ */ static void eri_init_macregs_generic(struct eri *erip) - { - struct eristr *sbp; - uint16_t ladrf[NMCFILTER_BITS/16]; - int i; - /* * set up the MAC parameter registers once * after power cycle. SUSPEND/RESUME also requires @@ -3361,8 +1561,7 @@ PUT_MACREG(alimit, BMAC_ATTEMPT_LIMIT); PUT_MACREG(macctl_type, BMAC_CONTROL_TYPE); PUT_MACREG(rseed, - ((erip->ouraddr.ether_addr_octet[0] & 0x3) << 8) | - erip->ouraddr.ether_addr_octet[1]); + ((erip->ouraddr[0] & 0x3) << 8) | erip->ouraddr[1]); PUT_MACREG(madd3, BMAC_ADDRESS_3); PUT_MACREG(madd4, BMAC_ADDRESS_4); @@ -3396,59 +1595,6 @@ PUT_MACREG(spcmd, BMAC_SEND_PAUSE_CMD); else PUT_MACREG(spcmd, 0); - /* - * Program BigMAC with local individual ethernet address. - */ - PUT_MACREG(madd0, (erip->ouraddr.ether_addr_octet[4] << 8) | - erip->ouraddr.ether_addr_octet[5]); - PUT_MACREG(madd1, (erip->ouraddr.ether_addr_octet[2] << 8) | - erip->ouraddr.ether_addr_octet[3]); - PUT_MACREG(madd2, (erip->ouraddr.ether_addr_octet[0] << 8) | - erip->ouraddr.ether_addr_octet[1]); - - /* - * Set up multicast address filter by passing all multicast - * addresses through a crc generator, and then using the - * low order 8 bits as a index into the 256 bit logical - * address filter. The high order four bits select the word, - * while the rest of the bits select the bit within the word. - */ - - bzero((caddr_t)ladrf, NMCFILTER_BITS/16 * sizeof (uint16_t)); - - /* - * Here we initialize the MC Hash bits - */ - for (sbp = eristrup; sbp; sbp = sbp->sb_nextp) { - if (sbp->sb_erip == erip) { - if (sbp->sb_flags & ERI_SALLMULTI) { - for (i = 0; i < NMCFILTER_BITS/16; i++) { - ladrf[i] = 0xffff; - } - break; /* All bits are already on */ - } - for (i = 0; i < NMCFILTER_BITS/16; i++) - ladrf[i] |= sbp->sb_ladrf[i]; - } - } - - PUT_MACREG(hash0, ladrf[0]); - PUT_MACREG(hash1, ladrf[1]); - PUT_MACREG(hash2, ladrf[2]); - PUT_MACREG(hash3, ladrf[3]); - PUT_MACREG(hash4, ladrf[4]); - PUT_MACREG(hash5, ladrf[5]); - PUT_MACREG(hash6, ladrf[6]); - PUT_MACREG(hash7, ladrf[7]); - PUT_MACREG(hash8, ladrf[8]); - PUT_MACREG(hash9, ladrf[9]); - PUT_MACREG(hash10, ladrf[10]); - PUT_MACREG(hash11, ladrf[11]); - PUT_MACREG(hash12, ladrf[12]); - PUT_MACREG(hash13, ladrf[13]); - PUT_MACREG(hash14, ladrf[14]); - PUT_MACREG(hash15, ladrf[15]); - } static int @@ -3499,7 +1645,7 @@ if (erip->rmblkp[i]) { if (erip->eri_dvmarh) dvma_unload(erip->eri_dvmarh, 2 * i, - DDI_DMA_SYNC_FORCPU); + DDI_DMA_SYNC_FORCPU); else if ((ddi_dma_unbind_handle(erip->ndmarh[i]) == DDI_FAILURE)) status = -1; @@ -3550,24 +1696,21 @@ for (i = 0; i < ERI_RPENDING; i++) { if ((bp = eri_allocb(ERI_BUFSIZE)) == NULL) { status = -1; - ERI_DEBUG_MSG1(erip, RESOURCE_MSG, - "eri_init_rxbufs allocb failed"); continue; } /* Load data buffer to DVMA space */ if (erip->eri_dvmarh) - (void) dvma_kaddr_load(erip->eri_dvmarh, - (caddr_t)bp->b_rptr, ERI_BUFSIZE, - 2 * i, &dma_cookie); + dvma_kaddr_load(erip->eri_dvmarh, + (caddr_t)bp->b_rptr, ERI_BUFSIZE, + 2 * i, &dma_cookie); /* * Bind data buffer to DMA handle */ else if (ddi_dma_addr_bind_handle(erip->ndmarh[i], NULL, - (caddr_t)bp->b_rptr, ERI_BUFSIZE, - DDI_DMA_READ | DDI_DMA_CONSISTENT, - DDI_DMA_DONTWAIT, 0, - &dma_cookie, &ccnt) != DDI_DMA_MAPPED) - status = -1; + (caddr_t)bp->b_rptr, ERI_BUFSIZE, + DDI_DMA_READ | DDI_DMA_CONSISTENT, DDI_DMA_DONTWAIT, 0, + &dma_cookie, &ccnt) != DDI_DMA_MAPPED) + status = -1; PUT_RMD((&erip->rmdp[i]), dma_cookie); erip->rmblkp[i] = bp; /* save for later use */ @@ -3576,8 +1719,8 @@ /* * sync RXDMA descriptors. */ - ERI_SYNCIOPB(erip, erip->rmdp, - (ERI_RPENDING * sizeof (struct rmd)), DDI_DMA_SYNC_FORDEV); + ERI_SYNCIOPB(erip, erip->rmdp, (ERI_RPENDING * sizeof (struct rmd)), + DDI_DMA_SYNC_FORDEV); /* * Reset RMD 'walking' pointers. */ @@ -3624,8 +1767,6 @@ static int eri_stop(struct eri *erip) { - ERI_DEBUG_MSG1(erip, INIT_MSG, - "eri_stop"); (void) eri_erx_reset(erip); (void) eri_etx_reset(erip); @@ -3639,13 +1780,13 @@ erip->global_reset_issued = 2; } else { param_linkup = 0; - erip->stats.link_up = ERI_LINK_DOWN; - erip->stats.link_duplex = ERI_UNKNOWN_DUPLEX; + erip->stats.link_up = LINK_STATE_DOWN; + erip->stats.link_duplex = LINK_DUPLEX_UNKNOWN; erip->global_reset_issued = -1; } ERI_DELAY((GET_SWRSTREG(reset) == ERI_CACHE_LINE_SIZE), - ERI_MAX_RST_DELAY); + ERI_MAX_RST_DELAY); erip->rx_reset_issued = -1; erip->tx_reset_issued = -1; @@ -3658,8 +1799,6 @@ if (GET_SWRSTREG(reset) == ERI_CACHE_LINE_SIZE) { return (0); } else { - ERI_DEBUG_MSG1(erip, XCVR_MSG, - "cannot stop eri"); return (1); } } @@ -3684,7 +1823,7 @@ ERI_DELAY(((GET_ERXREG(config) & 1) == 0), ERI_MAX_RST_DELAY); if ((GET_ERXREG(config) & 1) != 0) ERI_FAULT_MSG1(erip, SEVERITY_LOW, ERI_VERB_MSG, - disable_erx_msg); + disable_erx_msg); drv_usecwait(5000); /* Delay to insure no RX DMA activity */ @@ -3693,16 +1832,11 @@ * Wait until the reset is completed which is indicated by * the reset bit cleared or time out.. */ - ERI_DELAY(((GET_SWRSTREG(reset) & (ERI_G_RESET_ERX)) == - ERI_CACHE_LINE_SIZE), ERI_MAX_RST_DELAY); + ERI_DELAY(((GET_SWRSTREG(reset) & (ERI_G_RESET_ERX)) == + ERI_CACHE_LINE_SIZE), ERI_MAX_RST_DELAY); erip->rx_reset_issued = -1; - if (GET_SWRSTREG(reset) & (ERI_G_RESET_ERX)) { - ERI_DEBUG_MSG1(erip, INIT_MSG, - "Can not reset erx"); - return (1); - } else - return (0); + return ((GET_SWRSTREG(reset) & (ERI_G_RESET_ERX)) ? 1 : 0); } /* @@ -3725,14 +1859,14 @@ ERI_DELAY(((GET_ETXREG(config) & 1) == 0), ERI_MAX_RST_DELAY); if ((GET_ETXREG(config) & 1) != 0) ERI_FAULT_MSG1(erip, SEVERITY_LOW, ERI_VERB_MSG, - disable_etx_msg); + disable_etx_msg); drv_usecwait(5000); /* Delay to ensure DMA completed (if any). */ #endif drv_usecwait(5000); /* Delay to ensure DMA completed (if any). */ ERI_DELAY(((GET_ETXREG(config) & 1) == 0), ERI_MAX_RST_DELAY); if ((GET_ETXREG(config) & 1) != 0) ERI_FAULT_MSG1(erip, SEVERITY_LOW, ERI_VERB_MSG, - disable_etx_msg); + disable_etx_msg); PUT_SWRSTREG(reset, ERI_G_RESET_ETX | ERI_CACHE_LINE_SIZE); @@ -3741,12 +1875,10 @@ * cleared or time out.. */ ERI_DELAY(((GET_SWRSTREG(reset) & (ERI_G_RESET_ETX)) == - ERI_CACHE_LINE_SIZE), ERI_MAX_RST_DELAY); + ERI_CACHE_LINE_SIZE), ERI_MAX_RST_DELAY); erip->tx_reset_issued = -1; if (GET_SWRSTREG(reset) & (ERI_G_RESET_ETX)) { - ERI_DEBUG_MSG1(erip, INIT_MSG, - "cannot reset eri etx"); return (1); } else return (0); @@ -3762,9 +1894,6 @@ uint32_t i; uint64_t tx_ring; -#ifdef DEBUG - uint32_t txfifoth = ETX_CONFIG_THRESHOLD; -#endif /* * Initialize ETX Registers: @@ -3797,14 +1926,10 @@ break; default: ERI_FAULT_MSG2(erip, SEVERITY_HIGH, ERI_VERB_MSG, - unk_tx_descr_sze_msg, ERI_TPENDING); + unk_tx_descr_sze_msg, ERI_TPENDING); return (1); } - ERI_DEBUG_MSG2(erip, INIT_MSG, - "eri_init_txregs: tx fifo threshold %X", - txfifoth); - i <<= ERI_TX_RINGSZ_SHIFT; PUT_ETXREG(config, ETX_CONFIG_THRESHOLD | i); ENABLE_TXDMA(erip); @@ -3865,20 +1990,19 @@ break; default: ERI_FAULT_MSG2(erip, SEVERITY_HIGH, ERI_VERB_MSG, - unk_rx_descr_sze_msg, ERI_RPENDING); + unk_rx_descr_sze_msg, ERI_RPENDING); return (1); } i <<= ERI_RX_RINGSZ_SHIFT; i |= (ERI_FSTBYTE_OFFSET << ERI_RX_CONFIG_FBO_SHIFT) | - (sizeof (struct ether_header) << - ERI_RX_CONFIG_RX_CSSTART_SHIFT) | - (ERI_RX_FIFOTH_1024 << ERI_RX_CONFIG_RXFIFOTH_SHIFT); + (ETHERHEADER_SIZE << ERI_RX_CONFIG_RX_CSSTART_SHIFT) | + (ERI_RX_FIFOTH_1024 << ERI_RX_CONFIG_RXFIFOTH_SHIFT); PUT_ERXREG(config, i); PUT_ERXREG(rx_blanking, - (param_intr_blank_time << ERI_RX_BLNK_INTR_TIME_SHIFT) | - param_intr_blank_packets); + (param_intr_blank_time << ERI_RX_BLNK_INTR_TIME_SHIFT) | + param_intr_blank_packets); PUT_ERXREG(rx_pause_threshold, rx_pause_threshold); erip->rxfifo_size = GET_ERXREG(rxfifo_size); @@ -3913,9 +2037,8 @@ /* * sync RXDMA descriptors. */ - ERI_SYNCIOPB(erip, erip->rmdp, - (ERI_RPENDING * sizeof (struct rmd)), - DDI_DMA_SYNC_FORDEV); + ERI_SYNCIOPB(erip, erip->rmdp, (ERI_RPENDING * sizeof (struct rmd)), + DDI_DMA_SYNC_FORDEV); /* * Reset RMD 'walking' pointers. */ @@ -3949,9 +2072,7 @@ static void eri_init_rx(struct eri *erip) { - struct eristr *sbp; - uint16_t ladrf[NMCFILTER_BITS/16]; - int i; + uint16_t *ladrf; /* * First of all make sure the Receive MAC is stop. @@ -3962,24 +2083,9 @@ * Program BigMAC with local individual ethernet address. */ - PUT_MACREG(madd0, (erip->ouraddr.ether_addr_octet[4] << 8) | - erip->ouraddr.ether_addr_octet[5]); - PUT_MACREG(madd1, (erip->ouraddr.ether_addr_octet[2] << 8) | - erip->ouraddr.ether_addr_octet[3]); - PUT_MACREG(madd2, (erip->ouraddr.ether_addr_octet[0] << 8) | - erip->ouraddr.ether_addr_octet[1]); - - /* - * XXX moved here setting erip->flags from end of this fn. - */ - if (erip->promisc_cnt) - erip->flags |= ERI_PROMISC; - else - erip->flags &= ~ERI_PROMISC; - if (erip->all_multi_cnt) - erip->flags |= ERI_ALLMULTI; - else - erip->flags &= ~ERI_ALLMULTI; + PUT_MACREG(madd0, (erip->ouraddr[4] << 8) | erip->ouraddr[5]); + PUT_MACREG(madd1, (erip->ouraddr[2] << 8) | erip->ouraddr[3]); + PUT_MACREG(madd2, (erip->ouraddr[0] << 8) | erip->ouraddr[1]); /* * Set up multicast address filter by passing all multicast @@ -3989,40 +2095,7 @@ * while the rest of the bits select the bit within the word. */ - bzero(ladrf, sizeof (ladrf)); - - rw_enter(&eristruplock, RW_READER); - - /* - * Here we initialize the MC Hash bits - */ - for (sbp = eristrup; sbp; sbp = sbp->sb_nextp) { - if (sbp->sb_erip == erip) { - if (sbp->sb_flags & ERI_SALLMULTI) { - for (i = 0; i < NMCFILTER_BITS/16; i++) { - ladrf[i] = 0xffff; - } - break; /* All bits are already on */ - } - for (i = 0; i < NMCFILTER_BITS/16; i++) - ladrf[i] |= sbp->sb_ladrf[i]; - } - } - - /* - * Determine if Multicast mode. - */ - for (sbp = eristrup; sbp; sbp = sbp->sb_nextp) { - if (sbp->sb_erip == erip) { - if (sbp->sb_flags & ERI_SMULTI) - erip->flags |= ERI_MULTICAST; - else - erip->flags &= ~ERI_MULTICAST; - break; - } - } - - rw_exit(&eristruplock); + ladrf = erip->ladrf; PUT_MACREG(hash0, ladrf[0]); PUT_MACREG(hash1, ladrf[1]); @@ -4043,76 +2116,21 @@ #ifdef ERI_DONT_STRIP_CRC PUT_MACREG(rxcfg, - ((erip->flags & ERI_PROMISC ? BMAC_RXCFG_PROMIS : 0) | - (erip->flags & ERI_MULTICAST ? BMAC_RXCFG_HASH : 0) | - (erip->flags & ERI_ALLMULTI ? BMAC_RXCFG_GRPROM : 0) | + ((erip->promisc ? BMAC_RXCFG_PROMIS : 0) | + (erip->multi_refcnt ? BMAC_RXCFG_HASH : 0) | BMAC_RXCFG_ENAB)); #else PUT_MACREG(rxcfg, - ((erip->flag & ERI_PROMISC ? BMAC_RXCFG_PROMIS : 0) | - (erip->flags & ERI_MULTICAST ? BMAC_RXCFG_HASH : 0) | - (erip->flags & ERI_ALLMULTI ? BMAC_RXCFG_GRPROM : 0) | + ((erip->promisc ? BMAC_RXCFG_PROMIS : 0) | + (erip->multi_refcnt ? BMAC_RXCFG_HASH : 0) | BMAC_RXCFG_ENAB | BMAC_RXCFG_STRIP_CRC)); #endif /* wait after setting Hash Enable bit */ /* drv_usecwait(10); */ HSTAT(erip, rx_inits); - -#if 0 - /* - * XXX why is this here? - * should be moved before setting h/w register. - */ - - if (erip->promisc_cnt) - erip->flags |= ERI_PROMISC; - else - erip->flags &= ~ERI_PROMISC; - if (erip->all_multi) - erip->flags |= ERI_ALLMULTI; - else - erip->flags &= ~ERI_ALLMULTI; -#endif - } -#ifdef LATER_SPLIT_TX_RX -/* - * This routine is used to reset the TX DMA only. - * &erip->xmitlock is held before calling this routine. - */ -void -eri_init_tx_channel(struct eri *erip) -{ - uint32_t carrier_ext = 0; - - erip->flags &= ~ERI_TXINIT; - (void) eri_etx_reset(erip); - PUT_MACREG(txmask, BMAC_TXINTR_MASK); - (void) eri_init_txregs(erip); - if (erip->ngu_enable) - PUT_MACREG(txcfg, - ((param_mode ? BMAC_TXCFG_FDX: 0) | - ((param_lance_mode && (erip->lance_mode_enable)) ? - BMAC_TXCFG_ENIPG0 : 0) | - (carrier_ext ? BMAC_TXCFG_CARR_EXT : 0) | - BMAC_TXCFG_NGU)); - else - PUT_MACREG(txcfg, - ((param_mode ? BMAC_TXCFG_FDX: 0) | - ((param_lance_mode && (erip->lance_mode_enable)) ? - BMAC_TXCFG_ENIPG0 : 0) | - (carrier_ext ? BMAC_TXCFG_CARR_EXT : 0))); - - erip->tx_reset_issued = 0; - HSTAT(erip, tx_inits); - erip->flags |= ERI_TXINIT; - -} - -#endif - /* * This routine is used to init the TX MAC only. * &erip->xmitlock is held before calling this routine. @@ -4146,18 +2164,16 @@ PUT_MACREG(ipg2, param_ipg2); if (erip->ngu_enable) - PUT_MACREG(txcfg, - ((param_mode ? BMAC_TXCFG_FDX: 0) | - ((param_lance_mode && (erip->lance_mode_enable)) ? - BMAC_TXCFG_ENIPG0 : 0) | - (carrier_ext ? BMAC_TXCFG_CARR_EXT : 0) | - BMAC_TXCFG_NGU)); + PUT_MACREG(txcfg, ((param_mode ? BMAC_TXCFG_FDX: 0) | + ((param_lance_mode && (erip->lance_mode_enable)) ? + BMAC_TXCFG_ENIPG0 : 0) | + (carrier_ext ? BMAC_TXCFG_CARR_EXT : 0) | + BMAC_TXCFG_NGU)); else - PUT_MACREG(txcfg, - ((param_mode ? BMAC_TXCFG_FDX: 0) | - ((param_lance_mode && (erip->lance_mode_enable)) ? - BMAC_TXCFG_ENIPG0 : 0) | - (carrier_ext ? BMAC_TXCFG_CARR_EXT : 0))); + PUT_MACREG(txcfg, ((param_mode ? BMAC_TXCFG_FDX: 0) | + ((param_lance_mode && (erip->lance_mode_enable)) ? + BMAC_TXCFG_ENIPG0 : 0) | + (carrier_ext ? BMAC_TXCFG_CARR_EXT : 0))); ENABLE_TXDMA(erip); ENABLE_TXMAC(erip); @@ -4165,31 +2181,10 @@ HSTAT(erip, tx_inits); erip->flags |= ERI_TXINIT; } -/* - * Start xmit on any msgs previously enqueued on any write queues. - */ -static void -eri_wenable(struct eri *erip) -{ - struct eristr *sbp; - queue_t *wq; - - /* - * Order of wantw accesses is important. - */ - do { - erip->wantw = 0; - for (sbp = eristrup; sbp; sbp = sbp->sb_nextp) - if ((wq = WR(sbp->sb_rq))->q_first) - qenable(wq); - } while (erip->wantw); -} static void eri_unallocthings(struct eri *erip) { - - uint32_t flag; uint32_t i; @@ -4246,7 +2241,7 @@ /* * Initialize channel. - * Return 0 on success, nonzero on error. + * Return true on success, false on error. * * The recommended sequence for initialization is: * 1. Issue a Global Reset command to the Ethernet Channel. @@ -4277,48 +2272,35 @@ */ /* * lock order: - * intrlock->linklock->eristruplock->xmitlock->xcvrlock + * intrlock->linklock->xmitlock->xcvrlock */ -static int +static boolean_t eri_init(struct eri *erip) { - struct eristr *sbp; uint32_t init_stat = 0; uint32_t partial_init = 0; uint32_t carrier_ext = 0; uint32_t mac_ctl = 0; - uint_t ret; - uint32_t link_timeout = ERI_LINKCHECK_TIMER; - uint32_t linkflags; - - ERI_DEBUG_MSG1(erip, INIT_MSG, - "eri_init: Entered"); + boolean_t ret; + uint32_t link_timeout = ERI_LINKCHECK_TIMER; + link_state_t linkupdate = LINK_STATE_UNKNOWN; /* - * Just return if device is suspended. + * Just return successfully if device is suspended. * eri_init() will be called again from resume. */ - if (erip == NULL) { - ERI_DEBUG_MSG1(NULL, INIT_MSG, - "eri_init: erip == NULL"); - ret = 1; - goto init_exit; - } else if (erip->flags & ERI_SUSPENDED) { - ERI_DEBUG_MSG1(NULL, INIT_MSG, - "eri_init: erip->flags & ERI_SUSPENDED"); - ret = 1; + ASSERT(erip != NULL); + + if (erip->flags & ERI_SUSPENDED) { + ret = B_TRUE; goto init_exit; } - ERI_DEBUG_MSG1(erip, INIT_MSG, - "eri_init: Entered erip"); - mutex_enter(&erip->intrlock); eri_stop_timer(erip); /* acquire linklock */ - rw_enter(&eristruplock, RW_WRITER); mutex_enter(&erip->xmitlock); - erip->flags &= ERI_DLPI_LINKUP; - erip->wantw = 0; + erip->flags &= (ERI_DLPI_LINKUP | ERI_STARTED); + erip->wantw = B_FALSE; HSTAT(erip, inits); erip->txhung = 0; @@ -4328,15 +2310,14 @@ mutex_enter(&erip->xcvrlock); if (!param_linkup || erip->linkcheck) { if (!erip->linkcheck) - linkflags = DL_NOTE_LINK_DOWN; + linkupdate = LINK_STATE_DOWN; (void) eri_stop(erip); } if (!(erip->flags & ERI_DLPI_LINKUP) || !param_linkup) { erip->flags |= ERI_DLPI_LINKUP; eri_mif_poll(erip, MIF_POLL_STOP); (void) eri_new_xcvr(erip); - ERI_DEBUG_MSG1(erip, XCVR_MSG, - "New transceiver detected."); + ERI_DEBUG_MSG1(erip, XCVR_MSG, "New transceiver detected."); if (param_transceiver != NO_XCVR) { /* * Reset the new PHY and bring up the @@ -4349,14 +2330,14 @@ link_timeout = 0; goto done; } - if (erip->stats.link_up == ERI_LINK_UP) - linkflags |= DL_NOTE_LINK_UP; + if (erip->stats.link_up == LINK_STATE_UP) + linkupdate = LINK_STATE_UP; } else { erip->flags |= (ERI_RUNNING | ERI_INITIALIZED); param_linkup = 0; - erip->stats.link_up = ERI_LINK_DOWN; - erip->stats.link_duplex = ERI_UNKNOWN_DUPLEX; - linkflags |= DL_NOTE_LINK_DOWN; + erip->stats.link_up = LINK_STATE_DOWN; + erip->stats.link_duplex = LINK_DUPLEX_UNKNOWN; + linkupdate = LINK_STATE_DOWN; /* * Still go on and complete the MAC initialization as * xcvr might show up later. @@ -4398,47 +2379,6 @@ } /* - * Determine if promiscuous mode or multicast mode. - */ - for (sbp = eristrup; sbp; sbp = sbp->sb_nextp) { - if (sbp->sb_erip == erip) { - if (sbp->sb_flags & ERI_SALLPHYS) - erip->flags |= ERI_PROMISC; - if (sbp->sb_flags & ERI_SALLMULTI) - erip->flags |= ERI_ALLMULTI; - if (sbp->sb_flags & ERI_SMULTI) - erip->flags |= ERI_MULTICAST; - break; - } - } - - - /* - * Determine which internal loopback mode, if any - * only one internal loopback mode is set, the checking order is - * SERDES/SERIAL_LINK, PCS, and MAC - */ - for (sbp = eristrup; sbp; sbp = sbp->sb_nextp) { - if (sbp->sb_erip == erip) { - if (sbp->sb_flags & ERI_SSERLPBK) { - erip->flags |= ERI_SERLOOPBACK; - ERI_DEBUG_MSG2(erip, INIT_MSG, - "init(): flags = 0x%x\n", - erip->flags); - break; - } - - if (sbp->sb_flags & ERI_SMACLPBK) { - erip->flags |= ERI_MACLOOPBACK; - ERI_DEBUG_MSG2(erip, LOOPBACK_MSG, - "init(): flags = 0x%x\n", - erip->flags); - break; - } - } - } - - /* * BigMAC requires that we confirm that tx, rx and hash are in * quiescent state. * MAC will not reset successfully if the transceiver is not reset and @@ -4448,21 +2388,21 @@ */ if (eri_txmac_disable(erip)) { ERI_FAULT_MSG1(erip, SEVERITY_LOW, ERI_VERB_MSG, - disable_txmac_msg); + disable_txmac_msg); param_linkup = 0; /* force init again */ - erip->stats.link_up = ERI_LINK_DOWN; - erip->stats.link_duplex = ERI_UNKNOWN_DUPLEX; - linkflags |= DL_NOTE_LINK_DOWN; + erip->stats.link_up = LINK_STATE_DOWN; + erip->stats.link_duplex = LINK_DUPLEX_UNKNOWN; + linkupdate = LINK_STATE_DOWN; goto done; } if (eri_rxmac_disable(erip)) { ERI_FAULT_MSG1(erip, SEVERITY_LOW, ERI_VERB_MSG, - disable_rxmac_msg); + disable_rxmac_msg); param_linkup = 0; /* force init again */ - erip->stats.link_up = ERI_LINK_DOWN; - erip->stats.link_duplex = ERI_UNKNOWN_DUPLEX; - linkflags |= DL_NOTE_LINK_DOWN; + erip->stats.link_up = LINK_STATE_DOWN; + erip->stats.link_duplex = LINK_DUPLEX_UNKNOWN; + linkupdate = LINK_STATE_DOWN; goto done; } @@ -4500,7 +2440,7 @@ * config, txring_lo, txring_hi */ if (eri_init_txregs(erip)) - goto done; + goto done; /* * Initialize ERX Registers: * rxring_lo, rxring_hi, config, rx_blanking, @@ -4522,15 +2462,13 @@ #ifdef ERI_DONT_STRIP_CRC PUT_MACREG(rxcfg, - ((erip->flags & ERI_PROMISC ? BMAC_RXCFG_PROMIS : 0) | - (erip->flags & ERI_MULTICAST ? BMAC_RXCFG_HASH : 0) | - (erip->flags & ERI_ALLMULTI ? BMAC_RXCFG_GRPROM : 0) | + ((erip->promisc ? BMAC_RXCFG_PROMIS : 0) | + (erip->multi_refcnt ? BMAC_RXCFG_HASH : 0) | (carrier_ext ? BMAC_RXCFG_CARR_EXT : 0))); #else PUT_MACREG(rxcfg, - ((erip->flags & ERI_PROMISC ? BMAC_RXCFG_PROMIS : 0) | - (erip->flags & ERI_MULTICAST ? BMAC_RXCFG_HASH : 0) | - (erip->flags & ERI_ALLMULTI ? BMAC_RXCFG_GRPROM : 0) | + ((erip->promisc ? BMAC_RXCFG_PROMIS : 0) | + (erip->multi_refcnt ? BMAC_RXCFG_HASH : 0) | BMAC_RXCFG_STRIP_CRC | (carrier_ext ? BMAC_RXCFG_CARR_EXT : 0))); #endif @@ -4577,11 +2515,6 @@ */ if (erip->flags & ERI_MACLOOPBACK) { PUT_MACREG(xifc, GET_MACREG(xifc) | BMAC_XIFC_MIILPBK); - ERI_DEBUG_MSG1(erip, LOOPBACK_MSG, - "eri_init(): put in MAC int loopback mode\n"); - } else { - ERI_DEBUG_MSG1(erip, LOOPBACK_MSG, - "init(): internal loopback mode not set\n"); } /* @@ -4589,8 +2522,8 @@ */ ENABLE_MAC(erip); erip->flags |= (ERI_RUNNING | ERI_INITIALIZED | - ERI_TXINIT | ERI_RXINIT); - eri_wenable(erip); + ERI_TXINIT | ERI_RXINIT); + mac_tx_update(erip->mh); erip->global_reset_issued = 0; #ifdef ERI_10_10_FORCE_SPEED_WORKAROUND @@ -4602,16 +2535,16 @@ eri_unallocthings(erip); mutex_exit(&erip->xmitlock); - rw_exit(&eristruplock); eri_start_timer(erip, eri_check_link, link_timeout); mutex_exit(&erip->intrlock); - eri_send_notifications(erip, linkflags); - - ret = !(erip->flags & ERI_RUNNING); - if (ret) { + if (linkupdate != LINK_STATE_UNKNOWN) + mac_link_update(erip->mh, linkupdate); + + ret = (erip->flags & ERI_RUNNING) ? B_TRUE : B_FALSE; + if (!ret) { ERI_FAULT_MSG1(erip, SEVERITY_NONE, ERI_VERB_MSG, - "eri_init failed"); + "eri_init failed"); } init_exit: @@ -4627,14 +2560,12 @@ { ddi_dma_handle_t handle; - if (ddi_dma_alloc_handle(erip->dip, &dma_attr, - DDI_DMA_DONTWAIT, (caddr_t)0, &handle)) + if (ddi_dma_alloc_handle(erip->dip, &dma_attr, DDI_DMA_DONTWAIT, + NULL, &handle)) return (DDI_FAILURE); erip->burstsizes = ddi_dma_burstsizes(handle); ddi_dma_free_handle(&handle); - ERI_DEBUG_MSG2(erip, INIT_MSG, - "burstsize %X", erip->burstsizes); if (erip->burstsizes) return (DDI_SUCCESS); @@ -4672,7 +2603,7 @@ mutex_exit(&erip->intrlock); if (needind) - eri_notify_ind(erip, DL_NOTE_LINK_DOWN); + mac_link_update(erip->mh, LINK_STATE_DOWN); } /* @@ -4707,30 +2638,27 @@ /* * Allocate the TMD and RMD descriptors and extra for alignments. */ - size = (ERI_RPENDING * sizeof (struct rmd) - + ERI_TPENDING * sizeof (struct eri_tmd)) + ERI_GMDALIGN; + size = (ERI_RPENDING * sizeof (struct rmd) + + ERI_TPENDING * sizeof (struct eri_tmd)) + ERI_GMDALIGN; rval = ddi_dma_alloc_handle(erip->dip, &desc_dma_attr, - DDI_DMA_DONTWAIT, 0, &erip->md_h); + DDI_DMA_DONTWAIT, 0, &erip->md_h); if (rval != DDI_SUCCESS) { return (++alloc_stat); } erip->alloc_flag |= ERI_DESC_HANDLE_ALLOC; rval = ddi_dma_mem_alloc(erip->md_h, size, &erip->dev_attr, - DDI_DMA_CONSISTENT, DDI_DMA_DONTWAIT, 0, - (caddr_t *)&erip->iopbkbase, &real_len, - &erip->mdm_h); + DDI_DMA_CONSISTENT, DDI_DMA_DONTWAIT, 0, + (caddr_t *)&erip->iopbkbase, &real_len, &erip->mdm_h); if (rval != DDI_SUCCESS) { return (++alloc_stat); } erip->alloc_flag |= ERI_DESC_MEM_ALLOC; rval = ddi_dma_addr_bind_handle(erip->md_h, NULL, - (caddr_t)erip->iopbkbase, size, - DDI_DMA_RDWR | DDI_DMA_CONSISTENT, - DDI_DMA_DONTWAIT, 0, - &erip->md_c, &cookiec); + (caddr_t)erip->iopbkbase, size, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, + DDI_DMA_DONTWAIT, 0, &erip->md_c, &cookiec); if (rval != DDI_DMA_MAPPED) return (++alloc_stat); @@ -4832,27 +2760,24 @@ * So we cannot use ddi_dma_mem_alloc(, &erip->ge_dev_attr) * because we'll get little endian memory on PCI. */ - if (ddi_dma_alloc_handle(erip->dip, &desc_dma_attr, - DDI_DMA_DONTWAIT, 0, - &erip->tbuf_handle) != DDI_SUCCESS) { - ERI_FAULT_MSG1(erip, SEVERITY_HIGH, ERI_VERB_MSG, - alloc_tx_dmah_msg); - return (++alloc_stat); + if (ddi_dma_alloc_handle(erip->dip, &desc_dma_attr, DDI_DMA_DONTWAIT, + 0, &erip->tbuf_handle) != DDI_SUCCESS) { + ERI_FAULT_MSG1(erip, SEVERITY_HIGH, ERI_VERB_MSG, + alloc_tx_dmah_msg); + return (++alloc_stat); } erip->alloc_flag |= ERI_XBUFS_HANDLE_ALLOC; size = ERI_TPENDING * eri_tx_bcopy_max; erip->tbuf_kaddr = (caddr_t)kmem_alloc(size, KM_NOSLEEP); if (erip->tbuf_kaddr == NULL) { ERI_FAULT_MSG1(erip, SEVERITY_HIGH, ERI_VERB_MSG, - alloc_tx_dmah_msg); + alloc_tx_dmah_msg); return (++alloc_stat); } erip->alloc_flag |= ERI_XBUFS_KMEM_ALLOC; if (ddi_dma_addr_bind_handle(erip->tbuf_handle, NULL, - erip->tbuf_kaddr, size, - DDI_DMA_WRITE | DDI_DMA_CONSISTENT, - DDI_DMA_DONTWAIT, 0, - &dma_cookie, &cookiec) != DDI_DMA_MAPPED) { + erip->tbuf_kaddr, size, DDI_DMA_WRITE | DDI_DMA_CONSISTENT, + DDI_DMA_DONTWAIT, 0, &dma_cookie, &cookiec) != DDI_DMA_MAPPED) { return (++alloc_stat); } erip->tbuf_ioaddr = dma_cookie.dmac_address; @@ -4879,29 +2804,31 @@ * First check to see if it is our device interrupting. */ static uint_t -eri_intr(struct eri *erip) +eri_intr(caddr_t arg) { + struct eri *erip = (void *)arg; uint32_t erisbits; uint32_t mif_status; uint32_t serviced = DDI_INTR_UNCLAIMED; - uint32_t linkflags = 0; + link_state_t linkupdate = LINK_STATE_UNKNOWN; + boolean_t macupdate = B_FALSE; + mblk_t *mp; + mblk_t *head; + mblk_t **tail; + + head = NULL; + tail = &head; mutex_enter(&erip->intrlock); erisbits = GET_GLOBREG(status); - ERI_DEBUG_MSG5(erip, DIAG_MSG, - "eri_intr: start: erip %p gloregp %p status %X intmask %X", - erip, erip->globregp, erisbits, GET_GLOBREG(intmask)); /* * Check if it is only the RX_DONE interrupt, which is * the most frequent one. */ if (((erisbits & ERI_G_STATUS_RX_INT) == ERI_G_STATUS_RX_DONE) && - (erip->flags & ERI_RUNNING)) { - ERI_DEBUG_MSG5(erip, INTR_MSG, - "eri_intr:(RX_DONE)erip %p gloregp %p status %X intmask %X", - erip, erip->globregp, erisbits, GET_GLOBREG(intmask)); + (erip->flags & ERI_RUNNING)) { serviced = DDI_INTR_CLAIMED; goto rx_done_int; } @@ -4915,32 +2842,29 @@ /* Check for interesting events */ if ((erisbits & ERI_G_STATUS_INTR) == 0) { #ifdef ESTAR_WORKAROUND - uint32_t linkflags; + uint32_t linkupdate; #endif ERI_DEBUG_MSG2(erip, DIAG_MSG, - "eri_intr: Interrupt Not Claimed gsbits %X", erisbits); + "eri_intr: Interrupt Not Claimed gsbits %X", erisbits); #ifdef DEBUG noteri++; #endif - ERI_DEBUG_MSG2(erip, DIAG_MSG, - "eri_intr:MIF Config = 0x%X", - GET_MIFREG(mif_cfg)); - ERI_DEBUG_MSG2(erip, DIAG_MSG, - "eri_intr:MIF imask = 0x%X", - GET_MIFREG(mif_imask)); - ERI_DEBUG_MSG2(erip, DIAG_MSG, - "eri_intr:INT imask = 0x%X", - GET_GLOBREG(intmask)); - ERI_DEBUG_MSG2(erip, DIAG_MSG, - "eri_intr:alias %X", - GET_GLOBREG(status_alias)); + ERI_DEBUG_MSG2(erip, DIAG_MSG, "eri_intr:MIF Config = 0x%X", + GET_MIFREG(mif_cfg)); + ERI_DEBUG_MSG2(erip, DIAG_MSG, "eri_intr:MIF imask = 0x%X", + GET_MIFREG(mif_imask)); + ERI_DEBUG_MSG2(erip, DIAG_MSG, "eri_intr:INT imask = 0x%X", + GET_GLOBREG(intmask)); + ERI_DEBUG_MSG2(erip, DIAG_MSG, "eri_intr:alias %X", + GET_GLOBREG(status_alias)); #ifdef ESTAR_WORKAROUND - linkflags = eri_check_link_noind(erip); + linkupdate = eri_check_link_noind(erip); #endif mutex_exit(&erip->intrlock); #ifdef ESTAR_WORKAROUND - eri_send_notifications(erip, linkflags); + if (linkupdate != LINK_STATE_UNKNOWN) + mac_link_update(erip->mh, linkupdate); #endif return (serviced); } @@ -4949,15 +2873,12 @@ if (!(erip->flags & ERI_RUNNING)) { mutex_exit(&erip->intrlock); eri_uninit(erip); - ERI_DEBUG_MSG1(erip, INTR_MSG, - "eri_intr: eri not running"); return (serviced); } if (erisbits & ERI_G_STATUS_FATAL_ERR) { ERI_DEBUG_MSG2(erip, INTR_MSG, - "eri_intr: fatal error: erisbits = %X", - erisbits); + "eri_intr: fatal error: erisbits = %X", erisbits); (void) eri_fatal_err(erip, erisbits); eri_reinit_fatal++; @@ -4967,8 +2888,8 @@ mutex_exit(&erip->intrlock); } else { param_linkup = 0; - erip->stats.link_up = ERI_LINK_DOWN; - erip->stats.link_duplex = ERI_UNKNOWN_DUPLEX; + erip->stats.link_up = LINK_STATE_DOWN; + erip->stats.link_duplex = LINK_DUPLEX_UNKNOWN; DISABLE_MAC(erip); mutex_exit(&erip->intrlock); (void) eri_init(erip); @@ -4978,7 +2899,7 @@ if (erisbits & ERI_G_STATUS_NONFATAL_ERR) { ERI_DEBUG_MSG2(erip, INTR_MSG, - "eri_intr: non-fatal error: erisbits = %X", erisbits); + "eri_intr: non-fatal error: erisbits = %X", erisbits); (void) eri_nonfatal_err(erip, erisbits); if (erip->linkcheck) { mutex_exit(&erip->intrlock); @@ -4990,8 +2911,7 @@ if (erisbits & ERI_G_STATUS_MIF_INT) { uint16_t stat; ERI_DEBUG_MSG2(erip, XCVR_MSG, - "eri_intr:MIF Interrupt:mii_status %X", - erip->mii_status); + "eri_intr:MIF Interrupt:mii_status %X", erip->mii_status); eri_stop_timer(erip); /* acquire linklock */ mutex_enter(&erip->xmitlock); @@ -5000,16 +2920,16 @@ mif_status = GET_MIFREG(mif_bsts); eri_mif_poll(erip, MIF_POLL_STOP); ERI_DEBUG_MSG3(erip, XCVR_MSG, - "eri_intr: new MIF interrupt status %X XCVR status %X", - mif_status, erip->mii_status); + "eri_intr: new MIF interrupt status %X XCVR status %X", + mif_status, erip->mii_status); (void) eri_mii_read(erip, ERI_PHY_BMSR, &stat); - linkflags = eri_mif_check(erip, stat, stat); + linkupdate = eri_mif_check(erip, stat, stat); #else mif_status = GET_MIFREG(mif_bsts); eri_mif_poll(erip, MIF_POLL_STOP); - linkflags = eri_mif_check(erip, (uint16_t)mif_status, - (uint16_t)(mif_status >> 16)); + linkupdate = eri_mif_check(erip, (uint16_t)mif_status, + (uint16_t)(mif_status >> 16)); #endif eri_mif_poll(erip, MIF_POLL_START); mutex_exit(&erip->xcvrlock); @@ -5017,15 +2937,14 @@ if (!erip->openloop_autoneg) eri_start_timer(erip, eri_check_link, - ERI_LINKCHECK_TIMER); + ERI_LINKCHECK_TIMER); else eri_start_timer(erip, eri_check_link, - ERI_P_FAULT_TIMER); + ERI_P_FAULT_TIMER); } ERI_DEBUG_MSG2(erip, INTR_MSG, - "eri_intr:May have Read Interrupt status:status %X", - erisbits); + "eri_intr:May have Read Interrupt status:status %X", erisbits); rx_done_int: if ((erisbits & (ERI_G_STATUS_TX_INT_ME)) || @@ -5034,7 +2953,7 @@ erip->tx_completion = (uint32_t)(GET_ETXREG(tx_completion) & ETX_COMPLETION_MASK); - (void) eri_reclaim(erip, erip->tx_completion); + macupdate |= eri_reclaim(erip, erip->tx_completion); mutex_exit(&erip->xmitlock); } @@ -5050,13 +2969,13 @@ rmdp = rmdpbase + rmdi; ERI_DEBUG_MSG3(erip, INTR_MSG, - "eri_intr: packet received: rmdp = %X status %X", - rmdp, erisbits); + "eri_intr: packet received: rmdp = %X status %X", + rmdp, erisbits); /* * Sync RMD before looking at it. */ ERI_SYNCIOPB(erip, rmdp, sizeof (struct rmd), - DDI_DMA_SYNC_FORCPU); + DDI_DMA_SYNC_FORCPU); /* * Loop through each RMD. */ @@ -5064,10 +2983,15 @@ flags = GET_RMD_FLAGS(rmdp); while (((flags & ERI_RMD_OWN) == 0) && (loop_limit)) { /* process one packet */ - eri_read_dma(erip, rmdp, rmdi, flags); + mp = eri_read_dma(erip, rmdp, rmdi, flags); rmdi = (rmdi + 1) & rmdmax_mask; rmdp = rmdpbase + rmdi; + if (mp != NULL) { + *tail = mp; + tail = &mp->b_next; + } + /* * ERI RCV DMA fetches or updates four descriptors * a time. Also we don't want to update the desc. @@ -5083,8 +3007,8 @@ loop_limit = 1; } else { erip->rx_kick = - (rmdi + ERI_RPENDING - 4) & - rmdmax_mask; + (rmdi + ERI_RPENDING - 4) & + rmdmax_mask; PUT_ERXREG(rx_kick, erip->rx_kick); } } @@ -5093,15 +3017,25 @@ * Sync the next RMD before looking at it. */ ERI_SYNCIOPB(erip, rmdp, sizeof (struct rmd), - DDI_DMA_SYNC_FORCPU); + DDI_DMA_SYNC_FORCPU); flags = GET_RMD_FLAGS(rmdp); loop_limit--; } erip->rx_completion = rmdi; } + + erip->wantw = B_FALSE; + mutex_exit(&erip->intrlock); - eri_send_notifications(erip, linkflags); + if (head) + mac_rx(erip->mh, NULL, head); + + if (macupdate) + mac_tx_update(erip->mh); + + if (linkupdate != LINK_STATE_UNKNOWN) + mac_link_update(erip->mh, linkupdate); return (serviced); } @@ -5125,8 +3059,6 @@ uint32_t pci_error_int = 0; if (erisbits & ERI_G_STATUS_RX_TAG_ERR) { - ERI_DEBUG_MSG1(erip, FATAL_ERR_MSG, - "ERI RX Tag Error"); erip->rx_reset_issued = 1; HSTAT(erip, rxtag_err); } else { @@ -5138,8 +3070,6 @@ HSTAT(erip, parity_error); } else { HSTAT(erip, unknown_fatal); - ERI_DEBUG_MSG1(erip, FATAL_ERR_MSG, - "ERI Unknown fatal error"); } } @@ -5148,9 +3078,9 @@ */ if (pci_error_int && erip->pci_config_handle) { pci_status = pci_config_get16(erip->pci_config_handle, - PCI_CONF_STAT); - ERI_DEBUG_MSG2(erip, FATAL_ERR_MSG, - "Bus Error Status %x", pci_status); + PCI_CONF_STAT); + ERI_DEBUG_MSG2(erip, FATAL_ERR_MSG, "Bus Error Status %x", + pci_status); if (pci_status & PCI_DATA_PARITY_REP) HSTAT(erip, pci_data_parity_err); if (pci_status & PCI_SING_TARGET_ABORT) @@ -5166,8 +3096,8 @@ /* * clear it by writing the value that was read back. */ - pci_config_put16(erip->pci_config_handle, - PCI_CONF_STAT, pci_status); + pci_config_put16(erip->pci_config_handle, PCI_CONF_STAT, + pci_status); } } @@ -5190,60 +3120,43 @@ if (erisbits & ERI_G_STATUS_TX_MAC_INT) { txmac_sts = GET_MACREG(txsts); if (txmac_sts & BMAC_TXSTS_TX_URUN) { - ERI_DEBUG_MSG1(erip, NONFATAL_MSG, - "tx fifo underrun"); erip->linkcheck = 1; HSTAT(erip, txmac_urun); HSTAT(erip, oerrors); } if (txmac_sts & BMAC_TXSTS_MAXPKT_ERR) { - ERI_DEBUG_MSG1(erip, NONFATAL_MSG, - "tx max pkt size error"); erip->linkcheck = 1; HSTAT(erip, txmac_maxpkt_err); HSTAT(erip, oerrors); } if (txmac_sts & BMAC_TXSTS_NCC_EXP) { - ERI_DEBUG_MSG1(erip, NONFATAL_MSG, - "Normal collisions counter expired"); erip->stats.collisions += 0x10000; } if (txmac_sts & BMAC_TXSTS_ECC_EXP) { - ERI_DEBUG_MSG1(erip, NONFATAL_MSG, - "Excessive collisions counter expired"); erip->stats.excessive_coll += 0x10000; } if (txmac_sts & BMAC_TXSTS_LCC_EXP) { - ERI_DEBUG_MSG1(erip, NONFATAL_MSG, - "Late collisions counter expired"); erip->stats.late_coll += 0x10000; } if (txmac_sts & BMAC_TXSTS_FCC_EXP) { - ERI_DEBUG_MSG1(erip, NONFATAL_MSG, - "first collisions counter expired"); erip->stats.first_coll += 0x10000; } if (txmac_sts & BMAC_TXSTS_DEFER_EXP) { - ERI_DEBUG_MSG1(erip, NONFATAL_MSG, - "defer timer expired"); HSTAT(erip, defer_timer_exp); } if (txmac_sts & BMAC_TXSTS_PEAK_EXP) { - ERI_DEBUG_MSG1(erip, NONFATAL_MSG, - "peak attempts counter expired"); erip->stats.peak_attempt_cnt += 0x100; } } if (erisbits & ERI_G_STATUS_RX_NO_BUF) { - ERI_DEBUG_MSG1(erip, NONFATAL_MSG, - "rx pkt dropped/no free descriptor error"); + ERI_DEBUG_MSG1(erip, NONFATAL_MSG, "rx dropped/no free desc"); if (eri_overflow_reset) erip->linkcheck = 1; @@ -5261,8 +3174,7 @@ erip->rxfifo_wr_ptr = GET_ERXREG(rxfifo_wr_ptr); erip->rxfifo_rd_ptr = GET_ERXREG(rxfifo_rd_ptr); - ERI_DEBUG_MSG5(erip, - NONFATAL_MSG, + ERI_DEBUG_MSG5(erip, NONFATAL_MSG, "overflow intr %d: %8x wr:%2x rd:%2x", erip->check_rmac_hang, GET_MACREG(macsm), @@ -5270,7 +3182,7 @@ GET_ERXREG(rxfifo_rd_ptr)); eri_start_timer(erip, eri_check_link, - ERI_CHECK_HANG_TIMER); + ERI_CHECK_HANG_TIMER); #endif if (eri_overflow_reset) erip->linkcheck = 1; @@ -5280,29 +3192,21 @@ } if (rxmac_sts & BMAC_RXSTS_ALE_EXP) { - ERI_DEBUG_MSG1(erip, NONFATAL_MSG, - "RX Alignment Error Counter Expired"); erip->stats.rx_align_err += 0x10000; erip->stats.ierrors += 0x10000; } if (rxmac_sts & BMAC_RXSTS_CRC_EXP) { - ERI_DEBUG_MSG1(erip, NONFATAL_MSG, - "RX CRC Error Counter Expired"); erip->stats.rx_crc_err += 0x10000; erip->stats.ierrors += 0x10000; } if (rxmac_sts & BMAC_RXSTS_LEN_EXP) { - ERI_DEBUG_MSG1(erip, NONFATAL_MSG, - "RX Length Error Counter Expired"); erip->stats.rx_length_err += 0x10000; erip->stats.ierrors += 0x10000; } if (rxmac_sts & BMAC_RXSTS_CVI_EXP) { - ERI_DEBUG_MSG1(erip, NONFATAL_MSG, - "Rx Code Violation Err Count Expired"); erip->stats.rx_code_viol_err += 0x10000; erip->stats.ierrors += 0x10000; } @@ -5313,25 +3217,22 @@ macctl_sts = GET_MACREG(macctl_sts); if (macctl_sts & ERI_MCTLSTS_PAUSE_RCVD) { pause_time = ((macctl_sts & - ERI_MCTLSTS_PAUSE_TIME) >> 16); + ERI_MCTLSTS_PAUSE_TIME) >> 16); ERI_DEBUG_MSG2(erip, NONFATAL_MSG, - "PAUSE Received. pause time = %X slot_times", - pause_time); + "PAUSE Received. pause time = %X slot_times", + pause_time); HSTAT(erip, pause_rxcount); erip->stats.pause_time_count += pause_time; } if (macctl_sts & ERI_MCTLSTS_PAUSE_STATE) { - ERI_DEBUG_MSG1(erip, NONFATAL_MSG, - "Transition to PAUSE state"); HSTAT(erip, pause_oncount); + erip->stats.pausing = 1; } if (macctl_sts & ERI_MCTLSTS_NONPAUSE) { - ERI_DEBUG_MSG1(erip, NONFATAL_MSG, - "Transition to non-PAUSE state"); HSTAT(erip, pause_offcount); - + erip->stats.pausing = 0; } } @@ -5558,23 +3459,17 @@ } #endif ERI_DEBUG_MSG3(erip, FRM_MSG, - "Frame Reg :mii_read: phyad = %X reg = %X ", - phyad, regad); + "Frame Reg :mii_read: phyad = %X reg = %X ", phyad, regad); PUT_MIFREG(mif_frame, ERI_MIF_FRREAD | - (phyad << ERI_MIF_FRPHYAD_SHIFT) | - (regad << ERI_MIF_FRREGAD_SHIFT)); + (phyad << ERI_MIF_FRPHYAD_SHIFT) | + (regad << ERI_MIF_FRREGAD_SHIFT)); MIF_ERIDELAY(300, phyad, regad); frame = GET_MIFREG(mif_frame); if ((frame & ERI_MIF_FRTA0) == 0) { - ERI_DEBUG_MSG2(erip, FRM_MSG, - "MIF Read failure: data = %X", frame); return (1); } else { *datap = (uint16_t)(frame & ERI_MIF_FRDATA); - ERI_DEBUG_MSG2(erip, FRM_MSG, - "Frame Reg :mii_read: successful:data = %X ", - *datap); return (0); } @@ -5583,7 +3478,6 @@ static void eri_mii_write(struct eri *erip, uint8_t regad, uint16_t data) { - uint32_t frame; uint8_t phyad; if (!erip->frame_enable) { @@ -5593,272 +3487,30 @@ phyad = erip->phyad; - ERI_DEBUG_MSG4(erip, FRM_MSG, - "Frame Reg:eri_mii_write: phyad = %X \ - reg = %X data = %X", phyad, regad, data); - PUT_MIFREG(mif_frame, (ERI_MIF_FRWRITE | - (phyad << ERI_MIF_FRPHYAD_SHIFT) | - (regad << ERI_MIF_FRREGAD_SHIFT) | data)); + (phyad << ERI_MIF_FRPHYAD_SHIFT) | + (regad << ERI_MIF_FRREGAD_SHIFT) | data)); MIF_ERIDELAY(300, phyad, regad); - frame = GET_MIFREG(mif_frame); - if ((frame & ERI_MIF_FRTA0) == 0) { - ERI_DEBUG_MSG1(erip, MIF_MSG, - mif_write_fail_msg); - } else { - ERI_DEBUG_MSG1(erip, FRM_MSG, - "Frame Reg:eri_mii_write: successful"); - return; - } -} - -/* - * Return TRUE if the given multicast address is one - * of those that this particular Stream is interested in. - */ -static int -eri_mcmatch(struct eristr *sbp, struct ether_addr *addrp) -{ - struct ether_addr *mcbucket; - int mccount; - int i; - int mchash; - - /* - * Return FALSE if not a multicast address. - */ - if (!(addrp->ether_addr_octet[0] & 01)) - return (0); - - /* - * Check if all multicasts have been enabled for this Stream - */ - if (sbp->sb_flags & ERI_SALLMULTI) - return (1); - - /* - * Compute the hash value for the address and - * grab the bucket and the number of entries in the - * bucket. - */ - mchash = MCHASH(addrp); - mcbucket = sbp->sb_mctab[mchash]; - mccount = sbp->sb_mccount[mchash]; - - /* - * Return FALSE if no multicast addresses enabled for this Stream. - */ - if (mccount == 0) - return (0); - - /* - * Otherwise, find it in the table. - */ - if (mcbucket) - for (i = 0; i < mccount; i++) - if (!ether_cmp(addrp, &mcbucket[i])) - return (1); - return (0); + (void) GET_MIFREG(mif_frame); } -/* - * Send packet upstream. - * Assume mp->b_rptr points to ether_header. - */ -static void -eri_sendup(struct eri *erip, mblk_t *mp, struct eristr *(*acceptfunc)()) -{ - struct ether_addr *dhostp, *shostp; - struct eristr *sbp, *nsbp; - mblk_t *nmp; - uint32_t isgroupaddr; - int type; - - ERI_DEBUG_MSG1(erip, ENTER_MSG, "eri_sendup"); - dhostp = &((struct ether_header *)mp->b_rptr)->ether_dhost; - shostp = &((struct ether_header *)mp->b_rptr)->ether_shost; - type = get_ether_type(mp->b_rptr); - - isgroupaddr = dhostp->ether_addr_octet[0] & 01; - - /* - * While holding a reader lock on the linked list of streams structures, - * attempt to match the address criteria for each stream - * and pass up the raw M_DATA ("fastpath") or a DL_UNITDATA_IND. - */ - - rw_enter(&eristruplock, RW_READER); - - if ((sbp = (*acceptfunc)(eristrup, erip, type, dhostp)) == NULL) { - rw_exit(&eristruplock); - freemsg(mp); - return; - } - - /* - * Loop on matching open streams until (*acceptfunc)() returns NULL. - */ - for (; nsbp = (*acceptfunc)(sbp->sb_nextp, erip, type, dhostp); - sbp = nsbp) - if (canputnext(sbp->sb_rq)) - if (nmp = dupmsg(mp)) { - if ((sbp->sb_flags & ERI_SFAST) && - !isgroupaddr) { - nmp->b_rptr += - sizeof (struct ether_header); - putnext(sbp->sb_rq, nmp); - } else if (sbp->sb_flags & ERI_SRAW) - putnext(sbp->sb_rq, nmp); - else if ((nmp = eri_addudind(erip, nmp, shostp, - dhostp, type, isgroupaddr))) - putnext(sbp->sb_rq, nmp); - } else { - HSTAT(erip, allocbfail); - } else { - HSTAT(erip, nocanput); - } - - /* - * Do the last one. - */ - if (canputnext(sbp->sb_rq)) { - if ((sbp->sb_flags & ERI_SFAST) && !isgroupaddr) { - mp->b_rptr += sizeof (struct ether_header); - putnext(sbp->sb_rq, mp); - } else if (sbp->sb_flags & ERI_SRAW) - putnext(sbp->sb_rq, mp); - else if ((mp = eri_addudind(erip, mp, shostp, dhostp, - type, isgroupaddr))) - putnext(sbp->sb_rq, mp); - } else { - freemsg(mp); - HSTAT(erip, nocanput); - HSTAT(erip, norcvbuf); - } - - rw_exit(&eristruplock); -} - -/* - * Prefix msg with a DL_UNITDATA_IND mblk and return the new msg. - */ -static mblk_t * -eri_addudind(struct eri *erip, mblk_t *mp, struct ether_addr *shostp, - struct ether_addr *dhostp, int type, uint32_t isgroupaddr) -{ - dl_unitdata_ind_t *dludindp; - struct eridladdr *dlap; - mblk_t *nmp; - int size; - - mp->b_rptr += sizeof (struct ether_header); - - /* - * Allocate an M_PROTO mblk for the DL_UNITDATA_IND. - */ - size = sizeof (dl_unitdata_ind_t) + ERI_ADDRL + ERI_ADDRL; - if ((nmp = eri_allocb(ERI_HEADROOM + size)) == NULL) { - HSTAT(erip, allocbfail); - HSTAT(erip, ierrors); - ERI_DEBUG_MSG1(erip, RESOURCE_MSG, - "allocb failed"); - freemsg(mp); - return (NULL); - } - DB_TYPE(nmp) = M_PROTO; - nmp->b_wptr = nmp->b_datap->db_lim; - nmp->b_rptr = nmp->b_wptr - size; - - /* - * Construct a DL_UNITDATA_IND primitive. - */ - dludindp = (dl_unitdata_ind_t *)nmp->b_rptr; - dludindp->dl_primitive = DL_UNITDATA_IND; - dludindp->dl_dest_addr_length = ERI_ADDRL; - dludindp->dl_dest_addr_offset = sizeof (dl_unitdata_ind_t); - dludindp->dl_src_addr_length = ERI_ADDRL; - dludindp->dl_src_addr_offset = sizeof (dl_unitdata_ind_t) + ERI_ADDRL; - dludindp->dl_group_address = isgroupaddr; - - dlap = (struct eridladdr *)(nmp->b_rptr + sizeof (dl_unitdata_ind_t)); - ether_bcopy(dhostp, &dlap->dl_phys); - dlap->dl_sap = (uint16_t)type; - - dlap = (struct eridladdr *)(nmp->b_rptr + sizeof (dl_unitdata_ind_t) - + ERI_ADDRL); - ether_bcopy(shostp, &dlap->dl_phys); - dlap->dl_sap = (uint16_t)type; - - /* - * Link the M_PROTO and M_DATA together. - */ - nmp->b_cont = mp; - return (nmp); -} - -/* - * Test upstream destination sap and address match. - */ -static struct eristr * -eri_accept(struct eristr *sbp, struct eri *erip, int type, - struct ether_addr *addrp) -{ - t_uscalar_t sap; - uint32_t flags; - for (; sbp; sbp = sbp->sb_nextp) { - sap = sbp->sb_sap; - flags = sbp->sb_flags; - - if ((sbp->sb_erip == erip) && ERI_SAPMATCH(sap, type, flags)) - if ((ether_cmp(addrp, &erip->ouraddr) == 0) || - (ether_cmp(addrp, ðerbroadcastaddr) == 0) || - (flags & ERI_SALLPHYS) || - eri_mcmatch(sbp, addrp) || - ((addrp->ether_addr_octet[0] & 0x01) && - flags & ERI_SALLMULTI)) - return (sbp); - } - return (NULL); -} - -/* - * Test upstream destination sap and address match for ERI_SALLPHYS only. - */ -/* ARGSUSED3 */ -struct eristr * -eri_paccept(struct eristr *sbp, struct eri *erip, - int type, struct ether_addr *addrp) -{ - t_uscalar_t sap; - uint32_t flags; - - for (; sbp; sbp = sbp->sb_nextp) { - sap = sbp->sb_sap; - flags = sbp->sb_flags; - - if ((sbp->sb_erip == erip) && - ERI_SAPMATCH(sap, type, flags) && - ((flags & ERI_SALLPHYS) || - (addrp->ether_addr_octet[0] & 0x01) && - (flags & ERI_SALLMULTI))) - return (sbp); - } - return (NULL); -} - - /* <<<<<<<<<<<<<<<<< PACKET TRANSMIT FUNCTIONS >>>>>>>>>>>>>>>>>>>> */ #define ERI_CROSS_PAGE_BOUNDRY(i, size, pagesize) \ ((i & pagesize) != ((i + size) & pagesize)) -static int -eri_start(queue_t *wq, mblk_t *mp, struct eri *erip) +/* + * Send a single mblk. Returns B_TRUE if the packet is sent, or disposed of + * by freemsg. Returns B_FALSE if the packet was not sent or queued, and + * should be retried later (due to tx resource exhaustion.) + */ +static boolean_t +eri_send_msg(struct eri *erip, mblk_t *mp) { volatile struct eri_tmd *tmdp = NULL; volatile struct eri_tmd *tbasep = NULL; - mblk_t *nmp, *pmp = NULL; + mblk_t *nmp; uint32_t len = 0, len_msg = 0, xover_len = TX_STREAM_MIN; uint32_t nmblks = 0; uint32_t i, j; @@ -5867,7 +3519,7 @@ uint_t start_offset = 0; uint_t stuff_offset = 0; uint_t flags = 0; - struct ether_header *ehp; + boolean_t macupdate = B_FALSE; caddr_t ptr; uint32_t offset; @@ -5877,30 +3529,22 @@ ddi_dma_cookie_t c; if (!param_linkup) { - eri_cable_down_msg(erip); freemsg(mp); + HSTAT(erip, tnocar); HSTAT(erip, oerrors); - return (0); + return (B_TRUE); } - if (erip->flags & ERI_PROMISC) - if ((pmp = copymsg(mp)) == NULL) { /* copy now, freemsg later */ - HSTAT(erip, allocbfail); - HSTAT(erip, noxmtbuf); - } - nmp = mp; #ifdef ERI_HWCSUM - if (((struct eristr *)wq->q_ptr)->sb_flags & ERI_SCKSUM) { - hcksum_retrieve(mp, NULL, NULL, &start_offset, &stuff_offset, - NULL, NULL, &flags); - - if (flags & HCK_PARTIALCKSUM) { - start_offset += sizeof (*ehp); - stuff_offset += sizeof (*ehp); - tmdcsum = ERI_TMD_CSENABL; - } + hcksum_retrieve(mp, NULL, NULL, &start_offset, &stuff_offset, + NULL, NULL, &flags); + + if (flags & HCK_PARTIALCKSUM) { + start_offset += ETHERHEADER_SIZE; + stuff_offset += ETHERHEADER_SIZE; + tmdcsum = ERI_TMD_CSENABL; } #endif /* ERI_HWCSUM */ while (nmp != NULL) { @@ -5913,8 +3557,7 @@ /* * update MIB II statistics */ - ehp = (struct ether_header *)mp->b_rptr; - BUMP_OutNUcast(erip, ehp); + BUMP_OutNUcast(erip, mp->b_rptr); /* * ---------------------------------------------------------------------- @@ -5933,9 +3576,7 @@ HSTAT(erip, allocbfail); HSTAT(erip, noxmtbuf); freemsg(mp); - if (pmp) - freemsg(pmp); - return (1); /* bad case */ + return (B_TRUE); /* bad case */ } mcopymsg(mp, nmp->b_rptr); nmp->b_wptr = nmp->b_rptr + len_msg; @@ -5964,6 +3605,7 @@ for (j = 0; j < nmblks; j++) { /* for one or two mb cases */ + /*LINTED E_PTRDIFF_OVERFLOW*/ len = nmp->b_wptr - nmp->b_rptr; i = tmdp - tbasep; /* index */ @@ -5991,8 +3633,7 @@ len = len_msg; c.dmac_address = erip->tbuf_ioaddr + offset; (void) ddi_dma_sync(erip->tbuf_handle, - (off_t)offset, len_msg, - DDI_DMA_SYNC_FORDEV); + (off_t)offset, len_msg, DDI_DMA_SYNC_FORDEV); nmblks = 1; /* exit this for loop */ } else if ((!j) && (len < eri_tx_bcopy_max)) { /* tb-1st mb */ @@ -6003,17 +3644,16 @@ c.dmac_address = erip->tbuf_ioaddr + offset; (void) ddi_dma_sync(erip->tbuf_handle, - (off_t)offset, len, - DDI_DMA_SYNC_FORDEV); + (off_t)offset, len, DDI_DMA_SYNC_FORDEV); nmp = mp->b_cont; mp->b_cont = NULL; freeb(mp); } else if (erip->eri_dvmaxh != NULL) { /* fast DVMA */ - (void) dvma_kaddr_load(erip->eri_dvmaxh, - (caddr_t)nmp->b_rptr, len, 2 * i, &c); - (void) dvma_sync(erip->eri_dvmaxh, - 2 * i, DDI_DMA_SYNC_FORDEV); + dvma_kaddr_load(erip->eri_dvmaxh, + (caddr_t)nmp->b_rptr, len, 2 * i, &c); + dvma_sync(erip->eri_dvmaxh, + 2 * i, DDI_DMA_SYNC_FORDEV); erip->tmblkp[i] = nmp; if (!j) { @@ -6047,10 +3687,7 @@ mutex_exit(&erip->xmitlock); HSTAT(erip, noxmtbuf); - if (pmp) - freemsg(pmp); - - return (1); /* bad case */ + return (B_TRUE); /* bad case */ } erip->tmblkp[i] = nmp; @@ -6064,8 +3701,8 @@ /* first descr of packet */ if (!j) { ctrl = ERI_TMD_SOP| int_me | tmdcsum | - (start_offset << ERI_TMD_CSSTART_SHIFT) | - (stuff_offset << ERI_TMD_CSSTUFF_SHIFT); + (start_offset << ERI_TMD_CSSTART_SHIFT) | + (stuff_offset << ERI_TMD_CSSTUFF_SHIFT); } /* last descr of packet */ @@ -6075,7 +3712,7 @@ PUT_TMD(tmdp, c, len, ctrl); ERI_SYNCIOPB(erip, tmdp, sizeof (struct eri_tmd), - DDI_DMA_SYNC_FORDEV); + DDI_DMA_SYNC_FORDEV); tmdp = NEXTTMD(erip, tmdp); erip->tx_cur_cnt++; @@ -6090,25 +3727,18 @@ if (erip->tx_cur_cnt >= tx_interrupt_rate) { erip->tx_completion = (uint32_t)(GET_ETXREG(tx_completion) & ETX_COMPLETION_MASK); - (void) eri_reclaim(erip, erip->tx_completion); + macupdate |= eri_reclaim(erip, erip->tx_completion); } mutex_exit(&erip->xmitlock); - if (pmp != NULL) { /* pmp is copied at the beginning */ - if (erip->flags & (ERI_PROMISC | ERI_ALLMULTI)) { - /* will hold reader lock */ - eri_sendup(erip, pmp, eri_paccept); - } else - freemsg(pmp); - } - - return (0); + if (macupdate) + mac_tx_update(erip->mh); + + return (B_TRUE); notmds: HSTAT(erip, notmds); - erip->wantw = 1; - - (void) putbq(wq, mp); /* no qenable, avoid spinning at no-tmds */ + erip->wantw = B_TRUE; if (!erip->tx_int_me) { PUT_GLOBREG(intmask, GET_GLOBREG(intmask) & @@ -6119,21 +3749,40 @@ if (erip->tx_cur_cnt >= tx_interrupt_rate) { erip->tx_completion = (uint32_t)(GET_ETXREG(tx_completion) & ETX_COMPLETION_MASK); - (void) eri_reclaim(erip, erip->tx_completion); /* qenable */ + macupdate |= eri_reclaim(erip, erip->tx_completion); } mutex_exit(&erip->xmitlock); - if (pmp) - freemsg(pmp); - - return (1); + if (macupdate) + mac_tx_update(erip->mh); + + return (B_FALSE); +} + +static mblk_t * +eri_m_tx(void *arg, mblk_t *mp) +{ + struct eri *erip = arg; + mblk_t *next; + + while (mp != NULL) { + next = mp->b_next; + mp->b_next = NULL; + if (!eri_send_msg(erip, mp)) { + mp->b_next = next; + break; + } + mp = next; + } + + return (mp); } /* * Transmit completion reclaiming. */ -static uint_t +static boolean_t eri_reclaim(struct eri *erip, uint32_t tx_completion) { volatile struct eri_tmd *tmdp; @@ -6168,12 +3817,12 @@ if (bp) { if (erip->eri_dvmaxh) { - (void) dvma_unload(erip->eri_dvmaxh, 2 * i, - (uint_t)DONT_FLUSH); - } else - - /* dma handle case. */ + dvma_unload(erip->eri_dvmaxh, 2 * i, + (uint_t)DONT_FLUSH); + } else { + /* dma handle case. */ (void) ddi_dma_unbind_handle(erip->ndmaxh[i]); + } freeb(bp); erip->tmblkp[i] = NULL; @@ -6186,20 +3835,12 @@ erip->tcurp = tmdp; erip->tx_cur_cnt -= reclaimed; - if (reclaimed) { - if (erip->wantw) { - mutex_enter(&eriwenlock); - eri_wenable(erip); - mutex_exit(&eriwenlock); - } - } - - return (reclaimed); + return (erip->wantw && reclaimed ? B_TRUE : B_FALSE); } /* <<<<<<<<<<<<<<<<<<< PACKET RECEIVE FUNCTIONS >>>>>>>>>>>>>>>>>>> */ -static void +static mblk_t * eri_read_dma(struct eri *erip, volatile struct rmd *rmdp, int rmdi, uint64_t flags) { @@ -6210,8 +3851,7 @@ #ifdef ERI_RCV_CKSUM ushort_t sum; #endif /* ERI_RCV_CKSUM */ - - ERI_DEBUG_MSG1(erip, ENTER_MSG, "eri_read_dma"); + mblk_t *retmp = NULL; bp = erip->rmblkp[rmdi]; len = (flags & ERI_RMD_BUFSIZE) >> ERI_RMD_BUFSIZE_SHIFT; @@ -6229,25 +3869,25 @@ * (using CRC or checksum) but it would be expensive in this * routine, since it is run in interrupt context. */ - if ((flags & ERI_RMD_BAD) || (len < ETHERMIN) || (len > ETHERMAX)) { - ERI_DEBUG_MSG3(erip, CORRUPTION_MSG, - "eri_read_dma: Corrupted Packet is Recieved flags %p length %d", - flags, len); + if ((flags & ERI_RMD_BAD) || (len < ETHERMIN) || (len > ETHERMAX+4)) { + ERI_DEBUG_MSG3(erip, CORRUPTION_MSG, "eri_read_dma: " + "Corrupted Packet is Recieved flags %p length %d", + flags, len); HSTAT(erip, rx_bad_pkts); if ((flags & ERI_RMD_BAD) == 0) HSTAT(erip, ierrors); if (len < ETHERMIN) { HSTAT(erip, rx_runt); - } else if (len > ETHERMAX) { + } else if (len > ETHERMAX+4) { HSTAT(erip, rx_toolong_pkts); } HSTAT(erip, drop); UPDATE_RMD(rmdp); ERI_SYNCIOPB(erip, rmdp, sizeof (struct rmd), - DDI_DMA_SYNC_FORDEV); - return; + DDI_DMA_SYNC_FORDEV); + return (NULL); } #ifdef ERI_DONT_STRIP_CRC { @@ -6297,13 +3937,13 @@ if (len < eri_rx_bcopy_max) { if ((nbp = eri_allocb_sp(len + ERI_FSTBYTE_OFFSET))) { (void) ddi_dma_sync(erip->ndmarh[rmdi], 0, - len+ERI_FSTBYTE_OFFSET, DDI_DMA_SYNC_FORCPU); + len + ERI_FSTBYTE_OFFSET, DDI_DMA_SYNC_FORCPU); DB_TYPE(nbp) = M_DATA; bcopy(bp->b_rptr, nbp->b_rptr, - len + ERI_FSTBYTE_OFFSET); + len + ERI_FSTBYTE_OFFSET); UPDATE_RMD(rmdp); ERI_SYNCIOPB(erip, rmdp, sizeof (struct rmd), - DDI_DMA_SYNC_FORDEV); + DDI_DMA_SYNC_FORDEV); /* Add the First Byte offset to the b_rptr */ nbp->b_rptr += ERI_FSTBYTE_OFFSET; @@ -6311,59 +3951,13 @@ #ifdef ERI_RCV_CKSUM sum = ~(uint16_t)(flags & ERI_RMD_CKSUM); + /*LINTED E_PTRDIFF_OVERFLOW*/ ERI_PROCESS_READ(erip, nbp, sum); #else + /*LINTED E_PTRDIFF_OVERFLOW*/ ERI_PROCESS_READ(erip, nbp); #endif - } else { - - /* - * mblk allocation has failed. Re-use the old mblk for - * the next packet. Re-mapping is not required since - * the same mblk and dma cookie is to be used again. - */ - HSTAT(erip, ierrors); - HSTAT(erip, allocbfail); - HSTAT(erip, norcvbuf); - - UPDATE_RMD(rmdp); - ERI_SYNCIOPB(erip, rmdp, sizeof (struct rmd), - DDI_DMA_SYNC_FORDEV); - ERI_DEBUG_MSG1(erip, RESOURCE_MSG, - "allocb fail"); - } - } else { - /* Use dma unmap/map */ - if ((nbp = eri_allocb_sp(ERI_BUFSIZE))) { - /* - * How do we harden this, specially if unbind - * succeeds and then bind fails? - * If Unbind fails, we can leave without updating - * the descriptor but would it continue to work on - * next round? - */ - (void) ddi_dma_unbind_handle(erip->ndmarh[rmdi]); - (void) ddi_dma_addr_bind_handle(erip->ndmarh[rmdi], - NULL, (caddr_t)nbp->b_rptr, ERI_BUFSIZE, - DDI_DMA_READ | DDI_DMA_CONSISTENT, - DDI_DMA_DONTWAIT, 0, &c, &ccnt); - - erip->rmblkp[rmdi] = nbp; - PUT_RMD(rmdp, c); - ERI_SYNCIOPB(erip, rmdp, sizeof (struct rmd), - DDI_DMA_SYNC_FORDEV); - - /* Add the First Byte offset to the b_rptr */ - - bp->b_rptr += ERI_FSTBYTE_OFFSET; - bp->b_wptr = bp->b_rptr + len; - -#ifdef ERI_RCV_CKSUM - sum = ~(uint16_t)(flags & ERI_RMD_CKSUM); - ERI_PROCESS_READ(erip, bp, sum); -#else - ERI_PROCESS_READ(erip, bp); -#endif + retmp = nbp; } else { /* @@ -6377,165 +3971,71 @@ UPDATE_RMD(rmdp); ERI_SYNCIOPB(erip, rmdp, sizeof (struct rmd), - DDI_DMA_SYNC_FORDEV); - ERI_DEBUG_MSG1(erip, RESOURCE_MSG, - "allocb fail"); + DDI_DMA_SYNC_FORDEV); + ERI_DEBUG_MSG1(erip, RESOURCE_MSG, "allocb fail"); + } + } else { + /* Use dma unmap/map */ + if ((nbp = eri_allocb_sp(ERI_BUFSIZE))) { + /* + * How do we harden this, specially if unbind + * succeeds and then bind fails? + * If Unbind fails, we can leave without updating + * the descriptor but would it continue to work on + * next round? + */ + (void) ddi_dma_unbind_handle(erip->ndmarh[rmdi]); + (void) ddi_dma_addr_bind_handle(erip->ndmarh[rmdi], + NULL, (caddr_t)nbp->b_rptr, ERI_BUFSIZE, + DDI_DMA_READ | DDI_DMA_CONSISTENT, + DDI_DMA_DONTWAIT, 0, &c, &ccnt); + + erip->rmblkp[rmdi] = nbp; + PUT_RMD(rmdp, c); + ERI_SYNCIOPB(erip, rmdp, sizeof (struct rmd), + DDI_DMA_SYNC_FORDEV); + + /* Add the First Byte offset to the b_rptr */ + + bp->b_rptr += ERI_FSTBYTE_OFFSET; + bp->b_wptr = bp->b_rptr + len; + +#ifdef ERI_RCV_CKSUM + sum = ~(uint16_t)(flags & ERI_RMD_CKSUM); + /*LINTED E_PTRDIFF_OVERFLOW*/ + ERI_PROCESS_READ(erip, bp, sum); +#else + /*LINTED E_PTRDIFF_OVERFLOW*/ + ERI_PROCESS_READ(erip, bp); +#endif + retmp = bp; + } else { + + /* + * mblk allocation has failed. Re-use the old mblk for + * the next packet. Re-mapping is not required since + * the same mblk and dma cookie is to be used again. + */ + HSTAT(erip, ierrors); + HSTAT(erip, allocbfail); + HSTAT(erip, norcvbuf); + + UPDATE_RMD(rmdp); + ERI_SYNCIOPB(erip, rmdp, sizeof (struct rmd), + DDI_DMA_SYNC_FORDEV); + ERI_DEBUG_MSG1(erip, RESOURCE_MSG, "allocb fail"); } } + + return (retmp); } -#ifdef ERI_SERVICE_ROUTINE -static int -eri_rsrv(queue_t *q) -{ - mblk_t *mp; - struct eristr *sbp = (struct eristr *)q->q_ptr; - struct eri *erip; - struct ether_header *ehp; - t_uscalar_t type; - int len; - - /* - * First check if the stream is still there. - * If the stream is detached free all the mblks - */ - erip = sbp->sb_erip; - if (erip == NULL) { - while (mp = getq(q)) { - mp->b_wptr = mp->b_rptr; - freemsg(mp); - } - return (-1); - } - - while (mp = getq(q)) { - len = mp->b_wptr - mp->b_rptr; - if ((len < 0x3c) || (len > 0x5ea)) { - erip->drop++; - erip->ierrors++; - - ERI_DEBUG_MSG2(erip, CORRUPTION_MSG, - "eri_rsrv: Illegal Size Recieved len %x ", len); - - mp->b_wptr = mp->b_rptr; - freemsg(mp); - continue; - } - ehp = (struct ether_header *)mp->b_rptr; - type = get_ether_type(ehp); - /* - * ERI 1.0 has an address filtering bug in which - * it doesn't do any filtering for the last byte of - * the destination MAC address. Thus packets which - * are not intended for us can go thu. Here we filter - * out these packets. This bug will be fixed in the - * next Spin of the ERI ASIC. - */ - -#ifdef ERI_MAC_ADDR_FLTR_BUG - if (INVALID_MAC_ADDRESS(erip, ehp)) { - erip->drop++; - erip->ierrors++; - ERI_DEBUG_MSG1(erip, CORRUPTION_MSG, - "Host/Destination MAC address mismatch "); - mp->b_wptr = mp->b_rptr; - freemsg(mp); - continue; - } -#endif - /* - * update MIB II statistics - */ - HSTAT(erip, ipackets64); - HSTATN(erip, rbytes64, len); - - if ((type == ETHERTYPE_IPV4) && (IS_NOT_MULTICAST(ehp))) { - mp->b_rptr += sizeof (struct ether_header); -#ifdef ERI_RCV_CKSUM - if ((sbp->sb_flags & ERI_SCKSUM) && - (sbp->sb_flags & ERI_SFAST)) { - mp->b_ick_flag = ICK_VALID; - mp->b_ick_start = mp->b_rptr + - ERI_IPHDR_OFFSET; - mp->b_ick_end = mp->b_wptr; - } -#endif /* ERI_RCV_CKSUM */ - if (canputnext(q)) - (void) putnext(q, mp); - else { - freemsg(mp); - HSTAT(erip, nocanput); - HSTAT(erip, ierrors); - } - - } else if ((type == ETHERTYPE_IPV6) && - IS_NOT_MULTICAST(ehp)) { - mp->b_rptr += sizeof (struct ether_header); -#ifdef ERI_RCV_CKSUM - if ((sbp->sb_flags & ERI_SCKSUM) && - (sbp->sb_flags & ERI_SFAST)) { - mp->b_ick_flag = ICK_VALID; - mp->b_ick_start = mp->b_rptr + - ERI_IPHDR_OFFSET; - mp->b_ick_end = mp->b_wptr; - } -#endif /* ERI_RCV_CKSUM */ - if (canputnext(q)) - (void) putnext(q, mp); - else { - freemsg(mp); - HSTAT(erip, nocanput); - HSTAT(erip, ierrors); - } - } else { - - /* - * Strip the PADs for 802.3 - */ - if (type <= ETHERMTU) - mp->b_wptr = mp->b_rptr - + sizeof (struct ether_header) + type; - BUMP_InNUcast(erip, ehp); - - eri_sendup(erip, mp, eri_accept); - } - } - return (0); -} - -#endif /* ERI_SERVICE_ROUTINE */ - - #define LINK_STAT_DISPLAY_TIME 20 -static void -eri_cable_down_msg(struct eri *erip) -{ - time_t now = gethrestime_sec(); - - if ((erip->linksts_msg) && - ((now - erip->msg_time) > LINK_STAT_DISPLAY_TIME)) { - ERI_FAULT_MSG1(erip, SEVERITY_LOW, ERI_CON_MSG, - link_down_msg); - erip->msg_time = now; - } -} - static int eri_init_xfer_params(struct eri *erip) { - int prop_len = sizeof (int); int i; - int ipg1_conf, ipg2_conf; - int use_int_xcvr_conf, pace_count_conf; - int autoneg_conf; - int anar_100T4_conf; - int anar_100fdx_conf, anar_100hdx_conf; - int anar_10fdx_conf, anar_10hdx_conf; - int ipg0_conf, lance_mode_conf; - int intr_blank_time_conf, intr_blank_packets_conf; - int anar_pauseTX_conf, anar_pauseRX_conf; - int select_link_conf, default_link_conf; dev_info_t *dip; dip = erip->dip; @@ -6543,8 +4043,6 @@ for (i = 0; i < A_CNT(param_arr); i++) erip->param_arr[i] = param_arr[i]; - param_device = erip->instance; - erip->xmit_dma_mode = 0; erip->rcv_dma_mode = 0; erip->mifpoll_enable = mifpoll_enable; @@ -6552,13 +4050,10 @@ erip->frame_enable = 1; erip->ngu_enable = ngu_enable; - for (i = 0; i < A_CNT(param_arr); i++) - erip->param_display[i] = param_display_mii[i]; - if (!erip->g_nd && !eri_param_register(erip, erip->param_arr, A_CNT(param_arr))) { ERI_FAULT_MSG1(erip, SEVERITY_LOW, ERI_VERB_MSG, - param_reg_fail_msg); + param_reg_fail_msg); return (-1); } @@ -6567,26 +4062,7 @@ * Get the values from the global variables first. * Use the MASK to limit the value to allowed maximum. */ - param_ipg1 = ipg1 & ERI_MASK_8BIT; - param_ipg2 = ipg2 & ERI_MASK_8BIT; - param_use_intphy = use_int_xcvr & ERI_MASK_1BIT; - param_pace_count = pace_size & ERI_MASK_8BIT; - param_autoneg = adv_autoneg_cap; - param_anar_100T4 = adv_100T4_cap; - param_anar_100fdx = adv_100fdx_cap; - param_anar_100hdx = adv_100hdx_cap; - param_anar_10fdx = adv_10fdx_cap; - param_anar_10hdx = adv_10hdx_cap; - param_ipg0 = ipg0 & ERI_MASK_8BIT; - param_intr_blank_time = intr_blank_time & ERI_MASK_8BIT; - param_intr_blank_packets = intr_blank_packets & ERI_MASK_8BIT; - param_lance_mode = lance_mode & ERI_MASK_1BIT; - - param_select_link = select_link & ERI_MASK_1BIT; - param_default_link = default_link & ERI_MASK_1BIT; - - param_anar_asm_dir = adv_pauseTX_cap; - param_anar_pause = adv_pauseRX_cap; + param_transceiver = NO_XCVR; /* @@ -6594,11 +4070,8 @@ * property "transfer-speed". This may be done in OBP by using the command * "apply transfer-speed=<speed> <device>". The speed may be either 10 or 100. */ - if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, - "transfer-speed", (caddr_t)&i, &prop_len) - == DDI_PROP_SUCCESS) { - ERI_DEBUG_MSG2(erip, PROP_MSG, - "eri_init_xfer_params: transfer-speed property = %X", i); + i = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, "transfer-speed", 0); + if (i != 0) { param_autoneg = 0; /* force speed */ param_anar_100T4 = 0; param_anar_10fdx = 0; @@ -6617,156 +4090,78 @@ /* * Get the parameter values configured in .conf file. */ - if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "ipg1", - (caddr_t)&ipg1_conf, &prop_len) - == DDI_PROP_SUCCESS) { - ERI_DEBUG_MSG2(erip, PROP_MSG, - "eri_init_xfer_params: ipg1 property %X", ipg1_conf); - param_ipg1 = ipg1_conf & ERI_MASK_8BIT; - } - if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "ipg2", - (caddr_t)&ipg2_conf, &prop_len) - == DDI_PROP_SUCCESS) { - param_ipg2 = ipg2_conf & ERI_MASK_8BIT; - } - if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "use_int_xcvr", - (caddr_t)&use_int_xcvr_conf, &prop_len) - == DDI_PROP_SUCCESS) { - param_use_intphy = use_int_xcvr_conf & ERI_MASK_1BIT; - } - if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "pace_size", - (caddr_t)&pace_count_conf, &prop_len) - == DDI_PROP_SUCCESS) { - param_pace_count = pace_count_conf & ERI_MASK_8BIT; - } - if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "adv_autoneg_cap", - (caddr_t)&autoneg_conf, &prop_len) - == DDI_PROP_SUCCESS) { - param_autoneg = autoneg_conf & ERI_MASK_1BIT; - } - if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "adv_100T4_cap", - (caddr_t)&anar_100T4_conf, &prop_len) - == DDI_PROP_SUCCESS) { - param_anar_100T4 = anar_100T4_conf & ERI_MASK_1BIT; - } - if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "adv_100fdx_cap", - (caddr_t)&anar_100fdx_conf, &prop_len) - == DDI_PROP_SUCCESS) { - param_anar_100fdx = anar_100fdx_conf & ERI_MASK_1BIT; - } - if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "adv_100hdx_cap", - (caddr_t)&anar_100hdx_conf, &prop_len) - == DDI_PROP_SUCCESS) { - param_anar_100hdx = anar_100hdx_conf & ERI_MASK_1BIT; - } - if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "adv_10fdx_cap", - (caddr_t)&anar_10fdx_conf, &prop_len) - == DDI_PROP_SUCCESS) { - param_anar_10fdx = anar_10fdx_conf & ERI_MASK_1BIT; - } - if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "adv_10hdx_cap", - (caddr_t)&anar_10hdx_conf, &prop_len) - == DDI_PROP_SUCCESS) { - param_anar_10hdx = anar_10hdx_conf & ERI_MASK_1BIT; - } - if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "ipg0", - (caddr_t)&ipg0_conf, &prop_len) - == DDI_PROP_SUCCESS) { - param_ipg0 = ipg0_conf & ERI_MASK_8BIT; - } - if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "intr_blank_time", - (caddr_t)&intr_blank_time_conf, &prop_len) - == DDI_PROP_SUCCESS) { - param_intr_blank_time = intr_blank_time_conf & ERI_MASK_8BIT; - } - if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "intr_blank_packets", - (caddr_t)&intr_blank_packets_conf, &prop_len) - == DDI_PROP_SUCCESS) { - param_intr_blank_packets = - intr_blank_packets_conf & ERI_MASK_8BIT; - } - if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "lance_mode", - (caddr_t)&lance_mode_conf, &prop_len) - == DDI_PROP_SUCCESS) { - param_lance_mode = lance_mode_conf & ERI_MASK_1BIT; - } - if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "select_link", - (caddr_t)&select_link_conf, &prop_len) - == DDI_PROP_SUCCESS) { - param_select_link = select_link_conf & ERI_MASK_1BIT; - } - if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "default_link", - (caddr_t)&default_link_conf, &prop_len) - == DDI_PROP_SUCCESS) { - param_default_link = default_link_conf & ERI_MASK_1BIT; - } - if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "adv_asm_dir_cap", - (caddr_t)&anar_pauseTX_conf, &prop_len) - == DDI_PROP_SUCCESS) { - param_anar_asm_dir = anar_pauseTX_conf & ERI_MASK_1BIT; - } - if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "adv_pause_cap", - (caddr_t)&anar_pauseRX_conf, &prop_len) - == DDI_PROP_SUCCESS) { - param_anar_pause = anar_pauseRX_conf & ERI_MASK_1BIT; - } + param_ipg1 = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, "ipg1", ipg1) & + ERI_MASK_8BIT; + + param_ipg2 = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, "ipg2", ipg2) & + ERI_MASK_8BIT; + + param_use_intphy = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, + "use_int_xcvr", use_int_xcvr) & ERI_MASK_1BIT; + + param_use_intphy = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, + "pace_size", pace_size) & ERI_MASK_8BIT; + + param_autoneg = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, + "adv_autoneg_cap", adv_autoneg_cap) & ERI_MASK_1BIT; + + param_autoneg = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, + "adv_autoneg_cap", adv_autoneg_cap) & ERI_MASK_1BIT; + + param_anar_100T4 = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, + "adv_100T4_cap", adv_100T4_cap) & ERI_MASK_1BIT; + + param_anar_100fdx = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, + "adv_100fdx_cap", adv_100fdx_cap) & ERI_MASK_1BIT; + + param_anar_100hdx = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, + "adv_100hdx_cap", adv_100hdx_cap) & ERI_MASK_1BIT; + + param_anar_10fdx = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, + "adv_10fdx_cap", adv_10fdx_cap) & ERI_MASK_1BIT; + + param_anar_10hdx = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, + "adv_10hdx_cap", adv_10hdx_cap) & ERI_MASK_1BIT; + + param_ipg0 = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, "ipg0", ipg0) & + ERI_MASK_8BIT; + + param_intr_blank_time = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, + "intr_blank_time", intr_blank_time) & ERI_MASK_8BIT; + + param_intr_blank_packets = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, + "intr_blank_packets", intr_blank_packets) & ERI_MASK_8BIT; + + param_lance_mode = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, + "lance_mode", lance_mode) & ERI_MASK_1BIT; + + param_select_link = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, + "select_link", select_link) & ERI_MASK_1BIT; + + param_default_link = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, + "default_link", default_link) & ERI_MASK_1BIT; + + param_anar_asm_dir = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, + "adv_asm_dir_cap", adv_pauseTX_cap) & ERI_MASK_1BIT; + + param_anar_pause = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, + "adv_pause_cap", adv_pauseRX_cap) & ERI_MASK_1BIT; if (link_pulse_disabled) erip->link_pulse_disabled = 1; - else if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, - "link-pulse-disabled", (caddr_t)&i, &prop_len) - == DDI_PROP_SUCCESS) { - ERI_DEBUG_MSG1(erip, PROP_MSG, - "eri_init_xfer_params: dis link-pulse prop."); + if (ddi_prop_exists(DDI_DEV_T_ANY, dip, 0, "link-pulse-disabled")) erip->link_pulse_disabled = 1; - } + eri_statinit(erip); return (0); } -static struct eri * -eri_set_ppa(struct eristr *sbp, queue_t *wq) +static void +eri_process_ndd_ioctl(struct eri *erip, queue_t *wq, mblk_t *mp, int cmd) { - struct eri *erip = NULL; - int instance; - - if (sbp->sb_erip) /* ppa has been selected */ - return (sbp->sb_erip); - - instance = device; - if (device == -1) { /* select the first one found */ - mutex_enter(&erilock); - if (eriup) - instance = eriup->instance; - mutex_exit(&erilock); - } - if (instance == -1 || qassociate(wq, instance) != 0) { - return (NULL); - } - - mutex_enter(&erilock); - for (erip = eriup; erip; erip = erip->nextp) - if (instance == erip->instance) - break; - ASSERT(erip != NULL); - mutex_exit(&erilock); - - sbp->sb_erip = erip; - return (erip); -} - -static void -eri_process_ndd_ioctl(queue_t *wq, mblk_t *mp, int cmd) -{ - - struct eristr *sbp = (struct eristr *)wq->q_ptr; - struct eri *erip = NULL; - struct eri *erip1 = NULL; uint32_t old_ipg1, old_ipg2, old_use_int_xcvr, old_autoneg; - int32_t old_device; - int32_t new_device; uint32_t old_100T4; uint32_t old_100fdx, old_100hdx, old_10fdx, old_10hdx; uint32_t old_ipg0, old_lance_mode; @@ -6774,19 +4169,9 @@ uint32_t old_asm_dir, old_pause; uint32_t old_select_link, old_default_link; - erip = eri_set_ppa(sbp, wq); - - if (erip == NULL) { /* no device present */ - miocnak(wq, mp, 0, EINVAL); - return; - } - switch (cmd) { case ERI_ND_GET: - ERI_DEBUG_MSG1(erip, NDD_MSG, - "eri_process_ndd_ioctl:ND_GET"); - mutex_enter(&erilock); old_autoneg = param_autoneg; old_100T4 = param_anar_100T4; old_100fdx = param_anar_100fdx; @@ -6814,9 +4199,6 @@ param_anar_10hdx = old_10hdx; param_anar_asm_dir = old_asm_dir; param_anar_pause = old_pause; - mutex_exit(&erilock); - ERI_DEBUG_MSG1(erip, NDD_MSG, - "ndd_ioctl: _nd_getset nak"); miocnak(wq, mp, 0, EINVAL); return; } @@ -6829,16 +4211,10 @@ param_anar_asm_dir = old_asm_dir; param_anar_pause = old_pause; - mutex_exit(&erilock); - ERI_DEBUG_MSG1(erip, NDD_MSG, - "ndd_ioctl: _nd_getset ack"); qreply(wq, mp); break; case ERI_ND_SET: - ERI_DEBUG_MSG1(erip, NDD_MSG, - "eri_process_ndd_ioctl:ND_SET"); - old_device = param_device; old_ipg0 = param_ipg0; old_intr_blank_time = param_intr_blank_time; old_intr_blank_packets = param_intr_blank_packets; @@ -6860,57 +4236,29 @@ old_select_link = param_select_link; old_default_link = param_default_link; - mutex_enter(&erilock); if (!eri_nd_getset(wq, erip->g_nd, mp)) { param_autoneg = old_autoneg; - mutex_exit(&erilock); miocnak(wq, mp, 0, EINVAL); return; } - mutex_exit(&erilock); - - if (old_device != param_device) { - new_device = param_device; - param_device = old_device; - param_autoneg = old_autoneg; - if (new_device != -1 && - qassociate(wq, new_device) == 0) { - mutex_enter(&erilock); - for (erip1 = eriup; erip1; erip1 = erip1->nextp) - if (new_device == erip1->instance) - break; - mutex_exit(&erilock); - ASSERT(erip1 != NULL); - } - - if (erip1 == NULL) { - miocnak(wq, mp, 0, EINVAL); - return; - } - device = new_device; - sbp->sb_erip = erip1; - qreply(wq, mp); - return; - } qreply(wq, mp); if (param_autoneg != 0xff) { ERI_DEBUG_MSG2(erip, NDD_MSG, - "ndd_ioctl: new param_autoneg %d", - param_autoneg); + "ndd_ioctl: new param_autoneg %d", param_autoneg); param_linkup = 0; - erip->stats.link_up = ERI_LINK_DOWN; - erip->stats.link_duplex = ERI_UNKNOWN_DUPLEX; + erip->stats.link_up = LINK_STATE_DOWN; + erip->stats.link_duplex = LINK_DUPLEX_UNKNOWN; (void) eri_init(erip); } else { param_autoneg = old_autoneg; if ((old_use_int_xcvr != param_use_intphy) || - (old_default_link != param_default_link) || - (old_select_link != param_select_link)) { + (old_default_link != param_default_link) || + (old_select_link != param_select_link)) { param_linkup = 0; - erip->stats.link_up = ERI_LINK_DOWN; - erip->stats.link_duplex = ERI_UNKNOWN_DUPLEX; + erip->stats.link_up = LINK_STATE_DOWN; + erip->stats.link_duplex = LINK_DUPLEX_UNKNOWN; (void) eri_init(erip); } else if ((old_ipg1 != param_ipg1) || (old_ipg2 != param_ipg2) || @@ -6918,16 +4266,14 @@ (old_intr_blank_time != param_intr_blank_time) || (old_intr_blank_packets != param_intr_blank_packets) || - (old_lance_mode != param_lance_mode)) { + (old_lance_mode != param_lance_mode)) { param_linkup = 0; - erip->stats.link_up = ERI_LINK_DOWN; - erip->stats.link_duplex = ERI_UNKNOWN_DUPLEX; + erip->stats.link_up = LINK_STATE_DOWN; + erip->stats.link_duplex = LINK_DUPLEX_UNKNOWN; (void) eri_init(erip); } } break; - default: - break; } } @@ -6938,10 +4284,13 @@ struct eri *erip; struct erikstat *erikp; struct stats *esp; + boolean_t macupdate = B_FALSE; erip = (struct eri *)ksp->ks_private; erikp = (struct erikstat *)ksp->ks_data; + if (rw != KSTAT_READ) + return (EACCES); /* * Update all the stats by reading all the counter registers. * Counter register stats are not updated till they overflow @@ -6951,207 +4300,57 @@ mutex_enter(&erip->xmitlock); if ((erip->flags & ERI_RUNNING) && (erip->flags & ERI_TXINIT)) { erip->tx_completion = - GET_ETXREG(tx_completion) & ETX_COMPLETION_MASK; - (void) eri_reclaim(erip, erip->tx_completion); + GET_ETXREG(tx_completion) & ETX_COMPLETION_MASK; + macupdate |= eri_reclaim(erip, erip->tx_completion); } mutex_exit(&erip->xmitlock); + if (macupdate) + mac_tx_update(erip->mh); eri_savecntrs(erip); esp = &erip->stats; - if (rw == KSTAT_WRITE) { - esp->ipackets64 = erikp->erik_ipackets64.value.ull; - esp->ierrors = erikp->erik_ierrors.value.ul; - esp->opackets64 = erikp->erik_opackets64.value.ull; - esp->oerrors = erikp->erik_oerrors.value.ul; - - /* - * MIB II kstat variables - */ - esp->rbytes64 = erikp->erik_rbytes64.value.ull; - esp->obytes64 = erikp->erik_obytes64.value.ull; - esp->multircv = erikp->erik_multircv.value.ul; - esp->multixmt = erikp->erik_multixmt.value.ul; - esp->brdcstrcv = erikp->erik_brdcstrcv.value.ul; - esp->brdcstxmt = erikp->erik_brdcstxmt.value.ul; - esp->norcvbuf = erikp->erik_norcvbuf.value.ul; - esp->noxmtbuf = erikp->erik_noxmtbuf.value.ul; - -#ifdef kstat - esp->ifspeed = erikp->erik_ifspeed.value.ull; - esp->txmac_urun = erikp->erik_txmac_urun.value.ul; - esp->txmac_maxpkt_err = - erikp->erik_txmac_maxpkt_err.value.ul; - - esp->excessive_coll = erikp->erik_excessive_coll.value.ul; - esp->late_coll = erikp->erik_late_coll.value.ul; - esp->first_coll = erikp->erik_first_coll.value.ul; - esp->defer_timer_exp = - erikp->erik_defer_timer_exp.value.ul; - - esp->peak_attempt_cnt = - erikp->erik_peak_attempt_cnt.value.ul; - esp->tx_hang = erikp->erik_tx_hang.value.ul; - - esp->rx_corr = erikp->erik_rx_corr.value.ul; - esp->no_free_rx_desc = - erikp->erik_no_free_rx_desc.value.ul; - - esp->rx_overflow = erikp->erik_rx_overflow.value.ul; - esp->rx_hang = erikp->erik_rx_hang.value.ul; - esp->rx_align_err = erikp->erik_rx_align_err.value.ul; - esp->rx_crc_err = erikp->erik_rx_crc_err.value.ul; - esp->rx_length_err = erikp->erik_rx_length_err.value.ul; - esp->rx_code_viol_err = - erikp->erik_rx_code_viol_err.value.ul; - - esp->pause_rxcount = erikp->erik_pause_rxcount.value.ul; - esp->pause_oncount = erikp->erik_pause_oncount.value.ul; - esp->pause_offcount = erikp->erik_pause_offcount.value.ul; - esp->pause_time_count = - erikp->erik_pause_time_count.value.ul; - - esp->inits = erikp->erik_inits.value.ul; - esp->rx_inits = erikp->erik_rx_inits.value.ul; - esp->tx_inits = erikp->erik_tx_inits.value.ul; - esp->tnocar = erikp->erik_tnocar.value.ul; - esp->jab = erikp->erik_jab.value.ul; - esp->notmds = erikp->erik_notmds.value.ul; - esp->nocanput = erikp->erik_nocanput.value.ul; - esp->allocbfail = erikp->erik_allocbfail.value.ul; - esp->drop = erikp->erik_drop.value.ul; - esp->rx_bad_pkts = erikp->erik_rx_bad_pkts.value.ul; - esp->rx_runt = erikp->erik_rx_runt.value.ul; - esp->rx_toolong_pkts = erikp->erik_rx_toolong_pkts.value.ul; - - esp->rxtag_err = erikp->erik_rxtag_err.value.ul; - - esp->parity_error = erikp->erik_parity_error.value.ul; - - esp->eri_pci_error_int = erikp->erik_pci_error_int.value.ul; - esp->unknown_fatal = erikp->erik_unknown_fatal.value.ul; - esp->pci_data_parity_err - = erikp->erik_pci_data_parity_err.value.ul; - esp->pci_signal_target_abort - = erikp->erik_pci_signal_target_abort.value.ul; - esp->pci_rcvd_target_abort - = erikp->erik_pci_rcvd_target_abort.value.ul; - esp->pci_rcvd_master_abort - = erikp->erik_pci_rcvd_master_abort.value.ul; - esp->pci_signal_system_err - = erikp->erik_pci_signal_system_err.value.ul; - esp->pci_det_parity_err - = erikp->erik_pci_det_parity_err.value.ul; - - esp->pmcap = erikp->erik_pmcap.value.ul; - - esp->link_up = erikp->erik_link_up.value.ul; - - esp->link_duplex = erikp->erik_link_duplex.value.ul; - -#endif /* kstat */ - return (0); - } else { - erikp->erik_ipackets64.value.ull = esp->ipackets64; - erikp->erik_ipackets.value.ul = esp->ipackets64; - erikp->erik_ierrors.value.ul = esp->ierrors; - erikp->erik_opackets64.value.ull = esp->opackets64; - erikp->erik_opackets.value.ul = esp->opackets64; - erikp->erik_oerrors.value.ul = esp->oerrors; - erikp->erik_collisions.value.ul = esp->collisions; - erikp->erik_ifspeed.value.ull = esp->ifspeed * 1000000ULL; - - /* - * MIB II kstat variables - */ - erikp->erik_rbytes64.value.ull = esp->rbytes64; - erikp->erik_rbytes.value.ul = esp->rbytes64; - erikp->erik_obytes64.value.ull = esp->obytes64; - erikp->erik_obytes.value.ul = esp->obytes64; - - erikp->erik_multircv.value.ul = esp->multircv; - erikp->erik_multixmt.value.ul = esp->multixmt; - erikp->erik_brdcstrcv.value.ul = esp->brdcstrcv; - erikp->erik_brdcstxmt.value.ul = esp->brdcstxmt; - erikp->erik_norcvbuf.value.ul = esp->norcvbuf; - erikp->erik_noxmtbuf.value.ul = esp->noxmtbuf; - - erikp->erik_txmac_urun.value.ul = esp->txmac_urun; - erikp->erik_txmac_maxpkt_err.value.ul - = esp->txmac_maxpkt_err; - erikp->erik_excessive_coll.value.ul - = esp->excessive_coll; - erikp->erik_late_coll.value.ul = esp->late_coll; - erikp->erik_first_coll.value.ul = esp->first_coll; - erikp->erik_defer_timer_exp.value.ul - = esp->defer_timer_exp; - erikp->erik_peak_attempt_cnt.value.ul - = esp->peak_attempt_cnt; - erikp->erik_tx_hang.value.ul = esp->tx_hang; - - erikp->erik_rx_corr.value.ul = esp->rx_corr; - erikp->erik_no_free_rx_desc.value.ul - = esp->no_free_rx_desc; - - erikp->erik_rx_overflow.value.ul = esp->rx_overflow; - erikp->erik_rx_hang.value.ul = esp->rx_hang; - erikp->erik_rx_align_err.value.ul = esp->rx_align_err; - erikp->erik_rx_crc_err.value.ul = esp->rx_crc_err; - erikp->erik_rx_length_err.value.ul - = esp->rx_length_err; - erikp->erik_rx_code_viol_err.value.ul - = esp->rx_code_viol_err; - erikp->erik_pause_rxcount.value.ul - = esp->pause_rxcount; - erikp->erik_pause_oncount.value.ul - = esp->pause_oncount; - erikp->erik_pause_offcount.value.ul - = esp->pause_offcount; - erikp->erik_pause_time_count.value.ul - = esp->pause_time_count; - - erikp->erik_inits.value.ul = esp->inits; - erikp->erik_tnocar.value.ul = esp->tnocar; - erikp->erik_jab.value.ul = esp->jab; - erikp->erik_notmds.value.ul = esp->notmds; - erikp->erik_nocanput.value.ul = esp->nocanput; - erikp->erik_allocbfail.value.ul = esp->allocbfail; - erikp->erik_drop.value.ul = esp->drop; - erikp->erik_rx_bad_pkts.value.ul = esp->rx_bad_pkts; - erikp->erik_rx_runt.value.ul = esp->rx_runt; - erikp->erik_rx_toolong_pkts.value.ul - = esp->rx_toolong_pkts; - erikp->erik_rx_inits.value.ul - = esp->rx_inits; - erikp->erik_tx_inits.value.ul - = esp->tx_inits; - - erikp->erik_rxtag_err.value.ul = esp->rxtag_err; - - erikp->erik_parity_error.value.ul = esp->parity_error; - - erikp->erik_pci_error_int.value.ul = esp->pci_error_int; - erikp->erik_unknown_fatal.value.ul = esp->unknown_fatal; - erikp->erik_pci_data_parity_err.value.ul - = esp->pci_data_parity_err; - erikp->erik_pci_signal_target_abort.value.ul - = esp->pci_signal_target_abort; - erikp->erik_pci_rcvd_target_abort.value.ul - = esp->pci_rcvd_target_abort; - erikp->erik_pci_rcvd_master_abort.value.ul - = esp->pci_rcvd_master_abort; - erikp->erik_pci_signal_system_err.value.ul - = esp->pci_signal_system_err; - erikp->erik_pci_det_parity_err.value.ul - = esp->pci_det_parity_err; - - erikp->erik_pmcap.value.ul = esp->pmcap; - - erikp->erik_link_up.value.ul = esp->link_up; - - erikp->erik_link_duplex.value.ul = esp->link_duplex; - } + erikp->erik_txmac_maxpkt_err.value.ul = esp->txmac_maxpkt_err; + erikp->erik_defer_timer_exp.value.ul = esp->defer_timer_exp; + erikp->erik_peak_attempt_cnt.value.ul = esp->peak_attempt_cnt; + erikp->erik_tx_hang.value.ul = esp->tx_hang; + + erikp->erik_no_free_rx_desc.value.ul = esp->no_free_rx_desc; + + erikp->erik_rx_hang.value.ul = esp->rx_hang; + erikp->erik_rx_length_err.value.ul = esp->rx_length_err; + erikp->erik_rx_code_viol_err.value.ul = esp->rx_code_viol_err; + erikp->erik_pause_rxcount.value.ul = esp->pause_rxcount; + erikp->erik_pause_oncount.value.ul = esp->pause_oncount; + erikp->erik_pause_offcount.value.ul = esp->pause_offcount; + erikp->erik_pause_time_count.value.ul = esp->pause_time_count; + + erikp->erik_inits.value.ul = esp->inits; + erikp->erik_jab.value.ul = esp->jab; + erikp->erik_notmds.value.ul = esp->notmds; + erikp->erik_allocbfail.value.ul = esp->allocbfail; + erikp->erik_drop.value.ul = esp->drop; + erikp->erik_rx_bad_pkts.value.ul = esp->rx_bad_pkts; + erikp->erik_rx_inits.value.ul = esp->rx_inits; + erikp->erik_tx_inits.value.ul = esp->tx_inits; + erikp->erik_rxtag_err.value.ul = esp->rxtag_err; + erikp->erik_parity_error.value.ul = esp->parity_error; + erikp->erik_pci_error_int.value.ul = esp->pci_error_int; + erikp->erik_unknown_fatal.value.ul = esp->unknown_fatal; + erikp->erik_pci_data_parity_err.value.ul = esp->pci_data_parity_err; + erikp->erik_pci_signal_target_abort.value.ul = + esp->pci_signal_target_abort; + erikp->erik_pci_rcvd_target_abort.value.ul = + esp->pci_rcvd_target_abort; + erikp->erik_pci_rcvd_master_abort.value.ul = + esp->pci_rcvd_master_abort; + erikp->erik_pci_signal_system_err.value.ul = + esp->pci_signal_system_err; + erikp->erik_pci_det_parity_err.value.ul = esp->pci_det_parity_err; + + erikp->erik_pmcap.value.ul = esp->pmcap; + return (0); } @@ -7161,225 +4360,94 @@ struct kstat *ksp; struct erikstat *erikp; -#ifdef kstat - if ((ksp = kstat_create("eri", erip->instance, - NULL, "net", KSTAT_TYPE_NAMED, - sizeof (struct erikstat) / sizeof (kstat_named_t), - KSTAT_FLAG_PERSISTENT)) == NULL) { -#else - if ((ksp = kstat_create("eri", erip->instance, - NULL, "net", KSTAT_TYPE_NAMED, + if ((ksp = kstat_create("eri", erip->instance, "driver_info", "net", + KSTAT_TYPE_NAMED, sizeof (struct erikstat) / sizeof (kstat_named_t), 0)) == NULL) { -#endif /* kstat */ ERI_FAULT_MSG1(erip, SEVERITY_LOW, ERI_VERB_MSG, - kstat_create_fail_msg); + kstat_create_fail_msg); return; } erip->ksp = ksp; erikp = (struct erikstat *)(ksp->ks_data); - kstat_named_init(&erikp->erik_ipackets, "ipackets", - KSTAT_DATA_ULONG); - kstat_named_init(&erikp->erik_ierrors, "ierrors", - KSTAT_DATA_ULONG); - kstat_named_init(&erikp->erik_opackets, "opackets", - KSTAT_DATA_ULONG); - kstat_named_init(&erikp->erik_oerrors, "oerrors", - KSTAT_DATA_ULONG); - kstat_named_init(&erikp->erik_collisions, "collisions", - KSTAT_DATA_ULONG); - kstat_named_init(&erikp->erik_ifspeed, "ifspeed", - KSTAT_DATA_ULONGLONG); - /* * MIB II kstat variables */ - kstat_named_init(&erikp->erik_rbytes, "rbytes", - KSTAT_DATA_ULONG); - kstat_named_init(&erikp->erik_obytes, "obytes", - KSTAT_DATA_ULONG); - kstat_named_init(&erikp->erik_multircv, "multircv", - KSTAT_DATA_ULONG); - kstat_named_init(&erikp->erik_multixmt, "multixmt", - KSTAT_DATA_ULONG); - kstat_named_init(&erikp->erik_brdcstrcv, "brdcstrcv", - KSTAT_DATA_ULONG); - kstat_named_init(&erikp->erik_brdcstxmt, "brdcstxmt", - KSTAT_DATA_ULONG); - kstat_named_init(&erikp->erik_norcvbuf, "norcvbuf", - KSTAT_DATA_ULONG); - kstat_named_init(&erikp->erik_noxmtbuf, "noxmtbuf", - KSTAT_DATA_ULONG); - - kstat_named_init(&erikp->erik_inits, "inits", - KSTAT_DATA_ULONG); - kstat_named_init(&erikp->erik_tnocar, "nocarrier", - KSTAT_DATA_ULONG); - - kstat_named_init(&erikp->erik_txmac_urun, "txmac_urun", - KSTAT_DATA_ULONG); + + kstat_named_init(&erikp->erik_inits, "inits", KSTAT_DATA_ULONG); + kstat_named_init(&erikp->erik_txmac_maxpkt_err, "txmac_maxpkt_err", - KSTAT_DATA_ULONG); - kstat_named_init(&erikp->erik_excessive_coll, "excessive_coll", - KSTAT_DATA_ULONG); - kstat_named_init(&erikp->erik_late_coll, "late_coll", - KSTAT_DATA_ULONG); - kstat_named_init(&erikp->erik_first_coll, "first_coll", - KSTAT_DATA_ULONG); - kstat_named_init(&erikp->erik_defer_timer_exp, "defer_timer_exp", - KSTAT_DATA_ULONG); + KSTAT_DATA_ULONG); + kstat_named_init(&erikp->erik_defer_timer_exp, "defer_timer_exp", + KSTAT_DATA_ULONG); kstat_named_init(&erikp->erik_peak_attempt_cnt, "peak_attempt_cnt", - KSTAT_DATA_ULONG); - kstat_named_init(&erikp->erik_tx_hang, "tx_hang", - KSTAT_DATA_ULONG); - - kstat_named_init(&erikp->erik_rx_corr, "rx_corr", - KSTAT_DATA_ULONG); - kstat_named_init(&erikp->erik_no_free_rx_desc, "no_free_rx_desc", - KSTAT_DATA_ULONG); - kstat_named_init(&erikp->erik_rx_overflow, "rx_overflow", - KSTAT_DATA_ULONG); - kstat_named_init(&erikp->erik_rx_hang, "rx_hang", - KSTAT_DATA_ULONG); - kstat_named_init(&erikp->erik_rx_align_err, "rx_align_err", - KSTAT_DATA_ULONG); - kstat_named_init(&erikp->erik_rx_crc_err, "rx_crc_err", - KSTAT_DATA_ULONG); - kstat_named_init(&erikp->erik_rx_length_err, "rx_length_err", - KSTAT_DATA_ULONG); + KSTAT_DATA_ULONG); + kstat_named_init(&erikp->erik_tx_hang, "tx_hang", KSTAT_DATA_ULONG); + + kstat_named_init(&erikp->erik_no_free_rx_desc, "no_free_rx_desc", + KSTAT_DATA_ULONG); + kstat_named_init(&erikp->erik_rx_hang, "rx_hang", KSTAT_DATA_ULONG); + kstat_named_init(&erikp->erik_rx_length_err, "rx_length_err", + KSTAT_DATA_ULONG); kstat_named_init(&erikp->erik_rx_code_viol_err, "rx_code_viol_err", - KSTAT_DATA_ULONG); - - kstat_named_init(&erikp->erik_pause_rxcount, "pause_rcv_cnt", - KSTAT_DATA_ULONG); - - kstat_named_init(&erikp->erik_pause_oncount, "pause_on_cnt", - KSTAT_DATA_ULONG); - - kstat_named_init(&erikp->erik_pause_offcount, "pause_off_cnt", - KSTAT_DATA_ULONG); + KSTAT_DATA_ULONG); + + kstat_named_init(&erikp->erik_pause_rxcount, "pause_rcv_cnt", + KSTAT_DATA_ULONG); + + kstat_named_init(&erikp->erik_pause_oncount, "pause_on_cnt", + KSTAT_DATA_ULONG); + + kstat_named_init(&erikp->erik_pause_offcount, "pause_off_cnt", + KSTAT_DATA_ULONG); kstat_named_init(&erikp->erik_pause_time_count, "pause_time_cnt", - KSTAT_DATA_ULONG); - - kstat_named_init(&erikp->erik_jab, "jabber", - KSTAT_DATA_ULONG); - kstat_named_init(&erikp->erik_notmds, "no_tmds", - KSTAT_DATA_ULONG); - kstat_named_init(&erikp->erik_nocanput, "nocanput", - KSTAT_DATA_ULONG); + KSTAT_DATA_ULONG); + + kstat_named_init(&erikp->erik_jab, "jabber", KSTAT_DATA_ULONG); + kstat_named_init(&erikp->erik_notmds, "no_tmds", KSTAT_DATA_ULONG); kstat_named_init(&erikp->erik_allocbfail, "allocbfail", - KSTAT_DATA_ULONG); - - kstat_named_init(&erikp->erik_drop, "drop", - KSTAT_DATA_ULONG); + KSTAT_DATA_ULONG); + + kstat_named_init(&erikp->erik_drop, "drop", KSTAT_DATA_ULONG); kstat_named_init(&erikp->erik_rx_bad_pkts, "bad_pkts", - KSTAT_DATA_ULONG); - - kstat_named_init(&erikp->erik_rx_runt, "runt", - KSTAT_DATA_ULONG); - - kstat_named_init(&erikp->erik_rx_toolong_pkts, "toolong_pkts", - KSTAT_DATA_ULONG); - - kstat_named_init(&erikp->erik_rx_inits, "rx_inits", - KSTAT_DATA_ULONG); - - kstat_named_init(&erikp->erik_tx_inits, "tx_inits", - KSTAT_DATA_ULONG); + KSTAT_DATA_ULONG); + + kstat_named_init(&erikp->erik_rx_inits, "rx_inits", KSTAT_DATA_ULONG); + + kstat_named_init(&erikp->erik_tx_inits, "tx_inits", KSTAT_DATA_ULONG); kstat_named_init(&erikp->erik_rxtag_err, "rxtag_error", - KSTAT_DATA_ULONG); - - kstat_named_init(&erikp->erik_parity_error, - "parity_error", - KSTAT_DATA_ULONG); - - kstat_named_init(&erikp->erik_pci_error_int, - "pci_error_interrupt", - KSTAT_DATA_ULONG); + KSTAT_DATA_ULONG); + + kstat_named_init(&erikp->erik_parity_error, "parity_error", + KSTAT_DATA_ULONG); + + kstat_named_init(&erikp->erik_pci_error_int, "pci_error_interrupt", + KSTAT_DATA_ULONG); kstat_named_init(&erikp->erik_unknown_fatal, "unknown_fatal", - KSTAT_DATA_ULONG); + KSTAT_DATA_ULONG); kstat_named_init(&erikp->erik_pci_data_parity_err, - "pci_data_parity_err", KSTAT_DATA_ULONG); + "pci_data_parity_err", KSTAT_DATA_ULONG); kstat_named_init(&erikp->erik_pci_signal_target_abort, - "pci_signal_target_abort", KSTAT_DATA_ULONG); + "pci_signal_target_abort", KSTAT_DATA_ULONG); kstat_named_init(&erikp->erik_pci_rcvd_target_abort, - "pci_rcvd_target_abort", KSTAT_DATA_ULONG); + "pci_rcvd_target_abort", KSTAT_DATA_ULONG); kstat_named_init(&erikp->erik_pci_rcvd_master_abort, - "pci_rcvd_master_abort", KSTAT_DATA_ULONG); + "pci_rcvd_master_abort", KSTAT_DATA_ULONG); kstat_named_init(&erikp->erik_pci_signal_system_err, - "pci_signal_system_err", KSTAT_DATA_ULONG); + "pci_signal_system_err", KSTAT_DATA_ULONG); kstat_named_init(&erikp->erik_pci_det_parity_err, - "pci_det_parity_err", KSTAT_DATA_ULONG); - - kstat_named_init(&erikp->erik_pmcap, "pmcap", - KSTAT_DATA_ULONG); - - kstat_named_init(&erikp->erik_link_up, "link_up", - KSTAT_DATA_ULONG); - - kstat_named_init(&erikp->erik_link_duplex, "link_duplex", - KSTAT_DATA_ULONG); - /* - * 64-bit kstats : PSARC 1997/198 - */ - kstat_named_init(&erikp->erik_ipackets64, "ipackets64", - KSTAT_DATA_ULONGLONG); - kstat_named_init(&erikp->erik_opackets64, "opackets64", - KSTAT_DATA_ULONGLONG); - kstat_named_init(&erikp->erik_rbytes64, "rbytes64", - KSTAT_DATA_ULONGLONG); - kstat_named_init(&erikp->erik_obytes64, "obytes64", - KSTAT_DATA_ULONGLONG); + "pci_det_parity_err", KSTAT_DATA_ULONG); + + kstat_named_init(&erikp->erik_pmcap, "pmcap", KSTAT_DATA_ULONG); + ksp->ks_update = eri_stat_kstat_update; ksp->ks_private = (void *) erip; kstat_install(ksp); } -/* <<<<<<<<<<<<<<<<<<< PERFORMANCE MEASUREMENT FUNCTIONS >>>>>>>>>>> */ - -/* The following code is used for performance metering and debugging; */ -/* This routine is invoked via "TIME_POINT(label)" macros, which will */ -/* store the label and a timestamp. This allows to execution sequences */ -/* and timestamps associated with them. */ - - -#ifdef TPOINTS -/* Time trace points */ -int time_point_active; -static int time_point_offset, time_point_loc; -hrtime_t last_time_point; -#define POINTS 1024 -int time_points[POINTS]; -#define TPOINT(x) if (time_point_active) eri_time_point(x); -void -eri_time_point(int loc) -{ - static hrtime_t time_point_base; - - hrtime_t now; - - now = gethrtime(); - if (time_point_base == 0) { - time_point_base = now; - time_point_loc = loc; - time_point_offset = 0; - } else { - time_points[time_point_offset] = loc; - time_points[time_point_offset+1] = - (now - last_time_point) / 1000; - time_point_offset += 2; - if (time_point_offset >= POINTS) - time_point_offset = 0; /* wrap at end */ - /* time_point_active = 0; disable at end */ - } - last_time_point = now; -} -#else -#define TPOINT(x) -#endif /* <<<<<<<<<<<<<<<<<<<<<<< NDD SUPPORT FUNCTIONS >>>>>>>>>>>>>>>>>>> */ /* @@ -7401,7 +4469,7 @@ static int eri_param_get(queue_t *q, mblk_t *mp, caddr_t cp) { - param_t *eripa = (param_t *)cp; + param_t *eripa = (void *)cp; int param_len = 1; uint32_t param_val; mblk_t *nmp; @@ -7438,6 +4506,7 @@ while (tmp->b_cont) tmp = tmp->b_cont; + /*LINTED E_BAD_PTR_CAST_ALIGN*/ if (MBLKTAIL(tmp) < sz) { if ((tmp->b_cont = allocb(1024, BPRI_HI)) == NULL) return (ENOMEM); @@ -7452,102 +4521,37 @@ * named dispatch handler. Each element is loaded using * eri_nd_load() */ -/* ARGSUSED */ static int eri_param_register(struct eri *erip, param_t *eripa, int cnt) +{ /* cnt gives the count of the number of */ /* elements present in the parameter array */ -{ - int i, k; - - /* First 4 elements are read-only */ - for (i = 0, k = 0; i < 4; i++, k++, eripa++) - if (erip->param_display[k] == DISPLAY_PARAM) - if (!eri_nd_load(&erip->g_nd, - eripa->param_name, (pfi_t)eri_param_get, - (pfi_t)0, (caddr_t)eripa)) { - (void) eri_nd_free(&erip->g_nd); - return (B_FALSE); - } - - /* Next 10 elements are read and write */ - for (i = 0; i < 10; i++, k++, eripa++) - if (erip->param_display[k] == DISPLAY_PARAM) - if (eripa->param_name && eripa->param_name[0]) { - if (!eri_nd_load(&erip->g_nd, - eripa->param_name, (pfi_t)eri_param_get, - (pfi_t)eri_param_set, (caddr_t)eripa)) { - (void) eri_nd_free(&erip->g_nd); - return (B_FALSE); - } - } - - /* next 12 elements are read-only */ - for (i = 0; i < 12; i++, k++, eripa++) - if (erip->param_display[k] == DISPLAY_PARAM) - if (!eri_nd_load(&erip->g_nd, eripa->param_name, - (pfi_t)eri_param_get, (pfi_t)0, (caddr_t)eripa)) { - (void) eri_nd_free(&erip->g_nd); - return (B_FALSE); - } - - /* Next 5 elements are read and write */ - for (i = 0; i < 5; i++, k++, eripa++) - if (erip->param_display[k] == DISPLAY_PARAM) - if (eripa->param_name && eripa->param_name[0]) { - if (!eri_nd_load(&erip->g_nd, - eripa->param_name, (pfi_t)eri_param_get, - (pfi_t)eri_param_set, (caddr_t)eripa)) { - (void) eri_nd_free(&erip->g_nd); - return (B_FALSE); - } + + int i; + + for (i = 0; i < cnt; i++) { + pfi_t setter = (pfi_t)eri_param_set; + + switch (eripa->param_name[0]) { + case '+': /* read-write */ + setter = (pfi_t)eri_param_set; + break; + + case '-': /* read-only */ + setter = NULL; + break; + + case '!': /* read-only, not displayed */ + case '%': /* read-write, not displayed */ + continue; } - /* next 2 elements are read-only */ - for (i = 0; i < 2; i++, k++, eripa++) - if (erip->param_display[k] == DISPLAY_PARAM) - if (!eri_nd_load(&erip->g_nd, eripa->param_name, - (pfi_t)eri_param_get, (pfi_t)0, (caddr_t)eripa)) { - (void) eri_nd_free(&erip->g_nd); - return (B_FALSE); - } - /* Next 2 element is read and write */ - for (i = 0; i < 2; i++, k++, eripa++) - if (erip->param_display[k] == DISPLAY_PARAM) - if (eripa->param_name && eripa->param_name[0]) { - if (!eri_nd_load(&erip->g_nd, - eripa->param_name, (pfi_t)eri_param_get, - (pfi_t)eri_param_set, (caddr_t)eripa)) { - (void) eri_nd_free(&erip->g_nd); - return (B_FALSE); - } + + if (!eri_nd_load(&erip->g_nd, eripa->param_name + 1, + (pfi_t)eri_param_get, setter, (caddr_t)erip)) { + (void) eri_nd_free(&erip->g_nd); + return (B_FALSE); } - /* next 1 element is read-only */ - for (i = 0; i < 1; i++, k++, eripa++) - if (erip->param_display[k] == DISPLAY_PARAM) - if (!eri_nd_load(&erip->g_nd, eripa->param_name, - (pfi_t)eri_param_get, (pfi_t)0, (caddr_t)eripa)) { - (void) eri_nd_free(&erip->g_nd); - return (B_FALSE); - } - /* Next 5 elements are read and write */ - for (i = 0; i < 5; i++, k++, eripa++) - if (erip->param_display[k] == DISPLAY_PARAM) - if (eripa->param_name && eripa->param_name[0]) { - if (!eri_nd_load(&erip->g_nd, - eripa->param_name, (pfi_t)eri_param_get, - (pfi_t)eri_param_set, (caddr_t)eripa)) { - (void) eri_nd_free(&erip->g_nd); - return (B_FALSE); - } - } - /* next 10 elements are read-only */ - for (i = 0; i < 10; i++, k++, eripa++) - if (erip->param_display[k] == DISPLAY_PARAM) - if (!eri_nd_load(&erip->g_nd, eripa->param_name, - (pfi_t)eri_param_get, (pfi_t)0, (caddr_t)eripa)) { - (void) eri_nd_free(&erip->g_nd); - return (B_FALSE); - } + } return (B_TRUE); } @@ -7561,15 +4565,16 @@ eri_param_set(queue_t *q, mblk_t *mp, char *value, caddr_t cp) { char *end; - size_t new_value; - param_t *eripa = (param_t *)cp; - - new_value = eri_strtol(value, &end, 10); + long new_value; + param_t *eripa = (void *)cp; + + if (ddi_strtol(value, &end, 10, &new_value) != 0) + return (EINVAL); if (end == value || new_value < eripa->param_min || new_value > eripa->param_max) { return (EINVAL); } - eripa->param_val = new_value; + eripa->param_val = (uint32_t)new_value; return (0); } @@ -7580,10 +4585,10 @@ { ND *nd; - if ((nd = (ND *)(*nd_pparam)) != NULL) { + if ((nd = (void *)(*nd_pparam)) != NULL) { if (nd->nd_tbl) - kmem_free((char *)nd->nd_tbl, nd->nd_size); - kmem_free((char *)nd, sizeof (ND)); + kmem_free(nd->nd_tbl, nd->nd_size); + kmem_free(nd, sizeof (ND)); *nd_pparam = NULL; } } @@ -7603,8 +4608,8 @@ if (!nd_param) return (B_FALSE); - nd = (ND *)nd_param; - iocp = (IOCP)mp->b_rptr; + nd = (void *)nd_param; + iocp = (void *)mp->b_rptr; if ((iocp->ioc_count == 0) || !(mp1 = mp->b_cont)) { mp->b_datap->db_type = M_IOCACK; iocp->ioc_count = 0; @@ -7648,7 +4653,7 @@ * bad or not given. */ if (valp) - avail = eri_strtol(valp, (char **)0, 10); + (void) ddi_strtol(valp, NULL, 10, (long *)&avail); /* We overwrite the name/value with the reply data */ { mblk_t *mp2 = mp1; @@ -7672,11 +4677,11 @@ size_out = msgdsize(mp1); excess = size_out - avail; if (excess > 0) { - iocp->ioc_rval = size_out; + iocp->ioc_rval = (unsigned)size_out; size_out -= excess; (void) adjmsg(mp1, -(excess + 1)); err = eri_mk_mblk_tail_space(mp1, - &nmp, 1); + &nmp, 1); if (!err) *nmp->b_wptr++ = '\0'; else @@ -7692,23 +4697,15 @@ case ND_SET: if (valp) { - if ((iocp->ioc_cr != NULL) && - ((err = secpolicy_net_config(iocp->ioc_cr, B_FALSE)) - == 0)) { - err = (*nde->nde_set_pfi)(q, mp1, valp, - nde->nde_data, iocp->ioc_cr); - } + err = (*nde->nde_set_pfi)(q, mp1, valp, + nde->nde_data, iocp->ioc_cr); iocp->ioc_count = 0; freemsg(mp1); mp->b_cont = NULL; } break; - - default: - ERI_DEBUG_MSG1(NULL, DEFAULT_MSG, - "nd_getset: cmd is default"); - break; } + iocp->ioc_error = err; mp->b_datap->db_type = M_IOCACK; return (B_TRUE); @@ -7731,7 +4728,7 @@ if (!nd_pparam) return (B_FALSE); - if ((nd = (ND *)(*nd_pparam)) == NULL) { + if ((nd = (void *)(*nd_pparam)) == NULL) { if ((nd = (ND *)kmem_zalloc(sizeof (ND), KM_NOSLEEP)) == NULL) return (B_FALSE); @@ -7778,15 +4775,10 @@ * New Section */ #ifdef DEBUG -/*VARARGS*/ -/* ARGSUSED */ +/*PRINTFLIKE5*/ static void -eri_debug_msg( - char *file, - int line, - struct eri *erip, - debug_msg_t type, - char *fmt, ...) +eri_debug_msg(const char *file, int line, struct eri *erip, + debug_msg_t type, const char *fmt, ...) { char msg_buffer[255]; va_list ap; @@ -7811,16 +4803,16 @@ if (eri_msg_out & ERI_CON_MSG) { if (((type <= eri_debug_level) && eri_debug_all) || - ((type == eri_debug_level) && !eri_debug_all)) { + ((type == eri_debug_level) && !eri_debug_all)) { if (erip) - cmn_err(CE_CONT, "D: %s %s(%d):(%s%d) %s\n", - debug_msg_string[type], file, line, - DEVICE_NAME(erip->dip), erip->instance, - msg_buffer); + cmn_err(CE_CONT, "D: %s %s%d:(%s%d) %s\n", + debug_msg_string[type], file, line, + ddi_driver_name(erip->dip), erip->instance, + msg_buffer); else cmn_err(CE_CONT, "D: %s %s(%d): %s\n", - debug_msg_string[type], file, - line, msg_buffer); + debug_msg_string[type], file, + line, msg_buffer); } } mutex_exit(&eridebuglock); @@ -7828,51 +4820,45 @@ #endif -/* VARARGS */ -/* ARGSUSED */ +/*PRINTFLIKE4*/ static void -eri_fault_msg(char *file, uint_t line, struct eri *erip, uint_t severity, - msg_t type, char *fmt, ...) +eri_fault_msg(struct eri *erip, uint_t severity, msg_t type, + const char *fmt, ...) { char msg_buffer[255]; va_list ap; - mutex_enter(&erilock); - va_start(ap, fmt); (void) vsprintf(msg_buffer, fmt, ap); va_end(ap); if (erip == NULL) { cmn_err(CE_NOTE, "eri : %s", msg_buffer); - mutex_exit(&erilock); return; } if (severity == SEVERITY_HIGH) { - cmn_err(CE_WARN, "%s%d : %s", DEVICE_NAME(erip->dip), + cmn_err(CE_WARN, "%s%d : %s", ddi_driver_name(erip->dip), erip->instance, msg_buffer); } else switch (type) { case ERI_VERB_MSG: - cmn_err(CE_CONT, "?%s%d : %s", DEVICE_NAME(erip->dip), + cmn_err(CE_CONT, "?%s%d : %s", ddi_driver_name(erip->dip), erip->instance, msg_buffer); break; case ERI_LOG_MSG: - cmn_err(CE_NOTE, "^%s%d : %s", DEVICE_NAME(erip->dip), + cmn_err(CE_NOTE, "^%s%d : %s", ddi_driver_name(erip->dip), erip->instance, msg_buffer); break; case ERI_BUF_MSG: - cmn_err(CE_NOTE, "!%s%d : %s", DEVICE_NAME(erip->dip), + cmn_err(CE_NOTE, "!%s%d : %s", ddi_driver_name(erip->dip), erip->instance, msg_buffer); break; case ERI_CON_MSG: - cmn_err(CE_CONT, "%s%d : %s", DEVICE_NAME(erip->dip), + cmn_err(CE_CONT, "%s%d : %s", ddi_driver_name(erip->dip), erip->instance, msg_buffer); default: break; } - - mutex_exit(&erilock); } /* @@ -7888,7 +4874,6 @@ eri_stop_timer(struct eri *erip) { timeout_id_t id; - ERI_DEBUG_MSG1(erip, XCVR_MSG, "stop timer"); mutex_enter(&erip->linklock); if (erip->timerid) { erip->flags |= ERI_NOTIMEOUTS; /* prevent multiple timeout */ @@ -7908,13 +4893,11 @@ static void eri_start_timer(struct eri *erip, fptrv_t func, clock_t msec) { - ERI_DEBUG_MSG1(erip, XCVR_MSG, "start timer"); - if (msec) { if (!(erip->flags & ERI_NOTIMEOUTS) && - (erip->flags & ERI_RUNNING)) { - erip->timerid = timeout(func, (caddr_t)erip, - drv_usectohz(1000*msec)); + (erip->flags & ERI_RUNNING)) { + erip->timerid = timeout(func, (caddr_t)erip, + drv_usectohz(1000*msec)); } } @@ -7934,8 +4917,7 @@ status = B_FALSE; /* no change */ cfg = GET_MIFREG(mif_cfg); - ERI_DEBUG_MSG2(erip, MIF_MSG, - "cfg value = %X", cfg); + ERI_DEBUG_MSG2(erip, MIF_MSG, "cfg value = %X", cfg); old_transceiver = param_transceiver; if ((cfg & ERI_MIF_CFGM1) && !use_int_xcvr) { @@ -7952,8 +4934,8 @@ */ if (old_transceiver == INTERNAL_XCVR) { eri_mii_write(erip, ERI_PHY_BMCR, - (PHY_BMCR_ISOLATE | PHY_BMCR_PWRDN | - PHY_BMCR_LPBK)); + (PHY_BMCR_ISOLATE | PHY_BMCR_PWRDN | + PHY_BMCR_LPBK)); } status = B_TRUE; } @@ -7982,10 +4964,10 @@ * transceiver state. */ if ((old_transceiver == EXTERNAL_XCVR) && - (cfg & ERI_MIF_CFGM0)) { + (cfg & ERI_MIF_CFGM0)) { eri_mii_write(erip, ERI_PHY_BMCR, - (PHY_BMCR_ISOLATE | PHY_BMCR_PWRDN | - PHY_BMCR_LPBK)); + (PHY_BMCR_ISOLATE | PHY_BMCR_PWRDN | + PHY_BMCR_LPBK)); } status = B_TRUE; } @@ -8005,10 +4987,10 @@ /* * Did not find a valid xcvr. */ - ERI_FAULT_MSG1(erip, SEVERITY_NONE, ERI_VERB_MSG, - "Eri_new_xcvr : Select None"); - param_transceiver = NO_XCVR; - erip->xcvr_status = PHY_LINK_DOWN; + ERI_FAULT_MSG1(erip, SEVERITY_NONE, ERI_VERB_MSG, + "Eri_new_xcvr : Select None"); + param_transceiver = NO_XCVR; + erip->xcvr_status = PHY_LINK_DOWN; } if (erip->stats.pmcap == ERI_PMCAP_NONE) { @@ -8026,7 +5008,10 @@ static void eri_check_link(struct eri *erip) { - eri_send_notifications(erip, eri_check_link_noind(erip)); + link_state_t linkupdate = eri_check_link_noind(erip); + + if (linkupdate != LINK_STATE_UNKNOWN) + mac_link_update(erip->mh, linkupdate); } /* @@ -8043,9 +5028,8 @@ { uint16_t stat, control, mif_ints; uint32_t link_timeout = ERI_LINKCHECK_TIMER; - uint32_t linkflags = 0; - - ERI_DEBUG_MSG1(erip, XCVR_MSG, "eri_check_link_enter"); + uint32_t linkupdate = 0; + eri_stop_timer(erip); /* acquire linklock */ mutex_enter(&erip->xmitlock); @@ -8058,35 +5042,35 @@ if (erip->openloop_autoneg) { (void) eri_mii_read(erip, ERI_PHY_BMSR, &stat); ERI_DEBUG_MSG3(erip, XCVR_MSG, - "eri_check_link:openloop stat %X mii_status %X", - stat, erip->mii_status); + "eri_check_link:openloop stat %X mii_status %X", + stat, erip->mii_status); (void) eri_mii_read(erip, ERI_PHY_BMCR, &control); if (!(stat & PHY_BMSR_LNKSTS) && - (erip->openloop_autoneg < 2)) { + (erip->openloop_autoneg < 2)) { if (param_speed) { control &= ~PHY_BMCR_100M; param_anlpar_100hdx = 0; param_anlpar_10hdx = 1; param_speed = 0; - erip->stats.ifspeed = SPEED_10; + erip->stats.ifspeed = 10; } else { control |= PHY_BMCR_100M; param_anlpar_100hdx = 1; param_anlpar_10hdx = 0; param_speed = 1; - erip->stats.ifspeed = SPEED_100; + erip->stats.ifspeed = 100; } ERI_DEBUG_MSG3(erip, XCVR_MSG, - "eri_check_link: trying speed %X stat %X", - param_speed, stat); + "eri_check_link: trying speed %X stat %X", + param_speed, stat); erip->openloop_autoneg ++; eri_mii_write(erip, ERI_PHY_BMCR, control); link_timeout = ERI_P_FAULT_TIMER; } else { erip->openloop_autoneg = 0; - linkflags = eri_mif_check(erip, stat, stat); + linkupdate = eri_mif_check(erip, stat, stat); if (erip->openloop_autoneg) link_timeout = ERI_P_FAULT_TIMER; } @@ -8095,10 +5079,10 @@ mutex_exit(&erip->xmitlock); eri_start_timer(erip, eri_check_link, link_timeout); - return (linkflags); + return (linkupdate); } - linkflags = eri_mif_check(erip, mif_ints, stat); + linkupdate = eri_mif_check(erip, mif_ints, stat); eri_mif_poll(erip, MIF_POLL_START); mutex_exit(&erip->xcvrlock); mutex_exit(&erip->xmitlock); @@ -8125,7 +5109,7 @@ eri_start_timer(erip, eri_check_link, ERI_CHECK_HANG_TIMER); - return (linkflags); + return (linkupdate); } if (erip->check2_rmac_hang) { @@ -8157,7 +5141,7 @@ eri_start_timer(erip, eri_check_link, ERI_LINKCHECK_TIMER); (void) eri_init(erip); - return (linkflags); + return (linkupdate); } } } @@ -8167,19 +5151,14 @@ * Check if tx hung. */ #ifdef ERI_TX_HUNG - if ((erip->flags & ERI_RUNNING) && - param_linkup && (eri_check_txhung(erip))) { + if ((erip->flags & ERI_RUNNING) && param_linkup && + (eri_check_txhung(erip))) { HSTAT(erip, tx_hang); eri_reinit_txhung++; -#ifdef LATER_SPLIT_TX_RX - mutex_enter(&erip->xmitlock); - eri_init_tx(erip); - mutex_exit(&erip->xmitlock); -#endif erip->linkcheck = 1; eri_start_timer(erip, eri_check_link, ERI_CHECK_HANG_TIMER); (void) eri_init(erip); - return (linkflags); + return (linkupdate); } #endif @@ -8197,20 +5176,19 @@ eri_start_timer(erip, eri_check_link, ERI_CHECK_HANG_TIMER); else eri_start_timer(erip, eri_check_link, ERI_LINKCHECK_TIMER); - return (linkflags); + return (linkupdate); } -static uint32_t +static link_state_t eri_mif_check(struct eri *erip, uint16_t mif_ints, uint16_t mif_data) { uint16_t control, aner, anlpar, anar, an_common; uint16_t old_mintrans; int restart_autoneg = 0; - uint32_t retv; - - ERI_DEBUG_MSG4(erip, XCVR_MSG, - "eri_mif_check: mif_mask: %X, %X, %X", - erip->mif_mask, mif_ints, mif_data); + link_state_t retv; + + ERI_DEBUG_MSG4(erip, XCVR_MSG, "eri_mif_check: mif_mask: %X, %X, %X", + erip->mif_mask, mif_ints, mif_data); mif_ints &= ~erip->mif_mask; erip->mii_status = mif_data; @@ -8220,9 +5198,9 @@ * If so try to find out what the new xcvr setup is. */ if (((mif_ints & PHY_BMSR_RES1) && (mif_data == 0xFFFF)) || - (param_transceiver == NO_XCVR)) { + (param_transceiver == NO_XCVR)) { ERI_FAULT_MSG1(erip, SEVERITY_NONE, ERI_VERB_MSG, - "No status transceiver gone"); + "No status transceiver gone"); if (eri_new_xcvr(erip)) { if (param_transceiver != NO_XCVR) { /* @@ -8231,20 +5209,19 @@ (void) eri_reset_xcvr(erip); } } - return (0); + return (LINK_STATE_UNKNOWN); } if (param_autoneg && (mif_ints & PHY_BMSR_LNKSTS) && - (mif_data & PHY_BMSR_LNKSTS) && (mif_data & PHY_BMSR_ANC)) { + (mif_data & PHY_BMSR_LNKSTS) && (mif_data & PHY_BMSR_ANC)) { mif_ints |= PHY_BMSR_ANC; ERI_DEBUG_MSG3(erip, PHY_MSG, - "eri_mif_check: Set ANC bit mif_data %X mig_ints %X", - mif_data, mif_ints); + "eri_mif_check: Set ANC bit mif_data %X mig_ints %X", + mif_data, mif_ints); } if ((mif_ints & PHY_BMSR_ANC) && (mif_data & PHY_BMSR_ANC)) { - ERI_DEBUG_MSG1(erip, PHY_MSG, - "Auto-negotiation interrupt."); + ERI_DEBUG_MSG1(erip, PHY_MSG, "Auto-negotiation interrupt."); /* * Switch off Auto-negotiation interrupts and switch on @@ -8256,34 +5233,33 @@ param_aner_lpancap = 1 && (aner & PHY_ANER_LPNW); if ((aner & PHY_ANER_MLF) || (eri_force_mlf)) { ERI_DEBUG_MSG1(erip, XCVR_MSG, - "parallel detection fault"); + "parallel detection fault"); /* * Consider doing open loop auto-negotiation. */ ERI_DEBUG_MSG1(erip, XCVR_MSG, - "Going into Open loop Auto-neg"); + "Going into Open loop Auto-neg"); (void) eri_mii_read(erip, ERI_PHY_BMCR, &control); control &= ~(PHY_BMCR_ANE | PHY_BMCR_RAN | - PHY_BMCR_FDX); + PHY_BMCR_FDX); if (param_anar_100fdx || param_anar_100hdx) { control |= PHY_BMCR_100M; param_anlpar_100hdx = 1; param_anlpar_10hdx = 0; param_speed = 1; - erip->stats.ifspeed = SPEED_100; - - } else if (param_anar_10fdx || - param_anar_10hdx) { - control &= ~PHY_BMCR_100M; - param_anlpar_100hdx = 0; - param_anlpar_10hdx = 1; - param_speed = 0; - erip->stats.ifspeed = SPEED_10; + erip->stats.ifspeed = 100; + + } else if (param_anar_10fdx || param_anar_10hdx) { + control &= ~PHY_BMCR_100M; + param_anlpar_100hdx = 0; + param_anlpar_10hdx = 1; + param_speed = 0; + erip->stats.ifspeed = 10; } else { ERI_FAULT_MSG1(erip, SEVERITY_NONE, - ERI_VERB_MSG, - "Transceiver speed set incorrectly."); + ERI_VERB_MSG, + "Transceiver speed set incorrectly."); return (0); } @@ -8298,25 +5274,23 @@ (void) eri_mii_read(erip, ERI_PHY_ANAR, &anar); an_common = anar & anlpar; - ERI_DEBUG_MSG2(erip, XCVR_MSG, - "an_common = 0x%X", an_common); + ERI_DEBUG_MSG2(erip, XCVR_MSG, "an_common = 0x%X", an_common); if (an_common & (PHY_ANLPAR_TXFDX | PHY_ANLPAR_TX)) { param_speed = 1; - erip->stats.ifspeed = SPEED_100; + erip->stats.ifspeed = 100; param_mode = 1 && (an_common & PHY_ANLPAR_TXFDX); } else if (an_common & (PHY_ANLPAR_10FDX | PHY_ANLPAR_10)) { param_speed = 0; - erip->stats.ifspeed = SPEED_10; + erip->stats.ifspeed = 10; param_mode = 1 && (an_common & PHY_ANLPAR_10FDX); } else an_common = 0x0; if (!an_common) { ERI_FAULT_MSG1(erip, SEVERITY_MID, ERI_VERB_MSG, - "Transceiver: anar" - " not set with speed selection"); + "Transceiver: anar not set with speed selection"); } param_anlpar_100T4 = 1 && (anlpar & PHY_ANLPAR_T4); param_anlpar_100fdx = 1 && (anlpar & PHY_ANLPAR_TXFDX); @@ -8325,13 +5299,13 @@ param_anlpar_10hdx = 1 && (anlpar & PHY_ANLPAR_10); ERI_DEBUG_MSG2(erip, PHY_MSG, - "Link duplex = 0x%X", param_mode); + "Link duplex = 0x%X", param_mode); ERI_DEBUG_MSG2(erip, PHY_MSG, - "Link speed = 0x%X", param_speed); + "Link speed = 0x%X", param_speed); /* mif_ints |= PHY_BMSR_LNKSTS; prevent double msg */ /* mif_data |= PHY_BMSR_LNKSTS; prevent double msg */ } - retv = 0; + retv = LINK_STATE_UNKNOWN; if (mif_ints & PHY_BMSR_LNKSTS) { if (mif_data & PHY_BMSR_LNKSTS) { ERI_DEBUG_MSG1(erip, PHY_MSG, "Link Up"); @@ -8349,21 +5323,19 @@ */ eri_init_txmac(erip); param_linkup = 1; - erip->stats.link_up = ERI_LINK_UP; + erip->stats.link_up = LINK_STATE_UP; if (param_mode) - erip->stats.link_duplex = ERI_FULL_DUPLEX; + erip->stats.link_duplex = LINK_DUPLEX_FULL; else - erip->stats.link_duplex = ERI_HALF_DUPLEX; - - retv = DL_NOTE_LINK_UP; - eri_display_link_status(erip); + erip->stats.link_duplex = LINK_DUPLEX_HALF; + + retv = LINK_STATE_UP; } else { - ERI_DEBUG_MSG1(erip, PHY_MSG, - "Link down."); + ERI_DEBUG_MSG1(erip, PHY_MSG, "Link down."); param_linkup = 0; - erip->stats.link_up = ERI_LINK_DOWN; - erip->stats.link_duplex = ERI_UNKNOWN_DUPLEX; - retv = DL_NOTE_LINK_DOWN; + erip->stats.link_up = LINK_STATE_DOWN; + erip->stats.link_duplex = LINK_DUPLEX_UNKNOWN; + retv = LINK_STATE_DOWN; if (param_autoneg) { restart_autoneg = 1; } @@ -8372,14 +5344,14 @@ if (mif_data & PHY_BMSR_LNKSTS) { if (!param_linkup) { ERI_DEBUG_MSG1(erip, PHY_MSG, - "eri_mif_check: MIF data link up"); + "eri_mif_check: MIF data link up"); /* * Program Lu3X31T for minimum transition */ if (eri_phy_mintrans) { eri_mii_write(erip, 31, 0x8000); (void) eri_mii_read(erip, 0, - &old_mintrans); + &old_mintrans); eri_mii_write(erip, 0, 0x00F1); eri_mii_write(erip, 31, 0x0000); } @@ -8389,27 +5361,26 @@ eri_init_txmac(erip); param_linkup = 1; - erip->stats.link_up = ERI_LINK_UP; + erip->stats.link_up = LINK_STATE_UP; if (param_mode) erip->stats.link_duplex = - ERI_FULL_DUPLEX; + LINK_DUPLEX_FULL; else erip->stats.link_duplex = - ERI_HALF_DUPLEX; - - retv = DL_NOTE_LINK_UP; - eri_display_link_status(erip); + LINK_DUPLEX_HALF; + + retv = LINK_STATE_UP; } } else if (param_linkup) { /* * The link is down now. */ ERI_DEBUG_MSG1(erip, PHY_MSG, - "eri_mif_check:Link was up and went down"); + "eri_mif_check:Link was up and went down"); param_linkup = 0; - erip->stats.link_up = ERI_LINK_DOWN; - erip->stats.link_duplex = ERI_UNKNOWN_DUPLEX; - retv = DL_NOTE_LINK_DOWN; + erip->stats.link_up = LINK_STATE_DOWN; + erip->stats.link_duplex = LINK_DUPLEX_UNKNOWN; + retv = LINK_STATE_DOWN; if (param_autoneg) restart_autoneg = 1; } @@ -8419,7 +5390,7 @@ * Restart normal auto-negotiation. */ ERI_DEBUG_MSG1(erip, PHY_MSG, - "eri_mif_check:Restart AUto Negotiation"); + "eri_mif_check:Restart AUto Negotiation"); erip->openloop_autoneg = 0; param_mode = 0; param_speed = 0; @@ -8429,24 +5400,19 @@ param_anlpar_10fdx = 0; param_anlpar_10hdx = 0; param_aner_lpancap = 0; - (void) eri_mii_read(erip, ERI_PHY_BMCR, - &control); + (void) eri_mii_read(erip, ERI_PHY_BMCR, &control); control |= (PHY_BMCR_ANE | PHY_BMCR_RAN); eri_mii_write(erip, ERI_PHY_BMCR, control); } if (mif_ints & PHY_BMSR_JABDET) { if (mif_data & PHY_BMSR_JABDET) { - ERI_DEBUG_MSG1(erip, PHY_MSG, - "Jabber detected."); + ERI_DEBUG_MSG1(erip, PHY_MSG, "Jabber detected."); HSTAT(erip, jab); /* * Reset the new PHY and bring up the link + * (Check for failure?) */ (void) eri_reset_xcvr(erip); - /* - * eri_FAULT_MSG1(erip, SEVERITY_NONE, XCVR_MSG, - * "Unable to reset transceiver."); - */ } } return (retv); @@ -8467,8 +5433,8 @@ int n; ERI_DEBUG_MSG4(erip, XCVR_MSG, - "eri_reset_xcvr:ifspeed %X param_speed %X mif_mask %X", - erip->stats.ifspeed, param_speed, erip->mif_mask); + "eri_reset_xcvr:ifspeed %X param_speed %X mif_mask %X", + erip->stats.ifspeed, param_speed, erip->mif_mask); #ifdef ERI_10_10_FORCE_SPEED_WORKAROUND erip->ifspeed_old = erip->stats.ifspeed; @@ -8494,21 +5460,20 @@ if (eri_mii_read(erip, ERI_PHY_BMCR, &control) == 1) { /* Transceiver does not talk MII */ ERI_FAULT_MSG1(erip, SEVERITY_NONE, ERI_VERB_MSG, - "eri_reset_xcvr: no mii"); + "eri_reset_xcvr: no mii"); } if ((control & PHY_BMCR_RESET) == 0) goto reset_done; } ERI_FAULT_MSG2(erip, SEVERITY_NONE, ERI_VERB_MSG, - "eri_reset_xcvr:reset_failed n == 0, control %x", - control); + "eri_reset_xcvr:reset_failed n == 0, control %x", control); goto eri_reset_xcvr_failed; reset_done: ERI_DEBUG_MSG2(erip, AUTOCONFIG_MSG, - "eri_reset_xcvr: reset complete in %d us", - (1000 - n) * PHYRST_PERIOD); + "eri_reset_xcvr: reset complete in %d us", + (1000 - n) * PHYRST_PERIOD); (void) eri_mii_read(erip, ERI_PHY_BMSR, &stat); (void) eri_mii_read(erip, ERI_PHY_ANAR, &anar); @@ -8516,8 +5481,7 @@ (void) eri_mii_read(erip, ERI_PHY_IDR2, &idr2); ERI_DEBUG_MSG4(erip, XCVR_MSG, - "eri_reset_xcvr: control %x stat %x anar %x", - control, stat, anar); + "eri_reset_xcvr: control %x stat %x anar %x", control, stat, anar); /* * Initialize the read only transceiver ndd information @@ -8543,8 +5507,6 @@ * Select the operation mode of the transceiver. */ if (param_autoneg) { - ERI_DEBUG_MSG1(erip, PHY_MSG, - "Phy Supports Auto-negotiation."); /* * Initialize our auto-negotiation capabilities. */ @@ -8559,19 +5521,15 @@ anar |= PHY_ANAR_10FDX; if (param_anar_10hdx) anar |= PHY_ANAR_10; - ERI_DEBUG_MSG2(erip, XCVR_MSG, - "anar = %x", anar); + ERI_DEBUG_MSG2(erip, XCVR_MSG, "anar = %x", anar); eri_mii_write(erip, ERI_PHY_ANAR, anar); - } else { - ERI_DEBUG_MSG1(erip, PHY_MSG, - "Phy Doesn't support Auto-negotiation."); } /* Place the Transceiver in normal operation mode */ if ((control & PHY_BMCR_ISOLATE) || (control & PHY_BMCR_LPBK)) { control &= ~(PHY_BMCR_ISOLATE | PHY_BMCR_LPBK); eri_mii_write(erip, ERI_PHY_BMCR, - (control & ~PHY_BMCR_ISOLATE)); + (control & ~PHY_BMCR_ISOLATE)); } /* @@ -8594,12 +5552,11 @@ speed_10 = param_anar_10fdx | param_anar_10hdx; ERI_DEBUG_MSG5(erip, XCVR_MSG, "eri_reset_xcvr: %d %d %d %d", - param_anar_100fdx, param_anar_100hdx, param_anar_10fdx, - param_anar_10hdx); + param_anar_100fdx, param_anar_100hdx, param_anar_10fdx, + param_anar_10hdx); ERI_DEBUG_MSG3(erip, XCVR_MSG, - "eri_reset_xcvr: speed_100 %d speed_10 %d", - speed_100, speed_10); + "eri_reset_xcvr: speed_100 %d speed_10 %d", speed_100, speed_10); if ((!speed_100) && (speed_10)) { erip->mif_mask &= ~PHY_BMSR_JABDET; @@ -8612,13 +5569,11 @@ nicr &= ~PHY_NICR_LD; eri_mii_write(erip, ERI_PHY_NICR, nicr); param_linkup = 1; - erip->stats.link_up = ERI_LINK_UP; + erip->stats.link_up = LINK_STATE_UP; if (param_mode) - erip->stats.link_duplex = ERI_FULL_DUPLEX; + erip->stats.link_duplex = LINK_DUPLEX_FULL; else - erip->stats.link_duplex = ERI_HALF_DUPLEX; - - eri_display_link_status(erip); + erip->stats.link_duplex = LINK_DUPLEX_HALF; } } @@ -8631,8 +5586,6 @@ /* * Setup the transceiver for autonegotiation. */ - ERI_DEBUG_MSG1(erip, PHY_MSG, - "Setup for Auto-negotiation"); erip->mif_mask &= ~PHY_BMSR_ANC; /* @@ -8650,8 +5603,6 @@ /* * Force the transceiver. */ - ERI_DEBUG_MSG1(erip, PHY_MSG, - "Setup for forced mode"); erip->mif_mask &= ~PHY_BMSR_LNKSTS; /* @@ -8668,13 +5619,13 @@ param_anlpar_100fdx = param_anar_100fdx; param_anlpar_100hdx = param_anar_100hdx; param_speed = 1; - erip->stats.ifspeed = SPEED_100; + erip->stats.ifspeed = 100; param_mode = param_anar_100fdx; if (param_mode) { param_anlpar_100hdx = 0; - erip->stats.link_duplex = ERI_FULL_DUPLEX; + erip->stats.link_duplex = LINK_DUPLEX_FULL; } else { - erip->stats.link_duplex = ERI_HALF_DUPLEX; + erip->stats.link_duplex = LINK_DUPLEX_HALF; } } else if (speed_10) { control &= ~PHY_BMCR_100M; @@ -8685,17 +5636,17 @@ param_anlpar_10fdx = param_anar_10fdx; param_anlpar_10hdx = param_anar_10hdx; param_speed = 0; - erip->stats.ifspeed = SPEED_10; + erip->stats.ifspeed = 10; param_mode = param_anar_10fdx; if (param_mode) { param_anlpar_10hdx = 0; - erip->stats.link_duplex = ERI_FULL_DUPLEX; + erip->stats.link_duplex = LINK_DUPLEX_FULL; } else { - erip->stats.link_duplex = ERI_HALF_DUPLEX; + erip->stats.link_duplex = LINK_DUPLEX_HALF; } } else { ERI_FAULT_MSG1(erip, SEVERITY_NONE, ERI_VERB_MSG, - "Transceiver speed set incorrectly."); + "Transceiver speed set incorrectly."); } if (param_mode) { @@ -8703,8 +5654,8 @@ } ERI_DEBUG_MSG4(erip, PHY_MSG, - "control = %x status = %x param_mode %d", - control, stat, param_mode); + "control = %x status = %x param_mode %d", + control, stat, param_mode); eri_mii_write(erip, ERI_PHY_BMCR, control); /* @@ -8722,7 +5673,7 @@ (void) eri_mii_read(erip, ERI_PHY_ANAR, &anar); #endif ERI_DEBUG_MSG4(erip, PHY_MSG, - "control %X status %X anar %X", control, stat, anar); + "control %X status %X anar %X", control, stat, anar); eri_reset_xcvr_exit: return (0); @@ -8737,16 +5688,14 @@ eri_xcvr_force_mode(struct eri *erip, uint32_t *link_timeout) { - if (!param_autoneg && !param_linkup && - (erip->stats.ifspeed == SPEED_10) && - (param_anar_10fdx | param_anar_10hdx)) { + if (!param_autoneg && !param_linkup && (erip->stats.ifspeed == 10) && + (param_anar_10fdx | param_anar_10hdx)) { *link_timeout = SECOND(1); return; } - if (!param_autoneg && !param_linkup && - (erip->ifspeed_old == SPEED_10) && - (param_anar_100fdx | param_anar_100hdx)) { + if (!param_autoneg && !param_linkup && (erip->ifspeed_old == 10) && + (param_anar_100fdx | param_anar_100hdx)) { /* * May have to set link partner's speed and mode. */ @@ -8757,186 +5706,47 @@ #endif static void -eri_display_link_status(struct eri *erip) -{ - char link_up_msg[64]; - - ERI_DEBUG_MSG3(erip, PHY_MSG, - "eri_display_link_status: ifspeed %X param_mode %d", - erip->stats.ifspeed, param_mode); - switch (erip->stats.ifspeed) { - case SPEED_100: - (void) sprintf(link_up_msg, "100 Mbps "); - break; - case SPEED_10: - (void) sprintf(link_up_msg, "10 Mbps "); - break; - default: - link_up_msg[0] = '\0'; - } - - if (param_mode) - (void) strcat(link_up_msg, "full duplex link up"); - else - (void) strcat(link_up_msg, "half duplex link up"); - - ERI_FAULT_MSG2(erip, SEVERITY_NONE, ERI_CON_MSG, "%s\n", link_up_msg); - - erip->linksts_msg = ERI_VERB_MSG; - HSTAT(erip, tnocar); -} - -static void eri_mif_poll(struct eri *erip, soft_mif_enable_t enable) { if (enable == MIF_POLL_START) { - if (erip->mifpoll_enable && - !erip->openloop_autoneg) { - ERI_DEBUG_MSG1(erip, XCVR_MSG, - "Starting mif poll: normal start"); + if (erip->mifpoll_enable && !erip->openloop_autoneg) { erip->mif_config |= ERI_MIF_CFGPE; PUT_MIFREG(mif_cfg, erip->mif_config); drv_usecwait(ERI_MIF_POLL_DELAY); PUT_GLOBREG(intmask, GET_GLOBREG(intmask) & - ~ERI_G_MASK_MIF_INT); + ~ERI_G_MASK_MIF_INT); PUT_MIFREG(mif_imask, erip->mif_mask); - } else { - ERI_DEBUG_MSG1(erip, XCVR_MSG, - "Starting mif poll:fault start"); } } else if (enable == MIF_POLL_STOP) { - ERI_DEBUG_MSG1(erip, XCVR_MSG, - "Stopping mif poll"); erip->mif_config &= ~ERI_MIF_CFGPE; PUT_MIFREG(mif_cfg, erip->mif_config); drv_usecwait(ERI_MIF_POLL_DELAY); PUT_GLOBREG(intmask, GET_GLOBREG(intmask) | - ERI_G_MASK_MIF_INT); + ERI_G_MASK_MIF_INT); PUT_MIFREG(mif_imask, ERI_MIF_INTMASK); } ERI_DEBUG_MSG2(erip, XCVR_MSG, "MIF Config = 0x%X", - GET_MIFREG(mif_cfg)); + GET_MIFREG(mif_cfg)); ERI_DEBUG_MSG2(erip, XCVR_MSG, "MIF imask = 0x%X", - GET_MIFREG(mif_imask)); + GET_MIFREG(mif_imask)); ERI_DEBUG_MSG2(erip, XCVR_MSG, "INT imask = 0x%X", - GET_GLOBREG(intmask)); + GET_GLOBREG(intmask)); ERI_DEBUG_MSG1(erip, XCVR_MSG, "<== mif_poll"); } -/* - * This function is cut&pasted from mi.c, part of IP source base. - * By defining this function in eri, we remove dependency from ip module. - * This function can be removed once kernel level 'strtol' becomes available. - */ -static long -eri_strtol(char *str, char **ptr, int base) -{ - char *cp; - int digits; - long value; - boolean_t is_negative; - - cp = str; - while (*cp == ' ' || *cp == '\t' || *cp == '\n') - cp++; - is_negative = (*cp == '-'); - if (is_negative) - cp++; - if (base == 0) { - base = 10; - if (*cp == '0') { - base = 8; - cp++; - if (*cp == 'x' || *cp == 'X') { - base = 16; - cp++; - } - } - } - value = 0; - for (; *cp != '\0'; cp++) { - if (*cp >= '0' && *cp <= '9') - digits = *cp - '0'; - else if (*cp >= 'a' && *cp <= 'f') - digits = *cp - 'a' + 10; - else if (*cp >= 'A' && *cp <= 'F') - digits = *cp - 'A' + 10; - else - break; - if (digits >= base) - break; - value = (value * base) + digits; - } - - /* - * Note: we cast away const here deliberately - */ - if (ptr != NULL) - *ptr = (char *)cp; - if (is_negative) - value = -value; - return (value); -} - - -#ifdef XCVR -static int -eri_init_xcvr_info(struct eri *erip, int display_msg) -{ - uint16_t phy_id1, phy_id2; - uint32_t vendor_id; - uint16_t device_id; - uint16_t device_rev; - - (void) eri_mii_read(erip, ERI_PHY_IDR1, &phy_id1); - (void) eri_mii_read(erip, ERI_PHY_IDR2, &phy_id2); - - vendor_id = ((phy_id1 << 0x6) | (phy_id2 >> 10)); - device_id = (phy_id2 >>4) & 0x3f; - device_rev = (phy_id2 & 0xf); - - switch (vendor_id) { - case PHY_VENDOR_LUCENT: - if (display_msg) - ERI_FAULT_MSG2(erip, SEVERITY_NONE, ERI_VERB_MSG, - lucent_phy_msg, vendor_id); - break; - - /* - * No Phy/xcvrs are executed as default. - * This can happen if the xcvr is changed after the attach of a - * I/O board or a future NIC. - */ - default: - ERI_FAULT_MSG2(erip, SEVERITY_HIGH, ERI_VERB_MSG, - unk_phy_msg, vendor_id); - erip->vendor_id = 0; - erip->device_id = 0; - erip->device_rev = 0; - param_linkup = 0; - erip->stats.link_up = ERI_LINK_DOWN; - erip->stats.link_duplex = ERI_UNKNOWN_DUPLEX; - eri_notify_ind(erip, DL_NOTE_LINK_DOWN); - return (1); - } - erip->vendor_id = vendor_id; - erip->device_id = device_id; - erip->device_rev = device_rev; - return (0); -} -#endif - /* Decide if transmitter went dead and reinitialize everything */ #ifdef ERI_TX_HUNG static int eri_txhung_limit = 2; static int eri_check_txhung(struct eri *erip) { + boolean_t macupdate = B_FALSE; + mutex_enter(&erip->xmitlock); if (erip->flags & ERI_RUNNING) - erip->tx_completion = (uint32_t)(GET_ETXREG(tx_completion) - & ETX_COMPLETION_MASK); - (void) eri_reclaim(erip, erip->tx_completion); + erip->tx_completion = (uint32_t)(GET_ETXREG(tx_completion) & + ETX_COMPLETION_MASK); + macupdate |= eri_reclaim(erip, erip->tx_completion); /* Something needs to be sent out but it is not going out */ if ((erip->tcurp != erip->tnextp) && @@ -8950,159 +5760,9 @@ erip->erisave.starts = erip->stats.collisions; mutex_exit(&erip->xmitlock); + if (macupdate) + mac_tx_update(erip->mh); + return (erip->txhung >= eri_txhung_limit); } #endif - -/* Process a DL_CAPABILITY_REQ */ -static void -eri_dlcap_req(queue_t *wq, mblk_t *mp) -{ - struct eristr *sbp; - struct eri *erip; - dl_capability_req_t *icap; - int prim; - mblk_t *nmp; - - sbp = (struct eristr *)wq->q_ptr; - erip = sbp->sb_erip; - icap = (dl_capability_req_t *)mp->b_rptr; - prim = icap->dl_primitive; - - ASSERT(prim == DL_CAPABILITY_REQ); - - ERI_DEBUG_MSG2(erip, DLCAPAB_MSG, "eri_dlcap_req: DL_CAPABILITY for " - "instance=%d\n", erip->instance); - - if (icap->dl_sub_length == 0) { - /* IP wants to have a list of the capabilities we support. */ - ERI_DEBUG_MSG1(erip, DLCAPAB_MSG, "eri_dlcap_req: got request " - "for all capabilities"); - - nmp = eri_dlcap_all(wq); - if (nmp == NULL) { - dlerrorack(wq, mp, prim, DL_SYSERR, ENOSR); - return; - } - freemsg(mp); - } else { - /* - * IP is probably trying to enable or disable one or more - * capabilities. Reuse received mp to construct reply. - */ - ERI_DEBUG_MSG1(erip, DLCAPAB_MSG, "eri_dlcap_req: got len!=0 " - "DL_CAPABILITY_REQ\n"); - eri_dlcap_enable(wq, mp); - nmp = mp; - } - ASSERT(nmp != NULL); - - /* send reply back up */ - ERI_DEBUG_MSG1(erip, DLCAPAB_MSG, "eri_dlcap_req: sending ACK\n"); - qreply(wq, nmp); -} - -static mblk_t * -eri_dlcap_all(queue_t *wq) -{ - mblk_t *nmp; - dl_capability_ack_t *ocap; - dl_capability_sub_t *osub; - dl_capab_hcksum_t *ocksum; - uint_t size; - - /* Size of reply to send back up, say we support hardware checksum */ - size = sizeof (dl_capability_ack_t) + - sizeof (dl_capability_sub_t) + - sizeof (dl_capab_hcksum_t); - - /* allocate result mblk and get it started */ - if ((nmp = allocb(size, BPRI_MED)) == NULL) - return (NULL); - - /* update mblk info */ - nmp->b_datap->db_type = M_PROTO; - - /* dl_capability_ack_t, one per message */ - ocap = (dl_capability_ack_t *)nmp->b_rptr; - ocap->dl_primitive = DL_CAPABILITY_ACK; - ocap->dl_sub_length = size - sizeof (dl_capability_ack_t); - ocap->dl_sub_offset = sizeof (dl_capability_ack_t); - nmp->b_wptr += sizeof (dl_capability_ack_t); - - /* dl_capability_sub_t for hardware checksum offload */ - osub = (dl_capability_sub_t *)nmp->b_wptr; - osub->dl_cap = DL_CAPAB_HCKSUM; - osub->dl_length = sizeof (dl_capab_hcksum_t); - nmp->b_wptr += sizeof (dl_capability_sub_t); - - /* dl_capab_hcksum_t */ - ocksum = (dl_capab_hcksum_t *)nmp->b_wptr; - ocksum->hcksum_version = HCKSUM_VERSION_1; - /* tell ip that we're capable, but don't enable until ip says so */ - ocksum->hcksum_txflags = HCKSUM_INET_PARTIAL; - dlcapabsetqid(&ocksum->hcksum_mid, RD(wq)); - nmp->b_wptr += sizeof (dl_capab_hcksum_t); - - return (nmp); -} - -/* Process a non-zero length DL_CAPABILITY_REQ message */ -static void -eri_dlcap_enable(queue_t *wq, mblk_t *mp) -{ - struct eristr *sbp; - struct eri *erip; - dl_capability_req_t *icap; - dl_capability_sub_t *isub, *endp; - dl_capab_hcksum_t *icksum; - - sbp = (struct eristr *)wq->q_ptr; - ASSERT(MUTEX_HELD(&sbp->sb_lock)); - erip = sbp->sb_erip; - icap = (dl_capability_req_t *)mp->b_rptr; - icap->dl_primitive = DL_CAPABILITY_ACK; - - /* Make sure that IP supplied correct dl_sub_length */ - if ((sizeof (*icap) + icap->dl_sub_length) > MBLKL(mp)) { - ERI_DEBUG_MSG2(erip, DLCAPAB_MSG, "eri_dlcap_enable: bad " - "DL_CAPABILITY_REQ, invalid dl_sub_length (%d)\n", - icap->dl_sub_length); - return; - } - -#define SC(base, offset) (dl_capability_sub_t *)(((uchar_t *)(base))+(offset)) - /* - * There are sub-capabilities. Process the ones we know about. - * Loop until we don't have room for another sub-cap header.. - */ - for (isub = SC(icap, icap->dl_sub_offset), - endp = SC(isub, icap->dl_sub_length - sizeof (*isub)); - isub <= endp; isub = SC(isub, - sizeof (dl_capability_sub_t) + isub->dl_length)) { - - switch (isub->dl_cap) { - case DL_CAPAB_HCKSUM: - if ((uint8_t *)(isub + 1) + isub->dl_length > - mp->b_wptr) { - ERI_DEBUG_MSG1(erip, DLCAPAB_MSG, - "eri_dlcap_enable: malformed " - "sub-capability too long for mblk"); - break; - } - icksum = (dl_capab_hcksum_t *)(isub + 1); - - if (icksum->hcksum_txflags & HCKSUM_ENABLE) - sbp->sb_flags |= ERI_SCKSUM; - else - sbp->sb_flags &= ~ERI_SCKSUM; - dlcapabsetqid(&icksum->hcksum_mid, RD(wq)); - break; - - default: - /* Unknown sub-capability; ignore it */ - break; - } - } -#undef SC -}
--- a/usr/src/uts/sun/sys/eri.h Thu Jun 07 06:43:34 2007 -0700 +++ b/usr/src/uts/sun/sys/eri.h Thu Jun 07 06:48:35 2007 -0700 @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -36,9 +35,6 @@ #ifdef _KERNEL -#define ETHERTYPE_IPV4 ETHERTYPE_IP -#define ETHERTYPE_IPV6 (0x86dd) /* IPv6 */ - /* Named Dispatch Parameter Management Structure */ typedef struct param_s { uint32_t param_min; @@ -103,6 +99,7 @@ uint32_t pause_oncount; uint32_t pause_offcount; uint32_t pause_time_count; + uint32_t pausing; /* * Software event stats @@ -174,17 +171,6 @@ #define HSTATN(erip, x, n) erip->stats.x += n; -/* - * Definitions for module_info. - */ - -#define ERI_IDNUM (130) /* module ID number */ -#define ERI_NAME "eri" /* module name */ -#define ERI_MINPSZ (0) /* min packet size */ -#define ERI_MAXPSZ (ETHERMTU +14) /* max packet size */ -#define ERI_HIWAT (128 * 1024) /* hi-water mark */ -#define ERI_LOWAT (1) /* lo-water mark */ - #define TX_BCOPY_MAX 704 /* bcopy for packets < 704 bytes */ #define RX_BCOPY_MAX 704 /* bcopy for packets < 704 bytes */ #define TX_STREAM_MIN 512 @@ -199,52 +185,8 @@ * ordered on minor device number. */ -#define NMCHASH 64 /* # of multicast hash buckets */ -#define INIT_BUCKET_SIZE 16 /* Initial Hash Bucket Size */ #define NMCFILTER_BITS 256 /* # of multicast filter bits */ -struct eristr { - struct eristr *sb_nextp; /* next in list */ - queue_t *sb_rq; /* pointer to our rq */ - struct eri *sb_erip; /* attached device */ - t_uscalar_t sb_state; /* current DL state */ - t_uscalar_t sb_sap; /* bound sap */ - uint32_t sb_flags; /* misc. flags */ - minor_t sb_minor; /* minor device number */ - - struct ether_addr - *sb_mctab[NMCHASH]; /* Hash table of multicast addrs */ - uint32_t sb_mccount[NMCHASH]; /* # valid addresses in mctab[i] */ - uint32_t sb_mcsize[NMCHASH]; /* Allocated size of mctab[i] */ - - uint16_t sb_ladrf[NMCFILTER_BITS/16]; /* Multicast filter bits */ - uint16_t sb_ladrf_refcnt[NMCFILTER_BITS]; - /* Reference count for filter bits */ - - kmutex_t sb_lock; /* protect this structure */ - - uint32_t sb_notifications; /* DLPI notifications */ -}; - -#define MCHASH(a) ((*(((uint8_t *)(a)) + 0) ^ \ - *(((uint8_t *)(a)) + 1) ^ \ - *(((uint8_t *)(a)) + 2) ^ \ - *(((uint8_t *)(a)) + 3) ^ \ - *(((uint8_t *)(a)) + 4) ^ \ - *(((uint8_t *)(a)) + 5)) % (uint32_t)NMCHASH) - -/* - * per-stream flags - */ -#define ERI_SFAST 0x01 /* "M_DATA fastpath" mode */ -#define ERI_SRAW 0x02 /* M_DATA plain raw mode */ -#define ERI_SALLPHYS 0x04 /* "promiscuous mode" */ -#define ERI_SALLMULTI 0x08 /* enable all multicast addresses */ -#define ERI_SALLSAP 0x10 /* enable all ether type values */ -#define ERI_SCKSUM 0x20 /* Enable hardware tcp checksumming */ -#define ERI_SMULTI 0x40 /* enable multicast addresses */ -#define ERI_SSERLPBK 0x80 /* Enable SERDES loopback (DIAG) */ -#define ERI_SMACLPBK 0x100 /* Enable MAC int loopback (DIAG) */ /* * Maximum number of receive descriptors posted to the chip. @@ -257,11 +199,6 @@ #define ERI_TPENDING (erip->tpending) /* - * Full DLSAP address length (in struct dladdr format). - */ -#define ERI_ADDRL (sizeof (uint16_t) + ETHERADDRL) - -/* * Return the address of an adjacent descriptor in the given ring. */ #define NEXTRMD(erip, rmdp) (((rmdp) + 1) == (erip)->rmdlimp ? \ @@ -388,20 +325,6 @@ #define ERI_USE_NON_SERIAL_LINK 2 /* Select non-serial-link */ /* - * Speed definitions for param_speed - */ -#define SPEED_10 10 -#define SPEED_100 100 -#define SPEED_UNK 0 - -/* - * Mode definitions for param_mode - */ -#define ERI_MODE_HDX 0 -#define ERI_MODE_FDX 1 -#define ERI_MODE_UDX 2 - -/* * eri_linkup_state" definitions */ #define ERI_START_LINK_BRINGUP 0 @@ -425,8 +348,8 @@ * Each instance is dynamically allocated on first attach. */ struct eri { - struct eri *nextp; /* next in a linked list */ - dev_info_t *dip; /* associated dev_info */ + mac_handle_t mh; /* GLDv3 handle */ + dev_info_t *dip; /* associated dev_info */ uint_t instance; /* instance */ int pci_mode; /* sbus/pci device (future) */ @@ -434,17 +357,16 @@ int low_power_mode; /* E* (low power) */ int asic_rev; /* ERI ASIC rev no. */ int board_rev; /* ERI ASIC rev no. */ - int burstsizes; /* binary encoded val */ + int burstsizes; /* binary encoded val */ int pagesize; /* btop(9f) */ - uint32_t rxfifo_size; /* RX FIFO size */ + uint32_t rxfifo_size; /* RX FIFO size */ int rpending; /* Max.no. of RX bufs post */ int tpending; /* Max.no. of tX bufs post */ int tx_cur_cnt; /* # of packets for int_me */ - uint_t promisc_cnt; /* Promiscous streams open */ - uint_t all_sap_cnt; - uint_t all_multi_cnt; + uint_t multi_refcnt; + boolean_t promisc; int mifpoll_enable; int frame_enable; @@ -453,12 +375,13 @@ int link_pulse_disabled; int xmit_dma_mode; int rcv_dma_mode; - struct ether_addr factaddr; /* factory mac address */ - struct ether_addr ouraddr; /* individual address */ - uint32_t addrflags; /* address flags */ - uint32_t flags; /* misc. flags */ + uint8_t ouraddr[ETHERADDRL]; /* unicast address */ + uint32_t flags; /* misc. flags */ uint32_t alloc_flag; /* Buff alloc. status flags */ - uint32_t wantw; /* xmit: out of resources */ + boolean_t wantw; /* xmit: out of resources */ + + uint16_t ladrf[NMCFILTER_BITS/16]; /* Multicast filter */ + uint16_t ladrf_refcnt[NMCFILTER_BITS]; volatile struct global *globregp; /* ERI global regs */ volatile struct etx *etxregp; /* ERI ETX regs */ @@ -470,9 +393,6 @@ uint32_t *sw_reset_reg; - queue_t *ip4q; /* ip read queue */ - queue_t *ip6q; /* ip read queue */ - uint32_t rx_kick; /* RX kick register val */ uint32_t rx_completion; /* RX completion reg val */ #ifdef RCV_OVRFLOW_CORRUPTION_BUG @@ -576,7 +496,6 @@ int linkup_changed; /* link bringup state */ int linkcheck; - int linksts_msg; caddr_t g_nd; /* head of the */ /* named dispatch table */ @@ -614,7 +533,6 @@ mblk_t *tmblkp[ERI_TMDMAX]; /* mblks assoc with TMD */ mblk_t *rmblkp[ERI_RMDMAX]; /* mblks assoc with RMD */ param_t param_arr[ERI_PARAM_CNT]; - uint_t param_display[ERI_PARAM_CNT]; /* cntrl display */ struct stats stats; /* kstats */ @@ -623,18 +541,8 @@ */ uint32_t starts; uint32_t txhung; - time_t msg_time; struct erisave erisave; -#ifdef XMIT_SERIAL_QUEUE - /* A syncq implementation. */ - mblk_t *sqfirst; /* first mblk chain or NULL */ - mblk_t *sqlast; /* last mblk chain or NULL */ - kmutex_t sqlock; /* lock before using any member */ - uint16_t sqrefcnt; /* count of threads using */ - uint16_t sqnmblks; -#endif - uint64_t ifspeed_old; #ifdef ERI_RMAC_HANG_WORKAROUND @@ -648,6 +556,16 @@ uint32_t tx_int_me; }; +/* + * LADRF bit array manipulation macros. These are for working within the + * array of words defined by erip->ladrf, converting a bit (0-255) into + * the index and offset in the ladrf bit array. Note that the array is + * provided in "Big Endian" order. + */ +#define LADRF_MASK(bit) (1 << ((bit) % 16)) +#define LADRF_WORD(erip, bit) erip->ladrf[(15 - ((bit) / 16))] +#define LADRF_SET(erip, bit) (LADRF_WORD(erip, bit) |= LADRF_MASK(bit)) +#define LADRF_CLR(erip, bit) (LADRF_WORD(erip, bit) &= ~LADRF_MASK(bit)) /* * ERI IOCTLS. @@ -679,8 +597,7 @@ */ #define ERI_UNKOWN 0x00 /* unknown state */ #define ERI_RUNNING 0x01 /* chip is initialized */ -#define ERI_PROMISC 0x02 /* promiscuous mode enabled */ -#define ERI_MULTICAST 0x04 /* Multicast mode enabled */ +#define ERI_STARTED 0x02 /* mac layer started */ #define ERI_SUSPENDED 0x08 /* suspended interface */ #define ERI_INITIALIZED 0x10 /* interface initialized */ #define ERI_NOTIMEOUTS 0x20 /* disallow timeout rescheduling */ @@ -689,7 +606,6 @@ #define ERI_MACLOOPBACK 0x100 /* device has MAC int lpbk (DIAG) */ #define ERI_SERLOOPBACK 0x200 /* device has SERDES int lpbk (DIAG) */ #define ERI_DLPI_LINKUP 0x400 /* */ -#define ERI_ALLMULTI 0x800 /* */ /* * Mac address flags @@ -699,46 +615,12 @@ struct erikstat { /* - * Link Input/Output stats - */ - struct kstat_named erik_ipackets; - struct kstat_named erik_ierrors; - struct kstat_named erik_opackets; - struct kstat_named erik_oerrors; - struct kstat_named erik_collisions; - struct kstat_named erik_ifspeed; /* Interface Speed */ - /* - * required by kstat for MIB II objects(RFC 1213) - */ - struct kstat_named erik_rbytes; /* # octets received */ - /* MIB - ifInOctets */ - struct kstat_named erik_obytes; /* # octets transmitted */ - /* MIB - ifOutOctets */ - struct kstat_named erik_multircv; /* # multicast packets */ - /* delivered to upper layer */ - /* MIB - ifInNUcastPkts */ - struct kstat_named erik_multixmt; /* # multicast packets */ - /* requested to be sent */ - /* MIB - ifOutNUcastPkts */ - struct kstat_named erik_brdcstrcv; /* # broadcast packets */ - /* delivered to upper layer */ - /* MIB - ifInNUcastPkts */ - struct kstat_named erik_brdcstxmt; /* # broadcast packets */ - /* requested to be sent */ - /* MIB - ifOutNUcastPkts */ - struct kstat_named erik_norcvbuf; /* # rcv packets discarded */ - /* MIB - ifInDiscards */ - struct kstat_named erik_noxmtbuf; /* # xmt packets discarded */ - /* MIB - ifOutDiscards */ - /* * Software event stats */ struct kstat_named erik_inits; struct kstat_named erik_rx_inits; struct kstat_named erik_tx_inits; - struct kstat_named erik_tnocar; /* Link down counter */ - struct kstat_named erik_nocanput; struct kstat_named erik_allocbfail; struct kstat_named erik_drop; @@ -753,11 +635,7 @@ /* * MAC TX Event stats */ - struct kstat_named erik_txmac_urun; struct kstat_named erik_txmac_maxpkt_err; - struct kstat_named erik_excessive_coll; - struct kstat_named erik_late_coll; - struct kstat_named erik_first_coll; struct kstat_named erik_defer_timer_exp; struct kstat_named erik_peak_attempt_cnt; struct kstat_named erik_jab; @@ -767,17 +645,11 @@ /* * MAC RX Event stats */ - struct kstat_named erik_rx_corr; struct kstat_named erik_no_free_rx_desc; /* no free rx desc. */ - struct kstat_named erik_rx_overflow; struct kstat_named erik_rx_hang; - struct kstat_named erik_rx_align_err; - struct kstat_named erik_rx_crc_err; struct kstat_named erik_rx_length_err; struct kstat_named erik_rx_code_viol_err; struct kstat_named erik_rx_bad_pkts; - struct kstat_named erik_rx_runt; - struct kstat_named erik_rx_toolong_pkts; /* * Fatal errors @@ -806,21 +678,7 @@ struct kstat_named erik_pci_det_parity_err; - /* - * PSARC 1997/198 : 64bit kstats - */ - struct kstat_named erik_ipackets64; - struct kstat_named erik_opackets64; - struct kstat_named erik_rbytes64; /* # octets received */ - /* MIB - ifInOctets */ - struct kstat_named erik_obytes64; /* # octets transmitted */ - /* MIB - ifOutOctets */ - struct kstat_named erik_pmcap; /* Power management */ - - struct kstat_named erik_link_up; /* Link Status */ - - struct kstat_named erik_link_duplex; /* Link duplex */ }; /* TBD: new value ? */ @@ -849,13 +707,6 @@ #define ERI_FSTBYTE_OFFSET 2 #define ERI_CKSUM_OFFSET 14 -/* - * Private DLPI full dlsap address format. - */ -struct eridladdr { - struct ether_addr dl_phys; - uint16_t dl_sap; -}; #define ERI_PMCAP_NONE 0 #define ERI_PMCAP_4MHZ 4
--- a/usr/src/uts/sun/sys/eri_common.h Thu Jun 07 06:43:34 2007 -0700 +++ b/usr/src/uts/sun/sys/eri_common.h Thu Jun 07 06:48:35 2007 -0700 @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 1999-2001, 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -35,7 +34,6 @@ #ifdef _KERNEL -typedef int (*fptri_t)(); typedef void (*fptrv_t)(); typedef enum { @@ -70,16 +68,16 @@ #define ERI_FAULT_MSG1(p, t, f, a) \ - eri_fault_msg(__FILE__, __LINE__, (p), (t), (f), (a)); + eri_fault_msg((p), (t), (f), (a)); #define ERI_FAULT_MSG2(p, t, f, a, b) \ - eri_fault_msg(__FILE__, __LINE__, (p), (t), (f), (a), (b)); + eri_fault_msg((p), (t), (f), (a), (b)); #define ERI_FAULT_MSG3(p, t, f, a, b, c) \ - eri_fault_msg(__FILE__, __LINE__, (p), (t), (f), (a), (b), (c)); + eri_fault_msg((p), (t), (f), (a), (b), (c)); #define ERI_FAULT_MSG4(p, t, f, a, b, c, d) \ - eri_fault_msg(__FILE__, __LINE__, (p), (t), (f), (a), (b), (c), (d)); + eri_fault_msg((p), (t), (f), (a), (b), (c), (d)); #ifdef DEBUG typedef enum { @@ -178,8 +176,8 @@ "DLCAPAB" }; -static void eri_debug_msg(char *, int, struct eri *, debug_msg_t, - char *, ...); +static void eri_debug_msg(const char *, int, struct eri *, debug_msg_t, + const char *, ...); #define ERI_DEBUG_MSG1(t, f, a) \ eri_debug_msg(__FILE__, __LINE__, (t), (f), (a)); @@ -298,7 +296,7 @@ #define ERI_MASK_8BIT 0xff #define param_transceiver (erip->param_arr[0].param_val) -#define param_linkup (erip->param_arr[1].param_val) +#define param_linkup (erip->param_arr[1].param_val) #define param_speed (erip->param_arr[2].param_val) #define param_mode (erip->param_arr[3].param_val) #define param_ipg1 (erip->param_arr[4].param_val) @@ -325,33 +323,22 @@ #define param_anlpar_100hdx (erip->param_arr[23].param_val) #define param_anlpar_10fdx (erip->param_arr[24].param_val) #define param_anlpar_10hdx (erip->param_arr[25].param_val) -#define param_device (erip->param_arr[26].param_val) -#define param_lance_mode (erip->param_arr[27].param_val) -#define param_ipg0 (erip->param_arr[28].param_val) -#define param_intr_blank_time (erip->param_arr[29].param_val) -#define param_intr_blank_packets (erip->param_arr[30].param_val) -#define param_serial_link (erip->param_arr[31].param_val) +#define param_lance_mode (erip->param_arr[26].param_val) +#define param_ipg0 (erip->param_arr[27].param_val) +#define param_intr_blank_time (erip->param_arr[28].param_val) +#define param_intr_blank_packets (erip->param_arr[29].param_val) +#define param_serial_link (erip->param_arr[30].param_val) -#define param_non_serial_link (erip->param_arr[32].param_val) -#define param_select_link (erip->param_arr[33].param_val) -#define param_default_link (erip->param_arr[34].param_val) -#define param_link_in_use (erip->param_arr[35].param_val) -#define param_unknown0 (erip->param_arr[36].param_val) -#define param_unknown1 (erip->param_arr[37].param_val) -#define param_unknown2 (erip->param_arr[38].param_val) -#define param_anar_asm_dir (erip->param_arr[39].param_val) -#define param_anar_pause (erip->param_arr[40].param_val) -#define param_unknown3 (erip->param_arr[41].param_val) - -#define param_unknown4 (erip->param_arr[42].param_val) -#define param_unknown5 (erip->param_arr[43].param_val) -#define param_bmsr_asm_dir (erip->param_arr[44].param_val) -#define param_bmsr_pause (erip->param_arr[45].param_val) -#define param_anlpar_autoneg (erip->param_arr[46].param_val) -#define param_unknown6 (erip->param_arr[47].param_val) -#define param_unknown7 (erip->param_arr[48].param_val) +#define param_non_serial_link (erip->param_arr[31].param_val) +#define param_select_link (erip->param_arr[32].param_val) +#define param_default_link (erip->param_arr[33].param_val) +#define param_link_in_use (erip->param_arr[34].param_val) +#define param_anar_asm_dir (erip->param_arr[35].param_val) +#define param_anar_pause (erip->param_arr[36].param_val) +#define param_bmsr_asm_dir (erip->param_arr[37].param_val) +#define param_bmsr_pause (erip->param_arr[38].param_val) #define param_anlpar_pauseTX (erip->param_arr[49].param_val) -#define param_anlpar_pauseRX (erip->param_arr[50].param_val) +#define param_anlpar_pauseRX (erip->param_arr[40].param_val) /* <<<<<<<<<<<<<<<<<<<<<< Register operations >>>>>>>>>>>>>>>>>>>>> */ #define GET_PCSREG(reg) \ @@ -454,57 +441,12 @@ /* - * Ether_copy is not endian-correct. Define an endian-correct version. - */ -#define ether_bcopy(a, b) (bcopy((caddr_t)a, (caddr_t)b, 6)) - -/* * Ether-type is specifically big-endian, but data region is unknown endian + * Ether-type lives at offset 12 from the start of the packet. */ -typedef struct ether_header *eehp; - -#define get_ether_type(ptr) (\ - (((uint8_t *)&((eehp)ptr)->ether_type)[0] << 8) | \ - (((uint8_t *)&((eehp)ptr)->ether_type)[1])) -#define put_ether_type(ptr, value) {\ - ((uint8_t *)(&((eehp)ptr)->ether_type))[0] = \ - ((uint16_t)value & 0xff00) >> 8; \ - ((uint8_t *)(&((eehp)ptr)->ether_type))[1] = (value & 0xff); } - - -/* - * The following MACROS are used to filter out bad packets which are - * a result of descriptor corruption in ERI 1.0 ASIC. The packets are - * either concatenated or truncated. Here we compare the length field - * of the incoming packet with what is reported by the decriptor - * length field. This check is in addition to the illegal packet - * (64 < len < 1518) size check done in eri_read routines. - */ - -#ifdef ERI_ERI_REV_1_0 -#define IP_PACKET_LEN(len) \ - (len - 14) -#define INVALID_IP_PACKET_LENGTH(ipp, len) \ - ((len > 0x3c) && (ipp->ip_len != (len - 14))) - -#define IP_PACKET_IS_TCP(ipp) (ipp->ip_p & 0x06) - -#define ERI_ERX_HANG(wp, rp) \ - ((rp <= wp) ? ((wp - rp) > 1275) : ((rp -wp) < 4)) -#endif - - -#define DEVICE_NAME(dip) \ - ((strcmp(ddi_get_name(dip), "pci108e,1101") == 0) ? \ - "SUNW,eri" : "SUNW,eri:unknown") - -/* - * Allocate and zero-out "number" structures - * each of type "structure" in kernel memory. - */ -#define GETSTRUCT(structure, number) \ - (kmem_zalloc((size_t)(sizeof (structure) * (number)), KM_SLEEP)) +#define get_ether_type(ptr) \ + (((((uint8_t *)ptr)[12] << 8) | (((uint8_t *)ptr)[13]))) #endif /* _KERNEL */
--- a/usr/src/uts/sun/sys/eri_mac.h Thu Jun 07 06:43:34 2007 -0700 +++ b/usr/src/uts/sun/sys/eri_mac.h Thu Jun 07 06:48:35 2007 -0700 @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 1999-2000 by Sun Microsystems, Inc. - * All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. */ #ifndef _SYS_ERI_MAC_H @@ -745,7 +744,7 @@ #define BMAC_SLOT_TIME 0x40 #define BMAC_EXT_SLOT_TIME 0x200 #define BMAC_MIN_FRAME_SIZE 0x40 -#define BMAC_MAX_FRAME_SIZE (ETHERMTU + 18) +#define BMAC_MAX_FRAME_SIZE (ETHERMTU + 18 + 4) /* enet + vlan */ /* * Hardware bug: set MAC_FRAME_SIZE to 0x7fff to
--- a/usr/src/uts/sun/sys/eri_msg.h Thu Jun 07 06:43:34 2007 -0700 +++ b/usr/src/uts/sun/sys/eri_msg.h Thu Jun 07 06:48:35 2007 -0700 @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 1999-2000 by Sun Microsystems, Inc. - * All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. */ #ifndef _SYS_ERI_MSG_H @@ -36,28 +35,6 @@ /* * All strings used by eri messaging functions */ - -#if defined(DEBUG) -#ifdef LATER -static char *par_detect_fault_msg = "Parallel Detection Fault"; -static char *autoneg_speed_bad_msg = "Autonegotiated speed is bad"; -static char *phy_speed_bad_msg = "The current Phy/xcvr speed is not valid"; -static char *no_phy_msg = "No Phy/xcvr found"; -static char *unk_phy_msg = "Non supported Phy/Xcvr, Vendor Id: %x"; -static char *lucent_phy_msg = "Lucent Phy, Vendor Id: %x"; -static char *link_up_msg = "Link Up"; -static char *link_status_msg = "%s %4d Mbps %s-Duplex Link Up"; -#endif -#if 0 -static char *link_down_msg = - "No response from Ethernet network : Link down -- cable problem?"; -#endif -static char *mif_write_fail_msg = "MIF Write failure"; -#endif - -/* - * All strings used by eri messaging functions - */ static char *loopback_val_default = "Loopback Value: Error In Value."; static char *loopback_cmd_default = "Loopback Command: Error In Value."; static char *lmac_addr_msg = "Using local MAC address"; @@ -65,20 +42,6 @@ static char *busy_msg = "Driver is BUSY with upper layer"; static char *attach_fail_msg = "Attach entry point failed"; -#if defined(DEBUG) -static char *attach_bad_cmd_msg = "Attach entry point rcv'd a bad command"; -static char *burst_size_msg = "Could not identify the burst size"; -static char *detach_bad_cmd_msg = "Detach entry point rcv'd a bad command"; -static char *add_intr_fail_msg = "ddi_add_intr(9F) failed"; -static char *create_minor_node_fail_msg = "ddi_create_minor_node(9F) failed"; -#ifdef LATER -static char *mregs_4config_fail_msg = - "ddi_regs_map_setup(9F) for config space failed"; -#endif -static char *mregs_4global_reg_fail_msg = - "ddi_regs_map_setup(9F) for global reg failed"; -#endif - static char *mregs_4soft_reset_fail_msg = "ddi_regs_map_setup(9F) for soft reset failed"; static char *disable_erx_msg = "Can not disable Rx."; @@ -91,8 +54,6 @@ static char *alloc_rx_dmah_msg = "Can not allocate Rx dma handle."; static char *config_space_fatal_msg = "Configuration space failed in routine."; -static char *link_down_msg = - "No response from Ethernet network : Link down -- cable problem?"; static char *kstat_create_fail_msg = "kstat_create failed"; static char *param_reg_fail_msg = "param_register failed";