diff options
author | Ralph Campbell <ralph.campbell@qlogic.com> | 2008-04-17 00:09:24 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2008-04-17 00:09:24 -0400 |
commit | a51a2513a8cb201f02d83c37e106909938d2f761 (patch) | |
tree | 74e4dad1421eb922f7e108c968d2c7a1666b779e /drivers/infiniband/hw/ipath/ipath_mad.c | |
parent | 58411d1c012dca53ec9107bd98acb63f648e2435 (diff) |
IB/ipath: Add code to support multiple link speeds and widths
This patch adds code to get/set portinfo to support multiple link speeds
and widths.
Signed-off-by: Ralph Campbell <ralph.campbell@qlogic.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/hw/ipath/ipath_mad.c')
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_mad.c | 89 |
1 files changed, 60 insertions, 29 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_mad.c b/drivers/infiniband/hw/ipath/ipath_mad.c index aca876bae1c4..7516a2608988 100644 --- a/drivers/infiniband/hw/ipath/ipath_mad.c +++ b/drivers/infiniband/hw/ipath/ipath_mad.c | |||
@@ -146,6 +146,15 @@ static int recv_subn_get_guidinfo(struct ib_smp *smp, | |||
146 | return reply(smp); | 146 | return reply(smp); |
147 | } | 147 | } |
148 | 148 | ||
149 | static void set_link_width_enabled(struct ipath_devdata *dd, u32 w) | ||
150 | { | ||
151 | (void) dd->ipath_f_set_ib_cfg(dd, IPATH_IB_CFG_LWID_ENB, w); | ||
152 | } | ||
153 | |||
154 | static void set_link_speed_enabled(struct ipath_devdata *dd, u32 s) | ||
155 | { | ||
156 | (void) dd->ipath_f_set_ib_cfg(dd, IPATH_IB_CFG_SPD_ENB, s); | ||
157 | } | ||
149 | 158 | ||
150 | static int get_overrunthreshold(struct ipath_devdata *dd) | 159 | static int get_overrunthreshold(struct ipath_devdata *dd) |
151 | { | 160 | { |
@@ -226,6 +235,7 @@ static int recv_subn_get_portinfo(struct ib_smp *smp, | |||
226 | struct ib_device *ibdev, u8 port) | 235 | struct ib_device *ibdev, u8 port) |
227 | { | 236 | { |
228 | struct ipath_ibdev *dev; | 237 | struct ipath_ibdev *dev; |
238 | struct ipath_devdata *dd; | ||
229 | struct ib_port_info *pip = (struct ib_port_info *)smp->data; | 239 | struct ib_port_info *pip = (struct ib_port_info *)smp->data; |
230 | u16 lid; | 240 | u16 lid; |
231 | u8 ibcstat; | 241 | u8 ibcstat; |
@@ -239,6 +249,7 @@ static int recv_subn_get_portinfo(struct ib_smp *smp, | |||
239 | } | 249 | } |
240 | 250 | ||
241 | dev = to_idev(ibdev); | 251 | dev = to_idev(ibdev); |
252 | dd = dev->dd; | ||
242 | 253 | ||
243 | /* Clear all fields. Only set the non-zero fields. */ | 254 | /* Clear all fields. Only set the non-zero fields. */ |
244 | memset(smp->data, 0, sizeof(smp->data)); | 255 | memset(smp->data, 0, sizeof(smp->data)); |
@@ -248,25 +259,28 @@ static int recv_subn_get_portinfo(struct ib_smp *smp, | |||
248 | dev->mkeyprot == 0) | 259 | dev->mkeyprot == 0) |
249 | pip->mkey = dev->mkey; | 260 | pip->mkey = dev->mkey; |
250 | pip->gid_prefix = dev->gid_prefix; | 261 | pip->gid_prefix = dev->gid_prefix; |
251 | lid = dev->dd->ipath_lid; | 262 | lid = dd->ipath_lid; |
252 | pip->lid = lid ? cpu_to_be16(lid) : IB_LID_PERMISSIVE; | 263 | pip->lid = lid ? cpu_to_be16(lid) : IB_LID_PERMISSIVE; |
253 | pip->sm_lid = cpu_to_be16(dev->sm_lid); | 264 | pip->sm_lid = cpu_to_be16(dev->sm_lid); |
254 | pip->cap_mask = cpu_to_be32(dev->port_cap_flags); | 265 | pip->cap_mask = cpu_to_be32(dev->port_cap_flags); |
255 | /* pip->diag_code; */ | 266 | /* pip->diag_code; */ |
256 | pip->mkey_lease_period = cpu_to_be16(dev->mkey_lease_period); | 267 | pip->mkey_lease_period = cpu_to_be16(dev->mkey_lease_period); |
257 | pip->local_port_num = port; | 268 | pip->local_port_num = port; |
258 | pip->link_width_enabled = dev->link_width_enabled; | 269 | pip->link_width_enabled = dd->ipath_link_width_enabled; |
259 | pip->link_width_supported = 3; /* 1x or 4x */ | 270 | pip->link_width_supported = dd->ipath_link_width_supported; |
260 | pip->link_width_active = 2; /* 4x */ | 271 | pip->link_width_active = dd->ipath_link_width_active; |
261 | pip->linkspeed_portstate = 0x10; /* 2.5Gbps */ | 272 | pip->linkspeed_portstate = dd->ipath_link_speed_supported << 4; |
262 | ibcstat = dev->dd->ipath_lastibcstat; | 273 | ibcstat = dd->ipath_lastibcstat; |
263 | pip->linkspeed_portstate |= ((ibcstat >> 4) & 0x3) + 1; | 274 | /* map LinkState to IB portinfo values. */ |
275 | pip->linkspeed_portstate |= ipath_ib_linkstate(dd, ibcstat) + 1; | ||
276 | |||
264 | pip->portphysstate_linkdown = | 277 | pip->portphysstate_linkdown = |
265 | (ipath_cvt_physportstate[ibcstat & 0xf] << 4) | | 278 | (ipath_cvt_physportstate[ibcstat & dd->ibcs_lts_mask] << 4) | |
266 | (get_linkdowndefaultstate(dev->dd) ? 1 : 2); | 279 | (get_linkdowndefaultstate(dd) ? 1 : 2); |
267 | pip->mkeyprot_resv_lmc = (dev->mkeyprot << 6) | dev->dd->ipath_lmc; | 280 | pip->mkeyprot_resv_lmc = (dev->mkeyprot << 6) | dd->ipath_lmc; |
268 | pip->linkspeedactive_enabled = 0x11; /* 2.5Gbps, 2.5Gbps */ | 281 | pip->linkspeedactive_enabled = (dd->ipath_link_speed_active << 4) | |
269 | switch (dev->dd->ipath_ibmtu) { | 282 | dd->ipath_link_speed_enabled; |
283 | switch (dd->ipath_ibmtu) { | ||
270 | case 4096: | 284 | case 4096: |
271 | mtu = IB_MTU_4096; | 285 | mtu = IB_MTU_4096; |
272 | break; | 286 | break; |
@@ -300,7 +314,7 @@ static int recv_subn_get_portinfo(struct ib_smp *smp, | |||
300 | pip->mkey_violations = cpu_to_be16(dev->mkey_violations); | 314 | pip->mkey_violations = cpu_to_be16(dev->mkey_violations); |
301 | /* P_KeyViolations are counted by hardware. */ | 315 | /* P_KeyViolations are counted by hardware. */ |
302 | pip->pkey_violations = | 316 | pip->pkey_violations = |
303 | cpu_to_be16((ipath_get_cr_errpkey(dev->dd) - | 317 | cpu_to_be16((ipath_get_cr_errpkey(dd) - |
304 | dev->z_pkey_violations) & 0xFFFF); | 318 | dev->z_pkey_violations) & 0xFFFF); |
305 | pip->qkey_violations = cpu_to_be16(dev->qkey_violations); | 319 | pip->qkey_violations = cpu_to_be16(dev->qkey_violations); |
306 | /* Only the hardware GUID is supported for now */ | 320 | /* Only the hardware GUID is supported for now */ |
@@ -309,10 +323,17 @@ static int recv_subn_get_portinfo(struct ib_smp *smp, | |||
309 | /* 32.768 usec. response time (guessing) */ | 323 | /* 32.768 usec. response time (guessing) */ |
310 | pip->resv_resptimevalue = 3; | 324 | pip->resv_resptimevalue = 3; |
311 | pip->localphyerrors_overrunerrors = | 325 | pip->localphyerrors_overrunerrors = |
312 | (get_phyerrthreshold(dev->dd) << 4) | | 326 | (get_phyerrthreshold(dd) << 4) | |
313 | get_overrunthreshold(dev->dd); | 327 | get_overrunthreshold(dd); |
314 | /* pip->max_credit_hint; */ | 328 | /* pip->max_credit_hint; */ |
315 | /* pip->link_roundtrip_latency[3]; */ | 329 | if (dev->port_cap_flags & IB_PORT_LINK_LATENCY_SUP) { |
330 | u32 v; | ||
331 | |||
332 | v = dd->ipath_f_get_ib_cfg(dd, IPATH_IB_CFG_LINKLATENCY); | ||
333 | pip->link_roundtrip_latency[0] = v >> 16; | ||
334 | pip->link_roundtrip_latency[1] = v >> 8; | ||
335 | pip->link_roundtrip_latency[2] = v; | ||
336 | } | ||
316 | 337 | ||
317 | ret = reply(smp); | 338 | ret = reply(smp); |
318 | 339 | ||
@@ -440,19 +461,25 @@ static int recv_subn_set_portinfo(struct ib_smp *smp, | |||
440 | ib_dispatch_event(&event); | 461 | ib_dispatch_event(&event); |
441 | } | 462 | } |
442 | 463 | ||
443 | /* Only 4x supported but allow 1x or 4x to be set (see 14.2.6.6). */ | 464 | /* Allow 1x or 4x to be set (see 14.2.6.6). */ |
444 | lwe = pip->link_width_enabled; | 465 | lwe = pip->link_width_enabled; |
445 | if ((lwe >= 4 && lwe <= 8) || (lwe >= 0xC && lwe <= 0xFE)) | 466 | if (lwe) { |
446 | goto err; | 467 | if (lwe == 0xFF) |
447 | if (lwe == 0xFF) | 468 | lwe = dd->ipath_link_width_supported; |
448 | dev->link_width_enabled = 3; /* 1x or 4x */ | 469 | else if (lwe >= 16 || (lwe & ~dd->ipath_link_width_supported)) |
449 | else if (lwe) | 470 | goto err; |
450 | dev->link_width_enabled = lwe; | 471 | set_link_width_enabled(dd, lwe); |
472 | } | ||
451 | 473 | ||
452 | /* Only 2.5 Gbs supported. */ | 474 | /* Allow 2.5 or 5.0 Gbs. */ |
453 | lse = pip->linkspeedactive_enabled & 0xF; | 475 | lse = pip->linkspeedactive_enabled & 0xF; |
454 | if (lse >= 2 && lse <= 0xE) | 476 | if (lse) { |
455 | goto err; | 477 | if (lse == 15) |
478 | lse = dd->ipath_link_speed_supported; | ||
479 | else if (lse >= 8 || (lse & ~dd->ipath_link_speed_supported)) | ||
480 | goto err; | ||
481 | set_link_speed_enabled(dd, lse); | ||
482 | } | ||
456 | 483 | ||
457 | /* Set link down default state. */ | 484 | /* Set link down default state. */ |
458 | switch (pip->portphysstate_linkdown & 0xF) { | 485 | switch (pip->portphysstate_linkdown & 0xF) { |
@@ -946,10 +973,14 @@ static int recv_pma_get_portsamplescontrol(struct ib_perf *pmp, | |||
946 | * nsec. 0 == 4 nsec., 1 == 8 nsec., ..., 255 == 1020 nsec. Sample | 973 | * nsec. 0 == 4 nsec., 1 == 8 nsec., ..., 255 == 1020 nsec. Sample |
947 | * intervals are counted in ticks. Since we use Linux timers, that | 974 | * intervals are counted in ticks. Since we use Linux timers, that |
948 | * count in jiffies, we can't sample for less than 1000 ticks if HZ | 975 | * count in jiffies, we can't sample for less than 1000 ticks if HZ |
949 | * == 1000 (4000 ticks if HZ is 250). | 976 | * == 1000 (4000 ticks if HZ is 250). link_speed_active returns 2 for |
977 | * DDR, 1 for SDR, set the tick to 1 for DDR, 0 for SDR on chips that | ||
978 | * have hardware support for delaying packets. | ||
950 | */ | 979 | */ |
951 | /* XXX This is WRONG. */ | 980 | if (crp->cr_psstat) |
952 | p->tick = 250; /* 1 usec. */ | 981 | p->tick = dev->dd->ipath_link_speed_active - 1; |
982 | else | ||
983 | p->tick = 250; /* 1 usec. */ | ||
953 | p->counter_width = 4; /* 32 bit counters */ | 984 | p->counter_width = 4; /* 32 bit counters */ |
954 | p->counter_mask0_9 = COUNTER_MASK0_9; | 985 | p->counter_mask0_9 = COUNTER_MASK0_9; |
955 | spin_lock_irqsave(&dev->pending_lock, flags); | 986 | spin_lock_irqsave(&dev->pending_lock, flags); |