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