nge_tx.c revision 9fa05d92f6b225eb418fb782225c991b887ea8b7
/*
* 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 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include "nge.h"
#define TXD_OWN 0x80000000
#define TXD_ERR 0x40000000
#define TXD_END 0x20000000
#define TXD_BCNT_MSK 0x00003FFF
#define NGE_DBG NGE_DBG_SEND
#define NGE_TXSWD_RECYCLE(sd) {\
}
#pragma no_inline(nge_tx_recycle_all)
void
{
}
}
}
static size_t
{
;
if (num == 0) {
}
return (num);
}
static void
{
else
}
static void
{
else {
type);
}
}
/*
* Reclaim the resource after tx's completion
*/
void
{
int resched;
void *hw_sbd_p;
if (is_intr) {
return;
} else
/*
* Look through the send ring by bd's status part
* to find all the bds which has been transmitted sucessfully
* then reclaim all resouces associated with these bds
*/
break;
break;
}
}
/*
* We're about to release one or more places :-)
* These ASSERTions check that our invariants still hold:
* there must always be at least one free place
* at this point, there must be at least one place NOT free
* we're not about to free more places than were claimed!
*/
}
/*
* up to this place, we maybe have reclaim some resouce
* if there is a requirement to report to gld, report this.
*/
if (resched)
}
static uint32_t
{
}
}
return (start);
}
static void
{
/*
* Because there can be multiple concurrent threads in
* transit through this code, we only want to notify the
* hardware once the last one is departing ...
*/
/*
* Bump the watchdog counter, thus guaranteeing that it's
* nonzero (watchdog activated). Note that non-synchonised
* access here means we may race with the reclaim() code
* above, but the outcome will be harmless. At worst, the
* counter may not get reset on a partial reclaim; but the
* large trigger threshold makes false positives unlikely
*/
}
}
static enum send_status
#pragma inline(nge_send_copy)
static enum send_status
{
char *txb;
void *hw_sbd_p;
bds = 0x1;
return (SEND_COPY_FAIL);
/*
* up to this point, there's nothing that can fail,
* so we can go straight to claiming our
* already-reserved place son the train.
*
* This is the point of no return!
*/
totlen = 0;
totlen = 0;
continue;
}
}
/* Fill & sync hw desc */
/*
* The return status indicates that the message can be freed
* right away, as we've already copied the contents ...
*/
return (SEND_COPY_SUCESS);
}
/*
* static enum send_status
* nge_send_mapped(nge_t *ngep, mblk_t *mp, size_t fragno);
* #pragma inline(nge_send_mapped)
*/
static enum send_status
{
int err;
uint32_t i;
uint32_t j;
void *hw_sbd_p;
if (err != 0) {
return (SEND_MAP_FAIL);
}
/*
* Pre-scan the message chain, noting the total number of bytes,
* the number of fragments by pre-doing dma addr bind
* if the fragment is larger than NGE_COPY_SIZE.
* This way has the following advantages:
* 1. Acquire the detailed information of resouce
* need to send the message
*
* 2. If can not pre-apply enough resouce, fails at once
* and the driver will chose copy way to send out the
* message
*/
slot = 0;
if (mblen == 0)
continue;
/*
* If there can not map successfully, it is uncessary
* sending the message by map way. Sending the message
* by copy way.
*
* By referring to intel's suggestion, it is better
* the number of cookies should be less than 4.
*/
NGE_DEBUG(("err(%x) map tx bulk fails"
" cookie(%x), ncookies(%x)",
goto map_fail;
}
/*
* Check How many bds a cookie will consume
*/
;
}
/*
* Now allocate tx descriptors and fill them
* IMPORTANT:
* Up to the point where it claims a place, It is impossibel
* to fail.
*
* In this version, there's no setup to be done here, and there's
* nothing that can fail, so we can go straight to claiming our
* already-reserved places on the train.
*
* This is the point of no return!
*/
goto map_fail;
/* fill&sync hw desc, going in reverse order */
}
/* fill sw desc */
}
/*
* The return status indicates that the message can not be freed
* right away, until we can make assure the message has been sent
* out sucessfully.
*/
return (SEND_MAP_SUCCESS);
return (SEND_MAP_FAIL);
}
static boolean_t
{
enum send_status status;
/*
* 1.Check the number of the fragments of the messages
* If the total number is larger than 3,
* Chose copy way
*
* 2. Check the length of the message whether is larger than
* NGE_TX_COPY_SIZE, if so, choose the map way.
*/
continue;
frags++;
}
return (B_TRUE);
}
(frags <= NGE_MAP_FRAGS) &&
if (status == SEND_MAP_FAIL)
} else {
}
if (status == SEND_COPY_FAIL) {
if (status == SEND_COPY_FAIL) {
NGE_DEBUG(("nge_send: send fail!"));
return (B_FALSE);
}
}
/* Update the software statistics */
sw_stp->xmit_count ++;
return (B_TRUE);
}
/*
* nge_m_tx : Send a chain of packets.
*/
mblk_t *
{
}
break;
}
}
return (mp);
}
/* ARGSUSED */
{
/*
* when softintr is trigged, checking whether this
* is caused by our expected interrupt
*/
ngep->resched_needed = 0;
}
return (rslt);
}
nge_hot_txd_check(const void *hwd)
{
return (err_flag);
}
nge_sum_txd_check(const void *hwd)
{
return (err_flag);
}
/*
* Filling the contents of Tx's data descriptor
* before transmitting.
*/
void
{
/*
* Setting the length of the packet
* Note: the length filled in the part should be
* the original length subtract 1;
*/
/* setting ip checksum */
if (sum_flag & HCK_IPV4_HDRCKSUM)
= NGE_SET;
/* setting tcp checksum */
if (sum_flag & HCK_FULLCKSUM)
= NGE_SET;
/*
* indicating the end of BDs
*/
if (end)
/* pass desc to HW */
}
void
{
/*
* Setting the length of the packet
* Note: the length filled in the part should be
* the original length subtract 1;
*/
/* setting ip checksum */
if (sum_flag & HCK_IPV4_HDRCKSUM)
= NGE_SET;
/* setting tcp checksum */
if (sum_flag & HCK_FULLCKSUM)
= NGE_SET;
/*
* indicating the end of BDs
*/
if (end)
/* pass desc to HW */
}