080575042aba2197b425ebfd52061dea061a9aa1xy/*
080575042aba2197b425ebfd52061dea061a9aa1xy * This file is provided under a CDDLv1 license. When using or
080575042aba2197b425ebfd52061dea061a9aa1xy * redistributing this file, you may do so under this license.
080575042aba2197b425ebfd52061dea061a9aa1xy * In redistributing this file this license must be included
080575042aba2197b425ebfd52061dea061a9aa1xy * and no other modification of this header file is permitted.
080575042aba2197b425ebfd52061dea061a9aa1xy *
080575042aba2197b425ebfd52061dea061a9aa1xy * CDDL LICENSE SUMMARY
080575042aba2197b425ebfd52061dea061a9aa1xy *
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems * Copyright(c) 1999 - 2009 Intel Corporation. All rights reserved.
080575042aba2197b425ebfd52061dea061a9aa1xy *
080575042aba2197b425ebfd52061dea061a9aa1xy * The contents of this file are subject to the terms of Version
080575042aba2197b425ebfd52061dea061a9aa1xy * 1.0 of the Common Development and Distribution License (the "License").
080575042aba2197b425ebfd52061dea061a9aa1xy *
080575042aba2197b425ebfd52061dea061a9aa1xy * You should have received a copy of the License with this software.
080575042aba2197b425ebfd52061dea061a9aa1xy * You can obtain a copy of the License at
080575042aba2197b425ebfd52061dea061a9aa1xy * http://www.opensolaris.org/os/licensing.
080575042aba2197b425ebfd52061dea061a9aa1xy * See the License for the specific language governing permissions
080575042aba2197b425ebfd52061dea061a9aa1xy * and limitations under the License.
080575042aba2197b425ebfd52061dea061a9aa1xy */
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy/*
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
080575042aba2197b425ebfd52061dea061a9aa1xy */
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy/*
080575042aba2197b425ebfd52061dea061a9aa1xy * **********************************************************************
080575042aba2197b425ebfd52061dea061a9aa1xy * Module Name: *
25f2d433de915875c8393f0b0dc14aa155997ad0xy * e1000g_alloc.c *
080575042aba2197b425ebfd52061dea061a9aa1xy * *
080575042aba2197b425ebfd52061dea061a9aa1xy * Abstract: *
25f2d433de915875c8393f0b0dc14aa155997ad0xy * This file contains some routines that take care of *
25f2d433de915875c8393f0b0dc14aa155997ad0xy * memory allocation for descriptors and buffers. *
080575042aba2197b425ebfd52061dea061a9aa1xy * *
080575042aba2197b425ebfd52061dea061a9aa1xy * **********************************************************************
080575042aba2197b425ebfd52061dea061a9aa1xy */
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy#include "e1000g_sw.h"
080575042aba2197b425ebfd52061dea061a9aa1xy#include "e1000g_debug.h"
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy#define TX_SW_PKT_AREA_SZ \
25f2d433de915875c8393f0b0dc14aa155997ad0xy (sizeof (tx_sw_packet_t) * Adapter->tx_freelist_num)
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xystatic int e1000g_alloc_tx_descriptors(e1000g_tx_ring_t *);
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystemsstatic int e1000g_alloc_rx_descriptors(e1000g_rx_data_t *);
080575042aba2197b425ebfd52061dea061a9aa1xystatic void e1000g_free_tx_descriptors(e1000g_tx_ring_t *);
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystemsstatic void e1000g_free_rx_descriptors(e1000g_rx_data_t *);
080575042aba2197b425ebfd52061dea061a9aa1xystatic int e1000g_alloc_tx_packets(e1000g_tx_ring_t *);
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystemsstatic int e1000g_alloc_rx_packets(e1000g_rx_data_t *);
080575042aba2197b425ebfd52061dea061a9aa1xystatic void e1000g_free_tx_packets(e1000g_tx_ring_t *);
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing Chinastatic void e1000g_free_rx_packets(e1000g_rx_data_t *, boolean_t);
25f2d433de915875c8393f0b0dc14aa155997ad0xystatic int e1000g_alloc_dma_buffer(struct e1000g *,
25f2d433de915875c8393f0b0dc14aa155997ad0xy dma_buffer_t *, size_t, ddi_dma_attr_t *p_dma_attr);
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China/*
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China * In order to avoid address error crossing 64KB boundary
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China * during PCI-X packets receving, e1000g_alloc_dma_buffer_82546
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China * is used by some necessary adapter types.
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China */
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing Chinastatic int e1000g_alloc_dma_buffer_82546(struct e1000g *,
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China dma_buffer_t *, size_t, ddi_dma_attr_t *p_dma_attr);
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing Chinastatic int e1000g_dma_mem_alloc_82546(dma_buffer_t *buf,
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China size_t size, size_t *len);
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing Chinastatic boolean_t e1000g_cross_64k_bound(void *, uintptr_t);
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China
080575042aba2197b425ebfd52061dea061a9aa1xystatic void e1000g_free_dma_buffer(dma_buffer_t *);
080575042aba2197b425ebfd52061dea061a9aa1xy#ifdef __sparc
080575042aba2197b425ebfd52061dea061a9aa1xystatic int e1000g_alloc_dvma_buffer(struct e1000g *, dma_buffer_t *, size_t);
080575042aba2197b425ebfd52061dea061a9aa1xystatic void e1000g_free_dvma_buffer(dma_buffer_t *);
080575042aba2197b425ebfd52061dea061a9aa1xy#endif
080575042aba2197b425ebfd52061dea061a9aa1xystatic int e1000g_alloc_descriptors(struct e1000g *Adapter);
25f2d433de915875c8393f0b0dc14aa155997ad0xystatic void e1000g_free_descriptors(struct e1000g *Adapter);
080575042aba2197b425ebfd52061dea061a9aa1xystatic int e1000g_alloc_packets(struct e1000g *Adapter);
25f2d433de915875c8393f0b0dc14aa155997ad0xystatic void e1000g_free_packets(struct e1000g *Adapter);
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystemsstatic p_rx_sw_packet_t e1000g_alloc_rx_sw_packet(e1000g_rx_data_t *,
25f2d433de915875c8393f0b0dc14aa155997ad0xy ddi_dma_attr_t *p_dma_attr);
25f2d433de915875c8393f0b0dc14aa155997ad0xy
25f2d433de915875c8393f0b0dc14aa155997ad0xy/* DMA access attributes for descriptors <Little Endian> */
25f2d433de915875c8393f0b0dc14aa155997ad0xystatic ddi_device_acc_attr_t e1000g_desc_acc_attr = {
25f2d433de915875c8393f0b0dc14aa155997ad0xy DDI_DEVICE_ATTR_V0,
25f2d433de915875c8393f0b0dc14aa155997ad0xy DDI_STRUCTURE_LE_ACC,
837c1ac4e72b7d86278cca88b1075af557f7d161Stephen Hanson DDI_STRICTORDER_ACC
25f2d433de915875c8393f0b0dc14aa155997ad0xy};
25f2d433de915875c8393f0b0dc14aa155997ad0xy
25f2d433de915875c8393f0b0dc14aa155997ad0xy/* DMA access attributes for DMA buffers */
25f2d433de915875c8393f0b0dc14aa155997ad0xy#ifdef __sparc
25f2d433de915875c8393f0b0dc14aa155997ad0xystatic ddi_device_acc_attr_t e1000g_buf_acc_attr = {
25f2d433de915875c8393f0b0dc14aa155997ad0xy DDI_DEVICE_ATTR_V0,
25f2d433de915875c8393f0b0dc14aa155997ad0xy DDI_STRUCTURE_BE_ACC,
25f2d433de915875c8393f0b0dc14aa155997ad0xy DDI_STRICTORDER_ACC,
25f2d433de915875c8393f0b0dc14aa155997ad0xy};
25f2d433de915875c8393f0b0dc14aa155997ad0xy#else
25f2d433de915875c8393f0b0dc14aa155997ad0xystatic ddi_device_acc_attr_t e1000g_buf_acc_attr = {
25f2d433de915875c8393f0b0dc14aa155997ad0xy DDI_DEVICE_ATTR_V0,
25f2d433de915875c8393f0b0dc14aa155997ad0xy DDI_STRUCTURE_LE_ACC,
25f2d433de915875c8393f0b0dc14aa155997ad0xy DDI_STRICTORDER_ACC,
25f2d433de915875c8393f0b0dc14aa155997ad0xy};
25f2d433de915875c8393f0b0dc14aa155997ad0xy#endif
25f2d433de915875c8393f0b0dc14aa155997ad0xy
25f2d433de915875c8393f0b0dc14aa155997ad0xy/* DMA attributes for tx mblk buffers */
25f2d433de915875c8393f0b0dc14aa155997ad0xystatic ddi_dma_attr_t e1000g_tx_dma_attr = {
25f2d433de915875c8393f0b0dc14aa155997ad0xy DMA_ATTR_V0, /* version of this structure */
25f2d433de915875c8393f0b0dc14aa155997ad0xy 0, /* lowest usable address */
25f2d433de915875c8393f0b0dc14aa155997ad0xy 0xffffffffffffffffULL, /* highest usable address */
25f2d433de915875c8393f0b0dc14aa155997ad0xy 0x7fffffff, /* maximum DMAable byte count */
25f2d433de915875c8393f0b0dc14aa155997ad0xy 1, /* alignment in bytes */
25f2d433de915875c8393f0b0dc14aa155997ad0xy 0x7ff, /* burst sizes (any?) */
25f2d433de915875c8393f0b0dc14aa155997ad0xy 1, /* minimum transfer */
25f2d433de915875c8393f0b0dc14aa155997ad0xy 0xffffffffU, /* maximum transfer */
25f2d433de915875c8393f0b0dc14aa155997ad0xy 0xffffffffffffffffULL, /* maximum segment length */
4d7379630d53d9992780329b674af8c85935e858xiangtao you - Sun Microsystems - Beijing China MAX_COOKIES, /* maximum number of segments */
25f2d433de915875c8393f0b0dc14aa155997ad0xy 1, /* granularity */
9b6541b318d01d0d83bfb98699a7f09e35f37951gl DDI_DMA_FLAGERR, /* dma_attr_flags */
25f2d433de915875c8393f0b0dc14aa155997ad0xy};
25f2d433de915875c8393f0b0dc14aa155997ad0xy
25f2d433de915875c8393f0b0dc14aa155997ad0xy/* DMA attributes for pre-allocated rx/tx buffers */
25f2d433de915875c8393f0b0dc14aa155997ad0xystatic ddi_dma_attr_t e1000g_buf_dma_attr = {
25f2d433de915875c8393f0b0dc14aa155997ad0xy DMA_ATTR_V0, /* version of this structure */
25f2d433de915875c8393f0b0dc14aa155997ad0xy 0, /* lowest usable address */
25f2d433de915875c8393f0b0dc14aa155997ad0xy 0xffffffffffffffffULL, /* highest usable address */
25f2d433de915875c8393f0b0dc14aa155997ad0xy 0x7fffffff, /* maximum DMAable byte count */
25f2d433de915875c8393f0b0dc14aa155997ad0xy 1, /* alignment in bytes */
25f2d433de915875c8393f0b0dc14aa155997ad0xy 0x7ff, /* burst sizes (any?) */
25f2d433de915875c8393f0b0dc14aa155997ad0xy 1, /* minimum transfer */
25f2d433de915875c8393f0b0dc14aa155997ad0xy 0xffffffffU, /* maximum transfer */
25f2d433de915875c8393f0b0dc14aa155997ad0xy 0xffffffffffffffffULL, /* maximum segment length */
25f2d433de915875c8393f0b0dc14aa155997ad0xy 1, /* maximum number of segments */
25f2d433de915875c8393f0b0dc14aa155997ad0xy 1, /* granularity */
9b6541b318d01d0d83bfb98699a7f09e35f37951gl DDI_DMA_FLAGERR, /* dma_attr_flags */
25f2d433de915875c8393f0b0dc14aa155997ad0xy};
25f2d433de915875c8393f0b0dc14aa155997ad0xy
25f2d433de915875c8393f0b0dc14aa155997ad0xy/* DMA attributes for rx/tx descriptors */
25f2d433de915875c8393f0b0dc14aa155997ad0xystatic ddi_dma_attr_t e1000g_desc_dma_attr = {
25f2d433de915875c8393f0b0dc14aa155997ad0xy DMA_ATTR_V0, /* version of this structure */
25f2d433de915875c8393f0b0dc14aa155997ad0xy 0, /* lowest usable address */
25f2d433de915875c8393f0b0dc14aa155997ad0xy 0xffffffffffffffffULL, /* highest usable address */
25f2d433de915875c8393f0b0dc14aa155997ad0xy 0x7fffffff, /* maximum DMAable byte count */
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China E1000_MDALIGN, /* default alignment is 4k but can be changed */
25f2d433de915875c8393f0b0dc14aa155997ad0xy 0x7ff, /* burst sizes (any?) */
25f2d433de915875c8393f0b0dc14aa155997ad0xy 1, /* minimum transfer */
25f2d433de915875c8393f0b0dc14aa155997ad0xy 0xffffffffU, /* maximum transfer */
25f2d433de915875c8393f0b0dc14aa155997ad0xy 0xffffffffffffffffULL, /* maximum segment length */
25f2d433de915875c8393f0b0dc14aa155997ad0xy 1, /* maximum number of segments */
25f2d433de915875c8393f0b0dc14aa155997ad0xy 1, /* granularity */
9b6541b318d01d0d83bfb98699a7f09e35f37951gl DDI_DMA_FLAGERR, /* dma_attr_flags */
25f2d433de915875c8393f0b0dc14aa155997ad0xy};
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy#ifdef __sparc
080575042aba2197b425ebfd52061dea061a9aa1xystatic ddi_dma_lim_t e1000g_dma_limits = {
080575042aba2197b425ebfd52061dea061a9aa1xy (uint_t)0, /* dlim_addr_lo */
080575042aba2197b425ebfd52061dea061a9aa1xy (uint_t)0xffffffff, /* dlim_addr_hi */
080575042aba2197b425ebfd52061dea061a9aa1xy (uint_t)0xffffffff, /* dlim_cntr_max */
080575042aba2197b425ebfd52061dea061a9aa1xy (uint_t)0xfc00fc, /* dlim_burstsizes for 32 and 64 bit xfers */
080575042aba2197b425ebfd52061dea061a9aa1xy 0x1, /* dlim_minxfer */
080575042aba2197b425ebfd52061dea061a9aa1xy 1024 /* dlim_speed */
080575042aba2197b425ebfd52061dea061a9aa1xy};
080575042aba2197b425ebfd52061dea061a9aa1xy#endif
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy#ifdef __sparc
080575042aba2197b425ebfd52061dea061a9aa1xystatic dma_type_t e1000g_dma_type = USE_DVMA;
080575042aba2197b425ebfd52061dea061a9aa1xy#else
080575042aba2197b425ebfd52061dea061a9aa1xystatic dma_type_t e1000g_dma_type = USE_DMA;
080575042aba2197b425ebfd52061dea061a9aa1xy#endif
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xyextern krwlock_t e1000g_dma_type_lock;
080575042aba2197b425ebfd52061dea061a9aa1xy
25f2d433de915875c8393f0b0dc14aa155997ad0xy
080575042aba2197b425ebfd52061dea061a9aa1xyint
080575042aba2197b425ebfd52061dea061a9aa1xye1000g_alloc_dma_resources(struct e1000g *Adapter)
080575042aba2197b425ebfd52061dea061a9aa1xy{
25f2d433de915875c8393f0b0dc14aa155997ad0xy int result;
080575042aba2197b425ebfd52061dea061a9aa1xy
25f2d433de915875c8393f0b0dc14aa155997ad0xy result = DDI_FAILURE;
080575042aba2197b425ebfd52061dea061a9aa1xy
25f2d433de915875c8393f0b0dc14aa155997ad0xy while ((result != DDI_SUCCESS) &&
25f2d433de915875c8393f0b0dc14aa155997ad0xy (Adapter->tx_desc_num >= MIN_NUM_TX_DESCRIPTOR) &&
25f2d433de915875c8393f0b0dc14aa155997ad0xy (Adapter->rx_desc_num >= MIN_NUM_RX_DESCRIPTOR) &&
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China (Adapter->tx_freelist_num >= MIN_NUM_TX_FREELIST)) {
080575042aba2197b425ebfd52061dea061a9aa1xy
25f2d433de915875c8393f0b0dc14aa155997ad0xy result = e1000g_alloc_descriptors(Adapter);
25f2d433de915875c8393f0b0dc14aa155997ad0xy
25f2d433de915875c8393f0b0dc14aa155997ad0xy if (result == DDI_SUCCESS) {
25f2d433de915875c8393f0b0dc14aa155997ad0xy result = e1000g_alloc_packets(Adapter);
25f2d433de915875c8393f0b0dc14aa155997ad0xy
25f2d433de915875c8393f0b0dc14aa155997ad0xy if (result != DDI_SUCCESS)
25f2d433de915875c8393f0b0dc14aa155997ad0xy e1000g_free_descriptors(Adapter);
25f2d433de915875c8393f0b0dc14aa155997ad0xy }
25f2d433de915875c8393f0b0dc14aa155997ad0xy
25f2d433de915875c8393f0b0dc14aa155997ad0xy /*
25f2d433de915875c8393f0b0dc14aa155997ad0xy * If the allocation fails due to resource shortage,
25f2d433de915875c8393f0b0dc14aa155997ad0xy * we'll reduce the numbers of descriptors/buffers by
25f2d433de915875c8393f0b0dc14aa155997ad0xy * half, and try the allocation again.
25f2d433de915875c8393f0b0dc14aa155997ad0xy */
25f2d433de915875c8393f0b0dc14aa155997ad0xy if (result != DDI_SUCCESS) {
25f2d433de915875c8393f0b0dc14aa155997ad0xy /*
25f2d433de915875c8393f0b0dc14aa155997ad0xy * We must ensure the number of descriptors
25f2d433de915875c8393f0b0dc14aa155997ad0xy * is always a multiple of 8.
25f2d433de915875c8393f0b0dc14aa155997ad0xy */
25f2d433de915875c8393f0b0dc14aa155997ad0xy Adapter->tx_desc_num =
25f2d433de915875c8393f0b0dc14aa155997ad0xy (Adapter->tx_desc_num >> 4) << 3;
25f2d433de915875c8393f0b0dc14aa155997ad0xy Adapter->rx_desc_num =
25f2d433de915875c8393f0b0dc14aa155997ad0xy (Adapter->rx_desc_num >> 4) << 3;
25f2d433de915875c8393f0b0dc14aa155997ad0xy
25f2d433de915875c8393f0b0dc14aa155997ad0xy Adapter->tx_freelist_num >>= 1;
25f2d433de915875c8393f0b0dc14aa155997ad0xy }
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy
25f2d433de915875c8393f0b0dc14aa155997ad0xy return (result);
080575042aba2197b425ebfd52061dea061a9aa1xy}
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy/*
25f2d433de915875c8393f0b0dc14aa155997ad0xy * e1000g_alloc_descriptors - allocate DMA buffers for descriptors
25f2d433de915875c8393f0b0dc14aa155997ad0xy *
25f2d433de915875c8393f0b0dc14aa155997ad0xy * This routine allocates neccesary DMA buffers for
25f2d433de915875c8393f0b0dc14aa155997ad0xy * Transmit Descriptor Area
25f2d433de915875c8393f0b0dc14aa155997ad0xy * Receive Descrpitor Area
080575042aba2197b425ebfd52061dea061a9aa1xy */
080575042aba2197b425ebfd52061dea061a9aa1xystatic int
080575042aba2197b425ebfd52061dea061a9aa1xye1000g_alloc_descriptors(struct e1000g *Adapter)
080575042aba2197b425ebfd52061dea061a9aa1xy{
080575042aba2197b425ebfd52061dea061a9aa1xy int result;
080575042aba2197b425ebfd52061dea061a9aa1xy e1000g_tx_ring_t *tx_ring;
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems e1000g_rx_data_t *rx_data;
080575042aba2197b425ebfd52061dea061a9aa1xy
3d15c084da89e6f689f1804f3e2e600e5376c4e1chenlu chen - Sun Microsystems - Beijing China if (Adapter->mem_workaround_82546 &&
3d15c084da89e6f689f1804f3e2e600e5376c4e1chenlu chen - Sun Microsystems - Beijing China ((Adapter->shared.mac.type == e1000_82545) ||
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China (Adapter->shared.mac.type == e1000_82546) ||
3d15c084da89e6f689f1804f3e2e600e5376c4e1chenlu chen - Sun Microsystems - Beijing China (Adapter->shared.mac.type == e1000_82546_rev_3))) {
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China /* Align on a 64k boundary for these adapter types */
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China Adapter->desc_align = E1000_MDALIGN_82546;
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China } else {
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China /* Align on a 4k boundary for all other adapter types */
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China Adapter->desc_align = E1000_MDALIGN;
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China }
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China
080575042aba2197b425ebfd52061dea061a9aa1xy tx_ring = Adapter->tx_ring;
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy result = e1000g_alloc_tx_descriptors(tx_ring);
080575042aba2197b425ebfd52061dea061a9aa1xy if (result != DDI_SUCCESS)
080575042aba2197b425ebfd52061dea061a9aa1xy return (DDI_FAILURE);
080575042aba2197b425ebfd52061dea061a9aa1xy
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems rx_data = Adapter->rx_ring->rx_data;
080575042aba2197b425ebfd52061dea061a9aa1xy
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems result = e1000g_alloc_rx_descriptors(rx_data);
080575042aba2197b425ebfd52061dea061a9aa1xy if (result != DDI_SUCCESS) {
080575042aba2197b425ebfd52061dea061a9aa1xy e1000g_free_tx_descriptors(tx_ring);
080575042aba2197b425ebfd52061dea061a9aa1xy return (DDI_FAILURE);
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy return (DDI_SUCCESS);
080575042aba2197b425ebfd52061dea061a9aa1xy}
080575042aba2197b425ebfd52061dea061a9aa1xy
25f2d433de915875c8393f0b0dc14aa155997ad0xystatic void
25f2d433de915875c8393f0b0dc14aa155997ad0xye1000g_free_descriptors(struct e1000g *Adapter)
25f2d433de915875c8393f0b0dc14aa155997ad0xy{
25f2d433de915875c8393f0b0dc14aa155997ad0xy e1000g_tx_ring_t *tx_ring;
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems e1000g_rx_data_t *rx_data;
25f2d433de915875c8393f0b0dc14aa155997ad0xy
25f2d433de915875c8393f0b0dc14aa155997ad0xy tx_ring = Adapter->tx_ring;
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems rx_data = Adapter->rx_ring->rx_data;
25f2d433de915875c8393f0b0dc14aa155997ad0xy
25f2d433de915875c8393f0b0dc14aa155997ad0xy e1000g_free_tx_descriptors(tx_ring);
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems e1000g_free_rx_descriptors(rx_data);
25f2d433de915875c8393f0b0dc14aa155997ad0xy}
25f2d433de915875c8393f0b0dc14aa155997ad0xy
080575042aba2197b425ebfd52061dea061a9aa1xystatic int
080575042aba2197b425ebfd52061dea061a9aa1xye1000g_alloc_tx_descriptors(e1000g_tx_ring_t *tx_ring)
080575042aba2197b425ebfd52061dea061a9aa1xy{
080575042aba2197b425ebfd52061dea061a9aa1xy int mystat;
080575042aba2197b425ebfd52061dea061a9aa1xy boolean_t alloc_flag;
080575042aba2197b425ebfd52061dea061a9aa1xy size_t size;
080575042aba2197b425ebfd52061dea061a9aa1xy size_t len;
080575042aba2197b425ebfd52061dea061a9aa1xy uintptr_t templong;
080575042aba2197b425ebfd52061dea061a9aa1xy uint_t cookie_count;
080575042aba2197b425ebfd52061dea061a9aa1xy dev_info_t *devinfo;
080575042aba2197b425ebfd52061dea061a9aa1xy ddi_dma_cookie_t cookie;
080575042aba2197b425ebfd52061dea061a9aa1xy struct e1000g *Adapter;
25f2d433de915875c8393f0b0dc14aa155997ad0xy ddi_dma_attr_t dma_attr;
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy Adapter = tx_ring->adapter;
25f2d433de915875c8393f0b0dc14aa155997ad0xy devinfo = Adapter->dip;
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy alloc_flag = B_FALSE;
25f2d433de915875c8393f0b0dc14aa155997ad0xy dma_attr = e1000g_desc_dma_attr;
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy /*
080575042aba2197b425ebfd52061dea061a9aa1xy * Solaris 7 has a problem with allocating physically contiguous memory
080575042aba2197b425ebfd52061dea061a9aa1xy * that is aligned on a 4K boundary. The transmit and rx descriptors
080575042aba2197b425ebfd52061dea061a9aa1xy * need to aligned on a 4kbyte boundary. We first try to allocate the
080575042aba2197b425ebfd52061dea061a9aa1xy * memory with DMA attributes set to 4K alignment and also no scatter/
080575042aba2197b425ebfd52061dea061a9aa1xy * gather mechanism specified. In most cases, this does not allocate
080575042aba2197b425ebfd52061dea061a9aa1xy * memory aligned at a 4Kbyte boundary. We then try asking for memory
080575042aba2197b425ebfd52061dea061a9aa1xy * aligned on 4K boundary with scatter/gather set to 2. This works when
080575042aba2197b425ebfd52061dea061a9aa1xy * the amount of memory is less than 4k i.e a page size. If neither of
080575042aba2197b425ebfd52061dea061a9aa1xy * these options work or if the number of descriptors is greater than
080575042aba2197b425ebfd52061dea061a9aa1xy * 4K, ie more than 256 descriptors, we allocate 4k extra memory and
080575042aba2197b425ebfd52061dea061a9aa1xy * and then align the memory at a 4k boundary.
080575042aba2197b425ebfd52061dea061a9aa1xy */
25f2d433de915875c8393f0b0dc14aa155997ad0xy size = sizeof (struct e1000_tx_desc) * Adapter->tx_desc_num;
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy /*
080575042aba2197b425ebfd52061dea061a9aa1xy * Memory allocation for the transmit buffer descriptors.
080575042aba2197b425ebfd52061dea061a9aa1xy */
25f2d433de915875c8393f0b0dc14aa155997ad0xy dma_attr.dma_attr_sgllen = 1;
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China dma_attr.dma_attr_align = Adapter->desc_align;
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy /*
080575042aba2197b425ebfd52061dea061a9aa1xy * Allocate a new DMA handle for the transmit descriptor
080575042aba2197b425ebfd52061dea061a9aa1xy * memory area.
080575042aba2197b425ebfd52061dea061a9aa1xy */
25f2d433de915875c8393f0b0dc14aa155997ad0xy mystat = ddi_dma_alloc_handle(devinfo, &dma_attr,
080575042aba2197b425ebfd52061dea061a9aa1xy DDI_DMA_DONTWAIT, 0,
080575042aba2197b425ebfd52061dea061a9aa1xy &tx_ring->tbd_dma_handle);
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy if (mystat != DDI_SUCCESS) {
25f2d433de915875c8393f0b0dc14aa155997ad0xy E1000G_DEBUGLOG_1(Adapter, E1000G_WARN_LEVEL,
080575042aba2197b425ebfd52061dea061a9aa1xy "Could not allocate tbd dma handle: %d", mystat);
080575042aba2197b425ebfd52061dea061a9aa1xy tx_ring->tbd_dma_handle = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy return (DDI_FAILURE);
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy /*
080575042aba2197b425ebfd52061dea061a9aa1xy * Allocate memory to DMA data to and from the transmit
080575042aba2197b425ebfd52061dea061a9aa1xy * descriptors.
080575042aba2197b425ebfd52061dea061a9aa1xy */
080575042aba2197b425ebfd52061dea061a9aa1xy mystat = ddi_dma_mem_alloc(tx_ring->tbd_dma_handle,
080575042aba2197b425ebfd52061dea061a9aa1xy size,
25f2d433de915875c8393f0b0dc14aa155997ad0xy &e1000g_desc_acc_attr, DDI_DMA_CONSISTENT,
080575042aba2197b425ebfd52061dea061a9aa1xy DDI_DMA_DONTWAIT, 0,
080575042aba2197b425ebfd52061dea061a9aa1xy (caddr_t *)&tx_ring->tbd_area,
080575042aba2197b425ebfd52061dea061a9aa1xy &len, &tx_ring->tbd_acc_handle);
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy if ((mystat != DDI_SUCCESS) ||
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China ((uintptr_t)tx_ring->tbd_area & (Adapter->desc_align - 1))) {
080575042aba2197b425ebfd52061dea061a9aa1xy if (mystat == DDI_SUCCESS) {
080575042aba2197b425ebfd52061dea061a9aa1xy ddi_dma_mem_free(&tx_ring->tbd_acc_handle);
080575042aba2197b425ebfd52061dea061a9aa1xy tx_ring->tbd_acc_handle = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy tx_ring->tbd_area = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy if (tx_ring->tbd_dma_handle != NULL) {
080575042aba2197b425ebfd52061dea061a9aa1xy ddi_dma_free_handle(&tx_ring->tbd_dma_handle);
080575042aba2197b425ebfd52061dea061a9aa1xy tx_ring->tbd_dma_handle = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy alloc_flag = B_FALSE;
080575042aba2197b425ebfd52061dea061a9aa1xy } else
080575042aba2197b425ebfd52061dea061a9aa1xy alloc_flag = B_TRUE;
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy /*
080575042aba2197b425ebfd52061dea061a9aa1xy * Initialize the entire transmit buffer descriptor area to zero
080575042aba2197b425ebfd52061dea061a9aa1xy */
080575042aba2197b425ebfd52061dea061a9aa1xy if (alloc_flag)
080575042aba2197b425ebfd52061dea061a9aa1xy bzero(tx_ring->tbd_area, len);
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy /*
080575042aba2197b425ebfd52061dea061a9aa1xy * If the previous DMA attributes setting could not give us contiguous
080575042aba2197b425ebfd52061dea061a9aa1xy * memory or the number of descriptors is greater than the page size,
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China * we allocate extra memory and then align it at appropriate boundary.
080575042aba2197b425ebfd52061dea061a9aa1xy */
080575042aba2197b425ebfd52061dea061a9aa1xy if (!alloc_flag) {
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China size = size + Adapter->desc_align;
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy /*
080575042aba2197b425ebfd52061dea061a9aa1xy * DMA attributes set to no scatter/gather and 16 bit alignment
080575042aba2197b425ebfd52061dea061a9aa1xy */
25f2d433de915875c8393f0b0dc14aa155997ad0xy dma_attr.dma_attr_align = 1;
25f2d433de915875c8393f0b0dc14aa155997ad0xy dma_attr.dma_attr_sgllen = 1;
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy /*
080575042aba2197b425ebfd52061dea061a9aa1xy * Allocate a new DMA handle for the transmit descriptor memory
080575042aba2197b425ebfd52061dea061a9aa1xy * area.
080575042aba2197b425ebfd52061dea061a9aa1xy */
25f2d433de915875c8393f0b0dc14aa155997ad0xy mystat = ddi_dma_alloc_handle(devinfo, &dma_attr,
080575042aba2197b425ebfd52061dea061a9aa1xy DDI_DMA_DONTWAIT, 0,
080575042aba2197b425ebfd52061dea061a9aa1xy &tx_ring->tbd_dma_handle);
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy if (mystat != DDI_SUCCESS) {
25f2d433de915875c8393f0b0dc14aa155997ad0xy E1000G_DEBUGLOG_1(Adapter, E1000G_WARN_LEVEL,
080575042aba2197b425ebfd52061dea061a9aa1xy "Could not re-allocate tbd dma handle: %d", mystat);
080575042aba2197b425ebfd52061dea061a9aa1xy tx_ring->tbd_dma_handle = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy return (DDI_FAILURE);
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy /*
080575042aba2197b425ebfd52061dea061a9aa1xy * Allocate memory to DMA data to and from the transmit
080575042aba2197b425ebfd52061dea061a9aa1xy * descriptors.
080575042aba2197b425ebfd52061dea061a9aa1xy */
080575042aba2197b425ebfd52061dea061a9aa1xy mystat = ddi_dma_mem_alloc(tx_ring->tbd_dma_handle,
080575042aba2197b425ebfd52061dea061a9aa1xy size,
25f2d433de915875c8393f0b0dc14aa155997ad0xy &e1000g_desc_acc_attr, DDI_DMA_CONSISTENT,
080575042aba2197b425ebfd52061dea061a9aa1xy DDI_DMA_DONTWAIT, 0,
080575042aba2197b425ebfd52061dea061a9aa1xy (caddr_t *)&tx_ring->tbd_area,
080575042aba2197b425ebfd52061dea061a9aa1xy &len, &tx_ring->tbd_acc_handle);
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy if (mystat != DDI_SUCCESS) {
25f2d433de915875c8393f0b0dc14aa155997ad0xy E1000G_DEBUGLOG_1(Adapter, E1000G_WARN_LEVEL,
080575042aba2197b425ebfd52061dea061a9aa1xy "Could not allocate tbd dma memory: %d", mystat);
080575042aba2197b425ebfd52061dea061a9aa1xy tx_ring->tbd_acc_handle = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy tx_ring->tbd_area = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy if (tx_ring->tbd_dma_handle != NULL) {
080575042aba2197b425ebfd52061dea061a9aa1xy ddi_dma_free_handle(&tx_ring->tbd_dma_handle);
080575042aba2197b425ebfd52061dea061a9aa1xy tx_ring->tbd_dma_handle = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy return (DDI_FAILURE);
080575042aba2197b425ebfd52061dea061a9aa1xy } else
080575042aba2197b425ebfd52061dea061a9aa1xy alloc_flag = B_TRUE;
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy /*
080575042aba2197b425ebfd52061dea061a9aa1xy * Initialize the entire transmit buffer descriptor area to zero
080575042aba2197b425ebfd52061dea061a9aa1xy */
080575042aba2197b425ebfd52061dea061a9aa1xy bzero(tx_ring->tbd_area, len);
080575042aba2197b425ebfd52061dea061a9aa1xy /*
080575042aba2197b425ebfd52061dea061a9aa1xy * Memory has been allocated with the ddi_dma_mem_alloc call,
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China * but has not been aligned.
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China * We now align it on the appropriate boundary.
080575042aba2197b425ebfd52061dea061a9aa1xy */
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China templong = P2NPHASE((uintptr_t)tx_ring->tbd_area,
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China Adapter->desc_align);
080575042aba2197b425ebfd52061dea061a9aa1xy len = size - templong;
080575042aba2197b425ebfd52061dea061a9aa1xy templong += (uintptr_t)tx_ring->tbd_area;
080575042aba2197b425ebfd52061dea061a9aa1xy tx_ring->tbd_area = (struct e1000_tx_desc *)templong;
080575042aba2197b425ebfd52061dea061a9aa1xy } /* alignment workaround */
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy /*
080575042aba2197b425ebfd52061dea061a9aa1xy * Transmit buffer descriptor memory allocation succeeded
080575042aba2197b425ebfd52061dea061a9aa1xy */
080575042aba2197b425ebfd52061dea061a9aa1xy ASSERT(alloc_flag);
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy /*
080575042aba2197b425ebfd52061dea061a9aa1xy * Allocates DMA resources for the memory that was allocated by
080575042aba2197b425ebfd52061dea061a9aa1xy * the ddi_dma_mem_alloc call. The DMA resources then get bound to the
080575042aba2197b425ebfd52061dea061a9aa1xy * the memory address
080575042aba2197b425ebfd52061dea061a9aa1xy */
080575042aba2197b425ebfd52061dea061a9aa1xy mystat = ddi_dma_addr_bind_handle(tx_ring->tbd_dma_handle,
080575042aba2197b425ebfd52061dea061a9aa1xy (struct as *)NULL, (caddr_t)tx_ring->tbd_area,
080575042aba2197b425ebfd52061dea061a9aa1xy len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
25f2d433de915875c8393f0b0dc14aa155997ad0xy DDI_DMA_DONTWAIT, 0, &cookie, &cookie_count);
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy if (mystat != DDI_SUCCESS) {
25f2d433de915875c8393f0b0dc14aa155997ad0xy E1000G_DEBUGLOG_1(Adapter, E1000G_WARN_LEVEL,
080575042aba2197b425ebfd52061dea061a9aa1xy "Could not bind tbd dma resource: %d", mystat);
080575042aba2197b425ebfd52061dea061a9aa1xy if (tx_ring->tbd_acc_handle != NULL) {
080575042aba2197b425ebfd52061dea061a9aa1xy ddi_dma_mem_free(&tx_ring->tbd_acc_handle);
080575042aba2197b425ebfd52061dea061a9aa1xy tx_ring->tbd_acc_handle = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy tx_ring->tbd_area = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy if (tx_ring->tbd_dma_handle != NULL) {
080575042aba2197b425ebfd52061dea061a9aa1xy ddi_dma_free_handle(&tx_ring->tbd_dma_handle);
080575042aba2197b425ebfd52061dea061a9aa1xy tx_ring->tbd_dma_handle = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy return (DDI_FAILURE);
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy ASSERT(cookie_count == 1); /* 1 cookie */
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy if (cookie_count != 1) {
25f2d433de915875c8393f0b0dc14aa155997ad0xy E1000G_DEBUGLOG_2(Adapter, E1000G_WARN_LEVEL,
080575042aba2197b425ebfd52061dea061a9aa1xy "Could not bind tbd dma resource in a single frag. "
080575042aba2197b425ebfd52061dea061a9aa1xy "Count - %d Len - %d", cookie_count, len);
080575042aba2197b425ebfd52061dea061a9aa1xy e1000g_free_tx_descriptors(tx_ring);
080575042aba2197b425ebfd52061dea061a9aa1xy return (DDI_FAILURE);
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy tx_ring->tbd_dma_addr = cookie.dmac_laddress;
080575042aba2197b425ebfd52061dea061a9aa1xy tx_ring->tbd_first = tx_ring->tbd_area;
080575042aba2197b425ebfd52061dea061a9aa1xy tx_ring->tbd_last = tx_ring->tbd_first +
25f2d433de915875c8393f0b0dc14aa155997ad0xy (Adapter->tx_desc_num - 1);
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy return (DDI_SUCCESS);
080575042aba2197b425ebfd52061dea061a9aa1xy}
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xystatic int
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystemse1000g_alloc_rx_descriptors(e1000g_rx_data_t *rx_data)
080575042aba2197b425ebfd52061dea061a9aa1xy{
080575042aba2197b425ebfd52061dea061a9aa1xy int mystat;
080575042aba2197b425ebfd52061dea061a9aa1xy boolean_t alloc_flag;
080575042aba2197b425ebfd52061dea061a9aa1xy size_t size;
080575042aba2197b425ebfd52061dea061a9aa1xy size_t len;
080575042aba2197b425ebfd52061dea061a9aa1xy uintptr_t templong;
080575042aba2197b425ebfd52061dea061a9aa1xy uint_t cookie_count;
080575042aba2197b425ebfd52061dea061a9aa1xy dev_info_t *devinfo;
080575042aba2197b425ebfd52061dea061a9aa1xy ddi_dma_cookie_t cookie;
080575042aba2197b425ebfd52061dea061a9aa1xy struct e1000g *Adapter;
25f2d433de915875c8393f0b0dc14aa155997ad0xy ddi_dma_attr_t dma_attr;
080575042aba2197b425ebfd52061dea061a9aa1xy
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems Adapter = rx_data->rx_ring->adapter;
25f2d433de915875c8393f0b0dc14aa155997ad0xy devinfo = Adapter->dip;
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy alloc_flag = B_FALSE;
25f2d433de915875c8393f0b0dc14aa155997ad0xy dma_attr = e1000g_desc_dma_attr;
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy /*
080575042aba2197b425ebfd52061dea061a9aa1xy * Memory allocation for the receive buffer descriptors.
080575042aba2197b425ebfd52061dea061a9aa1xy */
25f2d433de915875c8393f0b0dc14aa155997ad0xy size = (sizeof (struct e1000_rx_desc)) * Adapter->rx_desc_num;
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy /*
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China * Asking for aligned memory with DMA attributes set for suitable value
080575042aba2197b425ebfd52061dea061a9aa1xy */
25f2d433de915875c8393f0b0dc14aa155997ad0xy dma_attr.dma_attr_sgllen = 1;
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China dma_attr.dma_attr_align = Adapter->desc_align;
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy /*
25f2d433de915875c8393f0b0dc14aa155997ad0xy * Allocate a new DMA handle for the receive descriptors
080575042aba2197b425ebfd52061dea061a9aa1xy */
25f2d433de915875c8393f0b0dc14aa155997ad0xy mystat = ddi_dma_alloc_handle(devinfo, &dma_attr,
080575042aba2197b425ebfd52061dea061a9aa1xy DDI_DMA_DONTWAIT, 0,
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems &rx_data->rbd_dma_handle);
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy if (mystat != DDI_SUCCESS) {
25f2d433de915875c8393f0b0dc14aa155997ad0xy E1000G_DEBUGLOG_1(Adapter, E1000G_WARN_LEVEL,
080575042aba2197b425ebfd52061dea061a9aa1xy "Could not allocate rbd dma handle: %d", mystat);
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems rx_data->rbd_dma_handle = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy return (DDI_FAILURE);
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy /*
080575042aba2197b425ebfd52061dea061a9aa1xy * Allocate memory to DMA data to and from the receive
080575042aba2197b425ebfd52061dea061a9aa1xy * descriptors.
080575042aba2197b425ebfd52061dea061a9aa1xy */
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems mystat = ddi_dma_mem_alloc(rx_data->rbd_dma_handle,
080575042aba2197b425ebfd52061dea061a9aa1xy size,
25f2d433de915875c8393f0b0dc14aa155997ad0xy &e1000g_desc_acc_attr, DDI_DMA_CONSISTENT,
080575042aba2197b425ebfd52061dea061a9aa1xy DDI_DMA_DONTWAIT, 0,
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems (caddr_t *)&rx_data->rbd_area,
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems &len, &rx_data->rbd_acc_handle);
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy /*
080575042aba2197b425ebfd52061dea061a9aa1xy * Check if memory allocation succeeded and also if the
080575042aba2197b425ebfd52061dea061a9aa1xy * allocated memory is aligned correctly.
080575042aba2197b425ebfd52061dea061a9aa1xy */
080575042aba2197b425ebfd52061dea061a9aa1xy if ((mystat != DDI_SUCCESS) ||
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems ((uintptr_t)rx_data->rbd_area & (Adapter->desc_align - 1))) {
080575042aba2197b425ebfd52061dea061a9aa1xy if (mystat == DDI_SUCCESS) {
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems ddi_dma_mem_free(&rx_data->rbd_acc_handle);
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems rx_data->rbd_acc_handle = NULL;
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems rx_data->rbd_area = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy }
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems if (rx_data->rbd_dma_handle != NULL) {
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems ddi_dma_free_handle(&rx_data->rbd_dma_handle);
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems rx_data->rbd_dma_handle = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy alloc_flag = B_FALSE;
080575042aba2197b425ebfd52061dea061a9aa1xy } else
080575042aba2197b425ebfd52061dea061a9aa1xy alloc_flag = B_TRUE;
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy /*
080575042aba2197b425ebfd52061dea061a9aa1xy * Initialize the allocated receive descriptor memory to zero.
080575042aba2197b425ebfd52061dea061a9aa1xy */
080575042aba2197b425ebfd52061dea061a9aa1xy if (alloc_flag)
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems bzero((caddr_t)rx_data->rbd_area, len);
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy /*
25f2d433de915875c8393f0b0dc14aa155997ad0xy * If memory allocation did not succeed, do the alignment ourselves
080575042aba2197b425ebfd52061dea061a9aa1xy */
080575042aba2197b425ebfd52061dea061a9aa1xy if (!alloc_flag) {
25f2d433de915875c8393f0b0dc14aa155997ad0xy dma_attr.dma_attr_align = 1;
25f2d433de915875c8393f0b0dc14aa155997ad0xy dma_attr.dma_attr_sgllen = 1;
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China size = size + Adapter->desc_align;
080575042aba2197b425ebfd52061dea061a9aa1xy /*
25f2d433de915875c8393f0b0dc14aa155997ad0xy * Allocate a new DMA handle for the receive descriptor.
080575042aba2197b425ebfd52061dea061a9aa1xy */
25f2d433de915875c8393f0b0dc14aa155997ad0xy mystat = ddi_dma_alloc_handle(devinfo, &dma_attr,
080575042aba2197b425ebfd52061dea061a9aa1xy DDI_DMA_DONTWAIT, 0,
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems &rx_data->rbd_dma_handle);
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy if (mystat != DDI_SUCCESS) {
25f2d433de915875c8393f0b0dc14aa155997ad0xy E1000G_DEBUGLOG_1(Adapter, E1000G_WARN_LEVEL,
080575042aba2197b425ebfd52061dea061a9aa1xy "Could not re-allocate rbd dma handle: %d", mystat);
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems rx_data->rbd_dma_handle = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy return (DDI_FAILURE);
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy /*
080575042aba2197b425ebfd52061dea061a9aa1xy * Allocate memory to DMA data to and from the receive
080575042aba2197b425ebfd52061dea061a9aa1xy * descriptors.
080575042aba2197b425ebfd52061dea061a9aa1xy */
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems mystat = ddi_dma_mem_alloc(rx_data->rbd_dma_handle,
080575042aba2197b425ebfd52061dea061a9aa1xy size,
25f2d433de915875c8393f0b0dc14aa155997ad0xy &e1000g_desc_acc_attr, DDI_DMA_CONSISTENT,
080575042aba2197b425ebfd52061dea061a9aa1xy DDI_DMA_DONTWAIT, 0,
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems (caddr_t *)&rx_data->rbd_area,
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems &len, &rx_data->rbd_acc_handle);
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy if (mystat != DDI_SUCCESS) {
25f2d433de915875c8393f0b0dc14aa155997ad0xy E1000G_DEBUGLOG_1(Adapter, E1000G_WARN_LEVEL,
080575042aba2197b425ebfd52061dea061a9aa1xy "Could not allocate rbd dma memory: %d", mystat);
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems rx_data->rbd_acc_handle = NULL;
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems rx_data->rbd_area = NULL;
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems if (rx_data->rbd_dma_handle != NULL) {
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems ddi_dma_free_handle(&rx_data->rbd_dma_handle);
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems rx_data->rbd_dma_handle = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy return (DDI_FAILURE);
080575042aba2197b425ebfd52061dea061a9aa1xy } else
080575042aba2197b425ebfd52061dea061a9aa1xy alloc_flag = B_TRUE;
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy /*
080575042aba2197b425ebfd52061dea061a9aa1xy * Initialize the allocated receive descriptor memory to zero.
080575042aba2197b425ebfd52061dea061a9aa1xy */
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems bzero((caddr_t)rx_data->rbd_area, len);
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems templong = P2NPHASE((uintptr_t)rx_data->rbd_area,
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China Adapter->desc_align);
080575042aba2197b425ebfd52061dea061a9aa1xy len = size - templong;
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems templong += (uintptr_t)rx_data->rbd_area;
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems rx_data->rbd_area = (struct e1000_rx_desc *)templong;
080575042aba2197b425ebfd52061dea061a9aa1xy } /* alignment workaround */
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy /*
080575042aba2197b425ebfd52061dea061a9aa1xy * The memory allocation of the receive descriptors succeeded
080575042aba2197b425ebfd52061dea061a9aa1xy */
080575042aba2197b425ebfd52061dea061a9aa1xy ASSERT(alloc_flag);
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy /*
080575042aba2197b425ebfd52061dea061a9aa1xy * Allocates DMA resources for the memory that was allocated by
080575042aba2197b425ebfd52061dea061a9aa1xy * the ddi_dma_mem_alloc call.
080575042aba2197b425ebfd52061dea061a9aa1xy */
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems mystat = ddi_dma_addr_bind_handle(rx_data->rbd_dma_handle,
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems (struct as *)NULL, (caddr_t)rx_data->rbd_area,
0f70fbf80d71251e7928b3122fb4848c2f92a5c6xy len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
25f2d433de915875c8393f0b0dc14aa155997ad0xy DDI_DMA_DONTWAIT, 0, &cookie, &cookie_count);
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy if (mystat != DDI_SUCCESS) {
25f2d433de915875c8393f0b0dc14aa155997ad0xy E1000G_DEBUGLOG_1(Adapter, E1000G_WARN_LEVEL,
080575042aba2197b425ebfd52061dea061a9aa1xy "Could not bind rbd dma resource: %d", mystat);
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems if (rx_data->rbd_acc_handle != NULL) {
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems ddi_dma_mem_free(&rx_data->rbd_acc_handle);
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems rx_data->rbd_acc_handle = NULL;
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems rx_data->rbd_area = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy }
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems if (rx_data->rbd_dma_handle != NULL) {
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems ddi_dma_free_handle(&rx_data->rbd_dma_handle);
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems rx_data->rbd_dma_handle = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy return (DDI_FAILURE);
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy ASSERT(cookie_count == 1);
080575042aba2197b425ebfd52061dea061a9aa1xy if (cookie_count != 1) {
25f2d433de915875c8393f0b0dc14aa155997ad0xy E1000G_DEBUGLOG_2(Adapter, E1000G_WARN_LEVEL,
080575042aba2197b425ebfd52061dea061a9aa1xy "Could not bind rbd dma resource in a single frag. "
080575042aba2197b425ebfd52061dea061a9aa1xy "Count - %d Len - %d", cookie_count, len);
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems e1000g_free_rx_descriptors(rx_data);
080575042aba2197b425ebfd52061dea061a9aa1xy return (DDI_FAILURE);
080575042aba2197b425ebfd52061dea061a9aa1xy }
25f2d433de915875c8393f0b0dc14aa155997ad0xy
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems rx_data->rbd_dma_addr = cookie.dmac_laddress;
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems rx_data->rbd_first = rx_data->rbd_area;
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems rx_data->rbd_last = rx_data->rbd_first +
25f2d433de915875c8393f0b0dc14aa155997ad0xy (Adapter->rx_desc_num - 1);
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy return (DDI_SUCCESS);
080575042aba2197b425ebfd52061dea061a9aa1xy}
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xystatic void
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystemse1000g_free_rx_descriptors(e1000g_rx_data_t *rx_data)
080575042aba2197b425ebfd52061dea061a9aa1xy{
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems if (rx_data->rbd_dma_handle != NULL) {
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems (void) ddi_dma_unbind_handle(rx_data->rbd_dma_handle);
080575042aba2197b425ebfd52061dea061a9aa1xy }
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems if (rx_data->rbd_acc_handle != NULL) {
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems ddi_dma_mem_free(&rx_data->rbd_acc_handle);
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems rx_data->rbd_acc_handle = NULL;
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems rx_data->rbd_area = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy }
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems if (rx_data->rbd_dma_handle != NULL) {
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems ddi_dma_free_handle(&rx_data->rbd_dma_handle);
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems rx_data->rbd_dma_handle = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy }
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems rx_data->rbd_dma_addr = NULL;
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems rx_data->rbd_first = NULL;
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems rx_data->rbd_last = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy}
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xystatic void
080575042aba2197b425ebfd52061dea061a9aa1xye1000g_free_tx_descriptors(e1000g_tx_ring_t *tx_ring)
080575042aba2197b425ebfd52061dea061a9aa1xy{
080575042aba2197b425ebfd52061dea061a9aa1xy if (tx_ring->tbd_dma_handle != NULL) {
fe62dec3a38f1f79ffe68417df75dbbb58135bb7Chen-Liang Xu (void) ddi_dma_unbind_handle(tx_ring->tbd_dma_handle);
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy if (tx_ring->tbd_acc_handle != NULL) {
080575042aba2197b425ebfd52061dea061a9aa1xy ddi_dma_mem_free(&tx_ring->tbd_acc_handle);
080575042aba2197b425ebfd52061dea061a9aa1xy tx_ring->tbd_acc_handle = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy tx_ring->tbd_area = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy if (tx_ring->tbd_dma_handle != NULL) {
080575042aba2197b425ebfd52061dea061a9aa1xy ddi_dma_free_handle(&tx_ring->tbd_dma_handle);
080575042aba2197b425ebfd52061dea061a9aa1xy tx_ring->tbd_dma_handle = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy tx_ring->tbd_dma_addr = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy tx_ring->tbd_first = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy tx_ring->tbd_last = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy}
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy/*
25f2d433de915875c8393f0b0dc14aa155997ad0xy * e1000g_alloc_packets - allocate DMA buffers for rx/tx
25f2d433de915875c8393f0b0dc14aa155997ad0xy *
25f2d433de915875c8393f0b0dc14aa155997ad0xy * This routine allocates neccesary buffers for
25f2d433de915875c8393f0b0dc14aa155997ad0xy * Transmit sw packet structure
25f2d433de915875c8393f0b0dc14aa155997ad0xy * DMA handle for Transmit
25f2d433de915875c8393f0b0dc14aa155997ad0xy * DMA buffer for Transmit
25f2d433de915875c8393f0b0dc14aa155997ad0xy * Receive sw packet structure
25f2d433de915875c8393f0b0dc14aa155997ad0xy * DMA buffer for Receive
080575042aba2197b425ebfd52061dea061a9aa1xy */
080575042aba2197b425ebfd52061dea061a9aa1xystatic int
080575042aba2197b425ebfd52061dea061a9aa1xye1000g_alloc_packets(struct e1000g *Adapter)
080575042aba2197b425ebfd52061dea061a9aa1xy{
080575042aba2197b425ebfd52061dea061a9aa1xy int result;
080575042aba2197b425ebfd52061dea061a9aa1xy e1000g_tx_ring_t *tx_ring;
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems e1000g_rx_data_t *rx_data;
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy tx_ring = Adapter->tx_ring;
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems rx_data = Adapter->rx_ring->rx_data;
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xyagain:
080575042aba2197b425ebfd52061dea061a9aa1xy rw_enter(&e1000g_dma_type_lock, RW_READER);
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy result = e1000g_alloc_tx_packets(tx_ring);
080575042aba2197b425ebfd52061dea061a9aa1xy if (result != DDI_SUCCESS) {
080575042aba2197b425ebfd52061dea061a9aa1xy if (e1000g_dma_type == USE_DVMA) {
080575042aba2197b425ebfd52061dea061a9aa1xy rw_exit(&e1000g_dma_type_lock);
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy rw_enter(&e1000g_dma_type_lock, RW_WRITER);
080575042aba2197b425ebfd52061dea061a9aa1xy e1000g_dma_type = USE_DMA;
080575042aba2197b425ebfd52061dea061a9aa1xy rw_exit(&e1000g_dma_type_lock);
080575042aba2197b425ebfd52061dea061a9aa1xy
25f2d433de915875c8393f0b0dc14aa155997ad0xy E1000G_DEBUGLOG_0(Adapter, E1000G_INFO_LEVEL,
080575042aba2197b425ebfd52061dea061a9aa1xy "No enough dvma resource for Tx packets, "
080575042aba2197b425ebfd52061dea061a9aa1xy "trying to allocate dma buffers...\n");
080575042aba2197b425ebfd52061dea061a9aa1xy goto again;
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy rw_exit(&e1000g_dma_type_lock);
080575042aba2197b425ebfd52061dea061a9aa1xy
25f2d433de915875c8393f0b0dc14aa155997ad0xy E1000G_DEBUGLOG_0(Adapter, E1000G_WARN_LEVEL,
080575042aba2197b425ebfd52061dea061a9aa1xy "Failed to allocate dma buffers for Tx packets\n");
080575042aba2197b425ebfd52061dea061a9aa1xy return (DDI_FAILURE);
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems result = e1000g_alloc_rx_packets(rx_data);
080575042aba2197b425ebfd52061dea061a9aa1xy if (result != DDI_SUCCESS) {
080575042aba2197b425ebfd52061dea061a9aa1xy e1000g_free_tx_packets(tx_ring);
080575042aba2197b425ebfd52061dea061a9aa1xy if (e1000g_dma_type == USE_DVMA) {
080575042aba2197b425ebfd52061dea061a9aa1xy rw_exit(&e1000g_dma_type_lock);
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy rw_enter(&e1000g_dma_type_lock, RW_WRITER);
080575042aba2197b425ebfd52061dea061a9aa1xy e1000g_dma_type = USE_DMA;
080575042aba2197b425ebfd52061dea061a9aa1xy rw_exit(&e1000g_dma_type_lock);
080575042aba2197b425ebfd52061dea061a9aa1xy
25f2d433de915875c8393f0b0dc14aa155997ad0xy E1000G_DEBUGLOG_0(Adapter, E1000G_INFO_LEVEL,
080575042aba2197b425ebfd52061dea061a9aa1xy "No enough dvma resource for Rx packets, "
080575042aba2197b425ebfd52061dea061a9aa1xy "trying to allocate dma buffers...\n");
080575042aba2197b425ebfd52061dea061a9aa1xy goto again;
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy rw_exit(&e1000g_dma_type_lock);
080575042aba2197b425ebfd52061dea061a9aa1xy
25f2d433de915875c8393f0b0dc14aa155997ad0xy E1000G_DEBUGLOG_0(Adapter, E1000G_WARN_LEVEL,
080575042aba2197b425ebfd52061dea061a9aa1xy "Failed to allocate dma buffers for Rx packets\n");
080575042aba2197b425ebfd52061dea061a9aa1xy return (DDI_FAILURE);
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy rw_exit(&e1000g_dma_type_lock);
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy return (DDI_SUCCESS);
080575042aba2197b425ebfd52061dea061a9aa1xy}
080575042aba2197b425ebfd52061dea061a9aa1xy
25f2d433de915875c8393f0b0dc14aa155997ad0xystatic void
25f2d433de915875c8393f0b0dc14aa155997ad0xye1000g_free_packets(struct e1000g *Adapter)
25f2d433de915875c8393f0b0dc14aa155997ad0xy{
25f2d433de915875c8393f0b0dc14aa155997ad0xy e1000g_tx_ring_t *tx_ring;
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems e1000g_rx_data_t *rx_data;
25f2d433de915875c8393f0b0dc14aa155997ad0xy
25f2d433de915875c8393f0b0dc14aa155997ad0xy tx_ring = Adapter->tx_ring;
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems rx_data = Adapter->rx_ring->rx_data;
25f2d433de915875c8393f0b0dc14aa155997ad0xy
25f2d433de915875c8393f0b0dc14aa155997ad0xy e1000g_free_tx_packets(tx_ring);
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China e1000g_free_rx_packets(rx_data, B_FALSE);
25f2d433de915875c8393f0b0dc14aa155997ad0xy}
25f2d433de915875c8393f0b0dc14aa155997ad0xy
080575042aba2197b425ebfd52061dea061a9aa1xy#ifdef __sparc
080575042aba2197b425ebfd52061dea061a9aa1xystatic int
080575042aba2197b425ebfd52061dea061a9aa1xye1000g_alloc_dvma_buffer(struct e1000g *Adapter,
080575042aba2197b425ebfd52061dea061a9aa1xy dma_buffer_t *buf, size_t size)
080575042aba2197b425ebfd52061dea061a9aa1xy{
080575042aba2197b425ebfd52061dea061a9aa1xy int mystat;
080575042aba2197b425ebfd52061dea061a9aa1xy dev_info_t *devinfo;
080575042aba2197b425ebfd52061dea061a9aa1xy ddi_dma_cookie_t cookie;
080575042aba2197b425ebfd52061dea061a9aa1xy
0f70fbf80d71251e7928b3122fb4848c2f92a5c6xy if (e1000g_force_detach)
0f70fbf80d71251e7928b3122fb4848c2f92a5c6xy devinfo = Adapter->priv_dip;
0f70fbf80d71251e7928b3122fb4848c2f92a5c6xy else
0f70fbf80d71251e7928b3122fb4848c2f92a5c6xy devinfo = Adapter->dip;
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy mystat = dvma_reserve(devinfo,
080575042aba2197b425ebfd52061dea061a9aa1xy &e1000g_dma_limits,
080575042aba2197b425ebfd52061dea061a9aa1xy Adapter->dvma_page_num,
080575042aba2197b425ebfd52061dea061a9aa1xy &buf->dma_handle);
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy if (mystat != DDI_SUCCESS) {
080575042aba2197b425ebfd52061dea061a9aa1xy buf->dma_handle = NULL;
25f2d433de915875c8393f0b0dc14aa155997ad0xy E1000G_DEBUGLOG_1(Adapter, E1000G_WARN_LEVEL,
080575042aba2197b425ebfd52061dea061a9aa1xy "Could not allocate dvma buffer handle: %d\n", mystat);
080575042aba2197b425ebfd52061dea061a9aa1xy return (DDI_FAILURE);
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy buf->address = kmem_alloc(size, KM_NOSLEEP);
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy if (buf->address == NULL) {
080575042aba2197b425ebfd52061dea061a9aa1xy if (buf->dma_handle != NULL) {
080575042aba2197b425ebfd52061dea061a9aa1xy dvma_release(buf->dma_handle);
080575042aba2197b425ebfd52061dea061a9aa1xy buf->dma_handle = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy }
25f2d433de915875c8393f0b0dc14aa155997ad0xy E1000G_DEBUGLOG_0(Adapter, E1000G_WARN_LEVEL,
080575042aba2197b425ebfd52061dea061a9aa1xy "Could not allocate dvma buffer memory\n");
080575042aba2197b425ebfd52061dea061a9aa1xy return (DDI_FAILURE);
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy dvma_kaddr_load(buf->dma_handle,
080575042aba2197b425ebfd52061dea061a9aa1xy buf->address, size, 0, &cookie);
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy buf->dma_address = cookie.dmac_laddress;
080575042aba2197b425ebfd52061dea061a9aa1xy buf->size = size;
080575042aba2197b425ebfd52061dea061a9aa1xy buf->len = 0;
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy return (DDI_SUCCESS);
080575042aba2197b425ebfd52061dea061a9aa1xy}
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xystatic void
080575042aba2197b425ebfd52061dea061a9aa1xye1000g_free_dvma_buffer(dma_buffer_t *buf)
080575042aba2197b425ebfd52061dea061a9aa1xy{
080575042aba2197b425ebfd52061dea061a9aa1xy if (buf->dma_handle != NULL) {
080575042aba2197b425ebfd52061dea061a9aa1xy dvma_unload(buf->dma_handle, 0, -1);
080575042aba2197b425ebfd52061dea061a9aa1xy } else {
080575042aba2197b425ebfd52061dea061a9aa1xy return;
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy buf->dma_address = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy if (buf->address != NULL) {
080575042aba2197b425ebfd52061dea061a9aa1xy kmem_free(buf->address, buf->size);
080575042aba2197b425ebfd52061dea061a9aa1xy buf->address = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy if (buf->dma_handle != NULL) {
080575042aba2197b425ebfd52061dea061a9aa1xy dvma_release(buf->dma_handle);
080575042aba2197b425ebfd52061dea061a9aa1xy buf->dma_handle = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy buf->size = 0;
080575042aba2197b425ebfd52061dea061a9aa1xy buf->len = 0;
080575042aba2197b425ebfd52061dea061a9aa1xy}
080575042aba2197b425ebfd52061dea061a9aa1xy#endif
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xystatic int
080575042aba2197b425ebfd52061dea061a9aa1xye1000g_alloc_dma_buffer(struct e1000g *Adapter,
25f2d433de915875c8393f0b0dc14aa155997ad0xy dma_buffer_t *buf, size_t size, ddi_dma_attr_t *p_dma_attr)
080575042aba2197b425ebfd52061dea061a9aa1xy{
080575042aba2197b425ebfd52061dea061a9aa1xy int mystat;
080575042aba2197b425ebfd52061dea061a9aa1xy dev_info_t *devinfo;
080575042aba2197b425ebfd52061dea061a9aa1xy ddi_dma_cookie_t cookie;
080575042aba2197b425ebfd52061dea061a9aa1xy size_t len;
080575042aba2197b425ebfd52061dea061a9aa1xy uint_t count;
080575042aba2197b425ebfd52061dea061a9aa1xy
0f70fbf80d71251e7928b3122fb4848c2f92a5c6xy if (e1000g_force_detach)
0f70fbf80d71251e7928b3122fb4848c2f92a5c6xy devinfo = Adapter->priv_dip;
0f70fbf80d71251e7928b3122fb4848c2f92a5c6xy else
0f70fbf80d71251e7928b3122fb4848c2f92a5c6xy devinfo = Adapter->dip;
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy mystat = ddi_dma_alloc_handle(devinfo,
25f2d433de915875c8393f0b0dc14aa155997ad0xy p_dma_attr,
080575042aba2197b425ebfd52061dea061a9aa1xy DDI_DMA_DONTWAIT, 0,
080575042aba2197b425ebfd52061dea061a9aa1xy &buf->dma_handle);
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy if (mystat != DDI_SUCCESS) {
080575042aba2197b425ebfd52061dea061a9aa1xy buf->dma_handle = NULL;
25f2d433de915875c8393f0b0dc14aa155997ad0xy E1000G_DEBUGLOG_1(Adapter, E1000G_WARN_LEVEL,
080575042aba2197b425ebfd52061dea061a9aa1xy "Could not allocate dma buffer handle: %d\n", mystat);
080575042aba2197b425ebfd52061dea061a9aa1xy return (DDI_FAILURE);
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy mystat = ddi_dma_mem_alloc(buf->dma_handle,
25f2d433de915875c8393f0b0dc14aa155997ad0xy size, &e1000g_buf_acc_attr, DDI_DMA_STREAMING,
080575042aba2197b425ebfd52061dea061a9aa1xy DDI_DMA_DONTWAIT, 0,
080575042aba2197b425ebfd52061dea061a9aa1xy &buf->address,
080575042aba2197b425ebfd52061dea061a9aa1xy &len, &buf->acc_handle);
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy if (mystat != DDI_SUCCESS) {
080575042aba2197b425ebfd52061dea061a9aa1xy buf->acc_handle = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy buf->address = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy if (buf->dma_handle != NULL) {
080575042aba2197b425ebfd52061dea061a9aa1xy ddi_dma_free_handle(&buf->dma_handle);
080575042aba2197b425ebfd52061dea061a9aa1xy buf->dma_handle = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy }
25f2d433de915875c8393f0b0dc14aa155997ad0xy E1000G_DEBUGLOG_1(Adapter, E1000G_WARN_LEVEL,
080575042aba2197b425ebfd52061dea061a9aa1xy "Could not allocate dma buffer memory: %d\n", mystat);
080575042aba2197b425ebfd52061dea061a9aa1xy return (DDI_FAILURE);
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy mystat = ddi_dma_addr_bind_handle(buf->dma_handle,
080575042aba2197b425ebfd52061dea061a9aa1xy (struct as *)NULL,
080575042aba2197b425ebfd52061dea061a9aa1xy buf->address,
0c35404fb68510fa79a18fcd7581fe676bad4882changqing li - Sun Microsystems - Beijing China len, DDI_DMA_RDWR | DDI_DMA_STREAMING,
25f2d433de915875c8393f0b0dc14aa155997ad0xy DDI_DMA_DONTWAIT, 0, &cookie, &count);
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy if (mystat != DDI_SUCCESS) {
080575042aba2197b425ebfd52061dea061a9aa1xy if (buf->acc_handle != NULL) {
080575042aba2197b425ebfd52061dea061a9aa1xy ddi_dma_mem_free(&buf->acc_handle);
080575042aba2197b425ebfd52061dea061a9aa1xy buf->acc_handle = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy buf->address = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy if (buf->dma_handle != NULL) {
080575042aba2197b425ebfd52061dea061a9aa1xy ddi_dma_free_handle(&buf->dma_handle);
080575042aba2197b425ebfd52061dea061a9aa1xy buf->dma_handle = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy }
25f2d433de915875c8393f0b0dc14aa155997ad0xy E1000G_DEBUGLOG_1(Adapter, E1000G_WARN_LEVEL,
080575042aba2197b425ebfd52061dea061a9aa1xy "Could not bind buffer dma handle: %d\n", mystat);
080575042aba2197b425ebfd52061dea061a9aa1xy return (DDI_FAILURE);
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy ASSERT(count == 1);
080575042aba2197b425ebfd52061dea061a9aa1xy if (count != 1) {
080575042aba2197b425ebfd52061dea061a9aa1xy if (buf->dma_handle != NULL) {
fe62dec3a38f1f79ffe68417df75dbbb58135bb7Chen-Liang Xu (void) ddi_dma_unbind_handle(buf->dma_handle);
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy if (buf->acc_handle != NULL) {
080575042aba2197b425ebfd52061dea061a9aa1xy ddi_dma_mem_free(&buf->acc_handle);
080575042aba2197b425ebfd52061dea061a9aa1xy buf->acc_handle = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy buf->address = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy if (buf->dma_handle != NULL) {
080575042aba2197b425ebfd52061dea061a9aa1xy ddi_dma_free_handle(&buf->dma_handle);
080575042aba2197b425ebfd52061dea061a9aa1xy buf->dma_handle = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy }
25f2d433de915875c8393f0b0dc14aa155997ad0xy E1000G_DEBUGLOG_1(Adapter, E1000G_WARN_LEVEL,
080575042aba2197b425ebfd52061dea061a9aa1xy "Could not bind buffer as a single frag. "
080575042aba2197b425ebfd52061dea061a9aa1xy "Count = %d\n", count);
080575042aba2197b425ebfd52061dea061a9aa1xy return (DDI_FAILURE);
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy buf->dma_address = cookie.dmac_laddress;
080575042aba2197b425ebfd52061dea061a9aa1xy buf->size = len;
080575042aba2197b425ebfd52061dea061a9aa1xy buf->len = 0;
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy return (DDI_SUCCESS);
080575042aba2197b425ebfd52061dea061a9aa1xy}
080575042aba2197b425ebfd52061dea061a9aa1xy
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China/*
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China * e1000g_alloc_dma_buffer_82546 - allocate a dma buffer along with all
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China * necessary handles. Same as e1000g_alloc_dma_buffer() except ensure
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China * that buffer that doesn't cross a 64k boundary.
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China */
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing Chinastatic int
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing Chinae1000g_alloc_dma_buffer_82546(struct e1000g *Adapter,
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China dma_buffer_t *buf, size_t size, ddi_dma_attr_t *p_dma_attr)
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China{
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China int mystat;
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China dev_info_t *devinfo;
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China ddi_dma_cookie_t cookie;
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China size_t len;
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China uint_t count;
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China if (e1000g_force_detach)
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China devinfo = Adapter->priv_dip;
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China else
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China devinfo = Adapter->dip;
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China mystat = ddi_dma_alloc_handle(devinfo,
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China p_dma_attr,
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China DDI_DMA_DONTWAIT, 0,
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China &buf->dma_handle);
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China if (mystat != DDI_SUCCESS) {
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China buf->dma_handle = NULL;
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China E1000G_DEBUGLOG_1(Adapter, E1000G_WARN_LEVEL,
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China "Could not allocate dma buffer handle: %d\n", mystat);
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China return (DDI_FAILURE);
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China }
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China mystat = e1000g_dma_mem_alloc_82546(buf, size, &len);
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China if (mystat != DDI_SUCCESS) {
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China buf->acc_handle = NULL;
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China buf->address = NULL;
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China if (buf->dma_handle != NULL) {
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China ddi_dma_free_handle(&buf->dma_handle);
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China buf->dma_handle = NULL;
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China }
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China E1000G_DEBUGLOG_1(Adapter, E1000G_WARN_LEVEL,
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China "Could not allocate dma buffer memory: %d\n", mystat);
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China return (DDI_FAILURE);
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China }
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China mystat = ddi_dma_addr_bind_handle(buf->dma_handle,
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China (struct as *)NULL,
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China buf->address,
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China len, DDI_DMA_READ | DDI_DMA_STREAMING,
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China DDI_DMA_DONTWAIT, 0, &cookie, &count);
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China if (mystat != DDI_SUCCESS) {
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China if (buf->acc_handle != NULL) {
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China ddi_dma_mem_free(&buf->acc_handle);
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China buf->acc_handle = NULL;
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China buf->address = NULL;
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China }
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China if (buf->dma_handle != NULL) {
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China ddi_dma_free_handle(&buf->dma_handle);
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China buf->dma_handle = NULL;
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China }
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China E1000G_DEBUGLOG_1(Adapter, E1000G_WARN_LEVEL,
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China "Could not bind buffer dma handle: %d\n", mystat);
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China return (DDI_FAILURE);
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China }
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China ASSERT(count == 1);
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China if (count != 1) {
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China if (buf->dma_handle != NULL) {
57ef6f696a98dddd9434e80a654341edd5316bf1guoqing zhu - Sun Microsystems - Beijing China (void) ddi_dma_unbind_handle(buf->dma_handle);
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China }
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China if (buf->acc_handle != NULL) {
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China ddi_dma_mem_free(&buf->acc_handle);
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China buf->acc_handle = NULL;
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China buf->address = NULL;
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China }
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China if (buf->dma_handle != NULL) {
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China ddi_dma_free_handle(&buf->dma_handle);
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China buf->dma_handle = NULL;
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China }
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China E1000G_DEBUGLOG_1(Adapter, E1000G_WARN_LEVEL,
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China "Could not bind buffer as a single frag. "
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China "Count = %d\n", count);
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China return (DDI_FAILURE);
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China }
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China buf->dma_address = cookie.dmac_laddress;
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China buf->size = len;
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China buf->len = 0;
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China return (DDI_SUCCESS);
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China}
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China/*
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China * e1000g_dma_mem_alloc_82546 - allocate a dma buffer, making up to
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China * ALLOC_RETRY attempts to get a buffer that doesn't cross a 64k boundary.
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China */
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing Chinastatic int
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing Chinae1000g_dma_mem_alloc_82546(dma_buffer_t *buf, size_t size, size_t *len)
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China{
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China#define ALLOC_RETRY 10
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China int stat;
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China int cnt = 0;
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China ddi_acc_handle_t hold[ALLOC_RETRY];
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China while (cnt < ALLOC_RETRY) {
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China hold[cnt] = NULL;
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China /* allocate memory */
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China stat = ddi_dma_mem_alloc(buf->dma_handle, size,
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China &e1000g_buf_acc_attr, DDI_DMA_STREAMING, DDI_DMA_DONTWAIT,
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China 0, &buf->address, len, &buf->acc_handle);
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China if (stat != DDI_SUCCESS) {
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China break;
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China }
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China /*
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China * Check 64k bounday:
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China * if it is bad, hold it and retry
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China * if it is good, exit loop
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China */
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China if (e1000g_cross_64k_bound(buf->address, *len)) {
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China hold[cnt] = buf->acc_handle;
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China stat = DDI_FAILURE;
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China } else {
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China break;
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China }
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China cnt++;
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China }
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China /* Release any held buffers crossing 64k bounday */
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China for (--cnt; cnt >= 0; cnt--) {
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China if (hold[cnt])
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China ddi_dma_mem_free(&hold[cnt]);
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China }
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China return (stat);
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China}
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China/*
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China * e1000g_cross_64k_bound - If starting and ending address cross a 64k boundary
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China * return true; otherwise return false
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China */
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing Chinastatic boolean_t
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing Chinae1000g_cross_64k_bound(void *addr, uintptr_t len)
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China{
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China uintptr_t start = (uintptr_t)addr;
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China uintptr_t end = start + len - 1;
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China return (((start ^ end) >> 16) == 0 ? B_FALSE : B_TRUE);
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China}
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China
080575042aba2197b425ebfd52061dea061a9aa1xystatic void
080575042aba2197b425ebfd52061dea061a9aa1xye1000g_free_dma_buffer(dma_buffer_t *buf)
080575042aba2197b425ebfd52061dea061a9aa1xy{
080575042aba2197b425ebfd52061dea061a9aa1xy if (buf->dma_handle != NULL) {
fe62dec3a38f1f79ffe68417df75dbbb58135bb7Chen-Liang Xu (void) ddi_dma_unbind_handle(buf->dma_handle);
080575042aba2197b425ebfd52061dea061a9aa1xy } else {
080575042aba2197b425ebfd52061dea061a9aa1xy return;
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy buf->dma_address = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy if (buf->acc_handle != NULL) {
080575042aba2197b425ebfd52061dea061a9aa1xy ddi_dma_mem_free(&buf->acc_handle);
080575042aba2197b425ebfd52061dea061a9aa1xy buf->acc_handle = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy buf->address = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy if (buf->dma_handle != NULL) {
080575042aba2197b425ebfd52061dea061a9aa1xy ddi_dma_free_handle(&buf->dma_handle);
080575042aba2197b425ebfd52061dea061a9aa1xy buf->dma_handle = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy buf->size = 0;
080575042aba2197b425ebfd52061dea061a9aa1xy buf->len = 0;
080575042aba2197b425ebfd52061dea061a9aa1xy}
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xystatic int
080575042aba2197b425ebfd52061dea061a9aa1xye1000g_alloc_tx_packets(e1000g_tx_ring_t *tx_ring)
080575042aba2197b425ebfd52061dea061a9aa1xy{
080575042aba2197b425ebfd52061dea061a9aa1xy int j;
25f2d433de915875c8393f0b0dc14aa155997ad0xy p_tx_sw_packet_t packet;
080575042aba2197b425ebfd52061dea061a9aa1xy int mystat;
080575042aba2197b425ebfd52061dea061a9aa1xy dma_buffer_t *tx_buf;
25f2d433de915875c8393f0b0dc14aa155997ad0xy struct e1000g *Adapter;
25f2d433de915875c8393f0b0dc14aa155997ad0xy dev_info_t *devinfo;
25f2d433de915875c8393f0b0dc14aa155997ad0xy ddi_dma_attr_t dma_attr;
25f2d433de915875c8393f0b0dc14aa155997ad0xy
25f2d433de915875c8393f0b0dc14aa155997ad0xy Adapter = tx_ring->adapter;
25f2d433de915875c8393f0b0dc14aa155997ad0xy devinfo = Adapter->dip;
25f2d433de915875c8393f0b0dc14aa155997ad0xy dma_attr = e1000g_buf_dma_attr;
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy /*
080575042aba2197b425ebfd52061dea061a9aa1xy * Memory allocation for the Transmit software structure, the transmit
080575042aba2197b425ebfd52061dea061a9aa1xy * software packet. This structure stores all the relevant information
080575042aba2197b425ebfd52061dea061a9aa1xy * for transmitting a single packet.
080575042aba2197b425ebfd52061dea061a9aa1xy */
080575042aba2197b425ebfd52061dea061a9aa1xy tx_ring->packet_area =
080575042aba2197b425ebfd52061dea061a9aa1xy kmem_zalloc(TX_SW_PKT_AREA_SZ, KM_NOSLEEP);
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy if (tx_ring->packet_area == NULL)
080575042aba2197b425ebfd52061dea061a9aa1xy return (DDI_FAILURE);
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy for (j = 0, packet = tx_ring->packet_area;
25f2d433de915875c8393f0b0dc14aa155997ad0xy j < Adapter->tx_freelist_num; j++, packet++) {
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy ASSERT(packet != NULL);
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy /*
080575042aba2197b425ebfd52061dea061a9aa1xy * Pre-allocate dma handles for transmit. These dma handles
080575042aba2197b425ebfd52061dea061a9aa1xy * will be dynamically bound to the data buffers passed down
080575042aba2197b425ebfd52061dea061a9aa1xy * from the upper layers at the time of transmitting. The
080575042aba2197b425ebfd52061dea061a9aa1xy * dynamic binding only applies for the packets that are larger
080575042aba2197b425ebfd52061dea061a9aa1xy * than the tx_bcopy_thresh.
080575042aba2197b425ebfd52061dea061a9aa1xy */
080575042aba2197b425ebfd52061dea061a9aa1xy switch (e1000g_dma_type) {
080575042aba2197b425ebfd52061dea061a9aa1xy#ifdef __sparc
080575042aba2197b425ebfd52061dea061a9aa1xy case USE_DVMA:
080575042aba2197b425ebfd52061dea061a9aa1xy mystat = dvma_reserve(devinfo,
080575042aba2197b425ebfd52061dea061a9aa1xy &e1000g_dma_limits,
080575042aba2197b425ebfd52061dea061a9aa1xy Adapter->dvma_page_num,
080575042aba2197b425ebfd52061dea061a9aa1xy &packet->tx_dma_handle);
080575042aba2197b425ebfd52061dea061a9aa1xy break;
080575042aba2197b425ebfd52061dea061a9aa1xy#endif
080575042aba2197b425ebfd52061dea061a9aa1xy case USE_DMA:
080575042aba2197b425ebfd52061dea061a9aa1xy mystat = ddi_dma_alloc_handle(devinfo,
25f2d433de915875c8393f0b0dc14aa155997ad0xy &e1000g_tx_dma_attr,
080575042aba2197b425ebfd52061dea061a9aa1xy DDI_DMA_DONTWAIT, 0,
080575042aba2197b425ebfd52061dea061a9aa1xy &packet->tx_dma_handle);
080575042aba2197b425ebfd52061dea061a9aa1xy break;
080575042aba2197b425ebfd52061dea061a9aa1xy default:
080575042aba2197b425ebfd52061dea061a9aa1xy ASSERT(B_FALSE);
080575042aba2197b425ebfd52061dea061a9aa1xy break;
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy if (mystat != DDI_SUCCESS) {
080575042aba2197b425ebfd52061dea061a9aa1xy packet->tx_dma_handle = NULL;
25f2d433de915875c8393f0b0dc14aa155997ad0xy E1000G_DEBUGLOG_1(Adapter, E1000G_WARN_LEVEL,
080575042aba2197b425ebfd52061dea061a9aa1xy "Could not allocate tx dma handle: %d\n", mystat);
080575042aba2197b425ebfd52061dea061a9aa1xy goto tx_pkt_fail;
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy /*
080575042aba2197b425ebfd52061dea061a9aa1xy * Pre-allocate transmit buffers for small packets that the
080575042aba2197b425ebfd52061dea061a9aa1xy * size is less than tx_bcopy_thresh. The data of those small
080575042aba2197b425ebfd52061dea061a9aa1xy * packets will be bcopy() to the transmit buffers instead of
080575042aba2197b425ebfd52061dea061a9aa1xy * using dynamical DMA binding. For small packets, bcopy will
080575042aba2197b425ebfd52061dea061a9aa1xy * bring better performance than DMA binding.
080575042aba2197b425ebfd52061dea061a9aa1xy */
080575042aba2197b425ebfd52061dea061a9aa1xy tx_buf = packet->tx_buf;
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy switch (e1000g_dma_type) {
080575042aba2197b425ebfd52061dea061a9aa1xy#ifdef __sparc
080575042aba2197b425ebfd52061dea061a9aa1xy case USE_DVMA:
080575042aba2197b425ebfd52061dea061a9aa1xy mystat = e1000g_alloc_dvma_buffer(Adapter,
25f2d433de915875c8393f0b0dc14aa155997ad0xy tx_buf, Adapter->tx_buffer_size);
080575042aba2197b425ebfd52061dea061a9aa1xy break;
080575042aba2197b425ebfd52061dea061a9aa1xy#endif
080575042aba2197b425ebfd52061dea061a9aa1xy case USE_DMA:
080575042aba2197b425ebfd52061dea061a9aa1xy mystat = e1000g_alloc_dma_buffer(Adapter,
25f2d433de915875c8393f0b0dc14aa155997ad0xy tx_buf, Adapter->tx_buffer_size, &dma_attr);
080575042aba2197b425ebfd52061dea061a9aa1xy break;
080575042aba2197b425ebfd52061dea061a9aa1xy default:
080575042aba2197b425ebfd52061dea061a9aa1xy ASSERT(B_FALSE);
080575042aba2197b425ebfd52061dea061a9aa1xy break;
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy if (mystat != DDI_SUCCESS) {
080575042aba2197b425ebfd52061dea061a9aa1xy ASSERT(packet->tx_dma_handle != NULL);
080575042aba2197b425ebfd52061dea061a9aa1xy switch (e1000g_dma_type) {
080575042aba2197b425ebfd52061dea061a9aa1xy#ifdef __sparc
080575042aba2197b425ebfd52061dea061a9aa1xy case USE_DVMA:
080575042aba2197b425ebfd52061dea061a9aa1xy dvma_release(packet->tx_dma_handle);
080575042aba2197b425ebfd52061dea061a9aa1xy break;
080575042aba2197b425ebfd52061dea061a9aa1xy#endif
080575042aba2197b425ebfd52061dea061a9aa1xy case USE_DMA:
080575042aba2197b425ebfd52061dea061a9aa1xy ddi_dma_free_handle(&packet->tx_dma_handle);
080575042aba2197b425ebfd52061dea061a9aa1xy break;
080575042aba2197b425ebfd52061dea061a9aa1xy default:
080575042aba2197b425ebfd52061dea061a9aa1xy ASSERT(B_FALSE);
080575042aba2197b425ebfd52061dea061a9aa1xy break;
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy packet->tx_dma_handle = NULL;
25f2d433de915875c8393f0b0dc14aa155997ad0xy E1000G_DEBUGLOG_0(Adapter, E1000G_WARN_LEVEL,
080575042aba2197b425ebfd52061dea061a9aa1xy "Allocate Tx buffer fail\n");
080575042aba2197b425ebfd52061dea061a9aa1xy goto tx_pkt_fail;
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy packet->dma_type = e1000g_dma_type;
080575042aba2197b425ebfd52061dea061a9aa1xy } /* for */
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy return (DDI_SUCCESS);
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xytx_pkt_fail:
080575042aba2197b425ebfd52061dea061a9aa1xy e1000g_free_tx_packets(tx_ring);
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy return (DDI_FAILURE);
080575042aba2197b425ebfd52061dea061a9aa1xy}
080575042aba2197b425ebfd52061dea061a9aa1xy
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing Chinaint
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing Chinae1000g_increase_rx_packets(e1000g_rx_data_t *rx_data)
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China{
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China int i;
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China p_rx_sw_packet_t packet;
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China p_rx_sw_packet_t cur, next;
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China struct e1000g *Adapter;
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China ddi_dma_attr_t dma_attr;
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China Adapter = rx_data->rx_ring->adapter;
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China dma_attr = e1000g_buf_dma_attr;
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China dma_attr.dma_attr_align = Adapter->rx_buf_align;
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China cur = NULL;
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China for (i = 0; i < RX_FREELIST_INCREASE_SIZE; i++) {
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China packet = e1000g_alloc_rx_sw_packet(rx_data, &dma_attr);
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China if (packet == NULL)
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China break;
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China packet->next = cur;
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China cur = packet;
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China }
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China Adapter->rx_freelist_num += i;
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China rx_data->avail_freepkt += i;
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China while (cur != NULL) {
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China QUEUE_PUSH_TAIL(&rx_data->free_list, &cur->Link);
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China next = cur->next;
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China cur->next = rx_data->packet_area;
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China rx_data->packet_area = cur;
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China cur = next;
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China }
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China return (DDI_SUCCESS);
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China}
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China
080575042aba2197b425ebfd52061dea061a9aa1xystatic int
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystemse1000g_alloc_rx_packets(e1000g_rx_data_t *rx_data)
080575042aba2197b425ebfd52061dea061a9aa1xy{
080575042aba2197b425ebfd52061dea061a9aa1xy int i;
25f2d433de915875c8393f0b0dc14aa155997ad0xy p_rx_sw_packet_t packet;
080575042aba2197b425ebfd52061dea061a9aa1xy struct e1000g *Adapter;
080575042aba2197b425ebfd52061dea061a9aa1xy uint32_t packet_num;
25f2d433de915875c8393f0b0dc14aa155997ad0xy ddi_dma_attr_t dma_attr;
080575042aba2197b425ebfd52061dea061a9aa1xy
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems Adapter = rx_data->rx_ring->adapter;
25f2d433de915875c8393f0b0dc14aa155997ad0xy dma_attr = e1000g_buf_dma_attr;
25f2d433de915875c8393f0b0dc14aa155997ad0xy dma_attr.dma_attr_align = Adapter->rx_buf_align;
592a4d85662412bade15f3d9e9e0cbcf8514348ccc
080575042aba2197b425ebfd52061dea061a9aa1xy /*
25f2d433de915875c8393f0b0dc14aa155997ad0xy * Allocate memory for the rx_sw_packet structures. Each one of these
080575042aba2197b425ebfd52061dea061a9aa1xy * structures will contain a virtual and physical address to an actual
25f2d433de915875c8393f0b0dc14aa155997ad0xy * receive buffer in host memory. Since we use one rx_sw_packet per
25f2d433de915875c8393f0b0dc14aa155997ad0xy * received packet, the maximum number of rx_sw_packet that we'll
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems * need is equal to the number of receive descriptors plus the freelist
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems * size.
080575042aba2197b425ebfd52061dea061a9aa1xy */
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China packet_num = Adapter->rx_desc_num + RX_FREELIST_INCREASE_SIZE;
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems rx_data->packet_area = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy for (i = 0; i < packet_num; i++) {
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems packet = e1000g_alloc_rx_sw_packet(rx_data, &dma_attr);
080575042aba2197b425ebfd52061dea061a9aa1xy if (packet == NULL)
080575042aba2197b425ebfd52061dea061a9aa1xy goto rx_pkt_fail;
080575042aba2197b425ebfd52061dea061a9aa1xy
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems packet->next = rx_data->packet_area;
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems rx_data->packet_area = packet;
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China Adapter->rx_freelist_num = RX_FREELIST_INCREASE_SIZE;
080575042aba2197b425ebfd52061dea061a9aa1xy return (DDI_SUCCESS);
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xyrx_pkt_fail:
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China e1000g_free_rx_packets(rx_data, B_TRUE);
080575042aba2197b425ebfd52061dea061a9aa1xy return (DDI_FAILURE);
080575042aba2197b425ebfd52061dea061a9aa1xy}
080575042aba2197b425ebfd52061dea061a9aa1xy
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China
25f2d433de915875c8393f0b0dc14aa155997ad0xystatic p_rx_sw_packet_t
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystemse1000g_alloc_rx_sw_packet(e1000g_rx_data_t *rx_data, ddi_dma_attr_t *p_dma_attr)
080575042aba2197b425ebfd52061dea061a9aa1xy{
080575042aba2197b425ebfd52061dea061a9aa1xy int mystat;
25f2d433de915875c8393f0b0dc14aa155997ad0xy p_rx_sw_packet_t packet;
080575042aba2197b425ebfd52061dea061a9aa1xy dma_buffer_t *rx_buf;
080575042aba2197b425ebfd52061dea061a9aa1xy struct e1000g *Adapter;
080575042aba2197b425ebfd52061dea061a9aa1xy
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems Adapter = rx_data->rx_ring->adapter;
080575042aba2197b425ebfd52061dea061a9aa1xy
25f2d433de915875c8393f0b0dc14aa155997ad0xy packet = kmem_zalloc(sizeof (rx_sw_packet_t), KM_NOSLEEP);
080575042aba2197b425ebfd52061dea061a9aa1xy if (packet == NULL) {
25f2d433de915875c8393f0b0dc14aa155997ad0xy E1000G_DEBUGLOG_0(Adapter, E1000G_WARN_LEVEL,
080575042aba2197b425ebfd52061dea061a9aa1xy "Cound not allocate memory for Rx SwPacket\n");
080575042aba2197b425ebfd52061dea061a9aa1xy return (NULL);
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy rx_buf = packet->rx_buf;
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy switch (e1000g_dma_type) {
080575042aba2197b425ebfd52061dea061a9aa1xy#ifdef __sparc
080575042aba2197b425ebfd52061dea061a9aa1xy case USE_DVMA:
080575042aba2197b425ebfd52061dea061a9aa1xy mystat = e1000g_alloc_dvma_buffer(Adapter,
25f2d433de915875c8393f0b0dc14aa155997ad0xy rx_buf, Adapter->rx_buffer_size);
080575042aba2197b425ebfd52061dea061a9aa1xy break;
080575042aba2197b425ebfd52061dea061a9aa1xy#endif
080575042aba2197b425ebfd52061dea061a9aa1xy case USE_DMA:
3d15c084da89e6f689f1804f3e2e600e5376c4e1chenlu chen - Sun Microsystems - Beijing China if (Adapter->mem_workaround_82546 &&
3d15c084da89e6f689f1804f3e2e600e5376c4e1chenlu chen - Sun Microsystems - Beijing China ((Adapter->shared.mac.type == e1000_82545) ||
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China (Adapter->shared.mac.type == e1000_82546) ||
3d15c084da89e6f689f1804f3e2e600e5376c4e1chenlu chen - Sun Microsystems - Beijing China (Adapter->shared.mac.type == e1000_82546_rev_3))) {
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China mystat = e1000g_alloc_dma_buffer_82546(Adapter,
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China rx_buf, Adapter->rx_buffer_size, p_dma_attr);
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China } else {
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China mystat = e1000g_alloc_dma_buffer(Adapter,
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China rx_buf, Adapter->rx_buffer_size, p_dma_attr);
ede5269ebe7fa3787cc9b58c3781b639c578f93dchenlu chen - Sun Microsystems - Beijing China }
080575042aba2197b425ebfd52061dea061a9aa1xy break;
080575042aba2197b425ebfd52061dea061a9aa1xy default:
080575042aba2197b425ebfd52061dea061a9aa1xy ASSERT(B_FALSE);
080575042aba2197b425ebfd52061dea061a9aa1xy break;
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy if (mystat != DDI_SUCCESS) {
080575042aba2197b425ebfd52061dea061a9aa1xy if (packet != NULL)
25f2d433de915875c8393f0b0dc14aa155997ad0xy kmem_free(packet, sizeof (rx_sw_packet_t));
080575042aba2197b425ebfd52061dea061a9aa1xy
25f2d433de915875c8393f0b0dc14aa155997ad0xy E1000G_DEBUGLOG_0(Adapter, E1000G_WARN_LEVEL,
080575042aba2197b425ebfd52061dea061a9aa1xy "Failed to allocate Rx buffer\n");
080575042aba2197b425ebfd52061dea061a9aa1xy return (NULL);
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy rx_buf->size -= E1000G_IPALIGNROOM;
080575042aba2197b425ebfd52061dea061a9aa1xy rx_buf->address += E1000G_IPALIGNROOM;
080575042aba2197b425ebfd52061dea061a9aa1xy rx_buf->dma_address += E1000G_IPALIGNROOM;
080575042aba2197b425ebfd52061dea061a9aa1xy
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems packet->rx_data = (caddr_t)rx_data;
080575042aba2197b425ebfd52061dea061a9aa1xy packet->free_rtn.free_func = e1000g_rxfree_func;
080575042aba2197b425ebfd52061dea061a9aa1xy packet->free_rtn.free_arg = (char *)packet;
080575042aba2197b425ebfd52061dea061a9aa1xy /*
080575042aba2197b425ebfd52061dea061a9aa1xy * esballoc is changed to desballoc which
080575042aba2197b425ebfd52061dea061a9aa1xy * is undocumented call but as per sun,
080575042aba2197b425ebfd52061dea061a9aa1xy * we can use it. It gives better efficiency.
080575042aba2197b425ebfd52061dea061a9aa1xy */
080575042aba2197b425ebfd52061dea061a9aa1xy packet->mp = desballoc((unsigned char *)
46ebaa55cce1df60528a191312d12199d38a4493Miles Xu, Sun Microsystems rx_buf->address,
46ebaa55cce1df60528a191312d12199d38a4493Miles Xu, Sun Microsystems rx_buf->size,
080575042aba2197b425ebfd52061dea061a9aa1xy BPRI_MED, &packet->free_rtn);
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy packet->dma_type = e1000g_dma_type;
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems packet->ref_cnt = 1;
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy return (packet);
080575042aba2197b425ebfd52061dea061a9aa1xy}
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xyvoid
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystemse1000g_free_rx_sw_packet(p_rx_sw_packet_t packet, boolean_t full_release)
080575042aba2197b425ebfd52061dea061a9aa1xy{
080575042aba2197b425ebfd52061dea061a9aa1xy dma_buffer_t *rx_buf;
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy if (packet->mp != NULL) {
080575042aba2197b425ebfd52061dea061a9aa1xy freemsg(packet->mp);
080575042aba2197b425ebfd52061dea061a9aa1xy packet->mp = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy rx_buf = packet->rx_buf;
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy switch (packet->dma_type) {
080575042aba2197b425ebfd52061dea061a9aa1xy#ifdef __sparc
080575042aba2197b425ebfd52061dea061a9aa1xy case USE_DVMA:
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems if (rx_buf->address != NULL) {
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems rx_buf->size += E1000G_IPALIGNROOM;
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems rx_buf->address -= E1000G_IPALIGNROOM;
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems }
080575042aba2197b425ebfd52061dea061a9aa1xy e1000g_free_dvma_buffer(rx_buf);
080575042aba2197b425ebfd52061dea061a9aa1xy break;
080575042aba2197b425ebfd52061dea061a9aa1xy#endif
080575042aba2197b425ebfd52061dea061a9aa1xy case USE_DMA:
080575042aba2197b425ebfd52061dea061a9aa1xy e1000g_free_dma_buffer(rx_buf);
080575042aba2197b425ebfd52061dea061a9aa1xy break;
080575042aba2197b425ebfd52061dea061a9aa1xy default:
080575042aba2197b425ebfd52061dea061a9aa1xy break;
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy packet->dma_type = USE_NONE;
080575042aba2197b425ebfd52061dea061a9aa1xy
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems if (!full_release)
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems return;
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems
25f2d433de915875c8393f0b0dc14aa155997ad0xy kmem_free(packet, sizeof (rx_sw_packet_t));
080575042aba2197b425ebfd52061dea061a9aa1xy}
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xystatic void
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing Chinae1000g_free_rx_packets(e1000g_rx_data_t *rx_data, boolean_t full_release)
080575042aba2197b425ebfd52061dea061a9aa1xy{
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems p_rx_sw_packet_t packet, next_packet;
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems uint32_t ref_cnt;
080575042aba2197b425ebfd52061dea061a9aa1xy
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems mutex_enter(&e1000g_rx_detach_lock);
0f70fbf80d71251e7928b3122fb4848c2f92a5c6xy
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems packet = rx_data->packet_area;
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems while (packet != NULL) {
0f70fbf80d71251e7928b3122fb4848c2f92a5c6xy next_packet = packet->next;
0f70fbf80d71251e7928b3122fb4848c2f92a5c6xy
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems ref_cnt = atomic_dec_32_nv(&packet->ref_cnt);
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems if (ref_cnt > 0) {
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems atomic_inc_32(&rx_data->pending_count);
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems atomic_inc_32(&e1000g_mblks_pending);
0f70fbf80d71251e7928b3122fb4848c2f92a5c6xy } else {
3fb4efef75bbb3a06a68d5ff59c33df03c73f6c9changqing li - Sun Microsystems - Beijing China e1000g_free_rx_sw_packet(packet, full_release);
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems packet = next_packet;
080575042aba2197b425ebfd52061dea061a9aa1xy }
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems
bcfab0594401266bd287f71573312d8af05de184Josef 'Jeff' Sipek if (full_release)
bcfab0594401266bd287f71573312d8af05de184Josef 'Jeff' Sipek rx_data->packet_area = NULL;
bcfab0594401266bd287f71573312d8af05de184Josef 'Jeff' Sipek
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems mutex_exit(&e1000g_rx_detach_lock);
080575042aba2197b425ebfd52061dea061a9aa1xy}
080575042aba2197b425ebfd52061dea061a9aa1xy
54e0d7a5e8285a3f01a0db8db1246ac7cac94d81Miles Xu, Sun Microsystems
080575042aba2197b425ebfd52061dea061a9aa1xystatic void
080575042aba2197b425ebfd52061dea061a9aa1xye1000g_free_tx_packets(e1000g_tx_ring_t *tx_ring)
080575042aba2197b425ebfd52061dea061a9aa1xy{
080575042aba2197b425ebfd52061dea061a9aa1xy int j;
080575042aba2197b425ebfd52061dea061a9aa1xy struct e1000g *Adapter;
25f2d433de915875c8393f0b0dc14aa155997ad0xy p_tx_sw_packet_t packet;
080575042aba2197b425ebfd52061dea061a9aa1xy dma_buffer_t *tx_buf;
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy Adapter = tx_ring->adapter;
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy for (j = 0, packet = tx_ring->packet_area;
25f2d433de915875c8393f0b0dc14aa155997ad0xy j < Adapter->tx_freelist_num; j++, packet++) {
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy if (packet == NULL)
080575042aba2197b425ebfd52061dea061a9aa1xy break;
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy /* Free the Tx DMA handle for dynamical binding */
080575042aba2197b425ebfd52061dea061a9aa1xy if (packet->tx_dma_handle != NULL) {
080575042aba2197b425ebfd52061dea061a9aa1xy switch (packet->dma_type) {
080575042aba2197b425ebfd52061dea061a9aa1xy#ifdef __sparc
080575042aba2197b425ebfd52061dea061a9aa1xy case USE_DVMA:
080575042aba2197b425ebfd52061dea061a9aa1xy dvma_release(packet->tx_dma_handle);
080575042aba2197b425ebfd52061dea061a9aa1xy break;
080575042aba2197b425ebfd52061dea061a9aa1xy#endif
080575042aba2197b425ebfd52061dea061a9aa1xy case USE_DMA:
080575042aba2197b425ebfd52061dea061a9aa1xy ddi_dma_free_handle(&packet->tx_dma_handle);
080575042aba2197b425ebfd52061dea061a9aa1xy break;
080575042aba2197b425ebfd52061dea061a9aa1xy default:
080575042aba2197b425ebfd52061dea061a9aa1xy ASSERT(B_FALSE);
080575042aba2197b425ebfd52061dea061a9aa1xy break;
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy packet->tx_dma_handle = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy } else {
080575042aba2197b425ebfd52061dea061a9aa1xy /*
080575042aba2197b425ebfd52061dea061a9aa1xy * If the dma handle is NULL, then we don't
080575042aba2197b425ebfd52061dea061a9aa1xy * need to check the packets left. For they
080575042aba2197b425ebfd52061dea061a9aa1xy * have not been initialized or have been freed.
080575042aba2197b425ebfd52061dea061a9aa1xy */
080575042aba2197b425ebfd52061dea061a9aa1xy break;
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy tx_buf = packet->tx_buf;
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy switch (packet->dma_type) {
080575042aba2197b425ebfd52061dea061a9aa1xy#ifdef __sparc
080575042aba2197b425ebfd52061dea061a9aa1xy case USE_DVMA:
080575042aba2197b425ebfd52061dea061a9aa1xy e1000g_free_dvma_buffer(tx_buf);
080575042aba2197b425ebfd52061dea061a9aa1xy break;
080575042aba2197b425ebfd52061dea061a9aa1xy#endif
080575042aba2197b425ebfd52061dea061a9aa1xy case USE_DMA:
080575042aba2197b425ebfd52061dea061a9aa1xy e1000g_free_dma_buffer(tx_buf);
080575042aba2197b425ebfd52061dea061a9aa1xy break;
080575042aba2197b425ebfd52061dea061a9aa1xy default:
080575042aba2197b425ebfd52061dea061a9aa1xy ASSERT(B_FALSE);
080575042aba2197b425ebfd52061dea061a9aa1xy break;
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy packet->dma_type = USE_NONE;
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy if (tx_ring->packet_area != NULL) {
080575042aba2197b425ebfd52061dea061a9aa1xy kmem_free(tx_ring->packet_area, TX_SW_PKT_AREA_SZ);
080575042aba2197b425ebfd52061dea061a9aa1xy tx_ring->packet_area = NULL;
080575042aba2197b425ebfd52061dea061a9aa1xy }
080575042aba2197b425ebfd52061dea061a9aa1xy}
080575042aba2197b425ebfd52061dea061a9aa1xy
080575042aba2197b425ebfd52061dea061a9aa1xy/*
25f2d433de915875c8393f0b0dc14aa155997ad0xy * e1000g_release_dma_resources - release allocated DMA resources
25f2d433de915875c8393f0b0dc14aa155997ad0xy *
25f2d433de915875c8393f0b0dc14aa155997ad0xy * This function releases any pending buffers that has been
25f2d433de915875c8393f0b0dc14aa155997ad0xy * previously allocated
080575042aba2197b425ebfd52061dea061a9aa1xy */
080575042aba2197b425ebfd52061dea061a9aa1xyvoid
25f2d433de915875c8393f0b0dc14aa155997ad0xye1000g_release_dma_resources(struct e1000g *Adapter)
080575042aba2197b425ebfd52061dea061a9aa1xy{
25f2d433de915875c8393f0b0dc14aa155997ad0xy e1000g_free_descriptors(Adapter);
25f2d433de915875c8393f0b0dc14aa155997ad0xy e1000g_free_packets(Adapter);
080575042aba2197b425ebfd52061dea061a9aa1xy}
9b6541b318d01d0d83bfb98699a7f09e35f37951gl
fe62dec3a38f1f79ffe68417df75dbbb58135bb7Chen-Liang Xu/* ARGSUSED */
9b6541b318d01d0d83bfb98699a7f09e35f37951glvoid
837c1ac4e72b7d86278cca88b1075af557f7d161Stephen Hansone1000g_set_fma_flags(int dma_flag)
9b6541b318d01d0d83bfb98699a7f09e35f37951gl{
9b6541b318d01d0d83bfb98699a7f09e35f37951gl if (dma_flag) {
9b6541b318d01d0d83bfb98699a7f09e35f37951gl e1000g_tx_dma_attr.dma_attr_flags = DDI_DMA_FLAGERR;
9b6541b318d01d0d83bfb98699a7f09e35f37951gl e1000g_buf_dma_attr.dma_attr_flags = DDI_DMA_FLAGERR;
9b6541b318d01d0d83bfb98699a7f09e35f37951gl e1000g_desc_dma_attr.dma_attr_flags = DDI_DMA_FLAGERR;
9b6541b318d01d0d83bfb98699a7f09e35f37951gl } else {
9b6541b318d01d0d83bfb98699a7f09e35f37951gl e1000g_tx_dma_attr.dma_attr_flags = 0;
9b6541b318d01d0d83bfb98699a7f09e35f37951gl e1000g_buf_dma_attr.dma_attr_flags = 0;
9b6541b318d01d0d83bfb98699a7f09e35f37951gl e1000g_desc_dma_attr.dma_attr_flags = 0;
9b6541b318d01d0d83bfb98699a7f09e35f37951gl }
9b6541b318d01d0d83bfb98699a7f09e35f37951gl}