/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/* Copyright © 2003-2011 Emulex. All rights reserved. */
/*
* Source file containing the implementation of the Transmit
* Path
*/
#include <oce_impl.h>
DMA_ATTR_V0, /* version number */
0x0000000000000000ull, /* low address */
0xFFFFFFFFFFFFFFFFull, /* high address */
0x0000000000010000ull, /* dma counter max */
OCE_TXMAP_ALIGN, /* alignment */
0x7FF, /* burst sizes */
0x00000001, /* minimum transfer size */
0x00000000FFFFFFFFull, /* maximum transfer size */
0xFFFFFFFFFFFFFFFFull, /* maximum segment size */
OCE_MAX_TXDMA_COOKIES, /* scatter/gather list length */
0x00000001, /* granularity */
DDI_DMA_FLAGERR /* dma_attr_flags */
};
DMA_ATTR_V0, /* version number */
0x0000000000000000ull, /* low address */
0xFFFFFFFFFFFFFFFFull, /* high address */
0x00000000FFFFFFFFull, /* dma counter max */
OCE_DMA_ALIGNMENT, /* alignment */
0x000007FF, /* burst sizes */
0x00000001, /* minimum transfer size */
0x00000000FFFFFFFFull, /* maximum transfer size */
0xFFFFFFFFFFFFFFFFull, /* maximum segment size */
0x00000001, /* granularity */
DDI_DMA_FLAGERR /* dma_attr_flags */
};
/*
* WQ map handle destructor
*
* wq - Pointer to WQ structure
* wqmd - pointer to WQE mapping handle descriptor
*
* return none
*/
static void
{
/* Free the DMA handle */
} /* oce_wqm_dtor */
/*
* WQ map handles contructor
*
* wqmd - pointer to WQE mapping handle descriptor
* wq - Pointer to WQ structure
*
* return DDI_SUCCESS=>success, DDI_FAILURE=>error
*/
static int
{
int ret;
/* Allocate DMA handle */
return (ret);
} /* oce_wqm_ctor */
/*
* function to create WQ mapping handles cache
*
* wq - pointer to WQ structure
*
* return DDI_SUCCESS=>success, DDI_FAILURE=>error
*/
int
{
int size;
int cnt;
int ret;
return (DDI_FAILURE);
}
/* Create the free buffer list */
if (ret != DDI_SUCCESS) {
goto wqm_fail;
}
}
return (DDI_SUCCESS);
return (DDI_FAILURE);
}
/*
* function to destroy WQ mapping handles cache
*
* wq - pointer to WQ structure
*
* return none
*/
void
{
}
}
/*
* function to create WQ buffer cache
*
* wq - pointer to WQ structure
* buf_size - size of the buffer
*
* return DDI_SUCCESS=>success, DDI_FAILURE=>error
*/
int
{
int size;
int cnt;
int ret;
return (DDI_FAILURE);
}
/* Create the free buffer list */
if (ret != DDI_SUCCESS) {
goto wqb_fail;
}
}
return (DDI_SUCCESS);
return (DDI_FAILURE);
}
/*
* function to destroy WQ buffer cache
*
* wq - pointer to WQ structure
*
* return none
*/
void
{
}
}
/*
* WQ buffer constructor
*
* wqbd - pointer to WQ buffer descriptor
* wq - pointer to WQ structure
* size - size of the buffer
* flags - KM_SLEEP or KM_NOSLEEP
*
* return DDI_SUCCESS=>success, DDI_FAILURE=>error
*/
static int
{
flags);
return (DDI_FAILURE);
}
return (DDI_SUCCESS);
}
/*
* WQ buffer destructor
*
* wq - pointer to WQ structure
* wqbd - pointer to WQ buffer descriptor
*
* return none
*/
static void
{
}
/*
* function to alloc WQE buffer descriptor
*
* wq - pointer to WQ structure
*
* return pointer to WQE buffer descriptor
*/
static inline oce_wq_bdesc_t *
{
}
/*
* function to free WQE buffer descriptor
*
* wq - pointer to WQ structure
* wqbd - pointer to WQ buffer descriptor
*
* return none
*/
static inline void
{
} /* oce_wqb_free */
/*
* function to allocate WQE mapping descriptor
*
* wq - pointer to WQ structure
*
* return pointer to WQE mapping descriptor
*/
static inline oce_wq_mdesc_t *
{
} /* oce_wqm_alloc */
/*
* function to insert WQE mapping descriptor to the list
*
* wq - pointer to WQ structure
* wqmd - Pointer to WQ mapping descriptor
*
* return none
*/
static inline void
{
}
/*
* function to free WQE mapping descriptor
*
* wq - pointer to WQ structure
* wqmd - Pointer to WQ mapping descriptor
*
* return none
*/
static void
{
return;
}
}
/*
* WQED kmem_cache constructor
*
* buf - pointer to WQE descriptor
*
* return DDI_SUCCESS
*/
int
{
return (DDI_SUCCESS);
}
/*
* WQED kmem_cache destructor
*
* buf - pointer to WQE descriptor
*
* return none
*/
void
{
}
/*
* function to choose a WQ given a mblk depending on priority, flowID etc.
*
* dev - software handle to device
* mp - the mblk to send
*
* return pointer to the WQ selected
*/
struct oce_wq *
{
int qidx = 0;
} else {
qidx = 0;
}
/* for the time being hardcode */
return (wq);
} /* oce_get_wq */
/*
* function to populate the single WQE
*
* wq - pointer to wq
* wqed - pointer to WQ entry descriptor
*
* return none
*/
#pragma inline(oce_fill_ring_descs)
static void
{
int i;
/* Copy the precreate WQE descs to the ring desc */
struct oce_nic_frag_wqe);
}
} /* oce_fill_ring_descs */
/*
* function to copy the packet to preallocated Tx buffer
*
* wq - pointer to WQ
* wqed - Pointer to WQE descriptor
* mp - Pointer to packet chain
* pktlen - Size of the packet
*
* return 0=>success, error code otherwise
*/
static int
{
int len = 0;
"wqb pool empty");
return (ENOMEM);
}
/* create a fragment wqe for the packet */
/* copy pkt into buffer */
}
/* Free the buffer */
return (EIO);
}
return (0);
} /* oce_bcopy_wqe */
/*
* function to copy the packet or dma map on the fly depending on size
*
* wq - pointer to WQ
* wqed - Pointer to WQE descriptor
* mp - Pointer to packet chain
*
* return DDI_SUCCESS=>success, DDI_FAILURE=>error
*/
static int
{
int ret;
"wqm pool empty");
return (ENOMEM);
}
if (ret != DDI_DMA_MAPPED) {
ret);
/* free the last one */
return (ENOMEM);
}
do {
if (--ncookies > 0)
&cookie);
else break;
} while (ncookies > 0);
return (0);
} /* oce_map_wqe */
static inline int
{
int wqe_freed = 0;
while (WQ_CQE_VALID(cqe)) {
/* update stats */
}
/* complete the WQEs */
/* clear the valid bit and progress cqe */
struct oce_nic_tx_cqe);
num_cqe++;
} /* for all valid CQE */
if (num_cqe)
return (num_cqe);
} /* oce_process_tx_completion */
/*
* function to drain a TxCQ and process its CQEs
*
* dev - software handle to the device
* cq - pointer to the cq to drain
*
* return the number of CQEs processed
*/
{
/* do while we do not reach a cqe that is not valid */
/* check if we need to restart Tx */
}
return (num_cqe);
} /* oce_process_wq_cqe */
/*
* function to insert vtag to packet
*
* mp - mblk pointer
* vlan_tag - tag to be inserted
*
* return none
*/
static inline void
{
}
/*
* function to strip vtag from packet
*
* mp - mblk pointer
*
* return none
*/
static inline void
{
ETHERADDRL * 2);
}
/*
* function to xmit Single packet over the wire
*
* wq - pointer to WQ
* mp - Pointer to packet chain
*
* return pointer to the packet
*/
mblk_t *
{
int num_mblks = 0;
int ret = 0;
int len = 0;
/* retrieve the adap priv struct ptr */
/* check if we have enough free slots */
}
return (mp);
}
/* check if we should copy */
num_mblks++;
}
return (NULL);
}
/* retrieve LSO information */
/* get the offload flags */
/* restrict the mapped segment to wat we support */
if (num_mblks > OCE_MAX_TX_HDL) {
return (NULL);
}
/* Reset it to new collapsed mp */
}
/* Get the packet descriptor for Tx */
return (NULL);
}
ip_offset = sizeof (struct ether_vlan_header);
} else {
ip_offset = sizeof (struct ether_header);
}
/* Save the WQ pointer */
/* If entire packet is less than the copy limit just do copy */
} else {
/* copy or dma map the individual fragments */
if (len == 0) {
continue;
}
} else {
}
if (ret != 0)
break;
}
}
/*
* Any failure other than insufficient Q entries
* drop the packet
*/
if (ret != 0) {
return (NULL);
}
/* fill rest of wqe header fields based on packet */
}
if (csum_flags & HCK_FULLCKSUM) {
if (etype == ETHERTYPE_IP) {
/* IPPROTO_TCP */
/* IPPROTO_UDP */
}
}
if (csum_flags & HCK_IPV4_HDRCKSUM)
if (tagged) {
}
/* h/w expects even no. of WQEs */
if (num_wqes & 0x1) {
num_wqes++;
}
goto wqe_fail;
}
/* fill the wq for adapter */
/* Set the mp pointer in the wqe descriptor */
}
/* Add the packet desc to list to be retrieved during cmpl */
/* ring tx doorbell */
/* Ring the door bell */
}
/* free mp if copied or packet chain collapsed */
}
return (NULL);
if (tagged) {
}
return (mp);
} /* oce_send_packet */
/*
* function to free the WQE descriptor
*
* wq - pointer to WQ
* wqed - Pointer to WQE descriptor
*
* return none
*/
#pragma inline(oce_free_wqed)
static void
{
int i = 0;
return;
}
}
}
} /* oce_free_wqed */
/*
* function to start the WQ
*
* wq - pointer to WQ
*
* return DDI_SUCCESS
*/
int
{
return (DDI_SUCCESS);
} /* oce_start_wq */
/*
* function to stop the WQ
*
* wq - pointer to WQ
*
* return none
*/
void
{
int ti;
/* Wait for already posted Tx to complete */
OCE_MSDELAY(1);
}
/* Free the remaining descriptors */
}
} /* oce_stop_wq */
/*
* function to set the tx mapping handle fma attr
*
* fm_caps - capability flags
*
* return none
*/
void
{
if (fm_caps == DDI_FM_NOT_CAPABLE) {
return;
}
if (DDI_FM_DMA_ERR_CAP(fm_caps)) {
} else {
}
} /* oce_set_tx_map_dma_fma_flags */