Date: Mon, 29 Oct 2012 13:49:06 +0000 (UTC) From: Andre Oppermann <andre@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r242312 - in user/andre/tcp_workqueue/sys: contrib/octeon-sdk dev/acpi_support dev/ath dev/mii kern mips/cavium netinet sys vm Message-ID: <201210291349.q9TDn6Fu073307@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: andre Date: Mon Oct 29 13:49:06 2012 New Revision: 242312 URL: http://svn.freebsd.org/changeset/base/242312 Log: Integrate from HEAD @242311. Modified: user/andre/tcp_workqueue/sys/contrib/octeon-sdk/cvmx-ebt3000.c user/andre/tcp_workqueue/sys/dev/acpi_support/acpi_ibm.c user/andre/tcp_workqueue/sys/dev/ath/if_ath.c user/andre/tcp_workqueue/sys/dev/ath/if_ath_misc.h user/andre/tcp_workqueue/sys/dev/ath/if_ath_tx.c user/andre/tcp_workqueue/sys/dev/ath/if_ath_tx.h user/andre/tcp_workqueue/sys/dev/ath/if_athvar.h user/andre/tcp_workqueue/sys/dev/mii/e1000phy.c user/andre/tcp_workqueue/sys/kern/kern_mbuf.c user/andre/tcp_workqueue/sys/kern/uipc_mbuf.c user/andre/tcp_workqueue/sys/mips/cavium/files.octeon1 user/andre/tcp_workqueue/sys/mips/cavium/octeon_ebt3000_cf.c user/andre/tcp_workqueue/sys/mips/cavium/octeon_machdep.c user/andre/tcp_workqueue/sys/mips/cavium/octeon_pcmap_regs.h user/andre/tcp_workqueue/sys/mips/cavium/uart_dev_oct16550.c user/andre/tcp_workqueue/sys/netinet/tcp_output.c user/andre/tcp_workqueue/sys/netinet/tcp_timer.h user/andre/tcp_workqueue/sys/sys/sched.h user/andre/tcp_workqueue/sys/vm/vm_page.c user/andre/tcp_workqueue/sys/vm/vm_page.h user/andre/tcp_workqueue/sys/vm/vm_pageout.c Directory Properties: user/andre/tcp_workqueue/sys/ (props changed) user/andre/tcp_workqueue/sys/contrib/octeon-sdk/ (props changed) Modified: user/andre/tcp_workqueue/sys/contrib/octeon-sdk/cvmx-ebt3000.c ============================================================================== --- user/andre/tcp_workqueue/sys/contrib/octeon-sdk/cvmx-ebt3000.c Mon Oct 29 13:16:33 2012 (r242311) +++ user/andre/tcp_workqueue/sys/contrib/octeon-sdk/cvmx-ebt3000.c Mon Oct 29 13:49:06 2012 (r242312) @@ -52,15 +52,18 @@ * */ +#if !defined(__FreeBSD__) || !defined(_KERNEL) #include "cvmx-config.h" +#endif #include "cvmx.h" +#include "cvmx-ebt3000.h" #include "cvmx-sysinfo.h" void ebt3000_char_write(int char_position, char val) { /* Note: phys_to_ptr won't work here, as we are most likely going to access the boot bus. */ - void *led_base = CASTPTR(void, CVMX_ADD_SEG32(CVMX_MIPS32_SPACE_KSEG0, cvmx_sysinfo_get()->led_display_base_addr)); + char *led_base = CASTPTR(char , CVMX_ADD_SEG32(CVMX_MIPS32_SPACE_KSEG0, cvmx_sysinfo_get()->led_display_base_addr)); if (!led_base) return; if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_EBT3000 && cvmx_sysinfo_get()->board_rev_major == 1) @@ -82,10 +85,10 @@ void ebt3000_char_write(int char_positio void ebt3000_str_write(const char *str) { /* Note: phys_to_ptr won't work here, as we are most likely going to access the boot bus. */ - void *led_base; + char *led_base; if (!cvmx_sysinfo_get()->led_display_base_addr) return; - led_base = CASTPTR(void, CVMX_ADD_SEG32(CVMX_MIPS32_SPACE_KSEG0, cvmx_sysinfo_get()->led_display_base_addr)); + led_base = CASTPTR(char, CVMX_ADD_SEG32(CVMX_MIPS32_SPACE_KSEG0, cvmx_sysinfo_get()->led_display_base_addr)); if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_EBT3000 && cvmx_sysinfo_get()->board_rev_major == 1) { char *ptr = (char *)(led_base + 4); Modified: user/andre/tcp_workqueue/sys/dev/acpi_support/acpi_ibm.c ============================================================================== --- user/andre/tcp_workqueue/sys/dev/acpi_support/acpi_ibm.c Mon Oct 29 13:16:33 2012 (r242311) +++ user/andre/tcp_workqueue/sys/dev/acpi_support/acpi_ibm.c Mon Oct 29 13:49:06 2012 (r242312) @@ -317,7 +317,7 @@ static devclass_t acpi_ibm_devclass; DRIVER_MODULE(acpi_ibm, acpi, acpi_ibm_driver, acpi_ibm_devclass, 0, 0); MODULE_DEPEND(acpi_ibm, acpi, 1, 1, 1); -static char *ibm_ids[] = {"IBM0068", NULL}; +static char *ibm_ids[] = {"IBM0068", "LEN0068", NULL}; static void ibm_led(void *softc, int onoff) Modified: user/andre/tcp_workqueue/sys/dev/ath/if_ath.c ============================================================================== --- user/andre/tcp_workqueue/sys/dev/ath/if_ath.c Mon Oct 29 13:16:33 2012 (r242311) +++ user/andre/tcp_workqueue/sys/dev/ath/if_ath.c Mon Oct 29 13:49:06 2012 (r242312) @@ -201,6 +201,7 @@ static void ath_announce(struct ath_soft static void ath_dfs_tasklet(void *, int); static void ath_node_powersave(struct ieee80211_node *, int); +static int ath_node_set_tim(struct ieee80211_node *, int); #ifdef IEEE80211_SUPPORT_TDMA #include <dev/ath/if_ath_tdma.h> @@ -1152,6 +1153,9 @@ ath_vap_create(struct ieee80211com *ic, avp->av_node_ps = vap->iv_node_ps; vap->iv_node_ps = ath_node_powersave; + avp->av_set_tim = vap->iv_set_tim; + vap->iv_set_tim = ath_node_set_tim; + /* Set default parameters */ /* @@ -2558,6 +2562,12 @@ ath_start(struct ifnet *ifp) ieee80211_free_node(ni); continue; } + + /* + * Check here if the node is in power save state. + */ + ath_tx_update_tim(sc, ni, 1); + if (next != NULL) { /* * Beware of state changing between frags. @@ -3536,6 +3546,24 @@ ath_tx_default_comp(struct ath_softc *sc SEQNO(bf->bf_state.bfs_seqno)); /* + * Check if the node software queue is empty; if so + * then clear the TIM. + * + * This needs to be done before the buffer is freed as + * otherwise the node reference will have been released + * and the node may not actually exist any longer. + * + * XXX I don't like this belonging here, but it's cleaner + * to do it here right now then all the other places + * where ath_tx_default_comp() is called. + * + * XXX TODO: during drain, ensure that the callback is + * being called so we get a chance to update the TIM. + */ + if (bf->bf_node) + ath_tx_update_tim(sc, bf->bf_node, 0); + + /* * Do any tx complete callback. Note this must * be done before releasing the node reference. * This will free the mbuf, release the net80211 @@ -3559,6 +3587,7 @@ ath_tx_update_ratectrl(struct ath_softc return; an = ATH_NODE(ni); + ATH_NODE_UNLOCK_ASSERT(an); if ((ts->ts_status & HAL_TXERR_FILT) == 0) { ATH_NODE_LOCK(an); @@ -3754,6 +3783,8 @@ ath_tx_processq(struct ath_softc *sc, st * Update statistics and call completion */ ath_tx_process_buf_completion(sc, txq, ts, bf); + + /* XXX at this point, bf and ni may be totally invalid */ } #ifdef IEEE80211_SUPPORT_SUPERG /* @@ -5397,6 +5428,219 @@ ath_node_powersave(struct ieee80211_node avp->av_node_ps(ni, enable); } +/* + * Notification from net80211 that the powersave queue state has + * changed. + * + * Since the software queue also may have some frames: + * + * + if the node software queue has frames and the TID state + * is 0, we set the TIM; + * + if the node and the stack are both empty, we clear the TIM bit. + * + If the stack tries to set the bit, always set it. + * + If the stack tries to clear the bit, only clear it if the + * software queue in question is also cleared. + * + * TODO: this is called during node teardown; so let's ensure this + * is all correctly handled and that the TIM bit is cleared. + * It may be that the node flush is called _AFTER_ the net80211 + * stack clears the TIM. + * + * Here is the racy part. Since it's possible >1 concurrent, + * overlapping TXes will appear complete with a TX completion in + * another thread, it's possible that the concurrent TIM calls will + * clash. We can't hold the node lock here because setting the + * TIM grabs the net80211 comlock and this may cause a LOR. + * The solution is either to totally serialise _everything_ at + * this point (ie, all TX, completion and any reset/flush go into + * one taskqueue) or a new "ath TIM lock" needs to be created that + * just wraps the driver state change and this call to avp->av_set_tim(). + * + * The same race exists in the net80211 power save queue handling + * as well. Since multiple transmitting threads may queue frames + * into the driver, as well as ps-poll and the driver transmitting + * frames (and thus clearing the psq), it's quite possible that + * a packet entering the PSQ and a ps-poll being handled will + * race, causing the TIM to be cleared and not re-set. + */ +static int +ath_node_set_tim(struct ieee80211_node *ni, int enable) +{ + struct ieee80211com *ic = ni->ni_ic; + struct ath_softc *sc = ic->ic_ifp->if_softc; + struct ath_node *an = ATH_NODE(ni); + struct ath_vap *avp = ATH_VAP(ni->ni_vap); + int changed = 0; + + ATH_NODE_UNLOCK_ASSERT(an); + + /* + * For now, just track and then update the TIM. + */ + ATH_NODE_LOCK(an); + an->an_stack_psq = enable; + + /* + * This will get called for all operating modes, + * even if avp->av_set_tim is unset. + * It's currently set for hostap/ibss modes; but + * the same infrastructure is used for both STA + * and AP/IBSS node power save. + */ + if (avp->av_set_tim == NULL) { + ATH_NODE_UNLOCK(an); + return (0); + } + + /* + * If setting the bit, always set it here. + * If clearing the bit, only clear it if the + * software queue is also empty. + * + * If the node has left power save, just clear the TIM + * bit regardless of the state of the power save queue. + * + * XXX TODO: although atomics are used, it's quite possible + * that a race will occur between this and setting/clearing + * in another thread. TX completion will occur always in + * one thread, however setting/clearing the TIM bit can come + * from a variety of different process contexts! + */ + if (enable && an->an_tim_set == 1) { + DPRINTF(sc, ATH_DEBUG_NODE_PWRSAVE, + "%s: an=%p, enable=%d, tim_set=1, ignoring\n", + __func__, an, enable); + ATH_NODE_UNLOCK(an); + } else if (enable) { + DPRINTF(sc, ATH_DEBUG_NODE_PWRSAVE, + "%s: an=%p, enable=%d, enabling TIM\n", + __func__, an, enable); + an->an_tim_set = 1; + ATH_NODE_UNLOCK(an); + changed = avp->av_set_tim(ni, enable); + } else if (atomic_load_acq_int(&an->an_swq_depth) == 0) { + /* disable */ + DPRINTF(sc, ATH_DEBUG_NODE_PWRSAVE, + "%s: an=%p, enable=%d, an_swq_depth == 0, disabling\n", + __func__, an, enable); + an->an_tim_set = 0; + ATH_NODE_UNLOCK(an); + changed = avp->av_set_tim(ni, enable); + } else if (! an->an_is_powersave) { + /* + * disable regardless; the node isn't in powersave now + */ + DPRINTF(sc, ATH_DEBUG_NODE_PWRSAVE, + "%s: an=%p, enable=%d, an_pwrsave=0, disabling\n", + __func__, an, enable); + an->an_tim_set = 0; + ATH_NODE_UNLOCK(an); + changed = avp->av_set_tim(ni, enable); + } else { + /* + * psq disable, node is currently in powersave, node + * software queue isn't empty, so don't clear the TIM bit + * for now. + */ + ATH_NODE_UNLOCK(an); + DPRINTF(sc, ATH_DEBUG_NODE_PWRSAVE, + "%s: enable=%d, an_swq_depth > 0, ignoring\n", + __func__, enable); + changed = 0; + } + + return (changed); +} + +/* + * Set or update the TIM from the software queue. + * + * Check the software queue depth before attempting to do lock + * anything; that avoids trying to obtain the lock. Then, + * re-check afterwards to ensure nothing has changed in the + * meantime. + * + * set: This is designed to be called from the TX path, after + * a frame has been queued; to see if the swq > 0. + * + * clear: This is designed to be called from the buffer completion point + * (right now it's ath_tx_default_comp()) where the state of + * a software queue has changed. + * + * It makes sense to place it at buffer free / completion rather + * than after each software queue operation, as there's no real + * point in churning the TIM bit as the last frames in the software + * queue are transmitted. If they fail and we retry them, we'd + * just be setting the TIM bit again anyway. + */ +void +ath_tx_update_tim(struct ath_softc *sc, struct ieee80211_node *ni, + int enable) +{ + struct ath_node *an; + struct ath_vap *avp; + + /* Don't do this for broadcast/etc frames */ + if (ni == NULL) + return; + + an = ATH_NODE(ni); + avp = ATH_VAP(ni->ni_vap); + + /* + * And for operating modes without the TIM handler set, let's + * just skip those. + */ + if (avp->av_set_tim == NULL) + return; + + ATH_NODE_UNLOCK_ASSERT(an); + + if (enable) { + /* + * Don't bother grabbing the lock unless the queue is not + * empty. + */ + if (atomic_load_acq_int(&an->an_swq_depth) == 0) + return; + + ATH_NODE_LOCK(an); + if (an->an_is_powersave && + an->an_tim_set == 0 && + atomic_load_acq_int(&an->an_swq_depth) != 0) { + DPRINTF(sc, ATH_DEBUG_NODE_PWRSAVE, + "%s: an=%p, swq_depth>0, tim_set=0, set!\n", + __func__, an); + an->an_tim_set = 1; + ATH_NODE_UNLOCK(an); + (void) avp->av_set_tim(ni, 1); + } else { + ATH_NODE_UNLOCK(an); + } + } else { + /* + * Don't bother grabbing the lock unless the queue is empty. + */ + if (atomic_load_acq_int(&an->an_swq_depth) != 0) + return; + + ATH_NODE_LOCK(an); + if (an->an_is_powersave && + an->an_stack_psq == 0 && + an->an_tim_set == 1 && + atomic_load_acq_int(&an->an_swq_depth) == 0) { + DPRINTF(sc, ATH_DEBUG_NODE_PWRSAVE, + "%s: an=%p, swq_depth=0, tim_set=1, psq_set=0," + " clear!\n", + __func__, an); + an->an_tim_set = 0; + ATH_NODE_UNLOCK(an); + (void) avp->av_set_tim(ni, 0); + } else { + ATH_NODE_UNLOCK(an); + } + } +} MODULE_VERSION(if_ath, 1); MODULE_DEPEND(if_ath, wlan, 1, 1, 1); /* 802.11 media layer */ Modified: user/andre/tcp_workqueue/sys/dev/ath/if_ath_misc.h ============================================================================== --- user/andre/tcp_workqueue/sys/dev/ath/if_ath_misc.h Mon Oct 29 13:16:33 2012 (r242311) +++ user/andre/tcp_workqueue/sys/dev/ath/if_ath_misc.h Mon Oct 29 13:49:06 2012 (r242312) @@ -107,6 +107,9 @@ extern void ath_tx_process_buf_completio extern int ath_stoptxdma(struct ath_softc *sc); +extern void ath_tx_update_tim(struct ath_softc *sc, + struct ieee80211_node *ni, int enable); + /* * This is only here so that the RX proc function can call it. * It's very likely that the "start TX after RX" call should be Modified: user/andre/tcp_workqueue/sys/dev/ath/if_ath_tx.c ============================================================================== --- user/andre/tcp_workqueue/sys/dev/ath/if_ath_tx.c Mon Oct 29 13:16:33 2012 (r242311) +++ user/andre/tcp_workqueue/sys/dev/ath/if_ath_tx.c Mon Oct 29 13:49:06 2012 (r242312) @@ -2219,6 +2219,13 @@ ath_raw_xmit(struct ieee80211_node *ni, ifp->if_opackets++; sc->sc_stats.ast_tx_raw++; + /* + * Update the TIM - if there's anything queued to the + * software queue and power save is enabled, we should + * set the TIM. + */ + ath_tx_update_tim(sc, ni, 1); + ATH_PCU_LOCK(sc); sc->sc_txstart_cnt--; ATH_PCU_UNLOCK(sc); @@ -5292,11 +5299,10 @@ ath_addba_response_timeout(struct ieee80 ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]); } -#if 0 /* * Check if a node is asleep or not. */ -static int +int ath_tx_node_is_asleep(struct ath_softc *sc, struct ath_node *an) { @@ -5304,7 +5310,6 @@ ath_tx_node_is_asleep(struct ath_softc * return (an->an_is_powersave); } -#endif /* * Mark a node as currently "in powersaving." Modified: user/andre/tcp_workqueue/sys/dev/ath/if_ath_tx.h ============================================================================== --- user/andre/tcp_workqueue/sys/dev/ath/if_ath_tx.h Mon Oct 29 13:16:33 2012 (r242311) +++ user/andre/tcp_workqueue/sys/dev/ath/if_ath_tx.h Mon Oct 29 13:49:06 2012 (r242312) @@ -128,6 +128,7 @@ extern void ath_addba_response_timeout(s */ extern void ath_tx_node_sleep(struct ath_softc *sc, struct ath_node *an); extern void ath_tx_node_wakeup(struct ath_softc *sc, struct ath_node *an); +extern int ath_tx_node_is_asleep(struct ath_softc *sc, struct ath_node *an); /* * Setup path Modified: user/andre/tcp_workqueue/sys/dev/ath/if_athvar.h ============================================================================== --- user/andre/tcp_workqueue/sys/dev/ath/if_athvar.h Mon Oct 29 13:16:33 2012 (r242311) +++ user/andre/tcp_workqueue/sys/dev/ath/if_athvar.h Mon Oct 29 13:49:06 2012 (r242312) @@ -173,6 +173,8 @@ struct ath_node { u_int8_t an_mgmtrix; /* min h/w rate index */ u_int8_t an_mcastrix; /* mcast h/w rate index */ uint32_t an_is_powersave; /* node is sleeping */ + uint32_t an_stack_psq; /* net80211 psq isn't empty */ + uint32_t an_tim_set; /* TIM has been set */ struct ath_buf *an_ff_buf[WME_NUM_AC]; /* ff staging area */ struct ath_tid an_tid[IEEE80211_TID_SIZE]; /* per-TID state */ char an_name[32]; /* eg "wlan0_a1" */ @@ -432,6 +434,7 @@ struct ath_vap { enum ieee80211_state, int); void (*av_bmiss)(struct ieee80211vap *); void (*av_node_ps)(struct ieee80211_node *, int); + int (*av_set_tim)(struct ieee80211_node *, int); }; #define ATH_VAP(vap) ((struct ath_vap *)(vap)) Modified: user/andre/tcp_workqueue/sys/dev/mii/e1000phy.c ============================================================================== --- user/andre/tcp_workqueue/sys/dev/mii/e1000phy.c Mon Oct 29 13:16:33 2012 (r242311) +++ user/andre/tcp_workqueue/sys/dev/mii/e1000phy.c Mon Oct 29 13:49:06 2012 (r242312) @@ -108,6 +108,7 @@ static const struct mii_phydesc e1000phy MII_PHY_DESC(xxMARVELL, E1116R), MII_PHY_DESC(xxMARVELL, E1116R_29), MII_PHY_DESC(xxMARVELL, E1118), + MII_PHY_DESC(xxMARVELL, E1145), MII_PHY_DESC(xxMARVELL, E1149R), MII_PHY_DESC(xxMARVELL, E3016), MII_PHY_DESC(xxMARVELL, PHYG65G), Modified: user/andre/tcp_workqueue/sys/kern/kern_mbuf.c ============================================================================== --- user/andre/tcp_workqueue/sys/kern/kern_mbuf.c Mon Oct 29 13:16:33 2012 (r242311) +++ user/andre/tcp_workqueue/sys/kern/kern_mbuf.c Mon Oct 29 13:49:06 2012 (r242312) @@ -244,7 +244,7 @@ static void mb_reclaim(void *); static void mbuf_init(void *); static void *mbuf_jumbo_alloc(uma_zone_t, int, uint8_t *, int); -/* Ensure that MSIZE doesn't break dtom() - it must be a power of 2 */ +/* Ensure that MSIZE must be a power of 2. */ CTASSERT((((MSIZE - 1) ^ MSIZE) + 1) >> 1 == MSIZE); /* Modified: user/andre/tcp_workqueue/sys/kern/uipc_mbuf.c ============================================================================== --- user/andre/tcp_workqueue/sys/kern/uipc_mbuf.c Mon Oct 29 13:16:33 2012 (r242311) +++ user/andre/tcp_workqueue/sys/kern/uipc_mbuf.c Mon Oct 29 13:49:06 2012 (r242312) @@ -1000,8 +1000,8 @@ m_adj(struct mbuf *mp, int req_len) /* * Rearange an mbuf chain so that len bytes are contiguous - * and in the data area of an mbuf (so that mtod and dtom - * will work for a structure of size len). Returns the resulting + * and in the data area of an mbuf (so that mtod will work + * for a structure of size len). Returns the resulting * mbuf chain on success, frees it and returns null on failure. * If there is room, it will add up to max_protohdr-len extra bytes to the * contiguous region in an attempt to avoid being called next time. Modified: user/andre/tcp_workqueue/sys/mips/cavium/files.octeon1 ============================================================================== --- user/andre/tcp_workqueue/sys/mips/cavium/files.octeon1 Mon Oct 29 13:16:33 2012 (r242311) +++ user/andre/tcp_workqueue/sys/mips/cavium/files.octeon1 Mon Oct 29 13:49:06 2012 (r242312) @@ -58,6 +58,7 @@ mips/cavium/octeon_gpio.c optional gpi contrib/octeon-sdk/cvmx-cmd-queue.c standard contrib/octeon-sdk/cvmx-bootmem.c standard contrib/octeon-sdk/cvmx-clock.c standard +contrib/octeon-sdk/cvmx-ebt3000.c standard contrib/octeon-sdk/cvmx-fpa.c standard contrib/octeon-sdk/cvmx-helper.c standard contrib/octeon-sdk/cvmx-helper-board.c standard Modified: user/andre/tcp_workqueue/sys/mips/cavium/octeon_ebt3000_cf.c ============================================================================== --- user/andre/tcp_workqueue/sys/mips/cavium/octeon_ebt3000_cf.c Mon Oct 29 13:16:33 2012 (r242311) +++ user/andre/tcp_workqueue/sys/mips/cavium/octeon_ebt3000_cf.c Mon Oct 29 13:49:06 2012 (r242312) @@ -326,15 +326,10 @@ static int cf_cmd_read (uint32_t nr_sect uint8_t *ptr_8; int error; -//#define OCTEON_VISUAL_CF_0 1 -#ifdef OCTEON_VISUAL_CF_0 - octeon_led_write_char(0, 'R'); -#endif ptr_8 = (uint8_t*)buf; ptr_16 = (uint16_t*)buf; lba = start_sector; - while (nr_sectors--) { error = cf_send_cmd(lba, CMD_READ_SECTOR); if (error != 0) { @@ -366,9 +361,6 @@ static int cf_cmd_read (uint32_t nr_sect lba++; } -#ifdef OCTEON_VISUAL_CF_0 - octeon_led_write_char(0, ' '); -#endif return (0); } @@ -387,10 +379,6 @@ static int cf_cmd_write (uint32_t nr_sec uint8_t *ptr_8; int error; -//#define OCTEON_VISUAL_CF_1 1 -#ifdef OCTEON_VISUAL_CF_1 - octeon_led_write_char(1, 'W'); -#endif lba = start_sector; ptr_8 = (uint8_t*)buf; ptr_16 = (uint16_t*)buf; @@ -425,9 +413,6 @@ static int cf_cmd_write (uint32_t nr_sec lba++; } -#ifdef OCTEON_VISUAL_CF_1 - octeon_led_write_char(1, ' '); -#endif return (0); } @@ -543,13 +528,6 @@ static int cf_wait_busy (void) { uint8_t status; -//#define OCTEON_VISUAL_CF_2 1 -#ifdef OCTEON_VISUAL_CF_2 - static int where0 = 0; - - octeon_led_run_wheel(&where0, 2); -#endif - switch (bus_type) { case CF_8: @@ -585,9 +563,6 @@ static int cf_wait_busy (void) return (ENXIO); } -#ifdef OCTEON_VISUAL_CF_2 - octeon_led_write_char(2, ' '); -#endif return (0); } Modified: user/andre/tcp_workqueue/sys/mips/cavium/octeon_machdep.c ============================================================================== --- user/andre/tcp_workqueue/sys/mips/cavium/octeon_machdep.c Mon Oct 29 13:16:33 2012 (r242311) +++ user/andre/tcp_workqueue/sys/mips/cavium/octeon_machdep.c Mon Oct 29 13:49:06 2012 (r242312) @@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$"); #include <sys/ptrace.h> #include <sys/reboot.h> #include <sys/signalvar.h> +#include <sys/sysctl.h> #include <sys/sysent.h> #include <sys/sysproto.h> #include <sys/time.h> @@ -74,6 +75,7 @@ __FBSDID("$FreeBSD$"); #include <contrib/octeon-sdk/cvmx.h> #include <contrib/octeon-sdk/cvmx-bootmem.h> +#include <contrib/octeon-sdk/cvmx-ebt3000.h> #include <contrib/octeon-sdk/cvmx-interrupt.h> #include <contrib/octeon-sdk/cvmx-version.h> @@ -159,88 +161,6 @@ platform_reset(void) cvmx_write_csr(CVMX_CIU_SOFT_RST, 1); } -void -octeon_led_write_char(int char_position, char val) -{ - uint64_t ptr = (OCTEON_CHAR_LED_BASE_ADDR | 0xf8); - - if (octeon_is_simulation()) - return; - - char_position &= 0x7; /* only 8 chars */ - ptr += char_position; - oct_write8_x8(ptr, val); -} - -void -octeon_led_write_char0(char val) -{ - uint64_t ptr = (OCTEON_CHAR_LED_BASE_ADDR | 0xf8); - - if (octeon_is_simulation()) - return; - oct_write8_x8(ptr, val); -} - -void -octeon_led_write_hexchar(int char_position, char hexval) -{ - uint64_t ptr = (OCTEON_CHAR_LED_BASE_ADDR | 0xf8); - char char1, char2; - - if (octeon_is_simulation()) - return; - - char1 = (hexval >> 4) & 0x0f; char1 = (char1 < 10)?char1+'0':char1+'7'; - char2 = (hexval & 0x0f); char2 = (char2 < 10)?char2+'0':char2+'7'; - char_position &= 0x7; /* only 8 chars */ - if (char_position > 6) - char_position = 6; - ptr += char_position; - oct_write8_x8(ptr, char1); - ptr++; - oct_write8_x8(ptr, char2); -} - -void -octeon_led_write_string(const char *str) -{ - uint64_t ptr = (OCTEON_CHAR_LED_BASE_ADDR | 0xf8); - int i; - - if (octeon_is_simulation()) - return; - - for (i=0; i<8; i++, ptr++) { - if (str && *str) - oct_write8_x8(ptr, *str++); - else - oct_write8_x8(ptr, ' '); - (void)cvmx_read_csr(CVMX_MIO_BOOT_BIST_STAT); - } -} - -static char progress[8] = { '-', '/', '|', '\\', '-', '/', '|', '\\'}; - -void -octeon_led_run_wheel(int *prog_count, int led_position) -{ - if (octeon_is_simulation()) - return; - octeon_led_write_char(led_position, progress[*prog_count]); - *prog_count += 1; - *prog_count &= 0x7; -} - -void -octeon_led_write_hex(uint32_t wl) -{ - char nbuf[80]; - - sprintf(nbuf, "%X", wl); - octeon_led_write_string(nbuf); -} - /* * octeon_debug_symbol * @@ -447,6 +367,46 @@ octeon_get_timecount(struct timecounter return ((unsigned)octeon_get_ticks()); } +static int +sysctl_machdep_led_display(SYSCTL_HANDLER_ARGS) +{ + size_t buflen; + char buf[9]; + int error; + + if (req->newptr == NULL) + return (EINVAL); + + if (cvmx_sysinfo_get()->led_display_base_addr == 0) + return (ENODEV); + + /* + * Revision 1.x of the EBT3000 only supports 4 characters, but + * other devices support 8. + */ + if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_EBT3000 && + cvmx_sysinfo_get()->board_rev_major == 1) + buflen = 4; + else + buflen = 8; + + if (req->newlen > buflen) + return (E2BIG); + + error = SYSCTL_IN(req, buf, req->newlen); + if (error != 0) + return (error); + + buf[req->newlen] = '\0'; + ebt3000_str_write(buf); + + return (0); +} + +SYSCTL_PROC(_machdep, OID_AUTO, led_display, CTLTYPE_STRING | CTLFLAG_WR, + NULL, 0, sysctl_machdep_led_display, "A", + "String to display on LED display"); + /** * version of printf that works better in exception context. * @@ -593,13 +553,19 @@ octeon_process_app_desc_ver_6(void) octeon_bootinfo->board_rev_major, octeon_bootinfo->board_rev_minor, octeon_bootinfo->eclock_hz); - memcpy(cvmx_sysinfo_get()->mac_addr_base, octeon_bootinfo->mac_addr_base, 6); + memcpy(cvmx_sysinfo_get()->mac_addr_base, + octeon_bootinfo->mac_addr_base, 6); cvmx_sysinfo_get()->mac_addr_count = octeon_bootinfo->mac_addr_count; cvmx_sysinfo_get()->compact_flash_common_base_addr = octeon_bootinfo->compact_flash_common_base_addr; cvmx_sysinfo_get()->compact_flash_attribute_base_addr = octeon_bootinfo->compact_flash_attribute_base_addr; cvmx_sysinfo_get()->core_mask = octeon_bootinfo->core_mask; + cvmx_sysinfo_get()->led_display_base_addr = + octeon_bootinfo->led_display_base_addr; + memcpy(cvmx_sysinfo_get()->board_serial_number, + octeon_bootinfo->board_serial_number, + sizeof cvmx_sysinfo_get()->board_serial_number); } static void @@ -616,6 +582,18 @@ octeon_boot_params_init(register_t ptr) KASSERT(octeon_bootinfo != NULL, ("octeon_bootinfo should be set")); + if (cvmx_sysinfo_get()->led_display_base_addr != 0) { + /* + * Revision 1.x of the EBT3000 only supports 4 characters, but + * other devices support 8. + */ + if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_EBT3000 && + cvmx_sysinfo_get()->board_rev_major == 1) + ebt3000_str_write("FBSD"); + else + ebt3000_str_write("FreeBSD!"); + } + if (cvmx_sysinfo_get()->phy_mem_desc_addr == (uint64_t)0) panic("Your boot loader did not supply a memory descriptor."); cvmx_bootmem_init(cvmx_sysinfo_get()->phy_mem_desc_addr); @@ -656,5 +634,6 @@ octeon_boot_params_init(register_t ptr) #endif strcpy(cpu_model, octeon_model_get_string(cvmx_get_proc_id())); printf("Model: %s\n", cpu_model); + printf("Serial number: %s\n", cvmx_sysinfo_get()->board_serial_number); } /* impEND: This stuff should move back into the Cavium SDK */ Modified: user/andre/tcp_workqueue/sys/mips/cavium/octeon_pcmap_regs.h ============================================================================== --- user/andre/tcp_workqueue/sys/mips/cavium/octeon_pcmap_regs.h Mon Oct 29 13:16:33 2012 (r242311) +++ user/andre/tcp_workqueue/sys/mips/cavium/octeon_pcmap_regs.h Mon Oct 29 13:49:06 2012 (r242312) @@ -54,7 +54,6 @@ #if defined(__mips_n64) #define oct_write64(a, v) (*(volatile uint64_t *)(a) = (uint64_t)(v)) -#define oct_write8_x8(a, v) (*(volatile uint8_t *)(a) = (uint8_t)(v)) #define OCT_READ(n, t) \ static inline t oct_read ## n(uintptr_t a) \ @@ -63,9 +62,6 @@ static inline t oct_read ## n(uintptr_t return (*p); \ } -OCT_READ(8, uint8_t); -OCT_READ(16, uint16_t); -OCT_READ(32, uint32_t); OCT_READ(64, uint64_t); #elif defined(__mips_n32) || defined(__mips_o32) @@ -81,17 +77,6 @@ static inline void oct_write64 (uint64_t : "r"(val64), "r"(csr_addr)); } -static inline void oct_write8_x8 (uint64_t csr_addr, uint8_t val8) -{ - __asm __volatile ( - ".set push\n" - ".set mips64\n" - "sb %0, 0(%1)\n" - ".set pop\n" - : - : "r"(val8), "r"(csr_addr)); -} - #define OCT_READ(n, t, insn) \ static inline t oct_read ## n(uint64_t a) \ { \ @@ -107,9 +92,6 @@ static inline t oct_read ## n(uint64_t a return ((t)tmp); \ } -OCT_READ(8, uint8_t, "lb"); -OCT_READ(16, uint16_t, "lh"); -OCT_READ(32, uint32_t, "lw"); OCT_READ(64, uint64_t, "ld"); #else @@ -158,66 +140,6 @@ static inline void oct_write64 (uint64_t intr_restore(sr); } -static inline void oct_write8_x8 (uint64_t csr_addr, uint8_t val8) -{ - uint32_t csr_addrh = csr_addr >> 32; - uint32_t csr_addrl = csr_addr; - uint32_t tmp1; - uint32_t tmp2; - register_t sr; - - sr = intr_disable(); - - __asm __volatile ( - ".set push\n" - ".set mips64\n" - ".set noreorder\n" - ".set noat\n" - "dsll %0, %3, 32\n" - "dsll %1, %4, 32\n" - "dsrl %1, %1, 32\n" - "or %0, %0, %1\n" - "sb %2, 0(%0)\n" - ".set pop\n" - : "=&r" (tmp1), "=&r" (tmp2) - : "r" (val8), "r" (csr_addrh), "r" (csr_addrl)); - - intr_restore(sr); -} - -#define OCT_READ(n, t, insn) \ -static inline t oct_read ## n(uint64_t csr_addr) \ -{ \ - uint32_t csr_addrh = csr_addr >> 32; \ - uint32_t csr_addrl = csr_addr; \ - uint32_t tmp1, tmp2; \ - register_t sr; \ - \ - sr = intr_disable(); \ - \ - __asm __volatile ( \ - ".set push\n" \ - ".set mips64\n" \ - ".set noreorder\n" \ - ".set noat\n" \ - "dsll %1, %2, 32\n" \ - "dsll %0, %3, 32\n" \ - "dsrl %0, %0, 32\n" \ - "or %1, %1, %0\n" \ - "lb %1, 0(%1)\n" \ - ".set pop\n" \ - : "=&r" (tmp1), "=&r" (tmp2) \ - : "r" (csr_addrh), "r" (csr_addrl)); \ - \ - intr_restore(sr); \ - \ - return ((t)tmp2); \ -} - -OCT_READ(8, uint8_t, "lb"); -OCT_READ(16, uint16_t, "lh"); -OCT_READ(32, uint32_t, "lw"); - static inline uint64_t oct_read64 (uint64_t csr_addr) { uint32_t csr_addrh = csr_addr >> 32; @@ -253,51 +175,18 @@ static inline uint64_t oct_read64 (uint6 #endif -#define oct_write64_int64(a, v) (oct_write64(a, (int64_t)(v))) - -/* - * Most write bus transactions are actually 64-bit on Octeon. - */ -static inline void oct_write8 (uint64_t csr_addr, uint8_t val8) -{ - oct_write64(csr_addr, (uint64_t) val8); -} - -static inline void oct_write16 (uint64_t csr_addr, uint16_t val16) -{ - oct_write64(csr_addr, (uint64_t) val16); -} - -static inline void oct_write32 (uint64_t csr_addr, uint32_t val32) -{ - oct_write64(csr_addr, (uint64_t) val32); -} - -#define oct_readint32(a) ((int32_t)oct_read32((a))) - /* * octeon_machdep.c * * Direct to Board Support level. */ -extern void octeon_led_write_char(int char_position, char val); -extern void octeon_led_write_hexchar(int char_position, char hexval); -extern void octeon_led_write_hex(uint32_t wl); -extern void octeon_led_write_string(const char *str); extern void octeon_reset(void); -extern void octeon_led_write_char0(char val); -extern void octeon_led_run_wheel(int *pos, int led_position); extern void octeon_debug_symbol(void); extern void octeon_ciu_reset(void); extern int octeon_is_simulation(void); #endif /* LOCORE */ /* - * EBT3000 LED Unit - */ -#define OCTEON_CHAR_LED_BASE_ADDR (0x1d020000 | (0x1ffffffffull << 31)) - -/* * Default FLASH device (physical) base address */ #define OCTEON_FLASH_BASE_ADDR (0x1d040000ull) Modified: user/andre/tcp_workqueue/sys/mips/cavium/uart_dev_oct16550.c ============================================================================== --- user/andre/tcp_workqueue/sys/mips/cavium/uart_dev_oct16550.c Mon Oct 29 13:16:33 2012 (r242311) +++ user/andre/tcp_workqueue/sys/mips/cavium/uart_dev_oct16550.c Mon Oct 29 13:49:06 2012 (r242312) @@ -632,13 +632,6 @@ oct16550_bus_ipend(struct uart_softc *sc } uart_unlock(sc->sc_hwmtx); -//#define OCTEON_VISUAL_UART 1 -#ifdef OCTEON_VISUAL_UART - static int where1 = 0; - - if (ipend) octeon_led_run_wheel(&where1, 6 + device_get_unit(sc->sc_dev)); -#endif - return (ipend); } Modified: user/andre/tcp_workqueue/sys/netinet/tcp_output.c ============================================================================== --- user/andre/tcp_workqueue/sys/netinet/tcp_output.c Mon Oct 29 13:16:33 2012 (r242311) +++ user/andre/tcp_workqueue/sys/netinet/tcp_output.c Mon Oct 29 13:49:06 2012 (r242312) @@ -547,13 +547,13 @@ after_sack_rexmit: /* * Sending of standalone window updates. * - * Window updates important when we close our window due to a full - * socket buffer and are opening it again after the application + * Window updates are important when we close our window due to a + * full socket buffer and are opening it again after the application * reads data from it. Once the window has opened again and the * remote end starts to send again the ACK clock takes over and * provides the most current window information. * - * We must avoid to the silly window syndrome whereas every read + * We must avoid the silly window syndrome whereas every read * from the receive buffer, no matter how small, causes a window * update to be sent. We also should avoid sending a flurry of * window updates when the socket buffer had queued a lot of data Modified: user/andre/tcp_workqueue/sys/netinet/tcp_timer.h ============================================================================== --- user/andre/tcp_workqueue/sys/netinet/tcp_timer.h Mon Oct 29 13:16:33 2012 (r242311) +++ user/andre/tcp_workqueue/sys/netinet/tcp_timer.h Mon Oct 29 13:49:06 2012 (r242312) @@ -118,7 +118,7 @@ #define TCP_MAXRXTSHIFT 12 /* maximum retransmits */ -#define TCPTV_DELACK (hz / PR_FASTHZ / 2) /* 100ms timeout */ +#define TCPTV_DELACK ( hz/10 ) /* 100ms timeout */ #ifdef TCPTIMERS static const char *tcptimers[] = Modified: user/andre/tcp_workqueue/sys/sys/sched.h ============================================================================== --- user/andre/tcp_workqueue/sys/sys/sched.h Mon Oct 29 13:16:33 2012 (r242311) +++ user/andre/tcp_workqueue/sys/sys/sched.h Mon Oct 29 13:49:06 2012 (r242312) @@ -151,11 +151,13 @@ static __inline void sched_pin(void) { curthread->td_pinned++; + __compiler_membar(); } static __inline void sched_unpin(void) { + __compiler_membar(); curthread->td_pinned--; } Modified: user/andre/tcp_workqueue/sys/vm/vm_page.c ============================================================================== --- user/andre/tcp_workqueue/sys/vm/vm_page.c Mon Oct 29 13:16:33 2012 (r242311) +++ user/andre/tcp_workqueue/sys/vm/vm_page.c Mon Oct 29 13:49:06 2012 (r242312) @@ -308,7 +308,6 @@ vm_page_startup(vm_offset_t vaddr) TAILQ_INIT(&vm_page_queues[i].pl); vm_page_queues[PQ_INACTIVE].cnt = &cnt.v_inactive_count; vm_page_queues[PQ_ACTIVE].cnt = &cnt.v_active_count; - vm_page_queues[PQ_HOLD].cnt = &cnt.v_active_count; /* * Allocate memory for use when boot strapping the kernel memory @@ -540,7 +539,7 @@ vm_page_unhold(vm_page_t mem) vm_page_lock_assert(mem, MA_OWNED); --mem->hold_count; KASSERT(mem->hold_count >= 0, ("vm_page_unhold: hold count < 0!!!")); - if (mem->hold_count == 0 && mem->queue == PQ_HOLD) + if (mem->hold_count == 0 && (mem->flags & PG_UNHOLDFREE) != 0) vm_page_free_toq(mem); } @@ -2042,9 +2041,9 @@ vm_page_free_toq(vm_page_t m) panic("vm_page_free: freeing wired page %p", m); if (m->hold_count != 0) { m->flags &= ~PG_ZERO; - vm_page_lock_queues(); - vm_page_enqueue(PQ_HOLD, m); - vm_page_unlock_queues(); + KASSERT((m->flags & PG_UNHOLDFREE) == 0, + ("vm_page_free: freeing PG_UNHOLDFREE page %p", m)); + m->flags |= PG_UNHOLDFREE; } else { /* * Restore the default memory attribute to the page. Modified: user/andre/tcp_workqueue/sys/vm/vm_page.h ============================================================================== --- user/andre/tcp_workqueue/sys/vm/vm_page.h Mon Oct 29 13:16:33 2012 (r242311) +++ user/andre/tcp_workqueue/sys/vm/vm_page.h Mon Oct 29 13:49:06 2012 (r242312) *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201210291349.q9TDn6Fu073307>