xref: /onnv-gate/usr/src/uts/common/io/e1000g/e1000g_tx.c (revision 6986:1e7638a44ce6)
13526Sxy150489 /*
23526Sxy150489  * This file is provided under a CDDLv1 license.  When using or
33526Sxy150489  * redistributing this file, you may do so under this license.
43526Sxy150489  * In redistributing this file this license must be included
53526Sxy150489  * and no other modification of this header file is permitted.
63526Sxy150489  *
73526Sxy150489  * CDDL LICENSE SUMMARY
83526Sxy150489  *
95882Syy150190  * Copyright(c) 1999 - 2008 Intel Corporation. All rights reserved.
103526Sxy150489  *
113526Sxy150489  * The contents of this file are subject to the terms of Version
123526Sxy150489  * 1.0 of the Common Development and Distribution License (the "License").
133526Sxy150489  *
143526Sxy150489  * You should have received a copy of the License with this software.
153526Sxy150489  * You can obtain a copy of the License at
163526Sxy150489  *	http://www.opensolaris.org/os/licensing.
173526Sxy150489  * See the License for the specific language governing permissions
183526Sxy150489  * and limitations under the License.
193526Sxy150489  */
203526Sxy150489 
213526Sxy150489 /*
225882Syy150190  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
233526Sxy150489  * Use is subject to license terms of the CDDLv1.
243526Sxy150489  */
253526Sxy150489 
263526Sxy150489 #pragma ident	"%Z%%M%	%I%	%E% SMI"
273526Sxy150489 
283526Sxy150489 /*
293526Sxy150489  * **********************************************************************
303526Sxy150489  *									*
313526Sxy150489  * Module Name:								*
323526Sxy150489  *   e1000g_tx.c							*
333526Sxy150489  *									*
343526Sxy150489  * Abstract:								*
354919Sxy150489  *   This file contains some routines that take care of Transmit,	*
364919Sxy150489  *   make the hardware to send the data pointed by the packet out	*
374919Sxy150489  *   on to the physical medium.						*
383526Sxy150489  *									*
393526Sxy150489  * **********************************************************************
403526Sxy150489  */
413526Sxy150489 
423526Sxy150489 #include "e1000g_sw.h"
433526Sxy150489 #include "e1000g_debug.h"
443526Sxy150489 
453526Sxy150489 static boolean_t e1000g_send(struct e1000g *, mblk_t *);
464919Sxy150489 static int e1000g_tx_copy(e1000g_tx_ring_t *,
47*6986Smx205022     p_tx_sw_packet_t, mblk_t *, boolean_t);
484919Sxy150489 static int e1000g_tx_bind(e1000g_tx_ring_t *,
494919Sxy150489     p_tx_sw_packet_t, mblk_t *);
50*6986Smx205022 static boolean_t e1000g_retreive_context(mblk_t *, context_data_t *, size_t);
51*6986Smx205022 static boolean_t e1000g_check_context(e1000g_tx_ring_t *, context_data_t *);
523526Sxy150489 static int e1000g_fill_tx_ring(e1000g_tx_ring_t *, LIST_DESCRIBER *,
53*6986Smx205022     context_data_t *);
54*6986Smx205022 static void e1000g_fill_context_descriptor(context_data_t *,
553526Sxy150489     struct e1000_context_desc *);
564919Sxy150489 static int e1000g_fill_tx_desc(e1000g_tx_ring_t *,
574919Sxy150489     p_tx_sw_packet_t, uint64_t, size_t);
583526Sxy150489 static uint32_t e1000g_fill_82544_desc(uint64_t Address, size_t Length,
594919Sxy150489     p_desc_array_t desc_array);
604919Sxy150489 static int e1000g_tx_workaround_PCIX_82544(p_tx_sw_packet_t, uint64_t, size_t);
614919Sxy150489 static int e1000g_tx_workaround_jumbo_82544(p_tx_sw_packet_t, uint64_t, size_t);
623526Sxy150489 static void e1000g_82547_timeout(void *);
633526Sxy150489 static void e1000g_82547_tx_move_tail(e1000g_tx_ring_t *);
643526Sxy150489 static void e1000g_82547_tx_move_tail_work(e1000g_tx_ring_t *);
653526Sxy150489 
664919Sxy150489 #ifndef E1000G_DEBUG
673526Sxy150489 #pragma inline(e1000g_tx_copy)
683526Sxy150489 #pragma inline(e1000g_tx_bind)
69*6986Smx205022 #pragma inline(e1000g_retreive_context)
70*6986Smx205022 #pragma inline(e1000g_check_context)
713526Sxy150489 #pragma inline(e1000g_fill_tx_ring)
723526Sxy150489 #pragma inline(e1000g_fill_context_descriptor)
733526Sxy150489 #pragma inline(e1000g_fill_tx_desc)
743526Sxy150489 #pragma inline(e1000g_fill_82544_desc)
753526Sxy150489 #pragma inline(e1000g_tx_workaround_PCIX_82544)
763526Sxy150489 #pragma inline(e1000g_tx_workaround_jumbo_82544)
774919Sxy150489 #pragma inline(e1000g_free_tx_swpkt)
783526Sxy150489 #endif
793526Sxy150489 
803526Sxy150489 /*
814919Sxy150489  * e1000g_free_tx_swpkt	- free up the tx sw packet
824919Sxy150489  *
834919Sxy150489  * Unbind the previously bound DMA handle for a given
844919Sxy150489  * transmit sw packet. And reset the sw packet data.
853526Sxy150489  */
863526Sxy150489 void
874919Sxy150489 e1000g_free_tx_swpkt(register p_tx_sw_packet_t packet)
883526Sxy150489 {
893526Sxy150489 	switch (packet->data_transfer_type) {
903526Sxy150489 	case USE_BCOPY:
913526Sxy150489 		packet->tx_buf->len = 0;
923526Sxy150489 		break;
933526Sxy150489 #ifdef __sparc
943526Sxy150489 	case USE_DVMA:
953526Sxy150489 		dvma_unload(packet->tx_dma_handle, 0, -1);
963526Sxy150489 		break;
973526Sxy150489 #endif
983526Sxy150489 	case USE_DMA:
993526Sxy150489 		ddi_dma_unbind_handle(packet->tx_dma_handle);
1003526Sxy150489 		break;
1013526Sxy150489 	default:
1023526Sxy150489 		break;
1033526Sxy150489 	}
1043526Sxy150489 
1053526Sxy150489 	/*
1063526Sxy150489 	 * The mblk has been stripped off the sw packet
1073526Sxy150489 	 * and will be freed in a triggered soft intr.
1083526Sxy150489 	 */
1093526Sxy150489 	ASSERT(packet->mp == NULL);
1103526Sxy150489 
1113526Sxy150489 	packet->data_transfer_type = USE_NONE;
1123526Sxy150489 	packet->num_mblk_frag = 0;
1133526Sxy150489 	packet->num_desc = 0;
1143526Sxy150489 }
1153526Sxy150489 
1163526Sxy150489 mblk_t *
1173526Sxy150489 e1000g_m_tx(void *arg, mblk_t *mp)
1183526Sxy150489 {
1193526Sxy150489 	struct e1000g *Adapter = (struct e1000g *)arg;
1203526Sxy150489 	mblk_t *next;
1213526Sxy150489 
1223526Sxy150489 	rw_enter(&Adapter->chip_lock, RW_READER);
1233526Sxy150489 
1245273Sgl147354 	if ((Adapter->chip_state != E1000G_START) ||
1255273Sgl147354 	    (Adapter->link_state != LINK_STATE_UP)) {
1263526Sxy150489 		freemsgchain(mp);
1273526Sxy150489 		mp = NULL;
1283526Sxy150489 	}
1293526Sxy150489 
1303526Sxy150489 	while (mp != NULL) {
1313526Sxy150489 		next = mp->b_next;
1323526Sxy150489 		mp->b_next = NULL;
1333526Sxy150489 
1343526Sxy150489 		if (!e1000g_send(Adapter, mp)) {
1353526Sxy150489 			mp->b_next = next;
1363526Sxy150489 			break;
1373526Sxy150489 		}
1383526Sxy150489 
1393526Sxy150489 		mp = next;
1403526Sxy150489 	}
1413526Sxy150489 
1423526Sxy150489 	rw_exit(&Adapter->chip_lock);
1433526Sxy150489 	return (mp);
1443526Sxy150489 }
1453526Sxy150489 
1463526Sxy150489 /*
1474919Sxy150489  * e1000g_send -  send packets onto the wire
1484919Sxy150489  *
1494919Sxy150489  * Called from e1000g_m_tx with an mblk ready to send. this
1504919Sxy150489  * routine sets up the transmit descriptors and sends data to
1514919Sxy150489  * the wire. It also pushes the just transmitted packet to
1524919Sxy150489  * the used tx sw packet list.
1533526Sxy150489  */
1543526Sxy150489 static boolean_t
1553526Sxy150489 e1000g_send(struct e1000g *Adapter, mblk_t *mp)
1563526Sxy150489 {
1574919Sxy150489 	struct e1000_hw *hw;
1584919Sxy150489 	p_tx_sw_packet_t packet;
1593526Sxy150489 	LIST_DESCRIBER pending_list;
1603526Sxy150489 	size_t len;
1613526Sxy150489 	size_t msg_size;
1623526Sxy150489 	uint32_t frag_count;
1633526Sxy150489 	int desc_count;
1643526Sxy150489 	uint32_t desc_total;
165*6986Smx205022 	boolean_t tx_undersize_flag;
1663526Sxy150489 	mblk_t *nmp;
1673526Sxy150489 	mblk_t *tmp;
1683526Sxy150489 	e1000g_tx_ring_t *tx_ring;
169*6986Smx205022 	context_data_t cur_context;
1703526Sxy150489 
1714919Sxy150489 	hw = &Adapter->shared;
1724919Sxy150489 	tx_ring = Adapter->tx_ring;
1734919Sxy150489 
1743526Sxy150489 	/* Get the total size and frags number of the message */
175*6986Smx205022 	tx_undersize_flag = B_FALSE;
1763526Sxy150489 	frag_count = 0;
1773526Sxy150489 	msg_size = 0;
1783526Sxy150489 	for (nmp = mp; nmp; nmp = nmp->b_cont) {
1793526Sxy150489 		frag_count++;
1803526Sxy150489 		msg_size += MBLKL(nmp);
1813526Sxy150489 	}
1823526Sxy150489 
183*6986Smx205022 	/* retreive and compute information for context descriptor */
184*6986Smx205022 	if (!e1000g_retreive_context(mp, &cur_context, msg_size)) {
185*6986Smx205022 		freemsg(mp);
186*6986Smx205022 		return (B_TRUE);
187*6986Smx205022 	}
188*6986Smx205022 
189*6986Smx205022 	/*
190*6986Smx205022 	 * Make sure the packet is less than the allowed size
191*6986Smx205022 	 */
192*6986Smx205022 	if (!cur_context.lso_flag &&
193*6986Smx205022 	    (msg_size > Adapter->max_frame_size - ETHERFCSL)) {
1943526Sxy150489 		/*
1953526Sxy150489 		 * For the over size packet, we'll just drop it.
1963526Sxy150489 		 * So we return B_TRUE here.
1973526Sxy150489 		 */
1984919Sxy150489 		E1000G_DEBUGLOG_1(Adapter, E1000G_WARN_LEVEL,
1993526Sxy150489 		    "Tx packet out of bound. length = %d \n", msg_size);
2004919Sxy150489 		E1000G_STAT(tx_ring->stat_over_size);
2013526Sxy150489 		freemsg(mp);
2023526Sxy150489 		return (B_TRUE);
2033526Sxy150489 	}
2043526Sxy150489 
2053526Sxy150489 	/*
2063526Sxy150489 	 * Check and reclaim tx descriptors.
2073526Sxy150489 	 * This low water mark check should be done all the time as
2083526Sxy150489 	 * Transmit interrupt delay can produce Transmit interrupts little
2093526Sxy150489 	 * late and that may cause few problems related to reaping Tx
2103526Sxy150489 	 * Descriptors... As you may run short of them before getting any
2113526Sxy150489 	 * transmit interrupt...
2123526Sxy150489 	 */
2135882Syy150190 	if (tx_ring->resched_needed ||
2145882Syy150190 	    (tx_ring->tbd_avail < Adapter->tx_recycle_thresh)) {
2153526Sxy150489 		(void) e1000g_recycle(tx_ring);
2165882Syy150190 		E1000G_DEBUG_STAT(tx_ring->stat_recycle);
2173526Sxy150489 
2185882Syy150190 		if (tx_ring->tbd_avail < DEFAULT_TX_NO_RESOURCE) {
2195882Syy150190 			E1000G_DEBUG_STAT(tx_ring->stat_lack_desc);
2205882Syy150190 			goto tx_no_resource;
2215882Syy150190 		}
2223526Sxy150489 	}
2233526Sxy150489 
2243526Sxy150489 	/*
2253526Sxy150489 	 * If the message size is less than the minimum ethernet packet size,
2263526Sxy150489 	 * we'll use bcopy to send it, and padd it to 60 bytes later.
2273526Sxy150489 	 */
2286394Scc210113 	if (msg_size < ETHERMIN) {
2294919Sxy150489 		E1000G_DEBUG_STAT(tx_ring->stat_under_size);
230*6986Smx205022 		tx_undersize_flag = B_TRUE;
2313526Sxy150489 	}
2323526Sxy150489 
2333526Sxy150489 	/* Initialize variables */
2343526Sxy150489 	desc_count = 1;	/* The initial value should be greater than 0 */
2353526Sxy150489 	desc_total = 0;
2363526Sxy150489 	QUEUE_INIT_LIST(&pending_list);
2373526Sxy150489 
2383526Sxy150489 	/* Process each mblk fragment and fill tx descriptors */
2393526Sxy150489 	packet = NULL;
2403526Sxy150489 	nmp = mp;
2413526Sxy150489 	while (nmp) {
2423526Sxy150489 		tmp = nmp->b_cont;
2433526Sxy150489 
2443526Sxy150489 		len = MBLKL(nmp);
2453526Sxy150489 		/* Check zero length mblks */
2463526Sxy150489 		if (len == 0) {
2474919Sxy150489 			E1000G_DEBUG_STAT(tx_ring->stat_empty_frags);
2483526Sxy150489 			/*
2493526Sxy150489 			 * If there're no packet buffers have been used,
2503526Sxy150489 			 * or we just completed processing a buffer, then
2513526Sxy150489 			 * skip the empty mblk fragment.
2523526Sxy150489 			 * Otherwise, there's still a pending buffer that
2533526Sxy150489 			 * needs to be processed (tx_copy).
2543526Sxy150489 			 */
2553526Sxy150489 			if (desc_count > 0) {
2563526Sxy150489 				nmp = tmp;
2573526Sxy150489 				continue;
2583526Sxy150489 			}
2593526Sxy150489 		}
2603526Sxy150489 
2613526Sxy150489 		/*
2623526Sxy150489 		 * Get a new TxSwPacket to process mblk buffers.
2633526Sxy150489 		 */
2643526Sxy150489 		if (desc_count > 0) {
2653526Sxy150489 			mutex_enter(&tx_ring->freelist_lock);
2664919Sxy150489 			packet = (p_tx_sw_packet_t)
2673526Sxy150489 			    QUEUE_POP_HEAD(&tx_ring->free_list);
2683526Sxy150489 			mutex_exit(&tx_ring->freelist_lock);
2693526Sxy150489 
2703526Sxy150489 			if (packet == NULL) {
2714919Sxy150489 				E1000G_DEBUGLOG_0(Adapter, E1000G_INFO_LEVEL,
2723526Sxy150489 				    "No Tx SwPacket available\n");
2734919Sxy150489 				E1000G_STAT(tx_ring->stat_no_swpkt);
2743526Sxy150489 				goto tx_send_failed;
2753526Sxy150489 			}
2763526Sxy150489 			QUEUE_PUSH_TAIL(&pending_list, &packet->Link);
2773526Sxy150489 		}
2783526Sxy150489 
2793526Sxy150489 		ASSERT(packet);
2803526Sxy150489 		/*
2813526Sxy150489 		 * If the size of the fragment is less than the tx_bcopy_thresh
2823526Sxy150489 		 * we'll use bcopy; Otherwise, we'll use DMA binding.
2833526Sxy150489 		 */
284*6986Smx205022 		if ((len <= Adapter->tx_bcopy_thresh) || tx_undersize_flag) {
2853526Sxy150489 			desc_count =
286*6986Smx205022 			    e1000g_tx_copy(tx_ring, packet, nmp,
287*6986Smx205022 			    tx_undersize_flag);
2884919Sxy150489 			E1000G_DEBUG_STAT(tx_ring->stat_copy);
2893526Sxy150489 		} else {
2903526Sxy150489 			desc_count =
2914919Sxy150489 			    e1000g_tx_bind(tx_ring, packet, nmp);
2924919Sxy150489 			E1000G_DEBUG_STAT(tx_ring->stat_bind);
2933526Sxy150489 		}
2943526Sxy150489 
2953526Sxy150489 		if (desc_count > 0)
2963526Sxy150489 			desc_total += desc_count;
2974919Sxy150489 		else if (desc_count < 0)
2984919Sxy150489 			goto tx_send_failed;
2993526Sxy150489 
3003526Sxy150489 		nmp = tmp;
3013526Sxy150489 	}
3023526Sxy150489 
3033526Sxy150489 	/* Assign the message to the last sw packet */
3043526Sxy150489 	ASSERT(packet);
3053526Sxy150489 	ASSERT(packet->mp == NULL);
3063526Sxy150489 	packet->mp = mp;
3073526Sxy150489 
3083526Sxy150489 	/* Try to recycle the tx descriptors again */
3094919Sxy150489 	if (tx_ring->tbd_avail < (desc_total + 2)) {
3104919Sxy150489 		E1000G_DEBUG_STAT(tx_ring->stat_recycle_retry);
3113526Sxy150489 		(void) e1000g_recycle(tx_ring);
3123526Sxy150489 	}
3133526Sxy150489 
3143526Sxy150489 	mutex_enter(&tx_ring->tx_lock);
3153526Sxy150489 
3163526Sxy150489 	/*
3173526Sxy150489 	 * If the number of available tx descriptors is not enough for transmit
3183526Sxy150489 	 * (one redundant descriptor and one hw checksum context descriptor are
3193526Sxy150489 	 * included), then return failure.
3203526Sxy150489 	 */
3214919Sxy150489 	if (tx_ring->tbd_avail < (desc_total + 2)) {
3224919Sxy150489 		E1000G_DEBUGLOG_0(Adapter, E1000G_INFO_LEVEL,
3233526Sxy150489 		    "No Enough Tx descriptors\n");
3244919Sxy150489 		E1000G_STAT(tx_ring->stat_no_desc);
3253526Sxy150489 		mutex_exit(&tx_ring->tx_lock);
3263526Sxy150489 		goto tx_send_failed;
3273526Sxy150489 	}
3283526Sxy150489 
329*6986Smx205022 	desc_count = e1000g_fill_tx_ring(tx_ring, &pending_list, &cur_context);
3303526Sxy150489 
3313526Sxy150489 	mutex_exit(&tx_ring->tx_lock);
3323526Sxy150489 
3333526Sxy150489 	ASSERT(desc_count > 0);
3343526Sxy150489 
3353526Sxy150489 	/* Send successful */
3363526Sxy150489 	return (B_TRUE);
3373526Sxy150489 
3383526Sxy150489 tx_send_failed:
3395882Syy150190 	/*
3405882Syy150190 	 * Enable Transmit interrupts, so that the interrupt routine can
3415882Syy150190 	 * call mac_tx_update() when transmit descriptors become available.
3425882Syy150190 	 */
3435882Syy150190 	tx_ring->resched_needed = B_TRUE;
3445882Syy150190 	if (!Adapter->tx_intr_enable)
3455882Syy150190 		e1000g_mask_tx_interrupt(Adapter);
3465882Syy150190 
3473526Sxy150489 	/* Free pending TxSwPackets */
3484919Sxy150489 	packet = (p_tx_sw_packet_t)QUEUE_GET_HEAD(&pending_list);
3493526Sxy150489 	while (packet) {
3503526Sxy150489 		packet->mp = NULL;
3514919Sxy150489 		e1000g_free_tx_swpkt(packet);
3524919Sxy150489 		packet = (p_tx_sw_packet_t)
3533526Sxy150489 		    QUEUE_GET_NEXT(&pending_list, &packet->Link);
3543526Sxy150489 	}
3553526Sxy150489 
3563526Sxy150489 	/* Return pending TxSwPackets to the "Free" list */
3573526Sxy150489 	mutex_enter(&tx_ring->freelist_lock);
3583526Sxy150489 	QUEUE_APPEND(&tx_ring->free_list, &pending_list);
3593526Sxy150489 	mutex_exit(&tx_ring->freelist_lock);
3603526Sxy150489 
3614919Sxy150489 	E1000G_STAT(tx_ring->stat_send_fail);
3623526Sxy150489 
3635882Syy150190 	/* Message will be scheduled for re-transmit */
3645882Syy150190 	return (B_FALSE);
3653526Sxy150489 
3663526Sxy150489 tx_no_resource:
3673526Sxy150489 	/*
3683526Sxy150489 	 * Enable Transmit interrupts, so that the interrupt routine can
3693526Sxy150489 	 * call mac_tx_update() when transmit descriptors become available.
3703526Sxy150489 	 */
3714919Sxy150489 	tx_ring->resched_needed = B_TRUE;
3723526Sxy150489 	if (!Adapter->tx_intr_enable)
3734919Sxy150489 		e1000g_mask_tx_interrupt(Adapter);
3743526Sxy150489 
3753526Sxy150489 	/* Message will be scheduled for re-transmit */
3763526Sxy150489 	return (B_FALSE);
3773526Sxy150489 }
3783526Sxy150489 
3794061Sxy150489 static boolean_t
380*6986Smx205022 e1000g_retreive_context(mblk_t *mp, context_data_t *cur_context,
381*6986Smx205022     size_t msg_size)
3824061Sxy150489 {
383*6986Smx205022 	uintptr_t ip_start;
384*6986Smx205022 	uintptr_t tcp_start;
385*6986Smx205022 	mblk_t *nmp;
386*6986Smx205022 
387*6986Smx205022 	bzero(cur_context, sizeof (context_data_t));
3884061Sxy150489 
389*6986Smx205022 	/* retrieve checksum info */
390*6986Smx205022 	hcksum_retrieve(mp, NULL, NULL, &cur_context->cksum_start,
391*6986Smx205022 	    &cur_context->cksum_stuff, NULL, NULL, &cur_context->cksum_flags);
392*6986Smx205022 	/* retreive ethernet header size */
393*6986Smx205022 	if (((struct ether_vlan_header *)mp->b_rptr)->ether_tpid ==
394*6986Smx205022 	    htons(ETHERTYPE_VLAN))
395*6986Smx205022 		cur_context->ether_header_size =
396*6986Smx205022 		    sizeof (struct ether_vlan_header);
397*6986Smx205022 	else
398*6986Smx205022 		cur_context->ether_header_size =
399*6986Smx205022 		    sizeof (struct ether_header);
4004061Sxy150489 
401*6986Smx205022 	if (cur_context->cksum_flags & HW_LSO) {
402*6986Smx205022 		if ((cur_context->mss = DB_LSOMSS(mp)) != 0) {
403*6986Smx205022 			/* free the invaid packet */
404*6986Smx205022 			if (!((cur_context->cksum_flags & HCK_PARTIALCKSUM) &&
405*6986Smx205022 			    (cur_context->cksum_flags & HCK_IPV4_HDRCKSUM))) {
406*6986Smx205022 				return (B_FALSE);
407*6986Smx205022 			}
408*6986Smx205022 			cur_context->lso_flag = B_TRUE;
409*6986Smx205022 			/*
410*6986Smx205022 			 * Some fields are cleared for the hardware to fill
411*6986Smx205022 			 * in. We don't assume Ethernet header, IP header and
412*6986Smx205022 			 * TCP header are always in the same mblk fragment,
413*6986Smx205022 			 * while we assume each header is always within one
414*6986Smx205022 			 * mblk fragment and Ethernet header is always in the
415*6986Smx205022 			 * first mblk fragment.
416*6986Smx205022 			 */
417*6986Smx205022 			nmp = mp;
418*6986Smx205022 			ip_start = (uintptr_t)(nmp->b_rptr)
419*6986Smx205022 			    + cur_context->ether_header_size;
420*6986Smx205022 			if (ip_start >= (uintptr_t)(nmp->b_wptr)) {
421*6986Smx205022 				ip_start = (uintptr_t)nmp->b_cont->b_rptr
422*6986Smx205022 				    + (ip_start - (uintptr_t)(nmp->b_wptr));
423*6986Smx205022 				nmp = nmp->b_cont;
424*6986Smx205022 			}
425*6986Smx205022 			tcp_start = ip_start +
426*6986Smx205022 			    IPH_HDR_LENGTH((ipha_t *)ip_start);
427*6986Smx205022 			if (tcp_start >= (uintptr_t)(nmp->b_wptr)) {
428*6986Smx205022 				tcp_start = (uintptr_t)nmp->b_cont->b_rptr
429*6986Smx205022 				    + (tcp_start - (uintptr_t)(nmp->b_wptr));
430*6986Smx205022 				nmp = nmp->b_cont;
431*6986Smx205022 			}
432*6986Smx205022 			cur_context->hdr_len = cur_context->ether_header_size
433*6986Smx205022 			    + IPH_HDR_LENGTH((ipha_t *)ip_start)
434*6986Smx205022 			    + TCP_HDR_LENGTH((tcph_t *)tcp_start);
435*6986Smx205022 			((ipha_t *)ip_start)->ipha_length = 0;
436*6986Smx205022 			((ipha_t *)ip_start)->ipha_hdr_checksum = 0;
437*6986Smx205022 			/* calculate the TCP packet payload length */
438*6986Smx205022 			cur_context->pay_len = msg_size - cur_context->hdr_len;
439*6986Smx205022 		}
440*6986Smx205022 	}
441*6986Smx205022 	return (B_TRUE);
442*6986Smx205022 }
4434061Sxy150489 
444*6986Smx205022 static boolean_t
445*6986Smx205022 e1000g_check_context(e1000g_tx_ring_t *tx_ring, context_data_t *cur_context)
446*6986Smx205022 {
447*6986Smx205022 	boolean_t context_reload;
448*6986Smx205022 	context_data_t *pre_context;
449*6986Smx205022 	struct e1000g *Adapter;
450*6986Smx205022 
451*6986Smx205022 	context_reload = B_FALSE;
452*6986Smx205022 	pre_context = &tx_ring->pre_context;
453*6986Smx205022 	Adapter = tx_ring->adapter;
454*6986Smx205022 
455*6986Smx205022 	/*
456*6986Smx205022 	 * The following code determine if the context descriptor is
457*6986Smx205022 	 * needed to be reloaded. The sequence of the conditions is
458*6986Smx205022 	 * made by their possibilities of changing.
459*6986Smx205022 	 */
460*6986Smx205022 	/*
461*6986Smx205022 	 * workaround for 82546EB, context descriptor must be reloaded
462*6986Smx205022 	 * per LSO/hw_cksum packet if LSO is enabled.
463*6986Smx205022 	 */
464*6986Smx205022 	if (Adapter->lso_premature_issue &&
465*6986Smx205022 	    Adapter->lso_enable &&
466*6986Smx205022 	    (cur_context->cksum_flags != 0)) {
467*6986Smx205022 
468*6986Smx205022 		context_reload = B_TRUE;
469*6986Smx205022 	} else if (cur_context->lso_flag) {
470*6986Smx205022 		if ((cur_context->cksum_flags != pre_context->cksum_flags) ||
471*6986Smx205022 		    (cur_context->pay_len != pre_context->pay_len) ||
472*6986Smx205022 		    (cur_context->mss != pre_context->mss) ||
473*6986Smx205022 		    (cur_context->hdr_len != pre_context->hdr_len) ||
474*6986Smx205022 		    (cur_context->cksum_stuff != pre_context->cksum_stuff) ||
475*6986Smx205022 		    (cur_context->cksum_start != pre_context->cksum_start) ||
476*6986Smx205022 		    (cur_context->ether_header_size !=
477*6986Smx205022 		    pre_context->ether_header_size)) {
478*6986Smx205022 
479*6986Smx205022 			context_reload = B_TRUE;
480*6986Smx205022 		}
481*6986Smx205022 	} else if (cur_context->cksum_flags != 0) {
482*6986Smx205022 		if ((cur_context->cksum_flags != pre_context->cksum_flags) ||
483*6986Smx205022 		    (cur_context->cksum_stuff != pre_context->cksum_stuff) ||
484*6986Smx205022 		    (cur_context->cksum_start != pre_context->cksum_start) ||
485*6986Smx205022 		    (cur_context->ether_header_size !=
486*6986Smx205022 		    pre_context->ether_header_size)) {
487*6986Smx205022 
488*6986Smx205022 			context_reload = B_TRUE;
4894061Sxy150489 		}
4904061Sxy150489 	}
4914061Sxy150489 
492*6986Smx205022 	return (context_reload);
4934061Sxy150489 }
4944061Sxy150489 
4953526Sxy150489 static int
4963526Sxy150489 e1000g_fill_tx_ring(e1000g_tx_ring_t *tx_ring, LIST_DESCRIBER *pending_list,
497*6986Smx205022     context_data_t *cur_context)
4983526Sxy150489 {
4993526Sxy150489 	struct e1000g *Adapter;
5004919Sxy150489 	struct e1000_hw *hw;
5014919Sxy150489 	p_tx_sw_packet_t first_packet;
5024919Sxy150489 	p_tx_sw_packet_t packet;
503*6986Smx205022 	p_tx_sw_packet_t previous_packet;
504*6986Smx205022 	boolean_t context_reload;
5053526Sxy150489 	struct e1000_tx_desc *first_data_desc;
5063526Sxy150489 	struct e1000_tx_desc *next_desc;
5073526Sxy150489 	struct e1000_tx_desc *descriptor;
5083526Sxy150489 	int desc_count;
509*6986Smx205022 	boolean_t buff_overrun_flag;
5103526Sxy150489 	int i;
5113526Sxy150489 
5123526Sxy150489 	Adapter = tx_ring->adapter;
5134919Sxy150489 	hw = &Adapter->shared;
5143526Sxy150489 
5153526Sxy150489 	desc_count = 0;
5164061Sxy150489 	first_packet = NULL;
5173526Sxy150489 	first_data_desc = NULL;
5183526Sxy150489 	descriptor = NULL;
519*6986Smx205022 	first_packet = NULL;
520*6986Smx205022 	packet = NULL;
521*6986Smx205022 	buff_overrun_flag = B_FALSE;
5223526Sxy150489 
5233526Sxy150489 	next_desc = tx_ring->tbd_next;
5243526Sxy150489 
525*6986Smx205022 	/* Context descriptor reload check */
526*6986Smx205022 	context_reload = e1000g_check_context(tx_ring, cur_context);
5274061Sxy150489 
528*6986Smx205022 	if (context_reload) {
5294919Sxy150489 		first_packet = (p_tx_sw_packet_t)QUEUE_GET_HEAD(pending_list);
5304061Sxy150489 
5313526Sxy150489 		descriptor = next_desc;
5323526Sxy150489 
533*6986Smx205022 		e1000g_fill_context_descriptor(cur_context,
5344061Sxy150489 		    (struct e1000_context_desc *)descriptor);
5353526Sxy150489 
5363526Sxy150489 		/* Check the wrap-around case */
5373526Sxy150489 		if (descriptor == tx_ring->tbd_last)
5383526Sxy150489 			next_desc = tx_ring->tbd_first;
5393526Sxy150489 		else
5403526Sxy150489 			next_desc++;
5413526Sxy150489 
5423526Sxy150489 		desc_count++;
5433526Sxy150489 	}
5443526Sxy150489 
5453526Sxy150489 	first_data_desc = next_desc;
5463526Sxy150489 
5474919Sxy150489 	packet = (p_tx_sw_packet_t)QUEUE_GET_HEAD(pending_list);
5483526Sxy150489 	while (packet) {
5493526Sxy150489 		ASSERT(packet->num_desc);
5503526Sxy150489 
5513526Sxy150489 		for (i = 0; i < packet->num_desc; i++) {
5524919Sxy150489 			ASSERT(tx_ring->tbd_avail > 0);
5533526Sxy150489 
5543526Sxy150489 			descriptor = next_desc;
5553526Sxy150489 			descriptor->buffer_addr =
5564919Sxy150489 			    packet->desc[i].address;
5573526Sxy150489 			descriptor->lower.data =
5584919Sxy150489 			    packet->desc[i].length;
5593526Sxy150489 
5603526Sxy150489 			/* Zero out status */
5613526Sxy150489 			descriptor->upper.data = 0;
5623526Sxy150489 
5633526Sxy150489 			descriptor->lower.data |=
5643526Sxy150489 			    E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
5653526Sxy150489 			/* must set RS on every outgoing descriptor */
5663526Sxy150489 			descriptor->lower.data |=
5673526Sxy150489 			    E1000_TXD_CMD_RS;
5683526Sxy150489 
569*6986Smx205022 			if (cur_context->lso_flag)
570*6986Smx205022 				descriptor->lower.data |= E1000_TXD_CMD_TSE;
571*6986Smx205022 
5723526Sxy150489 			/* Check the wrap-around case */
5733526Sxy150489 			if (descriptor == tx_ring->tbd_last)
5743526Sxy150489 				next_desc = tx_ring->tbd_first;
5753526Sxy150489 			else
5763526Sxy150489 				next_desc++;
5773526Sxy150489 
5783526Sxy150489 			desc_count++;
579*6986Smx205022 
580*6986Smx205022 			/*
581*6986Smx205022 			 * workaround for 82546EB errata 33, hang in PCI-X
582*6986Smx205022 			 * systems due to 2k Buffer Overrun during Transmit
583*6986Smx205022 			 * Operation. The workaround applies to all the Intel
584*6986Smx205022 			 * PCI-X chips.
585*6986Smx205022 			 */
586*6986Smx205022 			if (hw->bus.type == e1000_bus_type_pcix &&
587*6986Smx205022 			    descriptor == first_data_desc &&
588*6986Smx205022 			    ((descriptor->lower.data & E1000G_TBD_LENGTH_MASK)
589*6986Smx205022 			    > E1000_TX_BUFFER_OEVRRUN_THRESHOLD)) {
590*6986Smx205022 				/* modified the first descriptor */
591*6986Smx205022 				descriptor->lower.data &=
592*6986Smx205022 				    ~E1000G_TBD_LENGTH_MASK;
593*6986Smx205022 				descriptor->lower.flags.length =
594*6986Smx205022 				    E1000_TX_BUFFER_OEVRRUN_THRESHOLD;
595*6986Smx205022 
596*6986Smx205022 				/* insert a new descriptor */
597*6986Smx205022 				ASSERT(tx_ring->tbd_avail > 0);
598*6986Smx205022 				next_desc->buffer_addr =
599*6986Smx205022 				    packet->desc[0].address +
600*6986Smx205022 				    E1000_TX_BUFFER_OEVRRUN_THRESHOLD;
601*6986Smx205022 				next_desc->lower.data =
602*6986Smx205022 				    packet->desc[0].length -
603*6986Smx205022 				    E1000_TX_BUFFER_OEVRRUN_THRESHOLD;
604*6986Smx205022 
605*6986Smx205022 				/* Zero out status */
606*6986Smx205022 				next_desc->upper.data = 0;
607*6986Smx205022 
608*6986Smx205022 				next_desc->lower.data |=
609*6986Smx205022 				    E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
610*6986Smx205022 				/* must set RS on every outgoing descriptor */
611*6986Smx205022 				next_desc->lower.data |=
612*6986Smx205022 				    E1000_TXD_CMD_RS;
613*6986Smx205022 
614*6986Smx205022 				if (cur_context->lso_flag)
615*6986Smx205022 					next_desc->lower.data |=
616*6986Smx205022 					    E1000_TXD_CMD_TSE;
617*6986Smx205022 
618*6986Smx205022 				descriptor = next_desc;
619*6986Smx205022 
620*6986Smx205022 				/* Check the wrap-around case */
621*6986Smx205022 				if (next_desc == tx_ring->tbd_last)
622*6986Smx205022 					next_desc = tx_ring->tbd_first;
623*6986Smx205022 				else
624*6986Smx205022 					next_desc++;
625*6986Smx205022 
626*6986Smx205022 				desc_count++;
627*6986Smx205022 				buff_overrun_flag = B_TRUE;
628*6986Smx205022 			}
629*6986Smx205022 		}
630*6986Smx205022 
631*6986Smx205022 		if (buff_overrun_flag) {
632*6986Smx205022 			packet->num_desc++;
633*6986Smx205022 			buff_overrun_flag = B_FALSE;
6343526Sxy150489 		}
6353526Sxy150489 
6363526Sxy150489 		if (first_packet != NULL) {
6373526Sxy150489 			/*
6383526Sxy150489 			 * Count the checksum context descriptor for
6393526Sxy150489 			 * the first SwPacket.
6403526Sxy150489 			 */
6413526Sxy150489 			first_packet->num_desc++;
6423526Sxy150489 			first_packet = NULL;
6433526Sxy150489 		}
6443526Sxy150489 
645*6986Smx205022 		previous_packet = packet;
6464919Sxy150489 		packet = (p_tx_sw_packet_t)
6473526Sxy150489 		    QUEUE_GET_NEXT(pending_list, &packet->Link);
6483526Sxy150489 	}
6493526Sxy150489 
650*6986Smx205022 	/*
651*6986Smx205022 	 * workaround for 82546EB errata 21, LSO Premature Descriptor Write Back
652*6986Smx205022 	 */
653*6986Smx205022 	if (Adapter->lso_premature_issue && cur_context->lso_flag &&
654*6986Smx205022 	    ((descriptor->lower.data & E1000G_TBD_LENGTH_MASK) > 8)) {
655*6986Smx205022 		/* modified the previous descriptor */
656*6986Smx205022 		descriptor->lower.data -= 4;
657*6986Smx205022 
658*6986Smx205022 		/* insert a new descriptor */
659*6986Smx205022 		ASSERT(tx_ring->tbd_avail > 0);
660*6986Smx205022 		/* the lower 20 bits of lower.data is the length field */
661*6986Smx205022 		next_desc->buffer_addr =
662*6986Smx205022 		    descriptor->buffer_addr +
663*6986Smx205022 		    (descriptor->lower.data & E1000G_TBD_LENGTH_MASK);
664*6986Smx205022 		next_desc->lower.data = 4;
665*6986Smx205022 
666*6986Smx205022 		/* Zero out status */
667*6986Smx205022 		next_desc->upper.data = 0;
668*6986Smx205022 		/* It must be part of a LSO packet */
669*6986Smx205022 		next_desc->lower.data |=
670*6986Smx205022 		    E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D |
671*6986Smx205022 		    E1000_TXD_CMD_RS | E1000_TXD_CMD_TSE;
672*6986Smx205022 
673*6986Smx205022 		descriptor = next_desc;
674*6986Smx205022 
675*6986Smx205022 		/* Check the wrap-around case */
676*6986Smx205022 		if (descriptor == tx_ring->tbd_last)
677*6986Smx205022 			next_desc = tx_ring->tbd_first;
678*6986Smx205022 		else
679*6986Smx205022 			next_desc++;
680*6986Smx205022 
681*6986Smx205022 		desc_count++;
682*6986Smx205022 		/* update the number of descriptors */
683*6986Smx205022 		previous_packet->num_desc++;
684*6986Smx205022 	}
685*6986Smx205022 
6863526Sxy150489 	ASSERT(descriptor);
6873526Sxy150489 
688*6986Smx205022 	if (cur_context->cksum_flags) {
689*6986Smx205022 		if (cur_context->cksum_flags & HCK_IPV4_HDRCKSUM)
6903526Sxy150489 			((struct e1000_data_desc *)first_data_desc)->
6914608Syy150190 			    upper.fields.popts |= E1000_TXD_POPTS_IXSM;
692*6986Smx205022 		if (cur_context->cksum_flags & HCK_PARTIALCKSUM)
6933526Sxy150489 			((struct e1000_data_desc *)first_data_desc)->
6944608Syy150190 			    upper.fields.popts |= E1000_TXD_POPTS_TXSM;
6953526Sxy150489 	}
6963526Sxy150489 
6973526Sxy150489 	/*
6983526Sxy150489 	 * Last Descriptor of Packet needs End Of Packet (EOP), Report
699*6986Smx205022 	 * Status (RS) set.
7003526Sxy150489 	 */
7014919Sxy150489 	if (Adapter->tx_intr_delay) {
7023526Sxy150489 		descriptor->lower.data |= E1000_TXD_CMD_IDE |
703*6986Smx205022 		    E1000_TXD_CMD_EOP;
7043526Sxy150489 	} else {
705*6986Smx205022 		descriptor->lower.data |= E1000_TXD_CMD_EOP;
706*6986Smx205022 	}
707*6986Smx205022 
708*6986Smx205022 	/* Set append Ethernet CRC (IFCS) bits */
709*6986Smx205022 	if (cur_context->lso_flag) {
710*6986Smx205022 		first_data_desc->lower.data |= E1000_TXD_CMD_IFCS;
711*6986Smx205022 	} else {
712*6986Smx205022 		descriptor->lower.data |= E1000_TXD_CMD_IFCS;
7133526Sxy150489 	}
7143526Sxy150489 
7153526Sxy150489 	/*
7163526Sxy150489 	 * Sync the Tx descriptors DMA buffer
7173526Sxy150489 	 */
7184919Sxy150489 	(void) ddi_dma_sync(tx_ring->tbd_dma_handle,
7194919Sxy150489 	    0, 0, DDI_DMA_SYNC_FORDEV);
7203526Sxy150489 
7213526Sxy150489 	tx_ring->tbd_next = next_desc;
7223526Sxy150489 
7233526Sxy150489 	/*
7243526Sxy150489 	 * Advance the Transmit Descriptor Tail (Tdt), this tells the
7253526Sxy150489 	 * FX1000 that this frame is available to transmit.
7263526Sxy150489 	 */
7274919Sxy150489 	if (hw->mac.type == e1000_82547)
7283526Sxy150489 		e1000g_82547_tx_move_tail(tx_ring);
7293526Sxy150489 	else
7306735Scc210113 		E1000_WRITE_REG(hw, E1000_TDT(0),
7313526Sxy150489 		    (uint32_t)(next_desc - tx_ring->tbd_first));
7323526Sxy150489 
7335273Sgl147354 	if (e1000g_check_acc_handle(Adapter->osdep.reg_handle) != DDI_FM_OK) {
7345273Sgl147354 		ddi_fm_service_impact(Adapter->dip, DDI_SERVICE_DEGRADED);
7355273Sgl147354 		Adapter->chip_state = E1000G_ERROR;
7365273Sgl147354 	}
7375273Sgl147354 
7383526Sxy150489 	/* Put the pending SwPackets to the "Used" list */
7393526Sxy150489 	mutex_enter(&tx_ring->usedlist_lock);
7403526Sxy150489 	QUEUE_APPEND(&tx_ring->used_list, pending_list);
7414919Sxy150489 	tx_ring->tbd_avail -= desc_count;
7423526Sxy150489 	mutex_exit(&tx_ring->usedlist_lock);
7433526Sxy150489 
744*6986Smx205022 	/* update LSO related data */
745*6986Smx205022 	if (context_reload)
746*6986Smx205022 		tx_ring->pre_context = *cur_context;
7474061Sxy150489 
7483526Sxy150489 	return (desc_count);
7493526Sxy150489 }
7503526Sxy150489 
7513526Sxy150489 
7523526Sxy150489 /*
7534919Sxy150489  * e1000g_tx_setup - setup tx data structures
7544919Sxy150489  *
7554919Sxy150489  * This routine initializes all of the transmit related
7564919Sxy150489  * structures. This includes the Transmit descriptors,
7574919Sxy150489  * and the tx_sw_packet structures.
7583526Sxy150489  */
7593526Sxy150489 void
7604919Sxy150489 e1000g_tx_setup(struct e1000g *Adapter)
7613526Sxy150489 {
7623526Sxy150489 	struct e1000_hw *hw;
7634919Sxy150489 	p_tx_sw_packet_t packet;
7643526Sxy150489 	UINT i;
7653526Sxy150489 	uint32_t buf_high;
7663526Sxy150489 	uint32_t buf_low;
7673526Sxy150489 	uint32_t reg_tipg;
7683526Sxy150489 	uint32_t reg_tctl;
7693526Sxy150489 	uint32_t reg_tarc;
7703526Sxy150489 	uint16_t speed, duplex;
7713526Sxy150489 	int size;
7723526Sxy150489 	e1000g_tx_ring_t *tx_ring;
7733526Sxy150489 
7744919Sxy150489 	hw = &Adapter->shared;
7753526Sxy150489 	tx_ring = Adapter->tx_ring;
7763526Sxy150489 
7773526Sxy150489 	/* init the lists */
7783526Sxy150489 	/*
7793526Sxy150489 	 * Here we don't need to protect the lists using the
7804919Sxy150489 	 * usedlist_lock and freelist_lock, for they have
7813526Sxy150489 	 * been protected by the chip_lock.
7823526Sxy150489 	 */
7833526Sxy150489 	QUEUE_INIT_LIST(&tx_ring->used_list);
7843526Sxy150489 	QUEUE_INIT_LIST(&tx_ring->free_list);
7853526Sxy150489 
7863526Sxy150489 	/* Go through and set up each SW_Packet */
7873526Sxy150489 	packet = tx_ring->packet_area;
7884919Sxy150489 	for (i = 0; i < Adapter->tx_freelist_num; i++, packet++) {
7894919Sxy150489 		/* Initialize this tx_sw_apcket area */
7904919Sxy150489 		e1000g_free_tx_swpkt(packet);
7914919Sxy150489 		/* Add this tx_sw_packet to the free list */
7923526Sxy150489 		QUEUE_PUSH_TAIL(&tx_ring->free_list,
7933526Sxy150489 		    &packet->Link);
7943526Sxy150489 	}
7953526Sxy150489 
7963526Sxy150489 	/* Setup TX descriptor pointers */
7973526Sxy150489 	tx_ring->tbd_next = tx_ring->tbd_first;
7983526Sxy150489 	tx_ring->tbd_oldest = tx_ring->tbd_first;
7993526Sxy150489 
8003526Sxy150489 	/*
8013526Sxy150489 	 * Setup Hardware TX Registers
8023526Sxy150489 	 */
8033526Sxy150489 	/* Setup the Transmit Control Register (TCTL). */
8043526Sxy150489 	reg_tctl = E1000_TCTL_PSP | E1000_TCTL_EN |
8053526Sxy150489 	    (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT) |
8064919Sxy150489 	    (E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT) |
8074919Sxy150489 	    E1000_TCTL_RTLC;
8083526Sxy150489 
8093526Sxy150489 	/* Enable the MULR bit */
8104919Sxy150489 	if (hw->bus.type == e1000_bus_type_pci_express)
8113526Sxy150489 		reg_tctl |= E1000_TCTL_MULR;
8123526Sxy150489 
8134919Sxy150489 	E1000_WRITE_REG(hw, E1000_TCTL, reg_tctl);
8143526Sxy150489 
8154919Sxy150489 	if ((hw->mac.type == e1000_82571) || (hw->mac.type == e1000_82572)) {
8163526Sxy150489 		e1000_get_speed_and_duplex(hw, &speed, &duplex);
8173526Sxy150489 
8186735Scc210113 		reg_tarc = E1000_READ_REG(hw, E1000_TARC(0));
8193526Sxy150489 		reg_tarc |= (1 << 25);
8203526Sxy150489 		if (speed == SPEED_1000)
8213526Sxy150489 			reg_tarc |= (1 << 21);
8226735Scc210113 		E1000_WRITE_REG(hw, E1000_TARC(0), reg_tarc);
8233526Sxy150489 
8246735Scc210113 		reg_tarc = E1000_READ_REG(hw, E1000_TARC(1));
8253526Sxy150489 		reg_tarc |= (1 << 25);
8263526Sxy150489 		if (reg_tctl & E1000_TCTL_MULR)
8273526Sxy150489 			reg_tarc &= ~(1 << 28);
8283526Sxy150489 		else
8293526Sxy150489 			reg_tarc |= (1 << 28);
8306735Scc210113 		E1000_WRITE_REG(hw, E1000_TARC(1), reg_tarc);
8313526Sxy150489 
8324919Sxy150489 	} else if (hw->mac.type == e1000_80003es2lan) {
8336735Scc210113 		reg_tarc = E1000_READ_REG(hw, E1000_TARC(0));
8343526Sxy150489 		reg_tarc |= 1;
8356735Scc210113 		if (hw->phy.media_type == e1000_media_type_internal_serdes)
8363526Sxy150489 			reg_tarc |= (1 << 20);
8376735Scc210113 		E1000_WRITE_REG(hw, E1000_TARC(0), reg_tarc);
8383526Sxy150489 
8396735Scc210113 		reg_tarc = E1000_READ_REG(hw, E1000_TARC(1));
8403526Sxy150489 		reg_tarc |= 1;
8416735Scc210113 		E1000_WRITE_REG(hw, E1000_TARC(1), reg_tarc);
8423526Sxy150489 	}
8433526Sxy150489 
8443526Sxy150489 	/* Setup HW Base and Length of Tx descriptor area */
8454919Sxy150489 	size = (Adapter->tx_desc_num * sizeof (struct e1000_tx_desc));
8466735Scc210113 	E1000_WRITE_REG(hw, E1000_TDLEN(0), size);
8476735Scc210113 	size = E1000_READ_REG(hw, E1000_TDLEN(0));
8483526Sxy150489 
8493526Sxy150489 	buf_low = (uint32_t)tx_ring->tbd_dma_addr;
8503526Sxy150489 	buf_high = (uint32_t)(tx_ring->tbd_dma_addr >> 32);
8513526Sxy150489 
8526735Scc210113 	E1000_WRITE_REG(hw, E1000_TDBAL(0), buf_low);
8536735Scc210113 	E1000_WRITE_REG(hw, E1000_TDBAH(0), buf_high);
8543526Sxy150489 
8553526Sxy150489 	/* Setup our HW Tx Head & Tail descriptor pointers */
8566735Scc210113 	E1000_WRITE_REG(hw, E1000_TDH(0), 0);
8576735Scc210113 	E1000_WRITE_REG(hw, E1000_TDT(0), 0);
8583526Sxy150489 
8593526Sxy150489 	/* Set the default values for the Tx Inter Packet Gap timer */
8604919Sxy150489 	if ((hw->mac.type == e1000_82542) &&
8614919Sxy150489 	    ((hw->revision_id == E1000_REVISION_2) ||
8624919Sxy150489 	    (hw->revision_id == E1000_REVISION_3))) {
8633526Sxy150489 		reg_tipg = DEFAULT_82542_TIPG_IPGT;
8643526Sxy150489 		reg_tipg |=
8653526Sxy150489 		    DEFAULT_82542_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT;
8663526Sxy150489 		reg_tipg |=
8673526Sxy150489 		    DEFAULT_82542_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT;
8684919Sxy150489 	} else {
8696735Scc210113 		if (hw->phy.media_type == e1000_media_type_fiber)
8703526Sxy150489 			reg_tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
8713526Sxy150489 		else
8723526Sxy150489 			reg_tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
8733526Sxy150489 		reg_tipg |=
8743526Sxy150489 		    DEFAULT_82543_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT;
8753526Sxy150489 		reg_tipg |=
8763526Sxy150489 		    DEFAULT_82543_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT;
8773526Sxy150489 	}
8784919Sxy150489 	E1000_WRITE_REG(hw, E1000_TIPG, reg_tipg);
8793526Sxy150489 
8803526Sxy150489 	/* Setup Transmit Interrupt Delay Value */
8815882Syy150190 	E1000_WRITE_REG(hw, E1000_TIDV, Adapter->tx_intr_delay);
8825882Syy150190 	E1000G_DEBUGLOG_1(Adapter, E1000G_INFO_LEVEL,
8835882Syy150190 	    "E1000_TIDV: 0x%x\n", Adapter->tx_intr_delay);
8845882Syy150190 
8855882Syy150190 	if (hw->mac.type >= e1000_82540) {
8865882Syy150190 		E1000_WRITE_REG(&Adapter->shared, E1000_TADV,
8875882Syy150190 		    Adapter->tx_intr_abs_delay);
8885882Syy150190 		E1000G_DEBUGLOG_1(Adapter, E1000G_INFO_LEVEL,
8895882Syy150190 		    "E1000_TADV: 0x%x\n", Adapter->tx_intr_abs_delay);
8903526Sxy150489 	}
8913526Sxy150489 
8924919Sxy150489 	tx_ring->tbd_avail = Adapter->tx_desc_num;
8934919Sxy150489 
894*6986Smx205022 	/* Initialize stored context information */
895*6986Smx205022 	bzero(&(tx_ring->pre_context), sizeof (context_data_t));
8963526Sxy150489 }
8973526Sxy150489 
8983526Sxy150489 /*
8994919Sxy150489  * e1000g_recycle - recycle the tx descriptors and tx sw packets
9003526Sxy150489  */
9013526Sxy150489 int
9023526Sxy150489 e1000g_recycle(e1000g_tx_ring_t *tx_ring)
9033526Sxy150489 {
9043526Sxy150489 	struct e1000g *Adapter;
9053526Sxy150489 	LIST_DESCRIBER pending_list;
9064919Sxy150489 	p_tx_sw_packet_t packet;
9073526Sxy150489 	mblk_t *mp;
9083526Sxy150489 	mblk_t *nmp;
9093526Sxy150489 	struct e1000_tx_desc *descriptor;
9103526Sxy150489 	int desc_count;
9115882Syy150190 	int is_intr;
9123526Sxy150489 
9133526Sxy150489 	/*
9143526Sxy150489 	 * This function will examine each TxSwPacket in the 'used' queue
9153526Sxy150489 	 * if the e1000g is done with it then the associated resources (Tx
9163526Sxy150489 	 * Descriptors) will be "freed" and the TxSwPacket will be
9173526Sxy150489 	 * returned to the 'free' queue.
9183526Sxy150489 	 */
9193526Sxy150489 	Adapter = tx_ring->adapter;
9203526Sxy150489 
9214919Sxy150489 	packet = (p_tx_sw_packet_t)QUEUE_GET_HEAD(&tx_ring->used_list);
9223526Sxy150489 	if (packet == NULL) {
9234919Sxy150489 		tx_ring->recycle_fail = 0;
9244919Sxy150489 		tx_ring->stall_watchdog = 0;
9253526Sxy150489 		return (0);
9263526Sxy150489 	}
9273526Sxy150489 
9285882Syy150190 	is_intr = servicing_interrupt();
9295882Syy150190 
9305882Syy150190 	if (is_intr)
9315882Syy150190 		mutex_enter(&tx_ring->usedlist_lock);
9325882Syy150190 	else if (mutex_tryenter(&tx_ring->usedlist_lock) == 0)
9335882Syy150190 		return (0);
9345882Syy150190 
9355882Syy150190 	desc_count = 0;
9365882Syy150190 	QUEUE_INIT_LIST(&pending_list);
9375882Syy150190 
9384919Sxy150489 	/* Sync the Tx descriptor DMA buffer */
9394919Sxy150489 	(void) ddi_dma_sync(tx_ring->tbd_dma_handle,
9404919Sxy150489 	    0, 0, DDI_DMA_SYNC_FORKERNEL);
9415273Sgl147354 	if (e1000g_check_dma_handle(
9425273Sgl147354 	    tx_ring->tbd_dma_handle) != DDI_FM_OK) {
9435882Syy150190 		mutex_exit(&tx_ring->usedlist_lock);
9445273Sgl147354 		ddi_fm_service_impact(Adapter->dip, DDI_SERVICE_DEGRADED);
9455273Sgl147354 		Adapter->chip_state = E1000G_ERROR;
9465273Sgl147354 		return (0);
9475273Sgl147354 	}
9484919Sxy150489 
9493526Sxy150489 	/*
9503526Sxy150489 	 * While there are still TxSwPackets in the used queue check them
9513526Sxy150489 	 */
9523526Sxy150489 	while (packet =
9534919Sxy150489 	    (p_tx_sw_packet_t)QUEUE_GET_HEAD(&tx_ring->used_list)) {
9543526Sxy150489 
9553526Sxy150489 		/*
9563526Sxy150489 		 * Get hold of the next descriptor that the e1000g will
9573526Sxy150489 		 * report status back to (this will be the last descriptor
9584919Sxy150489 		 * of a given sw packet). We only want to free the
9594919Sxy150489 		 * sw packet (and it resources) if the e1000g is done
9603526Sxy150489 		 * with ALL of the descriptors.  If the e1000g is done
9613526Sxy150489 		 * with the last one then it is done with all of them.
9623526Sxy150489 		 */
9633526Sxy150489 		ASSERT(packet->num_desc);
9644919Sxy150489 		descriptor = tx_ring->tbd_oldest + (packet->num_desc - 1);
9653526Sxy150489 
9663526Sxy150489 		/* Check for wrap case */
9673526Sxy150489 		if (descriptor > tx_ring->tbd_last)
9684919Sxy150489 			descriptor -= Adapter->tx_desc_num;
9693526Sxy150489 
9703526Sxy150489 		/*
9713526Sxy150489 		 * If the descriptor done bit is set free TxSwPacket and
9723526Sxy150489 		 * associated resources
9733526Sxy150489 		 */
9743526Sxy150489 		if (descriptor->upper.fields.status & E1000_TXD_STAT_DD) {
9753526Sxy150489 			QUEUE_POP_HEAD(&tx_ring->used_list);
9763526Sxy150489 			QUEUE_PUSH_TAIL(&pending_list, &packet->Link);
9773526Sxy150489 
9783526Sxy150489 			if (descriptor == tx_ring->tbd_last)
9793526Sxy150489 				tx_ring->tbd_oldest =
9803526Sxy150489 				    tx_ring->tbd_first;
9813526Sxy150489 			else
9823526Sxy150489 				tx_ring->tbd_oldest =
9833526Sxy150489 				    descriptor + 1;
9843526Sxy150489 
9853526Sxy150489 			desc_count += packet->num_desc;
9863526Sxy150489 
9875882Syy150190 			if (is_intr && (desc_count >= Adapter->tx_recycle_num))
9883526Sxy150489 				break;
9893526Sxy150489 		} else {
9903526Sxy150489 			/*
9914919Sxy150489 			 * Found a sw packet that the e1000g is not done
9923526Sxy150489 			 * with then there is no reason to check the rest
9933526Sxy150489 			 * of the queue.
9943526Sxy150489 			 */
9953526Sxy150489 			break;
9963526Sxy150489 		}
9973526Sxy150489 	}
9983526Sxy150489 
9994919Sxy150489 	tx_ring->tbd_avail += desc_count;
10005882Syy150190 	Adapter->tx_pkt_cnt += desc_count;
10014919Sxy150489 
10023526Sxy150489 	mutex_exit(&tx_ring->usedlist_lock);
10033526Sxy150489 
10043526Sxy150489 	if (desc_count == 0) {
10054919Sxy150489 		tx_ring->recycle_fail++;
10064919Sxy150489 		E1000G_DEBUG_STAT(tx_ring->stat_recycle_none);
10073526Sxy150489 		return (0);
10083526Sxy150489 	}
10093526Sxy150489 
10104919Sxy150489 	tx_ring->recycle_fail = 0;
10114919Sxy150489 	tx_ring->stall_watchdog = 0;
10123526Sxy150489 
10133526Sxy150489 	mp = NULL;
10143526Sxy150489 	nmp = NULL;
10154919Sxy150489 	packet = (p_tx_sw_packet_t)QUEUE_GET_HEAD(&pending_list);
10163526Sxy150489 	ASSERT(packet != NULL);
10173526Sxy150489 	while (packet != NULL) {
10183526Sxy150489 		if (packet->mp != NULL) {
10193526Sxy150489 			ASSERT(packet->mp->b_next == NULL);
10203526Sxy150489 			/* Assemble the message chain */
10213526Sxy150489 			if (mp == NULL) {
10223526Sxy150489 				mp = packet->mp;
10233526Sxy150489 				nmp = packet->mp;
10243526Sxy150489 			} else {
10253526Sxy150489 				nmp->b_next = packet->mp;
10263526Sxy150489 				nmp = packet->mp;
10273526Sxy150489 			}
10283526Sxy150489 			/* Disconnect the message from the sw packet */
10293526Sxy150489 			packet->mp = NULL;
10303526Sxy150489 		}
10313526Sxy150489 
10323526Sxy150489 		/* Free the TxSwPackets */
10334919Sxy150489 		e1000g_free_tx_swpkt(packet);
10343526Sxy150489 
10354919Sxy150489 		packet = (p_tx_sw_packet_t)
10363526Sxy150489 		    QUEUE_GET_NEXT(&pending_list, &packet->Link);
10373526Sxy150489 	}
10383526Sxy150489 
10393526Sxy150489 	/* Return the TxSwPackets back to the FreeList */
10403526Sxy150489 	mutex_enter(&tx_ring->freelist_lock);
10413526Sxy150489 	QUEUE_APPEND(&tx_ring->free_list, &pending_list);
10423526Sxy150489 	mutex_exit(&tx_ring->freelist_lock);
10433526Sxy150489 
10445882Syy150190 	if (mp != NULL)
10455882Syy150190 		freemsgchain(mp);
10465882Syy150190 
10473526Sxy150489 	return (desc_count);
10483526Sxy150489 }
10493526Sxy150489 /*
10503526Sxy150489  * 82544 Coexistence issue workaround:
10513526Sxy150489  *    There are 2 issues.
10523526Sxy150489  *    1. If a 32 bit split completion happens from P64H2 and another
10533526Sxy150489  *	agent drives a 64 bit request/split completion after ONLY
10543526Sxy150489  *	1 idle clock (BRCM/Emulex/Adaptec fiber channel cards) then
10553526Sxy150489  *	82544 has a problem where in to clock all the data in, it
10563526Sxy150489  *	looks at REQ64# signal and since it has changed so fast (i.e. 1
10573526Sxy150489  *	idle clock turn around), it will fail to clock all the data in.
10583526Sxy150489  *	Data coming from certain ending addresses has exposure to this issue.
10593526Sxy150489  *
10603526Sxy150489  * To detect this issue, following equation can be used...
10613526Sxy150489  *	SIZE[3:0] + ADDR[2:0] = SUM[3:0].
10623526Sxy150489  *	If SUM[3:0] is in between 1 to 4, we will have this issue.
10633526Sxy150489  *
10643526Sxy150489  * ROOT CAUSE:
10653526Sxy150489  *	The erratum involves the 82544 PCIX elasticity FIFO implementations as
10663526Sxy150489  *	64-bit FIFO's and flushing of the final partial-bytes corresponding
10673526Sxy150489  *	to the end of a requested read burst. Under a specific burst condition
10683526Sxy150489  *	of ending-data alignment and 32-byte split-completions, the final
10693526Sxy150489  *	byte(s) of split-completion data require an extra clock cycle to flush
10703526Sxy150489  *	into 64-bit FIFO orientation.  An incorrect logic dependency on the
10713526Sxy150489  *	REQ64# signal occurring during during this clock cycle may cause the
10723526Sxy150489  *	residual byte(s) to be lost, thereby rendering the internal DMA client
10733526Sxy150489  *	forever awaiting the final byte(s) for an outbound data-fetch.  The
10743526Sxy150489  *	erratum is confirmed to *only* occur if certain subsequent external
10753526Sxy150489  *	64-bit PCIX bus transactions occur immediately (minimum possible bus
10763526Sxy150489  *	turn- around) following the odd-aligned 32-bit split-completion
10773526Sxy150489  *	containing the final byte(s).  Intel has confirmed that this has been
10783526Sxy150489  *	seen only with chipset/bridges which have the capability to provide
10793526Sxy150489  *	32-bit split-completion data, and in the presence of newer PCIX bus
10803526Sxy150489  *	agents which fully-optimize the inter-transaction turn-around (zero
10813526Sxy150489  *	additional initiator latency when pre-granted bus ownership).
10823526Sxy150489  *
10833526Sxy150489  *   	This issue does not exist in PCI bus mode, when any agent is operating
10843526Sxy150489  *	in 32 bit only mode or on chipsets that do not do 32 bit split
10853526Sxy150489  *	completions for 64 bit read requests (Serverworks chipsets). P64H2 does
10863526Sxy150489  *	32 bit split completions for any read request that has bit 2 set to 1
10873526Sxy150489  *	for the requested address and read request size is more than 8 bytes.
10883526Sxy150489  *
10893526Sxy150489  *   2. Another issue is related to 82544 driving DACs under the similar
10903526Sxy150489  *	scenario (32 bit split completion followed by 64 bit transaction with
10913526Sxy150489  *	only 1 cycle turnaround). This issue is still being root caused. We
10923526Sxy150489  *	think that both of these issues can be avoided if following workaround
10933526Sxy150489  *	is implemented. It seems DAC issues is related to ending addresses being
10943526Sxy150489  *	0x9, 0xA, 0xB, 0xC and hence ending up at odd boundaries in elasticity
10953526Sxy150489  *	FIFO which does not get flushed due to REQ64# dependency. We will only
10963526Sxy150489  *	know the full story after it has been simulated successfully by HW team.
10973526Sxy150489  *
10983526Sxy150489  * WORKAROUND:
10993526Sxy150489  *	Make sure we do not have ending address as 1,2,3,4(Hang) or 9,a,b,c(DAC)
11003526Sxy150489  */
11013526Sxy150489 static uint32_t
11024919Sxy150489 e1000g_fill_82544_desc(uint64_t address,
11034919Sxy150489     size_t length, p_desc_array_t desc_array)
11043526Sxy150489 {
11053526Sxy150489 	/*
11063526Sxy150489 	 * Since issue is sensitive to length and address.
11073526Sxy150489 	 * Let us first check the address...
11083526Sxy150489 	 */
11093526Sxy150489 	uint32_t safe_terminator;
11103526Sxy150489 
11114919Sxy150489 	if (length <= 4) {
11124919Sxy150489 		desc_array->descriptor[0].address = address;
11134919Sxy150489 		desc_array->descriptor[0].length = length;
11144919Sxy150489 		desc_array->elements = 1;
11154919Sxy150489 		return (desc_array->elements);
11163526Sxy150489 	}
11173526Sxy150489 	safe_terminator =
11184919Sxy150489 	    (uint32_t)((((uint32_t)address & 0x7) +
11194919Sxy150489 	    (length & 0xF)) & 0xF);
11203526Sxy150489 	/*
11213526Sxy150489 	 * if it does not fall between 0x1 to 0x4 and 0x9 to 0xC then
11223526Sxy150489 	 * return
11233526Sxy150489 	 */
11243526Sxy150489 	if (safe_terminator == 0 ||
11254919Sxy150489 	    (safe_terminator > 4 && safe_terminator < 9) ||
11263526Sxy150489 	    (safe_terminator > 0xC && safe_terminator <= 0xF)) {
11274919Sxy150489 		desc_array->descriptor[0].address = address;
11284919Sxy150489 		desc_array->descriptor[0].length = length;
11294919Sxy150489 		desc_array->elements = 1;
11304919Sxy150489 		return (desc_array->elements);
11313526Sxy150489 	}
11323526Sxy150489 
11334919Sxy150489 	desc_array->descriptor[0].address = address;
11344919Sxy150489 	desc_array->descriptor[0].length = length - 4;
11354919Sxy150489 	desc_array->descriptor[1].address = address + (length - 4);
11364919Sxy150489 	desc_array->descriptor[1].length = 4;
11374919Sxy150489 	desc_array->elements = 2;
11384919Sxy150489 	return (desc_array->elements);
11393526Sxy150489 }
11403526Sxy150489 
11413526Sxy150489 static int
11424919Sxy150489 e1000g_tx_copy(e1000g_tx_ring_t *tx_ring, p_tx_sw_packet_t packet,
1143*6986Smx205022     mblk_t *mp, boolean_t tx_undersize_flag)
11443526Sxy150489 {
11453526Sxy150489 	size_t len;
11463526Sxy150489 	size_t len1;
11473526Sxy150489 	dma_buffer_t *tx_buf;
11483526Sxy150489 	mblk_t *nmp;
11493526Sxy150489 	boolean_t finished;
11503526Sxy150489 	int desc_count;
11513526Sxy150489 
11523526Sxy150489 	desc_count = 0;
11533526Sxy150489 	tx_buf = packet->tx_buf;
11543526Sxy150489 	len = MBLKL(mp);
11553526Sxy150489 
11563526Sxy150489 	ASSERT((tx_buf->len + len) <= tx_buf->size);
11573526Sxy150489 
11583526Sxy150489 	if (len > 0) {
11593526Sxy150489 		bcopy(mp->b_rptr,
11603526Sxy150489 		    tx_buf->address + tx_buf->len,
11613526Sxy150489 		    len);
11623526Sxy150489 		tx_buf->len += len;
11633526Sxy150489 
11643526Sxy150489 		packet->num_mblk_frag++;
11653526Sxy150489 	}
11663526Sxy150489 
11673526Sxy150489 	nmp = mp->b_cont;
11683526Sxy150489 	if (nmp == NULL) {
11693526Sxy150489 		finished = B_TRUE;
11703526Sxy150489 	} else {
11713526Sxy150489 		len1 = MBLKL(nmp);
11723526Sxy150489 		if ((tx_buf->len + len1) > tx_buf->size)
11733526Sxy150489 			finished = B_TRUE;
1174*6986Smx205022 		else if (tx_undersize_flag)
11753526Sxy150489 			finished = B_FALSE;
11764919Sxy150489 		else if (len1 > tx_ring->adapter->tx_bcopy_thresh)
11773526Sxy150489 			finished = B_TRUE;
11783526Sxy150489 		else
11793526Sxy150489 			finished = B_FALSE;
11803526Sxy150489 	}
11813526Sxy150489 
11823526Sxy150489 	if (finished) {
11834919Sxy150489 		E1000G_DEBUG_STAT_COND(tx_ring->stat_multi_copy,
11844919Sxy150489 		    (tx_buf->len > len));
11853526Sxy150489 
11863526Sxy150489 		/*
11873526Sxy150489 		 * If the packet is smaller than 64 bytes, which is the
11883526Sxy150489 		 * minimum ethernet packet size, pad the packet to make
11893526Sxy150489 		 * it at least 60 bytes. The hardware will add 4 bytes
11903526Sxy150489 		 * for CRC.
11913526Sxy150489 		 */
1192*6986Smx205022 		if (tx_undersize_flag) {
11936394Scc210113 			ASSERT(tx_buf->len < ETHERMIN);
11943526Sxy150489 
11953526Sxy150489 			bzero(tx_buf->address + tx_buf->len,
11966394Scc210113 			    ETHERMIN - tx_buf->len);
11976394Scc210113 			tx_buf->len = ETHERMIN;
11983526Sxy150489 		}
11993526Sxy150489 
12003526Sxy150489 #ifdef __sparc
12014919Sxy150489 		if (packet->dma_type == USE_DVMA)
12023526Sxy150489 			dvma_sync(tx_buf->dma_handle, 0, DDI_DMA_SYNC_FORDEV);
12034919Sxy150489 		else
12043526Sxy150489 			(void) ddi_dma_sync(tx_buf->dma_handle, 0,
12053526Sxy150489 			    tx_buf->len, DDI_DMA_SYNC_FORDEV);
12064919Sxy150489 #else
12074919Sxy150489 		(void) ddi_dma_sync(tx_buf->dma_handle, 0,
12084919Sxy150489 		    tx_buf->len, DDI_DMA_SYNC_FORDEV);
12094919Sxy150489 #endif
12103526Sxy150489 
12113526Sxy150489 		packet->data_transfer_type = USE_BCOPY;
12123526Sxy150489 
12134919Sxy150489 		desc_count = e1000g_fill_tx_desc(tx_ring,
12143526Sxy150489 		    packet,
12153526Sxy150489 		    tx_buf->dma_address,
12163526Sxy150489 		    tx_buf->len);
12173526Sxy150489 
12183526Sxy150489 		if (desc_count <= 0)
12193526Sxy150489 			return (-1);
12203526Sxy150489 	}
12213526Sxy150489 
12223526Sxy150489 	return (desc_count);
12233526Sxy150489 }
12243526Sxy150489 
12253526Sxy150489 static int
12264919Sxy150489 e1000g_tx_bind(e1000g_tx_ring_t *tx_ring, p_tx_sw_packet_t packet, mblk_t *mp)
12273526Sxy150489 {
12283526Sxy150489 	int j;
12293526Sxy150489 	int mystat;
12303526Sxy150489 	size_t len;
12313526Sxy150489 	ddi_dma_cookie_t dma_cookie;
12323526Sxy150489 	uint_t ncookies;
12333526Sxy150489 	int desc_count;
12343526Sxy150489 	uint32_t desc_total;
12353526Sxy150489 
12363526Sxy150489 	desc_total = 0;
12373526Sxy150489 	len = MBLKL(mp);
12383526Sxy150489 
12393526Sxy150489 	/*
12403526Sxy150489 	 * ddi_dma_addr_bind_handle() allocates  DMA  resources  for  a
12413526Sxy150489 	 * memory  object such that a device can perform DMA to or from
12423526Sxy150489 	 * the object.  DMA resources  are  allocated  considering  the
12433526Sxy150489 	 * device's  DMA  attributes  as  expressed by ddi_dma_attr(9S)
12443526Sxy150489 	 * (see ddi_dma_alloc_handle(9F)).
12453526Sxy150489 	 *
12463526Sxy150489 	 * ddi_dma_addr_bind_handle() fills in  the  first  DMA  cookie
12473526Sxy150489 	 * pointed  to by cookiep with the appropriate address, length,
12483526Sxy150489 	 * and bus type. *ccountp is set to the number of DMA  cookies
12493526Sxy150489 	 * representing this DMA object. Subsequent DMA cookies must be
12503526Sxy150489 	 * retrieved by calling ddi_dma_nextcookie(9F)  the  number  of
12513526Sxy150489 	 * times specified by *countp - 1.
12523526Sxy150489 	 */
12533526Sxy150489 	switch (packet->dma_type) {
12543526Sxy150489 #ifdef __sparc
12553526Sxy150489 	case USE_DVMA:
12563526Sxy150489 		dvma_kaddr_load(packet->tx_dma_handle,
12573526Sxy150489 		    (caddr_t)mp->b_rptr, len, 0, &dma_cookie);
12583526Sxy150489 
12593526Sxy150489 		dvma_sync(packet->tx_dma_handle, 0,
12603526Sxy150489 		    DDI_DMA_SYNC_FORDEV);
12613526Sxy150489 
12623526Sxy150489 		ncookies = 1;
12633526Sxy150489 		packet->data_transfer_type = USE_DVMA;
12643526Sxy150489 		break;
12653526Sxy150489 #endif
12663526Sxy150489 	case USE_DMA:
12673526Sxy150489 		if ((mystat = ddi_dma_addr_bind_handle(
12684608Syy150190 		    packet->tx_dma_handle, NULL,
12694608Syy150190 		    (caddr_t)mp->b_rptr, len,
12704608Syy150190 		    DDI_DMA_WRITE | DDI_DMA_STREAMING,
12714608Syy150190 		    DDI_DMA_DONTWAIT, 0, &dma_cookie,
12724608Syy150190 		    &ncookies)) != DDI_DMA_MAPPED) {
12733526Sxy150489 
12744919Sxy150489 			e1000g_log(tx_ring->adapter, CE_WARN,
12753526Sxy150489 			    "Couldn't bind mblk buffer to Tx DMA handle: "
12763526Sxy150489 			    "return: %X, Pkt: %X\n",
12773526Sxy150489 			    mystat, packet);
12783526Sxy150489 			return (-1);
12793526Sxy150489 		}
12803526Sxy150489 
12813526Sxy150489 		/*
12823526Sxy150489 		 * An implicit ddi_dma_sync() is done when the
12833526Sxy150489 		 * ddi_dma_addr_bind_handle() is called. So we
12843526Sxy150489 		 * don't need to explicitly call ddi_dma_sync()
12853526Sxy150489 		 * here any more.
12863526Sxy150489 		 */
12873526Sxy150489 		ASSERT(ncookies);
12884919Sxy150489 		E1000G_DEBUG_STAT_COND(tx_ring->stat_multi_cookie,
12894919Sxy150489 		    (ncookies > 1));
12903526Sxy150489 
12913526Sxy150489 		/*
12923526Sxy150489 		 * The data_transfer_type value must be set after the handle
12934919Sxy150489 		 * has been bound, for it will be used in e1000g_free_tx_swpkt()
12943526Sxy150489 		 * to decide whether we need to unbind the handle.
12953526Sxy150489 		 */
12963526Sxy150489 		packet->data_transfer_type = USE_DMA;
12973526Sxy150489 		break;
12983526Sxy150489 	default:
12993526Sxy150489 		ASSERT(B_FALSE);
13003526Sxy150489 		break;
13013526Sxy150489 	}
13023526Sxy150489 
13033526Sxy150489 	packet->num_mblk_frag++;
13043526Sxy150489 
13053526Sxy150489 	/*
13063526Sxy150489 	 * Each address could span thru multpile cookie..
13073526Sxy150489 	 * Each cookie will have one descriptor
13083526Sxy150489 	 */
13093526Sxy150489 	for (j = ncookies; j != 0; j--) {
13103526Sxy150489 
13114919Sxy150489 		desc_count = e1000g_fill_tx_desc(tx_ring,
13123526Sxy150489 		    packet,
13133526Sxy150489 		    dma_cookie.dmac_laddress,
13143526Sxy150489 		    dma_cookie.dmac_size);
13153526Sxy150489 
13163526Sxy150489 		if (desc_count <= 0)
13173526Sxy150489 			return (-1);
13183526Sxy150489 
13193526Sxy150489 		desc_total += desc_count;
13203526Sxy150489 
13213526Sxy150489 		/*
13223526Sxy150489 		 * ddi_dma_nextcookie() retrieves subsequent DMA
13233526Sxy150489 		 * cookies for a DMA object.
13243526Sxy150489 		 * ddi_dma_nextcookie() fills in the
13253526Sxy150489 		 * ddi_dma_cookie(9S) structure pointed to by
13263526Sxy150489 		 * cookiep.  The ddi_dma_cookie(9S) structure
13273526Sxy150489 		 * must be allocated prior to calling
13283526Sxy150489 		 * ddi_dma_nextcookie(). The DMA cookie count
13293526Sxy150489 		 * returned by ddi_dma_buf_bind_handle(9F),
13303526Sxy150489 		 * ddi_dma_addr_bind_handle(9F), or
13313526Sxy150489 		 * ddi_dma_getwin(9F) indicates the number of DMA
13323526Sxy150489 		 * cookies a DMA object consists of.  If the
13333526Sxy150489 		 * resulting cookie count, N, is larger than 1,
13343526Sxy150489 		 * ddi_dma_nextcookie() must be called N-1 times
13353526Sxy150489 		 * to retrieve all DMA cookies.
13363526Sxy150489 		 */
13373526Sxy150489 		if (j > 1) {
13383526Sxy150489 			ddi_dma_nextcookie(packet->tx_dma_handle,
13393526Sxy150489 			    &dma_cookie);
13403526Sxy150489 		}
13413526Sxy150489 	}
13423526Sxy150489 
13433526Sxy150489 	return (desc_total);
13443526Sxy150489 }
13453526Sxy150489 
13463526Sxy150489 static void
1347*6986Smx205022 e1000g_fill_context_descriptor(context_data_t *cur_context,
1348*6986Smx205022     struct e1000_context_desc *context_desc)
13493526Sxy150489 {
1350*6986Smx205022 	if (cur_context->cksum_flags & HCK_IPV4_HDRCKSUM) {
1351*6986Smx205022 		context_desc->lower_setup.ip_fields.ipcss =
1352*6986Smx205022 		    cur_context->ether_header_size;
1353*6986Smx205022 		context_desc->lower_setup.ip_fields.ipcso =
1354*6986Smx205022 		    cur_context->ether_header_size +
13553526Sxy150489 		    offsetof(struct ip, ip_sum);
1356*6986Smx205022 		context_desc->lower_setup.ip_fields.ipcse =
1357*6986Smx205022 		    cur_context->ether_header_size +
1358*6986Smx205022 		    cur_context->cksum_start - 1;
13593526Sxy150489 	} else
1360*6986Smx205022 		context_desc->lower_setup.ip_config = 0;
13613526Sxy150489 
1362*6986Smx205022 	if (cur_context->cksum_flags & HCK_PARTIALCKSUM) {
13633526Sxy150489 		/*
13643526Sxy150489 		 * The packet with same protocol has the following
13653526Sxy150489 		 * stuff and start offset:
13663526Sxy150489 		 * |  Protocol  | Stuff  | Start  | Checksum
13673526Sxy150489 		 * |		| Offset | Offset | Enable
13683526Sxy150489 		 * | IPv4 + TCP |  0x24  |  0x14  |  Yes
13693526Sxy150489 		 * | IPv4 + UDP |  0x1A  |  0x14  |  Yes
13703526Sxy150489 		 * | IPv6 + TCP |  0x20  |  0x10  |  No
13713526Sxy150489 		 * | IPv6 + UDP |  0x14  |  0x10  |  No
13723526Sxy150489 		 */
1373*6986Smx205022 		context_desc->upper_setup.tcp_fields.tucss =
1374*6986Smx205022 		    cur_context->cksum_start + cur_context->ether_header_size;
1375*6986Smx205022 		context_desc->upper_setup.tcp_fields.tucso =
1376*6986Smx205022 		    cur_context->cksum_stuff + cur_context->ether_header_size;
1377*6986Smx205022 		context_desc->upper_setup.tcp_fields.tucse = 0;
13783526Sxy150489 	} else
1379*6986Smx205022 		context_desc->upper_setup.tcp_config = 0;
13803526Sxy150489 
1381*6986Smx205022 	if (cur_context->lso_flag) {
1382*6986Smx205022 		context_desc->tcp_seg_setup.fields.mss = cur_context->mss;
1383*6986Smx205022 		context_desc->tcp_seg_setup.fields.hdr_len =
1384*6986Smx205022 		    cur_context->hdr_len;
1385*6986Smx205022 		/*
1386*6986Smx205022 		 * workaround for 82546EB errata 23, status-writeback
1387*6986Smx205022 		 * reporting (RS) should not be set on context or
1388*6986Smx205022 		 * Null descriptors
1389*6986Smx205022 		 */
1390*6986Smx205022 		context_desc->cmd_and_length = E1000_TXD_CMD_DEXT
1391*6986Smx205022 		    | E1000_TXD_CMD_TSE | E1000_TXD_CMD_IP | E1000_TXD_CMD_TCP
1392*6986Smx205022 		    | E1000_TXD_DTYP_C | cur_context->pay_len;
1393*6986Smx205022 	} else {
1394*6986Smx205022 		context_desc->cmd_and_length = E1000_TXD_CMD_DEXT
1395*6986Smx205022 		    | E1000_TXD_DTYP_C;
1396*6986Smx205022 		/*
1397*6986Smx205022 		 * Zero out the options for TCP Segmentation Offload
1398*6986Smx205022 		 */
1399*6986Smx205022 		context_desc->tcp_seg_setup.data = 0;
1400*6986Smx205022 	}
14013526Sxy150489 }
14023526Sxy150489 
14033526Sxy150489 static int
14044919Sxy150489 e1000g_fill_tx_desc(e1000g_tx_ring_t *tx_ring,
14054919Sxy150489     p_tx_sw_packet_t packet, uint64_t address, size_t size)
14063526Sxy150489 {
14074919Sxy150489 	struct e1000_hw *hw = &tx_ring->adapter->shared;
14084919Sxy150489 	p_sw_desc_t desc;
14093526Sxy150489 
14104919Sxy150489 	if (hw->mac.type == e1000_82544) {
14114919Sxy150489 		if (hw->bus.type == e1000_bus_type_pcix)
14124919Sxy150489 			return (e1000g_tx_workaround_PCIX_82544(packet,
14134919Sxy150489 			    address, size));
14143526Sxy150489 
14154919Sxy150489 		if (size > JUMBO_FRAG_LENGTH)
14164919Sxy150489 			return (e1000g_tx_workaround_jumbo_82544(packet,
14174919Sxy150489 			    address, size));
14183526Sxy150489 	}
14193526Sxy150489 
14204919Sxy150489 	ASSERT(packet->num_desc < MAX_TX_DESC_PER_PACKET);
14214919Sxy150489 
14224919Sxy150489 	desc = &packet->desc[packet->num_desc];
14234919Sxy150489 	desc->address = address;
14244919Sxy150489 	desc->length = size;
14254919Sxy150489 
14264919Sxy150489 	packet->num_desc++;
14274919Sxy150489 
14284919Sxy150489 	return (1);
14293526Sxy150489 }
14303526Sxy150489 
14313526Sxy150489 static int
14324919Sxy150489 e1000g_tx_workaround_PCIX_82544(p_tx_sw_packet_t packet,
14334919Sxy150489     uint64_t address, size_t size)
14343526Sxy150489 {
14354919Sxy150489 	p_sw_desc_t desc;
14363526Sxy150489 	int desc_count;
14373526Sxy150489 	long size_left;
14383526Sxy150489 	size_t len;
14393526Sxy150489 	uint32_t counter;
14403526Sxy150489 	uint32_t array_elements;
14414919Sxy150489 	desc_array_t desc_array;
14423526Sxy150489 
14433526Sxy150489 	/*
14443526Sxy150489 	 * Coexist Workaround for cordova: RP: 07/04/03
14453526Sxy150489 	 *
14463526Sxy150489 	 * RP: ERRATA: Workaround ISSUE:
14473526Sxy150489 	 * 8kb_buffer_Lockup CONTROLLER: Cordova Breakup
14483526Sxy150489 	 * Eachbuffer in to 8kb pieces until the
14493526Sxy150489 	 * remainder is < 8kb
14503526Sxy150489 	 */
14513526Sxy150489 	size_left = size;
14523526Sxy150489 	desc_count = 0;
14533526Sxy150489 
14543526Sxy150489 	while (size_left > 0) {
14553526Sxy150489 		if (size_left > MAX_TX_BUF_SIZE)
14563526Sxy150489 			len = MAX_TX_BUF_SIZE;
14573526Sxy150489 		else
14583526Sxy150489 			len = size_left;
14593526Sxy150489 
14603526Sxy150489 		array_elements = e1000g_fill_82544_desc(address,
14613526Sxy150489 		    len, &desc_array);
14623526Sxy150489 
14633526Sxy150489 		for (counter = 0; counter < array_elements; counter++) {
14643526Sxy150489 			ASSERT(packet->num_desc < MAX_TX_DESC_PER_PACKET);
14653526Sxy150489 			/*
14663526Sxy150489 			 * Put in the buffer address
14673526Sxy150489 			 */
14683526Sxy150489 			desc = &packet->desc[packet->num_desc];
14693526Sxy150489 
14704919Sxy150489 			desc->address =
14714919Sxy150489 			    desc_array.descriptor[counter].address;
14724919Sxy150489 			desc->length =
14734919Sxy150489 			    desc_array.descriptor[counter].length;
14743526Sxy150489 
14753526Sxy150489 			packet->num_desc++;
14763526Sxy150489 			desc_count++;
14773526Sxy150489 		} /* for */
14783526Sxy150489 
14793526Sxy150489 		/*
14803526Sxy150489 		 * Update the buffer address and length
14813526Sxy150489 		 */
14823526Sxy150489 		address += MAX_TX_BUF_SIZE;
14833526Sxy150489 		size_left -= MAX_TX_BUF_SIZE;
14843526Sxy150489 	} /* while */
14853526Sxy150489 
14863526Sxy150489 	return (desc_count);
14873526Sxy150489 }
14883526Sxy150489 
14893526Sxy150489 static int
14904919Sxy150489 e1000g_tx_workaround_jumbo_82544(p_tx_sw_packet_t packet,
14914919Sxy150489     uint64_t address, size_t size)
14923526Sxy150489 {
14934919Sxy150489 	p_sw_desc_t desc;
14943526Sxy150489 	int desc_count;
14953526Sxy150489 	long size_left;
14963526Sxy150489 	uint32_t offset;
14973526Sxy150489 
14983526Sxy150489 	/*
14993526Sxy150489 	 * Workaround for Jumbo Frames on Cordova
15003526Sxy150489 	 * PSD 06/01/2001
15013526Sxy150489 	 */
15023526Sxy150489 	size_left = size;
15033526Sxy150489 	desc_count = 0;
15043526Sxy150489 	offset = 0;
15053526Sxy150489 	while (size_left > 0) {
15063526Sxy150489 		ASSERT(packet->num_desc < MAX_TX_DESC_PER_PACKET);
15073526Sxy150489 
15083526Sxy150489 		desc = &packet->desc[packet->num_desc];
15093526Sxy150489 
15104919Sxy150489 		desc->address = address + offset;
15113526Sxy150489 
15123526Sxy150489 		if (size_left > JUMBO_FRAG_LENGTH)
15134919Sxy150489 			desc->length = JUMBO_FRAG_LENGTH;
15143526Sxy150489 		else
15154919Sxy150489 			desc->length = size_left;
15163526Sxy150489 
15173526Sxy150489 		packet->num_desc++;
15183526Sxy150489 		desc_count++;
15193526Sxy150489 
15204919Sxy150489 		offset += desc->length;
15213526Sxy150489 		size_left -= JUMBO_FRAG_LENGTH;
15223526Sxy150489 	}
15233526Sxy150489 
15243526Sxy150489 	return (desc_count);
15253526Sxy150489 }
15263526Sxy150489 
15274919Sxy150489 #pragma inline(e1000g_82547_tx_move_tail_work)
15284919Sxy150489 
15293526Sxy150489 static void
15303526Sxy150489 e1000g_82547_tx_move_tail_work(e1000g_tx_ring_t *tx_ring)
15313526Sxy150489 {
15324919Sxy150489 	struct e1000_hw *hw;
15333526Sxy150489 	uint16_t hw_tdt;
15343526Sxy150489 	uint16_t sw_tdt;
15353526Sxy150489 	struct e1000_tx_desc *tx_desc;
15363526Sxy150489 	uint16_t length = 0;
15373526Sxy150489 	boolean_t eop = B_FALSE;
15383526Sxy150489 	struct e1000g *Adapter;
15393526Sxy150489 
15403526Sxy150489 	Adapter = tx_ring->adapter;
15414919Sxy150489 	hw = &Adapter->shared;
15423526Sxy150489 
15436735Scc210113 	hw_tdt = E1000_READ_REG(hw, E1000_TDT(0));
15443526Sxy150489 	sw_tdt = tx_ring->tbd_next - tx_ring->tbd_first;
15453526Sxy150489 
15463526Sxy150489 	while (hw_tdt != sw_tdt) {
15473526Sxy150489 		tx_desc = &(tx_ring->tbd_first[hw_tdt]);
15483526Sxy150489 		length += tx_desc->lower.flags.length;
15493526Sxy150489 		eop = tx_desc->lower.data & E1000_TXD_CMD_EOP;
15504919Sxy150489 		if (++hw_tdt == Adapter->tx_desc_num)
15513526Sxy150489 			hw_tdt = 0;
15523526Sxy150489 
15533526Sxy150489 		if (eop) {
15543526Sxy150489 			if ((Adapter->link_duplex == HALF_DUPLEX) &&
15554919Sxy150489 			    (e1000_fifo_workaround_82547(hw, length)
15564919Sxy150489 			    != E1000_SUCCESS)) {
15573526Sxy150489 				if (tx_ring->timer_enable_82547) {
15583526Sxy150489 					ASSERT(tx_ring->timer_id_82547 == 0);
15593526Sxy150489 					tx_ring->timer_id_82547 =
15603526Sxy150489 					    timeout(e1000g_82547_timeout,
15614608Syy150190 					    (void *)tx_ring,
15624608Syy150190 					    drv_usectohz(10000));
15633526Sxy150489 				}
15643526Sxy150489 				return;
15653526Sxy150489 
15663526Sxy150489 			} else {
15676735Scc210113 				E1000_WRITE_REG(hw, E1000_TDT(0), hw_tdt);
15684919Sxy150489 				e1000_update_tx_fifo_head_82547(hw, length);
15693526Sxy150489 				length = 0;
15703526Sxy150489 			}
15713526Sxy150489 		}
15723526Sxy150489 	}
15733526Sxy150489 }
15743526Sxy150489 
15753526Sxy150489 static void
15763526Sxy150489 e1000g_82547_timeout(void *arg)
15773526Sxy150489 {
15783526Sxy150489 	e1000g_tx_ring_t *tx_ring;
15793526Sxy150489 
15803526Sxy150489 	tx_ring = (e1000g_tx_ring_t *)arg;
15813526Sxy150489 
15823526Sxy150489 	mutex_enter(&tx_ring->tx_lock);
15833526Sxy150489 
15843526Sxy150489 	tx_ring->timer_id_82547 = 0;
15853526Sxy150489 	e1000g_82547_tx_move_tail_work(tx_ring);
15863526Sxy150489 
15873526Sxy150489 	mutex_exit(&tx_ring->tx_lock);
15883526Sxy150489 }
15893526Sxy150489 
15903526Sxy150489 static void
15913526Sxy150489 e1000g_82547_tx_move_tail(e1000g_tx_ring_t *tx_ring)
15923526Sxy150489 {
15933526Sxy150489 	timeout_id_t tid;
15943526Sxy150489 
15953526Sxy150489 	ASSERT(MUTEX_HELD(&tx_ring->tx_lock));
15963526Sxy150489 
15973526Sxy150489 	tid = tx_ring->timer_id_82547;
15983526Sxy150489 	tx_ring->timer_id_82547 = 0;
15993526Sxy150489 	if (tid != 0) {
16003526Sxy150489 		tx_ring->timer_enable_82547 = B_FALSE;
16013526Sxy150489 		mutex_exit(&tx_ring->tx_lock);
16023526Sxy150489 
16033526Sxy150489 		(void) untimeout(tid);
16043526Sxy150489 
16053526Sxy150489 		mutex_enter(&tx_ring->tx_lock);
16063526Sxy150489 	}
16073526Sxy150489 	tx_ring->timer_enable_82547 = B_TRUE;
16083526Sxy150489 	e1000g_82547_tx_move_tail_work(tx_ring);
16093526Sxy150489 }
1610