xref: /freebsd/sys/dev/ipmi/ipmi_kcs.c (revision f5147e312f43a9050468de539aeafa072caa1a60)
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)
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 		device_printf(sc->ipmi_dev,
420 		    "KCS: Failed to read completion code\n");
421 		goto fail;
422 	}
423 #ifdef KCS_DEBUG
424 	device_printf(sc->ipmi_dev, "KCS: Read completion code: %02x\n",
425 	    req->ir_compcode);
426 #endif
427 
428 	/* Finally, read the reply from the BMC. */
429 	i = 0;
430 	for (;;) {
431 		state = kcs_read_byte(sc, &data);
432 		if (state == 0) {
433 			device_printf(sc->ipmi_dev,
434 			    "KCS: Read failed on byte %d\n", i + 1);
435 			goto fail;
436 		}
437 		if (state == 2)
438 			break;
439 		if (i < req->ir_replybuflen) {
440 			req->ir_reply[i] = data;
441 #ifdef KCS_DEBUG
442 			device_printf(sc->ipmi_dev, "KCS: Read data %02x\n",
443 			    data);
444 		} else {
445 			device_printf(sc->ipmi_dev,
446 			    "KCS: Read short %02x byte %d\n", data, i + 1);
447 #endif
448 		}
449 		i++;
450 	}
451 	IPMI_IO_UNLOCK(sc);
452 	req->ir_replylen = i;
453 #ifdef KCS_DEBUG
454 	device_printf(sc->ipmi_dev, "KCS: READ finished (%d bytes)\n", i);
455 	if (req->ir_replybuflen < i)
456 #else
457 	if (req->ir_replybuflen < i && req->ir_replybuflen != 0)
458 #endif
459 		device_printf(sc->ipmi_dev,
460 		    "KCS: Read short: %zd buffer, %d actual\n",
461 		    req->ir_replybuflen, i);
462 	return (1);
463 fail:
464 	kcs_error(sc);
465 	IPMI_IO_UNLOCK(sc);
466 	return (0);
467 }
468 
469 static void
470 kcs_loop(void *arg)
471 {
472 	struct ipmi_softc *sc = arg;
473 	struct ipmi_request *req;
474 	int i, ok;
475 
476 	IPMI_LOCK(sc);
477 	while ((req = ipmi_dequeue_request(sc)) != NULL) {
478 		IPMI_UNLOCK(sc);
479 		ok = 0;
480 		for (i = 0; i < 3 && !ok; i++)
481 			ok = kcs_polled_request(sc, req);
482 		if (ok)
483 			req->ir_error = 0;
484 		else
485 			req->ir_error = EIO;
486 		IPMI_LOCK(sc);
487 		ipmi_complete_request(sc, req);
488 	}
489 	IPMI_UNLOCK(sc);
490 	kproc_exit(0);
491 }
492 
493 static int
494 kcs_startup(struct ipmi_softc *sc)
495 {
496 
497 	return (kproc_create(kcs_loop, sc, &sc->ipmi_kthread, 0, 0, "%s: kcs",
498 	    device_get_nameunit(sc->ipmi_dev)));
499 }
500 
501 static int
502 kcs_driver_request(struct ipmi_softc *sc, struct ipmi_request *req, int timo)
503 {
504 	int i, ok;
505 
506 	ok = 0;
507 	for (i = 0; i < 3 && !ok; i++)
508 		ok = kcs_polled_request(sc, req);
509 	if (ok)
510 		req->ir_error = 0;
511 	else
512 		req->ir_error = EIO;
513 	return (req->ir_error);
514 }
515 
516 int
517 ipmi_kcs_attach(struct ipmi_softc *sc)
518 {
519 	int status;
520 
521 	/* Setup function pointers. */
522 	sc->ipmi_startup = kcs_startup;
523 	sc->ipmi_enqueue_request = ipmi_polled_enqueue_request;
524 	sc->ipmi_driver_request = kcs_driver_request;
525 	sc->ipmi_driver_requests_polled = 1;
526 
527 	/* See if we can talk to the controller. */
528 	status = INB(sc, KCS_CTL_STS);
529 	if (status == 0xff) {
530 		device_printf(sc->ipmi_dev, "couldn't find it\n");
531 		return (ENXIO);
532 	}
533 
534 #ifdef KCS_DEBUG
535 	device_printf(sc->ipmi_dev, "KCS: initial state: %02x\n", status);
536 #endif
537 	if (status & KCS_STATUS_OBF ||
538 	    KCS_STATUS_STATE(status) != KCS_STATUS_STATE_IDLE)
539 		kcs_error(sc);
540 
541 	return (0);
542 }
543 
544 /*
545  * Determine the alignment automatically for a PCI attachment.  In this case,
546  * any unused bytes will return 0x00 when read.  We make use of the C/D bit
547  * in the CTL_STS register to try to start a GET_STATUS transaction.  When
548  * we write the command, that bit should be set, so we should get a non-zero
549  * value back when we read CTL_STS if the offset we are testing is the CTL_STS
550  * register.
551  */
552 int
553 ipmi_kcs_probe_align(struct ipmi_softc *sc)
554 {
555 	int data, status;
556 
557 	sc->ipmi_io_spacing = 1;
558 retry:
559 #ifdef KCS_DEBUG
560 	device_printf(sc->ipmi_dev, "Trying KCS align %d... ", sc->ipmi_io_spacing);
561 #endif
562 
563 	/* Wait for IBF = 0 */
564 	status = INB(sc, KCS_CTL_STS);
565 	while (status & KCS_STATUS_IBF) {
566 		DELAY(100);
567 		status = INB(sc, KCS_CTL_STS);
568 	}
569 
570 	OUTB(sc, KCS_CTL_STS, KCS_CONTROL_GET_STATUS_ABORT);
571 
572 	/* Wait for IBF = 0 */
573 	status = INB(sc, KCS_CTL_STS);
574 	while (status & KCS_STATUS_IBF) {
575 		DELAY(100);
576 		status = INB(sc, KCS_CTL_STS);
577 	}
578 
579 	/* If we got 0x00 back, then this must not be the CTL_STS register. */
580 	if (status == 0) {
581 #ifdef KCS_DEBUG
582 		printf("failed\n");
583 #endif
584 		sc->ipmi_io_spacing <<= 1;
585 		if (sc->ipmi_io_spacing > 4)
586 			return (0);
587 		goto retry;
588 	}
589 #ifdef KCS_DEBUG
590 	printf("ok\n");
591 #endif
592 
593 	/* Finish out the transaction. */
594 
595 	/* Clear OBF */
596 	if (status & KCS_STATUS_OBF)
597 		data = INB(sc, KCS_DATA);
598 
599 	/* 0x00 to DATA_IN */
600 	OUTB(sc, KCS_DATA, 0);
601 
602 	/* Wait for IBF = 0 */
603 	status = INB(sc, KCS_CTL_STS);
604 	while (status & KCS_STATUS_IBF) {
605 		DELAY(100);
606 		status = INB(sc, KCS_CTL_STS);
607 	}
608 
609 	if (KCS_STATUS_STATE(status) == KCS_STATUS_STATE_READ) {
610 		/* Wait for IBF = 1 */
611 		while (!(status & KCS_STATUS_OBF)) {
612 			DELAY(100);
613 			status = INB(sc, KCS_CTL_STS);
614 		}
615 
616 		/* Read error status. */
617 		data = INB(sc, KCS_DATA);
618 
619 		/* Write dummy READ to DATA_IN. */
620 		OUTB(sc, KCS_DATA, KCS_DATA_IN_READ);
621 
622 		/* Wait for IBF = 0 */
623 		status = INB(sc, KCS_CTL_STS);
624 		while (status & KCS_STATUS_IBF) {
625 			DELAY(100);
626 			status = INB(sc, KCS_CTL_STS);
627 		}
628 	}
629 
630 	if (KCS_STATUS_STATE(status) == KCS_STATUS_STATE_IDLE) {
631 		/* Wait for IBF = 1 */
632 		while (!(status & KCS_STATUS_OBF)) {
633 			DELAY(100);
634 			status = INB(sc, KCS_CTL_STS);
635 		}
636 
637 		/* Clear OBF */
638 		if (status & KCS_STATUS_OBF)
639 			data = INB(sc, KCS_DATA);
640 	} else
641 		device_printf(sc->ipmi_dev, "KCS probe: end state %x\n",
642 		    KCS_STATUS_STATE(status));
643 
644 	return (1);
645 }
646