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