Commit | Line | Data |
---|---|---|
f21fb3ed RV |
1 | /********************************************************************** |
2 | * Author: Cavium, Inc. | |
3 | * | |
4 | * Contact: support@cavium.com | |
5 | * Please include "LiquidIO" in the subject. | |
6 | * | |
7 | * Copyright (c) 2003-2015 Cavium, Inc. | |
8 | * | |
9 | * This file is free software; you can redistribute it and/or modify | |
10 | * it under the terms of the GNU General Public License, Version 2, as | |
11 | * published by the Free Software Foundation. | |
12 | * | |
13 | * This file is distributed in the hope that it will be useful, but | |
14 | * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty | |
15 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or | |
16 | * NONINFRINGEMENT. See the GNU General Public License for more | |
17 | * details. | |
18 | * | |
19 | * This file may also be available under a different license from Cavium. | |
20 | * Contact Cavium, Inc. for more information | |
21 | **********************************************************************/ | |
22 | #include <linux/version.h> | |
23 | #include <linux/types.h> | |
24 | #include <linux/list.h> | |
25 | #include <linux/interrupt.h> | |
26 | #include <linux/pci.h> | |
27 | #include <linux/crc32.h> | |
28 | #include <linux/kthread.h> | |
29 | #include <linux/netdevice.h> | |
5b173cf9 | 30 | #include <linux/vmalloc.h> |
f21fb3ed RV |
31 | #include "octeon_config.h" |
32 | #include "liquidio_common.h" | |
33 | #include "octeon_droq.h" | |
34 | #include "octeon_iq.h" | |
35 | #include "response_manager.h" | |
36 | #include "octeon_device.h" | |
37 | #include "octeon_nic.h" | |
38 | #include "octeon_main.h" | |
39 | #include "octeon_network.h" | |
40 | #include "cn66xx_regs.h" | |
41 | #include "cn66xx_device.h" | |
42 | #include "cn68xx_regs.h" | |
43 | #include "cn68xx_device.h" | |
44 | #include "liquidio_image.h" | |
45 | #include "octeon_mem_ops.h" | |
46 | ||
47 | /** Default configuration | |
48 | * for CN66XX OCTEON Models. | |
49 | */ | |
50 | static struct octeon_config default_cn66xx_conf = { | |
51 | .card_type = LIO_210SV, | |
52 | .card_name = LIO_210SV_NAME, | |
53 | ||
54 | /** IQ attributes */ | |
55 | .iq = { | |
56 | .max_iqs = CN6XXX_CFG_IO_QUEUES, | |
57 | .pending_list_size = | |
58 | (CN6XXX_MAX_IQ_DESCRIPTORS * CN6XXX_CFG_IO_QUEUES), | |
59 | .instr_type = OCTEON_64BYTE_INSTR, | |
60 | .db_min = CN6XXX_DB_MIN, | |
61 | .db_timeout = CN6XXX_DB_TIMEOUT, | |
62 | } | |
63 | , | |
64 | ||
65 | /** OQ attributes */ | |
66 | .oq = { | |
67 | .max_oqs = CN6XXX_CFG_IO_QUEUES, | |
68 | .info_ptr = OCTEON_OQ_INFOPTR_MODE, | |
69 | .refill_threshold = CN6XXX_OQ_REFIL_THRESHOLD, | |
70 | .oq_intr_pkt = CN6XXX_OQ_INTR_PKT, | |
71 | .oq_intr_time = CN6XXX_OQ_INTR_TIME, | |
72 | .pkts_per_intr = CN6XXX_OQ_PKTSPER_INTR, | |
73 | } | |
74 | , | |
75 | ||
76 | .num_nic_ports = DEFAULT_NUM_NIC_PORTS_66XX, | |
77 | .num_def_rx_descs = CN6XXX_MAX_OQ_DESCRIPTORS, | |
78 | .num_def_tx_descs = CN6XXX_MAX_IQ_DESCRIPTORS, | |
79 | .def_rx_buf_size = CN6XXX_OQ_BUF_SIZE, | |
80 | ||
81 | /* For ethernet interface 0: Port cfg Attributes */ | |
82 | .nic_if_cfg[0] = { | |
83 | /* Max Txqs: Half for each of the two ports :max_iq/2 */ | |
84 | .max_txqs = MAX_TXQS_PER_INTF, | |
85 | ||
86 | /* Actual configured value. Range could be: 1...max_txqs */ | |
87 | .num_txqs = DEF_TXQS_PER_INTF, | |
88 | ||
89 | /* Max Rxqs: Half for each of the two ports :max_oq/2 */ | |
90 | .max_rxqs = MAX_RXQS_PER_INTF, | |
91 | ||
92 | /* Actual configured value. Range could be: 1...max_rxqs */ | |
93 | .num_rxqs = DEF_RXQS_PER_INTF, | |
94 | ||
95 | /* Num of desc for rx rings */ | |
96 | .num_rx_descs = CN6XXX_MAX_OQ_DESCRIPTORS, | |
97 | ||
98 | /* Num of desc for tx rings */ | |
99 | .num_tx_descs = CN6XXX_MAX_IQ_DESCRIPTORS, | |
100 | ||
101 | /* SKB size, We need not change buf size even for Jumbo frames. | |
102 | * Octeon can send jumbo frames in 4 consecutive descriptors, | |
103 | */ | |
104 | .rx_buf_size = CN6XXX_OQ_BUF_SIZE, | |
105 | ||
106 | .base_queue = BASE_QUEUE_NOT_REQUESTED, | |
107 | ||
108 | .gmx_port_id = 0, | |
109 | }, | |
110 | ||
111 | .nic_if_cfg[1] = { | |
112 | /* Max Txqs: Half for each of the two ports :max_iq/2 */ | |
113 | .max_txqs = MAX_TXQS_PER_INTF, | |
114 | ||
115 | /* Actual configured value. Range could be: 1...max_txqs */ | |
116 | .num_txqs = DEF_TXQS_PER_INTF, | |
117 | ||
118 | /* Max Rxqs: Half for each of the two ports :max_oq/2 */ | |
119 | .max_rxqs = MAX_RXQS_PER_INTF, | |
120 | ||
121 | /* Actual configured value. Range could be: 1...max_rxqs */ | |
122 | .num_rxqs = DEF_RXQS_PER_INTF, | |
123 | ||
124 | /* Num of desc for rx rings */ | |
125 | .num_rx_descs = CN6XXX_MAX_OQ_DESCRIPTORS, | |
126 | ||
127 | /* Num of desc for tx rings */ | |
128 | .num_tx_descs = CN6XXX_MAX_IQ_DESCRIPTORS, | |
129 | ||
130 | /* SKB size, We need not change buf size even for Jumbo frames. | |
131 | * Octeon can send jumbo frames in 4 consecutive descriptors, | |
132 | */ | |
133 | .rx_buf_size = CN6XXX_OQ_BUF_SIZE, | |
134 | ||
135 | .base_queue = BASE_QUEUE_NOT_REQUESTED, | |
136 | ||
137 | .gmx_port_id = 1, | |
138 | }, | |
139 | ||
140 | /** Miscellaneous attributes */ | |
141 | .misc = { | |
142 | /* Host driver link query interval */ | |
143 | .oct_link_query_interval = 100, | |
144 | ||
145 | /* Octeon link query interval */ | |
146 | .host_link_query_interval = 500, | |
147 | ||
148 | .enable_sli_oq_bp = 0, | |
149 | ||
150 | /* Control queue group */ | |
151 | .ctrlq_grp = 1, | |
152 | } | |
153 | , | |
154 | }; | |
155 | ||
156 | /** Default configuration | |
157 | * for CN68XX OCTEON Model. | |
158 | */ | |
159 | ||
160 | static struct octeon_config default_cn68xx_conf = { | |
161 | .card_type = LIO_410NV, | |
162 | .card_name = LIO_410NV_NAME, | |
163 | ||
164 | /** IQ attributes */ | |
165 | .iq = { | |
166 | .max_iqs = CN6XXX_CFG_IO_QUEUES, | |
167 | .pending_list_size = | |
168 | (CN6XXX_MAX_IQ_DESCRIPTORS * CN6XXX_CFG_IO_QUEUES), | |
169 | .instr_type = OCTEON_64BYTE_INSTR, | |
170 | .db_min = CN6XXX_DB_MIN, | |
171 | .db_timeout = CN6XXX_DB_TIMEOUT, | |
172 | } | |
173 | , | |
174 | ||
175 | /** OQ attributes */ | |
176 | .oq = { | |
177 | .max_oqs = CN6XXX_CFG_IO_QUEUES, | |
178 | .info_ptr = OCTEON_OQ_INFOPTR_MODE, | |
179 | .refill_threshold = CN6XXX_OQ_REFIL_THRESHOLD, | |
180 | .oq_intr_pkt = CN6XXX_OQ_INTR_PKT, | |
181 | .oq_intr_time = CN6XXX_OQ_INTR_TIME, | |
182 | .pkts_per_intr = CN6XXX_OQ_PKTSPER_INTR, | |
183 | } | |
184 | , | |
185 | ||
186 | .num_nic_ports = DEFAULT_NUM_NIC_PORTS_68XX, | |
187 | .num_def_rx_descs = CN6XXX_MAX_OQ_DESCRIPTORS, | |
188 | .num_def_tx_descs = CN6XXX_MAX_IQ_DESCRIPTORS, | |
189 | .def_rx_buf_size = CN6XXX_OQ_BUF_SIZE, | |
190 | ||
191 | .nic_if_cfg[0] = { | |
192 | /* Max Txqs: Half for each of the two ports :max_iq/2 */ | |
193 | .max_txqs = MAX_TXQS_PER_INTF, | |
194 | ||
195 | /* Actual configured value. Range could be: 1...max_txqs */ | |
196 | .num_txqs = DEF_TXQS_PER_INTF, | |
197 | ||
198 | /* Max Rxqs: Half for each of the two ports :max_oq/2 */ | |
199 | .max_rxqs = MAX_RXQS_PER_INTF, | |
200 | ||
201 | /* Actual configured value. Range could be: 1...max_rxqs */ | |
202 | .num_rxqs = DEF_RXQS_PER_INTF, | |
203 | ||
204 | /* Num of desc for rx rings */ | |
205 | .num_rx_descs = CN6XXX_MAX_OQ_DESCRIPTORS, | |
206 | ||
207 | /* Num of desc for tx rings */ | |
208 | .num_tx_descs = CN6XXX_MAX_IQ_DESCRIPTORS, | |
209 | ||
210 | /* SKB size, We need not change buf size even for Jumbo frames. | |
211 | * Octeon can send jumbo frames in 4 consecutive descriptors, | |
212 | */ | |
213 | .rx_buf_size = CN6XXX_OQ_BUF_SIZE, | |
214 | ||
215 | .base_queue = BASE_QUEUE_NOT_REQUESTED, | |
216 | ||
217 | .gmx_port_id = 0, | |
218 | }, | |
219 | ||
220 | .nic_if_cfg[1] = { | |
221 | /* Max Txqs: Half for each of the two ports :max_iq/2 */ | |
222 | .max_txqs = MAX_TXQS_PER_INTF, | |
223 | ||
224 | /* Actual configured value. Range could be: 1...max_txqs */ | |
225 | .num_txqs = DEF_TXQS_PER_INTF, | |
226 | ||
227 | /* Max Rxqs: Half for each of the two ports :max_oq/2 */ | |
228 | .max_rxqs = MAX_RXQS_PER_INTF, | |
229 | ||
230 | /* Actual configured value. Range could be: 1...max_rxqs */ | |
231 | .num_rxqs = DEF_RXQS_PER_INTF, | |
232 | ||
233 | /* Num of desc for rx rings */ | |
234 | .num_rx_descs = CN6XXX_MAX_OQ_DESCRIPTORS, | |
235 | ||
236 | /* Num of desc for tx rings */ | |
237 | .num_tx_descs = CN6XXX_MAX_IQ_DESCRIPTORS, | |
238 | ||
239 | /* SKB size, We need not change buf size even for Jumbo frames. | |
240 | * Octeon can send jumbo frames in 4 consecutive descriptors, | |
241 | */ | |
242 | .rx_buf_size = CN6XXX_OQ_BUF_SIZE, | |
243 | ||
244 | .base_queue = BASE_QUEUE_NOT_REQUESTED, | |
245 | ||
246 | .gmx_port_id = 1, | |
247 | }, | |
248 | ||
249 | .nic_if_cfg[2] = { | |
250 | /* Max Txqs: Half for each of the two ports :max_iq/2 */ | |
251 | .max_txqs = MAX_TXQS_PER_INTF, | |
252 | ||
253 | /* Actual configured value. Range could be: 1...max_txqs */ | |
254 | .num_txqs = DEF_TXQS_PER_INTF, | |
255 | ||
256 | /* Max Rxqs: Half for each of the two ports :max_oq/2 */ | |
257 | .max_rxqs = MAX_RXQS_PER_INTF, | |
258 | ||
259 | /* Actual configured value. Range could be: 1...max_rxqs */ | |
260 | .num_rxqs = DEF_RXQS_PER_INTF, | |
261 | ||
262 | /* Num of desc for rx rings */ | |
263 | .num_rx_descs = CN6XXX_MAX_OQ_DESCRIPTORS, | |
264 | ||
265 | /* Num of desc for tx rings */ | |
266 | .num_tx_descs = CN6XXX_MAX_IQ_DESCRIPTORS, | |
267 | ||
268 | /* SKB size, We need not change buf size even for Jumbo frames. | |
269 | * Octeon can send jumbo frames in 4 consecutive descriptors, | |
270 | */ | |
271 | .rx_buf_size = CN6XXX_OQ_BUF_SIZE, | |
272 | ||
273 | .base_queue = BASE_QUEUE_NOT_REQUESTED, | |
274 | ||
275 | .gmx_port_id = 2, | |
276 | }, | |
277 | ||
278 | .nic_if_cfg[3] = { | |
279 | /* Max Txqs: Half for each of the two ports :max_iq/2 */ | |
280 | .max_txqs = MAX_TXQS_PER_INTF, | |
281 | ||
282 | /* Actual configured value. Range could be: 1...max_txqs */ | |
283 | .num_txqs = DEF_TXQS_PER_INTF, | |
284 | ||
285 | /* Max Rxqs: Half for each of the two ports :max_oq/2 */ | |
286 | .max_rxqs = MAX_RXQS_PER_INTF, | |
287 | ||
288 | /* Actual configured value. Range could be: 1...max_rxqs */ | |
289 | .num_rxqs = DEF_RXQS_PER_INTF, | |
290 | ||
291 | /* Num of desc for rx rings */ | |
292 | .num_rx_descs = CN6XXX_MAX_OQ_DESCRIPTORS, | |
293 | ||
294 | /* Num of desc for tx rings */ | |
295 | .num_tx_descs = CN6XXX_MAX_IQ_DESCRIPTORS, | |
296 | ||
297 | /* SKB size, We need not change buf size even for Jumbo frames. | |
298 | * Octeon can send jumbo frames in 4 consecutive descriptors, | |
299 | */ | |
300 | .rx_buf_size = CN6XXX_OQ_BUF_SIZE, | |
301 | ||
302 | .base_queue = BASE_QUEUE_NOT_REQUESTED, | |
303 | ||
304 | .gmx_port_id = 3, | |
305 | }, | |
306 | ||
307 | /** Miscellaneous attributes */ | |
308 | .misc = { | |
309 | /* Host driver link query interval */ | |
310 | .oct_link_query_interval = 100, | |
311 | ||
312 | /* Octeon link query interval */ | |
313 | .host_link_query_interval = 500, | |
314 | ||
315 | .enable_sli_oq_bp = 0, | |
316 | ||
317 | /* Control queue group */ | |
318 | .ctrlq_grp = 1, | |
319 | } | |
320 | , | |
321 | }; | |
322 | ||
323 | /** Default configuration | |
324 | * for CN68XX OCTEON Model. | |
325 | */ | |
326 | static struct octeon_config default_cn68xx_210nv_conf = { | |
327 | .card_type = LIO_210NV, | |
328 | .card_name = LIO_210NV_NAME, | |
329 | ||
330 | /** IQ attributes */ | |
331 | ||
332 | .iq = { | |
333 | .max_iqs = CN6XXX_CFG_IO_QUEUES, | |
334 | .pending_list_size = | |
335 | (CN6XXX_MAX_IQ_DESCRIPTORS * CN6XXX_CFG_IO_QUEUES), | |
336 | .instr_type = OCTEON_64BYTE_INSTR, | |
337 | .db_min = CN6XXX_DB_MIN, | |
338 | .db_timeout = CN6XXX_DB_TIMEOUT, | |
339 | } | |
340 | , | |
341 | ||
342 | /** OQ attributes */ | |
343 | .oq = { | |
344 | .max_oqs = CN6XXX_CFG_IO_QUEUES, | |
345 | .info_ptr = OCTEON_OQ_INFOPTR_MODE, | |
346 | .refill_threshold = CN6XXX_OQ_REFIL_THRESHOLD, | |
347 | .oq_intr_pkt = CN6XXX_OQ_INTR_PKT, | |
348 | .oq_intr_time = CN6XXX_OQ_INTR_TIME, | |
349 | .pkts_per_intr = CN6XXX_OQ_PKTSPER_INTR, | |
350 | } | |
351 | , | |
352 | ||
353 | .num_nic_ports = DEFAULT_NUM_NIC_PORTS_68XX_210NV, | |
354 | .num_def_rx_descs = CN6XXX_MAX_OQ_DESCRIPTORS, | |
355 | .num_def_tx_descs = CN6XXX_MAX_IQ_DESCRIPTORS, | |
356 | .def_rx_buf_size = CN6XXX_OQ_BUF_SIZE, | |
357 | ||
358 | .nic_if_cfg[0] = { | |
359 | /* Max Txqs: Half for each of the two ports :max_iq/2 */ | |
360 | .max_txqs = MAX_TXQS_PER_INTF, | |
361 | ||
362 | /* Actual configured value. Range could be: 1...max_txqs */ | |
363 | .num_txqs = DEF_TXQS_PER_INTF, | |
364 | ||
365 | /* Max Rxqs: Half for each of the two ports :max_oq/2 */ | |
366 | .max_rxqs = MAX_RXQS_PER_INTF, | |
367 | ||
368 | /* Actual configured value. Range could be: 1...max_rxqs */ | |
369 | .num_rxqs = DEF_RXQS_PER_INTF, | |
370 | ||
371 | /* Num of desc for rx rings */ | |
372 | .num_rx_descs = CN6XXX_MAX_OQ_DESCRIPTORS, | |
373 | ||
374 | /* Num of desc for tx rings */ | |
375 | .num_tx_descs = CN6XXX_MAX_IQ_DESCRIPTORS, | |
376 | ||
377 | /* SKB size, We need not change buf size even for Jumbo frames. | |
378 | * Octeon can send jumbo frames in 4 consecutive descriptors, | |
379 | */ | |
380 | .rx_buf_size = CN6XXX_OQ_BUF_SIZE, | |
381 | ||
382 | .base_queue = BASE_QUEUE_NOT_REQUESTED, | |
383 | ||
384 | .gmx_port_id = 0, | |
385 | }, | |
386 | ||
387 | .nic_if_cfg[1] = { | |
388 | /* Max Txqs: Half for each of the two ports :max_iq/2 */ | |
389 | .max_txqs = MAX_TXQS_PER_INTF, | |
390 | ||
391 | /* Actual configured value. Range could be: 1...max_txqs */ | |
392 | .num_txqs = DEF_TXQS_PER_INTF, | |
393 | ||
394 | /* Max Rxqs: Half for each of the two ports :max_oq/2 */ | |
395 | .max_rxqs = MAX_RXQS_PER_INTF, | |
396 | ||
397 | /* Actual configured value. Range could be: 1...max_rxqs */ | |
398 | .num_rxqs = DEF_RXQS_PER_INTF, | |
399 | ||
400 | /* Num of desc for rx rings */ | |
401 | .num_rx_descs = CN6XXX_MAX_OQ_DESCRIPTORS, | |
402 | ||
403 | /* Num of desc for tx rings */ | |
404 | .num_tx_descs = CN6XXX_MAX_IQ_DESCRIPTORS, | |
405 | ||
406 | /* SKB size, We need not change buf size even for Jumbo frames. | |
407 | * Octeon can send jumbo frames in 4 consecutive descriptors, | |
408 | */ | |
409 | .rx_buf_size = CN6XXX_OQ_BUF_SIZE, | |
410 | ||
411 | .base_queue = BASE_QUEUE_NOT_REQUESTED, | |
412 | ||
413 | .gmx_port_id = 1, | |
414 | }, | |
415 | ||
416 | /** Miscellaneous attributes */ | |
417 | .misc = { | |
418 | /* Host driver link query interval */ | |
419 | .oct_link_query_interval = 100, | |
420 | ||
421 | /* Octeon link query interval */ | |
422 | .host_link_query_interval = 500, | |
423 | ||
424 | .enable_sli_oq_bp = 0, | |
425 | ||
426 | /* Control queue group */ | |
427 | .ctrlq_grp = 1, | |
428 | } | |
429 | , | |
430 | }; | |
431 | ||
432 | enum { | |
433 | OCTEON_CONFIG_TYPE_DEFAULT = 0, | |
434 | NUM_OCTEON_CONFS, | |
435 | }; | |
436 | ||
437 | static struct octeon_config_ptr { | |
438 | u32 conf_type; | |
439 | } oct_conf_info[MAX_OCTEON_DEVICES] = { | |
440 | { | |
441 | OCTEON_CONFIG_TYPE_DEFAULT, | |
442 | }, { | |
443 | OCTEON_CONFIG_TYPE_DEFAULT, | |
444 | }, { | |
445 | OCTEON_CONFIG_TYPE_DEFAULT, | |
446 | }, { | |
447 | OCTEON_CONFIG_TYPE_DEFAULT, | |
448 | }, | |
449 | }; | |
450 | ||
451 | static char oct_dev_state_str[OCT_DEV_STATES + 1][32] = { | |
452 | "BEGIN", "PCI-MAP-DONE", "DISPATCH-INIT-DONE", | |
453 | "IQ-INIT-DONE", "SCBUFF-POOL-INIT-DONE", "RESPLIST-INIT-DONE", | |
454 | "DROQ-INIT-DONE", "IO-QUEUES-INIT-DONE", "CONSOLE-INIT-DONE", | |
455 | "HOST-READY", "CORE-READY", "RUNNING", "IN-RESET", | |
456 | "INVALID" | |
457 | }; | |
458 | ||
459 | static char oct_dev_app_str[CVM_DRV_APP_COUNT + 1][32] = { | |
460 | "BASE", "NIC", "UNKNOWN"}; | |
461 | ||
462 | static struct octeon_device *octeon_device[MAX_OCTEON_DEVICES]; | |
463 | static u32 octeon_device_count; | |
464 | ||
465 | static struct octeon_core_setup core_setup[MAX_OCTEON_DEVICES]; | |
466 | ||
5b173cf9 | 467 | static void oct_set_config_info(int oct_id, int conf_type) |
f21fb3ed RV |
468 | { |
469 | if (conf_type < 0 || conf_type > (NUM_OCTEON_CONFS - 1)) | |
470 | conf_type = OCTEON_CONFIG_TYPE_DEFAULT; | |
471 | oct_conf_info[oct_id].conf_type = conf_type; | |
472 | } | |
473 | ||
474 | void octeon_init_device_list(int conf_type) | |
475 | { | |
476 | int i; | |
477 | ||
478 | memset(octeon_device, 0, (sizeof(void *) * MAX_OCTEON_DEVICES)); | |
479 | for (i = 0; i < MAX_OCTEON_DEVICES; i++) | |
480 | oct_set_config_info(i, conf_type); | |
481 | } | |
482 | ||
483 | static void *__retrieve_octeon_config_info(struct octeon_device *oct, | |
484 | u16 card_type) | |
485 | { | |
486 | u32 oct_id = oct->octeon_id; | |
487 | void *ret = NULL; | |
488 | ||
489 | switch (oct_conf_info[oct_id].conf_type) { | |
490 | case OCTEON_CONFIG_TYPE_DEFAULT: | |
491 | if (oct->chip_id == OCTEON_CN66XX) { | |
492 | ret = (void *)&default_cn66xx_conf; | |
493 | } else if ((oct->chip_id == OCTEON_CN68XX) && | |
494 | (card_type == LIO_210NV)) { | |
495 | ret = (void *)&default_cn68xx_210nv_conf; | |
496 | } else if ((oct->chip_id == OCTEON_CN68XX) && | |
497 | (card_type == LIO_410NV)) { | |
498 | ret = (void *)&default_cn68xx_conf; | |
499 | } | |
500 | break; | |
501 | default: | |
502 | break; | |
503 | } | |
504 | return ret; | |
505 | } | |
506 | ||
507 | static int __verify_octeon_config_info(struct octeon_device *oct, void *conf) | |
508 | { | |
509 | switch (oct->chip_id) { | |
510 | case OCTEON_CN66XX: | |
511 | case OCTEON_CN68XX: | |
512 | return lio_validate_cn6xxx_config_info(oct, conf); | |
513 | ||
514 | default: | |
515 | break; | |
516 | } | |
517 | ||
518 | return 1; | |
519 | } | |
520 | ||
521 | void *oct_get_config_info(struct octeon_device *oct, u16 card_type) | |
522 | { | |
523 | void *conf = NULL; | |
524 | ||
525 | conf = __retrieve_octeon_config_info(oct, card_type); | |
526 | if (!conf) | |
527 | return NULL; | |
528 | ||
529 | if (__verify_octeon_config_info(oct, conf)) { | |
530 | dev_err(&oct->pci_dev->dev, "Configuration verification failed\n"); | |
531 | return NULL; | |
532 | } | |
533 | ||
534 | return conf; | |
535 | } | |
536 | ||
537 | char *lio_get_state_string(atomic_t *state_ptr) | |
538 | { | |
539 | s32 istate = (s32)atomic_read(state_ptr); | |
540 | ||
541 | if (istate > OCT_DEV_STATES || istate < 0) | |
542 | return oct_dev_state_str[OCT_DEV_STATE_INVALID]; | |
543 | return oct_dev_state_str[istate]; | |
544 | } | |
545 | ||
546 | static char *get_oct_app_string(u32 app_mode) | |
547 | { | |
548 | if (app_mode <= CVM_DRV_APP_END) | |
549 | return oct_dev_app_str[app_mode - CVM_DRV_APP_START]; | |
550 | return oct_dev_app_str[CVM_DRV_INVALID_APP - CVM_DRV_APP_START]; | |
551 | } | |
552 | ||
553 | int octeon_download_firmware(struct octeon_device *oct, const u8 *data, | |
554 | size_t size) | |
555 | { | |
556 | int ret = 0; | |
557 | u8 *p; | |
558 | u8 *buffer; | |
559 | u32 crc32_result; | |
560 | u64 load_addr; | |
561 | u32 image_len; | |
562 | struct octeon_firmware_file_header *h; | |
563 | u32 i; | |
564 | ||
565 | if (size < sizeof(struct octeon_firmware_file_header)) { | |
566 | dev_err(&oct->pci_dev->dev, "Firmware file too small (%d < %d).\n", | |
567 | (u32)size, | |
568 | (u32)sizeof(struct octeon_firmware_file_header)); | |
569 | return -EINVAL; | |
570 | } | |
571 | ||
572 | h = (struct octeon_firmware_file_header *)data; | |
573 | ||
5b173cf9 | 574 | if (be32_to_cpu(h->magic) != LIO_NIC_MAGIC) { |
f21fb3ed RV |
575 | dev_err(&oct->pci_dev->dev, "Unrecognized firmware file.\n"); |
576 | return -EINVAL; | |
577 | } | |
578 | ||
579 | crc32_result = | |
580 | crc32(~0, data, | |
581 | sizeof(struct octeon_firmware_file_header) - | |
582 | sizeof(u32)) ^ ~0U; | |
583 | if (crc32_result != be32_to_cpu(h->crc32)) { | |
584 | dev_err(&oct->pci_dev->dev, "Firmware CRC mismatch (0x%08x != 0x%08x).\n", | |
585 | crc32_result, be32_to_cpu(h->crc32)); | |
586 | return -EINVAL; | |
587 | } | |
588 | ||
589 | if (memcmp(LIQUIDIO_VERSION, h->version, strlen(LIQUIDIO_VERSION))) { | |
590 | dev_err(&oct->pci_dev->dev, "Unmatched firmware version. Expected %s, got %s.\n", | |
591 | LIQUIDIO_VERSION, h->version); | |
592 | return -EINVAL; | |
593 | } | |
594 | ||
595 | if (be32_to_cpu(h->num_images) > LIO_MAX_IMAGES) { | |
596 | dev_err(&oct->pci_dev->dev, "Too many images in firmware file (%d).\n", | |
597 | be32_to_cpu(h->num_images)); | |
598 | return -EINVAL; | |
599 | } | |
600 | ||
601 | dev_info(&oct->pci_dev->dev, "Firmware version: %s\n", h->version); | |
602 | snprintf(oct->fw_info.liquidio_firmware_version, 32, "LIQUIDIO: %s", | |
603 | h->version); | |
604 | ||
605 | buffer = kmalloc(size, GFP_KERNEL); | |
606 | if (!buffer) | |
607 | return -ENOMEM; | |
608 | ||
609 | memcpy(buffer, data, size); | |
610 | ||
611 | p = buffer + sizeof(struct octeon_firmware_file_header); | |
612 | ||
613 | /* load all images */ | |
614 | for (i = 0; i < be32_to_cpu(h->num_images); i++) { | |
615 | load_addr = be64_to_cpu(h->desc[i].addr); | |
616 | image_len = be32_to_cpu(h->desc[i].len); | |
617 | ||
618 | /* validate the image */ | |
619 | crc32_result = crc32(~0, p, image_len) ^ ~0U; | |
620 | if (crc32_result != be32_to_cpu(h->desc[i].crc32)) { | |
621 | dev_err(&oct->pci_dev->dev, | |
622 | "Firmware CRC mismatch in image %d (0x%08x != 0x%08x).\n", | |
623 | i, crc32_result, | |
624 | be32_to_cpu(h->desc[i].crc32)); | |
625 | ret = -EINVAL; | |
626 | goto done_downloading; | |
627 | } | |
628 | ||
629 | /* download the image */ | |
630 | octeon_pci_write_core_mem(oct, load_addr, p, image_len); | |
631 | ||
632 | p += image_len; | |
633 | dev_dbg(&oct->pci_dev->dev, | |
634 | "Downloaded image %d (%d bytes) to address 0x%016llx\n", | |
635 | i, image_len, load_addr); | |
636 | } | |
637 | ||
638 | /* Invoke the bootcmd */ | |
639 | ret = octeon_console_send_cmd(oct, h->bootcmd, 50); | |
640 | ||
641 | done_downloading: | |
642 | kfree(buffer); | |
643 | ||
644 | return ret; | |
645 | } | |
646 | ||
647 | void octeon_free_device_mem(struct octeon_device *oct) | |
648 | { | |
649 | u32 i; | |
650 | ||
651 | for (i = 0; i < MAX_OCTEON_OUTPUT_QUEUES; i++) { | |
652 | /* could check mask as well */ | |
653 | if (oct->droq[i]) | |
654 | vfree(oct->droq[i]); | |
655 | } | |
656 | ||
657 | for (i = 0; i < MAX_OCTEON_INSTR_QUEUES; i++) { | |
658 | /* could check mask as well */ | |
659 | if (oct->instr_queue[i]) | |
660 | vfree(oct->instr_queue[i]); | |
661 | } | |
662 | ||
663 | i = oct->octeon_id; | |
664 | vfree(oct); | |
665 | ||
666 | octeon_device[i] = NULL; | |
667 | octeon_device_count--; | |
668 | } | |
669 | ||
670 | static struct octeon_device *octeon_allocate_device_mem(u32 pci_id, | |
671 | u32 priv_size) | |
672 | { | |
673 | struct octeon_device *oct; | |
674 | u8 *buf = NULL; | |
675 | u32 octdevsize = 0, configsize = 0, size; | |
676 | ||
677 | switch (pci_id) { | |
678 | case OCTEON_CN68XX: | |
679 | case OCTEON_CN66XX: | |
680 | configsize = sizeof(struct octeon_cn6xxx); | |
681 | break; | |
682 | ||
683 | default: | |
684 | pr_err("%s: Unknown PCI Device: 0x%x\n", | |
685 | __func__, | |
686 | pci_id); | |
687 | return NULL; | |
688 | } | |
689 | ||
690 | if (configsize & 0x7) | |
691 | configsize += (8 - (configsize & 0x7)); | |
692 | ||
693 | octdevsize = sizeof(struct octeon_device); | |
694 | if (octdevsize & 0x7) | |
695 | octdevsize += (8 - (octdevsize & 0x7)); | |
696 | ||
697 | if (priv_size & 0x7) | |
698 | priv_size += (8 - (priv_size & 0x7)); | |
699 | ||
700 | size = octdevsize + priv_size + configsize + | |
701 | (sizeof(struct octeon_dispatch) * DISPATCH_LIST_SIZE); | |
702 | ||
703 | buf = vmalloc(size); | |
704 | if (!buf) | |
705 | return NULL; | |
706 | ||
707 | memset(buf, 0, size); | |
708 | ||
709 | oct = (struct octeon_device *)buf; | |
710 | oct->priv = (void *)(buf + octdevsize); | |
711 | oct->chip = (void *)(buf + octdevsize + priv_size); | |
712 | oct->dispatch.dlist = (struct octeon_dispatch *) | |
713 | (buf + octdevsize + priv_size + configsize); | |
714 | ||
715 | return oct; | |
716 | } | |
717 | ||
718 | struct octeon_device *octeon_allocate_device(u32 pci_id, | |
719 | u32 priv_size) | |
720 | { | |
721 | u32 oct_idx = 0; | |
722 | struct octeon_device *oct = NULL; | |
723 | ||
724 | for (oct_idx = 0; oct_idx < MAX_OCTEON_DEVICES; oct_idx++) | |
725 | if (!octeon_device[oct_idx]) | |
726 | break; | |
727 | ||
728 | if (oct_idx == MAX_OCTEON_DEVICES) | |
729 | return NULL; | |
730 | ||
731 | oct = octeon_allocate_device_mem(pci_id, priv_size); | |
732 | if (!oct) | |
733 | return NULL; | |
734 | ||
735 | spin_lock_init(&oct->pci_win_lock); | |
736 | spin_lock_init(&oct->mem_access_lock); | |
737 | ||
738 | octeon_device_count++; | |
739 | octeon_device[oct_idx] = oct; | |
740 | ||
741 | oct->octeon_id = oct_idx; | |
742 | snprintf((oct->device_name), sizeof(oct->device_name), | |
743 | "LiquidIO%d", (oct->octeon_id)); | |
744 | ||
745 | return oct; | |
746 | } | |
747 | ||
748 | int octeon_setup_instr_queues(struct octeon_device *oct) | |
749 | { | |
750 | u32 i, num_iqs = 0; | |
751 | u32 num_descs = 0; | |
752 | ||
753 | /* this causes queue 0 to be default queue */ | |
754 | if (OCTEON_CN6XXX(oct)) { | |
755 | num_iqs = 1; | |
756 | num_descs = | |
757 | CFG_GET_NUM_DEF_TX_DESCS(CHIP_FIELD(oct, cn6xxx, conf)); | |
758 | } | |
759 | ||
760 | oct->num_iqs = 0; | |
761 | ||
762 | for (i = 0; i < num_iqs; i++) { | |
763 | oct->instr_queue[i] = | |
764 | vmalloc(sizeof(struct octeon_instr_queue)); | |
765 | if (!oct->instr_queue[i]) | |
766 | return 1; | |
767 | ||
768 | memset(oct->instr_queue[i], 0, | |
769 | sizeof(struct octeon_instr_queue)); | |
770 | ||
771 | oct->instr_queue[i]->app_ctx = (void *)(size_t)i; | |
772 | if (octeon_init_instr_queue(oct, i, num_descs)) | |
773 | return 1; | |
774 | ||
775 | oct->num_iqs++; | |
776 | } | |
777 | ||
778 | return 0; | |
779 | } | |
780 | ||
781 | int octeon_setup_output_queues(struct octeon_device *oct) | |
782 | { | |
783 | u32 i, num_oqs = 0; | |
784 | u32 num_descs = 0; | |
785 | u32 desc_size = 0; | |
786 | ||
787 | /* this causes queue 0 to be default queue */ | |
788 | if (OCTEON_CN6XXX(oct)) { | |
789 | /* CFG_GET_OQ_MAX_BASE_Q(CHIP_FIELD(oct, cn6xxx, conf)); */ | |
790 | num_oqs = 1; | |
791 | num_descs = | |
792 | CFG_GET_NUM_DEF_RX_DESCS(CHIP_FIELD(oct, cn6xxx, conf)); | |
793 | desc_size = | |
794 | CFG_GET_DEF_RX_BUF_SIZE(CHIP_FIELD(oct, cn6xxx, conf)); | |
795 | } | |
796 | ||
797 | oct->num_oqs = 0; | |
798 | ||
799 | for (i = 0; i < num_oqs; i++) { | |
800 | oct->droq[i] = vmalloc(sizeof(*oct->droq[i])); | |
801 | if (!oct->droq[i]) | |
802 | return 1; | |
803 | ||
804 | memset(oct->droq[i], 0, sizeof(struct octeon_droq)); | |
805 | ||
806 | if (octeon_init_droq(oct, i, num_descs, desc_size, NULL)) | |
807 | return 1; | |
808 | ||
809 | oct->num_oqs++; | |
810 | } | |
811 | ||
812 | return 0; | |
813 | } | |
814 | ||
815 | void octeon_set_io_queues_off(struct octeon_device *oct) | |
816 | { | |
817 | /* Disable the i/p and o/p queues for this Octeon. */ | |
818 | ||
819 | octeon_write_csr(oct, CN6XXX_SLI_PKT_INSTR_ENB, 0); | |
820 | octeon_write_csr(oct, CN6XXX_SLI_PKT_OUT_ENB, 0); | |
821 | } | |
822 | ||
823 | void octeon_set_droq_pkt_op(struct octeon_device *oct, | |
824 | u32 q_no, | |
825 | u32 enable) | |
826 | { | |
827 | u32 reg_val = 0; | |
828 | ||
829 | /* Disable the i/p and o/p queues for this Octeon. */ | |
830 | reg_val = octeon_read_csr(oct, CN6XXX_SLI_PKT_OUT_ENB); | |
831 | ||
832 | if (enable) | |
833 | reg_val = reg_val | (1 << q_no); | |
834 | else | |
835 | reg_val = reg_val & (~(1 << q_no)); | |
836 | ||
837 | octeon_write_csr(oct, CN6XXX_SLI_PKT_OUT_ENB, reg_val); | |
838 | } | |
839 | ||
840 | int octeon_init_dispatch_list(struct octeon_device *oct) | |
841 | { | |
842 | u32 i; | |
843 | ||
844 | oct->dispatch.count = 0; | |
845 | ||
846 | for (i = 0; i < DISPATCH_LIST_SIZE; i++) { | |
847 | oct->dispatch.dlist[i].opcode = 0; | |
848 | INIT_LIST_HEAD(&oct->dispatch.dlist[i].list); | |
849 | } | |
850 | ||
851 | for (i = 0; i <= REQTYPE_LAST; i++) | |
852 | octeon_register_reqtype_free_fn(oct, i, NULL); | |
853 | ||
854 | spin_lock_init(&oct->dispatch.lock); | |
855 | ||
856 | return 0; | |
857 | } | |
858 | ||
859 | void octeon_delete_dispatch_list(struct octeon_device *oct) | |
860 | { | |
861 | u32 i; | |
862 | struct list_head freelist, *temp, *tmp2; | |
863 | ||
864 | INIT_LIST_HEAD(&freelist); | |
865 | ||
866 | spin_lock_bh(&oct->dispatch.lock); | |
867 | ||
868 | for (i = 0; i < DISPATCH_LIST_SIZE; i++) { | |
869 | struct list_head *dispatch; | |
870 | ||
871 | dispatch = &oct->dispatch.dlist[i].list; | |
872 | while (dispatch->next != dispatch) { | |
873 | temp = dispatch->next; | |
874 | list_del(temp); | |
875 | list_add_tail(temp, &freelist); | |
876 | } | |
877 | ||
878 | oct->dispatch.dlist[i].opcode = 0; | |
879 | } | |
880 | ||
881 | oct->dispatch.count = 0; | |
882 | ||
883 | spin_unlock_bh(&oct->dispatch.lock); | |
884 | ||
885 | list_for_each_safe(temp, tmp2, &freelist) { | |
886 | list_del(temp); | |
887 | vfree(temp); | |
888 | } | |
889 | } | |
890 | ||
891 | octeon_dispatch_fn_t | |
892 | octeon_get_dispatch(struct octeon_device *octeon_dev, u16 opcode, | |
893 | u16 subcode) | |
894 | { | |
895 | u32 idx; | |
896 | struct list_head *dispatch; | |
897 | octeon_dispatch_fn_t fn = NULL; | |
898 | u16 combined_opcode = OPCODE_SUBCODE(opcode, subcode); | |
899 | ||
900 | idx = combined_opcode & OCTEON_OPCODE_MASK; | |
901 | ||
902 | spin_lock_bh(&octeon_dev->dispatch.lock); | |
903 | ||
904 | if (octeon_dev->dispatch.count == 0) { | |
905 | spin_unlock_bh(&octeon_dev->dispatch.lock); | |
906 | return NULL; | |
907 | } | |
908 | ||
909 | if (!(octeon_dev->dispatch.dlist[idx].opcode)) { | |
910 | spin_unlock_bh(&octeon_dev->dispatch.lock); | |
911 | return NULL; | |
912 | } | |
913 | ||
914 | if (octeon_dev->dispatch.dlist[idx].opcode == combined_opcode) { | |
915 | fn = octeon_dev->dispatch.dlist[idx].dispatch_fn; | |
916 | } else { | |
917 | list_for_each(dispatch, | |
918 | &octeon_dev->dispatch.dlist[idx].list) { | |
919 | if (((struct octeon_dispatch *)dispatch)->opcode == | |
920 | combined_opcode) { | |
921 | fn = ((struct octeon_dispatch *) | |
922 | dispatch)->dispatch_fn; | |
923 | break; | |
924 | } | |
925 | } | |
926 | } | |
927 | ||
928 | spin_unlock_bh(&octeon_dev->dispatch.lock); | |
929 | return fn; | |
930 | } | |
931 | ||
932 | /* octeon_register_dispatch_fn | |
933 | * Parameters: | |
934 | * octeon_id - id of the octeon device. | |
935 | * opcode - opcode for which driver should call the registered function | |
936 | * subcode - subcode for which driver should call the registered function | |
937 | * fn - The function to call when a packet with "opcode" arrives in | |
938 | * octeon output queues. | |
939 | * fn_arg - The argument to be passed when calling function "fn". | |
940 | * Description: | |
941 | * Registers a function and its argument to be called when a packet | |
942 | * arrives in Octeon output queues with "opcode". | |
943 | * Returns: | |
944 | * Success: 0 | |
945 | * Failure: 1 | |
946 | * Locks: | |
947 | * No locks are held. | |
948 | */ | |
949 | int | |
950 | octeon_register_dispatch_fn(struct octeon_device *oct, | |
951 | u16 opcode, | |
952 | u16 subcode, | |
953 | octeon_dispatch_fn_t fn, void *fn_arg) | |
954 | { | |
955 | u32 idx; | |
956 | octeon_dispatch_fn_t pfn; | |
957 | u16 combined_opcode = OPCODE_SUBCODE(opcode, subcode); | |
958 | ||
959 | idx = combined_opcode & OCTEON_OPCODE_MASK; | |
960 | ||
961 | spin_lock_bh(&oct->dispatch.lock); | |
962 | /* Add dispatch function to first level of lookup table */ | |
963 | if (oct->dispatch.dlist[idx].opcode == 0) { | |
964 | oct->dispatch.dlist[idx].opcode = combined_opcode; | |
965 | oct->dispatch.dlist[idx].dispatch_fn = fn; | |
966 | oct->dispatch.dlist[idx].arg = fn_arg; | |
967 | oct->dispatch.count++; | |
968 | spin_unlock_bh(&oct->dispatch.lock); | |
969 | return 0; | |
970 | } | |
971 | ||
972 | spin_unlock_bh(&oct->dispatch.lock); | |
973 | ||
974 | /* Check if there was a function already registered for this | |
975 | * opcode/subcode. | |
976 | */ | |
977 | pfn = octeon_get_dispatch(oct, opcode, subcode); | |
978 | if (!pfn) { | |
979 | struct octeon_dispatch *dispatch; | |
980 | ||
981 | dev_dbg(&oct->pci_dev->dev, | |
982 | "Adding opcode to dispatch list linked list\n"); | |
983 | dispatch = (struct octeon_dispatch *) | |
984 | vmalloc(sizeof(struct octeon_dispatch)); | |
985 | if (!dispatch) { | |
986 | dev_err(&oct->pci_dev->dev, | |
987 | "No memory to add dispatch function\n"); | |
988 | return 1; | |
989 | } | |
990 | dispatch->opcode = combined_opcode; | |
991 | dispatch->dispatch_fn = fn; | |
992 | dispatch->arg = fn_arg; | |
993 | ||
994 | /* Add dispatch function to linked list of fn ptrs | |
995 | * at the hashed index. | |
996 | */ | |
997 | spin_lock_bh(&oct->dispatch.lock); | |
998 | list_add(&dispatch->list, &oct->dispatch.dlist[idx].list); | |
999 | oct->dispatch.count++; | |
1000 | spin_unlock_bh(&oct->dispatch.lock); | |
1001 | ||
1002 | } else { | |
1003 | dev_err(&oct->pci_dev->dev, | |
1004 | "Found previously registered dispatch fn for opcode/subcode: %x/%x\n", | |
1005 | opcode, subcode); | |
1006 | return 1; | |
1007 | } | |
1008 | ||
1009 | return 0; | |
1010 | } | |
1011 | ||
1012 | /* octeon_unregister_dispatch_fn | |
1013 | * Parameters: | |
1014 | * oct - octeon device | |
1015 | * opcode - driver should unregister the function for this opcode | |
1016 | * subcode - driver should unregister the function for this subcode | |
1017 | * Description: | |
1018 | * Unregister the function set for this opcode+subcode. | |
1019 | * Returns: | |
1020 | * Success: 0 | |
1021 | * Failure: 1 | |
1022 | * Locks: | |
1023 | * No locks are held. | |
1024 | */ | |
1025 | int | |
1026 | octeon_unregister_dispatch_fn(struct octeon_device *oct, u16 opcode, | |
1027 | u16 subcode) | |
1028 | { | |
1029 | int retval = 0; | |
1030 | u32 idx; | |
1031 | struct list_head *dispatch, *dfree = NULL, *tmp2; | |
1032 | u16 combined_opcode = OPCODE_SUBCODE(opcode, subcode); | |
1033 | ||
1034 | idx = combined_opcode & OCTEON_OPCODE_MASK; | |
1035 | ||
1036 | spin_lock_bh(&oct->dispatch.lock); | |
1037 | ||
1038 | if (oct->dispatch.count == 0) { | |
1039 | spin_unlock_bh(&oct->dispatch.lock); | |
1040 | dev_err(&oct->pci_dev->dev, | |
1041 | "No dispatch functions registered for this device\n"); | |
1042 | return 1; | |
1043 | } | |
1044 | ||
1045 | if (oct->dispatch.dlist[idx].opcode == combined_opcode) { | |
1046 | dispatch = &oct->dispatch.dlist[idx].list; | |
1047 | if (dispatch->next != dispatch) { | |
1048 | dispatch = dispatch->next; | |
1049 | oct->dispatch.dlist[idx].opcode = | |
1050 | ((struct octeon_dispatch *)dispatch)->opcode; | |
1051 | oct->dispatch.dlist[idx].dispatch_fn = | |
1052 | ((struct octeon_dispatch *) | |
1053 | dispatch)->dispatch_fn; | |
1054 | oct->dispatch.dlist[idx].arg = | |
1055 | ((struct octeon_dispatch *)dispatch)->arg; | |
1056 | list_del(dispatch); | |
1057 | dfree = dispatch; | |
1058 | } else { | |
1059 | oct->dispatch.dlist[idx].opcode = 0; | |
1060 | oct->dispatch.dlist[idx].dispatch_fn = NULL; | |
1061 | oct->dispatch.dlist[idx].arg = NULL; | |
1062 | } | |
1063 | } else { | |
1064 | retval = 1; | |
1065 | list_for_each_safe(dispatch, tmp2, | |
1066 | &(oct->dispatch.dlist[idx]. | |
1067 | list)) { | |
1068 | if (((struct octeon_dispatch *)dispatch)->opcode == | |
1069 | combined_opcode) { | |
1070 | list_del(dispatch); | |
1071 | dfree = dispatch; | |
1072 | retval = 0; | |
1073 | } | |
1074 | } | |
1075 | } | |
1076 | ||
1077 | if (!retval) | |
1078 | oct->dispatch.count--; | |
1079 | ||
1080 | spin_unlock_bh(&oct->dispatch.lock); | |
1081 | ||
1082 | if (dfree) | |
1083 | vfree(dfree); | |
1084 | ||
1085 | return retval; | |
1086 | } | |
1087 | ||
1088 | int octeon_core_drv_init(struct octeon_recv_info *recv_info, void *buf) | |
1089 | { | |
1090 | u32 i; | |
1091 | char app_name[16]; | |
1092 | struct octeon_device *oct = (struct octeon_device *)buf; | |
1093 | struct octeon_recv_pkt *recv_pkt = recv_info->recv_pkt; | |
1094 | struct octeon_core_setup *cs = NULL; | |
1095 | u32 num_nic_ports = 0; | |
1096 | ||
1097 | if (OCTEON_CN6XXX(oct)) | |
1098 | num_nic_ports = | |
1099 | CFG_GET_NUM_NIC_PORTS(CHIP_FIELD(oct, cn6xxx, conf)); | |
1100 | ||
1101 | if (atomic_read(&oct->status) >= OCT_DEV_RUNNING) { | |
1102 | dev_err(&oct->pci_dev->dev, "Received CORE OK when device state is 0x%x\n", | |
1103 | atomic_read(&oct->status)); | |
1104 | goto core_drv_init_err; | |
1105 | } | |
1106 | ||
1107 | strncpy(app_name, | |
1108 | get_oct_app_string( | |
1109 | (u32)recv_pkt->rh.r_core_drv_init.app_mode), | |
1110 | sizeof(app_name) - 1); | |
1111 | oct->app_mode = (u32)recv_pkt->rh.r_core_drv_init.app_mode; | |
5b173cf9 | 1112 | if (recv_pkt->rh.r_core_drv_init.app_mode == CVM_DRV_NIC_APP) { |
f21fb3ed RV |
1113 | oct->fw_info.max_nic_ports = |
1114 | (u32)recv_pkt->rh.r_core_drv_init.max_nic_ports; | |
1115 | oct->fw_info.num_gmx_ports = | |
1116 | (u32)recv_pkt->rh.r_core_drv_init.num_gmx_ports; | |
5b173cf9 | 1117 | } |
f21fb3ed RV |
1118 | |
1119 | if (oct->fw_info.max_nic_ports < num_nic_ports) { | |
1120 | dev_err(&oct->pci_dev->dev, | |
1121 | "Config has more ports than firmware allows (%d > %d).\n", | |
1122 | num_nic_ports, oct->fw_info.max_nic_ports); | |
1123 | goto core_drv_init_err; | |
1124 | } | |
1125 | oct->fw_info.app_cap_flags = recv_pkt->rh.r_core_drv_init.app_cap_flags; | |
1126 | oct->fw_info.app_mode = (u32)recv_pkt->rh.r_core_drv_init.app_mode; | |
1127 | ||
1128 | atomic_set(&oct->status, OCT_DEV_CORE_OK); | |
1129 | ||
1130 | cs = &core_setup[oct->octeon_id]; | |
1131 | ||
1132 | if (recv_pkt->buffer_size[0] != sizeof(*cs)) { | |
1133 | dev_dbg(&oct->pci_dev->dev, "Core setup bytes expected %u found %d\n", | |
1134 | (u32)sizeof(*cs), | |
1135 | recv_pkt->buffer_size[0]); | |
1136 | } | |
1137 | ||
1138 | memcpy(cs, get_rbd(recv_pkt->buffer_ptr[0]), sizeof(*cs)); | |
1139 | strncpy(oct->boardinfo.name, cs->boardname, OCT_BOARD_NAME); | |
1140 | strncpy(oct->boardinfo.serial_number, cs->board_serial_number, | |
1141 | OCT_SERIAL_LEN); | |
1142 | ||
1143 | octeon_swap_8B_data((u64 *)cs, (sizeof(*cs) >> 3)); | |
1144 | ||
1145 | oct->boardinfo.major = cs->board_rev_major; | |
1146 | oct->boardinfo.minor = cs->board_rev_minor; | |
1147 | ||
1148 | dev_info(&oct->pci_dev->dev, | |
1149 | "Running %s (%llu Hz)\n", | |
1150 | app_name, CVM_CAST64(cs->corefreq)); | |
1151 | ||
1152 | core_drv_init_err: | |
1153 | for (i = 0; i < recv_pkt->buffer_count; i++) | |
1154 | recv_buffer_free(recv_pkt->buffer_ptr[i]); | |
1155 | octeon_free_recv_info(recv_info); | |
1156 | return 0; | |
1157 | } | |
1158 | ||
1159 | int octeon_get_tx_qsize(struct octeon_device *oct, u32 q_no) | |
1160 | ||
1161 | { | |
1162 | if (oct && (q_no < MAX_OCTEON_INSTR_QUEUES) && | |
1163 | (oct->io_qmask.iq & (1UL << q_no))) | |
1164 | return oct->instr_queue[q_no]->max_count; | |
1165 | ||
1166 | return -1; | |
1167 | } | |
1168 | ||
1169 | int octeon_get_rx_qsize(struct octeon_device *oct, u32 q_no) | |
1170 | { | |
1171 | if (oct && (q_no < MAX_OCTEON_OUTPUT_QUEUES) && | |
1172 | (oct->io_qmask.oq & (1UL << q_no))) | |
1173 | return oct->droq[q_no]->max_count; | |
1174 | return -1; | |
1175 | } | |
1176 | ||
1177 | /* Retruns the host firmware handshake OCTEON specific configuration */ | |
1178 | struct octeon_config *octeon_get_conf(struct octeon_device *oct) | |
1179 | { | |
1180 | struct octeon_config *default_oct_conf = NULL; | |
1181 | ||
1182 | /* check the OCTEON Device model & return the corresponding octeon | |
1183 | * configuration | |
1184 | */ | |
1185 | ||
1186 | if (OCTEON_CN6XXX(oct)) { | |
1187 | default_oct_conf = | |
1188 | (struct octeon_config *)(CHIP_FIELD(oct, cn6xxx, conf)); | |
1189 | } | |
1190 | ||
1191 | return default_oct_conf; | |
1192 | } | |
1193 | ||
1194 | /* scratch register address is same in all the OCT-II and CN70XX models */ | |
1195 | #define CNXX_SLI_SCRATCH1 0x3C0 | |
1196 | ||
1197 | /** Get the octeon device pointer. | |
1198 | * @param octeon_id - The id for which the octeon device pointer is required. | |
1199 | * @return Success: Octeon device pointer. | |
1200 | * @return Failure: NULL. | |
1201 | */ | |
1202 | struct octeon_device *lio_get_device(u32 octeon_id) | |
1203 | { | |
1204 | if (octeon_id >= MAX_OCTEON_DEVICES) | |
1205 | return NULL; | |
1206 | else | |
1207 | return octeon_device[octeon_id]; | |
1208 | } | |
1209 | ||
1210 | u64 lio_pci_readq(struct octeon_device *oct, u64 addr) | |
1211 | { | |
1212 | u64 val64; | |
1213 | unsigned long flags; | |
1214 | u32 val32, addrhi; | |
1215 | ||
1216 | spin_lock_irqsave(&oct->pci_win_lock, flags); | |
1217 | ||
1218 | /* The windowed read happens when the LSB of the addr is written. | |
1219 | * So write MSB first | |
1220 | */ | |
1221 | addrhi = (addr >> 32); | |
1222 | if ((oct->chip_id == OCTEON_CN66XX) || (oct->chip_id == OCTEON_CN68XX)) | |
1223 | addrhi |= 0x00060000; | |
1224 | writel(addrhi, oct->reg_list.pci_win_rd_addr_hi); | |
1225 | ||
1226 | /* Read back to preserve ordering of writes */ | |
1227 | val32 = readl(oct->reg_list.pci_win_rd_addr_hi); | |
1228 | ||
1229 | writel(addr & 0xffffffff, oct->reg_list.pci_win_rd_addr_lo); | |
1230 | val32 = readl(oct->reg_list.pci_win_rd_addr_lo); | |
1231 | ||
1232 | val64 = readq(oct->reg_list.pci_win_rd_data); | |
1233 | ||
1234 | spin_unlock_irqrestore(&oct->pci_win_lock, flags); | |
1235 | ||
1236 | return val64; | |
1237 | } | |
1238 | ||
1239 | void lio_pci_writeq(struct octeon_device *oct, | |
1240 | u64 val, | |
1241 | u64 addr) | |
1242 | { | |
1243 | u32 val32; | |
1244 | unsigned long flags; | |
1245 | ||
1246 | spin_lock_irqsave(&oct->pci_win_lock, flags); | |
1247 | ||
1248 | writeq(addr, oct->reg_list.pci_win_wr_addr); | |
1249 | ||
1250 | /* The write happens when the LSB is written. So write MSB first. */ | |
1251 | writel(val >> 32, oct->reg_list.pci_win_wr_data_hi); | |
1252 | /* Read the MSB to ensure ordering of writes. */ | |
1253 | val32 = readl(oct->reg_list.pci_win_wr_data_hi); | |
1254 | ||
1255 | writel(val & 0xffffffff, oct->reg_list.pci_win_wr_data_lo); | |
1256 | ||
1257 | spin_unlock_irqrestore(&oct->pci_win_lock, flags); | |
1258 | } | |
1259 | ||
1260 | int octeon_mem_access_ok(struct octeon_device *oct) | |
1261 | { | |
1262 | u64 access_okay = 0; | |
1263 | ||
1264 | /* Check to make sure a DDR interface is enabled */ | |
1265 | u64 lmc0_reset_ctl = lio_pci_readq(oct, CN6XXX_LMC0_RESET_CTL); | |
1266 | ||
1267 | access_okay = (lmc0_reset_ctl & CN6XXX_LMC0_RESET_CTL_DDR3RST_MASK); | |
1268 | ||
1269 | return access_okay ? 0 : 1; | |
1270 | } | |
1271 | ||
1272 | int octeon_wait_for_ddr_init(struct octeon_device *oct, u32 *timeout) | |
1273 | { | |
1274 | int ret = 1; | |
1275 | u32 ms; | |
1276 | ||
1277 | if (!timeout) | |
1278 | return ret; | |
1279 | ||
1280 | while (*timeout == 0) | |
1281 | schedule_timeout_uninterruptible(HZ / 10); | |
1282 | ||
1283 | for (ms = 0; (ret != 0) && ((*timeout == 0) || (ms <= *timeout)); | |
1284 | ms += HZ / 10) { | |
1285 | ret = octeon_mem_access_ok(oct); | |
1286 | ||
1287 | /* wait 100 ms */ | |
1288 | if (ret) | |
1289 | schedule_timeout_uninterruptible(HZ / 10); | |
1290 | } | |
1291 | ||
1292 | return ret; | |
1293 | } | |
1294 | ||
1295 | /** Get the octeon id assigned to the octeon device passed as argument. | |
1296 | * This function is exported to other modules. | |
1297 | * @param dev - octeon device pointer passed as a void *. | |
1298 | * @return octeon device id | |
1299 | */ | |
1300 | int lio_get_device_id(void *dev) | |
1301 | { | |
1302 | struct octeon_device *octeon_dev = (struct octeon_device *)dev; | |
1303 | u32 i; | |
1304 | ||
1305 | for (i = 0; i < MAX_OCTEON_DEVICES; i++) | |
1306 | if (octeon_device[i] == octeon_dev) | |
1307 | return octeon_dev->octeon_id; | |
1308 | return -1; | |
1309 | } |