static void qla4xxx_set_ipv6()

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;
	}
}