/*
* 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
*/
/*
*/
#include <sys/sysmacros.h>
#include <net/if_types.h>
#include <sys/ethernet.h>
#include <inet/ip_ftable.h>
#include <sys/socketvar.h>
#include <sys/sysmacros.h>
#include <net/if_types.h>
#include <sys/mac_client.h>
#include <sys/mac_provider.h>
#include <sys/mac_client_priv.h>
extern kmem_cache_t *rdsv3_alloc_cache;
unsigned int sum);
/*
* Check if the IP interface named by `lifrp' is RDS-capable.
*/
{
char *cp;
return (B_TRUE);
/*
* Strip off the logical interface portion before getting
* intimate with the name.
*/
*cp = '\0';
/*
* loopback is considered RDS-capable
*/
return (B_TRUE);
}
}
int
{
int rval = 0;
int numifs;
int i, j, n, rc;
*size = 0;
*nifs = 0;
/* snapshot the current number of interfaces */
lifn.lifn_count = 0;
CRED());
if (rval != 0) {
RDSV3_DPRINTF2("rdsv3_do_ip_ioctl",
"ksocket_ioctl returned: %d", rval);
return (rval);
}
if (numifs <= 0) {
return (0);
}
/* allocate extra room in case more interfaces appear */
numifs += 10;
/* get the interface names and ip addresses */
if (rc != 0) {
return (rc);
}
/* if our extra room is used up, try again */
goto retry_count;
}
/* calc actual number of ifconfs */
/*
* Count the RDS interfaces
*/
/*
* Copy as the SIOCGLIFFLAGS ioctl is destructive
*/
/*
* fetch the flags using the socket of the correct family
*/
case AF_INET:
break;
default:
continue;
}
if (rc != 0) continue;
/*
* If we got the flags, skip uninteresting
* interfaces based on flags
*/
continue;
if (lifr.lifr_flags &
continue;
if (!rdsv3_capable_interface(&lifr))
continue;
j++;
}
if (j <= 0) {
return (rval);
}
numifs = j;
/* This is the buffer we pass back */
/*
* Examine the array of interfaces and filter uninteresting ones
*/
/*
* Copy the address as the SIOCGLIFFLAGS ioctl is destructive
*/
/*
* fetch the flags using the socket of the correct family
*/
case AF_INET:
break;
default:
continue;
}
if (rc != 0) {
RDSV3_DPRINTF2("rdsv3_do_ip_ioctl",
continue;
}
/*
* If we got the flags, skip uninteresting
* interfaces based on flags
*/
continue;
if (lifr.lifr_flags &
continue;
if (!rdsv3_capable_interface(&lifr))
continue;
/* save the record */
rlp++;
}
return (rval);
}
/*
* Check if the IP interface named by `ifrp' is RDS-capable.
*/
{
char *cp;
/*
* Strip off the logical interface portion before getting
* intimate with the name.
*/
*cp = '\0';
/*
* loopback and IB are considered RDS-capable
*/
return (B_TRUE);
}
}
int
{
int rval = 0;
int numifs;
int i, j, n, rc;
*size = 0;
*nifs = 0;
CRED());
if (rval != 0) {
RDSV3_DPRINTF2("rdsv3_do_ip_ioctl_old",
"ksocket_ioctl(SIOCGIFNUM) returned: %d", rval);
return (rval);
}
if (numifs <= 0) {
return (0);
}
/* allocate extra room in case more interfaces appear */
numifs += 10;
/* get the interface names and ip addresses */
if (rc != 0) {
RDSV3_DPRINTF2("rdsv3_do_ip_ioctl_old",
"SIOCGLIFCONF failed: %d", rc);
return (rc);
}
/* if our extra room is used up, try again */
goto retry_count;
}
/* calc actual number of ifconfs */
/*
* Count the RDS interfaces
*/
/*
* Copy as the SIOCGIFFLAGS ioctl is destructive
*/
/*
* fetch the flags using the socket of the correct family
*/
case AF_INET:
break;
default:
continue;
}
if (rc != 0) continue;
RDSV3_DPRINTF2("rdsv3_do_ip_ioctl_old",
/*
* If we got the flags, skip uninteresting
* interfaces based on flags
*/
continue;
RDSV3_DPRINTF2("rdsv3_do_ip_ioctl_old",
continue;
RDSV3_DPRINTF2("rdsv3_do_ip_ioctl_old",
if (!rdsv3_capable_interface_old(&ifr))
continue;
RDSV3_DPRINTF2("rdsv3_do_ip_ioctl_old",
j++;
}
if (j <= 0) {
return (rval);
}
numifs = j;
/* This is the buffer we pass back */
/*
* Examine the array of interfaces and filter uninteresting ones
*/
/*
* Copy the address as the SIOCGIFFLAGS ioctl is destructive
*/
/*
* fetch the flags using the socket of the correct family
*/
case AF_INET:
break;
default:
continue;
}
if (rc != 0) {
RDSV3_DPRINTF2("rdsv3_do_ip_ioctl_old",
"ksocket_ioctl failed: %d for %s",
continue;
}
/*
* If we got the flags, skip uninteresting
* interfaces based on flags
*/
continue;
continue;
if (!rdsv3_capable_interface_old(&ifr))
continue;
/* save the record */
rlp++;
}
return (rval);
}
{
return (B_FALSE);
}
return (B_TRUE);
}
/*
* Work Queue Implementation
*/
#define RDSV3_WQ_THREAD_IDLE 0
/* worker thread */
void
{
while (work) {
/* process work */
}
/* No more work, go home, until called again */
}
}
/* XXX */
void
{
case RDSV3_WQ_THREAD_IDLE:
/* nothing to do */
break;
case RDSV3_WQ_THREAD_RUNNING:
/* FALLTHRU */
case RDSV3_WQ_THREAD_FLUSHING:
/* already flushing, wait until the flushing is complete */
do {
break;
case RDSV3_WQ_THREAD_EXITING:
return;
}
}
void
{
/* This is already in the queue, ignore this call */
return;
}
case RDSV3_WQ_THREAD_RUNNING:
break;
case RDSV3_WQ_THREAD_FLUSHING:
do {
break;
}
/* FALLTHRU */
case RDSV3_WQ_THREAD_IDLE:
break;
case RDSV3_WQ_THREAD_EXITING:
break;
}
}
/* timeout handler for delayed work queuing */
void
{
RDSV3_DPRINTF4("rdsv3_work_timeout_handler",
return;
}
RDSV3_DPRINTF4("rdsv3_work_timeout_handler",
}
void
{
RDSV3_DPRINTF4("rdsv3_queue_delayed_work",
if (delay == 0) {
return;
}
RDSV3_DPRINTF4("rdsv3_queue_delayed_work",
return;
}
wq->wq_pending++;
} else {
dwp);
wq->wq_pending--;
}
RDSV3_DPRINTF4("rdsv3_queue_delayed_work",
}
void
{
RDSV3_DPRINTF4("rdsv3_cancel_delayed_work",
} else {
RDSV3_DPRINTF4("rdsv3_cancel_delayed_work",
return;
}
RDSV3_DPRINTF4("rdsv3_cancel_delayed_work",
}
void
{
while (wq->wq_pending > 0) {
};
rdsv3_taskq = NULL;
}
/* ARGSUSED */
void
{
}
{
if (rdsv3_taskq == NULL) {
"ddi_taskq_create failed for rdsv3_taskq");
return (NULL);
}
return (NULL);
}
wq->wq_pending = 0;
return (wq);
}
/*
* Implementation for struct sock
*/
void
{
}
/* XXX - figure out right values */
struct rsock *
{
return (NULL);
}
return (sk);
}
void
{
}
/*
* Connection cache
*/
/* ARGSUSED */
int
{
return (0);
}
/* ARGSUSED */
void
{
}
int
{
return (0);
return (-1);
return (1);
}
return (-1);
return (1);
}
/* rdsv3_ib_incoming cache */
/* ARGSUSED */
int
{
sizeof (struct rdsv3_page_frag),
return (0);
}
/* ARGSUSED */
void
{
}
/* ib_frag_slab cache */
/* ARGSUSED */
int
{
RDSV3_DPRINTF2("rdsv3_ib_frag_constructor",
"kmem_alloc for %d failed", PAGE_SIZE);
return (-1);
}
iov_attr.iov_lso_hdr_sz = 0;
RDSV3_DPRINTF2("rdsv3_ib_frag_constructor",
"ibt_map_mem_iov failed");
return (-1);
}
return (0);
}
/* ARGSUSED */
void
{
/* unmap the page */
RDSV3_DPRINTF2("rdsv3_ib_frag_destructor",
"ibt_unmap_mem_iov failed");
/* free the page */
}
/* loop.c */
extern kmutex_t loop_conns_lock;
extern list_t loop_conns;
struct rdsv3_loop_connection
{
};
void
rdsv3_loop_init(void)
{
}
/* rdma.c */
/* IB Rkey is used here for comparison */
int
{
return (-1);
return (1);
return (0);
}
/* transport.c */
extern struct rdsv3_transport *transports[];
void
rdsv3_trans_exit(void)
{
int i;
/* currently, only IB transport */
for (i = 0; i < RDS_TRANS_COUNT; i++) {
if (transports[i]) {
trans = transports[i];
break;
}
}
/* trans->exit() will remove the trans from the list */
if (trans)
}
void
{
}
int
void *payload)
{
char *bp;
RDSV3_DPRINTF4("rdsv3_put_cmsg",
"Enter(msg: %p level: %d type: %d sz: %d)",
return (0);
}
/* check for first cmsg or this is another cmsg to be appended */
msg->msg_controllen = 0;
/* extend the existing cmsg to append the next cmsg */
if (msg->msg_control) {
}
/* assign payload the proper cmsg location */
(unsigned int)_CMSG_DATA_ALIGN(sizeof (struct cmsghdr)));
return (0);
}
/* ARGSUSED */
int
{
return (1);
}
/* checksum */
{
return (0xffff &
}
/* scatterlist implementation */
/* ARGSUSED */
{
return (0);
}
{
uint_t i;
for (i = 0; i < num; i++, s++) {
}
iov_attr.iov_lso_hdr_sz = 0;
if (i != IBT_SUCCESS) {
RDSV3_DPRINTF2("rdsv3_ib_dma_map_sg",
"ibt_map_mem_iov returned: %d", i);
return (0);
}
s = first;
}
return (num);
}
void
{
/* Zero length messages have no scatter gather entries */
if (num != 0) {
}
}
int
{
int ret;
sizeof (struct rdsv3_header);
return (-1);
if (ret != IBT_SUCCESS) {
RDSV3_DPRINTF2("rdsv3_ib_alloc_hdrs",
"ibt_register_mr returned: " "%d", ret);
return (-1);
}
KM_SLEEP);
sizeof (struct rdsv3_header)));
sizeof (struct rdsv3_header)));
return (0);
}
void
{
}
/*
* atomic_add_unless - add unless the number is a given value
* @v: pointer of type atomic_t
* @a: the amount to add to v...
* @u: ...unless v is equal to u.
*
* Atomically adds @a to @v, so long as it was not @u.
* Returns non-zero if @v was not @u, and zero otherwise.
*/
int
{
c = *v;
while (c != u && (old = atomic_cas_uint(v, c, c + a)) != c) {
c = old;
}
return ((ulong_t)c != u);
}