e1000g_tx.c revision da14cebe459d3275048785f25bd869cb09b5307f
2N/A * This file is provided under a CDDLv1 license. When using or 2N/A * redistributing this file, you may do so under this license. 2N/A * In redistributing this file this license must be included 2N/A * and no other modification of this header file is permitted. 2N/A * CDDL LICENSE SUMMARY 2N/A * Copyright(c) 1999 - 2008 Intel Corporation. All rights reserved. 2N/A * The contents of this file are subject to the terms of Version 2N/A * 1.0 of the Common Development and Distribution License (the "License"). 2N/A * You should have received a copy of the License with this software. 2N/A * You can obtain a copy of the License at 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 2N/A * Use is subject to license terms. 2N/A * ********************************************************************** 2N/A * This file contains some routines that take care of Transmit, * 2N/A * make the hardware to send the data pointed by the packet out * 2N/A * on to the physical medium. * 2N/A * ********************************************************************** 2N/A * e1000g_free_tx_swpkt - free up the tx sw packet 2N/A * Unbind the previously bound DMA handle for a given 2N/A * transmit sw packet. And reset the sw packet data. 2N/A * The mblk has been stripped off the sw packet 2N/A * and will be freed in a triggered soft intr. * e1000g_send - send packets onto the wire * Called from e1000g_m_tx with an mblk ready to send. this * routine sets up the transmit descriptors and sends data to * the wire. It also pushes the just transmitted packet to * the used tx sw packet list. /* Get the total size and frags number of the message */ /* retrieve and compute information for context descriptor */ * Make sure the packet is less than the allowed size * For the over size packet, we'll just drop it. * So we return B_TRUE here. "Tx packet out of bound. length = %d \n",
msg_size);
* Check and reclaim tx descriptors. * This low water mark check should be done all the time as * Transmit interrupt delay can produce Transmit interrupts little * late and that may cause few problems related to reaping Tx * Descriptors... As you may run short of them before getting any * If the message size is less than the minimum ethernet packet size, * we'll use bcopy to send it, and padd it to 60 bytes later. /* Initialize variables */ desc_count =
1;
/* The initial value should be greater than 0 */ /* Process each mblk fragment and fill tx descriptors */ * The software should guarantee LSO packet header(MAC+IP+TCP) * to be within one descriptor. Here we reallocate and refill the * the header if it's physical memory non-contiguous. /* find the last fragment of the header */ * If the header and the payload are in different mblks, * we simply force the header to be copied into pre-allocated * There are two cases we need to reallocate a mblk for the * 1. the header is in multiple mblks and the last fragment * share the same mblk with the payload * 2. the header is in a single mblk shared with the payload * and the header is physical memory non-contiguous * reallocate the mblk for the last header fragment, * expect to bcopy into pre-allocated page-aligned /* link the new header fragment with the other parts */ * adjust the bcopy threshhold to guarantee * the header to use bcopy way /* Check zero length mblks */ * If there're no packet buffers have been used, * or we just completed processing a buffer, then * skip the empty mblk fragment. * Otherwise, there's still a pending buffer that * needs to be processed (tx_copy). * Get a new TxSwPacket to process mblk buffers. "No Tx SwPacket available\n");
* If the size of the fragment is less than the tx_bcopy_thresh * we'll use bcopy; Otherwise, we'll use DMA binding. /* Assign the message to the last sw packet */ /* Try to recycle the tx descriptors again */ * If the number of available tx descriptors is not enough for transmit * (one redundant descriptor and one hw checksum context descriptor are * included), then return failure. "No Enough Tx descriptors\n");
* Enable Transmit interrupts, so that the interrupt routine can * call mac_tx_update() when transmit descriptors become available. /* Free pending TxSwPackets */ /* Return pending TxSwPackets to the "Free" list */ /* Message will be scheduled for re-transmit */ * Enable Transmit interrupts, so that the interrupt routine can * call mac_tx_update() when transmit descriptors become available. /* Message will be scheduled for re-transmit */ /* first check lso information */ /* retrieve checksum info */ /* retrieve ethernet header size */ /* free the invalid packet */ * Some fields are cleared for the hardware to fill * in. We don't assume Ethernet header, IP header and * TCP header are always in the same mblk fragment, * while we assume each header is always within one * mblk fragment and Ethernet header is always in the /* calculate the TCP packet payload length */ * The following code determine if the context descriptor is * needed to be reloaded. The sequence of the conditions is * made by their possibilities of changing. * workaround for 82546EB, context descriptor must be reloaded /* Context descriptor reload check */ /* Check the wrap-around case */ /* must set RS on every outgoing descriptor */ /* Check the wrap-around case */ * workaround for 82546EB errata 33, hang in PCI-X * systems due to 2k Buffer Overrun during Transmit * Operation. The workaround applies to all the Intel /* modified the first descriptor */ /* insert a new descriptor */ /* must set RS on every outgoing descriptor */ /* Check the wrap-around case */ * Count the checksum context descriptor for * workaround for 82546EB errata 21, LSO Premature Descriptor Write Back /* modified the previous descriptor */ /* insert a new descriptor */ /* the lower 20 bits of lower.data is the length field */ /* It must be part of a LSO packet */ /* Check the wrap-around case */ /* update the number of descriptors */ * Last Descriptor of Packet needs End Of Packet (EOP), Report /* Set append Ethernet CRC (IFCS) bits */ * Sync the Tx descriptors DMA buffer * Advance the Transmit Descriptor Tail (Tdt), this tells the * FX1000 that this frame is available to transmit. /* Put the pending SwPackets to the "Used" list */ /* update LSO related data */ * e1000g_tx_setup - setup tx data structures * This routine initializes all of the transmit related * structures. This includes the Transmit descriptors, * and the tx_sw_packet structures. * Here we don't need to protect the lists using the * usedlist_lock and freelist_lock, for they have * been protected by the chip_lock. /* Go through and set up each SW_Packet */ /* Initialize this tx_sw_apcket area */ /* Add this tx_sw_packet to the free list */ /* Setup TX descriptor pointers */ * Setup Hardware TX Registers /* Setup the Transmit Control Register (TCTL). */ /* Enable the MULR bit */ /* Setup HW Base and Length of Tx descriptor area */ * Write the highest location first and work backward to the lowest. * This is necessary for some adapter types to * prevent write combining from occurring. /* Setup our HW Tx Head & Tail descriptor pointers */ /* Set the default values for the Tx Inter Packet Gap timer */ /* Setup Transmit Interrupt Delay Value */ /* Initialize stored context information */ * e1000g_recycle - recycle the tx descriptors and tx sw packets * This function will examine each TxSwPacket in the 'used' queue * if the e1000g is done with it then the associated resources (Tx * Descriptors) will be "freed" and the TxSwPacket will be * returned to the 'free' queue. /* Sync the Tx descriptor DMA buffer */ * While there are still TxSwPackets in the used queue check them * Get hold of the next descriptor that the e1000g will * report status back to (this will be the last descriptor * of a given sw packet). We only want to free the * sw packet (and it resources) if the e1000g is done * with ALL of the descriptors. If the e1000g is done * with the last one then it is done with all of them. /* Check for wrap case */ * If the descriptor done bit is set free TxSwPacket and * Found a sw packet that the e1000g is not done * with then there is no reason to check the rest /* Assemble the message chain */ /* Disconnect the message from the sw packet */ /* Free the TxSwPackets */ /* Return the TxSwPackets back to the FreeList */ * 82544 Coexistence issue workaround: * 1. If a 32 bit split completion happens from P64H2 and another * 82544 has a problem where in to clock all the data in, it * looks at REQ64# signal and since it has changed so fast (i.e. 1 * idle clock turn around), it will fail to clock all the data in. * Data coming from certain ending addresses has exposure to this issue. * To detect this issue, following equation can be used... * SIZE[3:0] + ADDR[2:0] = SUM[3:0]. * If SUM[3:0] is in between 1 to 4, we will have this issue. * The erratum involves the 82544 PCIX elasticity FIFO implementations as * 64-bit FIFO's and flushing of the final partial-bytes corresponding * to the end of a requested read burst. Under a specific burst condition * of ending-data alignment and 32-byte split-completions, the final * byte(s) of split-completion data require an extra clock cycle to flush * into 64-bit FIFO orientation. An incorrect logic dependency on the * REQ64# signal occurring during during this clock cycle may cause the * residual byte(s) to be lost, thereby rendering the internal DMA client * forever awaiting the final byte(s) for an outbound data-fetch. The * erratum is confirmed to *only* occur if certain subsequent external * 64-bit PCIX bus transactions occur immediately (minimum possible bus * turn- around) following the odd-aligned 32-bit split-completion * containing the final byte(s). Intel has confirmed that this has been * 32-bit split-completion data, and in the presence of newer PCIX bus * agents which fully-optimize the inter-transaction turn-around (zero * additional initiator latency when pre-granted bus ownership). * This issue does not exist in PCI bus mode, when any agent is operating * in 32 bit only mode or on chipsets that do not do 32 bit split * completions for 64 bit read requests (Serverworks chipsets). P64H2 does * 32 bit split completions for any read request that has bit 2 set to 1 * for the requested address and read request size is more than 8 bytes. * 2. Another issue is related to 82544 driving DACs under the similar * scenario (32 bit split completion followed by 64 bit transaction with * only 1 cycle turnaround). This issue is still being root caused. We * think that both of these issues can be avoided if following workaround * is implemented. It seems DAC issues is related to ending addresses being * 0x9, 0xA, 0xB, 0xC and hence ending up at odd boundaries in elasticity * FIFO which does not get flushed due to REQ64# dependency. We will only * know the full story after it has been simulated successfully by HW team. * Make sure we do not have ending address as 1,2,3,4(Hang) or 9,a,b,c(DAC) * Since issue is sensitive to length and address. * Let us first check the address... * if it does not fall between 0x1 to 0x4 and 0x9 to 0xC then * If the packet is smaller than 64 bytes, which is the * minimum ethernet packet size, pad the packet to make * it at least 60 bytes. The hardware will add 4 bytes * ddi_dma_addr_bind_handle() allocates DMA resources for a * memory object such that a device can perform DMA to or from * the object. DMA resources are allocated considering the * device's DMA attributes as expressed by ddi_dma_attr(9S) * (see ddi_dma_alloc_handle(9F)). * ddi_dma_addr_bind_handle() fills in the first DMA cookie * pointed to by cookiep with the appropriate address, length, * and bus type. *ccountp is set to the number of DMA cookies * representing this DMA object. Subsequent DMA cookies must be * retrieved by calling ddi_dma_nextcookie(9F) the number of * times specified by *countp - 1. "Couldn't bind mblk buffer to Tx DMA handle: " * An implicit ddi_dma_sync() is done when the * ddi_dma_addr_bind_handle() is called. So we * don't need to explicitly call ddi_dma_sync() * The data_transfer_type value must be set after the handle * has been bound, for it will be used in e1000g_free_tx_swpkt() * to decide whether we need to unbind the handle. * Each address could span thru multpile cookie.. * Each cookie will have one descriptor * ddi_dma_nextcookie() retrieves subsequent DMA * cookies for a DMA object. * ddi_dma_nextcookie() fills in the * ddi_dma_cookie(9S) structure pointed to by * cookiep. The ddi_dma_cookie(9S) structure * must be allocated prior to calling * ddi_dma_nextcookie(). The DMA cookie count * returned by ddi_dma_buf_bind_handle(9F), * ddi_dma_addr_bind_handle(9F), or * ddi_dma_getwin(9F) indicates the number of DMA * cookies a DMA object consists of. If the * resulting cookie count, N, is larger than 1, * ddi_dma_nextcookie() must be called N-1 times * to retrieve all DMA cookies. * The packet with same protocol has the following * stuff and start offset: * | Protocol | Stuff | Start | Checksum * | | Offset | Offset | Enable * | IPv4 + TCP | 0x24 | 0x14 | Yes * | IPv4 + UDP | 0x1A | 0x14 | Yes * | IPv6 + TCP | 0x20 | 0x10 | No * | IPv6 + UDP | 0x14 | 0x10 | No * workaround for 82546EB errata 23, status-writeback * reporting (RS) should not be set on context or * Zero out the options for TCP Segmentation Offload * Coexist Workaround for cordova: RP: 07/04/03 * RP: ERRATA: Workaround ISSUE: * 8kb_buffer_Lockup CONTROLLER: Cordova Breakup * Eachbuffer in to 8kb pieces until the * Put in the buffer address * Update the buffer address and length * Workaround for Jumbo Frames on Cordova