nge_rx.c revision a55f711916b9f7718fabc2d1822bf5719aa6140f
/*
* 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 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include "nge.h"
#define NGE_DBG NGE_DBG_RECV
#define RXD_END 0x20000000
#define RXD_ERR 0x40000000
#define RXD_OWN 0x80000000
#define RXD_CSUM_MSK 0x1C000000
#define RXD_BCNT_MSK 0x00003FFF
#define RXD_CK8G_NO_HSUM 0x0
#define RXD_CK8G_TCP_SUM_ERR 0x04000000
#define RXD_CK8G_UDP_SUM_ERR 0x08000000
#define RXD_CK8G_IP_HSUM_ERR 0x0C000000
#define RXD_CK8G_IP_HSUM 0x10000000
#define RXD_CK8G_TCP_SUM 0x14000000
#define RXD_CK8G_UDP_SUM 0x18000000
#define RXD_CK8G_RESV 0x1C000000
/*
* Callback code invoked from STREAMs when the recv data buffer is free for
* recycling.
*
* The following table describes function behaviour:
*
* | mac stopped | mac running
* ---------------------------------------------------
* buffer delivered | free buffer | recycle buffer
* buffer not delivered | do nothing | recycle buffer (*)
*
* Note (*):
* Recycle buffer only if mac state did not change during execution of
* function. Otherwise if mac state changed, set buffer delivered & re-enter
* function by calling freemsg().
*/
void
{
/*
* Free the buffer directly if the buffer was allocated
* previously or mac was stopped.
*/
}
return;
}
/*
* recycle the data buffer again and fill them in free ring
*/
sw_stp->mp_alloc_err++;
} else {
else
}
/* call nge_rx_recycle again to free it */
else {
}
}
}
/*
* Checking the rx's BDs (one or more) to receive
* one complete packet.
* start_index: the start indexer of BDs for one packet.
* end_index: the end indexer of BDs for one packet.
*/
#pragma inline(nge_recv_packet)
static mblk_t *
{
void *hw_bd_p;
/*
* First check the free_list, if it is NULL,
* make the recycle_list be free_list.
*/
}
/* If it's not a qualified packet, delete it */
return (NULL);
}
/*
* If receive packet size is smaller than RX bcopy threshold,
* or there is no available buffer in free_list or recycle list,
* we use bcopy directly.
*/
else
sw_stp->mp_alloc_err++;
return (NULL);
}
} else {
/*
* Make sure the packet *contents* 4-byte aligned
*/
/* Fill the buffer from free_list */
}
/* replenish the buffer for hardware descriptor */
sw_stp->recv_count++;
return (mp);
}
#define RX_HW_ERR 0x01
#define RX_SUM_NO 0x02
#define RX_SUM_ERR 0x04
/*
* Statistic the rx's error
* and generate a log msg for these.
* Note:
* RXE, Parity Error, Symbo error, CRC error
* have been recored by nvidia's hardware
* statistics part (nge_statistics). So it is uncessary to record them by
* driver in this place.
*/
static uint32_t
#pragma inline(nge_rxsta_handle)
static uint32_t
{
err_flag = 0;
return (RX_HW_ERR);
switch (errors) {
default:
break;
case RXD_CK8G_TCP_SUM:
case RXD_CK8G_UDP_SUM:
*pflags |= HCK_FULLCKSUM;
*pflags |= HCK_IPV4_HDRCKSUM;
*pflags |= HCK_FULLCKSUM_OK;
break;
case RXD_CK8G_TCP_SUM_ERR:
case RXD_CK8G_UDP_SUM_ERR:
sw_stp->tcp_hwsum_err++;
*pflags |= HCK_IPV4_HDRCKSUM;
break;
case RXD_CK8G_IP_HSUM:
*pflags |= HCK_IPV4_HDRCKSUM;
break;
case RXD_CK8G_NO_HSUM:
break;
case RXD_CK8G_IP_HSUM_ERR:
sw_stp->ip_hwsum_err++;
err_flag |= RX_SUM_ERR;
break;
}
}
return (err_flag);
}
static mblk_t *
{
void * hw_bd_p;
/* Sync the descriptor for kernel */
} else {
0,
0,
}
/*
* Looking through the rx's ring to find the good packets
* and try to receive more and more packets in rx's ring
*/
for (;;) {
sum_flags = 0;
flag_err = 0;
/*
* If there is no packet in receving ring
* break the loop
*/
break;
ngep->recv_count++;
} else {
/* Hardware error, re-use the buffer */
}
0, 0, 0, 0, sum_flags, 0);
}
}
break;
}
/* Sync the descriptors for device */
} else {
0,
0,
}
return (head);
}
void
{
}
void
{
}
void
{
}
{
return (err_flag);
}
{
return (err_flag);
}