blob: bc16fc082d959e7c710107ce4cc17cb19055b232 [file] [log] [blame]
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001/*
2 * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 *
32 */
33
34#include <linux/module.h>
35#include <linux/moduleparam.h>
36#include <linux/netdevice.h>
37#include <linux/etherdevice.h>
38#include <linux/ip.h>
39#include <linux/tcp.h>
40#include <linux/if_vlan.h>
Faisal Latif37dab412008-04-29 13:46:54 -070041#include <linux/inet_lro.h>
Glenn Streiff3c2d7742008-02-04 20:20:45 -080042
43#include "nes.h"
44
Roland Dreierdd378182008-05-13 11:27:25 -070045static unsigned int nes_lro_max_aggr = NES_LRO_MAX_AGGR;
46module_param(nes_lro_max_aggr, uint, 0444);
47MODULE_PARM_DESC(nes_lro_max_aggr, "NIC LRO max packet aggregation");
48
Roland Dreier1a855fbf2008-04-16 21:01:09 -070049static u32 crit_err_count;
Glenn Streiff3c2d7742008-02-04 20:20:45 -080050u32 int_mod_timer_init;
51u32 int_mod_cq_depth_256;
52u32 int_mod_cq_depth_128;
53u32 int_mod_cq_depth_32;
54u32 int_mod_cq_depth_24;
55u32 int_mod_cq_depth_16;
56u32 int_mod_cq_depth_4;
57u32 int_mod_cq_depth_1;
58
59#include "nes_cm.h"
60
Roland Dreier1a855fbf2008-04-16 21:01:09 -070061static void nes_cqp_ce_handler(struct nes_device *nesdev, struct nes_hw_cq *cq);
62static void nes_init_csr_ne020(struct nes_device *nesdev, u8 hw_rev, u8 port_count);
63static int nes_init_serdes(struct nes_device *nesdev, u8 hw_rev, u8 port_count,
Chien Tungfcb7ad32008-09-30 14:49:44 -070064 struct nes_adapter *nesadapter, u8 OneG_Mode);
Roland Dreier1a855fbf2008-04-16 21:01:09 -070065static void nes_nic_napi_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq);
66static void nes_process_aeq(struct nes_device *nesdev, struct nes_hw_aeq *aeq);
67static void nes_process_ceq(struct nes_device *nesdev, struct nes_hw_ceq *ceq);
68static void nes_process_iwarp_aeqe(struct nes_device *nesdev,
69 struct nes_hw_aeqe *aeqe);
70static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number);
71static unsigned int nes_reset_adapter_ne020(struct nes_device *nesdev, u8 *OneG_Mode);
Glenn Streiff3c2d7742008-02-04 20:20:45 -080072
73#ifdef CONFIG_INFINIBAND_NES_DEBUG
74static unsigned char *nes_iwarp_state_str[] = {
75 "Non-Existant",
76 "Idle",
77 "RTS",
78 "Closing",
79 "RSVD1",
80 "Terminate",
81 "Error",
82 "RSVD2",
83};
84
85static unsigned char *nes_tcp_state_str[] = {
86 "Non-Existant",
87 "Closed",
88 "Listen",
89 "SYN Sent",
90 "SYN Rcvd",
91 "Established",
92 "Close Wait",
93 "FIN Wait 1",
94 "Closing",
95 "Last Ack",
96 "FIN Wait 2",
97 "Time Wait",
98 "RSVD1",
99 "RSVD2",
100 "RSVD3",
101 "RSVD4",
102};
103#endif
104
105
106/**
107 * nes_nic_init_timer_defaults
108 */
109void nes_nic_init_timer_defaults(struct nes_device *nesdev, u8 jumbomode)
110{
111 unsigned long flags;
112 struct nes_adapter *nesadapter = nesdev->nesadapter;
113 struct nes_hw_tune_timer *shared_timer = &nesadapter->tune_timer;
114
115 spin_lock_irqsave(&nesadapter->periodic_timer_lock, flags);
116
117 shared_timer->timer_in_use_min = NES_NIC_FAST_TIMER_LOW;
118 shared_timer->timer_in_use_max = NES_NIC_FAST_TIMER_HIGH;
119 if (jumbomode) {
120 shared_timer->threshold_low = DEFAULT_JUMBO_NES_QL_LOW;
121 shared_timer->threshold_target = DEFAULT_JUMBO_NES_QL_TARGET;
122 shared_timer->threshold_high = DEFAULT_JUMBO_NES_QL_HIGH;
123 } else {
124 shared_timer->threshold_low = DEFAULT_NES_QL_LOW;
125 shared_timer->threshold_target = DEFAULT_NES_QL_TARGET;
126 shared_timer->threshold_high = DEFAULT_NES_QL_HIGH;
127 }
128
129 /* todo use netdev->mtu to set thresholds */
130 spin_unlock_irqrestore(&nesadapter->periodic_timer_lock, flags);
131}
132
133
134/**
135 * nes_nic_init_timer
136 */
137static void nes_nic_init_timer(struct nes_device *nesdev)
138{
139 unsigned long flags;
140 struct nes_adapter *nesadapter = nesdev->nesadapter;
141 struct nes_hw_tune_timer *shared_timer = &nesadapter->tune_timer;
142
143 spin_lock_irqsave(&nesadapter->periodic_timer_lock, flags);
144
145 if (shared_timer->timer_in_use_old == 0) {
146 nesdev->deepcq_count = 0;
147 shared_timer->timer_direction_upward = 0;
148 shared_timer->timer_direction_downward = 0;
149 shared_timer->timer_in_use = NES_NIC_FAST_TIMER;
150 shared_timer->timer_in_use_old = 0;
151
152 }
153 if (shared_timer->timer_in_use != shared_timer->timer_in_use_old) {
154 shared_timer->timer_in_use_old = shared_timer->timer_in_use;
155 nes_write32(nesdev->regs+NES_PERIODIC_CONTROL,
156 0x80000000 | ((u32)(shared_timer->timer_in_use*8)));
157 }
158 /* todo use netdev->mtu to set thresholds */
159 spin_unlock_irqrestore(&nesadapter->periodic_timer_lock, flags);
160}
161
162
163/**
164 * nes_nic_tune_timer
165 */
166static void nes_nic_tune_timer(struct nes_device *nesdev)
167{
168 unsigned long flags;
169 struct nes_adapter *nesadapter = nesdev->nesadapter;
170 struct nes_hw_tune_timer *shared_timer = &nesadapter->tune_timer;
171 u16 cq_count = nesdev->currcq_count;
172
173 spin_lock_irqsave(&nesadapter->periodic_timer_lock, flags);
174
John Lacombe4b1cc7e2008-02-21 08:34:58 -0600175 if (shared_timer->cq_count_old <= cq_count)
176 shared_timer->cq_direction_downward = 0;
177 else
Glenn Streiff3c2d7742008-02-04 20:20:45 -0800178 shared_timer->cq_direction_downward++;
179 shared_timer->cq_count_old = cq_count;
180 if (shared_timer->cq_direction_downward > NES_NIC_CQ_DOWNWARD_TREND) {
John Lacombe4b1cc7e2008-02-21 08:34:58 -0600181 if (cq_count <= shared_timer->threshold_low &&
182 shared_timer->threshold_low > 4) {
Glenn Streiff3c2d7742008-02-04 20:20:45 -0800183 shared_timer->threshold_low = shared_timer->threshold_low/2;
184 shared_timer->cq_direction_downward=0;
185 nesdev->currcq_count = 0;
186 spin_unlock_irqrestore(&nesadapter->periodic_timer_lock, flags);
187 return;
188 }
189 }
190
191 if (cq_count > 1) {
192 nesdev->deepcq_count += cq_count;
193 if (cq_count <= shared_timer->threshold_low) { /* increase timer gently */
194 shared_timer->timer_direction_upward++;
195 shared_timer->timer_direction_downward = 0;
196 } else if (cq_count <= shared_timer->threshold_target) { /* balanced */
197 shared_timer->timer_direction_upward = 0;
198 shared_timer->timer_direction_downward = 0;
199 } else if (cq_count <= shared_timer->threshold_high) { /* decrease timer gently */
200 shared_timer->timer_direction_downward++;
201 shared_timer->timer_direction_upward = 0;
202 } else if (cq_count <= (shared_timer->threshold_high) * 2) {
203 shared_timer->timer_in_use -= 2;
204 shared_timer->timer_direction_upward = 0;
205 shared_timer->timer_direction_downward++;
206 } else {
207 shared_timer->timer_in_use -= 4;
208 shared_timer->timer_direction_upward = 0;
209 shared_timer->timer_direction_downward++;
210 }
211
212 if (shared_timer->timer_direction_upward > 3 ) { /* using history */
213 shared_timer->timer_in_use += 3;
214 shared_timer->timer_direction_upward = 0;
215 shared_timer->timer_direction_downward = 0;
216 }
217 if (shared_timer->timer_direction_downward > 5) { /* using history */
218 shared_timer->timer_in_use -= 4 ;
219 shared_timer->timer_direction_downward = 0;
220 shared_timer->timer_direction_upward = 0;
221 }
222 }
223
224 /* boundary checking */
225 if (shared_timer->timer_in_use > NES_NIC_FAST_TIMER_HIGH)
226 shared_timer->timer_in_use = NES_NIC_FAST_TIMER_HIGH;
227 else if (shared_timer->timer_in_use < NES_NIC_FAST_TIMER_LOW) {
228 shared_timer->timer_in_use = NES_NIC_FAST_TIMER_LOW;
229 }
230
231 nesdev->currcq_count = 0;
232
233 spin_unlock_irqrestore(&nesadapter->periodic_timer_lock, flags);
234}
235
236
237/**
238 * nes_init_adapter - initialize adapter
239 */
240struct nes_adapter *nes_init_adapter(struct nes_device *nesdev, u8 hw_rev) {
241 struct nes_adapter *nesadapter = NULL;
242 unsigned long num_pds;
243 u32 u32temp;
244 u32 port_count;
245 u16 max_rq_wrs;
246 u16 max_sq_wrs;
247 u32 max_mr;
248 u32 max_256pbl;
249 u32 max_4kpbl;
250 u32 max_qp;
251 u32 max_irrq;
252 u32 max_cq;
253 u32 hte_index_mask;
254 u32 adapter_size;
255 u32 arp_table_size;
256 u16 vendor_id;
257 u8 OneG_Mode;
258 u8 func_index;
259
260 /* search the list of existing adapters */
261 list_for_each_entry(nesadapter, &nes_adapter_list, list) {
262 nes_debug(NES_DBG_INIT, "Searching Adapter list for PCI devfn = 0x%X,"
263 " adapter PCI slot/bus = %u/%u, pci devices PCI slot/bus = %u/%u, .\n",
264 nesdev->pcidev->devfn,
265 PCI_SLOT(nesadapter->devfn),
266 nesadapter->bus_number,
267 PCI_SLOT(nesdev->pcidev->devfn),
268 nesdev->pcidev->bus->number );
269 if ((PCI_SLOT(nesadapter->devfn) == PCI_SLOT(nesdev->pcidev->devfn)) &&
270 (nesadapter->bus_number == nesdev->pcidev->bus->number)) {
271 nesadapter->ref_count++;
272 return nesadapter;
273 }
274 }
275
276 /* no adapter found */
277 num_pds = pci_resource_len(nesdev->pcidev, BAR_1) >> PAGE_SHIFT;
278 if ((hw_rev != NE020_REV) && (hw_rev != NE020_REV1)) {
279 nes_debug(NES_DBG_INIT, "NE020 driver detected unknown hardware revision 0x%x\n",
280 hw_rev);
281 return NULL;
282 }
283
284 nes_debug(NES_DBG_INIT, "Determine Soft Reset, QP_control=0x%x, CPU0=0x%x, CPU1=0x%x, CPU2=0x%x\n",
285 nes_read_indexed(nesdev, NES_IDX_QP_CONTROL + PCI_FUNC(nesdev->pcidev->devfn) * 8),
286 nes_read_indexed(nesdev, NES_IDX_INT_CPU_STATUS),
287 nes_read_indexed(nesdev, NES_IDX_INT_CPU_STATUS + 4),
288 nes_read_indexed(nesdev, NES_IDX_INT_CPU_STATUS + 8));
289
290 nes_debug(NES_DBG_INIT, "Reset and init NE020\n");
291
292
293 if ((port_count = nes_reset_adapter_ne020(nesdev, &OneG_Mode)) == 0)
294 return NULL;
Glenn Streiff3c2d7742008-02-04 20:20:45 -0800295
296 max_qp = nes_read_indexed(nesdev, NES_IDX_QP_CTX_SIZE);
297 nes_debug(NES_DBG_INIT, "QP_CTX_SIZE=%u\n", max_qp);
298
299 u32temp = nes_read_indexed(nesdev, NES_IDX_QUAD_HASH_TABLE_SIZE);
300 if (max_qp > ((u32)1 << (u32temp & 0x001f))) {
301 nes_debug(NES_DBG_INIT, "Reducing Max QPs to %u due to hash table size = 0x%08X\n",
302 max_qp, u32temp);
303 max_qp = (u32)1 << (u32temp & 0x001f);
304 }
305
306 hte_index_mask = ((u32)1 << ((u32temp & 0x001f)+1))-1;
307 nes_debug(NES_DBG_INIT, "Max QP = %u, hte_index_mask = 0x%08X.\n",
308 max_qp, hte_index_mask);
309
310 u32temp = nes_read_indexed(nesdev, NES_IDX_IRRQ_COUNT);
311
312 max_irrq = 1 << (u32temp & 0x001f);
313
314 if (max_qp > max_irrq) {
315 max_qp = max_irrq;
316 nes_debug(NES_DBG_INIT, "Reducing Max QPs to %u due to Available Q1s.\n",
317 max_qp);
318 }
319
320 /* there should be no reason to allocate more pds than qps */
321 if (num_pds > max_qp)
322 num_pds = max_qp;
323
324 u32temp = nes_read_indexed(nesdev, NES_IDX_MRT_SIZE);
325 max_mr = (u32)8192 << (u32temp & 0x7);
326
327 u32temp = nes_read_indexed(nesdev, NES_IDX_PBL_REGION_SIZE);
328 max_256pbl = (u32)1 << (u32temp & 0x0000001f);
329 max_4kpbl = (u32)1 << ((u32temp >> 16) & 0x0000001f);
330 max_cq = nes_read_indexed(nesdev, NES_IDX_CQ_CTX_SIZE);
331
332 u32temp = nes_read_indexed(nesdev, NES_IDX_ARP_CACHE_SIZE);
333 arp_table_size = 1 << u32temp;
334
335 adapter_size = (sizeof(struct nes_adapter) +
336 (sizeof(unsigned long)-1)) & (~(sizeof(unsigned long)-1));
337 adapter_size += sizeof(unsigned long) * BITS_TO_LONGS(max_qp);
338 adapter_size += sizeof(unsigned long) * BITS_TO_LONGS(max_mr);
339 adapter_size += sizeof(unsigned long) * BITS_TO_LONGS(max_cq);
340 adapter_size += sizeof(unsigned long) * BITS_TO_LONGS(num_pds);
341 adapter_size += sizeof(unsigned long) * BITS_TO_LONGS(arp_table_size);
342 adapter_size += sizeof(struct nes_qp **) * max_qp;
343
344 /* allocate a new adapter struct */
345 nesadapter = kzalloc(adapter_size, GFP_KERNEL);
346 if (nesadapter == NULL) {
347 return NULL;
348 }
349
350 nes_debug(NES_DBG_INIT, "Allocating new nesadapter @ %p, size = %u (actual size = %u).\n",
351 nesadapter, (u32)sizeof(struct nes_adapter), adapter_size);
352
Chien Tungfcb7ad32008-09-30 14:49:44 -0700353 if (nes_read_eeprom_values(nesdev, nesadapter)) {
354 printk(KERN_ERR PFX "Unable to read EEPROM data.\n");
355 kfree(nesadapter);
356 return NULL;
357 }
358
359 if (nes_init_serdes(nesdev, hw_rev, port_count, nesadapter,
360 OneG_Mode)) {
361 kfree(nesadapter);
362 return NULL;
363 }
364 nes_init_csr_ne020(nesdev, hw_rev, port_count);
365
Glenn Streiff3c2d7742008-02-04 20:20:45 -0800366 /* populate the new nesadapter */
367 nesadapter->devfn = nesdev->pcidev->devfn;
368 nesadapter->bus_number = nesdev->pcidev->bus->number;
369 nesadapter->ref_count = 1;
370 nesadapter->timer_int_req = 0xffff0000;
371 nesadapter->OneG_Mode = OneG_Mode;
372 nesadapter->doorbell_start = nesdev->doorbell_region;
373
374 /* nesadapter->tick_delta = clk_divisor; */
375 nesadapter->hw_rev = hw_rev;
376 nesadapter->port_count = port_count;
377
378 nesadapter->max_qp = max_qp;
379 nesadapter->hte_index_mask = hte_index_mask;
380 nesadapter->max_irrq = max_irrq;
381 nesadapter->max_mr = max_mr;
382 nesadapter->max_256pbl = max_256pbl - 1;
383 nesadapter->max_4kpbl = max_4kpbl - 1;
384 nesadapter->max_cq = max_cq;
385 nesadapter->free_256pbl = max_256pbl - 1;
386 nesadapter->free_4kpbl = max_4kpbl - 1;
387 nesadapter->max_pd = num_pds;
388 nesadapter->arp_table_size = arp_table_size;
389
390 nesadapter->et_pkt_rate_low = NES_TIMER_ENABLE_LIMIT;
391 if (nes_drv_opt & NES_DRV_OPT_DISABLE_INT_MOD) {
392 nesadapter->et_use_adaptive_rx_coalesce = 0;
393 nesadapter->timer_int_limit = NES_TIMER_INT_LIMIT;
394 nesadapter->et_rx_coalesce_usecs_irq = interrupt_mod_interval;
395 } else {
396 nesadapter->et_use_adaptive_rx_coalesce = 1;
397 nesadapter->timer_int_limit = NES_TIMER_INT_LIMIT_DYNAMIC;
398 nesadapter->et_rx_coalesce_usecs_irq = 0;
Harvey Harrison33718362008-04-16 21:01:10 -0700399 printk(PFX "%s: Using Adaptive Interrupt Moderation\n", __func__);
Glenn Streiff3c2d7742008-02-04 20:20:45 -0800400 }
401 /* Setup and enable the periodic timer */
402 if (nesadapter->et_rx_coalesce_usecs_irq)
403 nes_write32(nesdev->regs+NES_PERIODIC_CONTROL, 0x80000000 |
404 ((u32)(nesadapter->et_rx_coalesce_usecs_irq * 8)));
405 else
406 nes_write32(nesdev->regs+NES_PERIODIC_CONTROL, 0x00000000);
407
408 nesadapter->base_pd = 1;
409
410 nesadapter->device_cap_flags =
Steve Wise96f15c02008-07-14 23:48:53 -0700411 IB_DEVICE_LOCAL_DMA_LKEY | IB_DEVICE_MEM_WINDOW;
Glenn Streiff3c2d7742008-02-04 20:20:45 -0800412
413 nesadapter->allocated_qps = (unsigned long *)&(((unsigned char *)nesadapter)
414 [(sizeof(struct nes_adapter)+(sizeof(unsigned long)-1))&(~(sizeof(unsigned long)-1))]);
415 nesadapter->allocated_cqs = &nesadapter->allocated_qps[BITS_TO_LONGS(max_qp)];
416 nesadapter->allocated_mrs = &nesadapter->allocated_cqs[BITS_TO_LONGS(max_cq)];
417 nesadapter->allocated_pds = &nesadapter->allocated_mrs[BITS_TO_LONGS(max_mr)];
418 nesadapter->allocated_arps = &nesadapter->allocated_pds[BITS_TO_LONGS(num_pds)];
419 nesadapter->qp_table = (struct nes_qp **)(&nesadapter->allocated_arps[BITS_TO_LONGS(arp_table_size)]);
420
421
422 /* mark the usual suspect QPs and CQs as in use */
423 for (u32temp = 0; u32temp < NES_FIRST_QPN; u32temp++) {
424 set_bit(u32temp, nesadapter->allocated_qps);
425 set_bit(u32temp, nesadapter->allocated_cqs);
426 }
427
428 for (u32temp = 0; u32temp < 20; u32temp++)
429 set_bit(u32temp, nesadapter->allocated_pds);
430 u32temp = nes_read_indexed(nesdev, NES_IDX_QP_MAX_CFG_SIZES);
431
432 max_rq_wrs = ((u32temp >> 8) & 3);
433 switch (max_rq_wrs) {
434 case 0:
435 max_rq_wrs = 4;
436 break;
437 case 1:
438 max_rq_wrs = 16;
439 break;
440 case 2:
441 max_rq_wrs = 32;
442 break;
443 case 3:
444 max_rq_wrs = 512;
445 break;
446 }
447
448 max_sq_wrs = (u32temp & 3);
449 switch (max_sq_wrs) {
450 case 0:
451 max_sq_wrs = 4;
452 break;
453 case 1:
454 max_sq_wrs = 16;
455 break;
456 case 2:
457 max_sq_wrs = 32;
458 break;
459 case 3:
460 max_sq_wrs = 512;
461 break;
462 }
463 nesadapter->max_qp_wr = min(max_rq_wrs, max_sq_wrs);
464 nesadapter->max_irrq_wr = (u32temp >> 16) & 3;
465
466 nesadapter->max_sge = 4;
467 nesadapter->max_cqe = 32767;
468
469 if (nes_read_eeprom_values(nesdev, nesadapter)) {
470 printk(KERN_ERR PFX "Unable to read EEPROM data.\n");
471 kfree(nesadapter);
472 return NULL;
473 }
474
475 u32temp = nes_read_indexed(nesdev, NES_IDX_TCP_TIMER_CONFIG);
476 nes_write_indexed(nesdev, NES_IDX_TCP_TIMER_CONFIG,
477 (u32temp & 0xff000000) | (nesadapter->tcp_timer_core_clk_divisor & 0x00ffffff));
478
479 /* setup port configuration */
480 if (nesadapter->port_count == 1) {
Chien Tungfcb7ad32008-09-30 14:49:44 -0700481 nesadapter->log_port = 0x00000000;
Glenn Streiff3c2d7742008-02-04 20:20:45 -0800482 if (nes_drv_opt & NES_DRV_OPT_DUAL_LOGICAL_PORT)
483 nes_write_indexed(nesdev, NES_IDX_TX_POOL_SIZE, 0x00000002);
484 else
485 nes_write_indexed(nesdev, NES_IDX_TX_POOL_SIZE, 0x00000003);
486 } else {
Chien Tungfcb7ad32008-09-30 14:49:44 -0700487 if (nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G) {
488 nesadapter->log_port = 0x000000D8;
489 } else {
490 if (nesadapter->port_count == 2)
491 nesadapter->log_port = 0x00000044;
492 else
493 nesadapter->log_port = 0x000000e4;
494 }
Glenn Streiff3c2d7742008-02-04 20:20:45 -0800495 nes_write_indexed(nesdev, NES_IDX_TX_POOL_SIZE, 0x00000003);
496 }
497
Chien Tungfcb7ad32008-09-30 14:49:44 -0700498 nes_write_indexed(nesdev, NES_IDX_NIC_LOGPORT_TO_PHYPORT,
499 nesadapter->log_port);
Glenn Streiff3c2d7742008-02-04 20:20:45 -0800500 nes_debug(NES_DBG_INIT, "Probe time, LOG2PHY=%u\n",
501 nes_read_indexed(nesdev, NES_IDX_NIC_LOGPORT_TO_PHYPORT));
502
503 spin_lock_init(&nesadapter->resource_lock);
504 spin_lock_init(&nesadapter->phy_lock);
505 spin_lock_init(&nesadapter->pbl_lock);
506 spin_lock_init(&nesadapter->periodic_timer_lock);
507
508 INIT_LIST_HEAD(&nesadapter->nesvnic_list[0]);
509 INIT_LIST_HEAD(&nesadapter->nesvnic_list[1]);
510 INIT_LIST_HEAD(&nesadapter->nesvnic_list[2]);
511 INIT_LIST_HEAD(&nesadapter->nesvnic_list[3]);
512
513 if ((!nesadapter->OneG_Mode) && (nesadapter->port_count == 2)) {
514 u32 pcs_control_status0, pcs_control_status1;
515 u32 reset_value;
516 u32 i = 0;
517 u32 int_cnt = 0;
518 u32 ext_cnt = 0;
519 unsigned long flags;
520 u32 j = 0;
521
522 pcs_control_status0 = nes_read_indexed(nesdev,
523 NES_IDX_PHY_PCS_CONTROL_STATUS0);
524 pcs_control_status1 = nes_read_indexed(nesdev,
525 NES_IDX_PHY_PCS_CONTROL_STATUS0 + 0x200);
526
527 for (i = 0; i < NES_MAX_LINK_CHECK; i++) {
528 pcs_control_status0 = nes_read_indexed(nesdev,
529 NES_IDX_PHY_PCS_CONTROL_STATUS0);
530 pcs_control_status1 = nes_read_indexed(nesdev,
531 NES_IDX_PHY_PCS_CONTROL_STATUS0 + 0x200);
532 if ((0x0F000100 == (pcs_control_status0 & 0x0F000100))
533 || (0x0F000100 == (pcs_control_status1 & 0x0F000100)))
534 int_cnt++;
535 msleep(1);
536 }
537 if (int_cnt > 1) {
538 spin_lock_irqsave(&nesadapter->phy_lock, flags);
539 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, 0x0000F088);
540 mh_detected++;
541 reset_value = nes_read32(nesdev->regs+NES_SOFTWARE_RESET);
542 reset_value |= 0x0000003d;
543 nes_write32(nesdev->regs+NES_SOFTWARE_RESET, reset_value);
544
545 while (((nes_read32(nesdev->regs+NES_SOFTWARE_RESET)
546 & 0x00000040) != 0x00000040) && (j++ < 5000));
547 spin_unlock_irqrestore(&nesadapter->phy_lock, flags);
548
549 pcs_control_status0 = nes_read_indexed(nesdev,
550 NES_IDX_PHY_PCS_CONTROL_STATUS0);
551 pcs_control_status1 = nes_read_indexed(nesdev,
552 NES_IDX_PHY_PCS_CONTROL_STATUS0 + 0x200);
553
554 for (i = 0; i < NES_MAX_LINK_CHECK; i++) {
555 pcs_control_status0 = nes_read_indexed(nesdev,
556 NES_IDX_PHY_PCS_CONTROL_STATUS0);
557 pcs_control_status1 = nes_read_indexed(nesdev,
558 NES_IDX_PHY_PCS_CONTROL_STATUS0 + 0x200);
559 if ((0x0F000100 == (pcs_control_status0 & 0x0F000100))
560 || (0x0F000100 == (pcs_control_status1 & 0x0F000100))) {
561 if (++ext_cnt > int_cnt) {
562 spin_lock_irqsave(&nesadapter->phy_lock, flags);
563 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1,
564 0x0000F0C8);
565 mh_detected++;
566 reset_value = nes_read32(nesdev->regs+NES_SOFTWARE_RESET);
567 reset_value |= 0x0000003d;
568 nes_write32(nesdev->regs+NES_SOFTWARE_RESET, reset_value);
569
570 while (((nes_read32(nesdev->regs+NES_SOFTWARE_RESET)
571 & 0x00000040) != 0x00000040) && (j++ < 5000));
572 spin_unlock_irqrestore(&nesadapter->phy_lock, flags);
573 break;
574 }
575 }
576 msleep(1);
577 }
578 }
579 }
580
581 if (nesadapter->hw_rev == NE020_REV) {
582 init_timer(&nesadapter->mh_timer);
583 nesadapter->mh_timer.function = nes_mh_fix;
584 nesadapter->mh_timer.expires = jiffies + (HZ/5); /* 1 second */
585 nesadapter->mh_timer.data = (unsigned long)nesdev;
586 add_timer(&nesadapter->mh_timer);
587 } else {
588 nes_write32(nesdev->regs+NES_INTF_INT_STAT, 0x0f000000);
589 }
590
591 init_timer(&nesadapter->lc_timer);
592 nesadapter->lc_timer.function = nes_clc;
593 nesadapter->lc_timer.expires = jiffies + 3600 * HZ; /* 1 hour */
594 nesadapter->lc_timer.data = (unsigned long)nesdev;
595 add_timer(&nesadapter->lc_timer);
596
597 list_add_tail(&nesadapter->list, &nes_adapter_list);
598
599 for (func_index = 0; func_index < 8; func_index++) {
600 pci_bus_read_config_word(nesdev->pcidev->bus,
601 PCI_DEVFN(PCI_SLOT(nesdev->pcidev->devfn),
602 func_index), 0, &vendor_id);
603 if (vendor_id == 0xffff)
604 break;
605 }
Harvey Harrison33718362008-04-16 21:01:10 -0700606 nes_debug(NES_DBG_INIT, "%s %d functions found for %s.\n", __func__,
Glenn Streiff3c2d7742008-02-04 20:20:45 -0800607 func_index, pci_name(nesdev->pcidev));
608 nesadapter->adapter_fcn_count = func_index;
609
610 return nesadapter;
611}
612
613
614/**
615 * nes_reset_adapter_ne020
616 */
Roland Dreier1a855fbf2008-04-16 21:01:09 -0700617static unsigned int nes_reset_adapter_ne020(struct nes_device *nesdev, u8 *OneG_Mode)
Glenn Streiff3c2d7742008-02-04 20:20:45 -0800618{
619 u32 port_count;
620 u32 u32temp;
621 u32 i;
622
623 u32temp = nes_read32(nesdev->regs+NES_SOFTWARE_RESET);
624 port_count = ((u32temp & 0x00000300) >> 8) + 1;
625 /* TODO: assuming that both SERDES are set the same for now */
626 *OneG_Mode = (u32temp & 0x00003c00) ? 0 : 1;
627 nes_debug(NES_DBG_INIT, "Initial Software Reset = 0x%08X, port_count=%u\n",
628 u32temp, port_count);
629 if (*OneG_Mode)
630 nes_debug(NES_DBG_INIT, "Running in 1G mode.\n");
631 u32temp &= 0xff00ffc0;
632 switch (port_count) {
633 case 1:
634 u32temp |= 0x00ee0000;
635 break;
636 case 2:
637 u32temp |= 0x00cc0000;
638 break;
639 case 4:
640 u32temp |= 0x00000000;
641 break;
642 default:
643 return 0;
644 break;
645 }
646
647 /* check and do full reset if needed */
648 if (nes_read_indexed(nesdev, NES_IDX_QP_CONTROL+(PCI_FUNC(nesdev->pcidev->devfn)*8))) {
649 nes_debug(NES_DBG_INIT, "Issuing Full Soft reset = 0x%08X\n", u32temp | 0xd);
650 nes_write32(nesdev->regs+NES_SOFTWARE_RESET, u32temp | 0xd);
651
652 i = 0;
653 while (((nes_read32(nesdev->regs+NES_SOFTWARE_RESET) & 0x00000040) == 0) && i++ < 10000)
654 mdelay(1);
655 if (i >= 10000) {
656 nes_debug(NES_DBG_INIT, "Did not see full soft reset done.\n");
657 return 0;
658 }
Chien Tungbc5698f32008-04-23 11:55:45 -0700659
660 i = 0;
661 while ((nes_read_indexed(nesdev, NES_IDX_INT_CPU_STATUS) != 0x80) && i++ < 10000)
662 mdelay(1);
663 if (i >= 10000) {
664 printk(KERN_ERR PFX "Internal CPU not ready, status = %02X\n",
665 nes_read_indexed(nesdev, NES_IDX_INT_CPU_STATUS));
666 return 0;
667 }
Glenn Streiff3c2d7742008-02-04 20:20:45 -0800668 }
669
670 /* port reset */
671 switch (port_count) {
672 case 1:
673 u32temp |= 0x00ee0010;
674 break;
675 case 2:
676 u32temp |= 0x00cc0030;
677 break;
678 case 4:
679 u32temp |= 0x00000030;
680 break;
681 }
682
683 nes_debug(NES_DBG_INIT, "Issuing Port Soft reset = 0x%08X\n", u32temp | 0xd);
684 nes_write32(nesdev->regs+NES_SOFTWARE_RESET, u32temp | 0xd);
685
686 i = 0;
687 while (((nes_read32(nesdev->regs+NES_SOFTWARE_RESET) & 0x00000040) == 0) && i++ < 10000)
688 mdelay(1);
689 if (i >= 10000) {
690 nes_debug(NES_DBG_INIT, "Did not see port soft reset done.\n");
691 return 0;
692 }
693
694 /* serdes 0 */
695 i = 0;
696 while (((u32temp = (nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_STATUS0)
697 & 0x0000000f)) != 0x0000000f) && i++ < 5000)
698 mdelay(1);
699 if (i >= 5000) {
700 nes_debug(NES_DBG_INIT, "Serdes 0 not ready, status=%x\n", u32temp);
701 return 0;
702 }
703
704 /* serdes 1 */
705 if (port_count > 1) {
706 i = 0;
707 while (((u32temp = (nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_STATUS1)
708 & 0x0000000f)) != 0x0000000f) && i++ < 5000)
709 mdelay(1);
710 if (i >= 5000) {
711 nes_debug(NES_DBG_INIT, "Serdes 1 not ready, status=%x\n", u32temp);
712 return 0;
713 }
714 }
715
Glenn Streiff3c2d7742008-02-04 20:20:45 -0800716 return port_count;
717}
718
719
720/**
721 * nes_init_serdes
722 */
Roland Dreier1a855fbf2008-04-16 21:01:09 -0700723static int nes_init_serdes(struct nes_device *nesdev, u8 hw_rev, u8 port_count,
Chien Tungfcb7ad32008-09-30 14:49:44 -0700724 struct nes_adapter *nesadapter, u8 OneG_Mode)
Glenn Streiff3c2d7742008-02-04 20:20:45 -0800725{
726 int i;
727 u32 u32temp;
Chien Tungfcb7ad32008-09-30 14:49:44 -0700728 u32 serdes_common_control;
Glenn Streiff3c2d7742008-02-04 20:20:45 -0800729
730 if (hw_rev != NE020_REV) {
731 /* init serdes 0 */
732
733 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000000FF);
Chien Tungfcb7ad32008-09-30 14:49:44 -0700734 if (nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G) {
735 serdes_common_control = nes_read_indexed(nesdev,
736 NES_IDX_ETH_SERDES_COMMON_CONTROL0);
737 serdes_common_control |= 0x000000100;
738 nes_write_indexed(nesdev,
739 NES_IDX_ETH_SERDES_COMMON_CONTROL0,
740 serdes_common_control);
741 } else if (!OneG_Mode) {
Glenn Streiff3c2d7742008-02-04 20:20:45 -0800742 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_HIGHZ_LANE_MODE0, 0x11110000);
Chien Tungfcb7ad32008-09-30 14:49:44 -0700743 }
744 if (((port_count > 1) &&
745 (nesadapter->phy_type[0] != NES_PHY_TYPE_PUMA_1G)) ||
746 ((port_count > 2) &&
747 (nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G))) {
Glenn Streiff3c2d7742008-02-04 20:20:45 -0800748 /* init serdes 1 */
749 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL1, 0x000000FF);
Chien Tungfcb7ad32008-09-30 14:49:44 -0700750 if (nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G) {
751 serdes_common_control = nes_read_indexed(nesdev,
752 NES_IDX_ETH_SERDES_COMMON_CONTROL1);
753 serdes_common_control |= 0x000000100;
754 nes_write_indexed(nesdev,
755 NES_IDX_ETH_SERDES_COMMON_CONTROL1,
756 serdes_common_control);
757 } else if (!OneG_Mode) {
Glenn Streiff3c2d7742008-02-04 20:20:45 -0800758 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_HIGHZ_LANE_MODE1, 0x11110000);
759 }
Chien Tungfcb7ad32008-09-30 14:49:44 -0700760 }
Glenn Streiff3c2d7742008-02-04 20:20:45 -0800761 } else {
762 /* init serdes 0 */
763 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, 0x00000008);
764 i = 0;
765 while (((u32temp = (nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_STATUS0)
766 & 0x0000000f)) != 0x0000000f) && i++ < 5000)
767 mdelay(1);
768 if (i >= 5000) {
769 nes_debug(NES_DBG_PHY, "Init: serdes 0 not ready, status=%x\n", u32temp);
770 return 1;
771 }
772 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_EMP0, 0x000bdef7);
773 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_DRIVE0, 0x9ce73000);
774 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_RX_MODE0, 0x0ff00000);
775 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_RX_SIGDET0, 0x00000000);
776 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_BYPASS0, 0x00000000);
777 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_LOOPBACK_CONTROL0, 0x00000000);
778 if (OneG_Mode)
779 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_RX_EQ_CONTROL0, 0xf0182222);
780 else
781 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_RX_EQ_CONTROL0, 0xf0042222);
782
783 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000000ff);
784 if (port_count > 1) {
785 /* init serdes 1 */
786 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, 0x00000048);
787 i = 0;
788 while (((u32temp = (nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_STATUS1)
789 & 0x0000000f)) != 0x0000000f) && (i++ < 5000))
790 mdelay(1);
791 if (i >= 5000) {
Harvey Harrison33718362008-04-16 21:01:10 -0700792 printk("%s: Init: serdes 1 not ready, status=%x\n", __func__, u32temp);
Glenn Streiff3c2d7742008-02-04 20:20:45 -0800793 /* return 1; */
794 }
795 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_EMP1, 0x000bdef7);
796 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_DRIVE1, 0x9ce73000);
797 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_RX_MODE1, 0x0ff00000);
798 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_RX_SIGDET1, 0x00000000);
799 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_BYPASS1, 0x00000000);
800 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_LOOPBACK_CONTROL1, 0x00000000);
801 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_RX_EQ_CONTROL1, 0xf0002222);
802 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL1, 0x000000ff);
803 }
804 }
805 return 0;
806}
807
808
809/**
810 * nes_init_csr_ne020
811 * Initialize registers for ne020 hardware
812 */
Roland Dreier1a855fbf2008-04-16 21:01:09 -0700813static void nes_init_csr_ne020(struct nes_device *nesdev, u8 hw_rev, u8 port_count)
Glenn Streiff3c2d7742008-02-04 20:20:45 -0800814{
815 u32 u32temp;
816
817 nes_debug(NES_DBG_INIT, "port_count=%d\n", port_count);
818
819 nes_write_indexed(nesdev, 0x000001E4, 0x00000007);
820 /* nes_write_indexed(nesdev, 0x000001E8, 0x000208C4); */
821 nes_write_indexed(nesdev, 0x000001E8, 0x00020874);
822 nes_write_indexed(nesdev, 0x000001D8, 0x00048002);
823 /* nes_write_indexed(nesdev, 0x000001D8, 0x0004B002); */
824 nes_write_indexed(nesdev, 0x000001FC, 0x00050005);
825 nes_write_indexed(nesdev, 0x00000600, 0x55555555);
826 nes_write_indexed(nesdev, 0x00000604, 0x55555555);
827
828 /* TODO: move these MAC register settings to NIC bringup */
829 nes_write_indexed(nesdev, 0x00002000, 0x00000001);
830 nes_write_indexed(nesdev, 0x00002004, 0x00000001);
831 nes_write_indexed(nesdev, 0x00002008, 0x0000FFFF);
832 nes_write_indexed(nesdev, 0x0000200C, 0x00000001);
833 nes_write_indexed(nesdev, 0x00002010, 0x000003c1);
834 nes_write_indexed(nesdev, 0x0000201C, 0x75345678);
835 if (port_count > 1) {
836 nes_write_indexed(nesdev, 0x00002200, 0x00000001);
837 nes_write_indexed(nesdev, 0x00002204, 0x00000001);
838 nes_write_indexed(nesdev, 0x00002208, 0x0000FFFF);
839 nes_write_indexed(nesdev, 0x0000220C, 0x00000001);
840 nes_write_indexed(nesdev, 0x00002210, 0x000003c1);
841 nes_write_indexed(nesdev, 0x0000221C, 0x75345678);
842 nes_write_indexed(nesdev, 0x00000908, 0x20000001);
843 }
844 if (port_count > 2) {
845 nes_write_indexed(nesdev, 0x00002400, 0x00000001);
846 nes_write_indexed(nesdev, 0x00002404, 0x00000001);
847 nes_write_indexed(nesdev, 0x00002408, 0x0000FFFF);
848 nes_write_indexed(nesdev, 0x0000240C, 0x00000001);
849 nes_write_indexed(nesdev, 0x00002410, 0x000003c1);
850 nes_write_indexed(nesdev, 0x0000241C, 0x75345678);
851 nes_write_indexed(nesdev, 0x00000910, 0x20000001);
852
853 nes_write_indexed(nesdev, 0x00002600, 0x00000001);
854 nes_write_indexed(nesdev, 0x00002604, 0x00000001);
855 nes_write_indexed(nesdev, 0x00002608, 0x0000FFFF);
856 nes_write_indexed(nesdev, 0x0000260C, 0x00000001);
857 nes_write_indexed(nesdev, 0x00002610, 0x000003c1);
858 nes_write_indexed(nesdev, 0x0000261C, 0x75345678);
859 nes_write_indexed(nesdev, 0x00000918, 0x20000001);
860 }
861
862 nes_write_indexed(nesdev, 0x00005000, 0x00018000);
863 /* nes_write_indexed(nesdev, 0x00005000, 0x00010000); */
Chien Tung2b537c22008-09-26 15:08:10 -0500864 nes_write_indexed(nesdev, NES_IDX_WQM_CONFIG1, (wqm_quanta << 1) |
865 0x00000001);
Glenn Streiff3c2d7742008-02-04 20:20:45 -0800866 nes_write_indexed(nesdev, 0x00005008, 0x1F1F1F1F);
867 nes_write_indexed(nesdev, 0x00005010, 0x1F1F1F1F);
868 nes_write_indexed(nesdev, 0x00005018, 0x1F1F1F1F);
869 nes_write_indexed(nesdev, 0x00005020, 0x1F1F1F1F);
870 nes_write_indexed(nesdev, 0x00006090, 0xFFFFFFFF);
871
872 /* TODO: move this to code, get from EEPROM */
873 nes_write_indexed(nesdev, 0x00000900, 0x20000001);
874 nes_write_indexed(nesdev, 0x000060C0, 0x0000028e);
875 nes_write_indexed(nesdev, 0x000060C8, 0x00000020);
Glenn Streiff7495ab62008-04-29 13:46:54 -0700876
Glenn Streiff3c2d7742008-02-04 20:20:45 -0800877 nes_write_indexed(nesdev, 0x000001EC, 0x7b2625a0);
878 /* nes_write_indexed(nesdev, 0x000001EC, 0x5f2625a0); */
879
880 if (hw_rev != NE020_REV) {
881 u32temp = nes_read_indexed(nesdev, 0x000008e8);
882 u32temp |= 0x80000000;
883 nes_write_indexed(nesdev, 0x000008e8, u32temp);
884 u32temp = nes_read_indexed(nesdev, 0x000021f8);
885 u32temp &= 0x7fffffff;
886 u32temp |= 0x7fff0010;
887 nes_write_indexed(nesdev, 0x000021f8, u32temp);
888 }
889}
890
891
892/**
893 * nes_destroy_adapter - destroy the adapter structure
894 */
895void nes_destroy_adapter(struct nes_adapter *nesadapter)
896{
897 struct nes_adapter *tmp_adapter;
898
899 list_for_each_entry(tmp_adapter, &nes_adapter_list, list) {
900 nes_debug(NES_DBG_SHUTDOWN, "Nes Adapter list entry = 0x%p.\n",
901 tmp_adapter);
902 }
903
904 nesadapter->ref_count--;
905 if (!nesadapter->ref_count) {
906 if (nesadapter->hw_rev == NE020_REV) {
907 del_timer(&nesadapter->mh_timer);
908 }
909 del_timer(&nesadapter->lc_timer);
910
911 list_del(&nesadapter->list);
912 kfree(nesadapter);
913 }
914}
915
916
917/**
918 * nes_init_cqp
919 */
920int nes_init_cqp(struct nes_device *nesdev)
921{
922 struct nes_adapter *nesadapter = nesdev->nesadapter;
923 struct nes_hw_cqp_qp_context *cqp_qp_context;
924 struct nes_hw_cqp_wqe *cqp_wqe;
925 struct nes_hw_ceq *ceq;
926 struct nes_hw_ceq *nic_ceq;
927 struct nes_hw_aeq *aeq;
928 void *vmem;
929 dma_addr_t pmem;
930 u32 count=0;
931 u32 cqp_head;
932 u64 u64temp;
933 u32 u32temp;
934
935 /* allocate CQP memory */
936 /* Need to add max_cq to the aeq size once cq overflow checking is added back */
937 /* SQ is 512 byte aligned, others are 256 byte aligned */
938 nesdev->cqp_mem_size = 512 +
939 (sizeof(struct nes_hw_cqp_wqe) * NES_CQP_SQ_SIZE) +
940 (sizeof(struct nes_hw_cqe) * NES_CCQ_SIZE) +
941 max(((u32)sizeof(struct nes_hw_ceqe) * NES_CCEQ_SIZE), (u32)256) +
942 max(((u32)sizeof(struct nes_hw_ceqe) * NES_NIC_CEQ_SIZE), (u32)256) +
943 (sizeof(struct nes_hw_aeqe) * nesadapter->max_qp) +
944 sizeof(struct nes_hw_cqp_qp_context);
945
946 nesdev->cqp_vbase = pci_alloc_consistent(nesdev->pcidev, nesdev->cqp_mem_size,
947 &nesdev->cqp_pbase);
948 if (!nesdev->cqp_vbase) {
949 nes_debug(NES_DBG_INIT, "Unable to allocate memory for host descriptor rings\n");
950 return -ENOMEM;
951 }
952 memset(nesdev->cqp_vbase, 0, nesdev->cqp_mem_size);
953
954 /* Allocate a twice the number of CQP requests as the SQ size */
955 nesdev->nes_cqp_requests = kzalloc(sizeof(struct nes_cqp_request) *
956 2 * NES_CQP_SQ_SIZE, GFP_KERNEL);
957 if (nesdev->nes_cqp_requests == NULL) {
958 nes_debug(NES_DBG_INIT, "Unable to allocate memory CQP request entries.\n");
959 pci_free_consistent(nesdev->pcidev, nesdev->cqp_mem_size, nesdev->cqp.sq_vbase,
960 nesdev->cqp.sq_pbase);
961 return -ENOMEM;
962 }
963
964 nes_debug(NES_DBG_INIT, "Allocated CQP structures at %p (phys = %016lX), size = %u.\n",
965 nesdev->cqp_vbase, (unsigned long)nesdev->cqp_pbase, nesdev->cqp_mem_size);
966
967 spin_lock_init(&nesdev->cqp.lock);
968 init_waitqueue_head(&nesdev->cqp.waitq);
969
970 /* Setup Various Structures */
971 vmem = (void *)(((unsigned long)nesdev->cqp_vbase + (512 - 1)) &
972 ~(unsigned long)(512 - 1));
973 pmem = (dma_addr_t)(((unsigned long long)nesdev->cqp_pbase + (512 - 1)) &
974 ~(unsigned long long)(512 - 1));
975
976 nesdev->cqp.sq_vbase = vmem;
977 nesdev->cqp.sq_pbase = pmem;
978 nesdev->cqp.sq_size = NES_CQP_SQ_SIZE;
979 nesdev->cqp.sq_head = 0;
980 nesdev->cqp.sq_tail = 0;
981 nesdev->cqp.qp_id = PCI_FUNC(nesdev->pcidev->devfn);
982
983 vmem += (sizeof(struct nes_hw_cqp_wqe) * nesdev->cqp.sq_size);
984 pmem += (sizeof(struct nes_hw_cqp_wqe) * nesdev->cqp.sq_size);
985
986 nesdev->ccq.cq_vbase = vmem;
987 nesdev->ccq.cq_pbase = pmem;
988 nesdev->ccq.cq_size = NES_CCQ_SIZE;
989 nesdev->ccq.cq_head = 0;
990 nesdev->ccq.ce_handler = nes_cqp_ce_handler;
991 nesdev->ccq.cq_number = PCI_FUNC(nesdev->pcidev->devfn);
992
993 vmem += (sizeof(struct nes_hw_cqe) * nesdev->ccq.cq_size);
994 pmem += (sizeof(struct nes_hw_cqe) * nesdev->ccq.cq_size);
995
996 nesdev->ceq_index = PCI_FUNC(nesdev->pcidev->devfn);
997 ceq = &nesadapter->ceq[nesdev->ceq_index];
998 ceq->ceq_vbase = vmem;
999 ceq->ceq_pbase = pmem;
1000 ceq->ceq_size = NES_CCEQ_SIZE;
1001 ceq->ceq_head = 0;
1002
1003 vmem += max(((u32)sizeof(struct nes_hw_ceqe) * ceq->ceq_size), (u32)256);
1004 pmem += max(((u32)sizeof(struct nes_hw_ceqe) * ceq->ceq_size), (u32)256);
1005
1006 nesdev->nic_ceq_index = PCI_FUNC(nesdev->pcidev->devfn) + 8;
1007 nic_ceq = &nesadapter->ceq[nesdev->nic_ceq_index];
1008 nic_ceq->ceq_vbase = vmem;
1009 nic_ceq->ceq_pbase = pmem;
1010 nic_ceq->ceq_size = NES_NIC_CEQ_SIZE;
1011 nic_ceq->ceq_head = 0;
1012
1013 vmem += max(((u32)sizeof(struct nes_hw_ceqe) * nic_ceq->ceq_size), (u32)256);
1014 pmem += max(((u32)sizeof(struct nes_hw_ceqe) * nic_ceq->ceq_size), (u32)256);
1015
1016 aeq = &nesadapter->aeq[PCI_FUNC(nesdev->pcidev->devfn)];
1017 aeq->aeq_vbase = vmem;
1018 aeq->aeq_pbase = pmem;
1019 aeq->aeq_size = nesadapter->max_qp;
1020 aeq->aeq_head = 0;
1021
1022 /* Setup QP Context */
1023 vmem += (sizeof(struct nes_hw_aeqe) * aeq->aeq_size);
1024 pmem += (sizeof(struct nes_hw_aeqe) * aeq->aeq_size);
1025
1026 cqp_qp_context = vmem;
1027 cqp_qp_context->context_words[0] =
1028 cpu_to_le32((PCI_FUNC(nesdev->pcidev->devfn) << 12) + (2 << 10));
1029 cqp_qp_context->context_words[1] = 0;
1030 cqp_qp_context->context_words[2] = cpu_to_le32((u32)nesdev->cqp.sq_pbase);
1031 cqp_qp_context->context_words[3] = cpu_to_le32(((u64)nesdev->cqp.sq_pbase) >> 32);
1032
1033
1034 /* Write the address to Create CQP */
1035 if ((sizeof(dma_addr_t) > 4)) {
1036 nes_write_indexed(nesdev,
1037 NES_IDX_CREATE_CQP_HIGH + (PCI_FUNC(nesdev->pcidev->devfn) * 8),
1038 ((u64)pmem) >> 32);
1039 } else {
1040 nes_write_indexed(nesdev,
1041 NES_IDX_CREATE_CQP_HIGH + (PCI_FUNC(nesdev->pcidev->devfn) * 8), 0);
1042 }
1043 nes_write_indexed(nesdev,
1044 NES_IDX_CREATE_CQP_LOW + (PCI_FUNC(nesdev->pcidev->devfn) * 8),
1045 (u32)pmem);
1046
1047 INIT_LIST_HEAD(&nesdev->cqp_avail_reqs);
1048 INIT_LIST_HEAD(&nesdev->cqp_pending_reqs);
1049
1050 for (count = 0; count < 2*NES_CQP_SQ_SIZE; count++) {
1051 init_waitqueue_head(&nesdev->nes_cqp_requests[count].waitq);
1052 list_add_tail(&nesdev->nes_cqp_requests[count].list, &nesdev->cqp_avail_reqs);
1053 }
1054
1055 /* Write Create CCQ WQE */
1056 cqp_head = nesdev->cqp.sq_head++;
1057 cqp_wqe = &nesdev->cqp.sq_vbase[cqp_head];
1058 nes_fill_init_cqp_wqe(cqp_wqe, nesdev);
1059 set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_OPCODE_IDX,
1060 (NES_CQP_CREATE_CQ | NES_CQP_CQ_CEQ_VALID |
1061 NES_CQP_CQ_CHK_OVERFLOW | ((u32)nesdev->ccq.cq_size << 16)));
1062 set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_ID_IDX,
1063 (nesdev->ccq.cq_number |
1064 ((u32)nesdev->ceq_index << 16)));
1065 u64temp = (u64)nesdev->ccq.cq_pbase;
1066 set_wqe_64bit_value(cqp_wqe->wqe_words, NES_CQP_CQ_WQE_PBL_LOW_IDX, u64temp);
1067 cqp_wqe->wqe_words[NES_CQP_CQ_WQE_CQ_CONTEXT_HIGH_IDX] = 0;
1068 u64temp = (unsigned long)&nesdev->ccq;
1069 cqp_wqe->wqe_words[NES_CQP_CQ_WQE_CQ_CONTEXT_LOW_IDX] =
1070 cpu_to_le32((u32)(u64temp >> 1));
1071 cqp_wqe->wqe_words[NES_CQP_CQ_WQE_CQ_CONTEXT_HIGH_IDX] =
1072 cpu_to_le32(((u32)((u64temp) >> 33)) & 0x7FFFFFFF);
1073 cqp_wqe->wqe_words[NES_CQP_CQ_WQE_DOORBELL_INDEX_HIGH_IDX] = 0;
1074
1075 /* Write Create CEQ WQE */
1076 cqp_head = nesdev->cqp.sq_head++;
1077 cqp_wqe = &nesdev->cqp.sq_vbase[cqp_head];
1078 nes_fill_init_cqp_wqe(cqp_wqe, nesdev);
1079 set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_OPCODE_IDX,
1080 (NES_CQP_CREATE_CEQ + ((u32)nesdev->ceq_index << 8)));
1081 set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_CEQ_WQE_ELEMENT_COUNT_IDX, ceq->ceq_size);
1082 u64temp = (u64)ceq->ceq_pbase;
1083 set_wqe_64bit_value(cqp_wqe->wqe_words, NES_CQP_CQ_WQE_PBL_LOW_IDX, u64temp);
1084
1085 /* Write Create AEQ WQE */
1086 cqp_head = nesdev->cqp.sq_head++;
1087 cqp_wqe = &nesdev->cqp.sq_vbase[cqp_head];
1088 nes_fill_init_cqp_wqe(cqp_wqe, nesdev);
1089 set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_OPCODE_IDX,
1090 (NES_CQP_CREATE_AEQ + ((u32)PCI_FUNC(nesdev->pcidev->devfn) << 8)));
1091 set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_AEQ_WQE_ELEMENT_COUNT_IDX, aeq->aeq_size);
1092 u64temp = (u64)aeq->aeq_pbase;
1093 set_wqe_64bit_value(cqp_wqe->wqe_words, NES_CQP_CQ_WQE_PBL_LOW_IDX, u64temp);
1094
1095 /* Write Create NIC CEQ WQE */
1096 cqp_head = nesdev->cqp.sq_head++;
1097 cqp_wqe = &nesdev->cqp.sq_vbase[cqp_head];
1098 nes_fill_init_cqp_wqe(cqp_wqe, nesdev);
1099 set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_OPCODE_IDX,
1100 (NES_CQP_CREATE_CEQ + ((u32)nesdev->nic_ceq_index << 8)));
1101 set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_CEQ_WQE_ELEMENT_COUNT_IDX, nic_ceq->ceq_size);
1102 u64temp = (u64)nic_ceq->ceq_pbase;
1103 set_wqe_64bit_value(cqp_wqe->wqe_words, NES_CQP_CQ_WQE_PBL_LOW_IDX, u64temp);
1104
1105 /* Poll until CCQP done */
1106 count = 0;
1107 do {
1108 if (count++ > 1000) {
1109 printk(KERN_ERR PFX "Error creating CQP\n");
1110 pci_free_consistent(nesdev->pcidev, nesdev->cqp_mem_size,
1111 nesdev->cqp_vbase, nesdev->cqp_pbase);
1112 return -1;
1113 }
1114 udelay(10);
1115 } while (!(nes_read_indexed(nesdev,
1116 NES_IDX_QP_CONTROL + (PCI_FUNC(nesdev->pcidev->devfn) * 8)) & (1 << 8)));
1117
1118 nes_debug(NES_DBG_INIT, "CQP Status = 0x%08X\n", nes_read_indexed(nesdev,
1119 NES_IDX_QP_CONTROL+(PCI_FUNC(nesdev->pcidev->devfn)*8)));
1120
1121 u32temp = 0x04800000;
1122 nes_write32(nesdev->regs+NES_WQE_ALLOC, u32temp | nesdev->cqp.qp_id);
1123
1124 /* wait for the CCQ, CEQ, and AEQ to get created */
1125 count = 0;
1126 do {
1127 if (count++ > 1000) {
1128 printk(KERN_ERR PFX "Error creating CCQ, CEQ, and AEQ\n");
1129 pci_free_consistent(nesdev->pcidev, nesdev->cqp_mem_size,
1130 nesdev->cqp_vbase, nesdev->cqp_pbase);
1131 return -1;
1132 }
1133 udelay(10);
1134 } while (((nes_read_indexed(nesdev,
1135 NES_IDX_QP_CONTROL+(PCI_FUNC(nesdev->pcidev->devfn)*8)) & (15<<8)) != (15<<8)));
1136
1137 /* dump the QP status value */
1138 nes_debug(NES_DBG_INIT, "QP Status = 0x%08X\n", nes_read_indexed(nesdev,
1139 NES_IDX_QP_CONTROL+(PCI_FUNC(nesdev->pcidev->devfn)*8)));
1140
1141 nesdev->cqp.sq_tail++;
1142
1143 return 0;
1144}
1145
1146
1147/**
1148 * nes_destroy_cqp
1149 */
1150int nes_destroy_cqp(struct nes_device *nesdev)
1151{
1152 struct nes_hw_cqp_wqe *cqp_wqe;
1153 u32 count = 0;
1154 u32 cqp_head;
1155 unsigned long flags;
1156
1157 do {
1158 if (count++ > 1000)
1159 break;
1160 udelay(10);
1161 } while (!(nesdev->cqp.sq_head == nesdev->cqp.sq_tail));
1162
1163 /* Reset CCQ */
1164 nes_write32(nesdev->regs+NES_CQE_ALLOC, NES_CQE_ALLOC_RESET |
1165 nesdev->ccq.cq_number);
1166
1167 /* Disable device interrupts */
1168 nes_write32(nesdev->regs+NES_INT_MASK, 0x7fffffff);
1169
1170 spin_lock_irqsave(&nesdev->cqp.lock, flags);
1171
1172 /* Destroy the AEQ */
1173 cqp_head = nesdev->cqp.sq_head++;
1174 nesdev->cqp.sq_head &= nesdev->cqp.sq_size-1;
1175 cqp_wqe = &nesdev->cqp.sq_vbase[cqp_head];
1176 cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] = cpu_to_le32(NES_CQP_DESTROY_AEQ |
1177 ((u32)PCI_FUNC(nesdev->pcidev->devfn) << 8));
1178 cqp_wqe->wqe_words[NES_CQP_WQE_COMP_CTX_HIGH_IDX] = 0;
1179
1180 /* Destroy the NIC CEQ */
1181 cqp_head = nesdev->cqp.sq_head++;
1182 nesdev->cqp.sq_head &= nesdev->cqp.sq_size-1;
1183 cqp_wqe = &nesdev->cqp.sq_vbase[cqp_head];
1184 cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] = cpu_to_le32(NES_CQP_DESTROY_CEQ |
1185 ((u32)nesdev->nic_ceq_index << 8));
1186
1187 /* Destroy the CEQ */
1188 cqp_head = nesdev->cqp.sq_head++;
1189 nesdev->cqp.sq_head &= nesdev->cqp.sq_size-1;
1190 cqp_wqe = &nesdev->cqp.sq_vbase[cqp_head];
1191 cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] = cpu_to_le32(NES_CQP_DESTROY_CEQ |
1192 (nesdev->ceq_index << 8));
1193
1194 /* Destroy the CCQ */
1195 cqp_head = nesdev->cqp.sq_head++;
1196 nesdev->cqp.sq_head &= nesdev->cqp.sq_size-1;
1197 cqp_wqe = &nesdev->cqp.sq_vbase[cqp_head];
1198 cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] = cpu_to_le32(NES_CQP_DESTROY_CQ);
1199 cqp_wqe->wqe_words[NES_CQP_WQE_ID_IDX] = cpu_to_le32(nesdev->ccq.cq_number |
1200 ((u32)nesdev->ceq_index << 16));
1201
1202 /* Destroy CQP */
1203 cqp_head = nesdev->cqp.sq_head++;
1204 nesdev->cqp.sq_head &= nesdev->cqp.sq_size-1;
1205 cqp_wqe = &nesdev->cqp.sq_vbase[cqp_head];
1206 cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] = cpu_to_le32(NES_CQP_DESTROY_QP |
1207 NES_CQP_QP_TYPE_CQP);
1208 cqp_wqe->wqe_words[NES_CQP_WQE_ID_IDX] = cpu_to_le32(nesdev->cqp.qp_id);
1209
1210 barrier();
1211 /* Ring doorbell (5 WQEs) */
1212 nes_write32(nesdev->regs+NES_WQE_ALLOC, 0x05800000 | nesdev->cqp.qp_id);
1213
1214 spin_unlock_irqrestore(&nesdev->cqp.lock, flags);
1215
1216 /* wait for the CCQ, CEQ, and AEQ to get destroyed */
1217 count = 0;
1218 do {
1219 if (count++ > 1000) {
1220 printk(KERN_ERR PFX "Function%d: Error destroying CCQ, CEQ, and AEQ\n",
1221 PCI_FUNC(nesdev->pcidev->devfn));
1222 break;
1223 }
1224 udelay(10);
1225 } while (((nes_read_indexed(nesdev,
1226 NES_IDX_QP_CONTROL + (PCI_FUNC(nesdev->pcidev->devfn)*8)) & (15 << 8)) != 0));
1227
1228 /* dump the QP status value */
1229 nes_debug(NES_DBG_SHUTDOWN, "Function%d: QP Status = 0x%08X\n",
1230 PCI_FUNC(nesdev->pcidev->devfn),
1231 nes_read_indexed(nesdev,
1232 NES_IDX_QP_CONTROL+(PCI_FUNC(nesdev->pcidev->devfn)*8)));
1233
1234 kfree(nesdev->nes_cqp_requests);
1235
1236 /* Free the control structures */
1237 pci_free_consistent(nesdev->pcidev, nesdev->cqp_mem_size, nesdev->cqp.sq_vbase,
1238 nesdev->cqp.sq_pbase);
1239
1240 return 0;
1241}
1242
1243
1244/**
1245 * nes_init_phy
1246 */
1247int nes_init_phy(struct nes_device *nesdev)
1248{
1249 struct nes_adapter *nesadapter = nesdev->nesadapter;
1250 u32 counter = 0;
Eric Schneider0e1de5d2008-04-29 13:46:54 -07001251 u32 sds_common_control0;
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001252 u32 mac_index = nesdev->mac_index;
Eric Schneider0e1de5d2008-04-29 13:46:54 -07001253 u32 tx_config = 0;
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001254 u16 phy_data;
Eric Schneider0e1de5d2008-04-29 13:46:54 -07001255 u32 temp_phy_data = 0;
1256 u32 temp_phy_data2 = 0;
1257 u32 i = 0;
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001258
Eric Schneider0e1de5d2008-04-29 13:46:54 -07001259 if ((nesadapter->OneG_Mode) &&
1260 (nesadapter->phy_type[mac_index] != NES_PHY_TYPE_PUMA_1G)) {
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001261 nes_debug(NES_DBG_PHY, "1G PHY, mac_index = %d.\n", mac_index);
1262 if (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_1G) {
Harvey Harrison33718362008-04-16 21:01:10 -07001263 printk(PFX "%s: Programming mdc config for 1G\n", __func__);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001264 tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG);
Chien Tunge88bd7b2008-09-26 15:08:10 -05001265 tx_config &= 0xFFFFFFE3;
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001266 tx_config |= 0x04;
1267 nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config);
1268 }
1269
1270 nes_read_1G_phy_reg(nesdev, 1, nesadapter->phy_index[mac_index], &phy_data);
1271 nes_debug(NES_DBG_PHY, "Phy data from register 1 phy address %u = 0x%X.\n",
1272 nesadapter->phy_index[mac_index], phy_data);
Glenn Streiff7495ab62008-04-29 13:46:54 -07001273 nes_write_1G_phy_reg(nesdev, 23, nesadapter->phy_index[mac_index], 0xb000);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001274
1275 /* Reset the PHY */
1276 nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], 0x8000);
1277 udelay(100);
1278 counter = 0;
1279 do {
1280 nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], &phy_data);
1281 nes_debug(NES_DBG_PHY, "Phy data from register 0 = 0x%X.\n", phy_data);
1282 if (counter++ > 100) break;
1283 } while (phy_data & 0x8000);
1284
1285 /* Setting no phy loopback */
1286 phy_data &= 0xbfff;
1287 phy_data |= 0x1140;
1288 nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], phy_data);
1289 nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], &phy_data);
1290 nes_debug(NES_DBG_PHY, "Phy data from register 0 = 0x%X.\n", phy_data);
1291
1292 nes_read_1G_phy_reg(nesdev, 0x17, nesadapter->phy_index[mac_index], &phy_data);
1293 nes_debug(NES_DBG_PHY, "Phy data from register 0x17 = 0x%X.\n", phy_data);
1294
1295 nes_read_1G_phy_reg(nesdev, 0x1e, nesadapter->phy_index[mac_index], &phy_data);
1296 nes_debug(NES_DBG_PHY, "Phy data from register 0x1e = 0x%X.\n", phy_data);
1297
1298 /* Setting the interrupt mask */
1299 nes_read_1G_phy_reg(nesdev, 0x19, nesadapter->phy_index[mac_index], &phy_data);
1300 nes_debug(NES_DBG_PHY, "Phy data from register 0x19 = 0x%X.\n", phy_data);
1301 nes_write_1G_phy_reg(nesdev, 0x19, nesadapter->phy_index[mac_index], 0xffee);
1302
1303 nes_read_1G_phy_reg(nesdev, 0x19, nesadapter->phy_index[mac_index], &phy_data);
1304 nes_debug(NES_DBG_PHY, "Phy data from register 0x19 = 0x%X.\n", phy_data);
1305
1306 /* turning on flow control */
1307 nes_read_1G_phy_reg(nesdev, 4, nesadapter->phy_index[mac_index], &phy_data);
1308 nes_debug(NES_DBG_PHY, "Phy data from register 0x4 = 0x%X.\n", phy_data);
1309 nes_write_1G_phy_reg(nesdev, 4, nesadapter->phy_index[mac_index],
1310 (phy_data & ~(0x03E0)) | 0xc00);
1311 /* nes_write_1G_phy_reg(nesdev, 4, nesadapter->phy_index[mac_index],
1312 phy_data | 0xc00); */
1313 nes_read_1G_phy_reg(nesdev, 4, nesadapter->phy_index[mac_index], &phy_data);
1314 nes_debug(NES_DBG_PHY, "Phy data from register 0x4 = 0x%X.\n", phy_data);
1315
1316 nes_read_1G_phy_reg(nesdev, 9, nesadapter->phy_index[mac_index], &phy_data);
1317 nes_debug(NES_DBG_PHY, "Phy data from register 0x9 = 0x%X.\n", phy_data);
1318 /* Clear Half duplex */
1319 nes_write_1G_phy_reg(nesdev, 9, nesadapter->phy_index[mac_index],
1320 phy_data & ~(0x0100));
1321 nes_read_1G_phy_reg(nesdev, 9, nesadapter->phy_index[mac_index], &phy_data);
1322 nes_debug(NES_DBG_PHY, "Phy data from register 0x9 = 0x%X.\n", phy_data);
1323
1324 nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], &phy_data);
1325 nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], phy_data | 0x0300);
1326 } else {
Eric Schneider0e1de5d2008-04-29 13:46:54 -07001327 if ((nesadapter->phy_type[mac_index] == NES_PHY_TYPE_IRIS) ||
1328 (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_ARGUS)) {
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001329 /* setup 10G MDIO operation */
1330 tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG);
Chien Tunge88bd7b2008-09-26 15:08:10 -05001331 tx_config &= 0xFFFFFFE3;
1332 tx_config |= 0x15;
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001333 nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config);
1334 }
Eric Schneider0e1de5d2008-04-29 13:46:54 -07001335 if ((nesadapter->phy_type[mac_index] == NES_PHY_TYPE_ARGUS)) {
1336 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee);
1337
1338 temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
1339 mdelay(10);
1340 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee);
1341 temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
1342
1343 /*
1344 * if firmware is already running (like from a
1345 * driver un-load/load, don't do anything.
1346 */
1347 if (temp_phy_data == temp_phy_data2) {
1348 /* configure QT2505 AMCC PHY */
1349 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0x0000, 0x8000);
1350 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc300, 0x0000);
1351 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc302, 0x0044);
1352 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc318, 0x0052);
1353 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc319, 0x0008);
1354 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc31a, 0x0098);
1355 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0x0026, 0x0E00);
1356 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0x0027, 0x0000);
1357 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0x0028, 0xA528);
1358
1359 /*
1360 * remove micro from reset; chip boots from ROM,
1361 * uploads EEPROM f/w image, uC executes f/w
1362 */
1363 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc300, 0x0002);
1364
1365 /*
1366 * wait for heart beat to start to
1367 * know loading is done
1368 */
1369 counter = 0;
1370 do {
1371 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee);
1372 temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
1373 if (counter++ > 1000) {
1374 nes_debug(NES_DBG_PHY, "AMCC PHY- breaking from heartbeat check <this is bad!!!> \n");
1375 break;
1376 }
1377 mdelay(100);
1378 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee);
1379 temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
1380 } while ((temp_phy_data2 == temp_phy_data));
1381
1382 /*
1383 * wait for tracking to start to know
1384 * f/w is good to go
1385 */
1386 counter = 0;
1387 do {
1388 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7fd);
1389 temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
1390 if (counter++ > 1000) {
1391 nes_debug(NES_DBG_PHY, "AMCC PHY- breaking from status check <this is bad!!!> \n");
1392 break;
1393 }
1394 mdelay(1000);
1395 /*
1396 * nes_debug(NES_DBG_PHY, "AMCC PHY- phy_status not ready yet = 0x%02X\n",
1397 * temp_phy_data);
1398 */
1399 } while (((temp_phy_data & 0xff) != 0x50) && ((temp_phy_data & 0xff) != 0x70));
1400
1401 /* set LOS Control invert RXLOSB_I_PADINV */
1402 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd003, 0x0000);
1403 /* set LOS Control to mask of RXLOSB_I */
1404 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc314, 0x0042);
1405 /* set LED1 to input mode (LED1 and LED2 share same LED) */
1406 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd006, 0x0007);
1407 /* set LED2 to RX link_status and activity */
1408 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd007, 0x000A);
1409 /* set LED3 to RX link_status */
1410 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd008, 0x0009);
1411
1412 /*
1413 * reset the res-calibration on t2
1414 * serdes; ensures it is stable after
1415 * the amcc phy is stable
1416 */
1417
Glenn Streiff7495ab62008-04-29 13:46:54 -07001418 sds_common_control0 = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0);
Eric Schneider0e1de5d2008-04-29 13:46:54 -07001419 sds_common_control0 |= 0x1;
1420 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, sds_common_control0);
1421
1422 /* release the res-calibration reset */
1423 sds_common_control0 &= 0xfffffffe;
1424 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, sds_common_control0);
1425
1426 i = 0;
Glenn Streiff7495ab62008-04-29 13:46:54 -07001427 while (((nes_read32(nesdev->regs + NES_SOFTWARE_RESET) & 0x00000040) != 0x00000040)
Eric Schneider0e1de5d2008-04-29 13:46:54 -07001428 && (i++ < 5000)) {
1429 /* mdelay(1); */
1430 }
1431
1432 /*
1433 * wait for link train done before moving on,
1434 * or will get an interupt storm
1435 */
1436 counter = 0;
1437 do {
1438 temp_phy_data = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 +
1439 (0x200 * (nesdev->mac_index & 1)));
1440 if (counter++ > 1000) {
1441 nes_debug(NES_DBG_PHY, "AMCC PHY- breaking from link train wait <this is bad, link didnt train!!!>\n");
1442 break;
1443 }
1444 mdelay(1);
1445 } while (((temp_phy_data & 0x0f1f0000) != 0x0f0f0000));
1446 }
1447 }
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001448 }
1449 return 0;
1450}
1451
1452
1453/**
1454 * nes_replenish_nic_rq
1455 */
1456static void nes_replenish_nic_rq(struct nes_vnic *nesvnic)
1457{
1458 unsigned long flags;
1459 dma_addr_t bus_address;
1460 struct sk_buff *skb;
1461 struct nes_hw_nic_rq_wqe *nic_rqe;
1462 struct nes_hw_nic *nesnic;
1463 struct nes_device *nesdev;
1464 u32 rx_wqes_posted = 0;
1465
1466 nesnic = &nesvnic->nic;
1467 nesdev = nesvnic->nesdev;
1468 spin_lock_irqsave(&nesnic->rq_lock, flags);
1469 if (nesnic->replenishing_rq !=0) {
1470 if (((nesnic->rq_size-1) == atomic_read(&nesvnic->rx_skbs_needed)) &&
1471 (atomic_read(&nesvnic->rx_skb_timer_running) == 0)) {
1472 atomic_set(&nesvnic->rx_skb_timer_running, 1);
1473 spin_unlock_irqrestore(&nesnic->rq_lock, flags);
1474 nesvnic->rq_wqes_timer.expires = jiffies + (HZ/2); /* 1/2 second */
1475 add_timer(&nesvnic->rq_wqes_timer);
1476 } else
1477 spin_unlock_irqrestore(&nesnic->rq_lock, flags);
1478 return;
1479 }
1480 nesnic->replenishing_rq = 1;
1481 spin_unlock_irqrestore(&nesnic->rq_lock, flags);
1482 do {
1483 skb = dev_alloc_skb(nesvnic->max_frame_size);
1484 if (skb) {
1485 skb->dev = nesvnic->netdev;
1486
1487 bus_address = pci_map_single(nesdev->pcidev,
1488 skb->data, nesvnic->max_frame_size, PCI_DMA_FROMDEVICE);
1489
1490 nic_rqe = &nesnic->rq_vbase[nesvnic->nic.rq_head];
1491 nic_rqe->wqe_words[NES_NIC_RQ_WQE_LENGTH_1_0_IDX] =
1492 cpu_to_le32(nesvnic->max_frame_size);
1493 nic_rqe->wqe_words[NES_NIC_RQ_WQE_LENGTH_3_2_IDX] = 0;
1494 nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_LOW_IDX] =
1495 cpu_to_le32((u32)bus_address);
1496 nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_HIGH_IDX] =
1497 cpu_to_le32((u32)((u64)bus_address >> 32));
1498 nesnic->rx_skb[nesnic->rq_head] = skb;
1499 nesnic->rq_head++;
1500 nesnic->rq_head &= nesnic->rq_size - 1;
1501 atomic_dec(&nesvnic->rx_skbs_needed);
1502 barrier();
1503 if (++rx_wqes_posted == 255) {
1504 nes_write32(nesdev->regs+NES_WQE_ALLOC, (rx_wqes_posted << 24) | nesnic->qp_id);
1505 rx_wqes_posted = 0;
1506 }
1507 } else {
1508 spin_lock_irqsave(&nesnic->rq_lock, flags);
1509 if (((nesnic->rq_size-1) == atomic_read(&nesvnic->rx_skbs_needed)) &&
1510 (atomic_read(&nesvnic->rx_skb_timer_running) == 0)) {
1511 atomic_set(&nesvnic->rx_skb_timer_running, 1);
1512 spin_unlock_irqrestore(&nesnic->rq_lock, flags);
1513 nesvnic->rq_wqes_timer.expires = jiffies + (HZ/2); /* 1/2 second */
1514 add_timer(&nesvnic->rq_wqes_timer);
1515 } else
1516 spin_unlock_irqrestore(&nesnic->rq_lock, flags);
1517 break;
1518 }
1519 } while (atomic_read(&nesvnic->rx_skbs_needed));
1520 barrier();
1521 if (rx_wqes_posted)
1522 nes_write32(nesdev->regs+NES_WQE_ALLOC, (rx_wqes_posted << 24) | nesnic->qp_id);
1523 nesnic->replenishing_rq = 0;
1524}
1525
1526
1527/**
1528 * nes_rq_wqes_timeout
1529 */
1530static void nes_rq_wqes_timeout(unsigned long parm)
1531{
1532 struct nes_vnic *nesvnic = (struct nes_vnic *)parm;
Harvey Harrison33718362008-04-16 21:01:10 -07001533 printk("%s: Timer fired.\n", __func__);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001534 atomic_set(&nesvnic->rx_skb_timer_running, 0);
1535 if (atomic_read(&nesvnic->rx_skbs_needed))
1536 nes_replenish_nic_rq(nesvnic);
1537}
1538
1539
Faisal Latif37dab412008-04-29 13:46:54 -07001540static int nes_lro_get_skb_hdr(struct sk_buff *skb, void **iphdr,
1541 void **tcph, u64 *hdr_flags, void *priv)
1542{
1543 unsigned int ip_len;
1544 struct iphdr *iph;
1545 skb_reset_network_header(skb);
1546 iph = ip_hdr(skb);
1547 if (iph->protocol != IPPROTO_TCP)
1548 return -1;
1549 ip_len = ip_hdrlen(skb);
1550 skb_set_transport_header(skb, ip_len);
1551 *tcph = tcp_hdr(skb);
1552
1553 *hdr_flags = LRO_IPV4 | LRO_TCP;
1554 *iphdr = iph;
1555 return 0;
1556}
1557
1558
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001559/**
1560 * nes_init_nic_qp
1561 */
1562int nes_init_nic_qp(struct nes_device *nesdev, struct net_device *netdev)
1563{
1564 struct nes_hw_cqp_wqe *cqp_wqe;
1565 struct nes_hw_nic_sq_wqe *nic_sqe;
1566 struct nes_hw_nic_qp_context *nic_context;
1567 struct sk_buff *skb;
1568 struct nes_hw_nic_rq_wqe *nic_rqe;
1569 struct nes_vnic *nesvnic = netdev_priv(netdev);
1570 unsigned long flags;
1571 void *vmem;
1572 dma_addr_t pmem;
1573 u64 u64temp;
1574 int ret;
1575 u32 cqp_head;
1576 u32 counter;
1577 u32 wqe_count;
1578 u8 jumbomode=0;
1579
1580 /* Allocate fragment, SQ, RQ, and CQ; Reuse CEQ based on the PCI function */
1581 nesvnic->nic_mem_size = 256 +
1582 (NES_NIC_WQ_SIZE * sizeof(struct nes_first_frag)) +
1583 (NES_NIC_WQ_SIZE * sizeof(struct nes_hw_nic_sq_wqe)) +
1584 (NES_NIC_WQ_SIZE * sizeof(struct nes_hw_nic_rq_wqe)) +
1585 (NES_NIC_WQ_SIZE * 2 * sizeof(struct nes_hw_nic_cqe)) +
1586 sizeof(struct nes_hw_nic_qp_context);
1587
1588 nesvnic->nic_vbase = pci_alloc_consistent(nesdev->pcidev, nesvnic->nic_mem_size,
1589 &nesvnic->nic_pbase);
1590 if (!nesvnic->nic_vbase) {
1591 nes_debug(NES_DBG_INIT, "Unable to allocate memory for NIC host descriptor rings\n");
1592 return -ENOMEM;
1593 }
1594 memset(nesvnic->nic_vbase, 0, nesvnic->nic_mem_size);
1595 nes_debug(NES_DBG_INIT, "Allocated NIC QP structures at %p (phys = %016lX), size = %u.\n",
1596 nesvnic->nic_vbase, (unsigned long)nesvnic->nic_pbase, nesvnic->nic_mem_size);
1597
1598 vmem = (void *)(((unsigned long)nesvnic->nic_vbase + (256 - 1)) &
1599 ~(unsigned long)(256 - 1));
1600 pmem = (dma_addr_t)(((unsigned long long)nesvnic->nic_pbase + (256 - 1)) &
1601 ~(unsigned long long)(256 - 1));
1602
1603 /* Setup the first Fragment buffers */
1604 nesvnic->nic.first_frag_vbase = vmem;
1605
1606 for (counter = 0; counter < NES_NIC_WQ_SIZE; counter++) {
1607 nesvnic->nic.frag_paddr[counter] = pmem;
1608 pmem += sizeof(struct nes_first_frag);
1609 }
1610
1611 /* setup the SQ */
1612 vmem += (NES_NIC_WQ_SIZE * sizeof(struct nes_first_frag));
1613
1614 nesvnic->nic.sq_vbase = (void *)vmem;
1615 nesvnic->nic.sq_pbase = pmem;
1616 nesvnic->nic.sq_head = 0;
1617 nesvnic->nic.sq_tail = 0;
1618 nesvnic->nic.sq_size = NES_NIC_WQ_SIZE;
1619 for (counter = 0; counter < NES_NIC_WQ_SIZE; counter++) {
1620 nic_sqe = &nesvnic->nic.sq_vbase[counter];
1621 nic_sqe->wqe_words[NES_NIC_SQ_WQE_MISC_IDX] =
1622 cpu_to_le32(NES_NIC_SQ_WQE_DISABLE_CHKSUM |
1623 NES_NIC_SQ_WQE_COMPLETION);
1624 nic_sqe->wqe_words[NES_NIC_SQ_WQE_LENGTH_0_TAG_IDX] =
1625 cpu_to_le32((u32)NES_FIRST_FRAG_SIZE << 16);
1626 nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_LOW_IDX] =
1627 cpu_to_le32((u32)nesvnic->nic.frag_paddr[counter]);
1628 nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_HIGH_IDX] =
1629 cpu_to_le32((u32)((u64)nesvnic->nic.frag_paddr[counter] >> 32));
1630 }
1631
1632 nesvnic->get_cqp_request = nes_get_cqp_request;
1633 nesvnic->post_cqp_request = nes_post_cqp_request;
1634 nesvnic->mcrq_mcast_filter = NULL;
1635
1636 spin_lock_init(&nesvnic->nic.sq_lock);
1637 spin_lock_init(&nesvnic->nic.rq_lock);
1638
1639 /* setup the RQ */
1640 vmem += (NES_NIC_WQ_SIZE * sizeof(struct nes_hw_nic_sq_wqe));
1641 pmem += (NES_NIC_WQ_SIZE * sizeof(struct nes_hw_nic_sq_wqe));
1642
1643
1644 nesvnic->nic.rq_vbase = vmem;
1645 nesvnic->nic.rq_pbase = pmem;
1646 nesvnic->nic.rq_head = 0;
1647 nesvnic->nic.rq_tail = 0;
1648 nesvnic->nic.rq_size = NES_NIC_WQ_SIZE;
1649
1650 /* setup the CQ */
1651 vmem += (NES_NIC_WQ_SIZE * sizeof(struct nes_hw_nic_rq_wqe));
1652 pmem += (NES_NIC_WQ_SIZE * sizeof(struct nes_hw_nic_rq_wqe));
1653
1654 if (nesdev->nesadapter->netdev_count > 2)
1655 nesvnic->mcrq_qp_id = nesvnic->nic_index + 32;
1656 else
1657 nesvnic->mcrq_qp_id = nesvnic->nic.qp_id + 4;
1658
1659 nesvnic->nic_cq.cq_vbase = vmem;
1660 nesvnic->nic_cq.cq_pbase = pmem;
1661 nesvnic->nic_cq.cq_head = 0;
1662 nesvnic->nic_cq.cq_size = NES_NIC_WQ_SIZE * 2;
1663
1664 nesvnic->nic_cq.ce_handler = nes_nic_napi_ce_handler;
1665
1666 /* Send CreateCQ request to CQP */
1667 spin_lock_irqsave(&nesdev->cqp.lock, flags);
1668 cqp_head = nesdev->cqp.sq_head;
1669
1670 cqp_wqe = &nesdev->cqp.sq_vbase[cqp_head];
1671 nes_fill_init_cqp_wqe(cqp_wqe, nesdev);
1672
1673 cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] = cpu_to_le32(
1674 NES_CQP_CREATE_CQ | NES_CQP_CQ_CEQ_VALID |
1675 ((u32)nesvnic->nic_cq.cq_size << 16));
1676 cqp_wqe->wqe_words[NES_CQP_WQE_ID_IDX] = cpu_to_le32(
1677 nesvnic->nic_cq.cq_number | ((u32)nesdev->nic_ceq_index << 16));
1678 u64temp = (u64)nesvnic->nic_cq.cq_pbase;
1679 set_wqe_64bit_value(cqp_wqe->wqe_words, NES_CQP_CQ_WQE_PBL_LOW_IDX, u64temp);
1680 cqp_wqe->wqe_words[NES_CQP_CQ_WQE_CQ_CONTEXT_HIGH_IDX] = 0;
1681 u64temp = (unsigned long)&nesvnic->nic_cq;
1682 cqp_wqe->wqe_words[NES_CQP_CQ_WQE_CQ_CONTEXT_LOW_IDX] = cpu_to_le32((u32)(u64temp >> 1));
1683 cqp_wqe->wqe_words[NES_CQP_CQ_WQE_CQ_CONTEXT_HIGH_IDX] =
1684 cpu_to_le32(((u32)((u64temp) >> 33)) & 0x7FFFFFFF);
1685 cqp_wqe->wqe_words[NES_CQP_CQ_WQE_DOORBELL_INDEX_HIGH_IDX] = 0;
1686 if (++cqp_head >= nesdev->cqp.sq_size)
1687 cqp_head = 0;
1688 cqp_wqe = &nesdev->cqp.sq_vbase[cqp_head];
1689 nes_fill_init_cqp_wqe(cqp_wqe, nesdev);
1690
1691 /* Send CreateQP request to CQP */
1692 nic_context = (void *)(&nesvnic->nic_cq.cq_vbase[nesvnic->nic_cq.cq_size]);
1693 nic_context->context_words[NES_NIC_CTX_MISC_IDX] =
1694 cpu_to_le32((u32)NES_NIC_CTX_SIZE |
1695 ((u32)PCI_FUNC(nesdev->pcidev->devfn) << 12));
1696 nes_debug(NES_DBG_INIT, "RX_WINDOW_BUFFER_PAGE_TABLE_SIZE = 0x%08X, RX_WINDOW_BUFFER_SIZE = 0x%08X\n",
1697 nes_read_indexed(nesdev, NES_IDX_RX_WINDOW_BUFFER_PAGE_TABLE_SIZE),
1698 nes_read_indexed(nesdev, NES_IDX_RX_WINDOW_BUFFER_SIZE));
1699 if (nes_read_indexed(nesdev, NES_IDX_RX_WINDOW_BUFFER_SIZE) != 0) {
1700 nic_context->context_words[NES_NIC_CTX_MISC_IDX] |= cpu_to_le32(NES_NIC_BACK_STORE);
1701 }
1702
1703 u64temp = (u64)nesvnic->nic.sq_pbase;
Glenn Streiff7495ab62008-04-29 13:46:54 -07001704 nic_context->context_words[NES_NIC_CTX_SQ_LOW_IDX] = cpu_to_le32((u32)u64temp);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001705 nic_context->context_words[NES_NIC_CTX_SQ_HIGH_IDX] = cpu_to_le32((u32)(u64temp >> 32));
1706 u64temp = (u64)nesvnic->nic.rq_pbase;
Glenn Streiff7495ab62008-04-29 13:46:54 -07001707 nic_context->context_words[NES_NIC_CTX_RQ_LOW_IDX] = cpu_to_le32((u32)u64temp);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001708 nic_context->context_words[NES_NIC_CTX_RQ_HIGH_IDX] = cpu_to_le32((u32)(u64temp >> 32));
1709
1710 cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] = cpu_to_le32(NES_CQP_CREATE_QP |
1711 NES_CQP_QP_TYPE_NIC);
1712 cqp_wqe->wqe_words[NES_CQP_WQE_ID_IDX] = cpu_to_le32(nesvnic->nic.qp_id);
1713 u64temp = (u64)nesvnic->nic_cq.cq_pbase +
1714 (nesvnic->nic_cq.cq_size * sizeof(struct nes_hw_nic_cqe));
1715 set_wqe_64bit_value(cqp_wqe->wqe_words, NES_CQP_QP_WQE_CONTEXT_LOW_IDX, u64temp);
1716
1717 if (++cqp_head >= nesdev->cqp.sq_size)
1718 cqp_head = 0;
1719 nesdev->cqp.sq_head = cqp_head;
1720
1721 barrier();
1722
1723 /* Ring doorbell (2 WQEs) */
1724 nes_write32(nesdev->regs+NES_WQE_ALLOC, 0x02800000 | nesdev->cqp.qp_id);
1725
1726 spin_unlock_irqrestore(&nesdev->cqp.lock, flags);
1727 nes_debug(NES_DBG_INIT, "Waiting for create NIC QP%u to complete.\n",
1728 nesvnic->nic.qp_id);
1729
1730 ret = wait_event_timeout(nesdev->cqp.waitq, (nesdev->cqp.sq_tail == cqp_head),
1731 NES_EVENT_TIMEOUT);
1732 nes_debug(NES_DBG_INIT, "Create NIC QP%u completed, wait_event_timeout ret = %u.\n",
1733 nesvnic->nic.qp_id, ret);
1734 if (!ret) {
1735 nes_debug(NES_DBG_INIT, "NIC QP%u create timeout expired\n", nesvnic->nic.qp_id);
1736 pci_free_consistent(nesdev->pcidev, nesvnic->nic_mem_size, nesvnic->nic_vbase,
1737 nesvnic->nic_pbase);
1738 return -EIO;
1739 }
1740
1741 /* Populate the RQ */
1742 for (counter = 0; counter < (NES_NIC_WQ_SIZE - 1); counter++) {
1743 skb = dev_alloc_skb(nesvnic->max_frame_size);
1744 if (!skb) {
1745 nes_debug(NES_DBG_INIT, "%s: out of memory for receive skb\n", netdev->name);
1746
1747 nes_destroy_nic_qp(nesvnic);
1748 return -ENOMEM;
1749 }
1750
1751 skb->dev = netdev;
1752
1753 pmem = pci_map_single(nesdev->pcidev, skb->data,
1754 nesvnic->max_frame_size, PCI_DMA_FROMDEVICE);
1755
1756 nic_rqe = &nesvnic->nic.rq_vbase[counter];
1757 nic_rqe->wqe_words[NES_NIC_RQ_WQE_LENGTH_1_0_IDX] = cpu_to_le32(nesvnic->max_frame_size);
1758 nic_rqe->wqe_words[NES_NIC_RQ_WQE_LENGTH_3_2_IDX] = 0;
Glenn Streiff7495ab62008-04-29 13:46:54 -07001759 nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_LOW_IDX] = cpu_to_le32((u32)pmem);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001760 nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_HIGH_IDX] = cpu_to_le32((u32)((u64)pmem >> 32));
1761 nesvnic->nic.rx_skb[counter] = skb;
1762 }
1763
1764 wqe_count = NES_NIC_WQ_SIZE - 1;
1765 nesvnic->nic.rq_head = wqe_count;
1766 barrier();
1767 do {
1768 counter = min(wqe_count, ((u32)255));
1769 wqe_count -= counter;
1770 nes_write32(nesdev->regs+NES_WQE_ALLOC, (counter << 24) | nesvnic->nic.qp_id);
1771 } while (wqe_count);
1772 init_timer(&nesvnic->rq_wqes_timer);
1773 nesvnic->rq_wqes_timer.function = nes_rq_wqes_timeout;
1774 nesvnic->rq_wqes_timer.data = (unsigned long)nesvnic;
1775 nes_debug(NES_DBG_INIT, "NAPI support Enabled\n");
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001776 if (nesdev->nesadapter->et_use_adaptive_rx_coalesce)
1777 {
1778 nes_nic_init_timer(nesdev);
1779 if (netdev->mtu > 1500)
1780 jumbomode = 1;
Faisal Latif37dab412008-04-29 13:46:54 -07001781 nes_nic_init_timer_defaults(nesdev, jumbomode);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001782 }
Roland Dreierdd378182008-05-13 11:27:25 -07001783 nesvnic->lro_mgr.max_aggr = nes_lro_max_aggr;
Glenn Streiff7495ab62008-04-29 13:46:54 -07001784 nesvnic->lro_mgr.max_desc = NES_MAX_LRO_DESCRIPTORS;
1785 nesvnic->lro_mgr.lro_arr = nesvnic->lro_desc;
Faisal Latif37dab412008-04-29 13:46:54 -07001786 nesvnic->lro_mgr.get_skb_header = nes_lro_get_skb_hdr;
Glenn Streiff7495ab62008-04-29 13:46:54 -07001787 nesvnic->lro_mgr.features = LRO_F_NAPI | LRO_F_EXTRACT_VLAN_ID;
1788 nesvnic->lro_mgr.dev = netdev;
1789 nesvnic->lro_mgr.ip_summed = CHECKSUM_UNNECESSARY;
Faisal Latif37dab412008-04-29 13:46:54 -07001790 nesvnic->lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY;
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001791 return 0;
1792}
1793
1794
1795/**
1796 * nes_destroy_nic_qp
1797 */
1798void nes_destroy_nic_qp(struct nes_vnic *nesvnic)
1799{
Bob Sharp7a8d1402008-09-26 15:08:10 -05001800 u64 u64temp;
1801 dma_addr_t bus_address;
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001802 struct nes_device *nesdev = nesvnic->nesdev;
1803 struct nes_hw_cqp_wqe *cqp_wqe;
Bob Sharp7a8d1402008-09-26 15:08:10 -05001804 struct nes_hw_nic_sq_wqe *nic_sqe;
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001805 struct nes_hw_nic_rq_wqe *nic_rqe;
Bob Sharp7a8d1402008-09-26 15:08:10 -05001806 __le16 *wqe_fragment_length;
1807 u16 wqe_fragment_index;
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001808 u64 wqe_frag;
1809 u32 cqp_head;
1810 unsigned long flags;
1811 int ret;
1812
1813 /* Free remaining NIC receive buffers */
1814 while (nesvnic->nic.rq_head != nesvnic->nic.rq_tail) {
Glenn Streiff7495ab62008-04-29 13:46:54 -07001815 nic_rqe = &nesvnic->nic.rq_vbase[nesvnic->nic.rq_tail];
Bob Sharp7a8d1402008-09-26 15:08:10 -05001816 wqe_frag = (u64)le32_to_cpu(
1817 nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_LOW_IDX]);
1818 wqe_frag |= ((u64)le32_to_cpu(
1819 nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_HIGH_IDX]))<<32;
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001820 pci_unmap_single(nesdev->pcidev, (dma_addr_t)wqe_frag,
1821 nesvnic->max_frame_size, PCI_DMA_FROMDEVICE);
1822 dev_kfree_skb(nesvnic->nic.rx_skb[nesvnic->nic.rq_tail++]);
1823 nesvnic->nic.rq_tail &= (nesvnic->nic.rq_size - 1);
1824 }
1825
Bob Sharp7a8d1402008-09-26 15:08:10 -05001826 /* Free remaining NIC transmit buffers */
1827 while (nesvnic->nic.sq_head != nesvnic->nic.sq_tail) {
1828 nic_sqe = &nesvnic->nic.sq_vbase[nesvnic->nic.sq_tail];
1829 wqe_fragment_index = 1;
1830 wqe_fragment_length = (__le16 *)
1831 &nic_sqe->wqe_words[NES_NIC_SQ_WQE_LENGTH_0_TAG_IDX];
1832 /* bump past the vlan tag */
1833 wqe_fragment_length++;
1834 if (le16_to_cpu(wqe_fragment_length[wqe_fragment_index]) != 0) {
1835 u64temp = (u64)le32_to_cpu(
1836 nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_LOW_IDX+
1837 wqe_fragment_index*2]);
1838 u64temp += ((u64)le32_to_cpu(
1839 nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_HIGH_IDX
1840 + wqe_fragment_index*2]))<<32;
1841 bus_address = (dma_addr_t)u64temp;
1842 if (test_and_clear_bit(nesvnic->nic.sq_tail,
1843 nesvnic->nic.first_frag_overflow)) {
1844 pci_unmap_single(nesdev->pcidev,
1845 bus_address,
1846 le16_to_cpu(wqe_fragment_length[
1847 wqe_fragment_index++]),
1848 PCI_DMA_TODEVICE);
1849 }
1850 for (; wqe_fragment_index < 5; wqe_fragment_index++) {
1851 if (wqe_fragment_length[wqe_fragment_index]) {
1852 u64temp = le32_to_cpu(
1853 nic_sqe->wqe_words[
1854 NES_NIC_SQ_WQE_FRAG0_LOW_IDX+
1855 wqe_fragment_index*2]);
1856 u64temp += ((u64)le32_to_cpu(
1857 nic_sqe->wqe_words[
1858 NES_NIC_SQ_WQE_FRAG0_HIGH_IDX+
1859 wqe_fragment_index*2]))<<32;
1860 bus_address = (dma_addr_t)u64temp;
1861 pci_unmap_page(nesdev->pcidev,
1862 bus_address,
1863 le16_to_cpu(
1864 wqe_fragment_length[
1865 wqe_fragment_index]),
1866 PCI_DMA_TODEVICE);
1867 } else
1868 break;
1869 }
1870 }
1871 if (nesvnic->nic.tx_skb[nesvnic->nic.sq_tail])
1872 dev_kfree_skb(
1873 nesvnic->nic.tx_skb[nesvnic->nic.sq_tail]);
1874
1875 nesvnic->nic.sq_tail = (++nesvnic->nic.sq_tail)
1876 & (nesvnic->nic.sq_size - 1);
1877 }
1878
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001879 spin_lock_irqsave(&nesdev->cqp.lock, flags);
1880
1881 /* Destroy NIC QP */
1882 cqp_head = nesdev->cqp.sq_head;
1883 cqp_wqe = &nesdev->cqp.sq_vbase[cqp_head];
1884 nes_fill_init_cqp_wqe(cqp_wqe, nesdev);
1885
1886 set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_OPCODE_IDX,
1887 (NES_CQP_DESTROY_QP | NES_CQP_QP_TYPE_NIC));
1888 set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_ID_IDX,
1889 nesvnic->nic.qp_id);
1890
1891 if (++cqp_head >= nesdev->cqp.sq_size)
1892 cqp_head = 0;
1893
1894 cqp_wqe = &nesdev->cqp.sq_vbase[cqp_head];
1895
1896 /* Destroy NIC CQ */
1897 nes_fill_init_cqp_wqe(cqp_wqe, nesdev);
1898 set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_OPCODE_IDX,
1899 (NES_CQP_DESTROY_CQ | ((u32)nesvnic->nic_cq.cq_size << 16)));
1900 set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_ID_IDX,
1901 (nesvnic->nic_cq.cq_number | ((u32)nesdev->nic_ceq_index << 16)));
1902
1903 if (++cqp_head >= nesdev->cqp.sq_size)
1904 cqp_head = 0;
1905
1906 nesdev->cqp.sq_head = cqp_head;
1907 barrier();
1908
1909 /* Ring doorbell (2 WQEs) */
1910 nes_write32(nesdev->regs+NES_WQE_ALLOC, 0x02800000 | nesdev->cqp.qp_id);
1911
1912 spin_unlock_irqrestore(&nesdev->cqp.lock, flags);
1913 nes_debug(NES_DBG_SHUTDOWN, "Waiting for CQP, cqp_head=%u, cqp.sq_head=%u,"
1914 " cqp.sq_tail=%u, cqp.sq_size=%u\n",
1915 cqp_head, nesdev->cqp.sq_head,
1916 nesdev->cqp.sq_tail, nesdev->cqp.sq_size);
1917
1918 ret = wait_event_timeout(nesdev->cqp.waitq, (nesdev->cqp.sq_tail == cqp_head),
1919 NES_EVENT_TIMEOUT);
1920
1921 nes_debug(NES_DBG_SHUTDOWN, "Destroy NIC QP returned, wait_event_timeout ret = %u, cqp_head=%u,"
1922 " cqp.sq_head=%u, cqp.sq_tail=%u\n",
1923 ret, cqp_head, nesdev->cqp.sq_head, nesdev->cqp.sq_tail);
1924 if (!ret) {
1925 nes_debug(NES_DBG_SHUTDOWN, "NIC QP%u destroy timeout expired\n",
1926 nesvnic->nic.qp_id);
1927 }
1928
1929 pci_free_consistent(nesdev->pcidev, nesvnic->nic_mem_size, nesvnic->nic_vbase,
1930 nesvnic->nic_pbase);
1931}
1932
1933/**
1934 * nes_napi_isr
1935 */
1936int nes_napi_isr(struct nes_device *nesdev)
1937{
1938 struct nes_adapter *nesadapter = nesdev->nesadapter;
1939 u32 int_stat;
1940
1941 if (nesdev->napi_isr_ran) {
1942 /* interrupt status has already been read in ISR */
1943 int_stat = nesdev->int_stat;
1944 } else {
1945 int_stat = nes_read32(nesdev->regs + NES_INT_STAT);
1946 nesdev->int_stat = int_stat;
1947 nesdev->napi_isr_ran = 1;
1948 }
1949
1950 int_stat &= nesdev->int_req;
1951 /* iff NIC, process here, else wait for DPC */
1952 if ((int_stat) && ((int_stat & 0x0000ff00) == int_stat)) {
1953 nesdev->napi_isr_ran = 0;
Glenn Streiff7495ab62008-04-29 13:46:54 -07001954 nes_write32(nesdev->regs + NES_INT_STAT,
1955 (int_stat &
1956 ~(NES_INT_INTF | NES_INT_TIMER | NES_INT_MAC0 | NES_INT_MAC1 | NES_INT_MAC2 | NES_INT_MAC3)));
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001957
1958 /* Process the CEQs */
1959 nes_process_ceq(nesdev, &nesdev->nesadapter->ceq[nesdev->nic_ceq_index]);
1960
1961 if (unlikely((((nesadapter->et_rx_coalesce_usecs_irq) &&
Glenn Streiff7495ab62008-04-29 13:46:54 -07001962 (!nesadapter->et_use_adaptive_rx_coalesce)) ||
1963 ((nesadapter->et_use_adaptive_rx_coalesce) &&
1964 (nesdev->deepcq_count > nesadapter->et_pkt_rate_low))))) {
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001965 if ((nesdev->int_req & NES_INT_TIMER) == 0) {
1966 /* Enable Periodic timer interrupts */
1967 nesdev->int_req |= NES_INT_TIMER;
1968 /* ack any pending periodic timer interrupts so we don't get an immediate interrupt */
1969 /* TODO: need to also ack other unused periodic timer values, get from nesadapter */
1970 nes_write32(nesdev->regs+NES_TIMER_STAT,
1971 nesdev->timer_int_req | ~(nesdev->nesadapter->timer_int_req));
1972 nes_write32(nesdev->regs+NES_INTF_INT_MASK,
1973 ~(nesdev->intf_int_req | NES_INTF_PERIODIC_TIMER));
1974 }
1975
1976 if (unlikely(nesadapter->et_use_adaptive_rx_coalesce))
1977 {
1978 nes_nic_init_timer(nesdev);
1979 }
1980 /* Enable interrupts, except CEQs */
1981 nes_write32(nesdev->regs+NES_INT_MASK, 0x0000ffff | (~nesdev->int_req));
1982 } else {
1983 /* Enable interrupts, make sure timer is off */
1984 nesdev->int_req &= ~NES_INT_TIMER;
1985 nes_write32(nesdev->regs+NES_INTF_INT_MASK, ~(nesdev->intf_int_req));
1986 nes_write32(nesdev->regs+NES_INT_MASK, ~nesdev->int_req);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001987 }
1988 nesdev->deepcq_count = 0;
1989 return 1;
1990 } else {
1991 return 0;
1992 }
1993}
1994
1995
1996/**
1997 * nes_dpc
1998 */
1999void nes_dpc(unsigned long param)
2000{
2001 struct nes_device *nesdev = (struct nes_device *)param;
2002 struct nes_adapter *nesadapter = nesdev->nesadapter;
2003 u32 counter;
2004 u32 loop_counter = 0;
2005 u32 int_status_bit;
2006 u32 int_stat;
2007 u32 timer_stat;
2008 u32 temp_int_stat;
2009 u32 intf_int_stat;
2010 u32 debug_error;
2011 u32 processed_intf_int = 0;
2012 u16 processed_timer_int = 0;
2013 u16 completion_ints = 0;
2014 u16 timer_ints = 0;
2015
2016 /* nes_debug(NES_DBG_ISR, "\n"); */
2017
2018 do {
2019 timer_stat = 0;
2020 if (nesdev->napi_isr_ran) {
2021 nesdev->napi_isr_ran = 0;
2022 int_stat = nesdev->int_stat;
2023 } else
2024 int_stat = nes_read32(nesdev->regs+NES_INT_STAT);
2025 if (processed_intf_int != 0)
2026 int_stat &= nesdev->int_req & ~NES_INT_INTF;
2027 else
2028 int_stat &= nesdev->int_req;
2029 if (processed_timer_int == 0) {
2030 processed_timer_int = 1;
2031 if (int_stat & NES_INT_TIMER) {
2032 timer_stat = nes_read32(nesdev->regs + NES_TIMER_STAT);
2033 if ((timer_stat & nesdev->timer_int_req) == 0) {
2034 int_stat &= ~NES_INT_TIMER;
2035 }
2036 }
2037 } else {
2038 int_stat &= ~NES_INT_TIMER;
2039 }
2040
2041 if (int_stat) {
Glenn Streiff7495ab62008-04-29 13:46:54 -07002042 if (int_stat & ~(NES_INT_INTF | NES_INT_TIMER | NES_INT_MAC0|
2043 NES_INT_MAC1|NES_INT_MAC2 | NES_INT_MAC3)) {
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002044 /* Ack the interrupts */
2045 nes_write32(nesdev->regs+NES_INT_STAT,
Glenn Streiff7495ab62008-04-29 13:46:54 -07002046 (int_stat & ~(NES_INT_INTF | NES_INT_TIMER | NES_INT_MAC0|
2047 NES_INT_MAC1 | NES_INT_MAC2 | NES_INT_MAC3)));
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002048 }
2049
2050 temp_int_stat = int_stat;
2051 for (counter = 0, int_status_bit = 1; counter < 16; counter++) {
2052 if (int_stat & int_status_bit) {
2053 nes_process_ceq(nesdev, &nesadapter->ceq[counter]);
2054 temp_int_stat &= ~int_status_bit;
2055 completion_ints = 1;
2056 }
2057 if (!(temp_int_stat & 0x0000ffff))
2058 break;
2059 int_status_bit <<= 1;
2060 }
2061
2062 /* Process the AEQ for this pci function */
2063 int_status_bit = 1 << (16 + PCI_FUNC(nesdev->pcidev->devfn));
2064 if (int_stat & int_status_bit) {
2065 nes_process_aeq(nesdev, &nesadapter->aeq[PCI_FUNC(nesdev->pcidev->devfn)]);
2066 }
2067
2068 /* Process the MAC interrupt for this pci function */
2069 int_status_bit = 1 << (24 + nesdev->mac_index);
2070 if (int_stat & int_status_bit) {
2071 nes_process_mac_intr(nesdev, nesdev->mac_index);
2072 }
2073
2074 if (int_stat & NES_INT_TIMER) {
2075 if (timer_stat & nesdev->timer_int_req) {
2076 nes_write32(nesdev->regs + NES_TIMER_STAT,
2077 (timer_stat & nesdev->timer_int_req) |
2078 ~(nesdev->nesadapter->timer_int_req));
2079 timer_ints = 1;
2080 }
2081 }
2082
2083 if (int_stat & NES_INT_INTF) {
2084 processed_intf_int = 1;
2085 intf_int_stat = nes_read32(nesdev->regs+NES_INTF_INT_STAT);
2086 intf_int_stat &= nesdev->intf_int_req;
2087 if (NES_INTF_INT_CRITERR & intf_int_stat) {
2088 debug_error = nes_read_indexed(nesdev, NES_IDX_DEBUG_ERROR_CONTROL_STATUS);
2089 printk(KERN_ERR PFX "Critical Error reported by device!!! 0x%02X\n",
2090 (u16)debug_error);
2091 nes_write_indexed(nesdev, NES_IDX_DEBUG_ERROR_CONTROL_STATUS,
2092 0x01010000 | (debug_error & 0x0000ffff));
2093 /* BUG(); */
2094 if (crit_err_count++ > 10)
2095 nes_write_indexed(nesdev, NES_IDX_DEBUG_ERROR_MASKS1, 1 << 0x17);
2096 }
2097 if (NES_INTF_INT_PCIERR & intf_int_stat) {
2098 printk(KERN_ERR PFX "PCI Error reported by device!!!\n");
2099 BUG();
2100 }
2101 if (NES_INTF_INT_AEQ_OFLOW & intf_int_stat) {
2102 printk(KERN_ERR PFX "AEQ Overflow reported by device!!!\n");
2103 BUG();
2104 }
2105 nes_write32(nesdev->regs+NES_INTF_INT_STAT, intf_int_stat);
2106 }
2107
2108 if (int_stat & NES_INT_TSW) {
2109 }
2110 }
2111 /* Don't use the interface interrupt bit stay in loop */
Glenn Streiff7495ab62008-04-29 13:46:54 -07002112 int_stat &= ~NES_INT_INTF | NES_INT_TIMER | NES_INT_MAC0 |
2113 NES_INT_MAC1 | NES_INT_MAC2 | NES_INT_MAC3;
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002114 } while ((int_stat != 0) && (loop_counter++ < MAX_DPC_ITERATIONS));
2115
2116 if (timer_ints == 1) {
2117 if ((nesadapter->et_rx_coalesce_usecs_irq) || (nesadapter->et_use_adaptive_rx_coalesce)) {
2118 if (completion_ints == 0) {
2119 nesdev->timer_only_int_count++;
2120 if (nesdev->timer_only_int_count>=nesadapter->timer_int_limit) {
2121 nesdev->timer_only_int_count = 0;
2122 nesdev->int_req &= ~NES_INT_TIMER;
2123 nes_write32(nesdev->regs + NES_INTF_INT_MASK, ~(nesdev->intf_int_req));
Glenn Streiff7495ab62008-04-29 13:46:54 -07002124 nes_write32(nesdev->regs + NES_INT_MASK, ~nesdev->int_req);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002125 } else {
Glenn Streiff7495ab62008-04-29 13:46:54 -07002126 nes_write32(nesdev->regs+NES_INT_MASK, 0x0000ffff | (~nesdev->int_req));
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002127 }
2128 } else {
2129 if (unlikely(nesadapter->et_use_adaptive_rx_coalesce))
2130 {
2131 nes_nic_init_timer(nesdev);
2132 }
2133 nesdev->timer_only_int_count = 0;
Glenn Streiff7495ab62008-04-29 13:46:54 -07002134 nes_write32(nesdev->regs+NES_INT_MASK, 0x0000ffff | (~nesdev->int_req));
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002135 }
2136 } else {
2137 nesdev->timer_only_int_count = 0;
2138 nesdev->int_req &= ~NES_INT_TIMER;
2139 nes_write32(nesdev->regs+NES_INTF_INT_MASK, ~(nesdev->intf_int_req));
2140 nes_write32(nesdev->regs+NES_TIMER_STAT,
2141 nesdev->timer_int_req | ~(nesdev->nesadapter->timer_int_req));
2142 nes_write32(nesdev->regs+NES_INT_MASK, ~nesdev->int_req);
2143 }
2144 } else {
2145 if ( (completion_ints == 1) &&
2146 (((nesadapter->et_rx_coalesce_usecs_irq) &&
2147 (!nesadapter->et_use_adaptive_rx_coalesce)) ||
2148 ((nesdev->deepcq_count > nesadapter->et_pkt_rate_low) &&
2149 (nesadapter->et_use_adaptive_rx_coalesce) )) ) {
2150 /* nes_debug(NES_DBG_ISR, "Enabling periodic timer interrupt.\n" ); */
2151 nesdev->timer_only_int_count = 0;
2152 nesdev->int_req |= NES_INT_TIMER;
2153 nes_write32(nesdev->regs+NES_TIMER_STAT,
2154 nesdev->timer_int_req | ~(nesdev->nesadapter->timer_int_req));
2155 nes_write32(nesdev->regs+NES_INTF_INT_MASK,
2156 ~(nesdev->intf_int_req | NES_INTF_PERIODIC_TIMER));
2157 nes_write32(nesdev->regs+NES_INT_MASK, 0x0000ffff | (~nesdev->int_req));
2158 } else {
2159 nes_write32(nesdev->regs+NES_INT_MASK, ~nesdev->int_req);
2160 }
2161 }
2162 nesdev->deepcq_count = 0;
2163}
2164
2165
2166/**
2167 * nes_process_ceq
2168 */
Roland Dreier1a855fbf2008-04-16 21:01:09 -07002169static void nes_process_ceq(struct nes_device *nesdev, struct nes_hw_ceq *ceq)
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002170{
2171 u64 u64temp;
2172 struct nes_hw_cq *cq;
2173 u32 head;
2174 u32 ceq_size;
2175
2176 /* nes_debug(NES_DBG_CQ, "\n"); */
2177 head = ceq->ceq_head;
2178 ceq_size = ceq->ceq_size;
2179
2180 do {
2181 if (le32_to_cpu(ceq->ceq_vbase[head].ceqe_words[NES_CEQE_CQ_CTX_HIGH_IDX]) &
2182 NES_CEQE_VALID) {
Glenn Streiff7495ab62008-04-29 13:46:54 -07002183 u64temp = (((u64)(le32_to_cpu(ceq->ceq_vbase[head].ceqe_words[NES_CEQE_CQ_CTX_HIGH_IDX]))) << 32) |
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002184 ((u64)(le32_to_cpu(ceq->ceq_vbase[head].ceqe_words[NES_CEQE_CQ_CTX_LOW_IDX])));
2185 u64temp <<= 1;
2186 cq = *((struct nes_hw_cq **)&u64temp);
2187 /* nes_debug(NES_DBG_CQ, "pCQ = %p\n", cq); */
2188 barrier();
2189 ceq->ceq_vbase[head].ceqe_words[NES_CEQE_CQ_CTX_HIGH_IDX] = 0;
2190
2191 /* call the event handler */
2192 cq->ce_handler(nesdev, cq);
2193
2194 if (++head >= ceq_size)
2195 head = 0;
2196 } else {
2197 break;
2198 }
2199
2200 } while (1);
2201
2202 ceq->ceq_head = head;
2203}
2204
2205
2206/**
2207 * nes_process_aeq
2208 */
Roland Dreier1a855fbf2008-04-16 21:01:09 -07002209static void nes_process_aeq(struct nes_device *nesdev, struct nes_hw_aeq *aeq)
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002210{
Glenn Streiff7495ab62008-04-29 13:46:54 -07002211 /* u64 u64temp; */
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002212 u32 head;
2213 u32 aeq_size;
2214 u32 aeqe_misc;
2215 u32 aeqe_cq_id;
2216 struct nes_hw_aeqe volatile *aeqe;
2217
2218 head = aeq->aeq_head;
2219 aeq_size = aeq->aeq_size;
2220
2221 do {
2222 aeqe = &aeq->aeq_vbase[head];
2223 if ((le32_to_cpu(aeqe->aeqe_words[NES_AEQE_MISC_IDX]) & NES_AEQE_VALID) == 0)
2224 break;
2225 aeqe_misc = le32_to_cpu(aeqe->aeqe_words[NES_AEQE_MISC_IDX]);
2226 aeqe_cq_id = le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX]);
2227 if (aeqe_misc & (NES_AEQE_QP|NES_AEQE_CQ)) {
2228 if (aeqe_cq_id >= NES_FIRST_QPN) {
2229 /* dealing with an accelerated QP related AE */
Glenn Streiff7495ab62008-04-29 13:46:54 -07002230 /*
2231 * u64temp = (((u64)(le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_HIGH_IDX]))) << 32) |
2232 * ((u64)(le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_LOW_IDX])));
2233 */
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002234 nes_process_iwarp_aeqe(nesdev, (struct nes_hw_aeqe *)aeqe);
2235 } else {
2236 /* TODO: dealing with a CQP related AE */
2237 nes_debug(NES_DBG_AEQ, "Processing CQP related AE, misc = 0x%04X\n",
2238 (u16)(aeqe_misc >> 16));
2239 }
2240 }
2241
2242 aeqe->aeqe_words[NES_AEQE_MISC_IDX] = 0;
2243
2244 if (++head >= aeq_size)
2245 head = 0;
2246 }
2247 while (1);
2248 aeq->aeq_head = head;
2249}
2250
2251static void nes_reset_link(struct nes_device *nesdev, u32 mac_index)
2252{
2253 struct nes_adapter *nesadapter = nesdev->nesadapter;
2254 u32 reset_value;
2255 u32 i=0;
2256 u32 u32temp;
2257
2258 if (nesadapter->hw_rev == NE020_REV) {
2259 return;
2260 }
2261 mh_detected++;
2262
2263 reset_value = nes_read32(nesdev->regs+NES_SOFTWARE_RESET);
2264
2265 if ((mac_index == 0) || ((mac_index == 1) && (nesadapter->OneG_Mode)))
2266 reset_value |= 0x0000001d;
2267 else
2268 reset_value |= 0x0000002d;
2269
2270 if (4 <= (nesadapter->link_interrupt_count[mac_index] / ((u16)NES_MAX_LINK_INTERRUPTS))) {
2271 if ((!nesadapter->OneG_Mode) && (nesadapter->port_count == 2)) {
2272 nesadapter->link_interrupt_count[0] = 0;
2273 nesadapter->link_interrupt_count[1] = 0;
2274 u32temp = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1);
2275 if (0x00000040 & u32temp)
2276 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, 0x0000F088);
2277 else
2278 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, 0x0000F0C8);
2279
2280 reset_value |= 0x0000003d;
2281 }
2282 nesadapter->link_interrupt_count[mac_index] = 0;
2283 }
2284
2285 nes_write32(nesdev->regs+NES_SOFTWARE_RESET, reset_value);
2286
2287 while (((nes_read32(nesdev->regs+NES_SOFTWARE_RESET)
2288 & 0x00000040) != 0x00000040) && (i++ < 5000));
2289
2290 if (0x0000003d == (reset_value & 0x0000003d)) {
2291 u32 pcs_control_status0, pcs_control_status1;
2292
2293 for (i = 0; i < 10; i++) {
2294 pcs_control_status0 = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0);
2295 pcs_control_status1 = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + 0x200);
2296 if (((0x0F000000 == (pcs_control_status0 & 0x0F000000))
2297 && (pcs_control_status0 & 0x00100000))
2298 || ((0x0F000000 == (pcs_control_status1 & 0x0F000000))
2299 && (pcs_control_status1 & 0x00100000)))
2300 continue;
2301 else
2302 break;
2303 }
2304 if (10 == i) {
2305 u32temp = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1);
2306 if (0x00000040 & u32temp)
2307 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, 0x0000F088);
2308 else
2309 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, 0x0000F0C8);
2310
2311 nes_write32(nesdev->regs+NES_SOFTWARE_RESET, reset_value);
2312
2313 while (((nes_read32(nesdev->regs + NES_SOFTWARE_RESET)
2314 & 0x00000040) != 0x00000040) && (i++ < 5000));
2315 }
2316 }
2317}
2318
2319/**
2320 * nes_process_mac_intr
2321 */
Roland Dreier1a855fbf2008-04-16 21:01:09 -07002322static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number)
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002323{
2324 unsigned long flags;
2325 u32 pcs_control_status;
2326 struct nes_adapter *nesadapter = nesdev->nesadapter;
2327 struct nes_vnic *nesvnic;
2328 u32 mac_status;
2329 u32 mac_index = nesdev->mac_index;
2330 u32 u32temp;
2331 u16 phy_data;
2332 u16 temp_phy_data;
Eric Schneider0e1de5d2008-04-29 13:46:54 -07002333 u32 pcs_val = 0x0f0f0000;
2334 u32 pcs_mask = 0x0f1f0000;
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002335
2336 spin_lock_irqsave(&nesadapter->phy_lock, flags);
2337 if (nesadapter->mac_sw_state[mac_number] != NES_MAC_SW_IDLE) {
2338 spin_unlock_irqrestore(&nesadapter->phy_lock, flags);
2339 return;
2340 }
2341 nesadapter->mac_sw_state[mac_number] = NES_MAC_SW_INTERRUPT;
2342 spin_unlock_irqrestore(&nesadapter->phy_lock, flags);
2343
2344 /* ack the MAC interrupt */
2345 mac_status = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (mac_index * 0x200));
2346 /* Clear the interrupt */
2347 nes_write_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (mac_index * 0x200), mac_status);
2348
2349 nes_debug(NES_DBG_PHY, "MAC%u interrupt status = 0x%X.\n", mac_number, mac_status);
2350
2351 if (mac_status & (NES_MAC_INT_LINK_STAT_CHG | NES_MAC_INT_XGMII_EXT)) {
2352 nesdev->link_status_interrupts++;
2353 if (0 == (++nesadapter->link_interrupt_count[mac_index] % ((u16)NES_MAX_LINK_INTERRUPTS))) {
2354 spin_lock_irqsave(&nesadapter->phy_lock, flags);
2355 nes_reset_link(nesdev, mac_index);
2356 spin_unlock_irqrestore(&nesadapter->phy_lock, flags);
2357 }
2358 /* read the PHY interrupt status register */
Chien Tungfcb7ad32008-09-30 14:49:44 -07002359 if ((nesadapter->OneG_Mode) &&
2360 (nesadapter->phy_type[mac_index] != NES_PHY_TYPE_PUMA_1G)) {
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002361 do {
2362 nes_read_1G_phy_reg(nesdev, 0x1a,
2363 nesadapter->phy_index[mac_index], &phy_data);
2364 nes_debug(NES_DBG_PHY, "Phy%d data from register 0x1a = 0x%X.\n",
2365 nesadapter->phy_index[mac_index], phy_data);
2366 } while (phy_data&0x8000);
2367
2368 temp_phy_data = 0;
2369 do {
2370 nes_read_1G_phy_reg(nesdev, 0x11,
2371 nesadapter->phy_index[mac_index], &phy_data);
2372 nes_debug(NES_DBG_PHY, "Phy%d data from register 0x11 = 0x%X.\n",
2373 nesadapter->phy_index[mac_index], phy_data);
2374 if (temp_phy_data == phy_data)
2375 break;
2376 temp_phy_data = phy_data;
2377 } while (1);
2378
2379 nes_read_1G_phy_reg(nesdev, 0x1e,
2380 nesadapter->phy_index[mac_index], &phy_data);
2381 nes_debug(NES_DBG_PHY, "Phy%d data from register 0x1e = 0x%X.\n",
2382 nesadapter->phy_index[mac_index], phy_data);
2383
2384 nes_read_1G_phy_reg(nesdev, 1,
2385 nesadapter->phy_index[mac_index], &phy_data);
2386 nes_debug(NES_DBG_PHY, "1G phy%u data from register 1 = 0x%X\n",
2387 nesadapter->phy_index[mac_index], phy_data);
2388
2389 if (temp_phy_data & 0x1000) {
2390 nes_debug(NES_DBG_PHY, "The Link is up according to the PHY\n");
2391 phy_data = 4;
2392 } else {
2393 nes_debug(NES_DBG_PHY, "The Link is down according to the PHY\n");
2394 }
2395 }
2396 nes_debug(NES_DBG_PHY, "Eth SERDES Common Status: 0=0x%08X, 1=0x%08X\n",
2397 nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_STATUS0),
2398 nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_STATUS0+0x200));
Eric Schneider0e1de5d2008-04-29 13:46:54 -07002399
2400 if (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_PUMA_1G) {
2401 switch (mac_index) {
2402 case 1:
2403 case 3:
2404 pcs_control_status = nes_read_indexed(nesdev,
2405 NES_IDX_PHY_PCS_CONTROL_STATUS0 + 0x200);
2406 break;
2407 default:
2408 pcs_control_status = nes_read_indexed(nesdev,
2409 NES_IDX_PHY_PCS_CONTROL_STATUS0);
2410 break;
2411 }
2412 } else {
2413 pcs_control_status = nes_read_indexed(nesdev,
2414 NES_IDX_PHY_PCS_CONTROL_STATUS0 + ((mac_index & 1) * 0x200));
2415 pcs_control_status = nes_read_indexed(nesdev,
2416 NES_IDX_PHY_PCS_CONTROL_STATUS0 + ((mac_index & 1) * 0x200));
2417 }
2418
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002419 nes_debug(NES_DBG_PHY, "PCS PHY Control/Status%u: 0x%08X\n",
2420 mac_index, pcs_control_status);
Eric Schneider0e1de5d2008-04-29 13:46:54 -07002421 if ((nesadapter->OneG_Mode) &&
2422 (nesadapter->phy_type[mac_index] != NES_PHY_TYPE_PUMA_1G)) {
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002423 u32temp = 0x01010000;
2424 if (nesadapter->port_count > 2) {
2425 u32temp |= 0x02020000;
2426 }
2427 if ((pcs_control_status & u32temp)!= u32temp) {
2428 phy_data = 0;
2429 nes_debug(NES_DBG_PHY, "PCS says the link is down\n");
2430 }
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002431 } else {
Eric Schneider0e1de5d2008-04-29 13:46:54 -07002432 switch (nesadapter->phy_type[mac_index]) {
2433 case NES_PHY_TYPE_IRIS:
2434 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1);
2435 temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
2436 u32temp = 20;
2437 do {
2438 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1);
2439 phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
2440 if ((phy_data == temp_phy_data) || (!(--u32temp)))
2441 break;
2442 temp_phy_data = phy_data;
2443 } while (1);
2444 nes_debug(NES_DBG_PHY, "%s: Phy data = 0x%04X, link was %s.\n",
2445 __func__, phy_data, nesadapter->mac_link_down[mac_index] ? "DOWN" : "UP");
2446 break;
2447
2448 case NES_PHY_TYPE_ARGUS:
2449 /* clear the alarms */
2450 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0x0008);
2451 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0xc001);
2452 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0xc002);
2453 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0xc005);
2454 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0xc006);
2455 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 0x9003);
2456 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 0x9004);
2457 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 0x9005);
2458 /* check link status */
2459 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1);
2460 temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
2461 u32temp = 100;
2462 do {
2463 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1);
2464
2465 phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
2466 if ((phy_data == temp_phy_data) || (!(--u32temp)))
2467 break;
2468 temp_phy_data = phy_data;
2469 } while (1);
2470 nes_debug(NES_DBG_PHY, "%s: Phy data = 0x%04X, link was %s.\n",
2471 __func__, phy_data, nesadapter->mac_link_down ? "DOWN" : "UP");
2472 break;
2473
2474 case NES_PHY_TYPE_PUMA_1G:
2475 if (mac_index < 2)
2476 pcs_val = pcs_mask = 0x01010000;
2477 else
2478 pcs_val = pcs_mask = 0x02020000;
2479 /* fall through */
2480 default:
2481 phy_data = (pcs_val == (pcs_control_status & pcs_mask)) ? 0x4 : 0x0;
2482 break;
2483 }
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002484 }
2485
2486 if (phy_data & 0x0004) {
2487 nesadapter->mac_link_down[mac_index] = 0;
2488 list_for_each_entry(nesvnic, &nesadapter->nesvnic_list[mac_index], list) {
2489 nes_debug(NES_DBG_PHY, "The Link is UP!!. linkup was %d\n",
2490 nesvnic->linkup);
2491 if (nesvnic->linkup == 0) {
Eric Schneider0e1de5d2008-04-29 13:46:54 -07002492 printk(PFX "The Link is now up for port %s, netdev %p.\n",
2493 nesvnic->netdev->name, nesvnic->netdev);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002494 if (netif_queue_stopped(nesvnic->netdev))
2495 netif_start_queue(nesvnic->netdev);
2496 nesvnic->linkup = 1;
2497 netif_carrier_on(nesvnic->netdev);
2498 }
2499 }
2500 } else {
2501 nesadapter->mac_link_down[mac_index] = 1;
2502 list_for_each_entry(nesvnic, &nesadapter->nesvnic_list[mac_index], list) {
2503 nes_debug(NES_DBG_PHY, "The Link is Down!!. linkup was %d\n",
2504 nesvnic->linkup);
2505 if (nesvnic->linkup == 1) {
Eric Schneider0e1de5d2008-04-29 13:46:54 -07002506 printk(PFX "The Link is now down for port %s, netdev %p.\n",
2507 nesvnic->netdev->name, nesvnic->netdev);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002508 if (!(netif_queue_stopped(nesvnic->netdev)))
2509 netif_stop_queue(nesvnic->netdev);
2510 nesvnic->linkup = 0;
2511 netif_carrier_off(nesvnic->netdev);
2512 }
2513 }
2514 }
2515 }
2516
2517 nesadapter->mac_sw_state[mac_number] = NES_MAC_SW_IDLE;
2518}
2519
2520
2521
Roland Dreier1a855fbf2008-04-16 21:01:09 -07002522static void nes_nic_napi_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq)
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002523{
2524 struct nes_vnic *nesvnic = container_of(cq, struct nes_vnic, nic_cq);
2525
2526 netif_rx_schedule(nesdev->netdev[nesvnic->netdev_index], &nesvnic->napi);
2527}
2528
2529
2530/* The MAX_RQES_TO_PROCESS defines how many max read requests to complete before
2531* getting out of nic_ce_handler
2532*/
2533#define MAX_RQES_TO_PROCESS 384
2534
2535/**
2536 * nes_nic_ce_handler
2537 */
2538void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq)
2539{
2540 u64 u64temp;
2541 dma_addr_t bus_address;
2542 struct nes_hw_nic *nesnic;
2543 struct nes_vnic *nesvnic = container_of(cq, struct nes_vnic, nic_cq);
2544 struct nes_adapter *nesadapter = nesdev->nesadapter;
2545 struct nes_hw_nic_rq_wqe *nic_rqe;
2546 struct nes_hw_nic_sq_wqe *nic_sqe;
2547 struct sk_buff *skb;
2548 struct sk_buff *rx_skb;
2549 __le16 *wqe_fragment_length;
2550 u32 head;
2551 u32 cq_size;
2552 u32 rx_pkt_size;
2553 u32 cqe_count=0;
2554 u32 cqe_errv;
2555 u32 cqe_misc;
2556 u16 wqe_fragment_index = 1; /* first fragment (0) is used by copy buffer */
2557 u16 vlan_tag;
2558 u16 pkt_type;
2559 u16 rqes_processed = 0;
2560 u8 sq_cqes = 0;
Faisal Latif37dab412008-04-29 13:46:54 -07002561 u8 nes_use_lro = 0;
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002562
2563 head = cq->cq_head;
2564 cq_size = cq->cq_size;
2565 cq->cqes_pending = 1;
Faisal Latif37dab412008-04-29 13:46:54 -07002566 if (nesvnic->netdev->features & NETIF_F_LRO)
2567 nes_use_lro = 1;
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002568 do {
2569 if (le32_to_cpu(cq->cq_vbase[head].cqe_words[NES_NIC_CQE_MISC_IDX]) &
2570 NES_NIC_CQE_VALID) {
2571 nesnic = &nesvnic->nic;
2572 cqe_misc = le32_to_cpu(cq->cq_vbase[head].cqe_words[NES_NIC_CQE_MISC_IDX]);
2573 if (cqe_misc & NES_NIC_CQE_SQ) {
2574 sq_cqes++;
2575 wqe_fragment_index = 1;
2576 nic_sqe = &nesnic->sq_vbase[nesnic->sq_tail];
2577 skb = nesnic->tx_skb[nesnic->sq_tail];
2578 wqe_fragment_length = (__le16 *)&nic_sqe->wqe_words[NES_NIC_SQ_WQE_LENGTH_0_TAG_IDX];
2579 /* bump past the vlan tag */
2580 wqe_fragment_length++;
2581 if (le16_to_cpu(wqe_fragment_length[wqe_fragment_index]) != 0) {
Glenn Streiff7495ab62008-04-29 13:46:54 -07002582 u64temp = (u64) le32_to_cpu(nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_LOW_IDX +
2583 wqe_fragment_index * 2]);
2584 u64temp += ((u64)le32_to_cpu(nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_HIGH_IDX +
2585 wqe_fragment_index * 2])) << 32;
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002586 bus_address = (dma_addr_t)u64temp;
2587 if (test_and_clear_bit(nesnic->sq_tail, nesnic->first_frag_overflow)) {
2588 pci_unmap_single(nesdev->pcidev,
2589 bus_address,
2590 le16_to_cpu(wqe_fragment_length[wqe_fragment_index++]),
2591 PCI_DMA_TODEVICE);
2592 }
2593 for (; wqe_fragment_index < 5; wqe_fragment_index++) {
2594 if (wqe_fragment_length[wqe_fragment_index]) {
Glenn Streiff7495ab62008-04-29 13:46:54 -07002595 u64temp = le32_to_cpu(nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_LOW_IDX +
2596 wqe_fragment_index * 2]);
2597 u64temp += ((u64)le32_to_cpu(nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_HIGH_IDX
2598 + wqe_fragment_index * 2])) <<32;
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002599 bus_address = (dma_addr_t)u64temp;
2600 pci_unmap_page(nesdev->pcidev,
2601 bus_address,
2602 le16_to_cpu(wqe_fragment_length[wqe_fragment_index]),
2603 PCI_DMA_TODEVICE);
2604 } else
2605 break;
2606 }
2607 if (skb)
2608 dev_kfree_skb_any(skb);
2609 }
2610 nesnic->sq_tail++;
2611 nesnic->sq_tail &= nesnic->sq_size-1;
2612 if (sq_cqes > 128) {
2613 barrier();
2614 /* restart the queue if it had been stopped */
2615 if (netif_queue_stopped(nesvnic->netdev))
2616 netif_wake_queue(nesvnic->netdev);
2617 sq_cqes = 0;
2618 }
2619 } else {
2620 rqes_processed ++;
2621
2622 cq->rx_cqes_completed++;
2623 cq->rx_pkts_indicated++;
2624 rx_pkt_size = cqe_misc & 0x0000ffff;
2625 nic_rqe = &nesnic->rq_vbase[nesnic->rq_tail];
2626 /* Get the skb */
2627 rx_skb = nesnic->rx_skb[nesnic->rq_tail];
2628 nic_rqe = &nesnic->rq_vbase[nesvnic->nic.rq_tail];
2629 bus_address = (dma_addr_t)le32_to_cpu(nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_LOW_IDX]);
2630 bus_address += ((u64)le32_to_cpu(nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_HIGH_IDX])) << 32;
2631 pci_unmap_single(nesdev->pcidev, bus_address,
2632 nesvnic->max_frame_size, PCI_DMA_FROMDEVICE);
2633 /* rx_skb->tail = rx_skb->data + rx_pkt_size; */
2634 /* rx_skb->len = rx_pkt_size; */
2635 rx_skb->len = 0; /* TODO: see if this is necessary */
2636 skb_put(rx_skb, rx_pkt_size);
2637 rx_skb->protocol = eth_type_trans(rx_skb, nesvnic->netdev);
2638 nesnic->rq_tail++;
2639 nesnic->rq_tail &= nesnic->rq_size - 1;
2640
2641 atomic_inc(&nesvnic->rx_skbs_needed);
2642 if (atomic_read(&nesvnic->rx_skbs_needed) > (nesvnic->nic.rq_size>>1)) {
2643 nes_write32(nesdev->regs+NES_CQE_ALLOC,
2644 cq->cq_number | (cqe_count << 16));
Glenn Streiff7495ab62008-04-29 13:46:54 -07002645 /* nesadapter->tune_timer.cq_count += cqe_count; */
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002646 nesdev->currcq_count += cqe_count;
2647 cqe_count = 0;
2648 nes_replenish_nic_rq(nesvnic);
2649 }
2650 pkt_type = (u16)(le32_to_cpu(cq->cq_vbase[head].cqe_words[NES_NIC_CQE_TAG_PKT_TYPE_IDX]));
2651 cqe_errv = (cqe_misc & NES_NIC_CQE_ERRV_MASK) >> NES_NIC_CQE_ERRV_SHIFT;
2652 rx_skb->ip_summed = CHECKSUM_NONE;
2653
2654 if ((NES_PKT_TYPE_TCPV4_BITS == (pkt_type & NES_PKT_TYPE_TCPV4_MASK)) ||
2655 (NES_PKT_TYPE_UDPV4_BITS == (pkt_type & NES_PKT_TYPE_UDPV4_MASK))) {
2656 if ((cqe_errv &
2657 (NES_NIC_ERRV_BITS_IPV4_CSUM_ERR | NES_NIC_ERRV_BITS_TCPUDP_CSUM_ERR |
2658 NES_NIC_ERRV_BITS_IPH_ERR | NES_NIC_ERRV_BITS_WQE_OVERRUN)) == 0) {
2659 if (nesvnic->rx_checksum_disabled == 0) {
2660 rx_skb->ip_summed = CHECKSUM_UNNECESSARY;
2661 }
2662 } else
2663 nes_debug(NES_DBG_CQ, "%s: unsuccessfully checksummed TCP or UDP packet."
2664 " errv = 0x%X, pkt_type = 0x%X.\n",
2665 nesvnic->netdev->name, cqe_errv, pkt_type);
2666
2667 } else if ((pkt_type & NES_PKT_TYPE_IPV4_MASK) == NES_PKT_TYPE_IPV4_BITS) {
2668 if ((cqe_errv &
2669 (NES_NIC_ERRV_BITS_IPV4_CSUM_ERR | NES_NIC_ERRV_BITS_IPH_ERR |
2670 NES_NIC_ERRV_BITS_WQE_OVERRUN)) == 0) {
2671 if (nesvnic->rx_checksum_disabled == 0) {
2672 rx_skb->ip_summed = CHECKSUM_UNNECESSARY;
2673 /* nes_debug(NES_DBG_CQ, "%s: Reporting successfully checksummed IPv4 packet.\n",
2674 nesvnic->netdev->name); */
2675 }
2676 } else
2677 nes_debug(NES_DBG_CQ, "%s: unsuccessfully checksummed TCP or UDP packet."
2678 " errv = 0x%X, pkt_type = 0x%X.\n",
2679 nesvnic->netdev->name, cqe_errv, pkt_type);
2680 }
2681 /* nes_debug(NES_DBG_CQ, "pkt_type=%x, APBVT_MASK=%x\n",
2682 pkt_type, (pkt_type & NES_PKT_TYPE_APBVT_MASK)); */
2683
2684 if ((pkt_type & NES_PKT_TYPE_APBVT_MASK) == NES_PKT_TYPE_APBVT_BITS) {
2685 nes_cm_recv(rx_skb, nesvnic->netdev);
2686 } else {
2687 if ((cqe_misc & NES_NIC_CQE_TAG_VALID) && (nesvnic->vlan_grp != NULL)) {
2688 vlan_tag = (u16)(le32_to_cpu(
2689 cq->cq_vbase[head].cqe_words[NES_NIC_CQE_TAG_PKT_TYPE_IDX])
2690 >> 16);
2691 nes_debug(NES_DBG_CQ, "%s: Reporting stripped VLAN packet. Tag = 0x%04X\n",
2692 nesvnic->netdev->name, vlan_tag);
Faisal Latif37dab412008-04-29 13:46:54 -07002693 if (nes_use_lro)
2694 lro_vlan_hwaccel_receive_skb(&nesvnic->lro_mgr, rx_skb,
2695 nesvnic->vlan_grp, vlan_tag, NULL);
2696 else
2697 nes_vlan_rx(rx_skb, nesvnic->vlan_grp, vlan_tag);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002698 } else {
Faisal Latif37dab412008-04-29 13:46:54 -07002699 if (nes_use_lro)
2700 lro_receive_skb(&nesvnic->lro_mgr, rx_skb, NULL);
2701 else
2702 nes_netif_rx(rx_skb);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002703 }
2704 }
2705
2706 nesvnic->netdev->last_rx = jiffies;
2707 /* nesvnic->netstats.rx_packets++; */
2708 /* nesvnic->netstats.rx_bytes += rx_pkt_size; */
2709 }
2710
2711 cq->cq_vbase[head].cqe_words[NES_NIC_CQE_MISC_IDX] = 0;
2712 /* Accounting... */
2713 cqe_count++;
2714 if (++head >= cq_size)
2715 head = 0;
2716 if (cqe_count == 255) {
2717 /* Replenish Nic CQ */
2718 nes_write32(nesdev->regs+NES_CQE_ALLOC,
2719 cq->cq_number | (cqe_count << 16));
Glenn Streiff7495ab62008-04-29 13:46:54 -07002720 /* nesdev->nesadapter->tune_timer.cq_count += cqe_count; */
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002721 nesdev->currcq_count += cqe_count;
2722 cqe_count = 0;
2723 }
2724
2725 if (cq->rx_cqes_completed >= nesvnic->budget)
2726 break;
2727 } else {
2728 cq->cqes_pending = 0;
2729 break;
2730 }
2731
2732 } while (1);
2733
Faisal Latif37dab412008-04-29 13:46:54 -07002734 if (nes_use_lro)
2735 lro_flush_all(&nesvnic->lro_mgr);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002736 if (sq_cqes) {
2737 barrier();
2738 /* restart the queue if it had been stopped */
2739 if (netif_queue_stopped(nesvnic->netdev))
2740 netif_wake_queue(nesvnic->netdev);
2741 }
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002742 cq->cq_head = head;
2743 /* nes_debug(NES_DBG_CQ, "CQ%u Processed = %u cqes, new head = %u.\n",
2744 cq->cq_number, cqe_count, cq->cq_head); */
2745 cq->cqe_allocs_pending = cqe_count;
2746 if (unlikely(nesadapter->et_use_adaptive_rx_coalesce))
2747 {
Glenn Streiff7495ab62008-04-29 13:46:54 -07002748 /* nesdev->nesadapter->tune_timer.cq_count += cqe_count; */
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002749 nesdev->currcq_count += cqe_count;
2750 nes_nic_tune_timer(nesdev);
2751 }
2752 if (atomic_read(&nesvnic->rx_skbs_needed))
2753 nes_replenish_nic_rq(nesvnic);
Faisal Latif37dab412008-04-29 13:46:54 -07002754}
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002755
2756
2757/**
2758 * nes_cqp_ce_handler
2759 */
Roland Dreier1a855fbf2008-04-16 21:01:09 -07002760static void nes_cqp_ce_handler(struct nes_device *nesdev, struct nes_hw_cq *cq)
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002761{
2762 u64 u64temp;
2763 unsigned long flags;
2764 struct nes_hw_cqp *cqp = NULL;
2765 struct nes_cqp_request *cqp_request;
2766 struct nes_hw_cqp_wqe *cqp_wqe;
2767 u32 head;
2768 u32 cq_size;
2769 u32 cqe_count=0;
2770 u32 error_code;
2771 /* u32 counter; */
2772
2773 head = cq->cq_head;
2774 cq_size = cq->cq_size;
2775
2776 do {
2777 /* process the CQE */
2778 /* nes_debug(NES_DBG_CQP, "head=%u cqe_words=%08X\n", head,
2779 le32_to_cpu(cq->cq_vbase[head].cqe_words[NES_CQE_OPCODE_IDX])); */
2780
2781 if (le32_to_cpu(cq->cq_vbase[head].cqe_words[NES_CQE_OPCODE_IDX]) & NES_CQE_VALID) {
2782 u64temp = (((u64)(le32_to_cpu(cq->cq_vbase[head].
Glenn Streiff7495ab62008-04-29 13:46:54 -07002783 cqe_words[NES_CQE_COMP_COMP_CTX_HIGH_IDX]))) << 32) |
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002784 ((u64)(le32_to_cpu(cq->cq_vbase[head].
2785 cqe_words[NES_CQE_COMP_COMP_CTX_LOW_IDX])));
2786 cqp = *((struct nes_hw_cqp **)&u64temp);
2787
2788 error_code = le32_to_cpu(cq->cq_vbase[head].cqe_words[NES_CQE_ERROR_CODE_IDX]);
2789 if (error_code) {
2790 nes_debug(NES_DBG_CQP, "Bad Completion code for opcode 0x%02X from CQP,"
2791 " Major/Minor codes = 0x%04X:%04X.\n",
2792 le32_to_cpu(cq->cq_vbase[head].cqe_words[NES_CQE_OPCODE_IDX])&0x3f,
2793 (u16)(error_code >> 16),
2794 (u16)error_code);
2795 nes_debug(NES_DBG_CQP, "cqp: qp_id=%u, sq_head=%u, sq_tail=%u\n",
2796 cqp->qp_id, cqp->sq_head, cqp->sq_tail);
2797 }
2798
2799 u64temp = (((u64)(le32_to_cpu(nesdev->cqp.sq_vbase[cqp->sq_tail].
Glenn Streiff7495ab62008-04-29 13:46:54 -07002800 wqe_words[NES_CQP_WQE_COMP_SCRATCH_HIGH_IDX]))) << 32) |
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002801 ((u64)(le32_to_cpu(nesdev->cqp.sq_vbase[cqp->sq_tail].
2802 wqe_words[NES_CQP_WQE_COMP_SCRATCH_LOW_IDX])));
2803 cqp_request = *((struct nes_cqp_request **)&u64temp);
2804 if (cqp_request) {
2805 if (cqp_request->waiting) {
2806 /* nes_debug(NES_DBG_CQP, "%s: Waking up requestor\n"); */
2807 cqp_request->major_code = (u16)(error_code >> 16);
2808 cqp_request->minor_code = (u16)error_code;
2809 barrier();
2810 cqp_request->request_done = 1;
2811 wake_up(&cqp_request->waitq);
Roland Dreier1ff66e82008-07-14 23:48:49 -07002812 nes_put_cqp_request(nesdev, cqp_request);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002813 } else {
Roland Dreier1ff66e82008-07-14 23:48:49 -07002814 if (cqp_request->callback)
2815 cqp_request->cqp_callback(nesdev, cqp_request);
2816 nes_free_cqp_request(nesdev, cqp_request);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002817 }
2818 } else {
2819 wake_up(&nesdev->cqp.waitq);
2820 }
2821
2822 cq->cq_vbase[head].cqe_words[NES_CQE_OPCODE_IDX] = 0;
Glenn Streiff7495ab62008-04-29 13:46:54 -07002823 nes_write32(nesdev->regs + NES_CQE_ALLOC, cq->cq_number | (1 << 16));
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002824 if (++cqp->sq_tail >= cqp->sq_size)
2825 cqp->sq_tail = 0;
2826
2827 /* Accounting... */
2828 cqe_count++;
2829 if (++head >= cq_size)
2830 head = 0;
2831 } else {
2832 break;
2833 }
2834 } while (1);
2835 cq->cq_head = head;
2836
2837 spin_lock_irqsave(&nesdev->cqp.lock, flags);
2838 while ((!list_empty(&nesdev->cqp_pending_reqs)) &&
2839 ((((nesdev->cqp.sq_tail+nesdev->cqp.sq_size)-nesdev->cqp.sq_head) &
2840 (nesdev->cqp.sq_size - 1)) != 1)) {
2841 cqp_request = list_entry(nesdev->cqp_pending_reqs.next,
2842 struct nes_cqp_request, list);
2843 list_del_init(&cqp_request->list);
2844 head = nesdev->cqp.sq_head++;
2845 nesdev->cqp.sq_head &= nesdev->cqp.sq_size-1;
2846 cqp_wqe = &nesdev->cqp.sq_vbase[head];
2847 memcpy(cqp_wqe, &cqp_request->cqp_wqe, sizeof(*cqp_wqe));
2848 barrier();
2849 cqp_wqe->wqe_words[NES_CQP_WQE_COMP_SCRATCH_LOW_IDX] =
2850 cpu_to_le32((u32)((unsigned long)cqp_request));
2851 cqp_wqe->wqe_words[NES_CQP_WQE_COMP_SCRATCH_HIGH_IDX] =
2852 cpu_to_le32((u32)(upper_32_bits((unsigned long)cqp_request)));
2853 nes_debug(NES_DBG_CQP, "CQP request %p (opcode 0x%02X) put on CQPs SQ wqe%u.\n",
2854 cqp_request, le32_to_cpu(cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX])&0x3f, head);
2855 /* Ring doorbell (1 WQEs) */
2856 barrier();
2857 nes_write32(nesdev->regs+NES_WQE_ALLOC, 0x01800000 | nesdev->cqp.qp_id);
2858 }
2859 spin_unlock_irqrestore(&nesdev->cqp.lock, flags);
2860
2861 /* Arm the CCQ */
2862 nes_write32(nesdev->regs+NES_CQE_ALLOC, NES_CQE_ALLOC_NOTIFY_NEXT |
2863 cq->cq_number);
2864 nes_read32(nesdev->regs+NES_CQE_ALLOC);
2865}
2866
2867
2868/**
2869 * nes_process_iwarp_aeqe
2870 */
Roland Dreier1a855fbf2008-04-16 21:01:09 -07002871static void nes_process_iwarp_aeqe(struct nes_device *nesdev,
2872 struct nes_hw_aeqe *aeqe)
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002873{
2874 u64 context;
2875 u64 aeqe_context = 0;
2876 unsigned long flags;
2877 struct nes_qp *nesqp;
2878 int resource_allocated;
2879 /* struct iw_cm_id *cm_id; */
2880 struct nes_adapter *nesadapter = nesdev->nesadapter;
2881 struct ib_event ibevent;
2882 /* struct iw_cm_event cm_event; */
2883 u32 aeq_info;
2884 u32 next_iwarp_state = 0;
2885 u16 async_event_id;
2886 u8 tcp_state;
2887 u8 iwarp_state;
2888
2889 nes_debug(NES_DBG_AEQ, "\n");
2890 aeq_info = le32_to_cpu(aeqe->aeqe_words[NES_AEQE_MISC_IDX]);
2891 if ((NES_AEQE_INBOUND_RDMA&aeq_info) || (!(NES_AEQE_QP&aeq_info))) {
Glenn Streiff7495ab62008-04-29 13:46:54 -07002892 context = le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_LOW_IDX]);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002893 context += ((u64)le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_HIGH_IDX])) << 32;
2894 } else {
2895 aeqe_context = le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_LOW_IDX]);
2896 aeqe_context += ((u64)le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_HIGH_IDX])) << 32;
2897 context = (unsigned long)nesadapter->qp_table[le32_to_cpu(
Glenn Streiff7495ab62008-04-29 13:46:54 -07002898 aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX]) - NES_FIRST_QPN];
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002899 BUG_ON(!context);
2900 }
2901
2902 async_event_id = (u16)aeq_info;
2903 tcp_state = (aeq_info & NES_AEQE_TCP_STATE_MASK) >> NES_AEQE_TCP_STATE_SHIFT;
2904 iwarp_state = (aeq_info & NES_AEQE_IWARP_STATE_MASK) >> NES_AEQE_IWARP_STATE_SHIFT;
2905 nes_debug(NES_DBG_AEQ, "aeid = 0x%04X, qp-cq id = %d, aeqe = %p,"
2906 " Tcp state = %s, iWARP state = %s\n",
2907 async_event_id,
2908 le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX]), aeqe,
2909 nes_tcp_state_str[tcp_state], nes_iwarp_state_str[iwarp_state]);
2910
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002911 switch (async_event_id) {
2912 case NES_AEQE_AEID_LLP_FIN_RECEIVED:
2913 nesqp = *((struct nes_qp **)&context);
2914 if (atomic_inc_return(&nesqp->close_timer_started) == 1) {
2915 nesqp->cm_id->add_ref(nesqp->cm_id);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002916 schedule_nes_timer(nesqp->cm_node, (struct sk_buff *)nesqp,
2917 NES_TIMER_TYPE_CLOSE, 1, 0);
2918 nes_debug(NES_DBG_AEQ, "QP%u Not decrementing QP refcount (%d),"
2919 " need ae to finish up, original_last_aeq = 0x%04X."
2920 " last_aeq = 0x%04X, scheduling timer. TCP state = %d\n",
2921 nesqp->hwqp.qp_id, atomic_read(&nesqp->refcount),
2922 async_event_id, nesqp->last_aeq, tcp_state);
2923 }
2924 if ((tcp_state != NES_AEQE_TCP_STATE_CLOSE_WAIT) ||
2925 (nesqp->ibqp_state != IB_QPS_RTS)) {
2926 /* FIN Received but tcp state or IB state moved on,
2927 should expect a close complete */
2928 return;
2929 }
2930 case NES_AEQE_AEID_LLP_CLOSE_COMPLETE:
2931 case NES_AEQE_AEID_LLP_CONNECTION_RESET:
2932 case NES_AEQE_AEID_TERMINATE_SENT:
2933 case NES_AEQE_AEID_RDMAP_ROE_BAD_LLP_CLOSE:
2934 case NES_AEQE_AEID_RESET_SENT:
2935 nesqp = *((struct nes_qp **)&context);
2936 if (async_event_id == NES_AEQE_AEID_RESET_SENT) {
2937 tcp_state = NES_AEQE_TCP_STATE_CLOSED;
2938 }
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002939 spin_lock_irqsave(&nesqp->lock, flags);
2940 nesqp->hw_iwarp_state = iwarp_state;
2941 nesqp->hw_tcp_state = tcp_state;
2942 nesqp->last_aeq = async_event_id;
2943
2944 if ((tcp_state == NES_AEQE_TCP_STATE_CLOSED) ||
2945 (tcp_state == NES_AEQE_TCP_STATE_TIME_WAIT)) {
2946 nesqp->hte_added = 0;
2947 spin_unlock_irqrestore(&nesqp->lock, flags);
2948 nes_debug(NES_DBG_AEQ, "issuing hw modifyqp for QP%u to remove hte\n",
2949 nesqp->hwqp.qp_id);
2950 nes_hw_modify_qp(nesdev, nesqp,
2951 NES_CQP_QP_IWARP_STATE_ERROR | NES_CQP_QP_DEL_HTE, 0);
2952 spin_lock_irqsave(&nesqp->lock, flags);
2953 }
2954
2955 if ((nesqp->ibqp_state == IB_QPS_RTS) &&
2956 ((tcp_state == NES_AEQE_TCP_STATE_CLOSE_WAIT) ||
2957 (async_event_id == NES_AEQE_AEID_LLP_CONNECTION_RESET))) {
2958 switch (nesqp->hw_iwarp_state) {
2959 case NES_AEQE_IWARP_STATE_RTS:
2960 next_iwarp_state = NES_CQP_QP_IWARP_STATE_CLOSING;
2961 nesqp->hw_iwarp_state = NES_AEQE_IWARP_STATE_CLOSING;
2962 break;
2963 case NES_AEQE_IWARP_STATE_TERMINATE:
2964 next_iwarp_state = NES_CQP_QP_IWARP_STATE_TERMINATE;
2965 nesqp->hw_iwarp_state = NES_AEQE_IWARP_STATE_TERMINATE;
2966 if (async_event_id == NES_AEQE_AEID_RDMAP_ROE_BAD_LLP_CLOSE) {
2967 next_iwarp_state |= 0x02000000;
2968 nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED;
2969 }
2970 break;
2971 default:
2972 next_iwarp_state = 0;
2973 }
2974 spin_unlock_irqrestore(&nesqp->lock, flags);
2975 if (next_iwarp_state) {
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002976 nes_debug(NES_DBG_AEQ, "issuing hw modifyqp for QP%u. next state = 0x%08X,"
2977 " also added another reference\n",
2978 nesqp->hwqp.qp_id, next_iwarp_state);
2979 nes_hw_modify_qp(nesdev, nesqp, next_iwarp_state, 0);
2980 }
2981 nes_cm_disconn(nesqp);
2982 } else {
2983 if (async_event_id == NES_AEQE_AEID_LLP_FIN_RECEIVED) {
2984 /* FIN Received but ib state not RTS,
2985 close complete will be on its way */
2986 spin_unlock_irqrestore(&nesqp->lock, flags);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002987 return;
2988 }
2989 spin_unlock_irqrestore(&nesqp->lock, flags);
2990 if (async_event_id == NES_AEQE_AEID_RDMAP_ROE_BAD_LLP_CLOSE) {
2991 next_iwarp_state = NES_CQP_QP_IWARP_STATE_TERMINATE | 0x02000000;
2992 nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED;
2993 nes_debug(NES_DBG_AEQ, "issuing hw modifyqp for QP%u. next state = 0x%08X,"
2994 " also added another reference\n",
2995 nesqp->hwqp.qp_id, next_iwarp_state);
2996 nes_hw_modify_qp(nesdev, nesqp, next_iwarp_state, 0);
2997 }
2998 nes_cm_disconn(nesqp);
2999 }
3000 break;
3001 case NES_AEQE_AEID_LLP_TERMINATE_RECEIVED:
3002 nesqp = *((struct nes_qp **)&context);
3003 spin_lock_irqsave(&nesqp->lock, flags);
3004 nesqp->hw_iwarp_state = iwarp_state;
3005 nesqp->hw_tcp_state = tcp_state;
3006 nesqp->last_aeq = async_event_id;
3007 spin_unlock_irqrestore(&nesqp->lock, flags);
3008 nes_debug(NES_DBG_AEQ, "Processing an NES_AEQE_AEID_LLP_TERMINATE_RECEIVED"
3009 " event on QP%u \n Q2 Data:\n",
3010 nesqp->hwqp.qp_id);
3011 if (nesqp->ibqp.event_handler) {
3012 ibevent.device = nesqp->ibqp.device;
3013 ibevent.element.qp = &nesqp->ibqp;
3014 ibevent.event = IB_EVENT_QP_FATAL;
3015 nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context);
3016 }
3017 if ((tcp_state == NES_AEQE_TCP_STATE_CLOSE_WAIT) ||
3018 ((nesqp->ibqp_state == IB_QPS_RTS)&&
3019 (async_event_id == NES_AEQE_AEID_LLP_CONNECTION_RESET))) {
Glenn Streiff3c2d7742008-02-04 20:20:45 -08003020 nes_cm_disconn(nesqp);
3021 } else {
3022 nesqp->in_disconnect = 0;
3023 wake_up(&nesqp->kick_waitq);
3024 }
3025 break;
3026 case NES_AEQE_AEID_LLP_TOO_MANY_RETRIES:
3027 nesqp = *((struct nes_qp **)&context);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08003028 spin_lock_irqsave(&nesqp->lock, flags);
3029 nesqp->hw_iwarp_state = NES_AEQE_IWARP_STATE_ERROR;
3030 nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED;
3031 nesqp->last_aeq = async_event_id;
3032 if (nesqp->cm_id) {
3033 nes_debug(NES_DBG_AEQ, "Processing an NES_AEQE_AEID_LLP_TOO_MANY_RETRIES"
3034 " event on QP%u, remote IP = 0x%08X \n",
3035 nesqp->hwqp.qp_id,
3036 ntohl(nesqp->cm_id->remote_addr.sin_addr.s_addr));
3037 } else {
3038 nes_debug(NES_DBG_AEQ, "Processing an NES_AEQE_AEID_LLP_TOO_MANY_RETRIES"
3039 " event on QP%u \n",
3040 nesqp->hwqp.qp_id);
3041 }
3042 spin_unlock_irqrestore(&nesqp->lock, flags);
3043 next_iwarp_state = NES_CQP_QP_IWARP_STATE_ERROR | NES_CQP_QP_RESET;
3044 nes_hw_modify_qp(nesdev, nesqp, next_iwarp_state, 0);
3045 if (nesqp->ibqp.event_handler) {
3046 ibevent.device = nesqp->ibqp.device;
3047 ibevent.element.qp = &nesqp->ibqp;
3048 ibevent.event = IB_EVENT_QP_FATAL;
3049 nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context);
3050 }
3051 break;
3052 case NES_AEQE_AEID_AMP_BAD_STAG_INDEX:
3053 if (NES_AEQE_INBOUND_RDMA&aeq_info) {
3054 nesqp = nesadapter->qp_table[le32_to_cpu(
3055 aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX])-NES_FIRST_QPN];
3056 } else {
3057 /* TODO: get the actual WQE and mask off wqe index */
3058 context &= ~((u64)511);
3059 nesqp = *((struct nes_qp **)&context);
3060 }
3061 spin_lock_irqsave(&nesqp->lock, flags);
3062 nesqp->hw_iwarp_state = iwarp_state;
3063 nesqp->hw_tcp_state = tcp_state;
3064 nesqp->last_aeq = async_event_id;
3065 spin_unlock_irqrestore(&nesqp->lock, flags);
3066 nes_debug(NES_DBG_AEQ, "Processing an NES_AEQE_AEID_AMP_BAD_STAG_INDEX event on QP%u\n",
3067 nesqp->hwqp.qp_id);
3068 if (nesqp->ibqp.event_handler) {
3069 ibevent.device = nesqp->ibqp.device;
3070 ibevent.element.qp = &nesqp->ibqp;
3071 ibevent.event = IB_EVENT_QP_ACCESS_ERR;
3072 nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context);
3073 }
3074 break;
3075 case NES_AEQE_AEID_AMP_UNALLOCATED_STAG:
3076 nesqp = *((struct nes_qp **)&context);
3077 spin_lock_irqsave(&nesqp->lock, flags);
3078 nesqp->hw_iwarp_state = iwarp_state;
3079 nesqp->hw_tcp_state = tcp_state;
3080 nesqp->last_aeq = async_event_id;
3081 spin_unlock_irqrestore(&nesqp->lock, flags);
3082 nes_debug(NES_DBG_AEQ, "Processing an NES_AEQE_AEID_AMP_UNALLOCATED_STAG event on QP%u\n",
3083 nesqp->hwqp.qp_id);
3084 if (nesqp->ibqp.event_handler) {
3085 ibevent.device = nesqp->ibqp.device;
3086 ibevent.element.qp = &nesqp->ibqp;
3087 ibevent.event = IB_EVENT_QP_ACCESS_ERR;
3088 nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context);
3089 }
3090 break;
3091 case NES_AEQE_AEID_PRIV_OPERATION_DENIED:
3092 nesqp = nesadapter->qp_table[le32_to_cpu(aeqe->aeqe_words
3093 [NES_AEQE_COMP_QP_CQ_ID_IDX])-NES_FIRST_QPN];
3094 spin_lock_irqsave(&nesqp->lock, flags);
3095 nesqp->hw_iwarp_state = iwarp_state;
3096 nesqp->hw_tcp_state = tcp_state;
3097 nesqp->last_aeq = async_event_id;
3098 spin_unlock_irqrestore(&nesqp->lock, flags);
3099 nes_debug(NES_DBG_AEQ, "Processing an NES_AEQE_AEID_PRIV_OPERATION_DENIED event on QP%u,"
3100 " nesqp = %p, AE reported %p\n",
3101 nesqp->hwqp.qp_id, nesqp, *((struct nes_qp **)&context));
3102 if (nesqp->ibqp.event_handler) {
3103 ibevent.device = nesqp->ibqp.device;
3104 ibevent.element.qp = &nesqp->ibqp;
3105 ibevent.event = IB_EVENT_QP_ACCESS_ERR;
3106 nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context);
3107 }
3108 break;
3109 case NES_AEQE_AEID_CQ_OPERATION_ERROR:
3110 context <<= 1;
3111 nes_debug(NES_DBG_AEQ, "Processing an NES_AEQE_AEID_CQ_OPERATION_ERROR event on CQ%u, %p\n",
3112 le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX]), (void *)(unsigned long)context);
3113 resource_allocated = nes_is_resource_allocated(nesadapter, nesadapter->allocated_cqs,
3114 le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX]));
3115 if (resource_allocated) {
3116 printk(KERN_ERR PFX "%s: Processing an NES_AEQE_AEID_CQ_OPERATION_ERROR event on CQ%u\n",
Harvey Harrison33718362008-04-16 21:01:10 -07003117 __func__, le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX]));
Glenn Streiff3c2d7742008-02-04 20:20:45 -08003118 }
3119 break;
3120 case NES_AEQE_AEID_DDP_UBE_DDP_MESSAGE_TOO_LONG_FOR_AVAILABLE_BUFFER:
3121 nesqp = nesadapter->qp_table[le32_to_cpu(
3122 aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX])-NES_FIRST_QPN];
3123 spin_lock_irqsave(&nesqp->lock, flags);
3124 nesqp->hw_iwarp_state = iwarp_state;
3125 nesqp->hw_tcp_state = tcp_state;
3126 nesqp->last_aeq = async_event_id;
3127 spin_unlock_irqrestore(&nesqp->lock, flags);
3128 nes_debug(NES_DBG_AEQ, "Processing an NES_AEQE_AEID_DDP_UBE_DDP_MESSAGE_TOO_LONG"
3129 "_FOR_AVAILABLE_BUFFER event on QP%u\n",
3130 nesqp->hwqp.qp_id);
3131 if (nesqp->ibqp.event_handler) {
3132 ibevent.device = nesqp->ibqp.device;
3133 ibevent.element.qp = &nesqp->ibqp;
3134 ibevent.event = IB_EVENT_QP_ACCESS_ERR;
3135 nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context);
3136 }
3137 /* tell cm to disconnect, cm will queue work to thread */
Glenn Streiff3c2d7742008-02-04 20:20:45 -08003138 nes_cm_disconn(nesqp);
3139 break;
3140 case NES_AEQE_AEID_DDP_UBE_INVALID_MSN_NO_BUFFER_AVAILABLE:
3141 nesqp = *((struct nes_qp **)&context);
3142 spin_lock_irqsave(&nesqp->lock, flags);
3143 nesqp->hw_iwarp_state = iwarp_state;
3144 nesqp->hw_tcp_state = tcp_state;
3145 nesqp->last_aeq = async_event_id;
3146 spin_unlock_irqrestore(&nesqp->lock, flags);
3147 nes_debug(NES_DBG_AEQ, "Processing an NES_AEQE_AEID_DDP_UBE_INVALID_MSN"
3148 "_NO_BUFFER_AVAILABLE event on QP%u\n",
3149 nesqp->hwqp.qp_id);
3150 if (nesqp->ibqp.event_handler) {
3151 ibevent.device = nesqp->ibqp.device;
3152 ibevent.element.qp = &nesqp->ibqp;
3153 ibevent.event = IB_EVENT_QP_FATAL;
3154 nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context);
3155 }
3156 /* tell cm to disconnect, cm will queue work to thread */
Glenn Streiff3c2d7742008-02-04 20:20:45 -08003157 nes_cm_disconn(nesqp);
3158 break;
3159 case NES_AEQE_AEID_LLP_RECEIVED_MPA_CRC_ERROR:
3160 nesqp = *((struct nes_qp **)&context);
3161 spin_lock_irqsave(&nesqp->lock, flags);
3162 nesqp->hw_iwarp_state = iwarp_state;
3163 nesqp->hw_tcp_state = tcp_state;
3164 nesqp->last_aeq = async_event_id;
3165 spin_unlock_irqrestore(&nesqp->lock, flags);
3166 nes_debug(NES_DBG_AEQ, "Processing an NES_AEQE_AEID_LLP_RECEIVED_MPA_CRC_ERROR"
3167 " event on QP%u \n Q2 Data:\n",
3168 nesqp->hwqp.qp_id);
3169 if (nesqp->ibqp.event_handler) {
3170 ibevent.device = nesqp->ibqp.device;
3171 ibevent.element.qp = &nesqp->ibqp;
3172 ibevent.event = IB_EVENT_QP_FATAL;
3173 nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context);
3174 }
3175 /* tell cm to disconnect, cm will queue work to thread */
Glenn Streiff3c2d7742008-02-04 20:20:45 -08003176 nes_cm_disconn(nesqp);
3177 break;
3178 /* TODO: additional AEs need to be here */
3179 default:
3180 nes_debug(NES_DBG_AEQ, "Processing an iWARP related AE for QP, misc = 0x%04X\n",
3181 async_event_id);
3182 break;
3183 }
3184
3185}
3186
3187
3188/**
3189 * nes_iwarp_ce_handler
3190 */
3191void nes_iwarp_ce_handler(struct nes_device *nesdev, struct nes_hw_cq *hw_cq)
3192{
3193 struct nes_cq *nescq = container_of(hw_cq, struct nes_cq, hw_cq);
3194
3195 /* nes_debug(NES_DBG_CQ, "Processing completion event for iWARP CQ%u.\n",
3196 nescq->hw_cq.cq_number); */
3197 nes_write32(nesdev->regs+NES_CQ_ACK, nescq->hw_cq.cq_number);
3198
3199 if (nescq->ibcq.comp_handler)
3200 nescq->ibcq.comp_handler(&nescq->ibcq, nescq->ibcq.cq_context);
3201
3202 return;
3203}
3204
3205
3206/**
3207 * nes_manage_apbvt()
3208 */
3209int nes_manage_apbvt(struct nes_vnic *nesvnic, u32 accel_local_port,
3210 u32 nic_index, u32 add_port)
3211{
3212 struct nes_device *nesdev = nesvnic->nesdev;
3213 struct nes_hw_cqp_wqe *cqp_wqe;
Glenn Streiff3c2d7742008-02-04 20:20:45 -08003214 struct nes_cqp_request *cqp_request;
3215 int ret = 0;
3216 u16 major_code;
3217
3218 /* Send manage APBVT request to CQP */
3219 cqp_request = nes_get_cqp_request(nesdev);
3220 if (cqp_request == NULL) {
3221 nes_debug(NES_DBG_QP, "Failed to get a cqp_request.\n");
3222 return -ENOMEM;
3223 }
3224 cqp_request->waiting = 1;
3225 cqp_wqe = &cqp_request->cqp_wqe;
3226
3227 nes_debug(NES_DBG_QP, "%s APBV for local port=%u(0x%04x), nic_index=%u\n",
3228 (add_port == NES_MANAGE_APBVT_ADD) ? "ADD" : "DEL",
3229 accel_local_port, accel_local_port, nic_index);
3230
3231 nes_fill_init_cqp_wqe(cqp_wqe, nesdev);
3232 set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_OPCODE_IDX, (NES_CQP_MANAGE_APBVT |
3233 ((add_port == NES_MANAGE_APBVT_ADD) ? NES_CQP_APBVT_ADD : 0)));
3234 set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_ID_IDX,
3235 ((nic_index << NES_CQP_APBVT_NIC_SHIFT) | accel_local_port));
3236
3237 nes_debug(NES_DBG_QP, "Waiting for CQP completion for APBVT.\n");
3238
3239 atomic_set(&cqp_request->refcount, 2);
Roland Dreier8294f292008-07-14 23:48:49 -07003240 nes_post_cqp_request(nesdev, cqp_request);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08003241
3242 if (add_port == NES_MANAGE_APBVT_ADD)
3243 ret = wait_event_timeout(cqp_request->waitq, (cqp_request->request_done != 0),
3244 NES_EVENT_TIMEOUT);
3245 nes_debug(NES_DBG_QP, "Completed, ret=%u, CQP Major:Minor codes = 0x%04X:0x%04X\n",
3246 ret, cqp_request->major_code, cqp_request->minor_code);
3247 major_code = cqp_request->major_code;
Roland Dreier1ff66e82008-07-14 23:48:49 -07003248
3249 nes_put_cqp_request(nesdev, cqp_request);
3250
Glenn Streiff3c2d7742008-02-04 20:20:45 -08003251 if (!ret)
3252 return -ETIME;
3253 else if (major_code)
3254 return -EIO;
3255 else
3256 return 0;
3257}
3258
3259
3260/**
3261 * nes_manage_arp_cache
3262 */
3263void nes_manage_arp_cache(struct net_device *netdev, unsigned char *mac_addr,
3264 u32 ip_addr, u32 action)
3265{
3266 struct nes_hw_cqp_wqe *cqp_wqe;
3267 struct nes_vnic *nesvnic = netdev_priv(netdev);
3268 struct nes_device *nesdev;
3269 struct nes_cqp_request *cqp_request;
3270 int arp_index;
3271
3272 nesdev = nesvnic->nesdev;
3273 arp_index = nes_arp_table(nesdev, ip_addr, mac_addr, action);
3274 if (arp_index == -1) {
3275 return;
3276 }
3277
3278 /* update the ARP entry */
3279 cqp_request = nes_get_cqp_request(nesdev);
3280 if (cqp_request == NULL) {
3281 nes_debug(NES_DBG_NETDEV, "Failed to get a cqp_request.\n");
3282 return;
3283 }
3284 cqp_request->waiting = 0;
3285 cqp_wqe = &cqp_request->cqp_wqe;
3286 nes_fill_init_cqp_wqe(cqp_wqe, nesdev);
3287
3288 cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] = cpu_to_le32(
3289 NES_CQP_MANAGE_ARP_CACHE | NES_CQP_ARP_PERM);
3290 cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] |= cpu_to_le32(
3291 (u32)PCI_FUNC(nesdev->pcidev->devfn) << NES_CQP_ARP_AEQ_INDEX_SHIFT);
3292 cqp_wqe->wqe_words[NES_CQP_WQE_ID_IDX] = cpu_to_le32(arp_index);
3293
3294 if (action == NES_ARP_ADD) {
3295 cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] |= cpu_to_le32(NES_CQP_ARP_VALID);
3296 cqp_wqe->wqe_words[NES_CQP_ARP_WQE_MAC_ADDR_LOW_IDX] = cpu_to_le32(
3297 (((u32)mac_addr[2]) << 24) | (((u32)mac_addr[3]) << 16) |
Glenn Streiff7495ab62008-04-29 13:46:54 -07003298 (((u32)mac_addr[4]) << 8) | (u32)mac_addr[5]);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08003299 cqp_wqe->wqe_words[NES_CQP_ARP_WQE_MAC_HIGH_IDX] = cpu_to_le32(
3300 (((u32)mac_addr[0]) << 16) | (u32)mac_addr[1]);
3301 } else {
3302 cqp_wqe->wqe_words[NES_CQP_ARP_WQE_MAC_ADDR_LOW_IDX] = 0;
3303 cqp_wqe->wqe_words[NES_CQP_ARP_WQE_MAC_HIGH_IDX] = 0;
3304 }
3305
3306 nes_debug(NES_DBG_NETDEV, "Not waiting for CQP, cqp.sq_head=%u, cqp.sq_tail=%u\n",
3307 nesdev->cqp.sq_head, nesdev->cqp.sq_tail);
3308
3309 atomic_set(&cqp_request->refcount, 1);
Roland Dreier8294f292008-07-14 23:48:49 -07003310 nes_post_cqp_request(nesdev, cqp_request);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08003311}
3312
3313
3314/**
3315 * flush_wqes
3316 */
3317void flush_wqes(struct nes_device *nesdev, struct nes_qp *nesqp,
3318 u32 which_wq, u32 wait_completion)
3319{
Glenn Streiff3c2d7742008-02-04 20:20:45 -08003320 struct nes_cqp_request *cqp_request;
3321 struct nes_hw_cqp_wqe *cqp_wqe;
3322 int ret;
3323
3324 cqp_request = nes_get_cqp_request(nesdev);
3325 if (cqp_request == NULL) {
3326 nes_debug(NES_DBG_QP, "Failed to get a cqp_request.\n");
3327 return;
3328 }
3329 if (wait_completion) {
3330 cqp_request->waiting = 1;
3331 atomic_set(&cqp_request->refcount, 2);
3332 } else {
3333 cqp_request->waiting = 0;
3334 }
3335 cqp_wqe = &cqp_request->cqp_wqe;
3336 nes_fill_init_cqp_wqe(cqp_wqe, nesdev);
3337
3338 cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] =
3339 cpu_to_le32(NES_CQP_FLUSH_WQES | which_wq);
3340 cqp_wqe->wqe_words[NES_CQP_WQE_ID_IDX] = cpu_to_le32(nesqp->hwqp.qp_id);
3341
Roland Dreier8294f292008-07-14 23:48:49 -07003342 nes_post_cqp_request(nesdev, cqp_request);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08003343
3344 if (wait_completion) {
3345 /* Wait for CQP */
3346 ret = wait_event_timeout(cqp_request->waitq, (cqp_request->request_done != 0),
3347 NES_EVENT_TIMEOUT);
3348 nes_debug(NES_DBG_QP, "Flush SQ QP WQEs completed, ret=%u,"
3349 " CQP Major:Minor codes = 0x%04X:0x%04X\n",
3350 ret, cqp_request->major_code, cqp_request->minor_code);
Roland Dreier1ff66e82008-07-14 23:48:49 -07003351 nes_put_cqp_request(nesdev, cqp_request);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08003352 }
3353}