Adds the files that handle various configurable parameters of the 
driver ---- configuration of virtual NIC, control, data connections
to the VEx and general IB connection parameters.

Signed-off-by: Ramachandra K <[EMAIL PROTECTED]>
---

 drivers/infiniband/ulp/vnic/vnic_config.c |  739 +++++++++++++++++++++++++++++
 drivers/infiniband/ulp/vnic/vnic_config.h |  215 ++++++++
 2 files changed, 954 insertions(+), 0 deletions(-)

diff --git a/drivers/infiniband/ulp/vnic/vnic_config.c 
b/drivers/infiniband/ulp/vnic/vnic_config.c
new file mode 100644
index 0000000..61db4ee
--- /dev/null
+++ b/drivers/infiniband/ulp/vnic/vnic_config.c
@@ -0,0 +1,739 @@
+/*
+ * Copyright (c) 2006 SilverStorm Technologies Inc.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <linux/netdevice.h>
+#include <linux/string.h>
+#include <linux/utsname.h>
+
+#include <rdma/ib_cache.h>
+
+#include "vnic_util.h"
+#include "vnic_config.h"
+#include "vnic_trailer.h"
+
+#define CONFIG_PARAM(x) u32 x = 0xffffffff;
+#define DEFAULT_PARAM(x, y)            \
+       do {                            \
+               if (x == 0xffffffff)    \
+                        x = y;         \
+       } while(0)
+
+#define boolean_range_check(x)         __range_check(x, 0, 1, #x)
+#define u32_zero_range_check(x)                __range_check(x, 0, 0x7FFFFFFF, 
#x)
+#define u32_range_check(x)             __range_check(x, 1, 0x7FFFFFFF, #x)
+#define u16_zero_range_check(x)                __range_check(x, 0, 0xFFFF, #x)
+#define u16_range_check(x)             __range_check(x, 1, 0xFFFF, #x)
+#define u8_zero_range_check(x)         __range_check(x, 0, 0xFF, #x)
+#define u8_range_check(x)              __range_check(x, 1, 0xFF, #x)
+
+#define range_check(x, min, max)       __range_check(x, min, max, #x)
+#define less_or_equal_check(lo, hi)    __less_or_equal_check(lo, hi, #lo, #hi)
+#define less_than_check(lo, hi)                __less_than_check(lo, hi, #lo, 
#hi)
+#define power_of_2_check(num)          __power_of_2_check(num, #num)
+
+CONFIG_PARAM(max_address_entries);
+CONFIG_PARAM(min_address_entries);
+
+CONFIG_PARAM(min_mtu);
+module_param(min_mtu, int, 0444);
+
+CONFIG_PARAM(max_mtu);
+module_param(max_mtu, int, 0444);
+
+CONFIG_PARAM(host_recv_pool_entries);
+module_param(host_recv_pool_entries, int, 0444);
+
+CONFIG_PARAM(min_host_pool_sz);
+module_param(min_host_pool_sz, int, 0444);
+
+CONFIG_PARAM(min_eioc_pool_sz);
+module_param(min_eioc_pool_sz, int, 0444);
+
+CONFIG_PARAM(max_eioc_pool_sz);
+module_param(max_eioc_pool_sz, int, 0444);
+
+CONFIG_PARAM(min_host_kick_timeout);
+module_param(min_host_kick_timeout, int, 0444);
+
+CONFIG_PARAM(max_host_kick_timeout);
+module_param(max_host_kick_timeout, int, 0444);
+
+CONFIG_PARAM(min_host_kick_entries);
+module_param(min_host_kick_entries, int, 0444);
+
+CONFIG_PARAM(max_host_kick_entries);
+module_param(max_host_kick_entries, int, 0444);
+
+CONFIG_PARAM(min_host_kick_bytes);
+module_param(min_host_kick_bytes, int, 0444);
+
+CONFIG_PARAM(max_host_kick_bytes);
+module_param(max_host_kick_bytes, int, 0444);
+
+CONFIG_PARAM(min_host_update_sz);
+module_param(min_host_update_sz, int, 0444);
+
+CONFIG_PARAM(max_host_update_sz);
+module_param(max_host_update_sz, int, 0444);
+
+CONFIG_PARAM(min_eioc_update_sz);
+module_param(min_eioc_update_sz, int, 0444);
+
+CONFIG_PARAM(max_eioc_update_sz);
+module_param(max_eioc_update_sz, int, 0444);
+
+CONFIG_PARAM(notify_bundle_sz);
+module_param(notify_bundle_sz, int, 0444);
+
+CONFIG_PARAM(viport_stats_interval);
+CONFIG_PARAM(viport_hb_interval);
+CONFIG_PARAM(viport_hb_timeout);
+CONFIG_PARAM(control_rsp_timeout);
+CONFIG_PARAM(control_req_retry_count);
+
+/* Infiniband connection values */
+CONFIG_PARAM(retry_count);
+module_param(retry_count, int, 0444);
+
+MODULE_PARM_DESC(retry_count,
+                "number of errors that sender receives"
+                " before posting completion error. min:0 max:7");
+
+CONFIG_PARAM(sa_path_rec_get_timeout);
+module_param(sa_path_rec_get_timeout, int, 0444);
+MODULE_PARM_DESC(sa_path_rec_get_timeout,
+                "Time out value in milliseconds to be used in"
+                " SA path record get queries");
+
+CONFIG_PARAM(min_rnr_timer);
+
+CONFIG_PARAM(default_viports_per_netpath);
+CONFIG_PARAM(max_viports_per_netpath);
+
+CONFIG_PARAM(default_pkey);
+module_param(default_pkey, int, 0444);
+
+CONFIG_PARAM(default_no_path_timeout);
+CONFIG_PARAM(default_primary_connect_timeout);
+CONFIG_PARAM(default_primary_reconnect_timeout);
+CONFIG_PARAM(default_primary_switch_timeout);
+CONFIG_PARAM(default_prefer_primary);
+
+module_param(default_prefer_primary, int, 0444);
+module_param(default_no_path_timeout, int, 0444);
+module_param(default_primary_reconnect_timeout, int, 0444);
+module_param(default_primary_switch_timeout, int, 0444);
+
+CONFIG_PARAM(use_rx_csum);
+module_param(use_rx_csum, int, 0444);
+
+CONFIG_PARAM(use_tx_csum);
+module_param(use_tx_csum, int, 0444);
+
+static void config_control_defaults(struct control_config *control_config,
+                                   struct path_param *params)
+{
+       int len;
+       char *dot;
+       __be64 sid;
+
+       /* extracting the service id from the IOC guid */
+       sid = 0x10LL << 56 |
+           0x00LL << 48 |
+           0x06LL << 40 |
+           0x6aLL << 32 |
+           0x00LL << 24 |
+           0x00LL << 16 |
+           0x00LL << 8 | ((be64_to_cpu(params->ioc_guid) >> 32) & 0xFF);
+
+       control_config->ib_config.service_id = cpu_to_be64(sid);
+
+       control_config->ib_config.conn_data.path_id = 0;
+       control_config->ib_config.conn_data.vnic_instance = params->instance;
+       control_config->ib_config.conn_data.path_num = 0;
+       dot = strchr(system_utsname.nodename, '.');
+       if (dot != NULL) {
+               len = dot - system_utsname.nodename;
+       } else {
+               len = strlen(system_utsname.nodename);
+       }
+       memcpy(control_config->ib_config.conn_data.nodename,
+              system_utsname.nodename, len);
+
+       control_config->ib_config.retry_count = retry_count;
+       control_config->ib_config.rnr_retry_count = retry_count;
+       control_config->ib_config.min_rnr_timer = min_rnr_timer;
+
+       control_config->ib_config.num_recvs = 5;        /* not configurable */
+       control_config->ib_config.num_sends = 1;        /* not configurable */
+       control_config->ib_config.recv_scatter = 1;     /* not configurable */
+       control_config->ib_config.send_gather = 1;      /* not configurable */
+
+       control_config->num_recvs = control_config->ib_config.num_recvs;
+
+       control_config->vnic_instance = params->instance;
+       control_config->max_address_entries = max_address_entries;
+       control_config->min_address_entries = min_address_entries;
+       control_config->req_retry_count = control_req_retry_count;
+       control_config->rsp_timeout = CONV2JIFFIES(control_rsp_timeout);
+
+       return;
+}
+
+static void config_data_defaults(struct data_config *data_config,
+                                struct path_param *params)
+{
+       __be64 sid;
+
+       /* extracting the service id from the IOC guid */
+       sid = 0x10LL << 56 |
+           0x00LL << 48 |
+           0x06LL << 40 |
+           0x6aLL << 32 |
+           0x00LL << 24 |
+           0x00LL << 16 |
+           0x01LL << 8 | ((be64_to_cpu(params->ioc_guid) >> 32) & 0xFF);
+
+       data_config->ib_config.service_id = cpu_to_be64(sid);
+
+       data_config->ib_config.conn_data.path_id = jiffies;     /* random */
+       data_config->ib_config.conn_data.vnic_instance = params->instance;
+       data_config->ib_config.conn_data.path_num = 0;
+
+       data_config->ib_config.retry_count = retry_count;
+       data_config->ib_config.rnr_retry_count = retry_count;
+       data_config->ib_config.min_rnr_timer = min_rnr_timer;
+
+       /*
+        * NOTE: the num_recvs size assumes that the EIOC could
+        * RDMA enough packets to fill all of the host recv
+        * pool entries, plus send a kick message after each
+        * packet, plus RDMA new buffers for the size of
+        * the EIOC recv buffer pool, plus send kick messages
+        * after each min_host_update_sz of new buffers all
+        * before the host can even pull off the first completed
+        * receive off the completion queue, and repost the
+        * receive. NOT LIKELY!
+        */
+       data_config->ib_config.num_recvs = host_recv_pool_entries +
+           (max_eioc_pool_sz / min_host_update_sz);
+#if defined(LIMIT_OUTSTANDING_SENDS)
+       data_config->ib_config.num_sends = (2 * notify_bundle_sz) +
+           (host_recv_pool_entries / min_eioc_update_sz) + 1;
+#else                          /* !defined(LIMIT_OUTSTANDING_SENDS) */
+       /*
+        * NOTE: the num_sends size assumes that the HOST could
+        * post RDMA sends for every single buffer in the eiocs
+        * receive pool, and allocate a full complement of
+        * receive buffers on the host, and RDMA free buffers
+        * every min_eioc_update_sz entries all before the HCA
+        * can complete a single RDMA transfer. VERY UNLIKELY,
+        * BUT NOT COMPLETELY IMPOSSIBLE IF THERE IS AN IB
+        * PROBLEM!
+        */
+       data_config->ib_config.num_sends = max_eioc_pool_sz +
+           (host_recv_pool_entries / min_eioc_update_sz) + 1;
+#endif /* !defined(LIMIT_OUTSTANDING_SENDS) */
+
+       data_config->ib_config.recv_scatter = 1; /* not configurable */
+       data_config->ib_config.send_gather = 2;  /* not configurable */
+
+       data_config->num_recvs = data_config->ib_config.num_recvs;
+       data_config->path_id = data_config->ib_config.conn_data.path_id;
+
+       data_config->host_min.size_recv_pool_entry =
+           BUFFER_SIZE(ETH_VLAN_HLEN + min_mtu);
+       data_config->host_max.size_recv_pool_entry =
+           BUFFER_SIZE(ETH_VLAN_HLEN + max_mtu);
+       data_config->eioc_min.size_recv_pool_entry =
+           BUFFER_SIZE(ETH_VLAN_HLEN + min_mtu);
+       data_config->eioc_max.size_recv_pool_entry = MAX_PARAM_VALUE;
+
+       data_config->host_recv_pool_entries = host_recv_pool_entries;
+
+       data_config->host_min.num_recv_pool_entries = min_host_pool_sz;
+       data_config->host_max.num_recv_pool_entries = MAX_PARAM_VALUE;
+       data_config->eioc_min.num_recv_pool_entries = min_eioc_pool_sz;
+       data_config->eioc_max.num_recv_pool_entries = max_eioc_pool_sz;
+
+       data_config->host_min.timeout_before_kick = min_host_kick_timeout;
+       data_config->host_max.timeout_before_kick = max_host_kick_timeout;
+       data_config->eioc_min.timeout_before_kick = 0;
+       data_config->eioc_max.timeout_before_kick = MAX_PARAM_VALUE;
+
+       data_config->host_min.num_recv_pool_entries_before_kick =
+           min_host_kick_entries;
+       data_config->host_max.num_recv_pool_entries_before_kick =
+           max_host_kick_entries;
+       data_config->eioc_min.num_recv_pool_entries_before_kick = 0;
+       data_config->eioc_max.num_recv_pool_entries_before_kick =
+           MAX_PARAM_VALUE;
+
+       data_config->host_min.num_recv_pool_bytes_before_kick =
+           min_host_kick_bytes;
+       data_config->host_max.num_recv_pool_bytes_before_kick =
+           max_host_kick_bytes;
+       data_config->eioc_min.num_recv_pool_bytes_before_kick = 0;
+       data_config->eioc_max.num_recv_pool_bytes_before_kick = MAX_PARAM_VALUE;
+
+       data_config->host_min.free_recv_pool_entries_per_update =
+           min_host_update_sz;
+       data_config->host_max.free_recv_pool_entries_per_update =
+           max_host_update_sz;
+       data_config->eioc_min.free_recv_pool_entries_per_update =
+           min_eioc_update_sz;
+       data_config->eioc_max.free_recv_pool_entries_per_update =
+           max_eioc_update_sz;
+
+       data_config->notify_bundle = notify_bundle_sz;
+
+       return;
+}
+
+static void config_path_info_defaults(struct viport_config *config,
+                                     struct path_param *params)
+{
+       int i;
+       ib_get_cached_gid(config->ibdev, config->port, 0,
+                         &config->path_info.path.sgid);
+       for (i = 0; i < 16; i++) {
+               config->path_info.path.dgid.raw[i] = params->dgid[i];
+       }
+       config->path_info.path.pkey = params->pkey;
+       config->path_info.path.numb_path = 1;
+       config->sa_path_rec_get_timeout = sa_path_rec_get_timeout;
+
+}
+
+static BOOLEAN config_viport_defaults(struct viport_config *config,
+                                     struct path_param *params)
+{
+       config->ibdev = params->ibdev;
+       config->port = params->port;
+       config->guid = params->ioc_guid;
+       config->stats_interval = CONV2JIFFIES(viport_stats_interval);
+       config->hb_interval = CONV2JIFFIES(viport_hb_interval);
+       config->hb_timeout = CONV2USEC(viport_hb_timeout);
+
+       config_path_info_defaults(config, params);
+
+       config_control_defaults(&config->control_config, params);
+       config_data_defaults(&config->data_config, params);
+       return TRUE;
+}
+
+static void config_vnic_defaults(struct vnic_config *config)
+{
+       config->no_path_timeout = CONV2JIFFIES(default_no_path_timeout);
+       config->primary_connect_timeout =
+           CONV2JIFFIES(default_primary_connect_timeout);
+       config->primary_reconnect_timeout =
+           CONV2JIFFIES(default_primary_reconnect_timeout);
+       config->primary_switch_timeout =
+           CONV2JIFFIES(default_primary_switch_timeout);
+       config->prefer_primary = default_prefer_primary;
+       config->use_rx_csum = use_rx_csum;
+       config->use_tx_csum = use_tx_csum;
+       return;
+}
+
+static BOOLEAN config_is_valid(struct viport_config *config)
+{
+       /* TBD: */
+       return TRUE;
+}
+
+struct viport_config *config_alloc_viport(struct path_param *params)
+{
+       struct viport_config *config;
+
+       config =
+           (struct viport_config *)kmalloc(sizeof(struct viport_config),
+                                           GFP_KERNEL);
+       if (!config) {
+               CONFIG_ERROR
+                   ("couldn't allocate memory for struct viport_config\n");
+               goto failure;
+       }
+       memset(config, '\0', sizeof(struct viport_config));
+
+       if (!config_viport_defaults(config, params)) {
+               goto failure;
+       }
+
+       /* TBD: overrides go in here */
+
+       if (!config_is_valid(config)) {
+               CONFIG_ERROR("viport configuration is invalid\n");
+               goto failure;
+       }
+
+       return config;
+failure:
+       if (config) {
+               kfree(config);
+       }
+       return NULL;
+}
+
+void config_free_viport(struct viport_config *config)
+{
+       if (config) {
+               kfree(config);
+       }
+       return;
+}
+
+struct vnic_config *config_alloc_vnic(void)
+{
+       struct vnic_config *config;
+
+       config =
+           (struct vnic_config *)kmalloc(sizeof(struct vnic_config),
+                                         GFP_KERNEL);
+       if (!config) {
+               CONFIG_ERROR("couldn't allocate memory for"
+                            " struct vnic_config\n");
+               goto failure;
+       }
+       memset(config, '\0', sizeof(struct vnic_config));
+
+       config_vnic_defaults(config);
+
+       /* TBD: vnic overrides here */
+
+       return config;
+failure:
+       if (config) {
+               kfree(config);
+       }
+       return NULL;
+}
+
+void config_free_vnic(struct vnic_config *config)
+{
+       if (config) {
+               kfree(config);
+       }
+       return;
+}
+
+char *config_viport_name(struct viport_config *config)
+{
+       /* function only called by one thread, can return a static string */
+       static char str[92];
+
+       sprintf(str, "GUID %llx  instance %d",
+               ntoh64(config->guid), config->control_config.vnic_instance);
+       return str;
+}
+
+static int __power_of_2_check(u32 num, char *param_name)
+{
+       if (!is_power_of2(num)) {
+               CONFIG_ERROR("param %s must be a power of 2\n", param_name);
+               return 0;
+       }
+
+       return 1;
+}
+
+static int __less_than_check(u32 lo, u32 hi, char *lo_name, char *hi_name)
+{
+       if (lo >= hi) {
+               CONFIG_ERROR("param %s must be less than %s\n",
+                            lo_name, hi_name);
+               return 0;
+       }
+
+       return 1;
+}
+
+static int __less_or_equal_check(u32 lo, u32 hi, char *lo_name, char *hi_name)
+{
+       if (lo > hi) {
+               CONFIG_ERROR("param %s cannot be greater than %s \n",
+                            lo_name, hi_name);
+               return 0;
+       }
+
+       return 1;
+}
+
+static int __range_check(u32 num, u32 min, u32 max, char *param_name)
+{
+       if ((num < min) || (num > max)) {
+               CONFIG_ERROR("param %s must be between %d and %d\n",
+                             param_name, min, max);
+               return 0;
+       }
+
+       return 1;
+}
+
+void config_cleanup(void)
+{
+       /* nothing to do here */
+       return;
+}
+
+BOOLEAN config_start(void)
+{
+       DEFAULT_PARAM(max_address_entries, MAX_ADDRESS_ENTRIES);
+       DEFAULT_PARAM(min_address_entries, MIN_ADDRESS_ENTRIES);
+       DEFAULT_PARAM(min_mtu, MIN_MTU);
+       DEFAULT_PARAM(max_mtu, MAX_MTU);
+       DEFAULT_PARAM(host_recv_pool_entries, HOST_RECV_POOL_ENTRIES);
+       DEFAULT_PARAM(min_host_pool_sz, MIN_HOST_POOL_SZ);
+       DEFAULT_PARAM(min_eioc_pool_sz, MIN_EIOC_POOL_SZ);
+       DEFAULT_PARAM(max_eioc_pool_sz, MAX_EIOC_POOL_SZ);
+       DEFAULT_PARAM(min_host_kick_timeout, MIN_HOST_KICK_TIMEOUT);
+       DEFAULT_PARAM(max_host_kick_timeout, MAX_HOST_KICK_TIMEOUT);
+       DEFAULT_PARAM(min_host_kick_entries, MIN_HOST_KICK_ENTRIES);
+       DEFAULT_PARAM(max_host_kick_entries, MAX_HOST_KICK_ENTRIES);
+       DEFAULT_PARAM(min_host_kick_bytes, MIN_HOST_KICK_BYTES);
+       DEFAULT_PARAM(max_host_kick_bytes, MAX_HOST_KICK_BYTES);
+       DEFAULT_PARAM(min_host_update_sz, MIN_HOST_UPDATE_SZ);
+       DEFAULT_PARAM(max_host_update_sz, MAX_HOST_UPDATE_SZ);
+       DEFAULT_PARAM(min_eioc_update_sz, MIN_EIOC_UPDATE_SZ);
+       DEFAULT_PARAM(max_eioc_update_sz, MAX_EIOC_UPDATE_SZ);
+       DEFAULT_PARAM(notify_bundle_sz, NOTIFY_BUNDLE_SZ);
+       DEFAULT_PARAM(viport_stats_interval, VIPORT_STATS_INTERVAL);
+       DEFAULT_PARAM(viport_hb_interval, VIPORT_HEARTBEAT_INTERVAL);
+       DEFAULT_PARAM(viport_hb_timeout, VIPORT_HEARTBEAT_TIMEOUT);
+       DEFAULT_PARAM(control_rsp_timeout, CONTROL_RSP_TIMEOUT);
+       DEFAULT_PARAM(control_req_retry_count, CONTROL_REQ_RETRY_COUNT);
+       DEFAULT_PARAM(retry_count, RETRY_COUNT);
+       DEFAULT_PARAM(min_rnr_timer, MIN_RNR_TIMER);
+       DEFAULT_PARAM(sa_path_rec_get_timeout, SA_PATH_REC_GET_TIMEOUT);
+       DEFAULT_PARAM(default_viports_per_netpath, DEFAULT_VIPORTS_PER_NETPATH);
+       DEFAULT_PARAM(max_viports_per_netpath, MAX_VIPORTS_PER_NETPATH);
+       DEFAULT_PARAM(default_pkey, DEFAULT_PKEY);
+       DEFAULT_PARAM(default_no_path_timeout, DEFAULT_NO_PATH_TIMEOUT);
+       DEFAULT_PARAM(default_primary_connect_timeout, DEFAULT_PRI_CON_TIMEOUT);
+       DEFAULT_PARAM(default_primary_reconnect_timeout,
+                     DEFAULT_PRI_RECON_TIMEOUT);
+       DEFAULT_PARAM(default_primary_switch_timeout,
+                     DEFAULT_PRI_SWITCH_TIMEOUT);
+       DEFAULT_PARAM(default_prefer_primary, DEFAULT_PREFER_PRIMARY);
+       DEFAULT_PARAM(use_rx_csum, VNIC_USE_RX_CSUM);
+       DEFAULT_PARAM(use_tx_csum, VNIC_USE_TX_CSUM);
+
+       if (! u32_range_check(max_address_entries))
+               goto failure;
+
+       if (! u32_range_check(min_address_entries))
+               goto failure;
+
+       if (! range_check(min_mtu, MIN_MTU, MAX_MTU))
+               goto failure;
+
+       if (! range_check(max_mtu, MIN_MTU, MAX_MTU))
+               goto failure;
+
+       if (! u32_range_check(host_recv_pool_entries))
+               goto failure;
+
+       if (! u32_range_check(min_host_pool_sz))
+               goto failure;
+
+       if (! u32_range_check(min_eioc_pool_sz))
+               goto failure;
+
+       if (! u32_range_check(max_eioc_pool_sz))
+               goto failure;
+
+       if (! u32_zero_range_check(min_host_kick_timeout))
+               goto failure;
+
+       if (! u32_zero_range_check(max_host_kick_timeout))
+               goto failure;
+
+       if (! u32_zero_range_check(min_host_kick_entries))
+               goto failure;
+
+       if (! u32_zero_range_check(max_host_kick_entries))
+               goto failure;
+
+       if (! u32_zero_range_check(min_host_kick_bytes))
+               goto failure;
+
+       if (! u32_zero_range_check(max_host_kick_bytes))
+               goto failure;
+
+       if (! u32_range_check(min_host_update_sz))
+               goto failure;
+
+       if (! u32_range_check(max_host_update_sz))
+               goto failure;
+
+       if (! u32_range_check(min_eioc_update_sz))
+               goto failure;
+
+       if (! u32_range_check(max_eioc_update_sz))
+               goto failure;
+
+       if (! u8_range_check(notify_bundle_sz))
+               goto failure;
+
+       if (! u32_zero_range_check(viport_stats_interval))
+               goto failure;
+
+       if (! u32_zero_range_check(viport_hb_interval))
+               goto failure;
+
+       if (! u32_zero_range_check(viport_hb_timeout))
+               goto failure;
+
+       if (! u32_range_check(control_rsp_timeout))
+               goto failure;
+
+       if (! u8_range_check(control_req_retry_count))
+               goto failure;
+
+       if (! range_check(sa_path_rec_get_timeout,
+                         MIN_SA_TIMEOUT, MAX_SA_TIMEOUT))
+               goto failure;
+
+       if (! range_check(retry_count, 0, 7))
+               goto failure;
+
+       if (! range_check(min_rnr_timer, 0, 31))
+               goto failure;
+
+       if (! u32_range_check(default_viports_per_netpath))
+               goto failure;
+
+       if (! u8_range_check(max_viports_per_netpath))
+               goto failure;
+
+       if (! u16_zero_range_check(default_pkey))
+               goto failure;
+
+       if (! u32_range_check(default_no_path_timeout))
+               goto failure;
+
+       if (! u32_range_check(default_primary_connect_timeout))
+               goto failure;
+
+       if (! u32_range_check(default_primary_reconnect_timeout))
+               goto failure;
+
+       if (! u32_range_check(default_primary_switch_timeout))
+               goto failure;
+
+       if (! boolean_range_check(default_prefer_primary))
+               goto failure;
+
+       if (! boolean_range_check(use_rx_csum))
+               goto failure;
+
+       if (! boolean_range_check(use_tx_csum))
+               goto failure;
+
+       if (! less_or_equal_check(min_address_entries, max_address_entries))
+               goto failure;
+
+       if (! less_or_equal_check(min_mtu, max_mtu))
+               goto failure;
+
+       if (! less_or_equal_check(min_host_pool_sz, host_recv_pool_entries))
+               goto failure;
+
+       if (! power_of_2_check(host_recv_pool_entries))
+               goto failure;
+
+       if (! power_of_2_check(min_host_pool_sz))
+               goto failure;
+
+       if (! power_of_2_check(notify_bundle_sz))
+               goto failure;
+
+       if (! less_than_check(notify_bundle_sz, min_eioc_pool_sz))
+               goto failure;
+
+       if (! less_or_equal_check(min_eioc_pool_sz, max_eioc_pool_sz))
+               goto failure;
+
+       if (! power_of_2_check(min_eioc_pool_sz))
+               goto failure;
+
+       if (! power_of_2_check(max_eioc_pool_sz))
+               goto failure;
+
+       if (! less_or_equal_check(min_host_kick_timeout, max_host_kick_timeout))
+               goto failure;
+
+       if (! less_or_equal_check(min_host_kick_entries, max_host_kick_entries))
+               goto failure;
+
+       if (! less_or_equal_check(min_host_kick_bytes, max_host_kick_bytes))
+               goto failure;
+
+       if (! less_or_equal_check(min_host_update_sz, max_host_update_sz))
+               goto failure;
+
+       if (! power_of_2_check(min_host_update_sz))
+               goto failure;
+
+       if (! power_of_2_check(max_host_update_sz))
+               goto failure;
+
+       if (! less_than_check(min_host_update_sz, min_host_pool_sz))
+               goto failure;
+
+       if (! less_than_check(max_host_update_sz, host_recv_pool_entries))
+               goto failure;
+
+       if (! less_or_equal_check(min_eioc_update_sz, max_eioc_update_sz))
+               goto failure;
+
+       if (! power_of_2_check(min_eioc_update_sz))
+               goto failure;
+
+       if (! power_of_2_check(max_eioc_update_sz))
+               goto failure;
+
+       if (! less_than_check(min_eioc_update_sz, min_eioc_pool_sz))
+               goto failure;
+
+       if (! less_than_check(max_eioc_update_sz, max_eioc_pool_sz))
+               goto failure;
+
+       if (! less_or_equal_check(default_viports_per_netpath,
+                                 max_viports_per_netpath))
+               goto failure;
+
+       return TRUE;
+failure:
+       return FALSE;
+}
diff --git a/drivers/infiniband/ulp/vnic/vnic_config.h 
b/drivers/infiniband/ulp/vnic/vnic_config.h
new file mode 100644
index 0000000..88b5c44
--- /dev/null
+++ b/drivers/infiniband/ulp/vnic/vnic_config.h
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2006 SilverStorm Technologies Inc.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef VNIC_CONFIG_H_INCLUDED
+#define VNIC_CONFIG_H_INCLUDED
+
+#include <rdma/ib_verbs.h>
+#include <linux/types.h>
+
+#include "vnic_control.h"
+#include "vnic_ib.h"
+
+/* these are hard, compile time limits.
+ * lower runtime overrides may be in effect
+ */
+
+#define VNIC_CLASS_SUBCLASS 0x2000066A
+#define VNIC_PROTOCOL       0
+#define VNIC_PROT_VERSION   1
+
+#define MAX_ADDRESS_ENTRIES             64     /* TBD: arbitrary */
+#define MIN_ADDRESS_ENTRIES             16     /* TBD: arbitrary */
+
+#define MIN_MTU                         1500   /* minimum negotiated MTU size 
*/
+#define MAX_MTU                         9500   /* jumbo frame */
+#define ETH_VLAN_HLEN                   18
+
+#define HOST_RECV_POOL_ENTRIES          512    /* TBD: abritrary */
+#define MIN_HOST_POOL_SZ                64     /* TBD: abritrary */
+#define MIN_EIOC_POOL_SZ                64     /* TBD: abritrary */
+#define MAX_EIOC_POOL_SZ                256    /* TBD: abritrary */
+
+#define MIN_HOST_KICK_TIMEOUT           10     /* TBD: arbitrary */
+#define MAX_HOST_KICK_TIMEOUT                  100     /* in u_sec */
+
+#define MIN_HOST_KICK_ENTRIES                  1       /* TBD: arbitrary */
+#define MAX_HOST_KICK_ENTRIES           128    /* TBD: arbitrary */
+
+#define MIN_HOST_KICK_BYTES            0
+#define MAX_HOST_KICK_BYTES            5000
+
+#define MIN_HOST_UPDATE_SZ              8      /* TBD: arbitrary */
+#define MAX_HOST_UPDATE_SZ              32     /* TBD: arbitrary */
+#define MIN_EIOC_UPDATE_SZ              8      /* TBD: arbitrary */
+#define MAX_EIOC_UPDATE_SZ              32     /* TBD: arbitrary */
+
+#define NOTIFY_BUNDLE_SZ                32
+
+#define MAX_PARAM_VALUE                 0x40000000
+
+#define DEFAULT_VIPORTS_PER_NETPATH    1
+#define MAX_VIPORTS_PER_NETPATH                1
+
+#define VNIC_USE_RX_CSUM                TRUE
+#define VNIC_USE_TX_CSUM                TRUE
+#define DEFAULT_NO_PATH_TIMEOUT         1000   /* TBD: arbitrary */
+#define DEFAULT_PRI_CON_TIMEOUT                1000    /* TBD: arbitrary */
+#define DEFAULT_PRI_RECON_TIMEOUT      1000    /* TBD: arbitrary */
+#define DEFAULT_PRI_SWITCH_TIMEOUT      1000   /* TBD: arbitrary */
+#define DEFAULT_PREFER_PRIMARY          FALSE
+
+#define VIPORT_STATS_INTERVAL          50      /* .5 sec */
+#define VIPORT_HEARTBEAT_INTERVAL       100    /* 1 second */
+#define VIPORT_HEARTBEAT_TIMEOUT        6400   /* 64 sec */
+#define CONTROL_REQ_RETRY_COUNT                4
+#define CONTROL_RSP_TIMEOUT            100     /* 1 sec */
+
+/* infiniband connection parameters */
+#define RETRY_COUNT                     3
+#define MIN_RNR_TIMER                   22     /* 20 ms */
+#define DEFAULT_PKEY                    0      /* pkey table index */
+
+#define SA_PATH_REC_GET_TIMEOUT                1000    /* 1000 ms */
+#define MIN_SA_TIMEOUT                 100     /* 100 ms */
+#define MAX_SA_TIMEOUT                 20000   /* 20s */
+
+struct path_param {
+       __be64                  ioc_guid;
+       u8                      port;
+       u8                      instance;
+       struct ib_device        *ibdev;
+       struct vnic_ib_port     *ibport;
+       char                    name[IFNAMSIZ];
+       u8                      dgid[16];
+       __be16                  pkey;
+       u64                     rx_csum;
+       u64                     tx_csum;
+       u64                     heartbeat;
+};
+
+struct ib_config {
+       __be64                          service_id;
+       struct vnic_connection_data     conn_data;
+       u32                             retry_count;
+       u32                             rnr_retry_count;
+       u8                              min_rnr_timer;
+       u32                             num_sends;
+       u32                             num_recvs;
+       u32                             recv_scatter;   /* 1 */
+       u32                             send_gather;    /* 1 or 2 */
+       u32                             overrides;
+};
+
+struct control_config {
+       struct ib_config        ib_config;
+       u32                     num_recvs;
+       u8                      vnic_instance;
+       u16                     max_address_entries;
+       u16                     min_address_entries;
+       u32                     rsp_timeout;
+       u8                      req_retry_count;
+       u32                     overrides;
+};
+
+struct data_config {
+       struct ib_config                ib_config;
+       u64                             path_id;
+       u32                             num_recvs;
+       u32                             host_recv_pool_entries;
+       struct vnic_recv_pool_config    host_min;
+       struct vnic_recv_pool_config    host_max;
+       struct vnic_recv_pool_config    eioc_min;
+       struct vnic_recv_pool_config    eioc_max;
+       u32                             notify_bundle;
+       u32                             overrides;
+};
+
+struct viport_config {
+       struct viport                   *viport;
+       struct control_config           control_config;
+       struct data_config              data_config;
+       struct ib_path_info             path_info;
+       u32                             sa_path_rec_get_timeout;
+       struct ib_device                *ibdev;
+       u32                             port;
+       u32                             stats_interval;
+       u32                             hb_interval;
+       u32                             hb_timeout;
+       u64                             port_guid;
+       u64                             guid;
+       size_t                          path_idx;
+       char                            ioc_string[512 / 8 + 1];
+#define HB_INTERVAL_OVERRIDE   0x1
+#define GUID_OVERRIDE          0x2
+#define STRING_OVERRIDE                0x4
+#define HCA_OVERRIDE           0x8
+#define PORT_OVERRIDE          0x10
+#define PORTGUID_OVERRIDE      0x20
+       u32                             overrides;
+};
+
+/*
+ * primary_connect_timeout   - if the secondary connects first, how long do we
+ *                             give the primary?
+ * primary_reconnect_timeout - same as above, but used when recovering when
+ *                             both paths fail
+ * primary_reconnect_timeout - how long do we wait before switching to the
+ *                             primary when it comes back?
+ */
+struct vnic_config {
+       struct vnic     *vnic;
+       char            name[IFNAMSIZ];
+       u32             no_path_timeout;
+       u32             primary_connect_timeout;
+       u32             primary_reconnect_timeout;
+       u32             primary_switch_timeout;
+       int             prefer_primary;
+       BOOLEAN         use_rx_csum;
+       BOOLEAN         use_tx_csum;
+#define USE_RX_CSUM_OVERRIDE   0x1
+#define USE_TX_CSUM_OVERRIDE   0x2
+       u32             overrides;
+};
+
+BOOLEAN config_start(void);
+void config_cleanup(void);
+
+struct viport_config *config_alloc_viport(struct path_param *params);
+void config_free_viport(struct viport_config *config);
+
+struct vnic_config *config_alloc_vnic(void);
+void config_free_vnic(struct vnic_config *config);
+
+char *config_viport_name(struct viport_config *config);
+
+#endif /* VNIC_CONFIG_H_INCLUDED */


_______________________________________________
openib-general mailing list
openib-general@openib.org
http://openib.org/mailman/listinfo/openib-general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to