remove __P() from this directory
[dragonfly.git] / sys / dev / atm / hfa / fore_init.c
CommitLineData
984263bc
MD
1/*
2 *
3 * ===================================
4 * HARP | Host ATM Research Platform
5 * ===================================
6 *
7 *
8 * This Host ATM Research Platform ("HARP") file (the "Software") is
9 * made available by Network Computing Services, Inc. ("NetworkCS")
10 * "AS IS". NetworkCS does not provide maintenance, improvements or
11 * support of any kind.
12 *
13 * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
14 * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
15 * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
16 * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
17 * In no event shall NetworkCS be responsible for any damages, including
18 * but not limited to consequential damages, arising from or relating to
19 * any use of the Software or related support.
20 *
21 * Copyright 1994-1998 Network Computing Services, Inc.
22 *
23 * Copies of this Software may be made, however, the above copyright
24 * notice must be reproduced on all copies.
25 *
26 * @(#) $FreeBSD: src/sys/dev/hfa/fore_init.c,v 1.6 1999/08/29 10:28:09 bde Exp $
38e94a25 27 * @(#) $DragonFly: src/sys/dev/atm/hfa/fore_init.c,v 1.4 2003/08/27 10:35:16 rob Exp $
984263bc
MD
28 */
29
30/*
31 * FORE Systems 200-Series Adapter Support
32 * ---------------------------------------
33 *
34 * Cell Processor (CP) initialization routines
35 *
36 */
37
1f2de5d4 38#include "fore_include.h"
984263bc 39
984263bc
MD
40/*
41 * Local functions
42 */
43#ifdef FORE_PCI
38e94a25 44static void fore_get_prom (Fore_unit *);
984263bc
MD
45#endif
46
47
48/*
49 * Begin CP Initialization
50 *
51 * This function will poll for the successful downloading and starting of
52 * the CP microcode program. After the microcode is running, we will allocate
53 * any needed kernel memory (must do it in non-interrupt mode), build the CP
54 * queue configurations and issue an Initialize command to the CP.
55 *
56 * Arguments:
57 * fup pointer to device unit structure
58 *
59 * Returns:
60 * none
61 */
62void
63fore_initialize(fup)
64 Fore_unit *fup;
65{
66 Aali *aap;
67 Init_parms *inp;
68 caddr_t errmsg;
69 u_long vers;
70
71 /*
72 * Must wait until firmware has been downloaded and is running
73 */
74 if (CP_READ(fup->fu_mon->mon_bstat) != BOOT_RUNNING) {
75
76 /*
77 * Try again later
78 */
79 fup->fu_thandle =
38e94a25 80 timeout((KTimeout_ret(*) (void *))fore_initialize,
984263bc
MD
81 (void *)fup, hz);
82 return;
83 } else
84 callout_handle_init(&fup->fu_thandle);
85
86 /*
87 * Allocate queues and whatever else is needed
88 */
89 if (fore_xmit_allocate(fup)) {
90 errmsg = "transmit queue allocation";
91 goto failed;
92 }
93 if (fore_recv_allocate(fup)) {
94 errmsg = "receive queue allocation";
95 goto failed;
96 }
97 if (fore_buf_allocate(fup)) {
98 errmsg = "buffer supply queue allocation";
99 goto failed;
100 }
101 if (fore_cmd_allocate(fup)) {
102 errmsg = "command queue allocation";
103 goto failed;
104 }
105
106 /*
107 * CP microcode is downloaded - locate shared memory interface
108 */
109 aap = (Aali *)(fup->fu_ram + CP_READ(fup->fu_mon->mon_appl));
110 fup->fu_aali = aap;
111
112 /*
113 * Pick out any interesting info from the microcode
114 */
115 vers = CP_READ(aap->aali_ucode_ver);
116 if (vers < FORE_MIN_UCODE) {
117 errmsg = "unsupported microcode version";
118 goto failed;
119 }
120 snprintf(fup->fu_config.ac_firm_vers,
121 sizeof(fup->fu_config.ac_firm_vers), "%ld.%ld.%ld",
122 (vers >> 16) & 0xff, (vers >> 8) & 0xff, vers & 0xff);
123
124#ifdef notdef
125 /*
126 * Turn on CP debugging
127 */
128 aap->aali_hostlog = 1;
129#endif
130
131 /*
132 * Build the initialization block
133 */
134 inp = &aap->aali_init;
135 inp->init_numvcc = CP_WRITE(FORE_MAX_VCC);
136 inp->init_cmd_elem = CP_WRITE(CMD_QUELEN);
137 inp->init_xmit_elem = CP_WRITE(XMIT_QUELEN);
138 inp->init_recv_elem = CP_WRITE(RECV_QUELEN);
139 inp->init_recv_ext = CP_WRITE(RECV_EXTRA_SEGS);
140 inp->init_xmit_ext = CP_WRITE(XMIT_EXTRA_SEGS);
141 inp->init_buf1s.bfs_quelen = CP_WRITE(BUF1_SM_QUELEN);
142 inp->init_buf1s.bfs_bufsize = CP_WRITE(BUF1_SM_SIZE);
143 inp->init_buf1s.bfs_cppool = CP_WRITE(BUF1_SM_CPPOOL);
144 inp->init_buf1s.bfs_entsize = CP_WRITE(BUF1_SM_ENTSIZE);
145 inp->init_buf1l.bfs_quelen = CP_WRITE(BUF1_LG_QUELEN);
146 inp->init_buf1l.bfs_bufsize = CP_WRITE(BUF1_LG_SIZE);
147 inp->init_buf1l.bfs_cppool = CP_WRITE(BUF1_LG_CPPOOL);
148 inp->init_buf1l.bfs_entsize = CP_WRITE(BUF1_LG_ENTSIZE);
149 inp->init_buf2s.bfs_quelen = CP_WRITE(0);
150 inp->init_buf2s.bfs_bufsize = CP_WRITE(0);
151 inp->init_buf2s.bfs_cppool = CP_WRITE(0);
152 inp->init_buf2s.bfs_entsize = CP_WRITE(0);
153 inp->init_buf2l.bfs_quelen = CP_WRITE(0);
154 inp->init_buf2l.bfs_bufsize = CP_WRITE(0);
155 inp->init_buf2l.bfs_cppool = CP_WRITE(0);
156 inp->init_buf2l.bfs_entsize = CP_WRITE(0);
157
158 /*
159 * Enable device interrupts
160 */
161 aap->aali_intr_ena = CP_WRITE(1);
162
163 /*
164 * Issue the Initialize command to the CP and wait for
165 * the CP to interrupt to signal completion
166 */
167 inp->init_status = CP_WRITE(QSTAT_PENDING);
168 inp->init_cmd = CP_WRITE(CMD_INIT | CMD_INTR_REQ);
169 return;
170
171failed:
172 /*
173 * Initialization failure
174 */
175 fore_interface_free(fup);
176 log(LOG_ERR, "fore initialization failed: intf=%s%d, err=%s\n",
177 fup->fu_pif.pif_name, fup->fu_pif.pif_unit, errmsg);
178 return;
179}
180
181
182/*
183 * Complete CP Initialization
184 *
185 * Called after the CP has successfully completed processing of the
186 * Initialize command. We will now finish off our part of the
187 * initialization process by setting up all the host-based queue
188 * management structures.
189 *
190 * Called at interrupt level.
191 *
192 * Arguments:
193 * fup pointer to device unit structure
194 *
195 * Returns:
196 * none
197 */
198void
199fore_initialize_complete(fup)
200 Fore_unit *fup;
201{
202 Aali *aap = fup->fu_aali;
203
204 /*
205 * Log an initialization failure
206 */
207 if (CP_READ(aap->aali_init.init_status) & QSTAT_ERROR) {
208
209 log(LOG_ERR,
210 "fore initialization failed: intf=%s%d, hbeat=0x%lx\n",
211 fup->fu_pif.pif_name, fup->fu_pif.pif_unit,
212 (u_long)CP_READ(aap->aali_heartbeat));
213 return;
214 }
215
216 ATM_DEBUG1("heap=0x%lx\n", aap->aali_heap);
217 ATM_DEBUG1("heaplen=0x%lx\n", aap->aali_heaplen);
218 ATM_DEBUG1("cmd_q=0x%lx\n", aap->aali_cmd_q);
219 ATM_DEBUG1("xmit_q=0x%lx\n", aap->aali_xmit_q);
220 ATM_DEBUG1("recv_q=0x%lx\n", aap->aali_recv_q);
221 ATM_DEBUG1("buf1s_q=0x%lx\n", aap->aali_buf1s_q);
222 ATM_DEBUG1("buf1l_q=0x%lx\n", aap->aali_buf1l_q);
223 ATM_DEBUG1("buf2s_q=0x%lx\n", aap->aali_buf2s_q);
224 ATM_DEBUG1("buf2l_q=0x%lx\n", aap->aali_buf2l_q);
225
226 /*
227 * Initialize all of our queues
228 */
229 fore_xmit_initialize(fup);
230 fore_recv_initialize(fup);
231 fore_buf_initialize(fup);
232 fore_cmd_initialize(fup);
233
234 /*
235 * Mark device initialization completed
236 */
237 fup->fu_flags |= CUF_INITED;
238
239#ifdef FORE_PCI
240 fore_get_prom(fup);
241#endif
242 return;
243}
244
245
246#ifdef FORE_PCI
247/*
248 * Get device PROM values from CP
249 *
250 * This function will issue a GET_PROM command to the CP in order to
251 * initiate the DMA transfer of the CP's PROM structure to the host.
252 * This will be called after CP initialization has completed.
253 * There is (currently) no retry if this fails.
254 *
255 * Called at interrupt level.
256 *
257 * Arguments:
258 * fup pointer to device unit structure
259 *
260 * Returns:
261 * none
262 *
263 */
264static void
265fore_get_prom(fup)
266 Fore_unit *fup;
267{
268 H_cmd_queue *hcp;
269 Cmd_queue *cqp;
270
271 /*
272 * Queue command at end of command queue
273 */
274 hcp = fup->fu_cmd_tail;
275 if ((*hcp->hcq_status) & QSTAT_FREE) {
276
277 /*
278 * Queue entry available, so set our view of things up
279 */
280 hcp->hcq_code = CMD_GET_PROM;
281 hcp->hcq_arg = NULL;
282 fup->fu_cmd_tail = hcp->hcq_next;
283
284 /*
285 * Now set the CP-resident queue entry - the CP will grab
286 * the command when the op-code is set.
287 */
288 cqp = hcp->hcq_cpelem;
289 (*hcp->hcq_status) = QSTAT_PENDING;
290
291 fup->fu_promd = DMA_GET_ADDR(fup->fu_prom, sizeof(Fore_prom),
292 FORE_PROM_ALIGN, 0);
293 if (fup->fu_promd == NULL) {
294 fup->fu_stats->st_drv.drv_cm_nodma++;
295 return;
296 }
297 cqp->cmdq_prom.prom_buffer = (CP_dma) CP_WRITE(fup->fu_promd);
298 cqp->cmdq_prom.prom_cmd = CP_WRITE(CMD_GET_PROM | CMD_INTR_REQ);
299
300 } else {
301 /*
302 * Command queue full
303 */
304 fup->fu_stats->st_drv.drv_cm_full++;
305 }
306
307 return;
308}
309#endif /* FORE_PCI */
310