diff options
author | Garrett D'Amore <gdamore@opensolaris.org> | 2009-10-15 22:31:12 -0700 |
---|---|---|
committer | Garrett D'Amore <gdamore@opensolaris.org> | 2009-10-15 22:31:12 -0700 |
commit | 06673d9b6d946016a5231efebdb7818b7486bafc (patch) | |
tree | 12dff8ea3672b3ef3a9cb4e3893f321b9b1013c9 /usr/src | |
parent | ec39b9cf9a38586835b89f8cc2150710071adce3 (diff) | |
download | illumos-gate-06673d9b6d946016a5231efebdb7818b7486bafc.tar.gz |
6890821 hme should use common MII layer
6839675 hme ndd 10 mbps force failure (NICDRV test06 failure)
6890820 assertion failure in hme on x86
6890573 hme should not call mi_strtol
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/uts/common/io/hme/hme.c | 2446 | ||||
-rw-r--r-- | usr/src/uts/common/io/hme/hme.h | 187 | ||||
-rw-r--r-- | usr/src/uts/common/io/mii/mii_other.c | 3 | ||||
-rw-r--r-- | usr/src/uts/common/sys/miiregs.h | 3 | ||||
-rw-r--r-- | usr/src/uts/intel/hme/Makefile | 2 | ||||
-rw-r--r-- | usr/src/uts/sparc/hme/Makefile | 15 |
6 files changed, 256 insertions, 2400 deletions
diff --git a/usr/src/uts/common/io/hme/hme.c b/usr/src/uts/common/io/hme/hme.c index 580a8b2996..d90382a7ff 100644 --- a/usr/src/uts/common/io/hme/hme.c +++ b/usr/src/uts/common/io/hme/hme.c @@ -38,14 +38,12 @@ #include <sys/conf.h> #include <sys/strsun.h> #include <sys/kstat.h> -#include <inet/common.h> -#include <inet/mi.h> -#include <inet/nd.h> #include <sys/pattr.h> #include <sys/dlpi.h> #include <sys/strsubr.h> #include <sys/mac_provider.h> #include <sys/mac_ether.h> +#include <sys/mii.h> #include <sys/ethernet.h> #include <sys/vlan.h> #include <sys/pci.h> @@ -60,37 +58,18 @@ typedef void (*fptrv_t)(); typedef enum { NO_MSG = 0, - AUTOCONFIG_MSG = 1, - STREAMS_MSG = 2, - IOCTL_MSG = 3, - PROTO_MSG = 4, - INIT_MSG = 5, - TX_MSG = 6, - RX_MSG = 7, - INTR_MSG = 8, - UNINIT_MSG = 9, - CONFIG_MSG = 10, - PROP_MSG = 11, - ENTER_MSG = 12, - RESUME_MSG = 13, - AUTONEG_MSG = 14, - NAUTONEG_MSG = 15, - FATAL_ERR_MSG = 16, - NFATAL_ERR_MSG = 17, - NDD_MSG = 18, - PHY_MSG = 19, - XCVR_MSG = 20, - NOXCVR_MSG = 21, - NSUPPORT_MSG = 22, - ERX_MSG = 23, - FREE_MSG = 24, - IPG_MSG = 25, - DDI_MSG = 26, - DEFAULT_MSG = 27, - DISPLAY_MSG = 28, - LATECOLL_MSG = 29, - MIFPOLL_MSG = 30, - LINKPULSE_MSG = 31 + AUTOCONFIG_MSG, + DISPLAY_MSG, + INIT_MSG, + UNINIT_MSG, + CONFIG_MSG, + MII_MSG, + FATAL_ERR_MSG, + NFATAL_ERR_MSG, + XCVR_MSG, + NOXCVR_MSG, + ERX_MSG, + DDI_MSG, } msg_t; msg_t hme_debug_level = NO_MSG; @@ -98,36 +77,17 @@ msg_t hme_debug_level = NO_MSG; static char *msg_string[] = { "NONE ", "AUTOCONFIG ", - "STREAMS ", - "IOCTL ", - "PROTO ", + "DISPLAY " "INIT ", - "TX ", - "RX ", - "INTR ", "UNINIT ", "CONFIG ", - "PROP ", - "ENTER ", - "RESUME ", - "AUTONEG ", - "NAUTONEG ", + "MII ", "FATAL_ERR ", "NFATAL_ERR ", - "NDD ", - "PHY ", "XCVR ", "NOXCVR ", - "NSUPPOR ", "ERX ", - "FREE ", - "IPG ", "DDI ", - "DEFAULT ", - "DISPLAY " - "LATECOLL_MSG ", - "MIFPOLL_MSG ", - "LINKPULSE_MSG " }; #define SEVERITY_NONE 0 @@ -151,30 +111,19 @@ static int hme_urun_fix = 0; /* Bug fixed in Sbus/FEPS 2.0 */ */ static int hme_64bit_enable = 1; /* Use 64-bit sbus transfers */ static int hme_reject_own = 1; /* Reject packets with own SA */ -static int hme_autoneg_enable = 1; /* Enable auto-negotiation */ - -static int hme_ngu_enable = 1; /* to enable Never Give Up mode */ -static int hme_mifpoll_enable = 1; /* to enable mif poll */ +static int hme_ngu_enable = 0; /* Never Give Up mode */ -/* - * The following variables are used for configuring link-operation. - * Later these parameters may be changed per interface using "ndd" command - * These parameters may also be specified as properties using the .conf - * file mechanism for each interface. - */ +mac_priv_prop_t hme_priv_prop[] = { + { "_ipg0", MAC_PROP_PERM_RW }, + { "_ipg1", MAC_PROP_PERM_RW }, + { "_ipg2", MAC_PROP_PERM_RW }, + { "_lance_mode", MAC_PROP_PERM_RW }, +}; static int hme_lance_mode = 1; /* to enable lance mode */ static int hme_ipg0 = 16; static int hme_ipg1 = 8; static int hme_ipg2 = 4; -static int hme_use_int_xcvr = 0; -static int hme_pace_size = 0; /* Do not use pacing */ - -/* - * The following variable value will be overridden by "link-pulse-disabled" - * property which may be created by OBP or hme.conf file. - */ -static int hme_link_pulse_disabled = 0; /* link pulse disabled */ /* * The following parameters may be configured by the user. If they are not @@ -189,67 +138,10 @@ static int hme_link_pulse_disabled = 0; /* link pulse disabled */ #define HME_MASK_5BIT 0x1f #define HME_MASK_8BIT 0xff -static int hme_adv_autoneg_cap = HME_NOTUSR | 0; -static int hme_adv_100T4_cap = HME_NOTUSR | 0; -static int hme_adv_100fdx_cap = HME_NOTUSR | 0; -static int hme_adv_100hdx_cap = HME_NOTUSR | 0; -static int hme_adv_10fdx_cap = HME_NOTUSR | 0; -static int hme_adv_10hdx_cap = HME_NOTUSR | 0; - -/* - * PHY_IDR1 and PHY_IDR2 values to identify National Semiconductor's DP83840 - * Rev C chip which needs some work-arounds. - */ -#define HME_NSIDR1 0x2000 -#define HME_NSIDR2 0x5c00 /* IDR2 register for with revision no. 0 */ - -/* - * PHY_IDR1 and PHY_IDR2 values to identify Quality Semiconductor's QS6612 - * chip which needs some work-arounds. - * Addition Interface Technologies Group (NPG) 8/28/1997. - */ -#define HME_QSIDR1 0x0181 -#define HME_QSIDR2 0x4400 /* IDR2 register for with revision no. 0 */ - -/* - * The least significant 4 bits of HME_NSIDR2 represent the revision - * no. of the DP83840 chip. For Rev-C of DP83840, the rev. no. is 0. - * The next revision of the chip is called DP83840A and the value of - * HME_NSIDR2 is 0x5c01 for this new chip. All the workarounds specific - * to DP83840 chip are valid for both the revisions of the chip. - * Assuming that these workarounds are valid for the future revisions - * also, we will apply these workarounds independent of the revision no. - * Hence we mask out the last 4 bits of the IDR2 register and compare - * with 0x5c00 value. - */ - -#define HME_DP83840 ((hmep->hme_idr1 == HME_NSIDR1) && \ - ((hmep->hme_idr2 & 0xfff0) == HME_NSIDR2)) -/* - * Likewise for the QSI 6612 Fast ethernet phy. - * Addition Interface Technologies Group (NPG) 8/28/1997. - */ -#define HME_QS6612 ((hmep->hme_idr1 == HME_QSIDR1) && \ - ((hmep->hme_idr2 & 0xfff0) == HME_QSIDR2)) /* * All strings used by hme messaging functions */ -static char *par_detect_msg = - "Parallel detection fault."; - -static char *xcvr_no_mii_msg = - "Transceiver does not talk MII."; - -static char *xcvr_isolate_msg = - "Transceiver isolate failed."; - -static char *int_xcvr_msg = - "Internal Transceiver Selected."; - -static char *ext_xcvr_msg = - "External Transceiver Selected."; - static char *no_xcvr_msg = "No transceiver found."; @@ -277,9 +169,6 @@ static char *mregs_4bmac_reg_fail_msg = static char *mregs_4mif_reg_fail_msg = "ddi_map_regs for mif reg failed"; -static char *param_reg_fail_msg = - "parameter register error"; - static char *init_fail_gen_msg = "Failed to initialize hardware/driver"; @@ -289,12 +178,6 @@ static char *ddi_nregs_fail_msg = static char *bad_num_regs_msg = "Invalid number of registers."; -static char *anar_not_set_msg = - "External Transceiver: anar not set with speed selection"; - -static char *par_detect_anar_not_set_msg = - "External Transceiver: anar not set with speed selection"; - /* FATAL ERR msgs */ /* @@ -323,44 +206,15 @@ static void hmesavecntrs(struct hme *); static void hme_fatal_err(struct hme *, uint_t); static void hme_nonfatal_err(struct hme *, uint_t); static int hmeburstsizes(struct hme *); -static void hme_start_mifpoll(struct hme *); -static void hme_stop_mifpoll(struct hme *); -static void hme_param_cleanup(struct hme *); -static int hme_param_get(queue_t *q, mblk_t *mp, caddr_t cp); -static int hme_param_register(struct hme *, hmeparam_t *, int); -static int hme_param_set(queue_t *, mblk_t *, char *, caddr_t); -static void send_bit(struct hme *, uint_t); -static uint_t get_bit(struct hme *); -static uint_t get_bit_std(struct hme *); -static uint_t hme_bb_mii_read(struct hme *, uchar_t, uint16_t *); -static void hme_bb_mii_write(struct hme *, uchar_t, uint16_t); +static void send_bit(struct hme *, uint16_t); +static uint16_t get_bit_std(uint8_t, struct hme *); +static uint16_t hme_bb_mii_read(struct hme *, uint8_t, uint8_t); +static void hme_bb_mii_write(struct hme *, uint8_t, uint8_t, uint16_t); static void hme_bb_force_idle(struct hme *); -static uint_t hme_mii_read(struct hme *, uchar_t, uint16_t *); -static void hme_mii_write(struct hme *, uchar_t, uint16_t); -static void hme_stop_timer(struct hme *); -static void hme_start_timer(struct hme *, fptrv_t, int); -static int hme_select_speed(struct hme *, int); -static void hme_reset_transceiver(struct hme *); -static void hme_check_transceiver(struct hme *); -static void hme_setup_link_default(struct hme *); -static void hme_setup_link_status(struct hme *); -static void hme_setup_link_control(struct hme *); -static int hme_check_txhung(struct hme *hmep); -static void hme_check_link(void *); - -static void hme_init_xcvr_info(struct hme *); -static void hme_disable_link_pulse(struct hme *); -static void hme_force_speed(void *); -static void hme_get_autoinfo(struct hme *); -static int hme_try_auto_negotiation(struct hme *); -static void hme_try_speed(void *); -static void hme_link_now_up(struct hme *); +static uint16_t hme_mii_read(void *, uint8_t, uint8_t); +static void hme_mii_write(void *, uint8_t, uint8_t, uint16_t); static void hme_setup_mac_address(struct hme *, dev_info_t *); - -static void hme_nd_free(caddr_t *nd_pparam); -static int hme_nd_getset(queue_t *q, caddr_t nd_param, MBLKP mp); -static boolean_t hme_nd_load(caddr_t *nd_pparam, char *name, - pfi_t get_pfi, pfi_t set_pfi, caddr_t data); +static void hme_mii_notify(void *, link_state_t); static void hme_fault_msg(struct hme *, uint_t, msg_t, char *, ...); @@ -377,11 +231,22 @@ static int hme_m_promisc(void *, boolean_t); static int hme_m_multicst(void *, boolean_t, const uint8_t *); static int hme_m_unicst(void *, const uint8_t *); static mblk_t *hme_m_tx(void *, mblk_t *); -static void hme_m_ioctl(void *, queue_t *, mblk_t *); static boolean_t hme_m_getcapab(void *, mac_capab_t, void *); +static int hme_m_getprop(void *, const char *, mac_prop_id_t, uint_t, + uint_t, void *, uint_t *); +static int hme_m_setprop(void *, const char *, mac_prop_id_t, uint_t, + const void *); + +static mii_ops_t hme_mii_ops = { + MII_OPS_VERSION, + hme_mii_read, + hme_mii_write, + hme_mii_notify, + NULL +}; static mac_callbacks_t hme_m_callbacks = { - MC_IOCTL | MC_GETCAPAB, + MC_GETCAPAB | MC_SETPROP | MC_GETPROP, hme_m_stat, hme_m_start, hme_m_stop, @@ -389,8 +254,12 @@ static mac_callbacks_t hme_m_callbacks = { hme_m_multicst, hme_m_unicst, hme_m_tx, - hme_m_ioctl, + NULL, hme_m_getcapab, + NULL, + NULL, + hme_m_setprop, + hme_m_getprop, }; DDI_DEFINE_STREAM_OPS(hme_dev_ops, nulldev, nulldev, hmeattach, hmedetach, @@ -473,13 +342,6 @@ static struct modlinkage modlinkage = { MODREV_1, &modldrv, NULL }; -/* - * Internal PHY Id: - */ - -#define HME_BB1 0x15 /* Babybac1, Rev 1.5 */ -#define HME_BB2 0x20 /* Babybac2, Rev 0 */ - /* <<<<<<<<<<<<<<<<<<<<<< Register operations >>>>>>>>>>>>>>>>>>>>> */ #define GET_MIFREG(reg) \ @@ -559,46 +421,26 @@ hmeladrf_bit(const uint8_t *addr) /* <<<<<<<<<<<<<<<<<<<<<<<< Bit Bang Operations >>>>>>>>>>>>>>>>>>>>>>>> */ -static int hme_internal_phy_id = HME_BB2; /* Internal PHY is Babybac2 */ - - static void -send_bit(struct hme *hmep, uint32_t x) +send_bit(struct hme *hmep, uint16_t x) { PUT_MIFREG(mif_bbdata, x); PUT_MIFREG(mif_bbclk, HME_BBCLK_LOW); PUT_MIFREG(mif_bbclk, HME_BBCLK_HIGH); } -/* - * To read the MII register bits from the Babybac1 transceiver - */ -static uint32_t -get_bit(struct hme *hmep) -{ - uint32_t x; - - PUT_MIFREG(mif_bbclk, HME_BBCLK_LOW); - PUT_MIFREG(mif_bbclk, HME_BBCLK_HIGH); - if (hmep->hme_transceiver == HME_INTERNAL_TRANSCEIVER) - x = (GET_MIFREG(mif_cfg) & HME_MIF_CFGM0) ? 1 : 0; - else - x = (GET_MIFREG(mif_cfg) & HME_MIF_CFGM1) ? 1 : 0; - return (x); -} - /* * To read the MII register bits according to the IEEE Standard */ -static uint32_t -get_bit_std(struct hme *hmep) +static uint16_t +get_bit_std(uint8_t phyad, struct hme *hmep) { - uint32_t x; + uint16_t x; PUT_MIFREG(mif_bbclk, HME_BBCLK_LOW); drv_usecwait(1); /* wait for >330 ns for stable data */ - if (hmep->hme_transceiver == HME_INTERNAL_TRANSCEIVER) + if (phyad == HME_INTERNAL_PHYAD) x = (GET_MIFREG(mif_cfg) & HME_MIF_CFGM0) ? 1 : 0; else x = (GET_MIFREG(mif_cfg) & HME_MIF_CFGM1) ? 1 : 0; @@ -607,18 +449,15 @@ get_bit_std(struct hme *hmep) } #define SEND_BIT(x) send_bit(hmep, x) -#define GET_BIT(x) x = get_bit(hmep) -#define GET_BIT_STD(x) x = get_bit_std(hmep) +#define GET_BIT_STD(phyad, x) x = get_bit_std(phyad, hmep) static void -hme_bb_mii_write(struct hme *hmep, uint8_t regad, uint16_t data) +hme_bb_mii_write(struct hme *hmep, uint8_t phyad, uint8_t regad, uint16_t data) { - uint8_t phyad; int i; PUT_MIFREG(mif_bbopenb, 1); /* Enable the MII driver */ - phyad = hmep->hme_phyad; (void) hme_bb_force_idle(hmep); SEND_BIT(0); SEND_BIT(1); /* <ST> */ SEND_BIT(0); SEND_BIT(1); /* <OP> */ @@ -642,18 +481,14 @@ hme_bb_mii_write(struct hme *hmep, uint8_t regad, uint16_t data) } /* Return 0 if OK, 1 if error (Transceiver does not talk management) */ -static uint_t -hme_bb_mii_read(struct hme *hmep, uint8_t regad, uint16_t *datap) +static uint16_t +hme_bb_mii_read(struct hme *hmep, uint8_t phyad, uint8_t regad) { - uint8_t phyad; int i; uint32_t x; - uint32_t y; - - *datap = 0; + uint16_t data = 0; PUT_MIFREG(mif_bbopenb, 1); /* Enable the MII driver */ - phyad = hmep->hme_phyad; (void) hme_bb_force_idle(hmep); SEND_BIT(0); SEND_BIT(1); /* <ST> */ SEND_BIT(1); SEND_BIT(0); /* <OP> */ @@ -666,36 +501,20 @@ hme_bb_mii_read(struct hme *hmep, uint8_t regad, uint16_t *datap) PUT_MIFREG(mif_bbopenb, 0); /* Disable the MII driver */ - if ((hme_internal_phy_id == HME_BB2) || - (hmep->hme_transceiver == HME_EXTERNAL_TRANSCEIVER)) { - GET_BIT_STD(x); - GET_BIT_STD(y); /* <TA> */ - for (i = 0xf; i >= 0; i--) { /* <DDDDDDDDDDDDDDDD> */ - GET_BIT_STD(x); - *datap += (x << i); - } - /* - * Kludge to get the Transceiver out of hung mode - */ - GET_BIT_STD(x); - GET_BIT_STD(x); - GET_BIT_STD(x); - } else { - GET_BIT(x); - GET_BIT(y); /* <TA> */ - for (i = 0xf; i >= 0; i--) { /* <DDDDDDDDDDDDDDDD> */ - GET_BIT(x); - *datap += (x << i); - } - /* - * Kludge to get the Transceiver out of hung mode - */ - GET_BIT(x); - GET_BIT(x); - GET_BIT(x); + GET_BIT_STD(phyad, x); + GET_BIT_STD(phyad, x); /* <TA> */ + for (i = 0xf; i >= 0; i--) { /* <DDDDDDDDDDDDDDDD> */ + GET_BIT_STD(phyad, x); + data += (x << i); } + /* + * Kludge to get the Transceiver out of hung mode + */ + GET_BIT_STD(phyad, x); + GET_BIT_STD(phyad, x); + GET_BIT_STD(phyad, x); CHECK_MIFREG(); - return (y); + return (data); } @@ -715,19 +534,14 @@ hme_bb_force_idle(struct hme *hmep) /* <<<<<<<<<<<<< Frame Register used for MII operations >>>>>>>>>>>>>>>>>>>> */ /* Return 0 if OK, 1 if error (Transceiver does not talk management) */ -static uint_t -hme_mii_read(struct hme *hmep, uchar_t regad, uint16_t *datap) +static uint16_t +hme_mii_read(void *arg, uint8_t phyad, uint8_t regad) { + struct hme *hmep = arg; uint32_t frame; - uint8_t phyad; - - if (hmep->hme_transceiver == HME_NO_TRANSCEIVER) - return (1); /* No transceiver present */ if (!hmep->hme_frame_enable) - return (hme_bb_mii_read(hmep, regad, datap)); - - phyad = hmep->hme_phyad; + return (hme_bb_mii_read(hmep, phyad, regad)); PUT_MIFREG(mif_frame, HME_MIF_FRREAD | (phyad << HME_MIF_FRPHYAD_SHIFT) | @@ -741,29 +555,24 @@ hme_mii_read(struct hme *hmep, uchar_t regad, uint16_t *datap) if ((frame & HME_MIF_FRTA0) == 0) { - HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, NAUTONEG_MSG, + HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, MII_MSG, "MIF Read failure"); - return (1); - } else { - *datap = (uint16_t)(frame & HME_MIF_FRDATA); - return (0); + return (0xffff); } - + return ((uint16_t)(frame & HME_MIF_FRDATA)); } static void -hme_mii_write(struct hme *hmep, uint8_t regad, uint16_t data) +hme_mii_write(void *arg, uint8_t phyad, uint8_t regad, uint16_t data) { + struct hme *hmep = arg; uint32_t frame; - uint8_t phyad; if (!hmep->hme_frame_enable) { - hme_bb_mii_write(hmep, regad, data); + hme_bb_mii_write(hmep, phyad, regad, data); return; } - phyad = hmep->hme_phyad; - PUT_MIFREG(mif_frame, HME_MIF_FRWRITE | (phyad << HME_MIF_FRPHYAD_SHIFT) | (regad << HME_MIF_FRREGAD_SHIFT) | data); @@ -774,1216 +583,22 @@ hme_mii_write(struct hme *hmep, uint8_t regad, uint16_t data) frame = GET_MIFREG(mif_frame); CHECK_MIFREG(); if ((frame & HME_MIF_FRTA0) == 0) { - HME_FAULT_MSG1(hmep, SEVERITY_MID, NAUTONEG_MSG, + HME_FAULT_MSG1(hmep, SEVERITY_MID, MII_MSG, "MIF Write failure"); } } -/* - * hme_stop_timer function is used by a function before doing link-related - * processing. It locks the "hme_linklock" to protect the link-related data - * structures. This lock will be subsequently released in hme_start_timer(). - */ -static void -hme_stop_timer(struct hme *hmep) -{ - timeout_id_t tid; - - mutex_enter(&hmep->hme_linklock); - - if (hmep->hme_timerid) { - tid = hmep->hme_timerid; - hmep->hme_timerid = 0; - mutex_exit(&hmep->hme_linklock); - (void) untimeout(tid); - mutex_enter(&hmep->hme_linklock); - } -} - -static void -hme_start_timer(struct hme *hmep, fptrv_t func, int msec) -{ - hmep->hme_timerid = timeout(func, hmep, drv_usectohz(1000 * msec)); - - mutex_exit(&hmep->hme_linklock); -} - -/* - * hme_select_speed is required only when auto-negotiation is not supported. - * It should be used only for the Internal Transceiver and not the External - * transceiver because we wouldn't know how to generate Link Down state on - * the wire. - * Currently it is required to support Electron 1.1 Build machines. When all - * these machines are upgraded to 1.2 or better, remove this function. - * - * Returns 1 if the link is up, 0 otherwise. - */ - -static int -hme_select_speed(struct hme *hmep, int speed) -{ - uint16_t stat; - uint16_t fdx; - - if (hmep->hme_linkup_cnt) /* not first time */ - goto read_status; - - if (hmep->hme_fdx) - fdx = PHY_BMCR_FDX; - else - fdx = 0; - - switch (speed) { - case HME_SPEED_100: - - switch (hmep->hme_transceiver) { - case HME_INTERNAL_TRANSCEIVER: - hme_mii_write(hmep, HME_PHY_BMCR, fdx | PHY_BMCR_100M); - break; - case HME_EXTERNAL_TRANSCEIVER: - if (hmep->hme_delay == 0) { - hme_mii_write(hmep, HME_PHY_BMCR, - fdx | PHY_BMCR_100M); - } - break; - default: - break; - } - break; - case HME_SPEED_10: - switch (hmep->hme_transceiver) { - case HME_INTERNAL_TRANSCEIVER: - hme_mii_write(hmep, HME_PHY_BMCR, fdx); - break; - case HME_EXTERNAL_TRANSCEIVER: - if (hmep->hme_delay == 0) { - hme_mii_write(hmep, HME_PHY_BMCR, fdx); - } - break; - default: - break; - } - break; - default: - return (0); - } - - if (!hmep->hme_linkup_cnt) { /* first time; select speed */ - (void) hme_mii_read(hmep, HME_PHY_BMSR, &stat); - hmep->hme_linkup_cnt++; - return (0); - } - -read_status: - hmep->hme_linkup_cnt++; - (void) hme_mii_read(hmep, HME_PHY_BMSR, &stat); - if (stat & PHY_BMSR_LNKSTS) - return (1); - else - return (0); -} - - -#define HME_PHYRST_PERIOD 600 /* 600 milliseconds, instead of 500 */ -#define HME_PDOWN_PERIOD 256 /* 256 milliseconds power down period to */ - /* insure a good reset of the QSI PHY */ - -static void -hme_reset_transceiver(struct hme *hmep) -{ - uint32_t cfg; - uint16_t stat; - uint16_t anar; - uint16_t control; - uint16_t csc; - int n; - - cfg = GET_MIFREG(mif_cfg); - - if (hmep->hme_transceiver == HME_EXTERNAL_TRANSCEIVER) { - /* Isolate the Internal Transceiver */ - PUT_MIFREG(mif_cfg, (cfg & ~HME_MIF_CFGPS)); - hmep->hme_phyad = HME_INTERNAL_PHYAD; - hmep->hme_transceiver = HME_INTERNAL_TRANSCEIVER; - hme_mii_write(hmep, HME_PHY_BMCR, (PHY_BMCR_ISOLATE | - PHY_BMCR_PWRDN | PHY_BMCR_LPBK)); - if (hme_mii_read(hmep, HME_PHY_BMCR, &control) == 1) - goto start_again; - - /* select the External transceiver */ - PUT_MIFREG(mif_cfg, (cfg | HME_MIF_CFGPS)); - hmep->hme_transceiver = HME_EXTERNAL_TRANSCEIVER; - hmep->hme_phyad = HME_EXTERNAL_PHYAD; - - } else if (cfg & HME_MIF_CFGM1) { - /* Isolate the External transceiver, if present */ - PUT_MIFREG(mif_cfg, (cfg | HME_MIF_CFGPS)); - hmep->hme_phyad = HME_EXTERNAL_PHYAD; - hmep->hme_transceiver = HME_EXTERNAL_TRANSCEIVER; - hme_mii_write(hmep, HME_PHY_BMCR, (PHY_BMCR_ISOLATE | - PHY_BMCR_PWRDN | PHY_BMCR_LPBK)); - if (hme_mii_read(hmep, HME_PHY_BMCR, &control) == 1) - goto start_again; - - /* select the Internal transceiver */ - PUT_MIFREG(mif_cfg, (cfg & ~HME_MIF_CFGPS)); - hmep->hme_transceiver = HME_INTERNAL_TRANSCEIVER; - hmep->hme_phyad = HME_INTERNAL_PHYAD; - } - - hme_mii_write(hmep, HME_PHY_BMCR, PHY_BMCR_PWRDN); - drv_usecwait((clock_t)HME_PDOWN_PERIOD); - - /* - * Now reset the transceiver. - */ - hme_mii_write(hmep, HME_PHY_BMCR, PHY_BMCR_RESET); - - /* - * Check for transceiver reset completion. - */ - n = HME_PHYRST_PERIOD / HMEWAITPERIOD; - - while (--n > 0) { - if (hme_mii_read(hmep, HME_PHY_BMCR, &control) == 1) { - HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, XCVR_MSG, - xcvr_no_mii_msg); - goto start_again; - } - if ((control & PHY_BMCR_RESET) == 0) - goto reset_issued; - if (hmep->hme_transceiver == HME_INTERNAL_TRANSCEIVER) - drv_usecwait((clock_t)HMEWAITPERIOD); - else - drv_usecwait((clock_t)(500 * HMEWAITPERIOD)); - } - /* - * phy reset failure - */ - hmep->phyfail++; - goto start_again; - -reset_issued: - - /* - * Get the PHY id registers. We need this to implement work-arounds - * for bugs in transceivers which use the National DP83840 PHY chip. - * National should fix this in the next release. - */ - - (void) hme_mii_read(hmep, HME_PHY_BMSR, &stat); - (void) hme_mii_read(hmep, HME_PHY_IDR1, &hmep->hme_idr1); - (void) hme_mii_read(hmep, HME_PHY_IDR2, &hmep->hme_idr2); - (void) hme_mii_read(hmep, HME_PHY_ANAR, &anar); - - hme_init_xcvr_info(hmep); - - hmep->hme_bmcr = control; - hmep->hme_anar = anar; - hmep->hme_bmsr = stat; - - /* - * The strapping of AN0 and AN1 pins on DP83840 cannot select - * 10FDX, 100FDX and Auto-negotiation. So select it here for the - * Internal Transceiver. - */ - if (hmep->hme_transceiver == HME_INTERNAL_TRANSCEIVER) { - anar = (PHY_ANAR_TXFDX | PHY_ANAR_10FDX | - PHY_ANAR_TX | PHY_ANAR_10 | PHY_SELECTOR); - } - /* - * Modify control and bmsr based on anar for Rev-C of DP83840. - */ - if (HME_DP83840) { - n = 0; - if (anar & PHY_ANAR_TXFDX) { - stat |= PHY_BMSR_100FDX; - n++; - } else - stat &= ~PHY_BMSR_100FDX; - - if (anar & PHY_ANAR_TX) { - stat |= PHY_BMSR_100HDX; - n++; - } else - stat &= ~PHY_BMSR_100HDX; - - if (anar & PHY_ANAR_10FDX) { - stat |= PHY_BMSR_10FDX; - n++; - } else - stat &= ~PHY_BMSR_10FDX; - - if (anar & PHY_ANAR_10) { - stat |= PHY_BMSR_10HDX; - n++; - } else - stat &= ~PHY_BMSR_10HDX; - - if (n == 1) { /* only one mode. disable auto-negotiation */ - stat &= ~PHY_BMSR_ACFG; - control &= ~PHY_BMCR_ANE; - } - if (n) { - hmep->hme_bmsr = stat; - hmep->hme_bmcr = control; - } - } - hme_setup_link_default(hmep); - hme_setup_link_status(hmep); - - - /* - * Place the Transceiver in normal operation mode - */ - hme_mii_write(hmep, HME_PHY_BMCR, (control & ~PHY_BMCR_ISOLATE)); - - /* - * check if the transceiver is not in Isolate mode - */ - n = HME_PHYRST_PERIOD / HMEWAITPERIOD; - - while (--n > 0) { - if (hme_mii_read(hmep, HME_PHY_BMCR, &control) == 1) { - HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, XCVR_MSG, - xcvr_no_mii_msg); - goto start_again; /* Transceiver does not talk MII */ - } - if ((control & PHY_BMCR_ISOLATE) == 0) - goto setconn; - drv_usecwait(HMEWAITPERIOD); - } - HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, XCVR_MSG, - xcvr_isolate_msg); - goto start_again; /* transceiver reset failure */ - -setconn: - - /* - * Work-around for the late-collision problem with 100m cables. - * National should fix this in the next release ! - */ - if (HME_DP83840) { - (void) hme_mii_read(hmep, HME_PHY_CSC, &csc); - - hme_mii_write(hmep, HME_PHY_CSC, (csc | PHY_CSCR_FCONN)); - } - - hmep->hme_linkcheck = 0; - hmep->hme_linkup = 0; - hme_setup_link_status(hmep); - hmep->hme_autoneg = HME_HWAN_TRY; - hmep->hme_force_linkdown = HME_FORCE_LINKDOWN; - hmep->hme_linkup_cnt = 0; - hmep->hme_delay = 0; - hme_setup_link_control(hmep); - hme_start_timer(hmep, hme_check_link, HME_LINKCHECK_TIMER); - - if (hmep->hme_mode == HME_FORCE_SPEED) - hme_force_speed(hmep); - else { - hmep->hme_linkup_10 = 0; - hmep->hme_tryspeed = HME_SPEED_100; - hmep->hme_ntries = HME_NTRIES_LOW; - hmep->hme_nlasttries = HME_NTRIES_LOW; - hme_try_speed(hmep); - } - return; - -start_again: - hme_start_timer(hmep, hme_check_link, HME_TICKS); -} - -static void -hme_check_transceiver(struct hme *hmep) -{ - uint32_t cfgsav; - uint32_t cfg; - uint32_t stat; - - /* - * If the MIF Polling is ON, and Internal transceiver is in use, just - * check for the presence of the External Transceiver. - * Otherwise: - * First check to see what transceivers are out there. - * If an external transceiver is present - * then use it, regardless of whether there is a Internal transceiver. - * If Internal transceiver is present and no external transceiver - * then use the Internal transceiver. - * If there is no external transceiver and no Internal transceiver, - * then something is wrong so print an error message. - */ - - cfgsav = GET_MIFREG(mif_cfg); - - if (hmep->hme_polling_on) { - - if (hmep->hme_transceiver == HME_INTERNAL_TRANSCEIVER) { - if ((cfgsav & HME_MIF_CFGM1) && !hme_param_use_intphy) { - hme_stop_mifpoll(hmep); - hmep->hme_phyad = HME_EXTERNAL_PHYAD; - hmep->hme_transceiver = - HME_EXTERNAL_TRANSCEIVER; - PUT_MIFREG(mif_cfg, ((cfgsav & ~HME_MIF_CFGPE) - | HME_MIF_CFGPS)); - } - } else if (hmep->hme_transceiver == HME_EXTERNAL_TRANSCEIVER) { - stat = (GET_MIFREG(mif_bsts) >> 16); - if ((stat == 0x00) || (hme_param_use_intphy)) { - - hme_stop_mifpoll(hmep); - hmep->hme_phyad = HME_INTERNAL_PHYAD; - hmep->hme_transceiver = - HME_INTERNAL_TRANSCEIVER; - PUT_MIFREG(mif_cfg, - (GET_MIFREG(mif_cfg) & ~HME_MIF_CFGPS)); - } - } - CHECK_MIFREG(); - return; - } - - cfg = GET_MIFREG(mif_cfg); - if ((cfg & HME_MIF_CFGM1) && !hme_param_use_intphy) { - PUT_MIFREG(mif_cfg, (cfgsav | HME_MIF_CFGPS)); - hmep->hme_phyad = HME_EXTERNAL_PHYAD; - hmep->hme_transceiver = HME_EXTERNAL_TRANSCEIVER; - - } else if (cfg & HME_MIF_CFGM0) { /* Internal Transceiver OK */ - PUT_MIFREG(mif_cfg, (cfgsav & ~HME_MIF_CFGPS)); - hmep->hme_phyad = HME_INTERNAL_PHYAD; - hmep->hme_transceiver = HME_INTERNAL_TRANSCEIVER; - - } else { - hmep->hme_transceiver = HME_NO_TRANSCEIVER; - HME_FAULT_MSG1(hmep, SEVERITY_HIGH, XCVR_MSG, no_xcvr_msg); - } - CHECK_MIFREG(); -} - -static void -hme_setup_link_default(struct hme *hmep) -{ - uint16_t bmsr; - - bmsr = hmep->hme_bmsr; - if (hme_param_autoneg & HME_NOTUSR) - hme_param_autoneg = HME_NOTUSR | - ((bmsr & PHY_BMSR_ACFG) ? 1 : 0); - if (hme_param_anar_100T4 & HME_NOTUSR) - hme_param_anar_100T4 = HME_NOTUSR | - ((bmsr & PHY_BMSR_100T4) ? 1 : 0); - if (hme_param_anar_100fdx & HME_NOTUSR) - hme_param_anar_100fdx = HME_NOTUSR | - ((bmsr & PHY_BMSR_100FDX) ? 1 : 0); - if (hme_param_anar_100hdx & HME_NOTUSR) - hme_param_anar_100hdx = HME_NOTUSR | - ((bmsr & PHY_BMSR_100HDX) ? 1 : 0); - if (hme_param_anar_10fdx & HME_NOTUSR) - hme_param_anar_10fdx = HME_NOTUSR | - ((bmsr & PHY_BMSR_10FDX) ? 1 : 0); - if (hme_param_anar_10hdx & HME_NOTUSR) - hme_param_anar_10hdx = HME_NOTUSR | - ((bmsr & PHY_BMSR_10HDX) ? 1 : 0); -} - -static void -hme_setup_link_status(struct hme *hmep) -{ - uint16_t tmp; - - if (hmep->hme_transceiver == HME_EXTERNAL_TRANSCEIVER) - hme_param_transceiver = 1; - else - hme_param_transceiver = 0; - - tmp = hmep->hme_bmsr; - if (tmp & PHY_BMSR_ACFG) - hme_param_bmsr_ancap = 1; - else - hme_param_bmsr_ancap = 0; - if (tmp & PHY_BMSR_100T4) - hme_param_bmsr_100T4 = 1; - else - hme_param_bmsr_100T4 = 0; - if (tmp & PHY_BMSR_100FDX) - hme_param_bmsr_100fdx = 1; - else - hme_param_bmsr_100fdx = 0; - if (tmp & PHY_BMSR_100HDX) - hme_param_bmsr_100hdx = 1; - else - hme_param_bmsr_100hdx = 0; - if (tmp & PHY_BMSR_10FDX) - hme_param_bmsr_10fdx = 1; - else - hme_param_bmsr_10fdx = 0; - if (tmp & PHY_BMSR_10HDX) - hme_param_bmsr_10hdx = 1; - else - hme_param_bmsr_10hdx = 0; - - if (hmep->hme_link_pulse_disabled) { - hme_param_linkup = 1; - hme_param_speed = 0; - hme_param_mode = 0; - hmep->hme_duplex = LINK_DUPLEX_HALF; - mac_link_update(hmep->hme_mh, LINK_STATE_UP); - return; - } - - if (!hmep->hme_linkup) { - hme_param_linkup = 0; - hmep->hme_duplex = LINK_DUPLEX_UNKNOWN; - mac_link_update(hmep->hme_mh, LINK_STATE_DOWN); - return; - } - - hme_param_linkup = 1; - - if (hmep->hme_fdx == HME_FULL_DUPLEX) { - hme_param_mode = 1; - hmep->hme_duplex = LINK_DUPLEX_FULL; - } else { - hme_param_mode = 0; - hmep->hme_duplex = LINK_DUPLEX_HALF; - } - - mac_link_update(hmep->hme_mh, LINK_STATE_UP); - - if (hmep->hme_mode == HME_FORCE_SPEED) { - if (hmep->hme_forcespeed == HME_SPEED_100) - hme_param_speed = 1; - else - hme_param_speed = 0; - return; - } - if (hmep->hme_tryspeed == HME_SPEED_100) - hme_param_speed = 1; - else - hme_param_speed = 0; - - - if (!(hmep->hme_aner & PHY_ANER_LPNW)) { - hme_param_aner_lpancap = 0; - hme_param_anlpar_100T4 = 0; - hme_param_anlpar_100fdx = 0; - hme_param_anlpar_100hdx = 0; - hme_param_anlpar_10fdx = 0; - hme_param_anlpar_10hdx = 0; - return; - } - hme_param_aner_lpancap = 1; - tmp = hmep->hme_anlpar; - if (tmp & PHY_ANLPAR_T4) - hme_param_anlpar_100T4 = 1; - else - hme_param_anlpar_100T4 = 0; - if (tmp & PHY_ANLPAR_TXFDX) - hme_param_anlpar_100fdx = 1; - else - hme_param_anlpar_100fdx = 0; - if (tmp & PHY_ANLPAR_TX) - hme_param_anlpar_100hdx = 1; - else - hme_param_anlpar_100hdx = 0; - if (tmp & PHY_ANLPAR_10FDX) - hme_param_anlpar_10fdx = 1; - else - hme_param_anlpar_10fdx = 0; - if (tmp & PHY_ANLPAR_10) - hme_param_anlpar_10hdx = 1; - else - hme_param_anlpar_10hdx = 0; -} - -static void -hme_setup_link_control(struct hme *hmep) -{ - uint16_t anar = PHY_SELECTOR; - uint32_t autoneg = ~HME_NOTUSR & hme_param_autoneg; - uint32_t anar_100T4 = ~HME_NOTUSR & hme_param_anar_100T4; - uint32_t anar_100fdx = ~HME_NOTUSR & hme_param_anar_100fdx; - uint32_t anar_100hdx = ~HME_NOTUSR & hme_param_anar_100hdx; - uint32_t anar_10fdx = ~HME_NOTUSR & hme_param_anar_10fdx; - uint32_t anar_10hdx = ~HME_NOTUSR & hme_param_anar_10hdx; - - if (autoneg) { - hmep->hme_mode = HME_AUTO_SPEED; - hmep->hme_tryspeed = HME_SPEED_100; - if (anar_100T4) - anar |= PHY_ANAR_T4; - if (anar_100fdx) - anar |= PHY_ANAR_TXFDX; - if (anar_100hdx) - anar |= PHY_ANAR_TX; - if (anar_10fdx) - anar |= PHY_ANAR_10FDX; - if (anar_10hdx) - anar |= PHY_ANAR_10; - hmep->hme_anar = anar; - } else { - hmep->hme_mode = HME_FORCE_SPEED; - if (anar_100T4) { - hmep->hme_forcespeed = HME_SPEED_100; - hmep->hme_fdx = HME_HALF_DUPLEX; - - } else if (anar_100fdx) { - /* 100fdx needs to be checked first for 100BaseFX */ - hmep->hme_forcespeed = HME_SPEED_100; - hmep->hme_fdx = HME_FULL_DUPLEX; - - } else if (anar_100hdx) { - hmep->hme_forcespeed = HME_SPEED_100; - hmep->hme_fdx = HME_HALF_DUPLEX; - } else if (anar_10hdx) { - /* 10hdx needs to be checked first for MII-AUI */ - /* MII-AUI BugIds 1252776,4032280,4035106,4028558 */ - hmep->hme_forcespeed = HME_SPEED_10; - hmep->hme_fdx = HME_HALF_DUPLEX; - - } else if (anar_10fdx) { - hmep->hme_forcespeed = HME_SPEED_10; - hmep->hme_fdx = HME_FULL_DUPLEX; - - } else { - hmep->hme_forcespeed = HME_SPEED_10; - hmep->hme_fdx = HME_HALF_DUPLEX; - } - } -} - -/* Decide if transmitter went dead and reinitialize everything */ -static int hme_txhung_limit = 3; -static int -hme_check_txhung(struct hme *hmep) -{ - boolean_t status; - - mutex_enter(&hmep->hme_xmitlock); - if (hmep->hme_flags & HMERUNNING) - hmereclaim(hmep); - - /* Something needs to be sent out but it is not going out */ - if ((hmep->hme_txindex != hmep->hme_txreclaim) && - (hmep->hme_opackets == hmep->hmesave.hme_opackets)) - hmep->hme_txhung++; - else - hmep->hme_txhung = 0; - - hmep->hmesave.hme_opackets = hmep->hme_opackets; - - status = hmep->hme_txhung >= hme_txhung_limit; - mutex_exit(&hmep->hme_xmitlock); - - return (status); -} - -/* - * hme_check_link () - * Called as a result of HME_LINKCHECK_TIMER timeout, to poll for Transceiver - * change or when a transceiver change has been detected by the hme_try_speed - * function. - * This function will also be called from the interrupt handler when polled mode - * is used. Before calling this function the interrupt lock should be freed - * so that the hmeinit() may be called. - * Note that the hmeinit() function calls hme_select_speed() to set the link - * speed and check for link status. - */ - static void -hme_check_link(void *arg) +hme_mii_notify(void *arg, link_state_t link) { struct hme *hmep = arg; - uint16_t stat; - uint_t temp; - - hme_stop_timer(hmep); /* acquire hme_linklock */ - - /* - * This condition was added to work around for - * a problem with the Synoptics/Bay 28115 switch. - * Basically if the link is up but no packets - * are being received. This can be checked using - * ipackets, which in case of reception will - * continue to increment after 'hmep->hme_iipackets' - * has been made equal to it and the 'hme_check_link' - * timer has expired. Note this could also be done - * if there's no traffic on the net. - * 'hmep->hme_ipackets' is incremented in hme_read - * for successfully received packets. - */ - if ((hmep->hme_flags & HMERUNNING) && (hmep->hme_linkup)) { - if (hmep->hme_ipackets != hmep->hme_iipackets) - /* - * Receptions are occurring set 'hmep->hme_iipackets' - * to 'hmep->hme_ipackets' to monitor if receptions - * occur during the next timeout interval. - */ - hmep->hme_iipackets = hmep->hme_ipackets; - else - /* - * Receptions not occurring could be due to - * Synoptics problem, try switchin of data - * scrabbling. That should bring up the link. - */ - hme_link_now_up(hmep); - } - - if ((hmep->hme_flags & HMERUNNING) && - (hmep->hme_linkup) && (hme_check_txhung(hmep))) { - - hme_start_timer(hmep, hme_check_link, HME_LINKCHECK_TIMER); - (void) hmeinit(hmep); /* To reset the transceiver and */ - /* to init the interface */ - return; - } - /* - * check if the transceiver is the same. - * init to be done if the external transceiver is - * connected/disconnected - */ - temp = hmep->hme_transceiver; /* save the transceiver type */ - hme_check_transceiver(hmep); - if ((temp != hmep->hme_transceiver) || (hmep->hme_linkup == 0)) { - if (temp != hmep->hme_transceiver) { - if (hmep->hme_transceiver == HME_EXTERNAL_TRANSCEIVER) { - HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, - XCVR_MSG, ext_xcvr_msg); - } else { - HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, - XCVR_MSG, int_xcvr_msg); - } - } - hmep->hme_linkcheck = 0; - hme_start_timer(hmep, hme_check_link, HME_LINKCHECK_TIMER); - (void) hmeinit(hmep); /* To reset xcvr and init interface */ - return; - } - - - if (hmep->hme_mifpoll_enable) { - stat = (GET_MIFREG(mif_bsts) >> 16); - - CHECK_MIFREG(); /* Verify */ - - if (!hmep->hme_mifpoll_flag) { - if (stat & PHY_BMSR_LNKSTS) { - hme_start_timer(hmep, hme_check_link, - HME_LINKCHECK_TIMER); - return; - } - hme_stop_mifpoll(hmep); - - temp = (GET_MIFREG(mif_bsts) >> 16); - } else { - hmep->hme_mifpoll_flag = 0; - } - } else { - if (hme_mii_read(hmep, HME_PHY_BMSR, &stat) == 1) { - /* Transceiver does not talk mii */ - hme_start_timer(hmep, hme_check_link, - HME_LINKCHECK_TIMER); - return; - } - - if (stat & PHY_BMSR_LNKSTS) { - hme_start_timer(hmep, hme_check_link, - HME_LINKCHECK_TIMER); - return; - } - } - - (void) hme_mii_read(hmep, HME_PHY_BMSR, &stat); - - /* - * The PHY may have automatically renegotiated link speed and mode. - * Get the new link speed and mode. - */ - if ((stat & PHY_BMSR_LNKSTS) && hme_autoneg_enable) { - if (hmep->hme_mode == HME_AUTO_SPEED) { - (void) hme_get_autoinfo(hmep); - hme_setup_link_status(hmep); - hme_start_mifpoll(hmep); - if (hmep->hme_fdx != hmep->hme_macfdx) { - hme_start_timer(hmep, hme_check_link, - HME_LINKCHECK_TIMER); - (void) hmeinit(hmep); - return; - } - } - hme_start_mifpoll(hmep); - hme_start_timer(hmep, hme_check_link, HME_LINKCHECK_TIMER); - return; - } - /* Reset the PHY and bring up the link */ - hme_reset_transceiver(hmep); -} - -static void -hme_init_xcvr_info(struct hme *hmep) -{ - uint16_t phy_id1, phy_id2; - - (void) hme_mii_read(hmep, HME_PHY_IDR1, &phy_id1); - (void) hme_mii_read(hmep, HME_PHY_IDR2, &phy_id2); -} - -/* - * Disable link pulses for the Internal Transceiver - */ - -static void -hme_disable_link_pulse(struct hme *hmep) -{ - uint16_t nicr; - - hme_mii_write(hmep, HME_PHY_BMCR, 0); /* force 10 Mbps */ - (void) hme_mii_read(hmep, HME_PHY_NICR, &nicr); - - hme_mii_write(hmep, HME_PHY_NICR, (nicr & ~PHY_NICR_LD)); - - hmep->hme_linkup = 1; - hmep->hme_linkcheck = 1; - hme_setup_link_status(hmep); - hme_start_mifpoll(hmep); - hme_start_timer(hmep, hme_check_link, HME_LINKCHECK_TIMER); -} - -static void -hme_force_speed(void *arg) -{ - struct hme *hmep = arg; - int linkup; - uint_t temp; - uint16_t csc; - - hme_stop_timer(hmep); - if (hmep->hme_fdx != hmep->hme_macfdx) { - hme_start_timer(hmep, hme_check_link, HME_TICKS*5); - return; - } - temp = hmep->hme_transceiver; /* save the transceiver type */ - hme_check_transceiver(hmep); - if (temp != hmep->hme_transceiver) { - if (hmep->hme_transceiver == HME_EXTERNAL_TRANSCEIVER) { - HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, XCVR_MSG, - ext_xcvr_msg); - } else { - HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, XCVR_MSG, - int_xcvr_msg); - } - hme_start_timer(hmep, hme_check_link, HME_TICKS * 10); - return; - } - - if ((hmep->hme_transceiver == HME_INTERNAL_TRANSCEIVER) && - (hmep->hme_link_pulse_disabled)) { - hmep->hme_forcespeed = HME_SPEED_10; - hme_disable_link_pulse(hmep); - return; - } - - /* - * To interoperate with auto-negotiable capable systems - * the link should be brought down for 1 second. - * How to do this using only standard registers ? - */ - if (HME_DP83840) { - if (hmep->hme_force_linkdown == HME_FORCE_LINKDOWN) { - hmep->hme_force_linkdown = HME_LINKDOWN_STARTED; - hme_mii_write(hmep, HME_PHY_BMCR, PHY_BMCR_100M); - (void) hme_mii_read(hmep, HME_PHY_CSC, &csc); - hme_mii_write(hmep, HME_PHY_CSC, - (csc | PHY_CSCR_TXOFF)); - hme_start_timer(hmep, hme_force_speed, 10 * HME_TICKS); - return; - } else if (hmep->hme_force_linkdown == HME_LINKDOWN_STARTED) { - (void) hme_mii_read(hmep, HME_PHY_CSC, &csc); - hme_mii_write(hmep, HME_PHY_CSC, - (csc & ~PHY_CSCR_TXOFF)); - hmep->hme_force_linkdown = HME_LINKDOWN_DONE; - } - } else { - if (hmep->hme_force_linkdown == HME_FORCE_LINKDOWN) { - hmep->hme_force_linkdown = HME_LINKDOWN_STARTED; - hme_mii_write(hmep, HME_PHY_BMCR, PHY_BMCR_LPBK); - hme_start_timer(hmep, hme_force_speed, 10 * HME_TICKS); - return; - } else if (hmep->hme_force_linkdown == HME_LINKDOWN_STARTED) { - hmep->hme_force_linkdown = HME_LINKDOWN_DONE; - } - } - - - linkup = hme_select_speed(hmep, hmep->hme_forcespeed); - if (hmep->hme_linkup_cnt == 1) { - hme_start_timer(hmep, hme_force_speed, SECOND(4)); - return; - } - if (linkup) { - - hmep->hme_linkup = 1; - hmep->hme_linkcheck = 1; - hmep->hme_ifspeed = hmep->hme_forcespeed; - hme_link_now_up(hmep); - hme_setup_link_status(hmep); - hme_start_mifpoll(hmep); - hme_start_timer(hmep, hme_check_link, HME_LINKCHECK_TIMER); - } else { - hme_start_timer(hmep, hme_force_speed, HME_TICKS); - } -} - -static void -hme_get_autoinfo(struct hme *hmep) -{ - uint16_t anar; - uint16_t aner; - uint16_t anlpar; - uint16_t tmp; - uint16_t ar; - - (void) hme_mii_read(hmep, HME_PHY_ANER, &aner); - (void) hme_mii_read(hmep, HME_PHY_ANLPAR, &anlpar); - (void) hme_mii_read(hmep, HME_PHY_ANAR, &anar); - - hmep->hme_anlpar = anlpar; - hmep->hme_aner = aner; - - if (aner & PHY_ANER_LPNW) { - - tmp = anar & anlpar; - if (tmp & PHY_ANAR_TXFDX) { - hmep->hme_tryspeed = HME_SPEED_100; - hmep->hme_fdx = HME_FULL_DUPLEX; - } else if (tmp & PHY_ANAR_TX) { - hmep->hme_tryspeed = HME_SPEED_100; - hmep->hme_fdx = HME_HALF_DUPLEX; - } else if (tmp & PHY_ANLPAR_10FDX) { - hmep->hme_tryspeed = HME_SPEED_10; - hmep->hme_fdx = HME_FULL_DUPLEX; - } else if (tmp & PHY_ANLPAR_10) { - hmep->hme_tryspeed = HME_SPEED_10; - hmep->hme_fdx = HME_HALF_DUPLEX; - } else { - if (HME_DP83840) { - - hmep->hme_fdx = HME_HALF_DUPLEX; - (void) hme_mii_read(hmep, HME_PHY_AR, &ar); - - if (ar & PHY_AR_SPEED10) - hmep->hme_tryspeed = HME_SPEED_10; - else - hmep->hme_tryspeed = HME_SPEED_100; - } else - HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, - AUTONEG_MSG, anar_not_set_msg); - } - } else { - hmep->hme_fdx = HME_HALF_DUPLEX; - if (anlpar & PHY_ANLPAR_TX) - hmep->hme_tryspeed = HME_SPEED_100; - else if (anlpar & PHY_ANLPAR_10) - hmep->hme_tryspeed = HME_SPEED_10; - else { - if (HME_DP83840) { - - (void) hme_mii_read(hmep, HME_PHY_AR, &ar); - - if (ar & PHY_AR_SPEED10) - hmep->hme_tryspeed = HME_SPEED_10; - else - hmep->hme_tryspeed = HME_SPEED_100; - } else - HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, - AUTONEG_MSG, par_detect_anar_not_set_msg); - } - } - - hmep->hme_linkup = 1; - hmep->hme_linkcheck = 1; - hmep->hme_ifspeed = hmep->hme_tryspeed; - hme_link_now_up(hmep); -} - -/* - * Return 1 if the link is up or auto-negotiation being tried, 0 otherwise. - */ - -static int -hme_try_auto_negotiation(struct hme *hmep) -{ - uint16_t stat; - uint16_t aner; - - if (hmep->hme_autoneg == HME_HWAN_TRY) { - /* auto negotiation not initiated */ - (void) hme_mii_read(hmep, HME_PHY_BMSR, &stat); - if (hme_mii_read(hmep, HME_PHY_BMSR, &stat) == 1) { - /* - * Transceiver does not talk mii - */ - goto hme_anfail; - } - if ((stat & PHY_BMSR_ACFG) == 0) { /* auto neg. not supported */ - - return (hmep->hme_autoneg = HME_HWAN_FAILED); - } - - /* - * Read ANER to clear status from previous operations. - */ - if (hme_mii_read(hmep, HME_PHY_ANER, &aner) == 1) { - /* - * Transceiver does not talk mii - */ - goto hme_anfail; - } - - hme_mii_write(hmep, HME_PHY_ANAR, hmep->hme_anar); - hme_mii_write(hmep, HME_PHY_BMCR, PHY_BMCR_ANE | PHY_BMCR_RAN); - /* - * auto-negotiation initiated - */ - hmep->hme_delay = 0; - hme_start_timer(hmep, hme_try_speed, HME_TICKS); - return (hmep->hme_autoneg = HME_HWAN_INPROGRESS); - /* - * auto-negotiation in progress - */ - } - - /* - * Auto-negotiation has been in progress. Wait for at least - * least 3000 ms. - * Changed 8/28/97 to fix bug ID 4070989. - */ - if (hmep->hme_delay < 30) { - hmep->hme_delay++; - hme_start_timer(hmep, hme_try_speed, HME_TICKS); - return (hmep->hme_autoneg = HME_HWAN_INPROGRESS); - } - - (void) hme_mii_read(hmep, HME_PHY_BMSR, &stat); - if (hme_mii_read(hmep, HME_PHY_BMSR, &stat) == 1) { - /* - * Transceiver does not talk mii - */ - goto hme_anfail; - } - - if ((stat & PHY_BMSR_ANC) == 0) { - /* - * wait for a maximum of 5 seconds - */ - if (hmep->hme_delay < 50) { - hmep->hme_delay++; - hme_start_timer(hmep, hme_try_speed, HME_TICKS); - return (hmep->hme_autoneg = HME_HWAN_INPROGRESS); - } - if (HME_DP83840) { - (void) hme_mii_read(hmep, HME_PHY_ANER, &aner); - if (aner & PHY_ANER_MLF) { - - return (hmep->hme_autoneg = HME_HWAN_FAILED); - } - } - - goto hme_anfail; - } - - (void) hme_mii_read(hmep, HME_PHY_ANER, &aner); - if (aner & PHY_ANER_MLF) { - HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, AUTONEG_MSG, - par_detect_msg); - goto hme_anfail; - } - - if (!(stat & PHY_BMSR_LNKSTS)) { - /* - * wait for a maximum of 10 seconds - */ - if (hmep->hme_delay < 100) { - hmep->hme_delay++; - hme_start_timer(hmep, hme_try_speed, HME_TICKS); - return (hmep->hme_autoneg = HME_HWAN_INPROGRESS); - } - goto hme_anfail; - } else { - hmep->hme_bmsr |= (PHY_BMSR_LNKSTS); - hme_get_autoinfo(hmep); - hmep->hme_force_linkdown = HME_LINKDOWN_DONE; - hme_setup_link_status(hmep); - hme_start_mifpoll(hmep); - hme_start_timer(hmep, hme_check_link, HME_LINKCHECK_TIMER); - if (hmep->hme_fdx != hmep->hme_macfdx) { - (void) hmeinit(hmep); - } - return (hmep->hme_autoneg = HME_HWAN_SUCCESFUL); - } - -hme_anfail: - hme_start_timer(hmep, hme_try_speed, HME_TICKS); - return (hmep->hme_autoneg = HME_HWAN_TRY); -} - -/* - * This function is used to perform automatic speed detection. - * The Internal Transceiver which is based on the National PHY chip - * 83840 supports auto-negotiation functionality. - * Some External transceivers may not support auto-negotiation. - * In that case, the software performs the speed detection. - * The software tries to bring down the link for about 2 seconds to - * force the Link Partner to notice speed change. - * The software speed detection favors the 100 Mbps speed. - * It does this by setting the 100 Mbps for longer duration ( 5 seconds ) - * than the 10 Mbps ( 2 seconds ). Also, even after the link is up - * in 10 Mbps once, the 100 Mbps is also tried. Only if the link - * is not up in 100 Mbps, the 10 Mbps speed is tried again. - */ -static void -hme_try_speed(void *arg) -{ - struct hme *hmep = arg; - int linkup; - uint_t temp; - - hme_stop_timer(hmep); - temp = hmep->hme_transceiver; /* save the transceiver type */ - hme_check_transceiver(hmep); - if (temp != hmep->hme_transceiver) { - if (hmep->hme_transceiver == HME_EXTERNAL_TRANSCEIVER) { - HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, XCVR_MSG, - ext_xcvr_msg); - } else { - HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, XCVR_MSG, - int_xcvr_msg); - } - hme_start_timer(hmep, hme_check_link, 10 * HME_TICKS); - return; - } - - if ((hmep->hme_transceiver == HME_INTERNAL_TRANSCEIVER) && - (hmep->hme_link_pulse_disabled)) { - hmep->hme_tryspeed = HME_SPEED_10; - hme_disable_link_pulse(hmep); - return; - } - - if (hme_autoneg_enable && (hmep->hme_autoneg != HME_HWAN_FAILED)) { - if (hme_try_auto_negotiation(hmep) != HME_HWAN_FAILED) - return; /* auto negotiation successful or being tried */ - } - - linkup = hme_select_speed(hmep, hmep->hme_tryspeed); - if (hmep->hme_linkup_cnt == 1) { - hme_start_timer(hmep, hme_try_speed, SECOND(1)); - return; - } - if (linkup) { - switch (hmep->hme_tryspeed) { - case HME_SPEED_100: - if (hmep->hme_linkup_cnt == 4) { - hmep->hme_ntries = HME_NTRIES_LOW; - hmep->hme_nlasttries = HME_NTRIES_LOW; - hmep->hme_linkup = 1; - hmep->hme_linkcheck = 1; - hme_link_now_up(hmep); - hme_setup_link_status(hmep); - hme_start_mifpoll(hmep); - hme_start_timer(hmep, hme_check_link, - HME_LINKCHECK_TIMER); - if (hmep->hme_fdx != hmep->hme_macfdx) { - (void) hmeinit(hmep); - } - } else - hme_start_timer(hmep, hme_try_speed, HME_TICKS); - break; - case HME_SPEED_10: - if (hmep->hme_linkup_cnt == 4) { - if (hmep->hme_linkup_10) { - hmep->hme_linkup_10 = 0; - hmep->hme_ntries = HME_NTRIES_LOW; - hmep->hme_nlasttries = HME_NTRIES_LOW; - hmep->hme_linkup = 1; - hmep->hme_linkcheck = 1; - hmep->hme_ifspeed = HME_SPEED_10; - hme_setup_link_status(hmep); - hme_start_mifpoll(hmep); - hme_start_timer(hmep, hme_check_link, - HME_LINKCHECK_TIMER); - if (hmep->hme_fdx != hmep->hme_macfdx) { - (void) hmeinit(hmep); - } - } else { - hmep->hme_linkup_10 = 1; - hmep->hme_tryspeed = HME_SPEED_100; - hmep->hme_force_linkdown = - HME_FORCE_LINKDOWN; - hmep->hme_linkup_cnt = 0; - hmep->hme_ntries = HME_NTRIES_LOW; - hmep->hme_nlasttries = HME_NTRIES_LOW; - hme_start_timer(hmep, - hme_try_speed, HME_TICKS); - } - - } else - hme_start_timer(hmep, hme_try_speed, HME_TICKS); - break; - default: - break; - } - return; - } - - hmep->hme_ntries--; - hmep->hme_linkup_cnt = 0; - if (hmep->hme_ntries == 0) { - hmep->hme_force_linkdown = HME_FORCE_LINKDOWN; - switch (hmep->hme_tryspeed) { - case HME_SPEED_100: - hmep->hme_tryspeed = HME_SPEED_10; - hmep->hme_ntries = HME_NTRIES_LOW_10; - break; - case HME_SPEED_10: - hmep->hme_ntries = HME_NTRIES_LOW; - hmep->hme_tryspeed = HME_SPEED_100; - break; - default: - break; - } + if (link == LINK_STATE_UP) { + (void) hmeinit(hmep); } - hme_start_timer(hmep, hme_try_speed, HME_TICKS); + mac_link_update(hmep->hme_mh, link); } -static void -hme_link_now_up(struct hme *hmep) -{ - uint16_t btxpc; - /* - * Work-around for the scramble problem with QSI - * chip and Synoptics 28115 switch. - * Addition Interface Technologies Group (NPG) 8/28/1997. - */ - if ((HME_QS6612) && ((hmep->hme_tryspeed == HME_SPEED_100) || - (hmep->hme_forcespeed == HME_SPEED_100))) { - /* - * Addition of a check for 'hmep->hme_forcespeed' - * This is necessary when the autonegotiation is - * disabled by the 'hme.conf' file. In this case - * hmep->hme_tryspeed is not initialized. Resulting - * in the workaround not being applied. - */ - if (hme_mii_read(hmep, HME_PHY_BTXPC, &btxpc) == 0) { - hme_mii_write(hmep, HME_PHY_BTXPC, - (btxpc | PHY_BTXPC_DSCRAM)); - drv_usecwait(20); - hme_mii_write(hmep, HME_PHY_BTXPC, btxpc); - } - } -} /* <<<<<<<<<<<<<<<<<<<<<<<<<<< LOADABLE ENTRIES >>>>>>>>>>>>>>>>>>>>>>> */ int @@ -2293,6 +908,9 @@ hme_mapebusrom(dev_info_t *dip, void *arg) return (DDI_WALK_PRUNESIB); } + if (ddi_get_parent(dip) != rom->parent) + return (DDI_WALK_CONTINUE); + if ((ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, "reg", ®s, &nregs)) != DDI_PROP_SUCCESS) { return (DDI_WALK_PRUNECHILD); @@ -2359,27 +977,14 @@ hmeget_promebus(dev_info_t *dip) /* * The implementation of ddi_walk_devs says that we must not - * be called during autoconfiguration. However, upon close - * examination, one will find the following is true: - * - * 1) since we're called at attach time, - * DEVI_BUSY_OWNED(ddi_get_parent(dip)) is implicitly true. + * be called during autoconfiguration. However, it turns out + * that it is safe to call this during our attach routine, + * because we are not a nexus device. * - * 2) we carefully ensure that we prune siblings for all cases - * except our own device, so we can't wind up walking down - * a changing sibling pointer. - * - * 3) since we are attaching, our peers will already have their - * dev_info nodes on the tree... hence our own sibling pointer - * (and those of our siblings) will be stable. - * - * 4) also, because of #3, our parents child pointer will be - * stable. - * - * So it should be safe to do this, because of our carefully - * constructed restrictions. + * Previously we rooted our search at our immediate parent, + * but this triggered an assertion panic in debug kernels. */ - ddi_walk_devs(ddi_get_parent(dip), hme_mapebusrom, &rom); + ddi_walk_devs(ddi_root_node(), hme_mapebusrom, &rom); if (rom.acch) { hmep->hme_romh = rom.acch; @@ -2472,7 +1077,6 @@ hmeget_hm_rev_property(struct hme *hmep) case HME_2P1_REVID_OBP: HME_FAULT_MSG2(hmep, SEVERITY_NONE, DISPLAY_MSG, "SBus 2.1 Found (Rev Id = %x)", hm_rev); - hmep->hme_mifpoll_enable = 1; hmep->hme_frame_enable = 1; break; @@ -2487,10 +1091,9 @@ hmeget_hm_rev_property(struct hme *hmep) break; default: - HME_FAULT_MSG3(hmep, SEVERITY_HIGH, DISPLAY_MSG, + HME_FAULT_MSG3(hmep, SEVERITY_NONE, DISPLAY_MSG, "%s (Rev Id = %x) Found", (hm_rev == HME_2C0_REVID) ? "PCI IO 2.0" : "Sbus", hm_rev); - hmep->hme_mifpoll_enable = 1; hmep->hme_frame_enable = 1; hmep->hme_lance_mode_enable = 1; hmep->hme_rxcv_enable = 1; @@ -2531,7 +1134,8 @@ hmeattach(dev_info_t *dip, ddi_attach_cmd_t cmd) return (DDI_FAILURE); hmep->hme_flags &= ~HMESUSPENDED; - hmep->hme_linkcheck = 0; + + mii_resume(hmep->hme_mii); if (hmep->hme_started) (void) hmeinit(hmep); @@ -2722,7 +1326,6 @@ hmeattach(dev_info_t *dip, ddi_attach_cmd_t cmd) * Based on the hm-rev, set some capabilities * Set up default capabilities for HM 2.0 */ - hmep->hme_mifpoll_enable = 0; hmep->hme_frame_enable = 0; hmep->hme_lance_mode_enable = 0; hmep->hme_rxcv_enable = 0; @@ -2756,7 +1359,7 @@ hmeattach(dev_info_t *dip, ddi_attach_cmd_t cmd) "hm-rev", (caddr_t)&hm_rev, sizeof (hm_rev)) != DDI_SUCCESS) { HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, AUTOCONFIG_MSG, - "hmeattach: ddi_prop_create error for hm_rev"); + "ddi_prop_create error for hm_rev"); } ddi_regs_map_free(&cfg_handle); @@ -2765,13 +1368,10 @@ hmeattach(dev_info_t *dip, ddi_attach_cmd_t cmd) /* get info via VPD */ if (hmeget_promprops(dip) != DDI_SUCCESS) { HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, AUTOCONFIG_MSG, - "hmeattach: no promprops"); + "no promprops"); } } - if (!hme_mifpoll_enable) - hmep->hme_mifpoll_enable = 0; - if (ddi_intr_hilevel(dip, 0)) { HME_FAULT_MSG1(hmep, SEVERITY_HIGH, NFATAL_ERR_MSG, " high-level interrupts are not supported"); @@ -2789,7 +1389,6 @@ hmeattach(dev_info_t *dip, ddi_attach_cmd_t cmd) */ mutex_init(&hmep->hme_xmitlock, NULL, MUTEX_DRIVER, hmep->hme_cookie); mutex_init(&hmep->hme_intrlock, NULL, MUTEX_DRIVER, hmep->hme_cookie); - mutex_init(&hmep->hme_linklock, NULL, MUTEX_DRIVER, hmep->hme_cookie); /* * Quiesce the hardware. @@ -2833,6 +1432,15 @@ hmeattach(dev_info_t *dip, ddi_attach_cmd_t cmd) hmestatinit(hmep); + hmep->hme_mii = mii_alloc(hmep, dip, &hme_mii_ops); + if (hmep->hme_mii == NULL) { + HME_FAULT_MSG1(hmep, SEVERITY_HIGH, CONFIG_MSG, + "mii_alloc failed"); + goto error_intr; + } + /* force a probe for the PHY */ + mii_probe(hmep->hme_mii); + if ((macp = mac_alloc(MAC_VERSION)) == NULL) { HME_FAULT_MSG1(hmep, SEVERITY_HIGH, CONFIG_MSG, "mac_alloc failed"); @@ -2846,6 +1454,9 @@ hmeattach(dev_info_t *dip, ddi_attach_cmd_t cmd) macp->m_min_sdu = 0; macp->m_max_sdu = ETHERMTU; macp->m_margin = VLAN_TAGSZ; + macp->m_priv_props = hme_priv_prop; + macp->m_priv_prop_count = + sizeof (hme_priv_prop) / sizeof (hme_priv_prop[0]); if (mac_register(macp, &hmep->hme_mh) != 0) { mac_free(macp); goto error_intr; @@ -2864,10 +1475,12 @@ error_intr: if (hmep->hme_cookie) ddi_remove_intr(dip, 0, (ddi_iblock_cookie_t)0); + if (hmep->hme_mii) + mii_free(hmep->hme_mii); + error_mutex: mutex_destroy(&hmep->hme_xmitlock); mutex_destroy(&hmep->hme_intrlock); - mutex_destroy(&hmep->hme_linklock); error_unmap: if (hmep->hme_globregh) @@ -2913,6 +1526,7 @@ hmedetach(dev_info_t *dip, ddi_detach_cmd_t cmd) break; case DDI_SUSPEND: + mii_suspend(hmep->hme_mii); hmep->hme_flags |= HMESUSPENDED; hmeuninit(hmep); return (DDI_SUCCESS); @@ -2935,6 +1549,9 @@ hmedetach(dev_info_t *dip, ddi_detach_cmd_t cmd) (void) hmestop(hmep); } + if (hmep->hme_mii) + mii_free(hmep->hme_mii); + /* * Remove instance of the intr */ @@ -2952,12 +1569,6 @@ hmedetach(dev_info_t *dip, ddi_detach_cmd_t cmd) hmep->hme_intrstats = NULL; /* - * Stop asynchronous timer events. - */ - hme_stop_timer(hmep); - mutex_exit(&hmep->hme_linklock); - - /* * Destroy all mutexes and data structures allocated during * attach time. * @@ -2985,13 +1596,10 @@ hmedetach(dev_info_t *dip, ddi_detach_cmd_t cmd) mutex_destroy(&hmep->hme_xmitlock); mutex_destroy(&hmep->hme_intrlock); - mutex_destroy(&hmep->hme_linklock); hmefreethings(hmep); hmefreebufs(hmep); - hme_param_cleanup(hmep); - ddi_set_driver_private(dip, NULL); kmem_free(hmep, sizeof (struct hme)); @@ -3006,7 +1614,6 @@ hmequiesce(dev_info_t *dip) if ((hmep = ddi_get_driver_private(dip)) == NULL) return (DDI_FAILURE); - hme_stop_mifpoll(hmep); (void) hmestop(hmep); return (DDI_SUCCESS); } @@ -3014,138 +1621,45 @@ hmequiesce(dev_info_t *dip) static boolean_t hmeinit_xfer_params(struct hme *hmep) { - int i; int hme_ipg1_conf, hme_ipg2_conf; - int hme_use_int_xcvr_conf, hme_pace_count_conf; - int hme_autoneg_conf; - int hme_anar_100T4_conf; - int hme_anar_100fdx_conf, hme_anar_100hdx_conf; - int hme_anar_10fdx_conf, hme_anar_10hdx_conf; int hme_ipg0_conf, hme_lance_mode_conf; int prop_len = sizeof (int); dev_info_t *dip; dip = hmep->dip; - for (i = 0; i < A_CNT(hme_param_arr); i++) - hmep->hme_param_arr[i] = hme_param_arr[i]; - - if (!hmep->hme_g_nd && !hme_param_register(hmep, hmep->hme_param_arr, - A_CNT(hme_param_arr))) { - HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, NDD_MSG, - param_reg_fail_msg); - return (B_FALSE); - } - /* * Set up the start-up values for user-configurable parameters * Get the values from the global variables first. * Use the MASK to limit the value to allowed maximum. */ - hme_param_ipg1 = hme_ipg1 & HME_MASK_8BIT; - hme_param_ipg2 = hme_ipg2 & HME_MASK_8BIT; - hme_param_use_intphy = hme_use_int_xcvr & HME_MASK_1BIT; - hme_param_pace_count = hme_pace_size & HME_MASK_8BIT; - hme_param_autoneg = hme_adv_autoneg_cap; - hme_param_anar_100T4 = hme_adv_100T4_cap; - hme_param_anar_100fdx = hme_adv_100fdx_cap; - hme_param_anar_100hdx = hme_adv_100hdx_cap; - hme_param_anar_10fdx = hme_adv_10fdx_cap; - hme_param_anar_10hdx = hme_adv_10hdx_cap; - hme_param_ipg0 = hme_ipg0 & HME_MASK_5BIT; - hme_param_lance_mode = hme_lance_mode & HME_MASK_1BIT; - - /* - * The link speed may be forced to either 10 Mbps or 100 Mbps using the - * 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) { - hme_param_autoneg = 0; /* force speed */ - hme_param_anar_100T4 = 0; - hme_param_anar_100fdx = 0; - hme_param_anar_10fdx = 0; - if (i == 10) { - hme_param_anar_10hdx = 1; - hme_param_anar_100hdx = 0; - } else { - hme_param_anar_10hdx = 0; - hme_param_anar_100hdx = 1; - } - } + hmep->hme_ipg1 = hme_ipg1 & HME_MASK_8BIT; + hmep->hme_ipg2 = hme_ipg2 & HME_MASK_8BIT; + hmep->hme_ipg0 = hme_ipg0 & HME_MASK_5BIT; /* * Get the parameter values configured in .conf file. */ if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "ipg1", (caddr_t)&hme_ipg1_conf, &prop_len) == DDI_PROP_SUCCESS) { - hme_param_ipg1 = hme_ipg1_conf & HME_MASK_8BIT; + hmep->hme_ipg1 = hme_ipg1_conf & HME_MASK_8BIT; } if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "ipg2", (caddr_t)&hme_ipg2_conf, &prop_len) == DDI_PROP_SUCCESS) { - hme_param_ipg2 = hme_ipg2_conf & HME_MASK_8BIT; - } - - if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "use_int_xcvr", - (caddr_t)&hme_use_int_xcvr_conf, &prop_len) == DDI_PROP_SUCCESS) { - hme_param_use_intphy = hme_use_int_xcvr_conf & HME_MASK_1BIT; - } - - if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "pace_size", - (caddr_t)&hme_pace_count_conf, &prop_len) == DDI_PROP_SUCCESS) { - hme_param_pace_count = hme_pace_count_conf & HME_MASK_8BIT; - } - - if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "adv_autoneg_cap", - (caddr_t)&hme_autoneg_conf, &prop_len) == DDI_PROP_SUCCESS) { - hme_param_autoneg = hme_autoneg_conf & HME_MASK_1BIT; - } - - if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "adv_100T4_cap", - (caddr_t)&hme_anar_100T4_conf, &prop_len) == DDI_PROP_SUCCESS) { - hme_param_anar_100T4 = hme_anar_100T4_conf & HME_MASK_1BIT; - } - - if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "adv_100fdx_cap", - (caddr_t)&hme_anar_100fdx_conf, &prop_len) == DDI_PROP_SUCCESS) { - hme_param_anar_100fdx = hme_anar_100fdx_conf & HME_MASK_1BIT; - } - - if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "adv_100hdx_cap", - (caddr_t)&hme_anar_100hdx_conf, &prop_len) == DDI_PROP_SUCCESS) { - hme_param_anar_100hdx = hme_anar_100hdx_conf & HME_MASK_1BIT; - } - - if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "adv_10fdx_cap", - (caddr_t)&hme_anar_10fdx_conf, &prop_len) == DDI_PROP_SUCCESS) { - hme_param_anar_10fdx = hme_anar_10fdx_conf & HME_MASK_1BIT; - } - - if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "adv_10hdx_cap", - (caddr_t)&hme_anar_10hdx_conf, &prop_len) == DDI_PROP_SUCCESS) { - hme_param_anar_10hdx = hme_anar_10hdx_conf & HME_MASK_1BIT; + hmep->hme_ipg2 = hme_ipg2_conf & HME_MASK_8BIT; } if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "ipg0", (caddr_t)&hme_ipg0_conf, &prop_len) == DDI_PROP_SUCCESS) { - hme_param_ipg0 = hme_ipg0_conf & HME_MASK_5BIT; + hmep->hme_ipg0 = hme_ipg0_conf & HME_MASK_5BIT; } if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "lance_mode", (caddr_t)&hme_lance_mode_conf, &prop_len) == DDI_PROP_SUCCESS) { - hme_param_lance_mode = hme_lance_mode_conf & HME_MASK_1BIT; + hmep->hme_lance_mode = hme_lance_mode_conf & HME_MASK_1BIT; } - if (hme_link_pulse_disabled) - hmep->hme_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) { - hmep->hme_link_pulse_disabled = 1; - } return (B_TRUE); } @@ -3325,14 +1839,6 @@ hmestatinit(struct hme *hmep) KSTAT_DATA_ULONG); /* - * I/O bus kstats - * kstat_named_init(&hkp->hk_pci_speed, "pci_bus_speed", - * KSTAT_DATA_ULONG); - * kstat_named_init(&hkp->hk_pci_size, "pci_bus_width", - * KSTAT_DATA_ULONG); - */ - - /* * xcvr kstats */ kstat_named_init(&hkp->hk_asic_rev, "asic_rev", @@ -3343,94 +1849,110 @@ hmestatinit(struct hme *hmep) kstat_install(ksp); } -static void -hme_m_ioctl(void *arg, queue_t *wq, mblk_t *mp) +int +hme_m_getprop(void *arg, const char *name, mac_prop_id_t num, uint_t flags, + uint_t sz, void *val, uint_t *perm) { - struct hme *hmep = arg; - struct iocblk *iocp = (void *)mp->b_rptr; - uint32_t old_ipg1, old_ipg2, old_use_int_xcvr, old_autoneg; - uint32_t old_100T4; - uint32_t old_100fdx, old_100hdx, old_10fdx, old_10hdx; - uint32_t old_ipg0, old_lance_mode; - - switch (iocp->ioc_cmd) { - - case HME_ND_GET: - - old_autoneg = hme_param_autoneg; - old_100T4 = hme_param_anar_100T4; - old_100fdx = hme_param_anar_100fdx; - old_100hdx = hme_param_anar_100hdx; - old_10fdx = hme_param_anar_10fdx; - old_10hdx = hme_param_anar_10hdx; - - hme_param_autoneg = old_autoneg & ~HME_NOTUSR; - hme_param_anar_100T4 = old_100T4 & ~HME_NOTUSR; - hme_param_anar_100fdx = old_100fdx & ~HME_NOTUSR; - hme_param_anar_100hdx = old_100hdx & ~HME_NOTUSR; - hme_param_anar_10fdx = old_10fdx & ~HME_NOTUSR; - hme_param_anar_10hdx = old_10hdx & ~HME_NOTUSR; - - if (!hme_nd_getset(wq, hmep->hme_g_nd, mp)) { - hme_param_autoneg = old_autoneg; - hme_param_anar_100T4 = old_100T4; - hme_param_anar_100fdx = old_100fdx; - hme_param_anar_100hdx = old_100hdx; - hme_param_anar_10fdx = old_10fdx; - hme_param_anar_10hdx = old_10hdx; - miocnak(wq, mp, 0, EINVAL); - return; - } - hme_param_autoneg = old_autoneg; - hme_param_anar_100T4 = old_100T4; - hme_param_anar_100fdx = old_100fdx; - hme_param_anar_100hdx = old_100hdx; - hme_param_anar_10fdx = old_10fdx; - hme_param_anar_10hdx = old_10hdx; - - qreply(wq, mp); + struct hme *hmep = arg; + int value; + boolean_t is_default; + int rv; + + rv = mii_m_getprop(hmep->hme_mii, name, num, flags, sz, val, perm); + if (rv != ENOTSUP) + return (rv); + + switch (num) { + case MAC_PROP_PRIVATE: break; + default: + return (ENOTSUP); + } - case HME_ND_SET: - old_ipg0 = hme_param_ipg0; - old_lance_mode = hme_param_lance_mode; - old_ipg1 = hme_param_ipg1; - old_ipg2 = hme_param_ipg2; - old_use_int_xcvr = hme_param_use_intphy; - old_autoneg = hme_param_autoneg; - hme_param_autoneg = 0xff; - - if (!hme_nd_getset(wq, hmep->hme_g_nd, mp)) { - hme_param_autoneg = old_autoneg; - miocnak(wq, mp, 0, EINVAL); - return; + *perm = MAC_PROP_PERM_RW; + + is_default = (flags & MAC_PROP_DEFAULT) ? B_TRUE : B_FALSE; + if (strcmp(name, "_ipg0") == 0) { + value = is_default ? hme_ipg0 : hmep->hme_ipg0; + + } else if (strcmp(name, "_ipg1") == 0) { + value = is_default ? hme_ipg1 : hmep->hme_ipg1; + } else if (strcmp(name, "_ipg2") == 0) { + value = is_default ? hme_ipg2 : hmep->hme_ipg2; + } else if (strcmp(name, "_lance_mode") == 0) { + value = is_default ? hme_lance_mode : hmep->hme_lance_mode; + } else { + return (ENOTSUP); + } + (void) snprintf(val, sz, "%d", value); + return (0); +} + +int +hme_m_setprop(void *arg, const char *name, mac_prop_id_t num, uint_t sz, + const void *val) +{ + struct hme *hmep = arg; + int rv; + long lval; + boolean_t init = B_FALSE; + + rv = mii_m_setprop(hmep->hme_mii, name, num, sz, val); + if (rv != ENOTSUP) + return (rv); + rv = 0; + + switch (num) { + case MAC_PROP_PRIVATE: + break; + default: + return (ENOTSUP); + } + + (void) ddi_strtol(val, NULL, 0, &lval); + + if (strcmp(name, "_ipg1") == 0) { + if ((lval >= 0) && (lval <= 255)) { + hmep->hme_ipg1 = lval & 0xff; + init = B_TRUE; + } else { + return (EINVAL); } - qreply(wq, mp); + } else if (strcmp(name, "_ipg2") == 0) { + if ((lval >= 0) && (lval <= 255)) { + hmep->hme_ipg2 = lval & 0xff; + init = B_TRUE; + } else { + return (EINVAL); + } - if (hme_param_autoneg != 0xff) { - hmep->hme_linkcheck = 0; - (void) hmeinit(hmep); + } else if (strcmp(name, "_ipg0") == 0) { + if ((lval >= 0) && (lval <= 31)) { + hmep->hme_ipg0 = lval & 0xff; + init = B_TRUE; } else { - hme_param_autoneg = old_autoneg; - if (old_use_int_xcvr != hme_param_use_intphy) { - hmep->hme_linkcheck = 0; - (void) hmeinit(hmep); - } else if ((old_ipg1 != hme_param_ipg1) || - (old_ipg2 != hme_param_ipg2) || - (old_ipg0 != hme_param_ipg0) || - (old_lance_mode != hme_param_lance_mode)) { - (void) hmeinit(hmep); - } + return (EINVAL); + } + } else if (strcmp(name, "_lance_mode") == 0) { + if ((lval >= 0) && (lval <= 1)) { + hmep->hme_lance_mode = lval & 0xff; + init = B_TRUE; + } else { + return (EINVAL); } - break; - default: - miocnak(wq, mp, 0, EINVAL); - break; + } else { + rv = ENOTSUP; + } + + if (init) { + (void) hmeinit(hmep); } + return (rv); } + /*ARGSUSED*/ static boolean_t hme_m_getcapab(void *arg, mac_capab_t cap, void *cap_data) @@ -3520,6 +2042,7 @@ hme_m_start(void *arg) return (EIO); } else { hmep->hme_started = B_TRUE; + mii_start(hmep->hme_mii); return (0); } } @@ -3529,6 +2052,7 @@ hme_m_stop(void *arg) { struct hme *hmep = arg; + mii_stop(hmep->hme_mii); hmep->hme_started = B_FALSE; hmeuninit(hmep); } @@ -3546,10 +2070,10 @@ hme_m_stat(void *arg, uint_t stat, uint64_t *val) mutex_exit(&hmep->hme_xmitlock); + if (mii_m_getstat(hmep->hme_mii, stat, val) == 0) { + return (0); + } switch (stat) { - case MAC_STAT_IFSPEED: - *val = hmep->hme_ifspeed * 1000000; - break; case MAC_STAT_IPACKETS: *val = hmep->hme_ipackets; break; @@ -3628,79 +2152,6 @@ hme_m_stat(void *arg, uint_t stat, uint64_t *val) case ETHER_STAT_CARRIER_ERRORS: *val = hmep->hme_carrier_errors; break; - case ETHER_STAT_XCVR_ADDR: - *val = hmep->hme_phyad; - break; - case ETHER_STAT_XCVR_ID: - *val = (hmep->hme_idr1 << 16U) | (hmep->hme_idr2); - break; - case ETHER_STAT_XCVR_INUSE: - switch (hmep->hme_transceiver) { - case HME_INTERNAL_TRANSCEIVER: - *val = XCVR_100X; - break; - case HME_NO_TRANSCEIVER: - *val = XCVR_NONE; - break; - default: - *val = XCVR_UNDEFINED; - break; - } - break; - case ETHER_STAT_CAP_100T4: - *val = hme_param_bmsr_100T4; - break; - case ETHER_STAT_ADV_CAP_100T4: - *val = hme_param_anar_100T4 & ~HME_NOTUSR; - break; - case ETHER_STAT_LP_CAP_100T4: - *val = hme_param_anlpar_100T4; - break; - case ETHER_STAT_CAP_100FDX: - *val = hme_param_bmsr_100fdx; - break; - case ETHER_STAT_ADV_CAP_100FDX: - *val = hme_param_anar_100fdx & ~HME_NOTUSR; - break; - case ETHER_STAT_LP_CAP_100FDX: - *val = hme_param_anlpar_100fdx; - break; - case ETHER_STAT_CAP_100HDX: - *val = hme_param_bmsr_100hdx; - break; - case ETHER_STAT_ADV_CAP_100HDX: - *val = hme_param_anar_100hdx & ~HME_NOTUSR; - break; - case ETHER_STAT_LP_CAP_100HDX: - *val = hme_param_anlpar_100hdx; - break; - case ETHER_STAT_CAP_10FDX: - *val = hme_param_bmsr_10fdx; - break; - case ETHER_STAT_ADV_CAP_10FDX: - *val = hme_param_anar_10fdx & ~HME_NOTUSR; - break; - case ETHER_STAT_LP_CAP_10FDX: - *val = hme_param_anlpar_10fdx; - break; - case ETHER_STAT_CAP_10HDX: - *val = hme_param_bmsr_10hdx; - break; - case ETHER_STAT_ADV_CAP_10HDX: - *val = hme_param_anar_10hdx & ~HME_NOTUSR; - break; - case ETHER_STAT_LP_CAP_10HDX: - *val = hme_param_anlpar_10hdx; - break; - case ETHER_STAT_CAP_AUTONEG: - *val = hme_param_bmsr_ancap; - break; - case ETHER_STAT_ADV_CAP_AUTONEG: - *val = hme_param_autoneg & ~HME_NOTUSR; - break; - case ETHER_STAT_LP_CAP_AUTONEG: - *val = hme_param_aner_lpancap; - break; default: return (EINVAL); } @@ -3902,6 +2353,8 @@ hmeinit(struct hme *hmep) { uint32_t i; int ret; + boolean_t fdx; + int phyad; /* * Lock sequence: @@ -3934,24 +2387,14 @@ hmeinit(struct hme *hmep) * situation as described in bug ID 4065896. */ - hme_stop_timer(hmep); /* acquire hme_linklock */ mutex_enter(&hmep->hme_xmitlock); hmep->hme_flags = 0; hmep->hme_wantw = B_FALSE; - hmep->hme_txhung = 0; - - /* - * Initializing 'hmep->hme_iipackets' to match current - * number of received packets. - */ - hmep->hme_iipackets = hmep->hme_ipackets; if (hmep->inits) hmesavecntrs(hmep); - hme_stop_mifpoll(hmep); - /* * Perform Global reset of the Sbus/FEPS ENET channel. */ @@ -4001,32 +2444,20 @@ hmeinit(struct hme *hmep) * ASIC, it selects Internal by default. */ - hme_check_transceiver(hmep); - if (hmep->hme_transceiver == HME_NO_TRANSCEIVER) { + switch ((phyad = mii_get_addr(hmep->hme_mii))) { + case -1: HME_FAULT_MSG1(hmep, SEVERITY_HIGH, XCVR_MSG, no_xcvr_msg); - hme_start_timer(hmep, hme_check_link, HME_LINKCHECK_TIMER); goto init_fail; /* abort initialization */ - } else if (hmep->hme_transceiver == HME_INTERNAL_TRANSCEIVER) + case HME_INTERNAL_PHYAD: PUT_MACREG(xifc, 0); - else + break; + case HME_EXTERNAL_PHYAD: + /* Isolate the Int. xcvr */ PUT_MACREG(xifc, BMAC_XIFC_MIIBUFDIS); - /* Isolate the Int. xcvr */ - /* - * Perform transceiver reset and speed selection only if - * the link is down. - */ - if (!hmep->hme_linkcheck) - /* - * Reset the PHY and bring up the link - * If it fails we will then increment a kstat. - */ - hme_reset_transceiver(hmep); - else { - if (hmep->hme_linkup) - hme_start_mifpoll(hmep); - hme_start_timer(hmep, hme_check_link, HME_LINKCHECK_TIMER); + break; } + hmep->inits++; /* @@ -4062,8 +2493,8 @@ hmeinit(struct hme *hmep) PUT_MACREG(palen, hme_palen); #endif - PUT_MACREG(ipg1, hme_param_ipg1); - PUT_MACREG(ipg2, hme_param_ipg2); + PUT_MACREG(ipg1, hmep->hme_ipg1); + PUT_MACREG(ipg2, hmep->hme_ipg2); PUT_MACREG(rseed, ((hmep->hme_ouraddr.ether_addr_octet[0] << 8) & 0x3) | @@ -4203,19 +2634,19 @@ hmeinit(struct hme *hmep) drv_usecwait(10); /* wait after setting Hash Enable bit */ + fdx = (mii_get_duplex(hmep->hme_mii) == LINK_DUPLEX_FULL); + if (hme_ngu_enable) - PUT_MACREG(txcfg, (hmep->hme_fdx ? BMAC_TXCFG_FDX: 0) | + PUT_MACREG(txcfg, (fdx ? BMAC_TXCFG_FDX : 0) | BMAC_TXCFG_NGU); else - PUT_MACREG(txcfg, (hmep->hme_fdx ? BMAC_TXCFG_FDX: 0)); - hmep->hme_macfdx = hmep->hme_fdx; - + PUT_MACREG(txcfg, (fdx ? BMAC_TXCFG_FDX: 0)); i = 0; - if ((hme_param_lance_mode) && (hmep->hme_lance_mode_enable)) - i = ((hme_param_ipg0 & HME_MASK_5BIT) << BMAC_XIFC_IPG0_SHIFT) + if ((hmep->hme_lance_mode) && (hmep->hme_lance_mode_enable)) + i = ((hmep->hme_ipg0 & HME_MASK_5BIT) << BMAC_XIFC_IPG0_SHIFT) | BMAC_XIFC_LANCE_ENAB; - if (hmep->hme_transceiver == HME_INTERNAL_TRANSCEIVER) + if (phyad == HME_INTERNAL_PHYAD) PUT_MACREG(xifc, i | (BMAC_XIFC_ENAB)); else PUT_MACREG(xifc, i | (BMAC_XIFC_ENAB | BMAC_XIFC_MIIBUFDIS)); @@ -4406,59 +2837,6 @@ hmefreebufs(struct hme *hmep) } /* - * hme_start_mifpoll() - Enables the polling of the BMSR register of the PHY. - * After enabling the poll, delay for atleast 62us for one poll to be done. - * Then read the MIF status register to auto-clear the MIF status field. - * Then program the MIF interrupt mask register to enable interrupts for the - * LINK_STATUS and JABBER_DETECT bits. - */ - -static void -hme_start_mifpoll(struct hme *hmep) -{ - uint32_t cfg; - - if (!hmep->hme_mifpoll_enable) - return; - - cfg = (GET_MIFREG(mif_cfg) & ~(HME_MIF_CFGPD | HME_MIF_CFGPR)); - PUT_MIFREG(mif_cfg, - (cfg = (cfg | (hmep->hme_phyad << HME_MIF_CFGPD_SHIFT) | - (HME_PHY_BMSR << HME_MIF_CFGPR_SHIFT) | HME_MIF_CFGPE))); - - drv_usecwait(HME_MIF_POLL_DELAY); - hmep->hme_polling_on = 1; - hmep->hme_mifpoll_flag = 0; - hmep->hme_mifpoll_data = (GET_MIFREG(mif_bsts) >> 16); - - /* Do not poll for Jabber Detect for 100 Mbps speed */ - if (((hmep->hme_mode == HME_AUTO_SPEED) && - (hmep->hme_tryspeed == HME_SPEED_100)) || - ((hmep->hme_mode == HME_FORCE_SPEED) && - (hmep->hme_forcespeed == HME_SPEED_100))) - PUT_MIFREG(mif_imask, ((uint16_t)~(PHY_BMSR_LNKSTS))); - else - PUT_MIFREG(mif_imask, - (uint16_t)~(PHY_BMSR_LNKSTS | PHY_BMSR_JABDET)); - - CHECK_MIFREG(); -} - -static void -hme_stop_mifpoll(struct hme *hmep) -{ - if ((!hmep->hme_mifpoll_enable) || (!hmep->hme_polling_on)) - return; - - PUT_MIFREG(mif_imask, 0xffff); /* mask interrupts */ - PUT_MIFREG(mif_cfg, (GET_MIFREG(mif_cfg) & ~HME_MIF_CFGPE)); - - hmep->hme_polling_on = 0; - drv_usecwait(HME_MIF_POLL_DELAY); - CHECK_MIFREG(); -} - -/* * Un-initialize (STOP) HME channel. */ static void @@ -4469,14 +2847,9 @@ hmeuninit(struct hme *hmep) */ HMEDELAY((hmep->hme_txindex == hmep->hme_txreclaim), HMEDRAINTIME); - hme_stop_timer(hmep); /* acquire hme_linklock */ - mutex_exit(&hmep->hme_linklock); - mutex_enter(&hmep->hme_intrlock); mutex_enter(&hmep->hme_xmitlock); - hme_stop_mifpoll(hmep); - hmep->hme_flags &= ~HMERUNNING; (void) hmestop(hmep); @@ -4601,7 +2974,6 @@ hmeintr(caddr_t arg) { struct hme *hmep = (void *)arg; uint32_t hmesbits; - uint32_t mif_status; uint32_t serviced = DDI_INTR_UNCLAIMED; uint32_t num_reads = 0; uint32_t rflags; @@ -4669,60 +3041,6 @@ hmeintr(caddr_t arg) hme_nonfatal_err(hmep, hmesbits); } - if (hmesbits & HMEG_STATUS_MIF_INTR) { - mif_status = (GET_MIFREG(mif_bsts) >> 16); - if (!(mif_status & PHY_BMSR_LNKSTS)) { - - if (hmep->hme_intrstats) - KIOIP->intrs[KSTAT_INTR_HARD]++; - - hme_stop_mifpoll(hmep); - hmep->hme_mifpoll_flag = 1; - mutex_exit(&hmep->hme_intrlock); - hme_stop_timer(hmep); - hme_start_timer(hmep, hme_check_link, MSECOND(1)); - return (serviced); - } - /* - * - * BugId 1261889 EscId 50699 ftp hangs @ 10 Mbps - * - * Here could be one cause: - * national PHY sees jabber, goes into "Jabber function", - * (see section 3.7.6 in PHY specs.), disables transmitter, - * and waits for internal transmit enable to be de-asserted - * for at least 750ms (the "unjab" time). Also, the PHY - * has asserted COL, the collision detect signal. - * - * In the meantime, the Sbus/FEPS, in never-give-up mode, - * continually retries, backs off 16 times as per spec, - * and restarts the transmission, so TX_EN is never - * deasserted long enough, in particular TX_EN is turned - * on approximately once every 4 microseconds on the - * average. PHY and MAC are deadlocked. - * - * Here is part of the fix: - * On seeing the jabber, treat it like a hme_fatal_err - * and reset both the Sbus/FEPS and the PHY. - */ - - if (mif_status & (PHY_BMSR_JABDET)) { - - /* national phy only defines this at 10 Mbps */ - if (hme_param_speed == 0) { /* 10 Mbps speed ? */ - hmep->hme_jab++; - - /* treat jabber like a fatal error */ - hmep->hme_linkcheck = 0; /* force PHY reset */ - mutex_exit(&hmep->hme_intrlock); - (void) hmeinit(hmep); - - return (serviced); - } - } - hme_start_mifpoll(hmep); - } - if (hmesbits & (HMEG_STATUS_TX_ALL | HMEG_STATUS_TINT)) { mutex_enter(&hmep->hme_xmitlock); @@ -5151,290 +3469,6 @@ hmesavecntrs(struct hme *hmep) } /* - * ndd support functions to get/set parameters - */ -/* Free the Named Dispatch Table by calling hme_nd_free */ -static void -hme_param_cleanup(struct hme *hmep) -{ - if (hmep->hme_g_nd) - (void) hme_nd_free(&hmep->hme_g_nd); -} - -/* - * Extracts the value from the hme parameter array and prints the - * parameter value. cp points to the required parameter. - */ -/* ARGSUSED */ -static int -hme_param_get(queue_t *q, mblk_t *mp, caddr_t cp) -{ - hmeparam_t *hmepa = (void *)cp; - - (void) mi_mpprintf(mp, "%d", hmepa->hme_param_val); - return (0); -} - -/* - * Register each element of the parameter array with the - * named dispatch handler. Each element is loaded using - * hme_nd_load() - */ -/* ARGSUSED */ -static int -hme_param_register(struct hme *hmep, hmeparam_t *hmepa, int cnt) -{ - int i; - - /* First 4 elements are read-only */ - for (i = 0; i < 4; i++, hmepa++) - if (!hme_nd_load(&hmep->hme_g_nd, hmepa->hme_param_name, - (pfi_t)hme_param_get, (pfi_t)0, (caddr_t)hmepa)) { - (void) hme_nd_free(&hmep->hme_g_nd); - return (B_FALSE); - } - /* Next 10 elements are read and write */ - for (i = 0; i < 10; i++, hmepa++) - if (hmepa->hme_param_name && hmepa->hme_param_name[0]) { - if (!hme_nd_load(&hmep->hme_g_nd, - hmepa->hme_param_name, (pfi_t)hme_param_get, - (pfi_t)hme_param_set, (caddr_t)hmepa)) { - (void) hme_nd_free(&hmep->hme_g_nd); - return (B_FALSE); - - } - } - /* next 12 elements are read-only */ - for (i = 0; i < 12; i++, hmepa++) - if (!hme_nd_load(&hmep->hme_g_nd, hmepa->hme_param_name, - (pfi_t)hme_param_get, (pfi_t)0, (caddr_t)hmepa)) { - (void) hme_nd_free(&hmep->hme_g_nd); - return (B_FALSE); - } - /* Next 3 elements are read and write */ - for (i = 0; i < 3; i++, hmepa++) - if (hmepa->hme_param_name && hmepa->hme_param_name[0]) { - if (!hme_nd_load(&hmep->hme_g_nd, - hmepa->hme_param_name, (pfi_t)hme_param_get, - (pfi_t)hme_param_set, (caddr_t)hmepa)) { - (void) hme_nd_free(&hmep->hme_g_nd); - return (B_FALSE); - } - } - - return (B_TRUE); -} - -/* - * Sets the hme parameter to the value in the hme_param_register using - * hme_nd_load(). - */ -/* ARGSUSED */ -static int -hme_param_set(queue_t *q, mblk_t *mp, char *value, caddr_t cp) -{ - char *end; - size_t new_value; - hmeparam_t *hmepa = (void *)cp; - - new_value = mi_strtol(value, &end, 10); - if (end == value || new_value < hmepa->hme_param_min || - new_value > hmepa->hme_param_max) { - return (EINVAL); - } - hmepa->hme_param_val = (uint32_t)new_value; - return (0); - -} - -/* Free the table pointed to by 'ndp' */ -static void -hme_nd_free(caddr_t *nd_pparam) -{ - ND *nd; - - if ((nd = (void *)(*nd_pparam)) != NULL) { - if (nd->nd_tbl) - mi_free((char *)nd->nd_tbl); - mi_free((char *)nd); - *nd_pparam = NULL; - } -} - -static int -hme_nd_getset(queue_t *q, caddr_t nd_param, MBLKP mp) -{ - int err; - IOCP iocp; - MBLKP mp1; - ND *nd; - NDE *nde; - char *valp; - size_t avail; - - if (!nd_param) - return (B_FALSE); - - 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; - iocp->ioc_error = EINVAL; - return (B_TRUE); - } - - /* - * NOTE - logic throughout nd_xxx assumes single data block for ioctl. - * However, existing code sends in some big buffers. - */ - avail = iocp->ioc_count; - if (mp1->b_cont) { - freemsg(mp1->b_cont); - mp1->b_cont = NULL; - } - - mp1->b_datap->db_lim[-1] = '\0'; /* Force null termination */ - valp = (char *)mp1->b_rptr; - for (nde = nd->nd_tbl; /* */; nde++) { - if (!nde->nde_name) - return (B_FALSE); - if (mi_strcmp(nde->nde_name, valp) == 0) - break; - } - - err = EINVAL; - while (*valp++) - ; - if (!*valp || valp >= (char *)mp1->b_wptr) - valp = NULL; - switch (iocp->ioc_cmd) { - case ND_GET: -/* - * (temporary) hack: "*valp" is size of user buffer for copyout. If result - * of action routine is too big, free excess and return ioc_rval as buffer - * size needed. Return as many mblocks as will fit, free the rest. For - * backward compatibility, assume size of original ioctl buffer if "*valp" - * bad or not given. - */ - if (valp) - avail = mi_strtol(valp, (char **)0, 10); - /* We overwrite the name/value with the reply data */ - { - mblk_t *mp2 = mp1; - - while (mp2) { - mp2->b_wptr = mp2->b_rptr; - mp2 = mp2->b_cont; - } - } - err = (*nde->nde_get_pfi)(q, mp1, nde->nde_data, iocp->ioc_cr); - if (!err) { - size_t size_out; - ssize_t excess; - - iocp->ioc_rval = 0; - - /* Tack on the null */ - (void) mi_mpprintf_putc((char *)mp1, '\0'); - size_out = msgdsize(mp1); - excess = size_out - avail; - if (excess > 0) { - iocp->ioc_rval = (int)size_out; - size_out -= excess; - (void) adjmsg(mp1, -(excess + 1)); - (void) mi_mpprintf_putc((char *)mp1, '\0'); - } - iocp->ioc_count = size_out; - } - break; - - 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); - } - iocp->ioc_count = 0; - freemsg(mp1); - mp->b_cont = NULL; - } - break; - - default: - break; - } - - iocp->ioc_error = err; - mp->b_datap->db_type = M_IOCACK; - return (B_TRUE); -} - -/* - * Load 'name' into the named dispatch table pointed to by 'ndp'. - * 'ndp' should be the address of a char pointer cell. If the table - * does not exist (*ndp == 0), a new table is allocated and 'ndp' - * is stuffed. If there is not enough space in the table for a new - * entry, more space is allocated. - */ -static boolean_t -hme_nd_load(caddr_t *nd_pparam, char *name, pfi_t get_pfi, - pfi_t set_pfi, caddr_t data) -{ - ND *nd; - NDE *nde; - - if (!nd_pparam) - return (B_FALSE); - - if ((nd = (void *)(*nd_pparam)) == NULL) { - if ((nd = (void *)mi_alloc(sizeof (ND), BPRI_MED)) == NULL) - return (B_FALSE); - bzero(nd, sizeof (ND)); - *nd_pparam = (caddr_t)nd; - } - - if (nd->nd_tbl) { - for (nde = nd->nd_tbl; nde->nde_name; nde++) { - if (mi_strcmp(name, nde->nde_name) == 0) - goto fill_it; - } - } - - if (nd->nd_free_count <= 1) { - if ((nde = (NDE *)mi_alloc(nd->nd_size + - NDE_ALLOC_SIZE, BPRI_MED)) == NULL) - return (B_FALSE); - bzero(nde, nd->nd_size + NDE_ALLOC_SIZE); - nd->nd_free_count += NDE_ALLOC_COUNT; - if (nd->nd_tbl) { - bcopy(nd->nd_tbl, nde, nd->nd_size); - mi_free((char *)nd->nd_tbl); - } else { - nd->nd_free_count--; - nde->nde_name = "?"; - nde->nde_get_pfi = nd_get_names; - nde->nde_set_pfi = nd_set_default; - } - nde->nde_data = (caddr_t)nd; - nd->nd_tbl = nde; - nd->nd_size += NDE_ALLOC_SIZE; - } - - for (nde = nd->nd_tbl; nde->nde_name; nde++) - ; - nd->nd_free_count--; -fill_it: - nde->nde_name = name; - nde->nde_get_pfi = get_pfi ? get_pfi : nd_get_default; - nde->nde_set_pfi = set_pfi ? set_pfi : nd_set_default; - nde->nde_data = data; - return (B_TRUE); -} - -/* * To set up the mac address for the network interface: * The adapter card may support a local mac address which is published * in a device node property "local-mac-address". This mac address is diff --git a/usr/src/uts/common/io/hme/hme.h b/usr/src/uts/common/io/hme/hme.h index 85b138e80f..d1fce450ea 100644 --- a/usr/src/uts/common/io/hme/hme.h +++ b/usr/src/uts/common/io/hme/hme.h @@ -30,100 +30,8 @@ extern "C" { #endif -/* mode */ -#define HME_AUTO_SPEED 0 -#define HME_FORCE_SPEED 1 - -/* speed */ -#define HME_SPEED_10 10 -#define HME_SPEED_100 100 - -/* half-duplex or full-duplex mode */ - -#define HME_HALF_DUPLEX 0 -#define HME_FULL_DUPLEX 1 - #ifdef _KERNEL -/* Named Dispatch Parameter Management Structure */ -typedef struct hmeparam_s { - uint32_t hme_param_min; - uint32_t hme_param_max; - uint32_t hme_param_val; - char *hme_param_name; -} hmeparam_t; - - -static hmeparam_t hme_param_arr[] = { - /* min max value name */ - { 0, 1, 1, "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, 16, "ipg0"}, -}; - - -#define hme_param_transceiver (hmep->hme_param_arr[0].hme_param_val) -#define hme_param_linkup (hmep->hme_param_arr[1].hme_param_val) -#define hme_param_speed (hmep->hme_param_arr[2].hme_param_val) -#define hme_param_mode (hmep->hme_param_arr[3].hme_param_val) -#define hme_param_ipg1 (hmep->hme_param_arr[4].hme_param_val) -#define hme_param_ipg2 (hmep->hme_param_arr[5].hme_param_val) -#define hme_param_use_intphy (hmep->hme_param_arr[6].hme_param_val) -#define hme_param_pace_count (hmep->hme_param_arr[7].hme_param_val) -#define hme_param_autoneg (hmep->hme_param_arr[8].hme_param_val) -#define hme_param_anar_100T4 (hmep->hme_param_arr[9].hme_param_val) -#define hme_param_anar_100fdx (hmep->hme_param_arr[10].hme_param_val) -#define hme_param_anar_100hdx (hmep->hme_param_arr[11].hme_param_val) -#define hme_param_anar_10fdx (hmep->hme_param_arr[12].hme_param_val) -#define hme_param_anar_10hdx (hmep->hme_param_arr[13].hme_param_val) -#define hme_param_bmsr_ancap (hmep->hme_param_arr[14].hme_param_val) -#define hme_param_bmsr_100T4 (hmep->hme_param_arr[15].hme_param_val) -#define hme_param_bmsr_100fdx (hmep->hme_param_arr[16].hme_param_val) -#define hme_param_bmsr_100hdx (hmep->hme_param_arr[17].hme_param_val) -#define hme_param_bmsr_10fdx (hmep->hme_param_arr[18].hme_param_val) -#define hme_param_bmsr_10hdx (hmep->hme_param_arr[19].hme_param_val) -#define hme_param_aner_lpancap (hmep->hme_param_arr[20].hme_param_val) -#define hme_param_anlpar_100T4 (hmep->hme_param_arr[21].hme_param_val) -#define hme_param_anlpar_100fdx (hmep->hme_param_arr[22].hme_param_val) -#define hme_param_anlpar_100hdx (hmep->hme_param_arr[23].hme_param_val) -#define hme_param_anlpar_10fdx (hmep->hme_param_arr[24].hme_param_val) -#define hme_param_anlpar_10hdx (hmep->hme_param_arr[25].hme_param_val) -#define hme_param_lance_mode (hmep->hme_param_arr[26].hme_param_val) -#define hme_param_ipg0 (hmep->hme_param_arr[27].hme_param_val) - -#define HME_PARAM_CNT 29 - - -/* command */ - -#define HME_ND_GET ND_GET -#define HME_ND_SET ND_SET - /* default IPG settings */ #define IPG1 8 #define IPG2 4 @@ -143,12 +51,6 @@ static hmeparam_t hme_param_arr[] = { * ordered on minor device number. */ -#define MSECOND(t) t -#define SECOND(t) t*1000 -#define HME_TICKS MSECOND(100) - -#define HME_LINKCHECK_TIMER SECOND(30) - #define HME_2P0_REVID 0xa0 /* hme - feps. */ #define HME_2P1_REVID 0x20 #define HME_2P1_REVID_OBP 0x21 @@ -156,38 +58,6 @@ static hmeparam_t hme_param_arr[] = { #define HME_2C0_REVID 0xc1 /* cheerio 2.0, hme 2.2 equiv. */ #define HME_REV_VERS_MASK 0x0f /* Mask to retain bits for cheerio ver */ -#define HME_NTRIES_LOW (SECOND(5)/HME_TICKS) /* 5 Seconds */ -#define HME_NTRIES_HIGH (SECOND(5)/HME_TICKS) /* 5 Seconds */ -#define HME_NTRIES_LOW_10 (SECOND(2)/HME_TICKS) /* 2 Seconds */ -#define HME_LINKDOWN_TIME (SECOND(2)/HME_TICKS) /* 2 Seconds */ - -#define HME_LINKDOWN_OK 0 -#define HME_FORCE_LINKDOWN 1 -#define HME_LINKDOWN_STARTED 2 -#define HME_LINKDOWN_DONE 3 - -#define P1_0 0x100 - -#define HME_EXTERNAL_TRANSCEIVER 0 -#define HME_INTERNAL_TRANSCEIVER 1 -#define HME_NO_TRANSCEIVER 2 - -#define HME_HWAN_TRY 0 /* Try Hardware autonegotiation */ -#define HME_HWAN_INPROGRESS 1 /* Hardware autonegotiation in progress */ -#define HME_HWAN_SUCCESFUL 2 /* Hardware autonegotiation succesful */ -#define HME_HWAN_FAILED 3 /* Hardware autonegotiation failed */ - -#define RESET_TO_BE_ISSUED 0 /* Reset command to be issued to the PHY */ -#define RESET_ISSUED 1 /* Reset command has been issued */ -#define ISOLATE_ISSUED 2 /* Isolate-remove command has been issued */ -#define POWER_OFF_ISSUED 3 /* The QSI Phy may have problems with */ - /* Power rampup. Issue powerdown in */ - /* the driver to insure good reset. */ -struct hmesave { - ulong_t hme_starts; - uint32_t hme_opackets; -}; - typedef struct { ddi_dma_handle_t dmah; ddi_acc_handle_t acch; @@ -202,68 +72,31 @@ typedef struct { */ struct hme { mac_handle_t hme_mh; /* GLDv3 handle */ + mii_handle_t hme_mii; dev_info_t *dip; /* associated dev_info */ int instance; /* instance */ ulong_t pagesize; /* btop(9F) */ - /* - * xcvr information - */ - uint16_t hme_idr1; /* PHY IDR1 register */ - uint16_t hme_idr2; /* PHY IDR2 register */ - uint16_t hme_anar; /* PHY ANAR register */ - uint16_t hme_anlpar; /* PHY ANLPAR register */ - uint16_t hme_aner; /* PHY ANER register */ - int hme_mifpoll_enable; int hme_frame_enable; int hme_lance_mode_enable; int hme_rxcv_enable; + uint32_t hme_lance_mode; + uint32_t hme_ipg0; + uint32_t hme_ipg1; + uint32_t hme_ipg2; + uint_t hme_burstsizes; /* binary encoded val */ uint32_t hme_config; /* Config reg store */ - int hme_phy_retries; /* phy reset failures */ int hme_phy_failure; /* phy failure type */ int hme_64bit_xfer; /* 64-bit Sbus xfers */ int hme_phyad; - int hme_autoneg; - - caddr_t hme_g_nd; /* head of the */ - /* named dispatch table */ - hmeparam_t hme_param_arr[HME_PARAM_CNT]; - int hme_transceiver; /* current PHY in use */ - int hme_link_pulse_disabled; - uint16_t hme_bmcr; /* PHY control register */ - uint16_t hme_bmsr; /* PHY status register */ - int hme_mode; /* auto/forced mode */ - int hme_linkup; /* link status */ - int hme_xcvr_state; /* transceiver status */ - int hme_forcespeed; /* speed in forced mode */ - int hme_tryspeed; /* speed in auto mode */ - int hme_fdx; /* full-duplex mode */ - int hme_pace_count; /* pacing pkt count */ - - int hme_macfdx; - int hme_linkcheck; - int hme_force_linkdown; + int hme_nlasttries; - int hme_ntries; - int hme_delay; - int hme_linkup_10; - int hme_linkup_cnt; - timeout_id_t hme_timerid; int hme_cheerio_mode; - int hme_polling_on; - int hme_mifpoll_data; - int hme_mifpoll_flag; - - /* - * This is part of the hardening of the hme driver - * (following x fields) - */ - ushort_t hme_disabled; struct ether_addr hme_factaddr; /* factory mac address */ struct ether_addr hme_ouraddr; /* individual address */ @@ -288,7 +121,6 @@ struct hme { kmutex_t hme_xmitlock; /* protect xmit-side fields */ kmutex_t hme_intrlock; /* protect intr-side fields */ - kmutex_t hme_linklock; /* protect link-side fields */ ddi_iblock_cookie_t hme_cookie; /* interrupt cookie */ struct hme_rmd *hme_rmdp; /* receive descriptor ring start */ @@ -331,11 +163,7 @@ struct hme { kstat_t *hme_ksp; /* kstat pointer */ kstat_t *hme_intrstats; /* kstat interrupt counter */ - uint64_t hme_iipackets; /* Used to store the Count of packets */ - /* recieved at the start of 'hme_check_link' */ - /* watch dog interval. */ - uint64_t hme_ifspeed; /* ifspeed is now in bits/sec */ uint64_t hme_ipackets; uint64_t hme_rbytes; uint64_t hme_ierrors; @@ -393,7 +221,6 @@ struct hme { uint32_t hme_starts; uint32_t hme_txhung; time_t hme_msg_time; - struct hmesave hmesave; /* * Debuging kstats diff --git a/usr/src/uts/common/io/mii/mii_other.c b/usr/src/uts/common/io/mii/mii_other.c index a0c763590e..622e76dbc7 100644 --- a/usr/src/uts/common/io/mii/mii_other.c +++ b/usr/src/uts/common/io/mii/mii_other.c @@ -51,6 +51,7 @@ static const struct { OUI(DAVICOM_2, "Davicom Semiconductor"), OUI(ICPLUS, "IC Plus Corp."), OUI(ICS, "Integrated Circuit Systems"), + OUI(LUCENT, "Lucent Technologies"), OUI(INTEL, "Intel"), OUI(MARVELL, "Marvell Technology"), OUI(NATIONAL_SEMI, "National Semiconductor"), @@ -106,6 +107,8 @@ static const struct { ID(ICS, ICS1892, "ICS1892"), ID(ICS, ICS1893, "ICS1893"), + ID(LUCENT, LU6612, "LU6612"), + { 0, 0, NULL }, }; diff --git a/usr/src/uts/common/sys/miiregs.h b/usr/src/uts/common/sys/miiregs.h index 00cd8c061a..7649eef7db 100644 --- a/usr/src/uts/common/sys/miiregs.h +++ b/usr/src/uts/common/sys/miiregs.h @@ -161,6 +161,7 @@ extern "C" { #define MII_OUI_ICPLUS 0x0090c3 #define MII_OUI_INTEL 0x00aa00 #define MII_OUI_INTEL_2 0x001f00 +#define MII_OUI_LUCENT 0x00601d #define MII_OUI_MARVELL 0x005043 #define MII_OUI_NATIONAL_SEMI 0x080017 #define MII_OUI_NATIONAL_SEMI_2 0x1000e8 @@ -196,6 +197,8 @@ extern "C" { #define MII_MODEL_INTEL_82562_EM 0x31 #define MII_MODEL_INTEL_82562_ET 0x32 +#define MII_MODEL_LUCENT_LU6612 0x0c + #define MII_MODEL_MARVELL_88E1000 0x00 #define MII_MODEL_MARVELL_88E1011 0x02 #define MII_MODEL_MARVELL_88E1000_2 0x03 diff --git a/usr/src/uts/intel/hme/Makefile b/usr/src/uts/intel/hme/Makefile index 34038f4cf1..1065312ea1 100644 --- a/usr/src/uts/intel/hme/Makefile +++ b/usr/src/uts/intel/hme/Makefile @@ -57,7 +57,7 @@ INSTALL_TARGET = $(BINARY) $(ROOTMODULE) # Overrides. # CFLAGS += $(CCVERBOSE) -LDFLAGS += -dy -Ndrv/ip -Nmisc/mac +LDFLAGS += -dy -Nmisc/mii -Nmisc/mac # # Default build targets. diff --git a/usr/src/uts/sparc/hme/Makefile b/usr/src/uts/sparc/hme/Makefile index 57abff14fd..196d125161 100644 --- a/usr/src/uts/sparc/hme/Makefile +++ b/usr/src/uts/sparc/hme/Makefile @@ -21,9 +21,7 @@ # # uts/sparc/hme/Makefile # -# ident "%Z%%M% %I% %E% SMI" -# -# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # This makefile drives the production of the hme driver @@ -59,16 +57,7 @@ INSTALL_TARGET = $(BINARY) $(ROOTMODULE) # Overrides. # CFLAGS += $(CCVERBOSE) -LDFLAGS += -dy -Ndrv/ip -Nmisc/mac - -# -# 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 +LDFLAGS += -dy -Nmisc/mii -Nmisc/mac # # Default build targets. |