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#define	POLLING_DELAY_MIN 4	/* Waits are 2-3 usecs on typical systems */
52#define	POLLING_DELAY_MAX 256
53
54static void	kcs_clear_obf(struct ipmi_softc *, int);
55static void	kcs_error(struct ipmi_softc *);
56static int	kcs_wait_for_ibf(struct ipmi_softc *, bool);
57static int	kcs_wait_for_obf(struct ipmi_softc *, bool);
58
59static int
60kcs_wait(struct ipmi_softc *sc, int value, int mask)
61{
62	int status, start = ticks;
63	int delay_usec = POLLING_DELAY_MIN;
64
65	status = INB(sc, KCS_CTL_STS);
66	while (ticks - start < MAX_TIMEOUT && (status & mask) != value) {
67		/*
68		 * The wait delay is increased exponentially to avoid putting
69		 * significant load on I/O bus.
70		 */
71		DELAY(delay_usec);
72		status = INB(sc, KCS_CTL_STS);
73		if (delay_usec < POLLING_DELAY_MAX)
74			delay_usec *= 2;
75	}
76	return (status);
77}
78
79static int
80kcs_wait_for_ibf(struct ipmi_softc *sc, bool level)
81{
82
83	return (kcs_wait(sc, level ? KCS_STATUS_IBF : 0, KCS_STATUS_IBF));
84}
85
86static int
87kcs_wait_for_obf(struct ipmi_softc *sc, bool level)
88{
89
90	return (kcs_wait(sc, level ? KCS_STATUS_OBF : 0, KCS_STATUS_OBF));
91}
92
93static void
94kcs_clear_obf(struct ipmi_softc *sc, int status)
95{
96	int data;
97
98	/* Clear OBF */
99	if (status & KCS_STATUS_OBF) {
100		data = INB(sc, KCS_DATA);
101	}
102}
103
104static void
105kcs_error(struct ipmi_softc *sc)
106{
107	int retry, status;
108	u_char data;
109
110	for (retry = 0; retry < 2; retry++) {
111
112		/* Wait for IBF = 0 */
113		status = kcs_wait_for_ibf(sc, 0);
114
115		/* ABORT */
116		OUTB(sc, KCS_CTL_STS, KCS_CONTROL_GET_STATUS_ABORT);
117
118		/* Wait for IBF = 0 */
119		status = kcs_wait_for_ibf(sc, 0);
120
121		/* Clear OBF */
122		kcs_clear_obf(sc, status);
123
124		if (status & KCS_STATUS_OBF) {
125			data = INB(sc, KCS_DATA);
126			if (data != 0)
127				device_printf(sc->ipmi_dev,
128				    "KCS Error Data %02x\n", data);
129		}
130
131		/* 0x00 to DATA_IN */
132		OUTB(sc, KCS_DATA, 0x00);
133
134		/* Wait for IBF = 0 */
135		status = kcs_wait_for_ibf(sc, 0);
136
137		if (KCS_STATUS_STATE(status) == KCS_STATUS_STATE_READ) {
138
139			/* Wait for OBF = 1 */
140			status = kcs_wait_for_obf(sc, 1);
141
142			/* Read error status */
143			data = INB(sc, KCS_DATA);
144			if (data != 0 && (data != 0xff || bootverbose))
145				device_printf(sc->ipmi_dev, "KCS error: %02x\n",
146				    data);
147
148			/* Write READ into Data_in */
149			OUTB(sc, KCS_DATA, KCS_DATA_IN_READ);
150
151			/* Wait for IBF = 0 */
152			status = kcs_wait_for_ibf(sc, 0);
153		}
154
155		/* IDLE STATE */
156		if (KCS_STATUS_STATE(status) == KCS_STATUS_STATE_IDLE) {
157			/* Wait for OBF = 1 */
158			status = kcs_wait_for_obf(sc, 1);
159
160			/* Clear OBF */
161			kcs_clear_obf(sc, status);
162			return;
163		}
164	}
165	device_printf(sc->ipmi_dev, "KCS: Error retry exhausted\n");
166}
167
168/*
169 * Start to write a request.  Waits for IBF to clear and then sends the
170 * WR_START command.
171 */
172static int
173kcs_start_write(struct ipmi_softc *sc)
174{
175	int retry, status;
176
177	for (retry = 0; retry < 10; retry++) {
178		/* Wait for IBF = 0 */
179		status = kcs_wait_for_ibf(sc, 0);
180		if (status & KCS_STATUS_IBF)
181			return (0);
182
183		/* Clear OBF */
184		kcs_clear_obf(sc, status);
185
186		/* Write start to command */
187		OUTB(sc, KCS_CTL_STS, KCS_CONTROL_WRITE_START);
188
189		/* Wait for IBF = 0 */
190		status = kcs_wait_for_ibf(sc, 0);
191		if (status & KCS_STATUS_IBF)
192			return (0);
193
194		if (KCS_STATUS_STATE(status) == KCS_STATUS_STATE_WRITE)
195			break;
196		DELAY(1000000);
197	}
198
199	if (KCS_STATUS_STATE(status) != KCS_STATUS_STATE_WRITE)
200		/* error state */
201		return (0);
202
203	/* Clear OBF */
204	kcs_clear_obf(sc, status);
205
206	return (1);
207}
208
209/*
210 * Write a byte of the request message, excluding the last byte of the
211 * message which requires special handling.
212 */
213static int
214kcs_write_byte(struct ipmi_softc *sc, u_char data)
215{
216	int status;
217
218	/* Data to Data */
219	OUTB(sc, KCS_DATA, data);
220
221	/* Wait for IBF = 0 */
222	status = kcs_wait_for_ibf(sc, 0);
223	if (status & KCS_STATUS_IBF)
224		return (0);
225
226	if (KCS_STATUS_STATE(status) != KCS_STATUS_STATE_WRITE)
227		return (0);
228
229	/* Clear OBF */
230	kcs_clear_obf(sc, status);
231	return (1);
232}
233
234/*
235 * Write the last byte of a request message.
236 */
237static int
238kcs_write_last_byte(struct ipmi_softc *sc, u_char data)
239{
240	int status;
241
242	/* Write end to command */
243	OUTB(sc, KCS_CTL_STS, KCS_CONTROL_WRITE_END);
244
245	/* Wait for IBF = 0 */
246	status = kcs_wait_for_ibf(sc, 0);
247	if (status & KCS_STATUS_IBF)
248		return (0);
249
250	if (KCS_STATUS_STATE(status) != KCS_STATUS_STATE_WRITE)
251		/* error state */
252		return (0);
253
254	/* Clear OBF */
255	kcs_clear_obf(sc, status);
256
257	/* Send data byte to DATA. */
258	OUTB(sc, KCS_DATA, data);
259	return (1);
260}
261
262/*
263 * Read one byte of the reply message.
264 */
265static int
266kcs_read_byte(struct ipmi_softc *sc, u_char *data)
267{
268	int status;
269	u_char dummy;
270
271	/* Wait for IBF = 0 */
272	status = kcs_wait_for_ibf(sc, 0);
273
274	/* Read State */
275	if (KCS_STATUS_STATE(status) == KCS_STATUS_STATE_READ) {
276
277		/* Wait for OBF = 1 */
278		status = kcs_wait_for_obf(sc, 1);
279		if ((status & KCS_STATUS_OBF) == 0)
280			return (0);
281
282		/* Read Data_out */
283		*data = INB(sc, KCS_DATA);
284
285		/* Write READ into Data_in */
286		OUTB(sc, KCS_DATA, KCS_DATA_IN_READ);
287		return (1);
288	}
289
290	/* Idle State */
291	if (KCS_STATUS_STATE(status) == KCS_STATUS_STATE_IDLE) {
292
293		/* Wait for OBF = 1*/
294		status = kcs_wait_for_obf(sc, 1);
295		if ((status & KCS_STATUS_OBF) == 0)
296			return (0);
297
298		/* Read Dummy */
299		dummy = INB(sc, KCS_DATA);
300		return (2);
301	}
302
303	/* Error State */
304	return (0);
305}
306
307/*
308 * Send a request message and collect the reply.  Returns true if we
309 * succeed.
310 */
311static int
312kcs_polled_request(struct ipmi_softc *sc, struct ipmi_request *req)
313{
314	u_char *cp, data;
315	int i, state;
316
317	IPMI_IO_LOCK(sc);
318
319	/* Send the request. */
320	if (!kcs_start_write(sc)) {
321		device_printf(sc->ipmi_dev, "KCS: Failed to start write\n");
322		goto fail;
323	}
324#ifdef KCS_DEBUG
325	device_printf(sc->ipmi_dev, "KCS: WRITE_START... ok\n");
326#endif
327
328	if (!kcs_write_byte(sc, req->ir_addr)) {
329		device_printf(sc->ipmi_dev, "KCS: Failed to write address\n");
330		goto fail;
331	}
332#ifdef KCS_DEBUG
333	device_printf(sc->ipmi_dev, "KCS: Wrote address: %02x\n", req->ir_addr);
334#endif
335
336	if (req->ir_requestlen == 0) {
337		if (!kcs_write_last_byte(sc, req->ir_command)) {
338			device_printf(sc->ipmi_dev,
339			    "KCS: Failed to write command\n");
340			goto fail;
341		}
342#ifdef KCS_DEBUG
343		device_printf(sc->ipmi_dev, "KCS: Wrote command: %02x\n",
344		    req->ir_command);
345#endif
346	} else {
347		if (!kcs_write_byte(sc, req->ir_command)) {
348			device_printf(sc->ipmi_dev,
349			    "KCS: Failed to write command\n");
350			goto fail;
351		}
352#ifdef KCS_DEBUG
353		device_printf(sc->ipmi_dev, "KCS: Wrote command: %02x\n",
354		    req->ir_command);
355#endif
356
357		cp = req->ir_request;
358		for (i = 0; i < req->ir_requestlen - 1; i++) {
359			if (!kcs_write_byte(sc, *cp++)) {
360				device_printf(sc->ipmi_dev,
361				    "KCS: Failed to write data byte %d\n",
362				    i + 1);
363				goto fail;
364			}
365#ifdef KCS_DEBUG
366			device_printf(sc->ipmi_dev, "KCS: Wrote data: %02x\n",
367			    cp[-1]);
368#endif
369		}
370
371		if (!kcs_write_last_byte(sc, *cp)) {
372			device_printf(sc->ipmi_dev,
373			    "KCS: Failed to write last dta byte\n");
374			goto fail;
375		}
376#ifdef KCS_DEBUG
377		device_printf(sc->ipmi_dev, "KCS: Wrote last data: %02x\n",
378		    *cp);
379#endif
380	}
381
382	/* Read the reply.  First, read the NetFn/LUN. */
383	if (kcs_read_byte(sc, &data) != 1) {
384		device_printf(sc->ipmi_dev, "KCS: Failed to read address\n");
385		goto fail;
386	}
387#ifdef KCS_DEBUG
388	device_printf(sc->ipmi_dev, "KCS: Read address: %02x\n", data);
389#endif
390	if (data != IPMI_REPLY_ADDR(req->ir_addr)) {
391		device_printf(sc->ipmi_dev, "KCS: Reply address mismatch\n");
392		goto fail;
393	}
394
395	/* Next we read the command. */
396	if (kcs_read_byte(sc, &data) != 1) {
397		device_printf(sc->ipmi_dev, "KCS: Failed to read command\n");
398		goto fail;
399	}
400#ifdef KCS_DEBUG
401	device_printf(sc->ipmi_dev, "KCS: Read command: %02x\n", data);
402#endif
403	if (data != req->ir_command) {
404		device_printf(sc->ipmi_dev, "KCS: Command mismatch\n");
405		goto fail;
406	}
407
408	/* Next we read the completion code. */
409	if (kcs_read_byte(sc, &req->ir_compcode) != 1) {
410		if (bootverbose) {
411			device_printf(sc->ipmi_dev,
412			    "KCS: Failed to read completion code\n");
413		}
414		goto fail;
415	}
416#ifdef KCS_DEBUG
417	device_printf(sc->ipmi_dev, "KCS: Read completion code: %02x\n",
418	    req->ir_compcode);
419#endif
420
421	/* Finally, read the reply from the BMC. */
422	i = 0;
423	for (;;) {
424		state = kcs_read_byte(sc, &data);
425		if (state == 0) {
426			device_printf(sc->ipmi_dev,
427			    "KCS: Read failed on byte %d\n", i + 1);
428			goto fail;
429		}
430		if (state == 2)
431			break;
432		if (i < req->ir_replybuflen) {
433			req->ir_reply[i] = data;
434#ifdef KCS_DEBUG
435			device_printf(sc->ipmi_dev, "KCS: Read data %02x\n",
436			    data);
437		} else {
438			device_printf(sc->ipmi_dev,
439			    "KCS: Read short %02x byte %d\n", data, i + 1);
440#endif
441		}
442		i++;
443	}
444	IPMI_IO_UNLOCK(sc);
445	req->ir_replylen = i;
446#ifdef KCS_DEBUG
447	device_printf(sc->ipmi_dev, "KCS: READ finished (%d bytes)\n", i);
448	if (req->ir_replybuflen < i)
449#else
450	if (req->ir_replybuflen < i && req->ir_replybuflen != 0)
451#endif
452		device_printf(sc->ipmi_dev,
453		    "KCS: Read short: %zd buffer, %d actual\n",
454		    req->ir_replybuflen, i);
455	return (1);
456fail:
457	kcs_error(sc);
458	IPMI_IO_UNLOCK(sc);
459	return (0);
460}
461
462static void
463kcs_loop(void *arg)
464{
465	struct ipmi_softc *sc = arg;
466	struct ipmi_request *req;
467	int i, ok;
468
469	IPMI_LOCK(sc);
470	while ((req = ipmi_dequeue_request(sc)) != NULL) {
471		IPMI_UNLOCK(sc);
472		ok = 0;
473		for (i = 0; i < 3 && !ok; i++)
474			ok = kcs_polled_request(sc, req);
475		if (ok)
476			req->ir_error = 0;
477		else
478			req->ir_error = EIO;
479		IPMI_LOCK(sc);
480		ipmi_complete_request(sc, req);
481	}
482	IPMI_UNLOCK(sc);
483	kproc_exit(0);
484}
485
486static int
487kcs_startup(struct ipmi_softc *sc)
488{
489
490	return (kproc_create(kcs_loop, sc, &sc->ipmi_kthread, 0, 0, "%s: kcs",
491	    device_get_nameunit(sc->ipmi_dev)));
492}
493
494static int
495kcs_driver_request(struct ipmi_softc *sc, struct ipmi_request *req, int timo)
496{
497	int i, ok;
498
499	ok = 0;
500	for (i = 0; i < 3 && !ok; i++)
501		ok = kcs_polled_request(sc, req);
502	if (ok)
503		req->ir_error = 0;
504	else
505		req->ir_error = EIO;
506	return (req->ir_error);
507}
508
509int
510ipmi_kcs_attach(struct ipmi_softc *sc)
511{
512	int status;
513
514	/* Setup function pointers. */
515	sc->ipmi_startup = kcs_startup;
516	sc->ipmi_enqueue_request = ipmi_polled_enqueue_request;
517	sc->ipmi_driver_request = kcs_driver_request;
518	sc->ipmi_driver_requests_polled = 1;
519
520	/* See if we can talk to the controller. */
521	status = INB(sc, KCS_CTL_STS);
522	if (status == 0xff) {
523		device_printf(sc->ipmi_dev, "couldn't find it\n");
524		return (ENXIO);
525	}
526
527#ifdef KCS_DEBUG
528	device_printf(sc->ipmi_dev, "KCS: initial state: %02x\n", status);
529#endif
530	if (status & KCS_STATUS_OBF ||
531	    KCS_STATUS_STATE(status) != KCS_STATUS_STATE_IDLE)
532		kcs_error(sc);
533
534	return (0);
535}
536
537/*
538 * Determine the alignment automatically for a PCI attachment.  In this case,
539 * any unused bytes will return 0x00 when read.  We make use of the C/D bit
540 * in the CTL_STS register to try to start a GET_STATUS transaction.  When
541 * we write the command, that bit should be set, so we should get a non-zero
542 * value back when we read CTL_STS if the offset we are testing is the CTL_STS
543 * register.
544 */
545int
546ipmi_kcs_probe_align(struct ipmi_softc *sc)
547{
548	int data, status;
549
550	sc->ipmi_io_spacing = 1;
551retry:
552#ifdef KCS_DEBUG
553	device_printf(sc->ipmi_dev, "Trying KCS align %d... ", sc->ipmi_io_spacing);
554#endif
555
556	/* Wait for IBF = 0 */
557	status = INB(sc, KCS_CTL_STS);
558	while (status & KCS_STATUS_IBF) {
559		DELAY(100);
560		status = INB(sc, KCS_CTL_STS);
561	}
562
563	OUTB(sc, KCS_CTL_STS, KCS_CONTROL_GET_STATUS_ABORT);
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	/* If we got 0x00 back, then this must not be the CTL_STS register. */
573	if (status == 0) {
574#ifdef KCS_DEBUG
575		printf("failed\n");
576#endif
577		sc->ipmi_io_spacing <<= 1;
578		if (sc->ipmi_io_spacing > 4)
579			return (0);
580		goto retry;
581	}
582#ifdef KCS_DEBUG
583	printf("ok\n");
584#endif
585
586	/* Finish out the transaction. */
587
588	/* Clear OBF */
589	if (status & KCS_STATUS_OBF)
590		data = INB(sc, KCS_DATA);
591
592	/* 0x00 to DATA_IN */
593	OUTB(sc, KCS_DATA, 0);
594
595	/* Wait for IBF = 0 */
596	status = INB(sc, KCS_CTL_STS);
597	while (status & KCS_STATUS_IBF) {
598		DELAY(100);
599		status = INB(sc, KCS_CTL_STS);
600	}
601
602	if (KCS_STATUS_STATE(status) == KCS_STATUS_STATE_READ) {
603		/* Wait for IBF = 1 */
604		while (!(status & KCS_STATUS_OBF)) {
605			DELAY(100);
606			status = INB(sc, KCS_CTL_STS);
607		}
608
609		/* Read error status. */
610		data = INB(sc, KCS_DATA);
611
612		/* Write dummy READ to DATA_IN. */
613		OUTB(sc, KCS_DATA, KCS_DATA_IN_READ);
614
615		/* Wait for IBF = 0 */
616		status = INB(sc, KCS_CTL_STS);
617		while (status & KCS_STATUS_IBF) {
618			DELAY(100);
619			status = INB(sc, KCS_CTL_STS);
620		}
621	}
622
623	if (KCS_STATUS_STATE(status) == KCS_STATUS_STATE_IDLE) {
624		/* Wait for IBF = 1 */
625		while (!(status & KCS_STATUS_OBF)) {
626			DELAY(100);
627			status = INB(sc, KCS_CTL_STS);
628		}
629
630		/* Clear OBF */
631		if (status & KCS_STATUS_OBF)
632			data = INB(sc, KCS_DATA);
633	} else
634		device_printf(sc->ipmi_dev, "KCS probe: end state %x\n",
635		    KCS_STATUS_STATE(status));
636
637	return (1);
638}
639