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

Andre Oppermann andre at FreeBSD.org
Mon Oct 29 13:49:07 UTC 2012


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 ***


More information about the svn-src-user mailing list