1/*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2011-2013 Qlogic Corporation
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 *
11 *  1. Redistributions of source code must retain the above copyright
12 *     notice, this list of conditions and the following disclaimer.
13 *  2. Redistributions in binary form must reproduce the above copyright
14 *     notice, this list of conditions and the following disclaimer in the
15 *     documentation and/or other materials provided with the distribution.
16 *
17 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 *  POSSIBILITY OF SUCH DAMAGE.
28 */
29/*
30 * File: qla_ioctl.c
31 * Author : David C Somayajulu, Qlogic Corporation, Aliso Viejo, CA 92656.
32 */
33
34#include <sys/cdefs.h>
35#include "qla_os.h"
36#include "qla_reg.h"
37#include "qla_hw.h"
38#include "qla_def.h"
39#include "qla_reg.h"
40#include "qla_inline.h"
41#include "qla_glbl.h"
42#include "qla_ioctl.h"
43
44static struct cdevsw qla_cdevsw = {
45	.d_version = D_VERSION,
46	.d_ioctl = qla_eioctl,
47	.d_name = "qlcnic",
48};
49
50int
51qla_make_cdev(qla_host_t *ha)
52{
53        ha->ioctl_dev = make_dev(&qla_cdevsw,
54				if_getdunit(ha->ifp),
55                                UID_ROOT,
56                                GID_WHEEL,
57                                0600,
58                                "%s",
59                                if_name(ha->ifp));
60
61	if (ha->ioctl_dev == NULL)
62		return (-1);
63
64        ha->ioctl_dev->si_drv1 = ha;
65
66	return (0);
67}
68
69void
70qla_del_cdev(qla_host_t *ha)
71{
72	if (ha->ioctl_dev != NULL)
73		destroy_dev(ha->ioctl_dev);
74	return;
75}
76
77int
78qla_eioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
79        struct thread *td)
80{
81        qla_host_t *ha;
82        int rval = 0;
83        qla_reg_val_t *rv;
84        qla_rd_flash_t *rdf;
85	qla_wr_flash_t *wrf;
86	qla_rd_pci_ids_t *pci_ids;
87	device_t pci_dev;
88
89        if ((ha = (qla_host_t *)dev->si_drv1) == NULL)
90                return ENXIO;
91
92	pci_dev= ha->pci_dev;
93
94        switch(cmd) {
95        case QLA_RDWR_REG:
96
97                rv = (qla_reg_val_t *)data;
98
99                if (rv->direct) {
100                        if (rv->rd) {
101                                rv->val = READ_OFFSET32(ha, rv->reg);
102                        } else {
103                                WRITE_OFFSET32(ha, rv->reg, rv->val);
104                        }
105                } else {
106                        if ((rval = qla_rdwr_indreg32(ha, rv->reg, &rv->val,
107                                rv->rd)))
108                                rval = ENXIO;
109                }
110                break;
111
112        case QLA_RD_FLASH:
113                rdf = (qla_rd_flash_t *)data;
114                if ((rval = qla_rd_flash32(ha, rdf->off, &rdf->data)))
115                        rval = ENXIO;
116                break;
117
118        case QLA_WR_FLASH:
119                wrf = (qla_wr_flash_t *)data;
120                if ((rval = qla_wr_flash_buffer(ha, wrf->off, wrf->size,
121					wrf->buffer, wrf->pattern)))
122                        rval = ENXIO;
123                break;
124
125	case QLA_ERASE_FLASH:
126		if (qla_erase_flash(ha, ((qla_erase_flash_t *)data)->off,
127			((qla_erase_flash_t *)data)->size))
128			rval = ENXIO;
129		break;
130
131	case QLA_RD_PCI_IDS:
132		pci_ids = (qla_rd_pci_ids_t *)data;
133		pci_ids->ven_id = pci_get_vendor(pci_dev);
134		pci_ids->dev_id = pci_get_device(pci_dev);
135		pci_ids->subsys_ven_id = pci_get_subvendor(pci_dev);
136		pci_ids->subsys_dev_id = pci_get_subdevice(pci_dev);
137		pci_ids->rev_id = pci_read_config(pci_dev, PCIR_REVID, 1);
138		break;
139
140        default:
141                break;
142        }
143
144        return rval;
145}
146