aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/hpilo.h
blob: 38576050776ad459f84800bf11453be5731f5c13 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
/*
 * linux/drivers/char/hpilo.h
 *
 * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
 *	David Altobelli <david.altobelli@hp.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
#ifndef __HPILO_H
#define __HPILO_H

#define ILO_NAME "hpilo"

/* max number of open channel control blocks per device, hw limited to 32 */
#define MAX_CCB		8
/* max number of supported devices */
#define MAX_ILO_DEV	1
/* max number of files */
#define MAX_OPEN	(MAX_CCB * MAX_ILO_DEV)
/* total wait time in usec */
#define MAX_WAIT_TIME	10000
/* per spin wait time in usec */
#define WAIT_TIME	10
/* spin counter for open/close delay */
#define MAX_WAIT	(MAX_WAIT_TIME / WAIT_TIME)

/*
 * Per device, used to track global memory allocations.
 */
struct ilo_hwinfo {
	/* mmio registers on device */
	char __iomem *mmio_vaddr;

	/* doorbell registers on device */
	char __iomem *db_vaddr;

	/* shared memory on device used for channel control blocks */
	char __iomem *ram_vaddr;

	/* files corresponding to this device */
	struct ccb_data *ccb_alloc[MAX_CCB];

	struct pci_dev *ilo_dev;

	spinlock_t alloc_lock;
	spinlock_t fifo_lock;
	spinlock_t open_lock;

	struct cdev cdev;
};

/* offset from mmio_vaddr for enabling doorbell interrupts */
#define DB_IRQ		0xB2
/* offset from mmio_vaddr for outbound communications */
#define DB_OUT		0xD4
/* DB_OUT reset bit */
#define DB_RESET	26

/*
 * Channel control block. Used to manage hardware queues.
 * The format must match hw's version.  The hw ccb is 128 bytes,
 * but the context area shouldn't be touched by the driver.
 */
#define ILOSW_CCB_SZ	64
#define ILOHW_CCB_SZ 	128
struct ccb {
	union {
		char *send_fifobar;
		u64 padding1;
	} ccb_u1;
	union {
		char *send_desc;
		u64 padding2;
	} ccb_u2;
	u64 send_ctrl;

	union {
		char *recv_fifobar;
		u64 padding3;
	} ccb_u3;
	union {
		char *recv_desc;
		u64 padding4;
	} ccb_u4;
	u64 recv_ctrl;

	union {
		char __iomem *db_base;
		u64 padding5;
	} ccb_u5;

	u64 channel;

	/* unused context area (64 bytes) */
};

/* ccb queue parameters */
#define SENDQ		1
#define RECVQ 		2
#define NR_QENTRY    	4
#define L2_QENTRY_SZ 	12

/* ccb ctrl bitfields */
#define CTRL_BITPOS_L2SZ             0
#define CTRL_BITPOS_FIFOINDEXMASK    4
#define CTRL_BITPOS_DESCLIMIT        18
#define CTRL_BITPOS_A                30
#define CTRL_BITPOS_G                31

/* ccb doorbell macros */
#define L2_DB_SIZE		14
#define ONE_DB_SIZE		(1 << L2_DB_SIZE)

/*
 * Per fd structure used to track the ccb allocated to that dev file.
 */
struct ccb_data {
	/* software version of ccb, using virtual addrs */
	struct ccb  driver_ccb;

	/* hardware version of ccb, using physical addrs */
	struct ccb  ilo_ccb;

	/* hardware ccb is written to this shared mapped device memory */
	struct ccb __iomem *mapped_ccb;

	/* dma'able memory used for send/recv queues */
	void       *dma_va;
	dma_addr_t  dma_pa;
	size_t      dma_size;

	/* pointer to hardware device info */
	struct ilo_hwinfo *ilo_hw;

	/* queue for this ccb to wait for recv data */
	wait_queue_head_t ccb_waitq;

	/* usage count, to allow for shared ccb's */
	int	    ccb_cnt;

	/* open wanted exclusive access to this ccb */
	int	    ccb_excl;
};

/*
 * FIFO queue structure, shared with hw.
 */
#define ILO_START_ALIGN	4096
#define ILO_CACHE_SZ 	 128
struct fifo {
    u64 nrents;	/* user requested number of fifo entries */
    u64 imask;  /* mask to extract valid fifo index */
    u64 merge;	/*  O/C bits to merge in during enqueue operation */
    u64 reset;	/* set to non-zero when the target device resets */
    u8  pad_0[ILO_CACHE_SZ - (sizeof(u64) * 4)];

    u64 head;
    u8  pad_1[ILO_CACHE_SZ - (sizeof(u64))];

    u64 tail;
    u8  pad_2[ILO_CACHE_SZ - (sizeof(u64))];

    u64 fifobar[1];
};

/* convert between struct fifo, and the fifobar, which is saved in the ccb */
#define FIFOHANDLESIZE (sizeof(struct fifo) - sizeof(u64))
#define FIFOBARTOHANDLE(_fifo) \
	((struct fifo *)(((char *)(_fifo)) - FIFOHANDLESIZE))

/* the number of qwords to consume from the entry descriptor */
#define ENTRY_BITPOS_QWORDS      0
/* descriptor index number (within a specified queue) */
#define ENTRY_BITPOS_DESCRIPTOR  10
/* state bit, fifo entry consumed by consumer */
#define ENTRY_BITPOS_C           22
/* state bit, fifo entry is occupied */
#define ENTRY_BITPOS_O           23

#define ENTRY_BITS_QWORDS        10
#define ENTRY_BITS_DESCRIPTOR    12
#define ENTRY_BITS_C             1
#define ENTRY_BITS_O             1
#define ENTRY_BITS_TOTAL	\
	(ENTRY_BITS_C + ENTRY_BITS_O + \
	 ENTRY_BITS_QWORDS + ENTRY_BITS_DESCRIPTOR)

/* extract various entry fields */
#define ENTRY_MASK ((1 << ENTRY_BITS_TOTAL) - 1)
#define ENTRY_MASK_C (((1 << ENTRY_BITS_C) - 1) << ENTRY_BITPOS_C)
#define ENTRY_MASK_O (((1 << ENTRY_BITS_O) - 1) << ENTRY_BITPOS_O)
#define ENTRY_MASK_QWORDS \
	(((1 << ENTRY_BITS_QWORDS) - 1) << ENTRY_BITPOS_QWORDS)
#define ENTRY_MASK_DESCRIPTOR \
	(((1 << ENTRY_BITS_DESCRIPTOR) - 1) << ENTRY_BITPOS_DESCRIPTOR)

#define ENTRY_MASK_NOSTATE (ENTRY_MASK >> (ENTRY_BITS_C + ENTRY_BITS_O))

#endif /* __HPILO_H */