oce_rx.c revision 4d0e50075058332ce0cd62bc2669a8a4dea45da0
/*
* 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 Emulex. All rights reserved.
* Use is subject to license terms.
*/
/*
* Source file containing the Recieve Path handling
* functions
*/
#include <oce_impl.h>
static void rx_pool_free(char *arg);
struct oce_nic_rx_cqe *cqe);
/*
* function to create a DMA buffer pool for RQ
*
* dev - software handle to the device
* num_items - number of buffers in the pool
* item_size - size of each buffer
*
* return DDI_SUCCESS => success, DDI_FAILURE otherwise
*/
int
{
int size;
int cnt;
int ret;
int nitems;
/* Create the free buffer list */
if (ret != DDI_SUCCESS) {
goto rqb_fail;
}
}
return (DDI_SUCCESS);
return (DDI_FAILURE);
} /* oce_rqb_cache_create */
/*
* function to Destroy RQ DMA buffer cache
*
* rq - pointer to rq structure
*
* return none
*/
void
{
!= NULL) {
}
} /* oce_rqb_cache_destroy */
/*
* RQ buffer destructor function
*
* rqbd - pointer to rq buffer descriptor
*
* return none
*/
static void
{
return;
}
/* Buffer is already free */
}
} /* oce_rqb_dtor */
/*
* RQ buffer constructor function
*
* rqbd - pointer to rq buffer descriptor
* rq - pointer to RQ structure
* size - size of the buffer
* flags - KM_SLEEP OR KM_NOSLEEP
*
* return DDI_SUCCESS => success, DDI_FAILURE otherwise
*/
static int
{
return (DDI_FAILURE);
}
/* override usable length */
return (DDI_SUCCESS);
} /* oce_rqb_ctor */
/*
* RQ buffer allocator function
*
* rq - pointer to RQ structure
*
* return pointer to RQ buffer descriptor
*/
static inline oce_rq_bdesc_t *
{
return (rqbd);
} /* oce_rqb_alloc */
/*
* function to free the RQ buffer
*
* rq - pointer to RQ structure
* rqbd - pointer to recieve buffer descriptor
*
* return none
*/
static inline void
{
} /* oce_rqb_free */
/*
* function to charge a given rq with buffers from a pool's free list
*
* dev - software handle to the device
* rq - pointer to the RQ to charge
* nbufs - numbers of buffers to be charged
*
* return number of rqe's charges.
*/
static inline int
{
struct oce_nic_rqe *rqe;
struct rq_shadow_entry *shadow_rq;
int32_t total_bufs = 0;
/* check number of slots free and recharge */
int i = 0;
const int retries = 1000;
do {
break;
}
} while ((++i) < retries);
"rqb pool empty @ ticks",
(uint32_t)ddi_get_lbolt());
break;
}
i = 0;
do {
break;
}
} while ((++i) < retries);
}
/*
* Failed again put back the buffer and continue
* loops for nbufs so its a finite loop
*/
continue;
}
/* fill the rqes */
struct oce_nic_rqe);
/* if we have reached the max allowed posts, post */
num_bufs = 0;
}
num_bufs++;
total_bufs++;
}
/* post pending bufs */
if (num_bufs) {
}
return (total_bufs);
} /* oce_rq_charge */
/*
* function to release the posted buffers
*
* rq - pointer to the RQ to charge
*
* return none
*/
void
{
struct rq_shadow_entry *shadow_rq;
/* Free the posted buffer since RQ is destroyed already */
}
}
/*
* function to process a single packet
*
* dev - software handle to the device
* rq - pointer to the RQ to charge
* cqe - Pointer to Completion Q entry
*
* return mblk pointer => success, NULL => error
*/
static inline mblk_t *
{
uint32_t csum_flags = 0;
int pkt_len;
int frag_size;
struct rq_shadow_entry *shadow_rq;
struct rq_shadow_entry *shadow_rqe;
struct ether_vlan_header *ehp;
/* Get the relevant Queue pointers */
/* Hardware always Strips Vlan tag so insert it back */
/* retrive the Rx buffer from the shadow ring */
return (NULL);
/* Move the pointers */
frag_cnt++;
}
return (NULL);
/* Chain the message mblks */
} else {
}
}
return (NULL);
}
/* check dma handle */
DDI_FM_OK) {
return (NULL);
}
/* set flags */
}
}
if (csum_flags) {
csum_flags, 0);
}
return (mblk_head);
} /* oce_rx */
/*
* function to process a Recieve queue
*
* arg - pointer to the RQ to charge
*
* return number of cqes processed
*/
oce_drain_rq_cq(void *arg)
{
struct oce_nic_rx_cqe *cqe;
return (0);
return (0);
/* dequeue till you reach an invalid cqe */
} else {
}
}
struct oce_nic_rx_cqe);
num_cqe++;
} /* for all valid CQEs */
if (mblk_head) {
}
return (num_cqe);
} /* oce_drain_rq_cq */
/*
* function to free mblk databuffer to the RQ pool
*
* arg - pointer to the receive buffer descriptor
*
* return none
*/
static void
rx_pool_free(char *arg)
{
int i = 0;
const int retries = 1000;
/* During destroy, arg will be NULL */
return;
}
/* retrieve the pointers from arg */
return;
}
do {
break;
}
} while ((++i) < retries);
/*
* Rx has stalled because of lack of buffers
* So try to charge fully
*/
}
} /* rx_pool_free */
/*
* function to stop the RX
*
* rq - pointer to RQ structure
*
* return none
*/
void
{
/*
* Wait for Packets sent up to be freed
*/
}
/* Drain the Event queue now */
} /* oce_stop_rq */
/*
* function to start the RX
*
* rq - pointer to RQ structure
*
* return number of rqe's charges.
*/
int
{
int ret = 0;
return (ret);
} /* oce_start_rq */