[openib-general] [PATCH 7/10] Handling of various configurable parameters of the driver
Ramachandra K
rkuchimanchi at silverstorm.com
Mon Oct 2 13:09:08 PDT 2006
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 <rkuchimanchi at silverstorm.com>
---
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 */
More information about the general
mailing list