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