in qla4xxx/ql4_os.c [2030:2277]
static void qla4xxx_set_ipv6(struct scsi_qla_host *ha,
struct iscsi_iface_param_info *iface_param,
struct addr_ctrl_blk *init_fw_cb)
{
/*
* iface_num 0 is valid for IPv6 Addr, linklocal, router, autocfg.
* iface_num 1 is valid only for IPv6 Addr.
*/
switch (iface_param->param) {
case ISCSI_NET_PARAM_IPV6_ADDR:
if (iface_param->iface_num & 0x1)
/* IPv6 Addr 1 */
memcpy(init_fw_cb->ipv6_addr1, iface_param->value,
sizeof(init_fw_cb->ipv6_addr1));
else
/* IPv6 Addr 0 */
memcpy(init_fw_cb->ipv6_addr0, iface_param->value,
sizeof(init_fw_cb->ipv6_addr0));
break;
case ISCSI_NET_PARAM_IPV6_LINKLOCAL:
if (iface_param->iface_num & 0x1)
break;
memcpy(init_fw_cb->ipv6_if_id, &iface_param->value[8],
sizeof(init_fw_cb->ipv6_if_id));
break;
case ISCSI_NET_PARAM_IPV6_ROUTER:
if (iface_param->iface_num & 0x1)
break;
memcpy(init_fw_cb->ipv6_dflt_rtr_addr, iface_param->value,
sizeof(init_fw_cb->ipv6_dflt_rtr_addr));
break;
case ISCSI_NET_PARAM_IPV6_ADDR_AUTOCFG:
/* Autocfg applies to even interface */
if (iface_param->iface_num & 0x1)
break;
if (iface_param->value[0] == ISCSI_IPV6_AUTOCFG_DISABLE)
init_fw_cb->ipv6_addtl_opts &=
cpu_to_le16(
~IPV6_ADDOPT_NEIGHBOR_DISCOVERY_ADDR_ENABLE);
else if (iface_param->value[0] == ISCSI_IPV6_AUTOCFG_ND_ENABLE)
init_fw_cb->ipv6_addtl_opts |=
cpu_to_le16(
IPV6_ADDOPT_NEIGHBOR_DISCOVERY_ADDR_ENABLE);
else
ql4_printk(KERN_ERR, ha,
"Invalid autocfg setting for IPv6 addr\n");
break;
case ISCSI_NET_PARAM_IPV6_LINKLOCAL_AUTOCFG:
/* Autocfg applies to even interface */
if (iface_param->iface_num & 0x1)
break;
if (iface_param->value[0] ==
ISCSI_IPV6_LINKLOCAL_AUTOCFG_ENABLE)
init_fw_cb->ipv6_addtl_opts |= cpu_to_le16(
IPV6_ADDOPT_AUTOCONFIG_LINK_LOCAL_ADDR);
else if (iface_param->value[0] ==
ISCSI_IPV6_LINKLOCAL_AUTOCFG_DISABLE)
init_fw_cb->ipv6_addtl_opts &= cpu_to_le16(
~IPV6_ADDOPT_AUTOCONFIG_LINK_LOCAL_ADDR);
else
ql4_printk(KERN_ERR, ha,
"Invalid autocfg setting for IPv6 linklocal addr\n");
break;
case ISCSI_NET_PARAM_IPV6_ROUTER_AUTOCFG:
/* Autocfg applies to even interface */
if (iface_param->iface_num & 0x1)
break;
if (iface_param->value[0] == ISCSI_IPV6_ROUTER_AUTOCFG_ENABLE)
memset(init_fw_cb->ipv6_dflt_rtr_addr, 0,
sizeof(init_fw_cb->ipv6_dflt_rtr_addr));
break;
case ISCSI_NET_PARAM_IFACE_ENABLE:
if (iface_param->value[0] == ISCSI_IFACE_ENABLE) {
init_fw_cb->ipv6_opts |=
cpu_to_le16(IPV6_OPT_IPV6_PROTOCOL_ENABLE);
qla4xxx_create_ipv6_iface(ha);
} else {
init_fw_cb->ipv6_opts &=
cpu_to_le16(~IPV6_OPT_IPV6_PROTOCOL_ENABLE &
0xFFFF);
qla4xxx_destroy_ipv6_iface(ha);
}
break;
case ISCSI_NET_PARAM_VLAN_TAG:
if (iface_param->len != sizeof(init_fw_cb->ipv6_vlan_tag))
break;
init_fw_cb->ipv6_vlan_tag =
cpu_to_be16(*(uint16_t *)iface_param->value);
break;
case ISCSI_NET_PARAM_VLAN_ENABLED:
if (iface_param->value[0] == ISCSI_VLAN_ENABLE)
init_fw_cb->ipv6_opts |=
cpu_to_le16(IPV6_OPT_VLAN_TAGGING_ENABLE);
else
init_fw_cb->ipv6_opts &=
cpu_to_le16(~IPV6_OPT_VLAN_TAGGING_ENABLE);
break;
case ISCSI_NET_PARAM_MTU:
init_fw_cb->eth_mtu_size =
cpu_to_le16(*(uint16_t *)iface_param->value);
break;
case ISCSI_NET_PARAM_PORT:
/* Autocfg applies to even interface */
if (iface_param->iface_num & 0x1)
break;
init_fw_cb->ipv6_port =
cpu_to_le16(*(uint16_t *)iface_param->value);
break;
case ISCSI_NET_PARAM_DELAYED_ACK_EN:
if (iface_param->iface_num & 0x1)
break;
if (iface_param->value[0] == ISCSI_NET_PARAM_DISABLE)
init_fw_cb->ipv6_tcp_opts |=
cpu_to_le16(IPV6_TCPOPT_DELAYED_ACK_DISABLE);
else
init_fw_cb->ipv6_tcp_opts &=
cpu_to_le16(~IPV6_TCPOPT_DELAYED_ACK_DISABLE &
0xFFFF);
break;
case ISCSI_NET_PARAM_TCP_NAGLE_DISABLE:
if (iface_param->iface_num & 0x1)
break;
if (iface_param->value[0] == ISCSI_NET_PARAM_DISABLE)
init_fw_cb->ipv6_tcp_opts |=
cpu_to_le16(IPV6_TCPOPT_NAGLE_ALGO_DISABLE);
else
init_fw_cb->ipv6_tcp_opts &=
cpu_to_le16(~IPV6_TCPOPT_NAGLE_ALGO_DISABLE);
break;
case ISCSI_NET_PARAM_TCP_WSF_DISABLE:
if (iface_param->iface_num & 0x1)
break;
if (iface_param->value[0] == ISCSI_NET_PARAM_DISABLE)
init_fw_cb->ipv6_tcp_opts |=
cpu_to_le16(IPV6_TCPOPT_WINDOW_SCALE_DISABLE);
else
init_fw_cb->ipv6_tcp_opts &=
cpu_to_le16(~IPV6_TCPOPT_WINDOW_SCALE_DISABLE);
break;
case ISCSI_NET_PARAM_TCP_WSF:
if (iface_param->iface_num & 0x1)
break;
init_fw_cb->ipv6_tcp_wsf = iface_param->value[0];
break;
case ISCSI_NET_PARAM_TCP_TIMER_SCALE:
if (iface_param->iface_num & 0x1)
break;
init_fw_cb->ipv6_tcp_opts &=
cpu_to_le16(~IPV6_TCPOPT_TIMER_SCALE);
init_fw_cb->ipv6_tcp_opts |=
cpu_to_le16((iface_param->value[0] << 1) &
IPV6_TCPOPT_TIMER_SCALE);
break;
case ISCSI_NET_PARAM_TCP_TIMESTAMP_EN:
if (iface_param->iface_num & 0x1)
break;
if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)
init_fw_cb->ipv6_tcp_opts |=
cpu_to_le16(IPV6_TCPOPT_TIMESTAMP_EN);
else
init_fw_cb->ipv6_tcp_opts &=
cpu_to_le16(~IPV6_TCPOPT_TIMESTAMP_EN);
break;
case ISCSI_NET_PARAM_IPV6_GRAT_NEIGHBOR_ADV_EN:
if (iface_param->iface_num & 0x1)
break;
if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)
init_fw_cb->ipv6_opts |=
cpu_to_le16(IPV6_OPT_GRAT_NEIGHBOR_ADV_EN);
else
init_fw_cb->ipv6_opts &=
cpu_to_le16(~IPV6_OPT_GRAT_NEIGHBOR_ADV_EN);
break;
case ISCSI_NET_PARAM_REDIRECT_EN:
if (iface_param->iface_num & 0x1)
break;
if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)
init_fw_cb->ipv6_opts |=
cpu_to_le16(IPV6_OPT_REDIRECT_EN);
else
init_fw_cb->ipv6_opts &=
cpu_to_le16(~IPV6_OPT_REDIRECT_EN);
break;
case ISCSI_NET_PARAM_IPV6_MLD_EN:
if (iface_param->iface_num & 0x1)
break;
if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)
init_fw_cb->ipv6_addtl_opts |=
cpu_to_le16(IPV6_ADDOPT_MLD_EN);
else
init_fw_cb->ipv6_addtl_opts &=
cpu_to_le16(~IPV6_ADDOPT_MLD_EN);
break;
case ISCSI_NET_PARAM_IPV6_FLOW_LABEL:
if (iface_param->iface_num & 0x1)
break;
init_fw_cb->ipv6_flow_lbl =
cpu_to_le16(*(uint16_t *)iface_param->value);
break;
case ISCSI_NET_PARAM_IPV6_TRAFFIC_CLASS:
if (iface_param->iface_num & 0x1)
break;
init_fw_cb->ipv6_traffic_class = iface_param->value[0];
break;
case ISCSI_NET_PARAM_IPV6_HOP_LIMIT:
if (iface_param->iface_num & 0x1)
break;
init_fw_cb->ipv6_hop_limit = iface_param->value[0];
break;
case ISCSI_NET_PARAM_IPV6_ND_REACHABLE_TMO:
if (iface_param->iface_num & 0x1)
break;
init_fw_cb->ipv6_nd_reach_time =
cpu_to_le32(*(uint32_t *)iface_param->value);
break;
case ISCSI_NET_PARAM_IPV6_ND_REXMIT_TIME:
if (iface_param->iface_num & 0x1)
break;
init_fw_cb->ipv6_nd_rexmit_timer =
cpu_to_le32(*(uint32_t *)iface_param->value);
break;
case ISCSI_NET_PARAM_IPV6_ND_STALE_TMO:
if (iface_param->iface_num & 0x1)
break;
init_fw_cb->ipv6_nd_stale_timeout =
cpu_to_le32(*(uint32_t *)iface_param->value);
break;
case ISCSI_NET_PARAM_IPV6_DUP_ADDR_DETECT_CNT:
if (iface_param->iface_num & 0x1)
break;
init_fw_cb->ipv6_dup_addr_detect_count = iface_param->value[0];
break;
case ISCSI_NET_PARAM_IPV6_RTR_ADV_LINK_MTU:
if (iface_param->iface_num & 0x1)
break;
init_fw_cb->ipv6_gw_advrt_mtu =
cpu_to_le32(*(uint32_t *)iface_param->value);
break;
default:
ql4_printk(KERN_ERR, ha, "Unknown IPv6 param = %d\n",
iface_param->param);
break;
}
}