Esempio n. 1
0
int ib_init_ah_from_wc(struct ib_device *device, u8 port_num, struct ib_wc *wc,
		       struct ib_grh *grh, struct ib_ah_attr *ah_attr)
{
	u32 flow_class;
	u16 gid_index;
	int ret;

	memset(ah_attr, 0, sizeof *ah_attr);
	ah_attr->dlid = wc->slid;
	ah_attr->sl = wc->sl;
	ah_attr->src_path_bits = wc->dlid_path_bits;
	ah_attr->port_num = port_num;

	if (wc->wc_flags & IB_WC_GRH) {
		ah_attr->ah_flags = IB_AH_GRH;
		ah_attr->grh.dgid = grh->sgid;

		ret = ib_find_cached_gid(device, &grh->dgid, &port_num,
					 &gid_index);
		if (ret)
			return ret;

		ah_attr->grh.sgid_index = (u8) gid_index;
		flow_class = be32_to_cpu(grh->version_tclass_flow);
		ah_attr->grh.flow_label = flow_class & 0xFFFFF;
		ah_attr->grh.hop_limit = 0xFF;
		ah_attr->grh.traffic_class = (flow_class >> 20) & 0xFF;
	}
Esempio n. 2
0
int ib_init_ah_from_wc(struct ib_device *device, u8 port_num, struct ib_wc *wc,
		       struct ib_grh *grh, struct ib_ah_attr *ah_attr)
{
	u32 flow_class;
	u16 gid_index;
	int ret;
	int is_eth = (rdma_port_get_link_layer(device, port_num) ==
			IB_LINK_LAYER_ETHERNET);
	union ib_gid sgid;
	int version;
	struct iphdr *iph = (struct iphdr *)((void *)grh + 20);

	memset(ah_attr, 0, sizeof *ah_attr);

	if (wc->wc_flags & IB_WC_GRH) {
		ah_attr->ah_flags = IB_AH_GRH;
		version = is_eth ? get_grh_header_version(grh) : 6;
		if (version == 4) {
			ipv6_addr_set_v4mapped(iph->saddr,
					       (struct in6_addr *)&ah_attr->grh.dgid);
			ipv6_addr_set_v4mapped(iph->daddr,
					       (struct in6_addr *)&sgid);
			ret = ib_find_cached_gid(device, &sgid, &port_num,
						 &gid_index);
			if (ret)
				return ret;

			ah_attr->grh.sgid_index = (u8) gid_index;
			ah_attr->grh.flow_label = iph->id & 0xfffff;
			ah_attr->grh.hop_limit = iph->ttl;
			ah_attr->grh.traffic_class = iph->tos;
		} else if (version == 6) {
			ah_attr->grh.dgid = grh->sgid;

			ret = ib_find_cached_gid(device, &grh->dgid, &port_num,
						 &gid_index);
			if (ret)
				return ret;

			ah_attr->grh.sgid_index = (u8) gid_index;
			flow_class = be32_to_cpu(grh->version_tclass_flow);
			ah_attr->grh.flow_label = flow_class & 0xFFFFF;
			ah_attr->grh.hop_limit = 0xFF;
			ah_attr->grh.traffic_class = (flow_class >> 20) & 0xFF;
		} else
Esempio n. 3
0
int ib_init_ah_from_wc(struct ib_device *device, u8 port_num, struct ib_wc *wc,
		       struct ib_grh *grh, struct ib_ah_attr *ah_attr)
{
	u32 flow_class;
	u16 gid_index;
	int ret;
	u8 if_index;
	int is_eth = (rdma_port_get_link_layer(device, port_num) ==
			IB_LINK_LAYER_ETHERNET);

	memset(ah_attr, 0, sizeof *ah_attr);
	if (is_eth) {
		if (!(wc->wc_flags & IB_WC_GRH))
			return -EPROTOTYPE;

		if (wc->wc_flags & IB_WC_WITH_SMAC &&
		    wc->wc_flags & IB_WC_WITH_VLAN) {
			memcpy(ah_attr->dmac, wc->smac, ETH_ALEN);
			ah_attr->vlan_id = wc->vlan_id;
		} else {
			if_index = device->get_netdev(device, port_num);
			ret = rdma_addr_find_dmac_by_grh(&grh->dgid, &grh->sgid,
					ah_attr->dmac, &ah_attr->vlan_id, if_index);
			if (ret)
				return ret;
		}
	} else {
		ah_attr->vlan_id = 0xffff;
	}


	ah_attr->dlid = wc->slid;
	ah_attr->sl = wc->sl;
	ah_attr->src_path_bits = wc->dlid_path_bits;
	ah_attr->port_num = port_num;

	if (wc->wc_flags & IB_WC_GRH) {
		ah_attr->ah_flags = IB_AH_GRH;
		ah_attr->grh.dgid = grh->sgid;

		ret = ib_find_cached_gid(device, &grh->dgid, &port_num,
					 &gid_index);
		if (ret)
			return ret;

		ah_attr->grh.sgid_index = (u8) gid_index;
		flow_class = be32_to_cpu(grh->version_tclass_flow);
		ah_attr->grh.flow_label = flow_class & 0xFFFFF;
		ah_attr->grh.hop_limit = 0xFF;
		ah_attr->grh.traffic_class = (flow_class >> 20) & 0xFF;
	}