From owner-svn-src-head@FreeBSD.ORG Sat Mar 13 04:55:48 2010 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 63159106566C; Sat, 13 Mar 2010 04:55:48 +0000 (UTC) (envelope-from jmallett@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 526EA8FC1E; Sat, 13 Mar 2010 04:55:48 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o2D4tm3I018102; Sat, 13 Mar 2010 04:55:48 GMT (envelope-from jmallett@svn.freebsd.org) Received: (from jmallett@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o2D4tmmq018101; Sat, 13 Mar 2010 04:55:48 GMT (envelope-from jmallett@svn.freebsd.org) Message-Id: <201003130455.o2D4tmmq018101@svn.freebsd.org> From: Juli Mallett Date: Sat, 13 Mar 2010 04:55:47 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r205115 - head/sys/mips/cavium/dev/rgmii X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 13 Mar 2010 04:55:48 -0000 Author: jmallett Date: Sat Mar 13 04:55:47 2010 New Revision: 205115 URL: http://svn.freebsd.org/changeset/base/205115 Log: o) Use octeon_fpa_alloc_phys in a situation in which we don't need a usable pointer, rather than octeon_fpa_alloc. o) Report half duplex status properly. o) Do not unconditionally update the last known link status in the softc. If report_link isn't set, when octeon_rgmx_config_speed is called the first time it will tell the driver (essentially) that we have already marked the interface up. Likewise, don't change media speed and duplex if only the link status is at issue. [1] o) Remove manual changing of link state and let octeon_rgmx_config_speed do the heavy lifting. [1] Reviewed by: [1] imp Sponsored by: Packet Forensics Modified: head/sys/mips/cavium/dev/rgmii/octeon_rgmx.c Modified: head/sys/mips/cavium/dev/rgmii/octeon_rgmx.c ============================================================================== --- head/sys/mips/cavium/dev/rgmii/octeon_rgmx.c Sat Mar 13 04:00:36 2010 (r205114) +++ head/sys/mips/cavium/dev/rgmii/octeon_rgmx.c Sat Mar 13 04:55:47 2010 (r205115) @@ -1015,10 +1015,9 @@ static u_int octeon_rgmx_pko_xmit_packet * 3 words or less are left. We write our 2nd word now and then put in a chain link * to new PKO cmd buf. */ - void *pko_cmd_buf = octeon_fpa_alloc(OCTEON_FPA_TX_CMDBUF_POOL); - uint64_t phys_cmd_buf; + uint64_t phys_cmd_buf = octeon_fpa_alloc_phys(OCTEON_FPA_TX_CMDBUF_POOL); - if (!pko_cmd_buf) { + if (!phys_cmd_buf) { /* * FPA pool for xmit-buffer-commands is empty. */ @@ -1026,7 +1025,6 @@ static u_int octeon_rgmx_pko_xmit_packet octeon_spinlock_unlock(&(sc->outq_ptr[queue].lock)); return (0); } - phys_cmd_buf = OCTEON_PTR2PHYS(pko_cmd_buf); xmit_cmd_ptr[1] = pko_pkt_word.word64; xmit_cmd_ptr[2] = phys_cmd_buf; @@ -1678,8 +1676,13 @@ static void octeon_rgmx_medstat (struct break; } - /* Always full duplex. */ - ifm->ifm_active |= IFM_FDX; + /* + * Check duplex. + */ + if (link_status.bits.duplex == 1) + ifm->ifm_active |= IFM_FDX; + else + ifm->ifm_active |= IFM_HDX; RGMX_UNLOCK(sc); } @@ -1815,7 +1818,6 @@ static int octeon_rgmx_ioctl (struct ifn static void octeon_rgmx_init (void *xsc) { struct rgmx_softc_dev *sc = xsc; - octeon_rgmx_rxx_rx_inbnd_t link_status; /* Enable interrupts. */ /* For RGMX they are already enabled earlier */ @@ -1836,19 +1838,7 @@ static void octeon_rgmx_init (void *xsc /* Hopefully PKO is running and will pick up packets via the timer or receive loop */ /* Set link status. */ - octeon_rgmx_config_speed(sc->port, 0); - - RGMX_LOCK(sc); - /* - * Parse link status. - */ - link_status.word64 = sc->link_status; - - if (link_status.bits.status) - if_link_state_change(sc->ifp, LINK_STATE_UP); - else - if_link_state_change(sc->ifp, LINK_STATE_DOWN); - RGMX_UNLOCK(sc); + octeon_rgmx_config_speed(sc->port, 1); } @@ -1863,7 +1853,6 @@ static void octeon_rgmx_config_speed (u_ uint64_t val64_tx_clk, val64_tx_slot, val64_tx_burst; u_int last_enabled; - sc = get_rgmx_softc(port); if (!sc) { printf(" config_speed didn't find sc int:%u port:%u", iface, port); @@ -1875,79 +1864,96 @@ static void octeon_rgmx_config_speed (u_ */ link_status.word64 = oct_read64(OCTEON_RGMX_RXX_RX_INBND(index, iface)); + RGMX_LOCK(sc); + /* * Compre to prev known state. If same then nothing to do. */ if (link_status.word64 == sc->link_status) { + RGMX_UNLOCK(sc); return; } - - RGMX_LOCK(sc); - old_link_status.word64 = sc->link_status; - sc->link_status = link_status.word64; - - last_enabled = octeon_rgmx_stop_port(port); - - gmx_cfg.word64 = oct_read64(OCTEON_RGMX_PRTX_CFG(index, iface)); - - /* - * Duplex - */ - gmx_cfg.bits.duplex = 1; - - switch (link_status.bits.speed) { - case 0: /* 10Mbps */ - gmx_cfg.bits.speed = 0; - gmx_cfg.bits.slottime = 0; - val64_tx_clk = 50; val64_tx_slot = 0x40; val64_tx_burst = 0; - break; - case 1: /* 100Mbps */ - gmx_cfg.bits.speed = 0; - gmx_cfg.bits.slottime = 0; - val64_tx_clk = 5; val64_tx_slot = 0x40; val64_tx_burst = 0; - break; - - case 2: /* 1Gbps */ - gmx_cfg.bits.speed = 1; - gmx_cfg.bits.slottime = 1; - val64_tx_clk = 1; val64_tx_slot = 0x200; val64_tx_burst = 0x2000; - break; - - case 3: /* ?? */ - default: - gmx_cfg.bits.speed = 1; - gmx_cfg.bits.slottime = 1; - val64_tx_clk = 1; val64_tx_slot = 0x200; val64_tx_burst = 0x2000; - break; - } - - oct_write64(OCTEON_RGMX_TXX_CLK(index, iface), val64_tx_clk); - oct_write64(OCTEON_RGMX_TXX_SLOT(index, iface), val64_tx_slot); - oct_write64(OCTEON_RGMX_TXX_BURST(index, iface), val64_tx_burst); - - oct_write64(OCTEON_RGMX_PRTX_CFG(index, iface), gmx_cfg.word64); + /* + * Compare to previous state modulo link status. If only link + * status is different, we don't need to change media. + */ + if (old_link_status.bits.duplex != link_status.bits.duplex || + old_link_status.bits.speed != link_status.bits.speed) { + last_enabled = octeon_rgmx_stop_port(port); + + gmx_cfg.word64 = oct_read64(OCTEON_RGMX_PRTX_CFG(index, iface)); + + /* + * Duplex + * XXX Set based on link_status.bits.duplex? + */ + gmx_cfg.bits.duplex = 1; + + switch (link_status.bits.speed) { + case 0: /* 10Mbps */ + gmx_cfg.bits.speed = 0; + gmx_cfg.bits.slottime = 0; + val64_tx_clk = 50; val64_tx_slot = 0x40; val64_tx_burst = 0; + break; + + case 1: /* 100Mbps */ + gmx_cfg.bits.speed = 0; + gmx_cfg.bits.slottime = 0; + val64_tx_clk = 5; val64_tx_slot = 0x40; val64_tx_burst = 0; + break; + + case 2: /* 1Gbps */ + gmx_cfg.bits.speed = 1; + gmx_cfg.bits.slottime = 1; + val64_tx_clk = 1; val64_tx_slot = 0x200; val64_tx_burst = 0x2000; + break; + + case 3: /* ?? */ + default: + gmx_cfg.bits.speed = 1; + gmx_cfg.bits.slottime = 1; + val64_tx_clk = 1; val64_tx_slot = 0x200; val64_tx_burst = 0x2000; + break; + } + + oct_write64(OCTEON_RGMX_TXX_CLK(index, iface), val64_tx_clk); + oct_write64(OCTEON_RGMX_TXX_SLOT(index, iface), val64_tx_slot); + oct_write64(OCTEON_RGMX_TXX_BURST(index, iface), val64_tx_burst); + + oct_write64(OCTEON_RGMX_PRTX_CFG(index, iface), gmx_cfg.word64); + + if (last_enabled) octeon_rgmx_start_port(port); + } - if (last_enabled) octeon_rgmx_start_port(port); + /* + * Now check and possibly change link status. + */ + if (link_status.bits.status != old_link_status.bits.status) { + if (report_link) { + if (link_status.bits.status) { + if_link_state_change(sc->ifp, LINK_STATE_UP); + } else { + if_link_state_change(sc->ifp, LINK_STATE_DOWN); + } + } + } - if (link_status.bits.status != old_link_status.bits.status) { + if (report_link) { + sc->link_status = link_status.word64; + } else { + /* + * We can't update link status proper since we can't + * change it in the interface, so keep the old link + * status intact but note the current speed and duplex + * settings. + */ + link_status.bits.status = old_link_status.bits.status; + sc->link_status = link_status.word64; + } -//#define DEBUG_LINESTATUS - if (link_status.bits.status) { -#ifdef DEBUG_LINESTATUS - printf(" %u/%u: Interface is now alive\n", iface, port); -#endif - if (report_link) if_link_state_change(sc->ifp, LINK_STATE_UP); - } else { -#ifdef DEBUG_LINESTATUS - printf(" %u/%u: Interface went down\n", iface, port); -#endif - if (report_link) if_link_state_change(sc->ifp, LINK_STATE_DOWN); - } - } RGMX_UNLOCK(sc); - } @@ -2167,7 +2173,6 @@ static void octeon_config_rgmii_port (u_ gmx_cfg.bits.en = 1; oct_write64(OCTEON_RGMX_PRTX_CFG(index, iface), gmx_cfg.word64); - octeon_rgmx_config_speed(port, 0); oct_write64(OCTEON_RGMX_TXX_THRESH(index, iface), 32);