153a374c1SSascha Wildner /*- 253a374c1SSascha Wildner * Copyright (c) 2006 IronPort Systems Inc. <ambrisko@ironport.com> 353a374c1SSascha Wildner * All rights reserved. 453a374c1SSascha Wildner * 553a374c1SSascha Wildner * Redistribution and use in source and binary forms, with or without 653a374c1SSascha Wildner * modification, are permitted provided that the following conditions 753a374c1SSascha Wildner * are met: 853a374c1SSascha Wildner * 1. Redistributions of source code must retain the above copyright 953a374c1SSascha Wildner * notice, this list of conditions and the following disclaimer. 1053a374c1SSascha Wildner * 2. Redistributions in binary form must reproduce the above copyright 1153a374c1SSascha Wildner * notice, this list of conditions and the following disclaimer in the 1253a374c1SSascha Wildner * documentation and/or other materials provided with the distribution. 1353a374c1SSascha Wildner * 1453a374c1SSascha Wildner * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1553a374c1SSascha Wildner * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1653a374c1SSascha Wildner * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1753a374c1SSascha Wildner * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1853a374c1SSascha Wildner * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1953a374c1SSascha Wildner * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2053a374c1SSascha Wildner * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2153a374c1SSascha Wildner * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2253a374c1SSascha Wildner * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2353a374c1SSascha Wildner * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2453a374c1SSascha Wildner * SUCH DAMAGE. 2553a374c1SSascha Wildner * 2653a374c1SSascha Wildner * $FreeBSD: head/sys/dev/ipmi/ipmivars.h 253812 2013-07-30 18:44:29Z sbruno $ 2753a374c1SSascha Wildner */ 2853a374c1SSascha Wildner 2953a374c1SSascha Wildner #ifndef __IPMIVARS_H__ 3053a374c1SSascha Wildner #define __IPMIVARS_H__ 3153a374c1SSascha Wildner 3253a374c1SSascha Wildner struct ipmi_get_info { 3353a374c1SSascha Wildner int iface_type; 3453a374c1SSascha Wildner uint64_t address; 3553a374c1SSascha Wildner int offset; 3653a374c1SSascha Wildner int io_mode; 3753a374c1SSascha Wildner int irq; 3853a374c1SSascha Wildner }; 3953a374c1SSascha Wildner 4053a374c1SSascha Wildner struct ipmi_device; 4153a374c1SSascha Wildner 4253a374c1SSascha Wildner struct ipmi_request { 4353a374c1SSascha Wildner TAILQ_ENTRY(ipmi_request) ir_link; 4453a374c1SSascha Wildner struct ipmi_device *ir_owner; /* Driver uses NULL. */ 4553a374c1SSascha Wildner u_char *ir_request; /* Request is data to send to BMC. */ 4653a374c1SSascha Wildner size_t ir_requestlen; 4753a374c1SSascha Wildner u_char *ir_reply; /* Reply is data read from BMC. */ 4853a374c1SSascha Wildner size_t ir_replybuflen; /* Length of ir_reply[] buffer. */ 4953a374c1SSascha Wildner int ir_replylen; /* Length of reply from BMC. */ 5053a374c1SSascha Wildner int ir_error; 5153a374c1SSascha Wildner long ir_msgid; 5253a374c1SSascha Wildner uint8_t ir_addr; 5353a374c1SSascha Wildner uint8_t ir_command; 5453a374c1SSascha Wildner uint8_t ir_compcode; 5553a374c1SSascha Wildner }; 5653a374c1SSascha Wildner 5753a374c1SSascha Wildner #define MAX_RES 3 5853a374c1SSascha Wildner #define KCS_DATA 0 5953a374c1SSascha Wildner #define KCS_CTL_STS 1 6053a374c1SSascha Wildner #define SMIC_DATA 0 6153a374c1SSascha Wildner #define SMIC_CTL_STS 1 6253a374c1SSascha Wildner #define SMIC_FLAGS 2 6353a374c1SSascha Wildner 6453a374c1SSascha Wildner struct ipmi_softc; 6553a374c1SSascha Wildner 6653a374c1SSascha Wildner /* Per file descriptor data. */ 6753a374c1SSascha Wildner struct ipmi_device { 6853a374c1SSascha Wildner TAILQ_ENTRY(ipmi_device) ipmi_link; 6953a374c1SSascha Wildner TAILQ_HEAD(,ipmi_request) ipmi_completed_requests; 7053a374c1SSascha Wildner struct ipmi_softc *ipmi_softc; 7153a374c1SSascha Wildner int ipmi_closing; 7253a374c1SSascha Wildner int ipmi_requests; 7353a374c1SSascha Wildner u_char ipmi_address; /* IPMB address. */ 7453a374c1SSascha Wildner u_char ipmi_lun; 7553a374c1SSascha Wildner }; 7653a374c1SSascha Wildner 7753a374c1SSascha Wildner struct ipmi_kcs { 7853a374c1SSascha Wildner }; 7953a374c1SSascha Wildner 8053a374c1SSascha Wildner struct ipmi_smic { 8153a374c1SSascha Wildner }; 8253a374c1SSascha Wildner 8353a374c1SSascha Wildner struct ipmi_ssif { 8453a374c1SSascha Wildner device_t smbus; 8553a374c1SSascha Wildner int smbus_address; 8653a374c1SSascha Wildner }; 8753a374c1SSascha Wildner 8853a374c1SSascha Wildner struct ipmi_softc { 8953a374c1SSascha Wildner device_t ipmi_dev; 9053a374c1SSascha Wildner union { 9153a374c1SSascha Wildner struct ipmi_kcs kcs; 9253a374c1SSascha Wildner struct ipmi_smic smic; 9353a374c1SSascha Wildner struct ipmi_ssif ssif; 9453a374c1SSascha Wildner } _iface; 9553a374c1SSascha Wildner int ipmi_io_rid; 9653a374c1SSascha Wildner int ipmi_io_type; 9753a374c1SSascha Wildner struct resource *ipmi_io_res[MAX_RES]; 9853a374c1SSascha Wildner int ipmi_io_spacing; 9953a374c1SSascha Wildner int ipmi_irq_rid; 10053a374c1SSascha Wildner struct resource *ipmi_irq_res; 10153a374c1SSascha Wildner void *ipmi_irq; 10253a374c1SSascha Wildner int ipmi_detaching; 10353a374c1SSascha Wildner int ipmi_opened; 10453a374c1SSascha Wildner struct cdev *ipmi_cdev; 10553a374c1SSascha Wildner TAILQ_HEAD(,ipmi_request) ipmi_pending_requests; 10653a374c1SSascha Wildner int ipmi_watchdog_active; 10753a374c1SSascha Wildner struct intr_config_hook ipmi_ich; 10853a374c1SSascha Wildner struct lock ipmi_lock; 10953a374c1SSascha Wildner struct cv ipmi_request_added; 11053a374c1SSascha Wildner struct thread *ipmi_kthread; 11153a374c1SSascha Wildner driver_intr_t *ipmi_intr; 11253a374c1SSascha Wildner struct kqinfo ipmi_kq; 113*7670f87fSMarkus Pfeiffer 114*7670f87fSMarkus Pfeiffer struct callout ipmi_watchdog; 115*7670f87fSMarkus Pfeiffer int ipmi_wdog_period; 116*7670f87fSMarkus Pfeiffer int ipmi_wdog_enable; 117*7670f87fSMarkus Pfeiffer 11853a374c1SSascha Wildner int (*ipmi_startup)(struct ipmi_softc *); 11953a374c1SSascha Wildner int (*ipmi_enqueue_request)(struct ipmi_softc *, struct ipmi_request *); 12053a374c1SSascha Wildner }; 12153a374c1SSascha Wildner 12253a374c1SSascha Wildner #define ipmi_ssif_smbus_address _iface.ssif.smbus_address 12353a374c1SSascha Wildner #define ipmi_ssif_smbus _iface.ssif.smbus 12453a374c1SSascha Wildner 12553a374c1SSascha Wildner struct ipmi_ipmb { 12653a374c1SSascha Wildner u_char foo; 12753a374c1SSascha Wildner }; 12853a374c1SSascha Wildner 12953a374c1SSascha Wildner #define KCS_MODE 0x01 13053a374c1SSascha Wildner #define SMIC_MODE 0x02 13153a374c1SSascha Wildner #define BT_MODE 0x03 13253a374c1SSascha Wildner #define SSIF_MODE 0x04 13353a374c1SSascha Wildner 13453a374c1SSascha Wildner /* KCS status flags */ 13553a374c1SSascha Wildner #define KCS_STATUS_OBF 0x01 /* Data Out ready from BMC */ 13653a374c1SSascha Wildner #define KCS_STATUS_IBF 0x02 /* Data In from System */ 13753a374c1SSascha Wildner #define KCS_STATUS_SMS_ATN 0x04 /* Ready in RX queue */ 13853a374c1SSascha Wildner #define KCS_STATUS_C_D 0x08 /* Command/Data register write*/ 13953a374c1SSascha Wildner #define KCS_STATUS_OEM1 0x10 14053a374c1SSascha Wildner #define KCS_STATUS_OEM2 0x20 14153a374c1SSascha Wildner #define KCS_STATUS_S0 0x40 14253a374c1SSascha Wildner #define KCS_STATUS_S1 0x80 14353a374c1SSascha Wildner #define KCS_STATUS_STATE(x) ((x)>>6) 14453a374c1SSascha Wildner #define KCS_STATUS_STATE_IDLE 0x0 14553a374c1SSascha Wildner #define KCS_STATUS_STATE_READ 0x1 14653a374c1SSascha Wildner #define KCS_STATUS_STATE_WRITE 0x2 14753a374c1SSascha Wildner #define KCS_STATUS_STATE_ERROR 0x3 14853a374c1SSascha Wildner #define KCS_IFACE_STATUS_OK 0x00 14953a374c1SSascha Wildner #define KCS_IFACE_STATUS_ABORT 0x01 15053a374c1SSascha Wildner #define KCS_IFACE_STATUS_ILLEGAL 0x02 15153a374c1SSascha Wildner #define KCS_IFACE_STATUS_LENGTH_ERR 0x06 15253a374c1SSascha Wildner #define KCS_IFACE_STATUS_UNKNOWN_ERR 0xff 15353a374c1SSascha Wildner 15453a374c1SSascha Wildner /* KCS control codes */ 15553a374c1SSascha Wildner #define KCS_CONTROL_GET_STATUS_ABORT 0x60 15653a374c1SSascha Wildner #define KCS_CONTROL_WRITE_START 0x61 15753a374c1SSascha Wildner #define KCS_CONTROL_WRITE_END 0x62 15853a374c1SSascha Wildner #define KCS_DATA_IN_READ 0x68 15953a374c1SSascha Wildner 16053a374c1SSascha Wildner /* SMIC status flags */ 16153a374c1SSascha Wildner #define SMIC_STATUS_BUSY 0x01 /* System set and BMC clears it */ 16253a374c1SSascha Wildner #define SMIC_STATUS_SMS_ATN 0x04 /* BMC has a message */ 16353a374c1SSascha Wildner #define SMIC_STATUS_EVT_ATN 0x08 /* Event has been RX */ 16453a374c1SSascha Wildner #define SMIC_STATUS_SMI 0x10 /* asserted SMI */ 16553a374c1SSascha Wildner #define SMIC_STATUS_TX_RDY 0x40 /* Ready to accept WRITE */ 16653a374c1SSascha Wildner #define SMIC_STATUS_RX_RDY 0x80 /* Ready to read */ 16753a374c1SSascha Wildner #define SMIC_STATUS_RESERVED 0x22 16853a374c1SSascha Wildner 16953a374c1SSascha Wildner /* SMIC control codes */ 17053a374c1SSascha Wildner #define SMIC_CC_SMS_GET_STATUS 0x40 17153a374c1SSascha Wildner #define SMIC_CC_SMS_WR_START 0x41 17253a374c1SSascha Wildner #define SMIC_CC_SMS_WR_NEXT 0x42 17353a374c1SSascha Wildner #define SMIC_CC_SMS_WR_END 0x43 17453a374c1SSascha Wildner #define SMIC_CC_SMS_RD_START 0x44 17553a374c1SSascha Wildner #define SMIC_CC_SMS_RD_NEXT 0x45 17653a374c1SSascha Wildner #define SMIC_CC_SMS_RD_END 0x46 17753a374c1SSascha Wildner 17853a374c1SSascha Wildner /* SMIC status codes */ 17953a374c1SSascha Wildner #define SMIC_SC_SMS_RDY 0xc0 18053a374c1SSascha Wildner #define SMIC_SC_SMS_WR_START 0xc1 18153a374c1SSascha Wildner #define SMIC_SC_SMS_WR_NEXT 0xc2 18253a374c1SSascha Wildner #define SMIC_SC_SMS_WR_END 0xc3 18353a374c1SSascha Wildner #define SMIC_SC_SMS_RD_START 0xc4 18453a374c1SSascha Wildner #define SMIC_SC_SMS_RD_NEXT 0xc5 18553a374c1SSascha Wildner #define SMIC_SC_SMS_RD_END 0xc6 18653a374c1SSascha Wildner 18753a374c1SSascha Wildner #define IPMI_ADDR(netfn, lun) ((netfn) << 2 | (lun)) 18853a374c1SSascha Wildner #define IPMI_REPLY_ADDR(addr) ((addr) + 0x4) 18953a374c1SSascha Wildner 19053a374c1SSascha Wildner #define IPMI_LOCK(sc) lockmgr(&(sc)->ipmi_lock, LK_EXCLUSIVE) 19153a374c1SSascha Wildner #define IPMI_UNLOCK(sc) lockmgr(&(sc)->ipmi_lock, LK_RELEASE) 19253a374c1SSascha Wildner #define IPMI_LOCK_ASSERT(sc) KKASSERT(lockowned(&(sc)->ipmi_lock)) 19353a374c1SSascha Wildner 19453a374c1SSascha Wildner #define ipmi_alloc_driver_request(addr, cmd, reqlen, replylen) \ 19553a374c1SSascha Wildner ipmi_alloc_request(NULL, 0, (addr), (cmd), (reqlen), (replylen)) 19653a374c1SSascha Wildner 19753a374c1SSascha Wildner /* I/O to a single I/O resource. */ 19853a374c1SSascha Wildner #define INB_SINGLE(sc, x) \ 19953a374c1SSascha Wildner bus_read_1((sc)->ipmi_io_res[0], (sc)->ipmi_io_spacing * (x)) 20053a374c1SSascha Wildner #define OUTB_SINGLE(sc, x, value) \ 20153a374c1SSascha Wildner bus_write_1((sc)->ipmi_io_res[0], (sc)->ipmi_io_spacing * (x), value) 20253a374c1SSascha Wildner 20353a374c1SSascha Wildner /* I/O with each register in its in I/O resource. */ 20453a374c1SSascha Wildner #define INB_MULTIPLE(sc, x) \ 20553a374c1SSascha Wildner bus_read_1((sc)->ipmi_io_res[(x)], 0) 20653a374c1SSascha Wildner #define OUTB_MULTIPLE(sc, x, value) \ 20753a374c1SSascha Wildner bus_write_1((sc)->ipmi_io_res[(x)], 0, value) 20853a374c1SSascha Wildner 20953a374c1SSascha Wildner /* 21053a374c1SSascha Wildner * Determine I/O method based on whether or not we have more than one I/O 21153a374c1SSascha Wildner * resource. 21253a374c1SSascha Wildner */ 21353a374c1SSascha Wildner #define INB(sc, x) \ 21453a374c1SSascha Wildner ((sc)->ipmi_io_res[1] != NULL ? INB_MULTIPLE(sc, x) : INB_SINGLE(sc, x)) 21553a374c1SSascha Wildner #define OUTB(sc, x, value) \ 21653a374c1SSascha Wildner ((sc)->ipmi_io_res[1] != NULL ? OUTB_MULTIPLE(sc, x, value) : \ 21753a374c1SSascha Wildner OUTB_SINGLE(sc, x, value)) 21853a374c1SSascha Wildner 21953a374c1SSascha Wildner #define MAX_TIMEOUT 6 * hz 22053a374c1SSascha Wildner 22153a374c1SSascha Wildner int ipmi_attach(device_t); 22253a374c1SSascha Wildner int ipmi_detach(device_t); 22353a374c1SSascha Wildner void ipmi_release_resources(device_t); 22453a374c1SSascha Wildner 22553a374c1SSascha Wildner /* Manage requests. */ 22653a374c1SSascha Wildner struct ipmi_request *ipmi_alloc_request(struct ipmi_device *, long, uint8_t, 22753a374c1SSascha Wildner uint8_t, size_t, size_t); 22853a374c1SSascha Wildner void ipmi_complete_request(struct ipmi_softc *, struct ipmi_request *); 22953a374c1SSascha Wildner struct ipmi_request *ipmi_dequeue_request(struct ipmi_softc *); 23053a374c1SSascha Wildner void ipmi_free_request(struct ipmi_request *); 23153a374c1SSascha Wildner int ipmi_polled_enqueue_request(struct ipmi_softc *, struct ipmi_request *); 23253a374c1SSascha Wildner int ipmi_submit_driver_request(struct ipmi_softc *, struct ipmi_request *, 23353a374c1SSascha Wildner int); 23453a374c1SSascha Wildner 23553a374c1SSascha Wildner /* Identify BMC interface via SMBIOS. */ 23653a374c1SSascha Wildner int ipmi_smbios_identify(struct ipmi_get_info *); 23753a374c1SSascha Wildner 23853a374c1SSascha Wildner /* Match BMC PCI device listed in SMBIOS. */ 23953a374c1SSascha Wildner const char *ipmi_pci_match(uint16_t, uint16_t); 24053a374c1SSascha Wildner 24153a374c1SSascha Wildner /* Interface attach routines. */ 24253a374c1SSascha Wildner int ipmi_kcs_attach(struct ipmi_softc *); 24353a374c1SSascha Wildner int ipmi_kcs_probe_align(struct ipmi_softc *); 24453a374c1SSascha Wildner int ipmi_smic_attach(struct ipmi_softc *); 24553a374c1SSascha Wildner int ipmi_ssif_attach(struct ipmi_softc *, device_t, int); 24653a374c1SSascha Wildner 24753a374c1SSascha Wildner #ifdef IPMB 24853a374c1SSascha Wildner int ipmi_handle_attn(struct ipmi_softc *); 24953a374c1SSascha Wildner #endif 25053a374c1SSascha Wildner 25153a374c1SSascha Wildner extern devclass_t ipmi_devclass; 25253a374c1SSascha Wildner extern int ipmi_attached; 25353a374c1SSascha Wildner 25453a374c1SSascha Wildner #endif /* !__IPMIVARS_H__ */ 255