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