diff options
author | Bryan O'Sullivan <bos@pathscale.com> | 2006-08-25 14:24:32 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2006-09-22 18:22:31 -0400 |
commit | 34b2aafea38efdf02cd8107a6e1057e2a297c447 (patch) | |
tree | fc800510f947696156df70cf6608f8283bab868c /drivers/infiniband/hw/ipath/ipath_mad.c | |
parent | b1c1b6a30eac88665a35a207cc5e6233090b9d65 (diff) |
IB/ipath: simplify layering code
A lot of ipath layer code was only called in one place. Now that the
ipath_core and ib_ipath drivers are merged, it's more sensible to simply
inline the simple stuff that the layer code was doing.
Signed-off-by: Bryan O'Sullivan <bryan.osullivan@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 | 339 |
1 files changed, 294 insertions, 45 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_mad.c b/drivers/infiniband/hw/ipath/ipath_mad.c index d3402341b7d0..72d1db89db8f 100644 --- a/drivers/infiniband/hw/ipath/ipath_mad.c +++ b/drivers/infiniband/hw/ipath/ipath_mad.c | |||
@@ -101,15 +101,15 @@ static int recv_subn_get_nodeinfo(struct ib_smp *smp, | |||
101 | nip->num_ports = ibdev->phys_port_cnt; | 101 | nip->num_ports = ibdev->phys_port_cnt; |
102 | /* This is already in network order */ | 102 | /* This is already in network order */ |
103 | nip->sys_guid = to_idev(ibdev)->sys_image_guid; | 103 | nip->sys_guid = to_idev(ibdev)->sys_image_guid; |
104 | nip->node_guid = ipath_layer_get_guid(dd); | 104 | nip->node_guid = dd->ipath_guid; |
105 | nip->port_guid = nip->sys_guid; | 105 | nip->port_guid = nip->sys_guid; |
106 | nip->partition_cap = cpu_to_be16(ipath_layer_get_npkeys(dd)); | 106 | nip->partition_cap = cpu_to_be16(ipath_get_npkeys(dd)); |
107 | nip->device_id = cpu_to_be16(ipath_layer_get_deviceid(dd)); | 107 | nip->device_id = cpu_to_be16(dd->ipath_deviceid); |
108 | majrev = ipath_layer_get_majrev(dd); | 108 | majrev = dd->ipath_majrev; |
109 | minrev = ipath_layer_get_minrev(dd); | 109 | minrev = dd->ipath_minrev; |
110 | nip->revision = cpu_to_be32((majrev << 16) | minrev); | 110 | nip->revision = cpu_to_be32((majrev << 16) | minrev); |
111 | nip->local_port_num = port; | 111 | nip->local_port_num = port; |
112 | vendor = ipath_layer_get_vendorid(dd); | 112 | vendor = dd->ipath_vendorid; |
113 | nip->vendor_id[0] = 0; | 113 | nip->vendor_id[0] = 0; |
114 | nip->vendor_id[1] = vendor >> 8; | 114 | nip->vendor_id[1] = vendor >> 8; |
115 | nip->vendor_id[2] = vendor; | 115 | nip->vendor_id[2] = vendor; |
@@ -133,13 +133,89 @@ static int recv_subn_get_guidinfo(struct ib_smp *smp, | |||
133 | */ | 133 | */ |
134 | if (startgx == 0) | 134 | if (startgx == 0) |
135 | /* The first is a copy of the read-only HW GUID. */ | 135 | /* The first is a copy of the read-only HW GUID. */ |
136 | *p = ipath_layer_get_guid(to_idev(ibdev)->dd); | 136 | *p = to_idev(ibdev)->dd->ipath_guid; |
137 | else | 137 | else |
138 | smp->status |= IB_SMP_INVALID_FIELD; | 138 | smp->status |= IB_SMP_INVALID_FIELD; |
139 | 139 | ||
140 | return reply(smp); | 140 | return reply(smp); |
141 | } | 141 | } |
142 | 142 | ||
143 | |||
144 | static int get_overrunthreshold(struct ipath_devdata *dd) | ||
145 | { | ||
146 | return (dd->ipath_ibcctrl >> | ||
147 | INFINIPATH_IBCC_OVERRUNTHRESHOLD_SHIFT) & | ||
148 | INFINIPATH_IBCC_OVERRUNTHRESHOLD_MASK; | ||
149 | } | ||
150 | |||
151 | /** | ||
152 | * set_overrunthreshold - set the overrun threshold | ||
153 | * @dd: the infinipath device | ||
154 | * @n: the new threshold | ||
155 | * | ||
156 | * Note that this will only take effect when the link state changes. | ||
157 | */ | ||
158 | static int set_overrunthreshold(struct ipath_devdata *dd, unsigned n) | ||
159 | { | ||
160 | unsigned v; | ||
161 | |||
162 | v = (dd->ipath_ibcctrl >> INFINIPATH_IBCC_OVERRUNTHRESHOLD_SHIFT) & | ||
163 | INFINIPATH_IBCC_OVERRUNTHRESHOLD_MASK; | ||
164 | if (v != n) { | ||
165 | dd->ipath_ibcctrl &= | ||
166 | ~(INFINIPATH_IBCC_OVERRUNTHRESHOLD_MASK << | ||
167 | INFINIPATH_IBCC_OVERRUNTHRESHOLD_SHIFT); | ||
168 | dd->ipath_ibcctrl |= | ||
169 | (u64) n << INFINIPATH_IBCC_OVERRUNTHRESHOLD_SHIFT; | ||
170 | ipath_write_kreg(dd, dd->ipath_kregs->kr_ibcctrl, | ||
171 | dd->ipath_ibcctrl); | ||
172 | } | ||
173 | return 0; | ||
174 | } | ||
175 | |||
176 | static int get_phyerrthreshold(struct ipath_devdata *dd) | ||
177 | { | ||
178 | return (dd->ipath_ibcctrl >> | ||
179 | INFINIPATH_IBCC_PHYERRTHRESHOLD_SHIFT) & | ||
180 | INFINIPATH_IBCC_PHYERRTHRESHOLD_MASK; | ||
181 | } | ||
182 | |||
183 | /** | ||
184 | * set_phyerrthreshold - set the physical error threshold | ||
185 | * @dd: the infinipath device | ||
186 | * @n: the new threshold | ||
187 | * | ||
188 | * Note that this will only take effect when the link state changes. | ||
189 | */ | ||
190 | static int set_phyerrthreshold(struct ipath_devdata *dd, unsigned n) | ||
191 | { | ||
192 | unsigned v; | ||
193 | |||
194 | v = (dd->ipath_ibcctrl >> INFINIPATH_IBCC_PHYERRTHRESHOLD_SHIFT) & | ||
195 | INFINIPATH_IBCC_PHYERRTHRESHOLD_MASK; | ||
196 | if (v != n) { | ||
197 | dd->ipath_ibcctrl &= | ||
198 | ~(INFINIPATH_IBCC_PHYERRTHRESHOLD_MASK << | ||
199 | INFINIPATH_IBCC_PHYERRTHRESHOLD_SHIFT); | ||
200 | dd->ipath_ibcctrl |= | ||
201 | (u64) n << INFINIPATH_IBCC_PHYERRTHRESHOLD_SHIFT; | ||
202 | ipath_write_kreg(dd, dd->ipath_kregs->kr_ibcctrl, | ||
203 | dd->ipath_ibcctrl); | ||
204 | } | ||
205 | return 0; | ||
206 | } | ||
207 | |||
208 | /** | ||
209 | * get_linkdowndefaultstate - get the default linkdown state | ||
210 | * @dd: the infinipath device | ||
211 | * | ||
212 | * Returns zero if the default is POLL, 1 if the default is SLEEP. | ||
213 | */ | ||
214 | static int get_linkdowndefaultstate(struct ipath_devdata *dd) | ||
215 | { | ||
216 | return !!(dd->ipath_ibcctrl & INFINIPATH_IBCC_LINKDOWNDEFAULTSTATE); | ||
217 | } | ||
218 | |||
143 | static int recv_subn_get_portinfo(struct ib_smp *smp, | 219 | static int recv_subn_get_portinfo(struct ib_smp *smp, |
144 | struct ib_device *ibdev, u8 port) | 220 | struct ib_device *ibdev, u8 port) |
145 | { | 221 | { |
@@ -166,7 +242,7 @@ static int recv_subn_get_portinfo(struct ib_smp *smp, | |||
166 | (dev->mkeyprot_resv_lmc >> 6) == 0) | 242 | (dev->mkeyprot_resv_lmc >> 6) == 0) |
167 | pip->mkey = dev->mkey; | 243 | pip->mkey = dev->mkey; |
168 | pip->gid_prefix = dev->gid_prefix; | 244 | pip->gid_prefix = dev->gid_prefix; |
169 | lid = ipath_layer_get_lid(dev->dd); | 245 | lid = dev->dd->ipath_lid; |
170 | pip->lid = lid ? cpu_to_be16(lid) : IB_LID_PERMISSIVE; | 246 | pip->lid = lid ? cpu_to_be16(lid) : IB_LID_PERMISSIVE; |
171 | pip->sm_lid = cpu_to_be16(dev->sm_lid); | 247 | pip->sm_lid = cpu_to_be16(dev->sm_lid); |
172 | pip->cap_mask = cpu_to_be32(dev->port_cap_flags); | 248 | pip->cap_mask = cpu_to_be32(dev->port_cap_flags); |
@@ -177,14 +253,14 @@ static int recv_subn_get_portinfo(struct ib_smp *smp, | |||
177 | pip->link_width_supported = 3; /* 1x or 4x */ | 253 | pip->link_width_supported = 3; /* 1x or 4x */ |
178 | pip->link_width_active = 2; /* 4x */ | 254 | pip->link_width_active = 2; /* 4x */ |
179 | pip->linkspeed_portstate = 0x10; /* 2.5Gbps */ | 255 | pip->linkspeed_portstate = 0x10; /* 2.5Gbps */ |
180 | ibcstat = ipath_layer_get_lastibcstat(dev->dd); | 256 | ibcstat = dev->dd->ipath_lastibcstat; |
181 | pip->linkspeed_portstate |= ((ibcstat >> 4) & 0x3) + 1; | 257 | pip->linkspeed_portstate |= ((ibcstat >> 4) & 0x3) + 1; |
182 | pip->portphysstate_linkdown = | 258 | pip->portphysstate_linkdown = |
183 | (ipath_cvt_physportstate[ibcstat & 0xf] << 4) | | 259 | (ipath_cvt_physportstate[ibcstat & 0xf] << 4) | |
184 | (ipath_layer_get_linkdowndefaultstate(dev->dd) ? 1 : 2); | 260 | (get_linkdowndefaultstate(dev->dd) ? 1 : 2); |
185 | pip->mkeyprot_resv_lmc = dev->mkeyprot_resv_lmc; | 261 | pip->mkeyprot_resv_lmc = dev->mkeyprot_resv_lmc; |
186 | pip->linkspeedactive_enabled = 0x11; /* 2.5Gbps, 2.5Gbps */ | 262 | pip->linkspeedactive_enabled = 0x11; /* 2.5Gbps, 2.5Gbps */ |
187 | switch (ipath_layer_get_ibmtu(dev->dd)) { | 263 | switch (dev->dd->ipath_ibmtu) { |
188 | case 4096: | 264 | case 4096: |
189 | mtu = IB_MTU_4096; | 265 | mtu = IB_MTU_4096; |
190 | break; | 266 | break; |
@@ -217,7 +293,7 @@ static int recv_subn_get_portinfo(struct ib_smp *smp, | |||
217 | pip->mkey_violations = cpu_to_be16(dev->mkey_violations); | 293 | pip->mkey_violations = cpu_to_be16(dev->mkey_violations); |
218 | /* P_KeyViolations are counted by hardware. */ | 294 | /* P_KeyViolations are counted by hardware. */ |
219 | pip->pkey_violations = | 295 | pip->pkey_violations = |
220 | cpu_to_be16((ipath_layer_get_cr_errpkey(dev->dd) - | 296 | cpu_to_be16((ipath_get_cr_errpkey(dev->dd) - |
221 | dev->z_pkey_violations) & 0xFFFF); | 297 | dev->z_pkey_violations) & 0xFFFF); |
222 | pip->qkey_violations = cpu_to_be16(dev->qkey_violations); | 298 | pip->qkey_violations = cpu_to_be16(dev->qkey_violations); |
223 | /* Only the hardware GUID is supported for now */ | 299 | /* Only the hardware GUID is supported for now */ |
@@ -226,8 +302,8 @@ static int recv_subn_get_portinfo(struct ib_smp *smp, | |||
226 | /* 32.768 usec. response time (guessing) */ | 302 | /* 32.768 usec. response time (guessing) */ |
227 | pip->resv_resptimevalue = 3; | 303 | pip->resv_resptimevalue = 3; |
228 | pip->localphyerrors_overrunerrors = | 304 | pip->localphyerrors_overrunerrors = |
229 | (ipath_layer_get_phyerrthreshold(dev->dd) << 4) | | 305 | (get_phyerrthreshold(dev->dd) << 4) | |
230 | ipath_layer_get_overrunthreshold(dev->dd); | 306 | get_overrunthreshold(dev->dd); |
231 | /* pip->max_credit_hint; */ | 307 | /* pip->max_credit_hint; */ |
232 | /* pip->link_roundtrip_latency[3]; */ | 308 | /* pip->link_roundtrip_latency[3]; */ |
233 | 309 | ||
@@ -237,6 +313,20 @@ bail: | |||
237 | return ret; | 313 | return ret; |
238 | } | 314 | } |
239 | 315 | ||
316 | /** | ||
317 | * get_pkeys - return the PKEY table for port 0 | ||
318 | * @dd: the infinipath device | ||
319 | * @pkeys: the pkey table is placed here | ||
320 | */ | ||
321 | static int get_pkeys(struct ipath_devdata *dd, u16 * pkeys) | ||
322 | { | ||
323 | struct ipath_portdata *pd = dd->ipath_pd[0]; | ||
324 | |||
325 | memcpy(pkeys, pd->port_pkeys, sizeof(pd->port_pkeys)); | ||
326 | |||
327 | return 0; | ||
328 | } | ||
329 | |||
240 | static int recv_subn_get_pkeytable(struct ib_smp *smp, | 330 | static int recv_subn_get_pkeytable(struct ib_smp *smp, |
241 | struct ib_device *ibdev) | 331 | struct ib_device *ibdev) |
242 | { | 332 | { |
@@ -249,9 +339,9 @@ static int recv_subn_get_pkeytable(struct ib_smp *smp, | |||
249 | memset(smp->data, 0, sizeof(smp->data)); | 339 | memset(smp->data, 0, sizeof(smp->data)); |
250 | if (startpx == 0) { | 340 | if (startpx == 0) { |
251 | struct ipath_ibdev *dev = to_idev(ibdev); | 341 | struct ipath_ibdev *dev = to_idev(ibdev); |
252 | unsigned i, n = ipath_layer_get_npkeys(dev->dd); | 342 | unsigned i, n = ipath_get_npkeys(dev->dd); |
253 | 343 | ||
254 | ipath_layer_get_pkeys(dev->dd, p); | 344 | get_pkeys(dev->dd, p); |
255 | 345 | ||
256 | for (i = 0; i < n; i++) | 346 | for (i = 0; i < n; i++) |
257 | q[i] = cpu_to_be16(p[i]); | 347 | q[i] = cpu_to_be16(p[i]); |
@@ -269,6 +359,24 @@ static int recv_subn_set_guidinfo(struct ib_smp *smp, | |||
269 | } | 359 | } |
270 | 360 | ||
271 | /** | 361 | /** |
362 | * set_linkdowndefaultstate - set the default linkdown state | ||
363 | * @dd: the infinipath device | ||
364 | * @sleep: the new state | ||
365 | * | ||
366 | * Note that this will only take effect when the link state changes. | ||
367 | */ | ||
368 | static int set_linkdowndefaultstate(struct ipath_devdata *dd, int sleep) | ||
369 | { | ||
370 | if (sleep) | ||
371 | dd->ipath_ibcctrl |= INFINIPATH_IBCC_LINKDOWNDEFAULTSTATE; | ||
372 | else | ||
373 | dd->ipath_ibcctrl &= ~INFINIPATH_IBCC_LINKDOWNDEFAULTSTATE; | ||
374 | ipath_write_kreg(dd, dd->ipath_kregs->kr_ibcctrl, | ||
375 | dd->ipath_ibcctrl); | ||
376 | return 0; | ||
377 | } | ||
378 | |||
379 | /** | ||
272 | * recv_subn_set_portinfo - set port information | 380 | * recv_subn_set_portinfo - set port information |
273 | * @smp: the incoming SM packet | 381 | * @smp: the incoming SM packet |
274 | * @ibdev: the infiniband device | 382 | * @ibdev: the infiniband device |
@@ -290,7 +398,7 @@ static int recv_subn_set_portinfo(struct ib_smp *smp, | |||
290 | u8 state; | 398 | u8 state; |
291 | u16 lstate; | 399 | u16 lstate; |
292 | u32 mtu; | 400 | u32 mtu; |
293 | int ret; | 401 | int ret, ore; |
294 | 402 | ||
295 | if (be32_to_cpu(smp->attr_mod) > ibdev->phys_port_cnt) | 403 | if (be32_to_cpu(smp->attr_mod) > ibdev->phys_port_cnt) |
296 | goto err; | 404 | goto err; |
@@ -304,7 +412,7 @@ static int recv_subn_set_portinfo(struct ib_smp *smp, | |||
304 | dev->mkey_lease_period = be16_to_cpu(pip->mkey_lease_period); | 412 | dev->mkey_lease_period = be16_to_cpu(pip->mkey_lease_period); |
305 | 413 | ||
306 | lid = be16_to_cpu(pip->lid); | 414 | lid = be16_to_cpu(pip->lid); |
307 | if (lid != ipath_layer_get_lid(dev->dd)) { | 415 | if (lid != dev->dd->ipath_lid) { |
308 | /* Must be a valid unicast LID address. */ | 416 | /* Must be a valid unicast LID address. */ |
309 | if (lid == 0 || lid >= IPATH_MULTICAST_LID_BASE) | 417 | if (lid == 0 || lid >= IPATH_MULTICAST_LID_BASE) |
310 | goto err; | 418 | goto err; |
@@ -342,11 +450,11 @@ static int recv_subn_set_portinfo(struct ib_smp *smp, | |||
342 | case 0: /* NOP */ | 450 | case 0: /* NOP */ |
343 | break; | 451 | break; |
344 | case 1: /* SLEEP */ | 452 | case 1: /* SLEEP */ |
345 | if (ipath_layer_set_linkdowndefaultstate(dev->dd, 1)) | 453 | if (set_linkdowndefaultstate(dev->dd, 1)) |
346 | goto err; | 454 | goto err; |
347 | break; | 455 | break; |
348 | case 2: /* POLL */ | 456 | case 2: /* POLL */ |
349 | if (ipath_layer_set_linkdowndefaultstate(dev->dd, 0)) | 457 | if (set_linkdowndefaultstate(dev->dd, 0)) |
350 | goto err; | 458 | goto err; |
351 | break; | 459 | break; |
352 | default: | 460 | default: |
@@ -376,7 +484,7 @@ static int recv_subn_set_portinfo(struct ib_smp *smp, | |||
376 | /* XXX We have already partially updated our state! */ | 484 | /* XXX We have already partially updated our state! */ |
377 | goto err; | 485 | goto err; |
378 | } | 486 | } |
379 | ipath_layer_set_mtu(dev->dd, mtu); | 487 | ipath_set_mtu(dev->dd, mtu); |
380 | 488 | ||
381 | dev->sm_sl = pip->neighbormtu_mastersmsl & 0xF; | 489 | dev->sm_sl = pip->neighbormtu_mastersmsl & 0xF; |
382 | 490 | ||
@@ -392,20 +500,16 @@ static int recv_subn_set_portinfo(struct ib_smp *smp, | |||
392 | * later. | 500 | * later. |
393 | */ | 501 | */ |
394 | if (pip->pkey_violations == 0) | 502 | if (pip->pkey_violations == 0) |
395 | dev->z_pkey_violations = | 503 | dev->z_pkey_violations = ipath_get_cr_errpkey(dev->dd); |
396 | ipath_layer_get_cr_errpkey(dev->dd); | ||
397 | 504 | ||
398 | if (pip->qkey_violations == 0) | 505 | if (pip->qkey_violations == 0) |
399 | dev->qkey_violations = 0; | 506 | dev->qkey_violations = 0; |
400 | 507 | ||
401 | if (ipath_layer_set_phyerrthreshold( | 508 | ore = pip->localphyerrors_overrunerrors; |
402 | dev->dd, | 509 | if (set_phyerrthreshold(dev->dd, (ore >> 4) & 0xF)) |
403 | (pip->localphyerrors_overrunerrors >> 4) & 0xF)) | ||
404 | goto err; | 510 | goto err; |
405 | 511 | ||
406 | if (ipath_layer_set_overrunthreshold( | 512 | if (set_overrunthreshold(dev->dd, (ore & 0xF))) |
407 | dev->dd, | ||
408 | (pip->localphyerrors_overrunerrors & 0xF))) | ||
409 | goto err; | 513 | goto err; |
410 | 514 | ||
411 | dev->subnet_timeout = pip->clientrereg_resv_subnetto & 0x1F; | 515 | dev->subnet_timeout = pip->clientrereg_resv_subnetto & 0x1F; |
@@ -423,7 +527,7 @@ static int recv_subn_set_portinfo(struct ib_smp *smp, | |||
423 | * is down or is being set to down. | 527 | * is down or is being set to down. |
424 | */ | 528 | */ |
425 | state = pip->linkspeed_portstate & 0xF; | 529 | state = pip->linkspeed_portstate & 0xF; |
426 | flags = ipath_layer_get_flags(dev->dd); | 530 | flags = dev->dd->ipath_flags; |
427 | lstate = (pip->portphysstate_linkdown >> 4) & 0xF; | 531 | lstate = (pip->portphysstate_linkdown >> 4) & 0xF; |
428 | if (lstate && !(state == IB_PORT_DOWN || state == IB_PORT_NOP)) | 532 | if (lstate && !(state == IB_PORT_DOWN || state == IB_PORT_NOP)) |
429 | goto err; | 533 | goto err; |
@@ -439,7 +543,7 @@ static int recv_subn_set_portinfo(struct ib_smp *smp, | |||
439 | /* FALLTHROUGH */ | 543 | /* FALLTHROUGH */ |
440 | case IB_PORT_DOWN: | 544 | case IB_PORT_DOWN: |
441 | if (lstate == 0) | 545 | if (lstate == 0) |
442 | if (ipath_layer_get_linkdowndefaultstate(dev->dd)) | 546 | if (get_linkdowndefaultstate(dev->dd)) |
443 | lstate = IPATH_IB_LINKDOWN_SLEEP; | 547 | lstate = IPATH_IB_LINKDOWN_SLEEP; |
444 | else | 548 | else |
445 | lstate = IPATH_IB_LINKDOWN; | 549 | lstate = IPATH_IB_LINKDOWN; |
@@ -451,7 +555,7 @@ static int recv_subn_set_portinfo(struct ib_smp *smp, | |||
451 | lstate = IPATH_IB_LINKDOWN_DISABLE; | 555 | lstate = IPATH_IB_LINKDOWN_DISABLE; |
452 | else | 556 | else |
453 | goto err; | 557 | goto err; |
454 | ipath_layer_set_linkstate(dev->dd, lstate); | 558 | ipath_set_linkstate(dev->dd, lstate); |
455 | if (flags & IPATH_LINKACTIVE) { | 559 | if (flags & IPATH_LINKACTIVE) { |
456 | event.event = IB_EVENT_PORT_ERR; | 560 | event.event = IB_EVENT_PORT_ERR; |
457 | ib_dispatch_event(&event); | 561 | ib_dispatch_event(&event); |
@@ -460,7 +564,7 @@ static int recv_subn_set_portinfo(struct ib_smp *smp, | |||
460 | case IB_PORT_ARMED: | 564 | case IB_PORT_ARMED: |
461 | if (!(flags & (IPATH_LINKINIT | IPATH_LINKACTIVE))) | 565 | if (!(flags & (IPATH_LINKINIT | IPATH_LINKACTIVE))) |
462 | break; | 566 | break; |
463 | ipath_layer_set_linkstate(dev->dd, IPATH_IB_LINKARM); | 567 | ipath_set_linkstate(dev->dd, IPATH_IB_LINKARM); |
464 | if (flags & IPATH_LINKACTIVE) { | 568 | if (flags & IPATH_LINKACTIVE) { |
465 | event.event = IB_EVENT_PORT_ERR; | 569 | event.event = IB_EVENT_PORT_ERR; |
466 | ib_dispatch_event(&event); | 570 | ib_dispatch_event(&event); |
@@ -469,7 +573,7 @@ static int recv_subn_set_portinfo(struct ib_smp *smp, | |||
469 | case IB_PORT_ACTIVE: | 573 | case IB_PORT_ACTIVE: |
470 | if (!(flags & IPATH_LINKARMED)) | 574 | if (!(flags & IPATH_LINKARMED)) |
471 | break; | 575 | break; |
472 | ipath_layer_set_linkstate(dev->dd, IPATH_IB_LINKACTIVE); | 576 | ipath_set_linkstate(dev->dd, IPATH_IB_LINKACTIVE); |
473 | event.event = IB_EVENT_PORT_ACTIVE; | 577 | event.event = IB_EVENT_PORT_ACTIVE; |
474 | ib_dispatch_event(&event); | 578 | ib_dispatch_event(&event); |
475 | break; | 579 | break; |
@@ -493,6 +597,152 @@ done: | |||
493 | return ret; | 597 | return ret; |
494 | } | 598 | } |
495 | 599 | ||
600 | /** | ||
601 | * rm_pkey - decrecment the reference count for the given PKEY | ||
602 | * @dd: the infinipath device | ||
603 | * @key: the PKEY index | ||
604 | * | ||
605 | * Return true if this was the last reference and the hardware table entry | ||
606 | * needs to be changed. | ||
607 | */ | ||
608 | static int rm_pkey(struct ipath_devdata *dd, u16 key) | ||
609 | { | ||
610 | int i; | ||
611 | int ret; | ||
612 | |||
613 | for (i = 0; i < ARRAY_SIZE(dd->ipath_pkeys); i++) { | ||
614 | if (dd->ipath_pkeys[i] != key) | ||
615 | continue; | ||
616 | if (atomic_dec_and_test(&dd->ipath_pkeyrefs[i])) { | ||
617 | dd->ipath_pkeys[i] = 0; | ||
618 | ret = 1; | ||
619 | goto bail; | ||
620 | } | ||
621 | break; | ||
622 | } | ||
623 | |||
624 | ret = 0; | ||
625 | |||
626 | bail: | ||
627 | return ret; | ||
628 | } | ||
629 | |||
630 | /** | ||
631 | * add_pkey - add the given PKEY to the hardware table | ||
632 | * @dd: the infinipath device | ||
633 | * @key: the PKEY | ||
634 | * | ||
635 | * Return an error code if unable to add the entry, zero if no change, | ||
636 | * or 1 if the hardware PKEY register needs to be updated. | ||
637 | */ | ||
638 | static int add_pkey(struct ipath_devdata *dd, u16 key) | ||
639 | { | ||
640 | int i; | ||
641 | u16 lkey = key & 0x7FFF; | ||
642 | int any = 0; | ||
643 | int ret; | ||
644 | |||
645 | if (lkey == 0x7FFF) { | ||
646 | ret = 0; | ||
647 | goto bail; | ||
648 | } | ||
649 | |||
650 | /* Look for an empty slot or a matching PKEY. */ | ||
651 | for (i = 0; i < ARRAY_SIZE(dd->ipath_pkeys); i++) { | ||
652 | if (!dd->ipath_pkeys[i]) { | ||
653 | any++; | ||
654 | continue; | ||
655 | } | ||
656 | /* If it matches exactly, try to increment the ref count */ | ||
657 | if (dd->ipath_pkeys[i] == key) { | ||
658 | if (atomic_inc_return(&dd->ipath_pkeyrefs[i]) > 1) { | ||
659 | ret = 0; | ||
660 | goto bail; | ||
661 | } | ||
662 | /* Lost the race. Look for an empty slot below. */ | ||
663 | atomic_dec(&dd->ipath_pkeyrefs[i]); | ||
664 | any++; | ||
665 | } | ||
666 | /* | ||
667 | * It makes no sense to have both the limited and unlimited | ||
668 | * PKEY set at the same time since the unlimited one will | ||
669 | * disable the limited one. | ||
670 | */ | ||
671 | if ((dd->ipath_pkeys[i] & 0x7FFF) == lkey) { | ||
672 | ret = -EEXIST; | ||
673 | goto bail; | ||
674 | } | ||
675 | } | ||
676 | if (!any) { | ||
677 | ret = -EBUSY; | ||
678 | goto bail; | ||
679 | } | ||
680 | for (i = 0; i < ARRAY_SIZE(dd->ipath_pkeys); i++) { | ||
681 | if (!dd->ipath_pkeys[i] && | ||
682 | atomic_inc_return(&dd->ipath_pkeyrefs[i]) == 1) { | ||
683 | /* for ipathstats, etc. */ | ||
684 | ipath_stats.sps_pkeys[i] = lkey; | ||
685 | dd->ipath_pkeys[i] = key; | ||
686 | ret = 1; | ||
687 | goto bail; | ||
688 | } | ||
689 | } | ||
690 | ret = -EBUSY; | ||
691 | |||
692 | bail: | ||
693 | return ret; | ||
694 | } | ||
695 | |||
696 | /** | ||
697 | * set_pkeys - set the PKEY table for port 0 | ||
698 | * @dd: the infinipath device | ||
699 | * @pkeys: the PKEY table | ||
700 | */ | ||
701 | static int set_pkeys(struct ipath_devdata *dd, u16 *pkeys) | ||
702 | { | ||
703 | struct ipath_portdata *pd; | ||
704 | int i; | ||
705 | int changed = 0; | ||
706 | |||
707 | pd = dd->ipath_pd[0]; | ||
708 | |||
709 | for (i = 0; i < ARRAY_SIZE(pd->port_pkeys); i++) { | ||
710 | u16 key = pkeys[i]; | ||
711 | u16 okey = pd->port_pkeys[i]; | ||
712 | |||
713 | if (key == okey) | ||
714 | continue; | ||
715 | /* | ||
716 | * The value of this PKEY table entry is changing. | ||
717 | * Remove the old entry in the hardware's array of PKEYs. | ||
718 | */ | ||
719 | if (okey & 0x7FFF) | ||
720 | changed |= rm_pkey(dd, okey); | ||
721 | if (key & 0x7FFF) { | ||
722 | int ret = add_pkey(dd, key); | ||
723 | |||
724 | if (ret < 0) | ||
725 | key = 0; | ||
726 | else | ||
727 | changed |= ret; | ||
728 | } | ||
729 | pd->port_pkeys[i] = key; | ||
730 | } | ||
731 | if (changed) { | ||
732 | u64 pkey; | ||
733 | |||
734 | pkey = (u64) dd->ipath_pkeys[0] | | ||
735 | ((u64) dd->ipath_pkeys[1] << 16) | | ||
736 | ((u64) dd->ipath_pkeys[2] << 32) | | ||
737 | ((u64) dd->ipath_pkeys[3] << 48); | ||
738 | ipath_cdbg(VERBOSE, "p0 new pkey reg %llx\n", | ||
739 | (unsigned long long) pkey); | ||
740 | ipath_write_kreg(dd, dd->ipath_kregs->kr_partitionkey, | ||
741 | pkey); | ||
742 | } | ||
743 | return 0; | ||
744 | } | ||
745 | |||
496 | static int recv_subn_set_pkeytable(struct ib_smp *smp, | 746 | static int recv_subn_set_pkeytable(struct ib_smp *smp, |
497 | struct ib_device *ibdev) | 747 | struct ib_device *ibdev) |
498 | { | 748 | { |
@@ -500,13 +750,12 @@ static int recv_subn_set_pkeytable(struct ib_smp *smp, | |||
500 | __be16 *p = (__be16 *) smp->data; | 750 | __be16 *p = (__be16 *) smp->data; |
501 | u16 *q = (u16 *) smp->data; | 751 | u16 *q = (u16 *) smp->data; |
502 | struct ipath_ibdev *dev = to_idev(ibdev); | 752 | struct ipath_ibdev *dev = to_idev(ibdev); |
503 | unsigned i, n = ipath_layer_get_npkeys(dev->dd); | 753 | unsigned i, n = ipath_get_npkeys(dev->dd); |
504 | 754 | ||
505 | for (i = 0; i < n; i++) | 755 | for (i = 0; i < n; i++) |
506 | q[i] = be16_to_cpu(p[i]); | 756 | q[i] = be16_to_cpu(p[i]); |
507 | 757 | ||
508 | if (startpx != 0 || | 758 | if (startpx != 0 || set_pkeys(dev->dd, q) != 0) |
509 | ipath_layer_set_pkeys(dev->dd, q) != 0) | ||
510 | smp->status |= IB_SMP_INVALID_FIELD; | 759 | smp->status |= IB_SMP_INVALID_FIELD; |
511 | 760 | ||
512 | return recv_subn_get_pkeytable(smp, ibdev); | 761 | return recv_subn_get_pkeytable(smp, ibdev); |
@@ -844,10 +1093,10 @@ static int recv_pma_get_portcounters(struct ib_perf *pmp, | |||
844 | struct ib_pma_portcounters *p = (struct ib_pma_portcounters *) | 1093 | struct ib_pma_portcounters *p = (struct ib_pma_portcounters *) |
845 | pmp->data; | 1094 | pmp->data; |
846 | struct ipath_ibdev *dev = to_idev(ibdev); | 1095 | struct ipath_ibdev *dev = to_idev(ibdev); |
847 | struct ipath_layer_counters cntrs; | 1096 | struct ipath_verbs_counters cntrs; |
848 | u8 port_select = p->port_select; | 1097 | u8 port_select = p->port_select; |
849 | 1098 | ||
850 | ipath_layer_get_counters(dev->dd, &cntrs); | 1099 | ipath_get_counters(dev->dd, &cntrs); |
851 | 1100 | ||
852 | /* Adjust counters for any resets done. */ | 1101 | /* Adjust counters for any resets done. */ |
853 | cntrs.symbol_error_counter -= dev->z_symbol_error_counter; | 1102 | cntrs.symbol_error_counter -= dev->z_symbol_error_counter; |
@@ -944,8 +1193,8 @@ static int recv_pma_get_portcounters_ext(struct ib_perf *pmp, | |||
944 | u64 swords, rwords, spkts, rpkts, xwait; | 1193 | u64 swords, rwords, spkts, rpkts, xwait; |
945 | u8 port_select = p->port_select; | 1194 | u8 port_select = p->port_select; |
946 | 1195 | ||
947 | ipath_layer_snapshot_counters(dev->dd, &swords, &rwords, &spkts, | 1196 | ipath_snapshot_counters(dev->dd, &swords, &rwords, &spkts, |
948 | &rpkts, &xwait); | 1197 | &rpkts, &xwait); |
949 | 1198 | ||
950 | /* Adjust counters for any resets done. */ | 1199 | /* Adjust counters for any resets done. */ |
951 | swords -= dev->z_port_xmit_data; | 1200 | swords -= dev->z_port_xmit_data; |
@@ -978,13 +1227,13 @@ static int recv_pma_set_portcounters(struct ib_perf *pmp, | |||
978 | struct ib_pma_portcounters *p = (struct ib_pma_portcounters *) | 1227 | struct ib_pma_portcounters *p = (struct ib_pma_portcounters *) |
979 | pmp->data; | 1228 | pmp->data; |
980 | struct ipath_ibdev *dev = to_idev(ibdev); | 1229 | struct ipath_ibdev *dev = to_idev(ibdev); |
981 | struct ipath_layer_counters cntrs; | 1230 | struct ipath_verbs_counters cntrs; |
982 | 1231 | ||
983 | /* | 1232 | /* |
984 | * Since the HW doesn't support clearing counters, we save the | 1233 | * Since the HW doesn't support clearing counters, we save the |
985 | * current count and subtract it from future responses. | 1234 | * current count and subtract it from future responses. |
986 | */ | 1235 | */ |
987 | ipath_layer_get_counters(dev->dd, &cntrs); | 1236 | ipath_get_counters(dev->dd, &cntrs); |
988 | 1237 | ||
989 | if (p->counter_select & IB_PMA_SEL_SYMBOL_ERROR) | 1238 | if (p->counter_select & IB_PMA_SEL_SYMBOL_ERROR) |
990 | dev->z_symbol_error_counter = cntrs.symbol_error_counter; | 1239 | dev->z_symbol_error_counter = cntrs.symbol_error_counter; |
@@ -1041,8 +1290,8 @@ static int recv_pma_set_portcounters_ext(struct ib_perf *pmp, | |||
1041 | struct ipath_ibdev *dev = to_idev(ibdev); | 1290 | struct ipath_ibdev *dev = to_idev(ibdev); |
1042 | u64 swords, rwords, spkts, rpkts, xwait; | 1291 | u64 swords, rwords, spkts, rpkts, xwait; |
1043 | 1292 | ||
1044 | ipath_layer_snapshot_counters(dev->dd, &swords, &rwords, &spkts, | 1293 | ipath_snapshot_counters(dev->dd, &swords, &rwords, &spkts, |
1045 | &rpkts, &xwait); | 1294 | &rpkts, &xwait); |
1046 | 1295 | ||
1047 | if (p->counter_select & IB_PMA_SELX_PORT_XMIT_DATA) | 1296 | if (p->counter_select & IB_PMA_SELX_PORT_XMIT_DATA) |
1048 | dev->z_port_xmit_data = swords; | 1297 | dev->z_port_xmit_data = swords; |