xref: /freebsd/sys/dev/ipmi/ipmi_kcs.c (revision 0629b152762b06325dd75a41bcb0a2789514141b)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2006 IronPort Systems Inc. <ambrisko@ironport.com>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31 
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/bus.h>
35 #include <sys/condvar.h>
36 #include <sys/eventhandler.h>
37 #include <sys/kernel.h>
38 #include <sys/kthread.h>
39 #include <sys/rman.h>
40 #include <sys/selinfo.h>
41 #include <machine/bus.h>
42 
43 #ifdef LOCAL_MODULE
44 #include <ipmi.h>
45 #include <ipmivars.h>
46 #else
47 #include <sys/ipmi.h>
48 #include <dev/ipmi/ipmivars.h>
49 #endif
50 
51 static void	kcs_clear_obf(struct ipmi_softc *, int);
52 static void	kcs_error(struct ipmi_softc *);
53 static int	kcs_wait_for_ibf(struct ipmi_softc *, int);
54 static int	kcs_wait_for_obf(struct ipmi_softc *, int);
55 
56 static int
57 kcs_wait_for_ibf(struct ipmi_softc *sc, int state)
58 {
59 	int status, start = ticks;
60 
61 	status = INB(sc, KCS_CTL_STS);
62 	if (state == 0) {
63 		/* WAIT FOR IBF = 0 */
64 		while (ticks - start < MAX_TIMEOUT && status & KCS_STATUS_IBF) {
65 			DELAY(100);
66 			status = INB(sc, KCS_CTL_STS);
67 		}
68 	} else {
69 		/* WAIT FOR IBF = 1 */
70 		while (ticks - start < MAX_TIMEOUT &&
71 		    !(status & KCS_STATUS_IBF)) {
72 			DELAY(100);
73 			status = INB(sc, KCS_CTL_STS);
74 		}
75 	}
76 	return (status);
77 }
78 
79 static int
80 kcs_wait_for_obf(struct ipmi_softc *sc, int state)
81 {
82 	int status, start = ticks;
83 
84 	status = INB(sc, KCS_CTL_STS);
85 	if (state == 0) {
86 		/* WAIT FOR OBF = 0 */
87 		while (ticks - start < MAX_TIMEOUT && status & KCS_STATUS_OBF) {
88 			DELAY(100);
89 			status = INB(sc, KCS_CTL_STS);
90 		}
91 	} else {
92 		/* WAIT FOR OBF = 1 */
93 		while (ticks - start < MAX_TIMEOUT &&
94 		    !(status & KCS_STATUS_OBF)) {
95 			DELAY(100);
96 			status = INB(sc, KCS_CTL_STS);
97 		}
98 	}
99 	return (status);
100 }
101 
102 static void
103 kcs_clear_obf(struct ipmi_softc *sc, int status)
104 {
105 	int data;
106 
107 	/* Clear OBF */
108 	if (status & KCS_STATUS_OBF) {
109 		data = INB(sc, KCS_DATA);
110 	}
111 }
112 
113 static void
114 kcs_error(struct ipmi_softc *sc)
115 {
116 	int retry, status;
117 	u_char data;
118 
119 	for (retry = 0; retry < 2; retry++) {
120 
121 		/* Wait for IBF = 0 */
122 		status = kcs_wait_for_ibf(sc, 0);
123 
124 		/* ABORT */
125 		OUTB(sc, KCS_CTL_STS, KCS_CONTROL_GET_STATUS_ABORT);
126 
127 		/* Wait for IBF = 0 */
128 		status = kcs_wait_for_ibf(sc, 0);
129 
130 		/* Clear OBF */
131 		kcs_clear_obf(sc, status);
132 
133 		if (status & KCS_STATUS_OBF) {
134 			data = INB(sc, KCS_DATA);
135 			if (data != 0)
136 				device_printf(sc->ipmi_dev,
137 				    "KCS Error Data %02x\n", data);
138 		}
139 
140 		/* 0x00 to DATA_IN */
141 		OUTB(sc, KCS_DATA, 0x00);
142 
143 		/* Wait for IBF = 0 */
144 		status = kcs_wait_for_ibf(sc, 0);
145 
146 		if (KCS_STATUS_STATE(status) == KCS_STATUS_STATE_READ) {
147 
148 			/* Wait for OBF = 1 */
149 			status = kcs_wait_for_obf(sc, 1);
150 
151 			/* Read error status */
152 			data = INB(sc, KCS_DATA);
153 			if (data != 0 && (data != 0xff || bootverbose))
154 				device_printf(sc->ipmi_dev, "KCS error: %02x\n",
155 				    data);
156 
157 			/* Write READ into Data_in */
158 			OUTB(sc, KCS_DATA, KCS_DATA_IN_READ);
159 
160 			/* Wait for IBF = 0 */
161 			status = kcs_wait_for_ibf(sc, 0);
162 		}
163 
164 		/* IDLE STATE */
165 		if (KCS_STATUS_STATE(status) == KCS_STATUS_STATE_IDLE) {
166 			/* Wait for OBF = 1 */
167 			status = kcs_wait_for_obf(sc, 1);
168 
169 			/* Clear OBF */
170 			kcs_clear_obf(sc, status);
171 			return;
172 		}
173 	}
174 	device_printf(sc->ipmi_dev, "KCS: Error retry exhausted\n");
175 }
176 
177 /*
178  * Start to write a request.  Waits for IBF to clear and then sends the
179  * WR_START command.
180  */
181 static int
182 kcs_start_write(struct ipmi_softc *sc)
183 {
184 	int retry, status;
185 
186 	for (retry = 0; retry < 10; retry++) {
187 		/* Wait for IBF = 0 */
188 		status = kcs_wait_for_ibf(sc, 0);
189 		if (status & KCS_STATUS_IBF)
190 			return (0);
191 
192 		/* Clear OBF */
193 		kcs_clear_obf(sc, status);
194 
195 		/* Write start to command */
196 		OUTB(sc, KCS_CTL_STS, KCS_CONTROL_WRITE_START);
197 
198 		/* Wait for IBF = 0 */
199 		status = kcs_wait_for_ibf(sc, 0);
200 		if (status & KCS_STATUS_IBF)
201 			return (0);
202 
203 		if (KCS_STATUS_STATE(status) == KCS_STATUS_STATE_WRITE)
204 			break;
205 		DELAY(1000000);
206 	}
207 
208 	if (KCS_STATUS_STATE(status) != KCS_STATUS_STATE_WRITE)
209 		/* error state */
210 		return (0);
211 
212 	/* Clear OBF */
213 	kcs_clear_obf(sc, status);
214 
215 	return (1);
216 }
217 
218 /*
219  * Write a byte of the request message, excluding the last byte of the
220  * message which requires special handling.
221  */
222 static int
223 kcs_write_byte(struct ipmi_softc *sc, u_char data)
224 {
225 	int status;
226 
227 	/* Data to Data */
228 	OUTB(sc, KCS_DATA, data);
229 
230 	/* Wait for IBF = 0 */
231 	status = kcs_wait_for_ibf(sc, 0);
232 	if (status & KCS_STATUS_IBF)
233 		return (0);
234 
235 	if (KCS_STATUS_STATE(status) != KCS_STATUS_STATE_WRITE)
236 		return (0);
237 
238 	/* Clear OBF */
239 	kcs_clear_obf(sc, status);
240 	return (1);
241 }
242 
243 /*
244  * Write the last byte of a request message.
245  */
246 static int
247 kcs_write_last_byte(struct ipmi_softc *sc, u_char data)
248 {
249 	int status;
250 
251 	/* Write end to command */
252 	OUTB(sc, KCS_CTL_STS, KCS_CONTROL_WRITE_END);
253 
254 	/* Wait for IBF = 0 */
255 	status = kcs_wait_for_ibf(sc, 0);
256 	if (status & KCS_STATUS_IBF)
257 		return (0);
258 
259 	if (KCS_STATUS_STATE(status) != KCS_STATUS_STATE_WRITE)
260 		/* error state */
261 		return (0);
262 
263 	/* Clear OBF */
264 	kcs_clear_obf(sc, status);
265 
266 	/* Send data byte to DATA. */
267 	OUTB(sc, KCS_DATA, data);
268 	return (1);
269 }
270 
271 /*
272  * Read one byte of the reply message.
273  */
274 static int
275 kcs_read_byte(struct ipmi_softc *sc, u_char *data)
276 {
277 	int status;
278 	u_char dummy;
279 
280 	/* Wait for IBF = 0 */
281 	status = kcs_wait_for_ibf(sc, 0);
282 
283 	/* Read State */
284 	if (KCS_STATUS_STATE(status) == KCS_STATUS_STATE_READ) {
285 
286 		/* Wait for OBF = 1 */
287 		status = kcs_wait_for_obf(sc, 1);
288 		if ((status & KCS_STATUS_OBF) == 0)
289 			return (0);
290 
291 		/* Read Data_out */
292 		*data = INB(sc, KCS_DATA);
293 
294 		/* Write READ into Data_in */
295 		OUTB(sc, KCS_DATA, KCS_DATA_IN_READ);
296 		return (1);
297 	}
298 
299 	/* Idle State */
300 	if (KCS_STATUS_STATE(status) == KCS_STATUS_STATE_IDLE) {
301 
302 		/* Wait for OBF = 1*/
303 		status = kcs_wait_for_obf(sc, 1);
304 		if ((status & KCS_STATUS_OBF) == 0)
305 			return (0);
306 
307 		/* Read Dummy */
308 		dummy = INB(sc, KCS_DATA);
309 		return (2);
310 	}
311 
312 	/* Error State */
313 	return (0);
314 }
315 
316 /*
317  * Send a request message and collect the reply.  Returns true if we
318  * succeed.
319  */
320 static int
321 kcs_polled_request(struct ipmi_softc *sc, struct ipmi_request *req)
322 {
323 	u_char *cp, data;
324 	int i, state;
325 
326 	IPMI_IO_LOCK(sc);
327 
328 	/* Send the request. */
329 	if (!kcs_start_write(sc)) {
330 		device_printf(sc->ipmi_dev, "KCS: Failed to start write\n");
331 		goto fail;
332 	}
333 #ifdef KCS_DEBUG
334 	device_printf(sc->ipmi_dev, "KCS: WRITE_START... ok\n");
335 #endif
336 
337 	if (!kcs_write_byte(sc, req->ir_addr)) {
338 		device_printf(sc->ipmi_dev, "KCS: Failed to write address\n");
339 		goto fail;
340 	}
341 #ifdef KCS_DEBUG
342 	device_printf(sc->ipmi_dev, "KCS: Wrote address: %02x\n", req->ir_addr);
343 #endif
344 
345 	if (req->ir_requestlen == 0) {
346 		if (!kcs_write_last_byte(sc, req->ir_command)) {
347 			device_printf(sc->ipmi_dev,
348 			    "KCS: Failed to write command\n");
349 			goto fail;
350 		}
351 #ifdef KCS_DEBUG
352 		device_printf(sc->ipmi_dev, "KCS: Wrote command: %02x\n",
353 		    req->ir_command);
354 #endif
355 	} else {
356 		if (!kcs_write_byte(sc, req->ir_command)) {
357 			device_printf(sc->ipmi_dev,
358 			    "KCS: Failed to write command\n");
359 			goto fail;
360 		}
361 #ifdef KCS_DEBUG
362 		device_printf(sc->ipmi_dev, "KCS: Wrote command: %02x\n",
363 		    req->ir_command);
364 #endif
365 
366 		cp = req->ir_request;
367 		for (i = 0; i < req->ir_requestlen - 1; i++) {
368 			if (!kcs_write_byte(sc, *cp++)) {
369 				device_printf(sc->ipmi_dev,
370 				    "KCS: Failed to write data byte %d\n",
371 				    i + 1);
372 				goto fail;
373 			}
374 #ifdef KCS_DEBUG
375 			device_printf(sc->ipmi_dev, "KCS: Wrote data: %02x\n",
376 			    cp[-1]);
377 #endif
378 		}
379 
380 		if (!kcs_write_last_byte(sc, *cp)) {
381 			device_printf(sc->ipmi_dev,
382 			    "KCS: Failed to write last dta byte\n");
383 			goto fail;
384 		}
385 #ifdef KCS_DEBUG
386 		device_printf(sc->ipmi_dev, "KCS: Wrote last data: %02x\n",
387 		    *cp);
388 #endif
389 	}
390 
391 	/* Read the reply.  First, read the NetFn/LUN. */
392 	if (kcs_read_byte(sc, &data) != 1) {
393 		device_printf(sc->ipmi_dev, "KCS: Failed to read address\n");
394 		goto fail;
395 	}
396 #ifdef KCS_DEBUG
397 	device_printf(sc->ipmi_dev, "KCS: Read address: %02x\n", data);
398 #endif
399 	if (data != IPMI_REPLY_ADDR(req->ir_addr)) {
400 		device_printf(sc->ipmi_dev, "KCS: Reply address mismatch\n");
401 		goto fail;
402 	}
403 
404 	/* Next we read the command. */
405 	if (kcs_read_byte(sc, &data) != 1) {
406 		device_printf(sc->ipmi_dev, "KCS: Failed to read command\n");
407 		goto fail;
408 	}
409 #ifdef KCS_DEBUG
410 	device_printf(sc->ipmi_dev, "KCS: Read command: %02x\n", data);
411 #endif
412 	if (data != req->ir_command) {
413 		device_printf(sc->ipmi_dev, "KCS: Command mismatch\n");
414 		goto fail;
415 	}
416 
417 	/* Next we read the completion code. */
418 	if (kcs_read_byte(sc, &req->ir_compcode) != 1) {
419 		if (bootverbose) {
420 			device_printf(sc->ipmi_dev,
421 			    "KCS: Failed to read completion code\n");
422 		}
423 		goto fail;
424 	}
425 #ifdef KCS_DEBUG
426 	device_printf(sc->ipmi_dev, "KCS: Read completion code: %02x\n",
427 	    req->ir_compcode);
428 #endif
429 
430 	/* Finally, read the reply from the BMC. */
431 	i = 0;
432 	for (;;) {
433 		state = kcs_read_byte(sc, &data);
434 		if (state == 0) {
435 			device_printf(sc->ipmi_dev,
436 			    "KCS: Read failed on byte %d\n", i + 1);
437 			goto fail;
438 		}
439 		if (state == 2)
440 			break;
441 		if (i < req->ir_replybuflen) {
442 			req->ir_reply[i] = data;
443 #ifdef KCS_DEBUG
444 			device_printf(sc->ipmi_dev, "KCS: Read data %02x\n",
445 			    data);
446 		} else {
447 			device_printf(sc->ipmi_dev,
448 			    "KCS: Read short %02x byte %d\n", data, i + 1);
449 #endif
450 		}
451 		i++;
452 	}
453 	IPMI_IO_UNLOCK(sc);
454 	req->ir_replylen = i;
455 #ifdef KCS_DEBUG
456 	device_printf(sc->ipmi_dev, "KCS: READ finished (%d bytes)\n", i);
457 	if (req->ir_replybuflen < i)
458 #else
459 	if (req->ir_replybuflen < i && req->ir_replybuflen != 0)
460 #endif
461 		device_printf(sc->ipmi_dev,
462 		    "KCS: Read short: %zd buffer, %d actual\n",
463 		    req->ir_replybuflen, i);
464 	return (1);
465 fail:
466 	kcs_error(sc);
467 	IPMI_IO_UNLOCK(sc);
468 	return (0);
469 }
470 
471 static void
472 kcs_loop(void *arg)
473 {
474 	struct ipmi_softc *sc = arg;
475 	struct ipmi_request *req;
476 	int i, ok;
477 
478 	IPMI_LOCK(sc);
479 	while ((req = ipmi_dequeue_request(sc)) != NULL) {
480 		IPMI_UNLOCK(sc);
481 		ok = 0;
482 		for (i = 0; i < 3 && !ok; i++)
483 			ok = kcs_polled_request(sc, req);
484 		if (ok)
485 			req->ir_error = 0;
486 		else
487 			req->ir_error = EIO;
488 		IPMI_LOCK(sc);
489 		ipmi_complete_request(sc, req);
490 	}
491 	IPMI_UNLOCK(sc);
492 	kproc_exit(0);
493 }
494 
495 static int
496 kcs_startup(struct ipmi_softc *sc)
497 {
498 
499 	return (kproc_create(kcs_loop, sc, &sc->ipmi_kthread, 0, 0, "%s: kcs",
500 	    device_get_nameunit(sc->ipmi_dev)));
501 }
502 
503 static int
504 kcs_driver_request(struct ipmi_softc *sc, struct ipmi_request *req, int timo)
505 {
506 	int i, ok;
507 
508 	ok = 0;
509 	for (i = 0; i < 3 && !ok; i++)
510 		ok = kcs_polled_request(sc, req);
511 	if (ok)
512 		req->ir_error = 0;
513 	else
514 		req->ir_error = EIO;
515 	return (req->ir_error);
516 }
517 
518 int
519 ipmi_kcs_attach(struct ipmi_softc *sc)
520 {
521 	int status;
522 
523 	/* Setup function pointers. */
524 	sc->ipmi_startup = kcs_startup;
525 	sc->ipmi_enqueue_request = ipmi_polled_enqueue_request;
526 	sc->ipmi_driver_request = kcs_driver_request;
527 	sc->ipmi_driver_requests_polled = 1;
528 
529 	/* See if we can talk to the controller. */
530 	status = INB(sc, KCS_CTL_STS);
531 	if (status == 0xff) {
532 		device_printf(sc->ipmi_dev, "couldn't find it\n");
533 		return (ENXIO);
534 	}
535 
536 #ifdef KCS_DEBUG
537 	device_printf(sc->ipmi_dev, "KCS: initial state: %02x\n", status);
538 #endif
539 	if (status & KCS_STATUS_OBF ||
540 	    KCS_STATUS_STATE(status) != KCS_STATUS_STATE_IDLE)
541 		kcs_error(sc);
542 
543 	return (0);
544 }
545 
546 /*
547  * Determine the alignment automatically for a PCI attachment.  In this case,
548  * any unused bytes will return 0x00 when read.  We make use of the C/D bit
549  * in the CTL_STS register to try to start a GET_STATUS transaction.  When
550  * we write the command, that bit should be set, so we should get a non-zero
551  * value back when we read CTL_STS if the offset we are testing is the CTL_STS
552  * register.
553  */
554 int
555 ipmi_kcs_probe_align(struct ipmi_softc *sc)
556 {
557 	int data, status;
558 
559 	sc->ipmi_io_spacing = 1;
560 retry:
561 #ifdef KCS_DEBUG
562 	device_printf(sc->ipmi_dev, "Trying KCS align %d... ", sc->ipmi_io_spacing);
563 #endif
564 
565 	/* Wait for IBF = 0 */
566 	status = INB(sc, KCS_CTL_STS);
567 	while (status & KCS_STATUS_IBF) {
568 		DELAY(100);
569 		status = INB(sc, KCS_CTL_STS);
570 	}
571 
572 	OUTB(sc, KCS_CTL_STS, KCS_CONTROL_GET_STATUS_ABORT);
573 
574 	/* Wait for IBF = 0 */
575 	status = INB(sc, KCS_CTL_STS);
576 	while (status & KCS_STATUS_IBF) {
577 		DELAY(100);
578 		status = INB(sc, KCS_CTL_STS);
579 	}
580 
581 	/* If we got 0x00 back, then this must not be the CTL_STS register. */
582 	if (status == 0) {
583 #ifdef KCS_DEBUG
584 		printf("failed\n");
585 #endif
586 		sc->ipmi_io_spacing <<= 1;
587 		if (sc->ipmi_io_spacing > 4)
588 			return (0);
589 		goto retry;
590 	}
591 #ifdef KCS_DEBUG
592 	printf("ok\n");
593 #endif
594 
595 	/* Finish out the transaction. */
596 
597 	/* Clear OBF */
598 	if (status & KCS_STATUS_OBF)
599 		data = INB(sc, KCS_DATA);
600 
601 	/* 0x00 to DATA_IN */
602 	OUTB(sc, KCS_DATA, 0);
603 
604 	/* Wait for IBF = 0 */
605 	status = INB(sc, KCS_CTL_STS);
606 	while (status & KCS_STATUS_IBF) {
607 		DELAY(100);
608 		status = INB(sc, KCS_CTL_STS);
609 	}
610 
611 	if (KCS_STATUS_STATE(status) == KCS_STATUS_STATE_READ) {
612 		/* Wait for IBF = 1 */
613 		while (!(status & KCS_STATUS_OBF)) {
614 			DELAY(100);
615 			status = INB(sc, KCS_CTL_STS);
616 		}
617 
618 		/* Read error status. */
619 		data = INB(sc, KCS_DATA);
620 
621 		/* Write dummy READ to DATA_IN. */
622 		OUTB(sc, KCS_DATA, KCS_DATA_IN_READ);
623 
624 		/* Wait for IBF = 0 */
625 		status = INB(sc, KCS_CTL_STS);
626 		while (status & KCS_STATUS_IBF) {
627 			DELAY(100);
628 			status = INB(sc, KCS_CTL_STS);
629 		}
630 	}
631 
632 	if (KCS_STATUS_STATE(status) == KCS_STATUS_STATE_IDLE) {
633 		/* Wait for IBF = 1 */
634 		while (!(status & KCS_STATUS_OBF)) {
635 			DELAY(100);
636 			status = INB(sc, KCS_CTL_STS);
637 		}
638 
639 		/* Clear OBF */
640 		if (status & KCS_STATUS_OBF)
641 			data = INB(sc, KCS_DATA);
642 	} else
643 		device_printf(sc->ipmi_dev, "KCS probe: end state %x\n",
644 		    KCS_STATUS_STATE(status));
645 
646 	return (1);
647 }
648