aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw
diff options
context:
space:
mode:
authorJoachim Fenkes <fenkes@de.ibm.com>2007-07-09 09:21:45 -0400
committerRoland Dreier <rolandd@cisco.com>2007-07-09 23:12:27 -0400
commit91f13aa3fc22e357b494c5b8270e94543870928d (patch)
treee8f78c2549945f5e3bc42e33ce81a18a9292f746 /drivers/infiniband/hw
parentb8a3ba551369982180917a999d32fcedbba34115 (diff)
IB/ehca: HW level, HW caps and MTU autodetection
In preparation for support of new eHCA2 features, change adapter probing: - Hardware level is changed to encode major and minor chip version - Hardware capabilities are queried from the firmware - The maximum MTU is queried from the firmware instead of assuming a fixed value Signed-off-by: Joachim Fenkes <fenkes@de.ibm.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/hw')
-rw-r--r--drivers/infiniband/hw/ehca/ehca_av.c6
-rw-r--r--drivers/infiniband/hw/ehca/ehca_classes.h2
-rw-r--r--drivers/infiniband/hw/ehca/ehca_hca.c27
-rw-r--r--drivers/infiniband/hw/ehca/ehca_main.c62
-rw-r--r--drivers/infiniband/hw/ehca/hipz_hw.h18
5 files changed, 104 insertions, 11 deletions
diff --git a/drivers/infiniband/hw/ehca/ehca_av.c b/drivers/infiniband/hw/ehca/ehca_av.c
index 0d6e2c4bb245..3cd6bf3402d1 100644
--- a/drivers/infiniband/hw/ehca/ehca_av.c
+++ b/drivers/infiniband/hw/ehca/ehca_av.c
@@ -118,7 +118,7 @@ struct ib_ah *ehca_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr)
118 } 118 }
119 memcpy(&av->av.grh.word_1, &gid, sizeof(gid)); 119 memcpy(&av->av.grh.word_1, &gid, sizeof(gid));
120 } 120 }
121 av->av.pmtu = EHCA_MAX_MTU; 121 av->av.pmtu = shca->max_mtu;
122 122
123 /* dgid comes in grh.word_3 */ 123 /* dgid comes in grh.word_3 */
124 memcpy(&av->av.grh.word_3, &ah_attr->grh.dgid, 124 memcpy(&av->av.grh.word_3, &ah_attr->grh.dgid,
@@ -137,6 +137,8 @@ int ehca_modify_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr)
137 struct ehca_av *av; 137 struct ehca_av *av;
138 struct ehca_ud_av new_ehca_av; 138 struct ehca_ud_av new_ehca_av;
139 struct ehca_pd *my_pd = container_of(ah->pd, struct ehca_pd, ib_pd); 139 struct ehca_pd *my_pd = container_of(ah->pd, struct ehca_pd, ib_pd);
140 struct ehca_shca *shca = container_of(ah->pd->device, struct ehca_shca,
141 ib_device);
140 u32 cur_pid = current->tgid; 142 u32 cur_pid = current->tgid;
141 143
142 if (my_pd->ib_pd.uobject && my_pd->ib_pd.uobject->context && 144 if (my_pd->ib_pd.uobject && my_pd->ib_pd.uobject->context &&
@@ -192,7 +194,7 @@ int ehca_modify_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr)
192 memcpy(&new_ehca_av.grh.word_1, &gid, sizeof(gid)); 194 memcpy(&new_ehca_av.grh.word_1, &gid, sizeof(gid));
193 } 195 }
194 196
195 new_ehca_av.pmtu = EHCA_MAX_MTU; 197 new_ehca_av.pmtu = shca->max_mtu;
196 198
197 memcpy(&new_ehca_av.grh.word_3, &ah_attr->grh.dgid, 199 memcpy(&new_ehca_av.grh.word_3, &ah_attr->grh.dgid,
198 sizeof(ah_attr->grh.dgid)); 200 sizeof(ah_attr->grh.dgid));
diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h
index 1d286d3cc2d5..35d948f2502c 100644
--- a/drivers/infiniband/hw/ehca/ehca_classes.h
+++ b/drivers/infiniband/hw/ehca/ehca_classes.h
@@ -107,6 +107,8 @@ struct ehca_shca {
107 struct ehca_pd *pd; 107 struct ehca_pd *pd;
108 struct h_galpas galpas; 108 struct h_galpas galpas;
109 struct mutex modify_mutex; 109 struct mutex modify_mutex;
110 u64 hca_cap;
111 int max_mtu;
110}; 112};
111 113
112struct ehca_pd { 114struct ehca_pd {
diff --git a/drivers/infiniband/hw/ehca/ehca_hca.c b/drivers/infiniband/hw/ehca/ehca_hca.c
index 32b55a4f0e5b..b310de5c94ae 100644
--- a/drivers/infiniband/hw/ehca/ehca_hca.c
+++ b/drivers/infiniband/hw/ehca/ehca_hca.c
@@ -45,11 +45,25 @@
45 45
46int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props) 46int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props)
47{ 47{
48 int ret = 0; 48 int i, ret = 0;
49 struct ehca_shca *shca = container_of(ibdev, struct ehca_shca, 49 struct ehca_shca *shca = container_of(ibdev, struct ehca_shca,
50 ib_device); 50 ib_device);
51 struct hipz_query_hca *rblock; 51 struct hipz_query_hca *rblock;
52 52
53 static const u32 cap_mapping[] = {
54 IB_DEVICE_RESIZE_MAX_WR, HCA_CAP_WQE_RESIZE,
55 IB_DEVICE_BAD_PKEY_CNTR, HCA_CAP_BAD_P_KEY_CTR,
56 IB_DEVICE_BAD_QKEY_CNTR, HCA_CAP_Q_KEY_VIOL_CTR,
57 IB_DEVICE_RAW_MULTI, HCA_CAP_RAW_PACKET_MCAST,
58 IB_DEVICE_AUTO_PATH_MIG, HCA_CAP_AUTO_PATH_MIG,
59 IB_DEVICE_CHANGE_PHY_PORT, HCA_CAP_SQD_RTS_PORT_CHANGE,
60 IB_DEVICE_UD_AV_PORT_ENFORCE, HCA_CAP_AH_PORT_NR_CHECK,
61 IB_DEVICE_CURR_QP_STATE_MOD, HCA_CAP_CUR_QP_STATE_MOD,
62 IB_DEVICE_SHUTDOWN_PORT, HCA_CAP_SHUTDOWN_PORT,
63 IB_DEVICE_INIT_TYPE, HCA_CAP_INIT_TYPE,
64 IB_DEVICE_PORT_ACTIVE_EVENT, HCA_CAP_PORT_ACTIVE_EVENT,
65 };
66
53 rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL); 67 rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
54 if (!rblock) { 68 if (!rblock) {
55 ehca_err(&shca->ib_device, "Can't allocate rblock memory."); 69 ehca_err(&shca->ib_device, "Can't allocate rblock memory.");
@@ -96,6 +110,13 @@ int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props)
96 props->max_total_mcast_qp_attach 110 props->max_total_mcast_qp_attach
97 = min_t(int, rblock->max_total_mcast_qp_attach, INT_MAX); 111 = min_t(int, rblock->max_total_mcast_qp_attach, INT_MAX);
98 112
113 /* translate device capabilities */
114 props->device_cap_flags = IB_DEVICE_SYS_IMAGE_GUID |
115 IB_DEVICE_RC_RNR_NAK_GEN | IB_DEVICE_N_NOTIFY_CQ;
116 for (i = 0; i < ARRAY_SIZE(cap_mapping); i += 2)
117 if (rblock->hca_cap_indicators & cap_mapping[i + 1])
118 props->device_cap_flags |= cap_mapping[i];
119
99query_device1: 120query_device1:
100 ehca_free_fw_ctrlblock(rblock); 121 ehca_free_fw_ctrlblock(rblock);
101 122
@@ -261,7 +282,7 @@ int ehca_modify_port(struct ib_device *ibdev,
261 } 282 }
262 283
263 if (mutex_lock_interruptible(&shca->modify_mutex)) 284 if (mutex_lock_interruptible(&shca->modify_mutex))
264 return -ERESTARTSYS; 285 return -ERESTARTSYS;
265 286
266 rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL); 287 rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
267 if (!rblock) { 288 if (!rblock) {
@@ -290,7 +311,7 @@ modify_port2:
290 ehca_free_fw_ctrlblock(rblock); 311 ehca_free_fw_ctrlblock(rblock);
291 312
292modify_port1: 313modify_port1:
293 mutex_unlock(&shca->modify_mutex); 314 mutex_unlock(&shca->modify_mutex);
294 315
295 return ret; 316 return ret;
296} 317}
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
index fea199f01eaa..eb22a6b296d9 100644
--- a/drivers/infiniband/hw/ehca/ehca_main.c
+++ b/drivers/infiniband/hw/ehca/ehca_main.c
@@ -205,11 +205,35 @@ static void ehca_destroy_slab_caches(void)
205#define EHCA_HCAAVER EHCA_BMASK_IBM(32,39) 205#define EHCA_HCAAVER EHCA_BMASK_IBM(32,39)
206#define EHCA_REVID EHCA_BMASK_IBM(40,63) 206#define EHCA_REVID EHCA_BMASK_IBM(40,63)
207 207
208static struct cap_descr {
209 u64 mask;
210 char *descr;
211} hca_cap_descr[] = {
212 { HCA_CAP_AH_PORT_NR_CHECK, "HCA_CAP_AH_PORT_NR_CHECK" },
213 { HCA_CAP_ATOMIC, "HCA_CAP_ATOMIC" },
214 { HCA_CAP_AUTO_PATH_MIG, "HCA_CAP_AUTO_PATH_MIG" },
215 { HCA_CAP_BAD_P_KEY_CTR, "HCA_CAP_BAD_P_KEY_CTR" },
216 { HCA_CAP_SQD_RTS_PORT_CHANGE, "HCA_CAP_SQD_RTS_PORT_CHANGE" },
217 { HCA_CAP_CUR_QP_STATE_MOD, "HCA_CAP_CUR_QP_STATE_MOD" },
218 { HCA_CAP_INIT_TYPE, "HCA_CAP_INIT_TYPE" },
219 { HCA_CAP_PORT_ACTIVE_EVENT, "HCA_CAP_PORT_ACTIVE_EVENT" },
220 { HCA_CAP_Q_KEY_VIOL_CTR, "HCA_CAP_Q_KEY_VIOL_CTR" },
221 { HCA_CAP_WQE_RESIZE, "HCA_CAP_WQE_RESIZE" },
222 { HCA_CAP_RAW_PACKET_MCAST, "HCA_CAP_RAW_PACKET_MCAST" },
223 { HCA_CAP_SHUTDOWN_PORT, "HCA_CAP_SHUTDOWN_PORT" },
224 { HCA_CAP_RC_LL_QP, "HCA_CAP_RC_LL_QP" },
225 { HCA_CAP_SRQ, "HCA_CAP_SRQ" },
226 { HCA_CAP_UD_LL_QP, "HCA_CAP_UD_LL_QP" },
227 { HCA_CAP_RESIZE_MR, "HCA_CAP_RESIZE_MR" },
228 { HCA_CAP_MINI_QP, "HCA_CAP_MINI_QP" },
229};
230
208int ehca_sense_attributes(struct ehca_shca *shca) 231int ehca_sense_attributes(struct ehca_shca *shca)
209{ 232{
210 int ret = 0; 233 int i, ret = 0;
211 u64 h_ret; 234 u64 h_ret;
212 struct hipz_query_hca *rblock; 235 struct hipz_query_hca *rblock;
236 struct hipz_query_port *port;
213 237
214 rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL); 238 rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
215 if (!rblock) { 239 if (!rblock) {
@@ -222,7 +246,7 @@ int ehca_sense_attributes(struct ehca_shca *shca)
222 ehca_gen_err("Cannot query device properties. h_ret=%lx", 246 ehca_gen_err("Cannot query device properties. h_ret=%lx",
223 h_ret); 247 h_ret);
224 ret = -EPERM; 248 ret = -EPERM;
225 goto num_ports1; 249 goto sense_attributes1;
226 } 250 }
227 251
228 if (ehca_nr_ports == 1) 252 if (ehca_nr_ports == 1)
@@ -242,18 +266,44 @@ int ehca_sense_attributes(struct ehca_shca *shca)
242 ehca_gen_dbg(" ... hardware version=%x:%x", hcaaver, revid); 266 ehca_gen_dbg(" ... hardware version=%x:%x", hcaaver, revid);
243 267
244 if ((hcaaver == 1) && (revid == 0)) 268 if ((hcaaver == 1) && (revid == 0))
245 shca->hw_level = 0; 269 shca->hw_level = 0x11;
246 else if ((hcaaver == 1) && (revid == 1)) 270 else if ((hcaaver == 1) && (revid == 1))
247 shca->hw_level = 1; 271 shca->hw_level = 0x12;
248 else if ((hcaaver == 1) && (revid == 2)) 272 else if ((hcaaver == 1) && (revid == 2))
249 shca->hw_level = 2; 273 shca->hw_level = 0x13;
274 else if ((hcaaver == 2) && (revid == 0))
275 shca->hw_level = 0x21;
276 else if ((hcaaver == 2) && (revid == 0x10))
277 shca->hw_level = 0x22;
278 else {
279 ehca_gen_warn("unknown hardware version"
280 " - assuming default level");
281 shca->hw_level = 0x22;
282 }
250 } 283 }
251 ehca_gen_dbg(" ... hardware level=%x", shca->hw_level); 284 ehca_gen_dbg(" ... hardware level=%x", shca->hw_level);
252 285
253 shca->sport[0].rate = IB_RATE_30_GBPS; 286 shca->sport[0].rate = IB_RATE_30_GBPS;
254 shca->sport[1].rate = IB_RATE_30_GBPS; 287 shca->sport[1].rate = IB_RATE_30_GBPS;
255 288
256num_ports1: 289 shca->hca_cap = rblock->hca_cap_indicators;
290 ehca_gen_dbg(" ... HCA capabilities:");
291 for (i = 0; i < ARRAY_SIZE(hca_cap_descr); i++)
292 if (EHCA_BMASK_GET(hca_cap_descr[i].mask, shca->hca_cap))
293 ehca_gen_dbg(" %s", hca_cap_descr[i].descr);
294
295 port = (struct hipz_query_port *) rblock;
296 h_ret = hipz_h_query_port(shca->ipz_hca_handle, 1, port);
297 if (h_ret != H_SUCCESS) {
298 ehca_gen_err("Cannot query port properties. h_ret=%lx",
299 h_ret);
300 ret = -EPERM;
301 goto sense_attributes1;
302 }
303
304 shca->max_mtu = port->max_mtu;
305
306sense_attributes1:
257 ehca_free_fw_ctrlblock(rblock); 307 ehca_free_fw_ctrlblock(rblock);
258 return ret; 308 return ret;
259} 309}
diff --git a/drivers/infiniband/hw/ehca/hipz_hw.h b/drivers/infiniband/hw/ehca/hipz_hw.h
index fad91368dc5a..9116fc943fee 100644
--- a/drivers/infiniband/hw/ehca/hipz_hw.h
+++ b/drivers/infiniband/hw/ehca/hipz_hw.h
@@ -360,6 +360,24 @@ struct hipz_query_hca {
360 u32 max_neq; 360 u32 max_neq;
361} __attribute__ ((packed)); 361} __attribute__ ((packed));
362 362
363#define HCA_CAP_AH_PORT_NR_CHECK EHCA_BMASK_IBM( 0, 0)
364#define HCA_CAP_ATOMIC EHCA_BMASK_IBM( 1, 1)
365#define HCA_CAP_AUTO_PATH_MIG EHCA_BMASK_IBM( 2, 2)
366#define HCA_CAP_BAD_P_KEY_CTR EHCA_BMASK_IBM( 3, 3)
367#define HCA_CAP_SQD_RTS_PORT_CHANGE EHCA_BMASK_IBM( 4, 4)
368#define HCA_CAP_CUR_QP_STATE_MOD EHCA_BMASK_IBM( 5, 5)
369#define HCA_CAP_INIT_TYPE EHCA_BMASK_IBM( 6, 6)
370#define HCA_CAP_PORT_ACTIVE_EVENT EHCA_BMASK_IBM( 7, 7)
371#define HCA_CAP_Q_KEY_VIOL_CTR EHCA_BMASK_IBM( 8, 8)
372#define HCA_CAP_WQE_RESIZE EHCA_BMASK_IBM( 9, 9)
373#define HCA_CAP_RAW_PACKET_MCAST EHCA_BMASK_IBM(10, 10)
374#define HCA_CAP_SHUTDOWN_PORT EHCA_BMASK_IBM(11, 11)
375#define HCA_CAP_RC_LL_QP EHCA_BMASK_IBM(12, 12)
376#define HCA_CAP_SRQ EHCA_BMASK_IBM(13, 13)
377#define HCA_CAP_UD_LL_QP EHCA_BMASK_IBM(16, 16)
378#define HCA_CAP_RESIZE_MR EHCA_BMASK_IBM(17, 17)
379#define HCA_CAP_MINI_QP EHCA_BMASK_IBM(18, 18)
380
363/* query port response block */ 381/* query port response block */
364struct hipz_query_port { 382struct hipz_query_port {
365 u32 state; 383 u32 state;