|
41 | 41 | #include <linux/err.h> |
42 | 42 |
|
43 | 43 | #include <ib_verbs.h> |
| 44 | +#include <ib_cache.h> |
44 | 45 |
|
45 | 46 | /* Protection domains */ |
46 | 47 |
|
@@ -88,6 +89,40 @@ struct ib_ah *ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr) |
88 | 89 | } |
89 | 90 | EXPORT_SYMBOL(ib_create_ah); |
90 | 91 |
|
| 92 | +struct ib_ah *ib_create_ah_from_wc(struct ib_pd *pd, struct ib_wc *wc, |
| 93 | + struct ib_grh *grh, u8 port_num) |
| 94 | +{ |
| 95 | + struct ib_ah_attr ah_attr; |
| 96 | + u32 flow_class; |
| 97 | + u16 gid_index; |
| 98 | + int ret; |
| 99 | + |
| 100 | + memset(&ah_attr, 0, sizeof ah_attr); |
| 101 | + ah_attr.dlid = wc->slid; |
| 102 | + ah_attr.sl = wc->sl; |
| 103 | + ah_attr.src_path_bits = wc->dlid_path_bits; |
| 104 | + ah_attr.port_num = port_num; |
| 105 | + |
| 106 | + if (wc->wc_flags & IB_WC_GRH) { |
| 107 | + ah_attr.ah_flags = IB_AH_GRH; |
| 108 | + ah_attr.grh.dgid = grh->dgid; |
| 109 | + |
| 110 | + ret = ib_find_cached_gid(pd->device, &grh->sgid, &port_num, |
| 111 | + &gid_index); |
| 112 | + if (ret) |
| 113 | + return ERR_PTR(ret); |
| 114 | + |
| 115 | + ah_attr.grh.sgid_index = (u8) gid_index; |
| 116 | + flow_class = be32_to_cpu(&grh->version_tclass_flow); |
| 117 | + ah_attr.grh.flow_label = flow_class & 0xFFFFF; |
| 118 | + ah_attr.grh.traffic_class = (flow_class >> 20) & 0xFF; |
| 119 | + ah_attr.grh.hop_limit = grh->hop_limit; |
| 120 | + } |
| 121 | + |
| 122 | + return ib_create_ah(pd, &ah_attr); |
| 123 | +} |
| 124 | +EXPORT_SYMBOL(ib_create_ah_from_wc); |
| 125 | + |
91 | 126 | int ib_modify_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr) |
92 | 127 | { |
93 | 128 | return ah->device->modify_ah ? |
|
0 commit comments