/*
* Copyright (C) 2007 VMware, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of the Common
* Development and Distribution License (the "License") version 1.0
* and no later version. You may not use this file except in
* compliance with the License.
*
* You can obtain a copy of the License at
*
* See the License for the specific language governing permissions
* and limitations under the License.
*/
/*
* Copyright (c) 2013, 2016 by Delphix. All rights reserved.
*/
#include <vmxnet3.h>
static void vmxnet3_put_rxbuf(vmxnet3_rxbuf_t *);
/*
* Allocate a new rxBuf from memory. All its fields are set except
* for its associated mblk which has to be allocated later.
*
* Returns:
* A new rxBuf or NULL.
*/
static vmxnet3_rxbuf_t *
{
int err;
if (!rxBuf) {
return (NULL);
}
canSleep)) != 0) {
return (NULL);
}
return (rxBuf);
}
static void
{
#ifndef DEBUG
#else
{
}
#endif
}
/*
* Return a rxBuf to the pool. The init argument, when B_TRUE, indicates
* that we're being called for the purpose of pool initialization, and
* therefore, we should place the buffer in the pool even if the device
* isn't enabled.
*
* Returns:
* B_TRUE if the buffer was returned to the pool, or B_FALSE if it
* wasn't (e.g. if the device is stopped).
*/
static boolean_t
{
}
return (returned);
}
/*
* Return a rxBuf to the pool or free it.
*/
static void
{
}
/*
* Get an unused rxBuf from the pool.
*
* Returns:
* A rxBuf or NULL if there are no buffers in the pool.
*/
static vmxnet3_rxbuf_t *
{
}
return (rxBuf);
}
/*
* Fill a rxPool by allocating the maximum number of buffers.
*
* Returns:
* 0 on success, non-zero on failure.
*/
static int
{
int err = 0;
break;
}
}
if (err != 0) {
}
}
return (err);
}
/*
* Populate a Rx descriptor with a new rxBuf. If the pool argument is B_TRUE,
* then try to take a buffer from rxPool. If the pool is empty and the
* dp->alloc_ok is true, then fall back to dynamic allocation. If pool is
* B_FALSE, then always allocate a new buffer (this is only used when
* populating the initial set of buffers in the receive queue during start).
*
* Returns:
* 0 on success, non-zero on failure.
*/
static int
{
/* The maximum number of pool buffers have been allocated. */
}
}
}
if (pool) {
B_FALSE));
} else {
}
return (ENOMEM);
}
/* rxDesc->rxd.btype = 0; */
} else {
return (ENOMEM);
}
return (0);
}
/*
* Initialize a RxQueue by populating the whole Rx ring with rxBufs.
*
* Returns:
* 0 on success, non-zero on failure.
*/
int
{
int err;
do {
goto error;
}
/*
* Pre-allocate rxPool buffers so that we never have to allocate
* new buffers from interrupt context when we need to replace a buffer
* in the rxqueue.
*/
goto error;
}
return (0);
}
return (err);
}
/*
* Finish a RxQueue by freeing all the related rxBufs.
*/
void
{
unsigned int i;
/* First the rxPool */
/* Then the ring */
/*
* Here, freemsg() will trigger a call to vmxnet3_put_rxbuf()
* which will then call vmxnet3_free_rxbuf() because the
* underlying device is disabled.
*/
}
}
/*
* Determine if a received packet was checksummed by the Vmxnet3
* device and tag the mp appropriately.
*/
static void
{
}
}
}
}
/*
* Interrupt handler for Rx. Look if there are any pending Rx and
* put them in mplist.
*
* Returns:
* A list of messages to pass to the MAC subystem.
*/
mblk_t *
{
do {
/*
* H/W may be still be in the middle of
* generating this entry, so hold on until
* the gen bit is flipped.
*/
}
/* Some Rx descriptors may have been skipped */
}
/*
* Now we have a piece of the packet in the rxdIdx
* descriptor. Grab it only if we achieve to replace
* it with a fresh buffer.
*/
B_TRUE) == 0) {
/* Success, we can chain the mblk with the mp */
rxdIdx);
if (eop) {
/*
* Tag the mp if it was
* checksummed by the H/W
*/
compDesc);
} else {
}
}
} else {
/*
* Keep the same buffer, we still need
* to flip the gen bit
*/
}
} while (!eop);
if (mp) {
if (mpValid) {
*mplistTail = mp;
} else {
/* This message got holes, drop it */
}
}
}
if (rxqCtrl->updateRxProd) {
/*
* All buffers are actually available, but we can't tell that to
* the device because it may interpret that as an empty ring.
* So skip one buffer.
*/
} else {
}
}
return (mplist);
}