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