blob: bdd98e66f432ff5158a9c4201ec08388f2a4635d [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); */
864 nes_write_indexed(nesdev, 0x00005004, 0x00020001);
865 nes_write_indexed(nesdev, 0x00005008, 0x1F1F1F1F);
866 nes_write_indexed(nesdev, 0x00005010, 0x1F1F1F1F);
867 nes_write_indexed(nesdev, 0x00005018, 0x1F1F1F1F);
868 nes_write_indexed(nesdev, 0x00005020, 0x1F1F1F1F);
869 nes_write_indexed(nesdev, 0x00006090, 0xFFFFFFFF);
870
871 /* TODO: move this to code, get from EEPROM */
872 nes_write_indexed(nesdev, 0x00000900, 0x20000001);
873 nes_write_indexed(nesdev, 0x000060C0, 0x0000028e);
874 nes_write_indexed(nesdev, 0x000060C8, 0x00000020);
Glenn Streiff7495ab62008-04-29 13:46:54 -0700875
Glenn Streiff3c2d7742008-02-04 20:20:45 -0800876 nes_write_indexed(nesdev, 0x000001EC, 0x7b2625a0);
877 /* nes_write_indexed(nesdev, 0x000001EC, 0x5f2625a0); */
878
879 if (hw_rev != NE020_REV) {
880 u32temp = nes_read_indexed(nesdev, 0x000008e8);
881 u32temp |= 0x80000000;
882 nes_write_indexed(nesdev, 0x000008e8, u32temp);
883 u32temp = nes_read_indexed(nesdev, 0x000021f8);
884 u32temp &= 0x7fffffff;
885 u32temp |= 0x7fff0010;
886 nes_write_indexed(nesdev, 0x000021f8, u32temp);
887 }
888}
889
890
891/**
892 * nes_destroy_adapter - destroy the adapter structure
893 */
894void nes_destroy_adapter(struct nes_adapter *nesadapter)
895{
896 struct nes_adapter *tmp_adapter;
897
898 list_for_each_entry(tmp_adapter, &nes_adapter_list, list) {
899 nes_debug(NES_DBG_SHUTDOWN, "Nes Adapter list entry = 0x%p.\n",
900 tmp_adapter);
901 }
902
903 nesadapter->ref_count--;
904 if (!nesadapter->ref_count) {
905 if (nesadapter->hw_rev == NE020_REV) {
906 del_timer(&nesadapter->mh_timer);
907 }
908 del_timer(&nesadapter->lc_timer);
909
910 list_del(&nesadapter->list);
911 kfree(nesadapter);
912 }
913}
914
915
916/**
917 * nes_init_cqp
918 */
919int nes_init_cqp(struct nes_device *nesdev)
920{
921 struct nes_adapter *nesadapter = nesdev->nesadapter;
922 struct nes_hw_cqp_qp_context *cqp_qp_context;
923 struct nes_hw_cqp_wqe *cqp_wqe;
924 struct nes_hw_ceq *ceq;
925 struct nes_hw_ceq *nic_ceq;
926 struct nes_hw_aeq *aeq;
927 void *vmem;
928 dma_addr_t pmem;
929 u32 count=0;
930 u32 cqp_head;
931 u64 u64temp;
932 u32 u32temp;
933
934 /* allocate CQP memory */
935 /* Need to add max_cq to the aeq size once cq overflow checking is added back */
936 /* SQ is 512 byte aligned, others are 256 byte aligned */
937 nesdev->cqp_mem_size = 512 +
938 (sizeof(struct nes_hw_cqp_wqe) * NES_CQP_SQ_SIZE) +
939 (sizeof(struct nes_hw_cqe) * NES_CCQ_SIZE) +
940 max(((u32)sizeof(struct nes_hw_ceqe) * NES_CCEQ_SIZE), (u32)256) +
941 max(((u32)sizeof(struct nes_hw_ceqe) * NES_NIC_CEQ_SIZE), (u32)256) +
942 (sizeof(struct nes_hw_aeqe) * nesadapter->max_qp) +
943 sizeof(struct nes_hw_cqp_qp_context);
944
945 nesdev->cqp_vbase = pci_alloc_consistent(nesdev->pcidev, nesdev->cqp_mem_size,
946 &nesdev->cqp_pbase);
947 if (!nesdev->cqp_vbase) {
948 nes_debug(NES_DBG_INIT, "Unable to allocate memory for host descriptor rings\n");
949 return -ENOMEM;
950 }
951 memset(nesdev->cqp_vbase, 0, nesdev->cqp_mem_size);
952
953 /* Allocate a twice the number of CQP requests as the SQ size */
954 nesdev->nes_cqp_requests = kzalloc(sizeof(struct nes_cqp_request) *
955 2 * NES_CQP_SQ_SIZE, GFP_KERNEL);
956 if (nesdev->nes_cqp_requests == NULL) {
957 nes_debug(NES_DBG_INIT, "Unable to allocate memory CQP request entries.\n");
958 pci_free_consistent(nesdev->pcidev, nesdev->cqp_mem_size, nesdev->cqp.sq_vbase,
959 nesdev->cqp.sq_pbase);
960 return -ENOMEM;
961 }
962
963 nes_debug(NES_DBG_INIT, "Allocated CQP structures at %p (phys = %016lX), size = %u.\n",
964 nesdev->cqp_vbase, (unsigned long)nesdev->cqp_pbase, nesdev->cqp_mem_size);
965
966 spin_lock_init(&nesdev->cqp.lock);
967 init_waitqueue_head(&nesdev->cqp.waitq);
968
969 /* Setup Various Structures */
970 vmem = (void *)(((unsigned long)nesdev->cqp_vbase + (512 - 1)) &
971 ~(unsigned long)(512 - 1));
972 pmem = (dma_addr_t)(((unsigned long long)nesdev->cqp_pbase + (512 - 1)) &
973 ~(unsigned long long)(512 - 1));
974
975 nesdev->cqp.sq_vbase = vmem;
976 nesdev->cqp.sq_pbase = pmem;
977 nesdev->cqp.sq_size = NES_CQP_SQ_SIZE;
978 nesdev->cqp.sq_head = 0;
979 nesdev->cqp.sq_tail = 0;
980 nesdev->cqp.qp_id = PCI_FUNC(nesdev->pcidev->devfn);
981
982 vmem += (sizeof(struct nes_hw_cqp_wqe) * nesdev->cqp.sq_size);
983 pmem += (sizeof(struct nes_hw_cqp_wqe) * nesdev->cqp.sq_size);
984
985 nesdev->ccq.cq_vbase = vmem;
986 nesdev->ccq.cq_pbase = pmem;
987 nesdev->ccq.cq_size = NES_CCQ_SIZE;
988 nesdev->ccq.cq_head = 0;
989 nesdev->ccq.ce_handler = nes_cqp_ce_handler;
990 nesdev->ccq.cq_number = PCI_FUNC(nesdev->pcidev->devfn);
991
992 vmem += (sizeof(struct nes_hw_cqe) * nesdev->ccq.cq_size);
993 pmem += (sizeof(struct nes_hw_cqe) * nesdev->ccq.cq_size);
994
995 nesdev->ceq_index = PCI_FUNC(nesdev->pcidev->devfn);
996 ceq = &nesadapter->ceq[nesdev->ceq_index];
997 ceq->ceq_vbase = vmem;
998 ceq->ceq_pbase = pmem;
999 ceq->ceq_size = NES_CCEQ_SIZE;
1000 ceq->ceq_head = 0;
1001
1002 vmem += max(((u32)sizeof(struct nes_hw_ceqe) * ceq->ceq_size), (u32)256);
1003 pmem += max(((u32)sizeof(struct nes_hw_ceqe) * ceq->ceq_size), (u32)256);
1004
1005 nesdev->nic_ceq_index = PCI_FUNC(nesdev->pcidev->devfn) + 8;
1006 nic_ceq = &nesadapter->ceq[nesdev->nic_ceq_index];
1007 nic_ceq->ceq_vbase = vmem;
1008 nic_ceq->ceq_pbase = pmem;
1009 nic_ceq->ceq_size = NES_NIC_CEQ_SIZE;
1010 nic_ceq->ceq_head = 0;
1011
1012 vmem += max(((u32)sizeof(struct nes_hw_ceqe) * nic_ceq->ceq_size), (u32)256);
1013 pmem += max(((u32)sizeof(struct nes_hw_ceqe) * nic_ceq->ceq_size), (u32)256);
1014
1015 aeq = &nesadapter->aeq[PCI_FUNC(nesdev->pcidev->devfn)];
1016 aeq->aeq_vbase = vmem;
1017 aeq->aeq_pbase = pmem;
1018 aeq->aeq_size = nesadapter->max_qp;
1019 aeq->aeq_head = 0;
1020
1021 /* Setup QP Context */
1022 vmem += (sizeof(struct nes_hw_aeqe) * aeq->aeq_size);
1023 pmem += (sizeof(struct nes_hw_aeqe) * aeq->aeq_size);
1024
1025 cqp_qp_context = vmem;
1026 cqp_qp_context->context_words[0] =
1027 cpu_to_le32((PCI_FUNC(nesdev->pcidev->devfn) << 12) + (2 << 10));
1028 cqp_qp_context->context_words[1] = 0;
1029 cqp_qp_context->context_words[2] = cpu_to_le32((u32)nesdev->cqp.sq_pbase);
1030 cqp_qp_context->context_words[3] = cpu_to_le32(((u64)nesdev->cqp.sq_pbase) >> 32);
1031
1032
1033 /* Write the address to Create CQP */
1034 if ((sizeof(dma_addr_t) > 4)) {
1035 nes_write_indexed(nesdev,
1036 NES_IDX_CREATE_CQP_HIGH + (PCI_FUNC(nesdev->pcidev->devfn) * 8),
1037 ((u64)pmem) >> 32);
1038 } else {
1039 nes_write_indexed(nesdev,
1040 NES_IDX_CREATE_CQP_HIGH + (PCI_FUNC(nesdev->pcidev->devfn) * 8), 0);
1041 }
1042 nes_write_indexed(nesdev,
1043 NES_IDX_CREATE_CQP_LOW + (PCI_FUNC(nesdev->pcidev->devfn) * 8),
1044 (u32)pmem);
1045
1046 INIT_LIST_HEAD(&nesdev->cqp_avail_reqs);
1047 INIT_LIST_HEAD(&nesdev->cqp_pending_reqs);
1048
1049 for (count = 0; count < 2*NES_CQP_SQ_SIZE; count++) {
1050 init_waitqueue_head(&nesdev->nes_cqp_requests[count].waitq);
1051 list_add_tail(&nesdev->nes_cqp_requests[count].list, &nesdev->cqp_avail_reqs);
1052 }
1053
1054 /* Write Create CCQ WQE */
1055 cqp_head = nesdev->cqp.sq_head++;
1056 cqp_wqe = &nesdev->cqp.sq_vbase[cqp_head];
1057 nes_fill_init_cqp_wqe(cqp_wqe, nesdev);
1058 set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_OPCODE_IDX,
1059 (NES_CQP_CREATE_CQ | NES_CQP_CQ_CEQ_VALID |
1060 NES_CQP_CQ_CHK_OVERFLOW | ((u32)nesdev->ccq.cq_size << 16)));
1061 set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_ID_IDX,
1062 (nesdev->ccq.cq_number |
1063 ((u32)nesdev->ceq_index << 16)));
1064 u64temp = (u64)nesdev->ccq.cq_pbase;
1065 set_wqe_64bit_value(cqp_wqe->wqe_words, NES_CQP_CQ_WQE_PBL_LOW_IDX, u64temp);
1066 cqp_wqe->wqe_words[NES_CQP_CQ_WQE_CQ_CONTEXT_HIGH_IDX] = 0;
1067 u64temp = (unsigned long)&nesdev->ccq;
1068 cqp_wqe->wqe_words[NES_CQP_CQ_WQE_CQ_CONTEXT_LOW_IDX] =
1069 cpu_to_le32((u32)(u64temp >> 1));
1070 cqp_wqe->wqe_words[NES_CQP_CQ_WQE_CQ_CONTEXT_HIGH_IDX] =
1071 cpu_to_le32(((u32)((u64temp) >> 33)) & 0x7FFFFFFF);
1072 cqp_wqe->wqe_words[NES_CQP_CQ_WQE_DOORBELL_INDEX_HIGH_IDX] = 0;
1073
1074 /* Write Create CEQ WQE */
1075 cqp_head = nesdev->cqp.sq_head++;
1076 cqp_wqe = &nesdev->cqp.sq_vbase[cqp_head];
1077 nes_fill_init_cqp_wqe(cqp_wqe, nesdev);
1078 set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_OPCODE_IDX,
1079 (NES_CQP_CREATE_CEQ + ((u32)nesdev->ceq_index << 8)));
1080 set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_CEQ_WQE_ELEMENT_COUNT_IDX, ceq->ceq_size);
1081 u64temp = (u64)ceq->ceq_pbase;
1082 set_wqe_64bit_value(cqp_wqe->wqe_words, NES_CQP_CQ_WQE_PBL_LOW_IDX, u64temp);
1083
1084 /* Write Create AEQ WQE */
1085 cqp_head = nesdev->cqp.sq_head++;
1086 cqp_wqe = &nesdev->cqp.sq_vbase[cqp_head];
1087 nes_fill_init_cqp_wqe(cqp_wqe, nesdev);
1088 set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_OPCODE_IDX,
1089 (NES_CQP_CREATE_AEQ + ((u32)PCI_FUNC(nesdev->pcidev->devfn) << 8)));
1090 set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_AEQ_WQE_ELEMENT_COUNT_IDX, aeq->aeq_size);
1091 u64temp = (u64)aeq->aeq_pbase;
1092 set_wqe_64bit_value(cqp_wqe->wqe_words, NES_CQP_CQ_WQE_PBL_LOW_IDX, u64temp);
1093
1094 /* Write Create NIC CEQ WQE */
1095 cqp_head = nesdev->cqp.sq_head++;
1096 cqp_wqe = &nesdev->cqp.sq_vbase[cqp_head];
1097 nes_fill_init_cqp_wqe(cqp_wqe, nesdev);
1098 set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_OPCODE_IDX,
1099 (NES_CQP_CREATE_CEQ + ((u32)nesdev->nic_ceq_index << 8)));
1100 set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_CEQ_WQE_ELEMENT_COUNT_IDX, nic_ceq->ceq_size);
1101 u64temp = (u64)nic_ceq->ceq_pbase;
1102 set_wqe_64bit_value(cqp_wqe->wqe_words, NES_CQP_CQ_WQE_PBL_LOW_IDX, u64temp);
1103
1104 /* Poll until CCQP done */
1105 count = 0;
1106 do {
1107 if (count++ > 1000) {
1108 printk(KERN_ERR PFX "Error creating CQP\n");
1109 pci_free_consistent(nesdev->pcidev, nesdev->cqp_mem_size,
1110 nesdev->cqp_vbase, nesdev->cqp_pbase);
1111 return -1;
1112 }
1113 udelay(10);
1114 } while (!(nes_read_indexed(nesdev,
1115 NES_IDX_QP_CONTROL + (PCI_FUNC(nesdev->pcidev->devfn) * 8)) & (1 << 8)));
1116
1117 nes_debug(NES_DBG_INIT, "CQP Status = 0x%08X\n", nes_read_indexed(nesdev,
1118 NES_IDX_QP_CONTROL+(PCI_FUNC(nesdev->pcidev->devfn)*8)));
1119
1120 u32temp = 0x04800000;
1121 nes_write32(nesdev->regs+NES_WQE_ALLOC, u32temp | nesdev->cqp.qp_id);
1122
1123 /* wait for the CCQ, CEQ, and AEQ to get created */
1124 count = 0;
1125 do {
1126 if (count++ > 1000) {
1127 printk(KERN_ERR PFX "Error creating CCQ, CEQ, and AEQ\n");
1128 pci_free_consistent(nesdev->pcidev, nesdev->cqp_mem_size,
1129 nesdev->cqp_vbase, nesdev->cqp_pbase);
1130 return -1;
1131 }
1132 udelay(10);
1133 } while (((nes_read_indexed(nesdev,
1134 NES_IDX_QP_CONTROL+(PCI_FUNC(nesdev->pcidev->devfn)*8)) & (15<<8)) != (15<<8)));
1135
1136 /* dump the QP status value */
1137 nes_debug(NES_DBG_INIT, "QP Status = 0x%08X\n", nes_read_indexed(nesdev,
1138 NES_IDX_QP_CONTROL+(PCI_FUNC(nesdev->pcidev->devfn)*8)));
1139
1140 nesdev->cqp.sq_tail++;
1141
1142 return 0;
1143}
1144
1145
1146/**
1147 * nes_destroy_cqp
1148 */
1149int nes_destroy_cqp(struct nes_device *nesdev)
1150{
1151 struct nes_hw_cqp_wqe *cqp_wqe;
1152 u32 count = 0;
1153 u32 cqp_head;
1154 unsigned long flags;
1155
1156 do {
1157 if (count++ > 1000)
1158 break;
1159 udelay(10);
1160 } while (!(nesdev->cqp.sq_head == nesdev->cqp.sq_tail));
1161
1162 /* Reset CCQ */
1163 nes_write32(nesdev->regs+NES_CQE_ALLOC, NES_CQE_ALLOC_RESET |
1164 nesdev->ccq.cq_number);
1165
1166 /* Disable device interrupts */
1167 nes_write32(nesdev->regs+NES_INT_MASK, 0x7fffffff);
1168
1169 spin_lock_irqsave(&nesdev->cqp.lock, flags);
1170
1171 /* Destroy the AEQ */
1172 cqp_head = nesdev->cqp.sq_head++;
1173 nesdev->cqp.sq_head &= nesdev->cqp.sq_size-1;
1174 cqp_wqe = &nesdev->cqp.sq_vbase[cqp_head];
1175 cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] = cpu_to_le32(NES_CQP_DESTROY_AEQ |
1176 ((u32)PCI_FUNC(nesdev->pcidev->devfn) << 8));
1177 cqp_wqe->wqe_words[NES_CQP_WQE_COMP_CTX_HIGH_IDX] = 0;
1178
1179 /* Destroy the NIC CEQ */
1180 cqp_head = nesdev->cqp.sq_head++;
1181 nesdev->cqp.sq_head &= nesdev->cqp.sq_size-1;
1182 cqp_wqe = &nesdev->cqp.sq_vbase[cqp_head];
1183 cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] = cpu_to_le32(NES_CQP_DESTROY_CEQ |
1184 ((u32)nesdev->nic_ceq_index << 8));
1185
1186 /* Destroy the CEQ */
1187 cqp_head = nesdev->cqp.sq_head++;
1188 nesdev->cqp.sq_head &= nesdev->cqp.sq_size-1;
1189 cqp_wqe = &nesdev->cqp.sq_vbase[cqp_head];
1190 cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] = cpu_to_le32(NES_CQP_DESTROY_CEQ |
1191 (nesdev->ceq_index << 8));
1192
1193 /* Destroy the CCQ */
1194 cqp_head = nesdev->cqp.sq_head++;
1195 nesdev->cqp.sq_head &= nesdev->cqp.sq_size-1;
1196 cqp_wqe = &nesdev->cqp.sq_vbase[cqp_head];
1197 cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] = cpu_to_le32(NES_CQP_DESTROY_CQ);
1198 cqp_wqe->wqe_words[NES_CQP_WQE_ID_IDX] = cpu_to_le32(nesdev->ccq.cq_number |
1199 ((u32)nesdev->ceq_index << 16));
1200
1201 /* Destroy CQP */
1202 cqp_head = nesdev->cqp.sq_head++;
1203 nesdev->cqp.sq_head &= nesdev->cqp.sq_size-1;
1204 cqp_wqe = &nesdev->cqp.sq_vbase[cqp_head];
1205 cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] = cpu_to_le32(NES_CQP_DESTROY_QP |
1206 NES_CQP_QP_TYPE_CQP);
1207 cqp_wqe->wqe_words[NES_CQP_WQE_ID_IDX] = cpu_to_le32(nesdev->cqp.qp_id);
1208
1209 barrier();
1210 /* Ring doorbell (5 WQEs) */
1211 nes_write32(nesdev->regs+NES_WQE_ALLOC, 0x05800000 | nesdev->cqp.qp_id);
1212
1213 spin_unlock_irqrestore(&nesdev->cqp.lock, flags);
1214
1215 /* wait for the CCQ, CEQ, and AEQ to get destroyed */
1216 count = 0;
1217 do {
1218 if (count++ > 1000) {
1219 printk(KERN_ERR PFX "Function%d: Error destroying CCQ, CEQ, and AEQ\n",
1220 PCI_FUNC(nesdev->pcidev->devfn));
1221 break;
1222 }
1223 udelay(10);
1224 } while (((nes_read_indexed(nesdev,
1225 NES_IDX_QP_CONTROL + (PCI_FUNC(nesdev->pcidev->devfn)*8)) & (15 << 8)) != 0));
1226
1227 /* dump the QP status value */
1228 nes_debug(NES_DBG_SHUTDOWN, "Function%d: QP Status = 0x%08X\n",
1229 PCI_FUNC(nesdev->pcidev->devfn),
1230 nes_read_indexed(nesdev,
1231 NES_IDX_QP_CONTROL+(PCI_FUNC(nesdev->pcidev->devfn)*8)));
1232
1233 kfree(nesdev->nes_cqp_requests);
1234
1235 /* Free the control structures */
1236 pci_free_consistent(nesdev->pcidev, nesdev->cqp_mem_size, nesdev->cqp.sq_vbase,
1237 nesdev->cqp.sq_pbase);
1238
1239 return 0;
1240}
1241
1242
1243/**
1244 * nes_init_phy
1245 */
1246int nes_init_phy(struct nes_device *nesdev)
1247{
1248 struct nes_adapter *nesadapter = nesdev->nesadapter;
1249 u32 counter = 0;
Eric Schneider0e1de5d2008-04-29 13:46:54 -07001250 u32 sds_common_control0;
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001251 u32 mac_index = nesdev->mac_index;
Eric Schneider0e1de5d2008-04-29 13:46:54 -07001252 u32 tx_config = 0;
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001253 u16 phy_data;
Eric Schneider0e1de5d2008-04-29 13:46:54 -07001254 u32 temp_phy_data = 0;
1255 u32 temp_phy_data2 = 0;
1256 u32 i = 0;
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001257
Eric Schneider0e1de5d2008-04-29 13:46:54 -07001258 if ((nesadapter->OneG_Mode) &&
1259 (nesadapter->phy_type[mac_index] != NES_PHY_TYPE_PUMA_1G)) {
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001260 nes_debug(NES_DBG_PHY, "1G PHY, mac_index = %d.\n", mac_index);
1261 if (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_1G) {
Harvey Harrison33718362008-04-16 21:01:10 -07001262 printk(PFX "%s: Programming mdc config for 1G\n", __func__);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001263 tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG);
1264 tx_config |= 0x04;
1265 nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config);
1266 }
1267
1268 nes_read_1G_phy_reg(nesdev, 1, nesadapter->phy_index[mac_index], &phy_data);
1269 nes_debug(NES_DBG_PHY, "Phy data from register 1 phy address %u = 0x%X.\n",
1270 nesadapter->phy_index[mac_index], phy_data);
Glenn Streiff7495ab62008-04-29 13:46:54 -07001271 nes_write_1G_phy_reg(nesdev, 23, nesadapter->phy_index[mac_index], 0xb000);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001272
1273 /* Reset the PHY */
1274 nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], 0x8000);
1275 udelay(100);
1276 counter = 0;
1277 do {
1278 nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], &phy_data);
1279 nes_debug(NES_DBG_PHY, "Phy data from register 0 = 0x%X.\n", phy_data);
1280 if (counter++ > 100) break;
1281 } while (phy_data & 0x8000);
1282
1283 /* Setting no phy loopback */
1284 phy_data &= 0xbfff;
1285 phy_data |= 0x1140;
1286 nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], phy_data);
1287 nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], &phy_data);
1288 nes_debug(NES_DBG_PHY, "Phy data from register 0 = 0x%X.\n", phy_data);
1289
1290 nes_read_1G_phy_reg(nesdev, 0x17, nesadapter->phy_index[mac_index], &phy_data);
1291 nes_debug(NES_DBG_PHY, "Phy data from register 0x17 = 0x%X.\n", phy_data);
1292
1293 nes_read_1G_phy_reg(nesdev, 0x1e, nesadapter->phy_index[mac_index], &phy_data);
1294 nes_debug(NES_DBG_PHY, "Phy data from register 0x1e = 0x%X.\n", phy_data);
1295
1296 /* Setting the interrupt mask */
1297 nes_read_1G_phy_reg(nesdev, 0x19, nesadapter->phy_index[mac_index], &phy_data);
1298 nes_debug(NES_DBG_PHY, "Phy data from register 0x19 = 0x%X.\n", phy_data);
1299 nes_write_1G_phy_reg(nesdev, 0x19, nesadapter->phy_index[mac_index], 0xffee);
1300
1301 nes_read_1G_phy_reg(nesdev, 0x19, nesadapter->phy_index[mac_index], &phy_data);
1302 nes_debug(NES_DBG_PHY, "Phy data from register 0x19 = 0x%X.\n", phy_data);
1303
1304 /* turning on flow control */
1305 nes_read_1G_phy_reg(nesdev, 4, nesadapter->phy_index[mac_index], &phy_data);
1306 nes_debug(NES_DBG_PHY, "Phy data from register 0x4 = 0x%X.\n", phy_data);
1307 nes_write_1G_phy_reg(nesdev, 4, nesadapter->phy_index[mac_index],
1308 (phy_data & ~(0x03E0)) | 0xc00);
1309 /* nes_write_1G_phy_reg(nesdev, 4, nesadapter->phy_index[mac_index],
1310 phy_data | 0xc00); */
1311 nes_read_1G_phy_reg(nesdev, 4, nesadapter->phy_index[mac_index], &phy_data);
1312 nes_debug(NES_DBG_PHY, "Phy data from register 0x4 = 0x%X.\n", phy_data);
1313
1314 nes_read_1G_phy_reg(nesdev, 9, nesadapter->phy_index[mac_index], &phy_data);
1315 nes_debug(NES_DBG_PHY, "Phy data from register 0x9 = 0x%X.\n", phy_data);
1316 /* Clear Half duplex */
1317 nes_write_1G_phy_reg(nesdev, 9, nesadapter->phy_index[mac_index],
1318 phy_data & ~(0x0100));
1319 nes_read_1G_phy_reg(nesdev, 9, nesadapter->phy_index[mac_index], &phy_data);
1320 nes_debug(NES_DBG_PHY, "Phy data from register 0x9 = 0x%X.\n", phy_data);
1321
1322 nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], &phy_data);
1323 nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], phy_data | 0x0300);
1324 } else {
Eric Schneider0e1de5d2008-04-29 13:46:54 -07001325 if ((nesadapter->phy_type[mac_index] == NES_PHY_TYPE_IRIS) ||
1326 (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_ARGUS)) {
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001327 /* setup 10G MDIO operation */
1328 tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG);
1329 tx_config |= 0x14;
1330 nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config);
1331 }
Eric Schneider0e1de5d2008-04-29 13:46:54 -07001332 if ((nesadapter->phy_type[mac_index] == NES_PHY_TYPE_ARGUS)) {
1333 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee);
1334
1335 temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
1336 mdelay(10);
1337 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee);
1338 temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
1339
1340 /*
1341 * if firmware is already running (like from a
1342 * driver un-load/load, don't do anything.
1343 */
1344 if (temp_phy_data == temp_phy_data2) {
1345 /* configure QT2505 AMCC PHY */
1346 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0x0000, 0x8000);
1347 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc300, 0x0000);
1348 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc302, 0x0044);
1349 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc318, 0x0052);
1350 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc319, 0x0008);
1351 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc31a, 0x0098);
1352 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0x0026, 0x0E00);
1353 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0x0027, 0x0000);
1354 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0x0028, 0xA528);
1355
1356 /*
1357 * remove micro from reset; chip boots from ROM,
1358 * uploads EEPROM f/w image, uC executes f/w
1359 */
1360 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc300, 0x0002);
1361
1362 /*
1363 * wait for heart beat to start to
1364 * know loading is done
1365 */
1366 counter = 0;
1367 do {
1368 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee);
1369 temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
1370 if (counter++ > 1000) {
1371 nes_debug(NES_DBG_PHY, "AMCC PHY- breaking from heartbeat check <this is bad!!!> \n");
1372 break;
1373 }
1374 mdelay(100);
1375 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee);
1376 temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
1377 } while ((temp_phy_data2 == temp_phy_data));
1378
1379 /*
1380 * wait for tracking to start to know
1381 * f/w is good to go
1382 */
1383 counter = 0;
1384 do {
1385 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7fd);
1386 temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
1387 if (counter++ > 1000) {
1388 nes_debug(NES_DBG_PHY, "AMCC PHY- breaking from status check <this is bad!!!> \n");
1389 break;
1390 }
1391 mdelay(1000);
1392 /*
1393 * nes_debug(NES_DBG_PHY, "AMCC PHY- phy_status not ready yet = 0x%02X\n",
1394 * temp_phy_data);
1395 */
1396 } while (((temp_phy_data & 0xff) != 0x50) && ((temp_phy_data & 0xff) != 0x70));
1397
1398 /* set LOS Control invert RXLOSB_I_PADINV */
1399 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd003, 0x0000);
1400 /* set LOS Control to mask of RXLOSB_I */
1401 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc314, 0x0042);
1402 /* set LED1 to input mode (LED1 and LED2 share same LED) */
1403 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd006, 0x0007);
1404 /* set LED2 to RX link_status and activity */
1405 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd007, 0x000A);
1406 /* set LED3 to RX link_status */
1407 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd008, 0x0009);
1408
1409 /*
1410 * reset the res-calibration on t2
1411 * serdes; ensures it is stable after
1412 * the amcc phy is stable
1413 */
1414
Glenn Streiff7495ab62008-04-29 13:46:54 -07001415 sds_common_control0 = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0);
Eric Schneider0e1de5d2008-04-29 13:46:54 -07001416 sds_common_control0 |= 0x1;
1417 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, sds_common_control0);
1418
1419 /* release the res-calibration reset */
1420 sds_common_control0 &= 0xfffffffe;
1421 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, sds_common_control0);
1422
1423 i = 0;
Glenn Streiff7495ab62008-04-29 13:46:54 -07001424 while (((nes_read32(nesdev->regs + NES_SOFTWARE_RESET) & 0x00000040) != 0x00000040)
Eric Schneider0e1de5d2008-04-29 13:46:54 -07001425 && (i++ < 5000)) {
1426 /* mdelay(1); */
1427 }
1428
1429 /*
1430 * wait for link train done before moving on,
1431 * or will get an interupt storm
1432 */
1433 counter = 0;
1434 do {
1435 temp_phy_data = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 +
1436 (0x200 * (nesdev->mac_index & 1)));
1437 if (counter++ > 1000) {
1438 nes_debug(NES_DBG_PHY, "AMCC PHY- breaking from link train wait <this is bad, link didnt train!!!>\n");
1439 break;
1440 }
1441 mdelay(1);
1442 } while (((temp_phy_data & 0x0f1f0000) != 0x0f0f0000));
1443 }
1444 }
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001445 }
1446 return 0;
1447}
1448
1449
1450/**
1451 * nes_replenish_nic_rq
1452 */
1453static void nes_replenish_nic_rq(struct nes_vnic *nesvnic)
1454{
1455 unsigned long flags;
1456 dma_addr_t bus_address;
1457 struct sk_buff *skb;
1458 struct nes_hw_nic_rq_wqe *nic_rqe;
1459 struct nes_hw_nic *nesnic;
1460 struct nes_device *nesdev;
1461 u32 rx_wqes_posted = 0;
1462
1463 nesnic = &nesvnic->nic;
1464 nesdev = nesvnic->nesdev;
1465 spin_lock_irqsave(&nesnic->rq_lock, flags);
1466 if (nesnic->replenishing_rq !=0) {
1467 if (((nesnic->rq_size-1) == atomic_read(&nesvnic->rx_skbs_needed)) &&
1468 (atomic_read(&nesvnic->rx_skb_timer_running) == 0)) {
1469 atomic_set(&nesvnic->rx_skb_timer_running, 1);
1470 spin_unlock_irqrestore(&nesnic->rq_lock, flags);
1471 nesvnic->rq_wqes_timer.expires = jiffies + (HZ/2); /* 1/2 second */
1472 add_timer(&nesvnic->rq_wqes_timer);
1473 } else
1474 spin_unlock_irqrestore(&nesnic->rq_lock, flags);
1475 return;
1476 }
1477 nesnic->replenishing_rq = 1;
1478 spin_unlock_irqrestore(&nesnic->rq_lock, flags);
1479 do {
1480 skb = dev_alloc_skb(nesvnic->max_frame_size);
1481 if (skb) {
1482 skb->dev = nesvnic->netdev;
1483
1484 bus_address = pci_map_single(nesdev->pcidev,
1485 skb->data, nesvnic->max_frame_size, PCI_DMA_FROMDEVICE);
1486
1487 nic_rqe = &nesnic->rq_vbase[nesvnic->nic.rq_head];
1488 nic_rqe->wqe_words[NES_NIC_RQ_WQE_LENGTH_1_0_IDX] =
1489 cpu_to_le32(nesvnic->max_frame_size);
1490 nic_rqe->wqe_words[NES_NIC_RQ_WQE_LENGTH_3_2_IDX] = 0;
1491 nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_LOW_IDX] =
1492 cpu_to_le32((u32)bus_address);
1493 nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_HIGH_IDX] =
1494 cpu_to_le32((u32)((u64)bus_address >> 32));
1495 nesnic->rx_skb[nesnic->rq_head] = skb;
1496 nesnic->rq_head++;
1497 nesnic->rq_head &= nesnic->rq_size - 1;
1498 atomic_dec(&nesvnic->rx_skbs_needed);
1499 barrier();
1500 if (++rx_wqes_posted == 255) {
1501 nes_write32(nesdev->regs+NES_WQE_ALLOC, (rx_wqes_posted << 24) | nesnic->qp_id);
1502 rx_wqes_posted = 0;
1503 }
1504 } else {
1505 spin_lock_irqsave(&nesnic->rq_lock, flags);
1506 if (((nesnic->rq_size-1) == atomic_read(&nesvnic->rx_skbs_needed)) &&
1507 (atomic_read(&nesvnic->rx_skb_timer_running) == 0)) {
1508 atomic_set(&nesvnic->rx_skb_timer_running, 1);
1509 spin_unlock_irqrestore(&nesnic->rq_lock, flags);
1510 nesvnic->rq_wqes_timer.expires = jiffies + (HZ/2); /* 1/2 second */
1511 add_timer(&nesvnic->rq_wqes_timer);
1512 } else
1513 spin_unlock_irqrestore(&nesnic->rq_lock, flags);
1514 break;
1515 }
1516 } while (atomic_read(&nesvnic->rx_skbs_needed));
1517 barrier();
1518 if (rx_wqes_posted)
1519 nes_write32(nesdev->regs+NES_WQE_ALLOC, (rx_wqes_posted << 24) | nesnic->qp_id);
1520 nesnic->replenishing_rq = 0;
1521}
1522
1523
1524/**
1525 * nes_rq_wqes_timeout
1526 */
1527static void nes_rq_wqes_timeout(unsigned long parm)
1528{
1529 struct nes_vnic *nesvnic = (struct nes_vnic *)parm;
Harvey Harrison33718362008-04-16 21:01:10 -07001530 printk("%s: Timer fired.\n", __func__);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001531 atomic_set(&nesvnic->rx_skb_timer_running, 0);
1532 if (atomic_read(&nesvnic->rx_skbs_needed))
1533 nes_replenish_nic_rq(nesvnic);
1534}
1535
1536
Faisal Latif37dab412008-04-29 13:46:54 -07001537static int nes_lro_get_skb_hdr(struct sk_buff *skb, void **iphdr,
1538 void **tcph, u64 *hdr_flags, void *priv)
1539{
1540 unsigned int ip_len;
1541 struct iphdr *iph;
1542 skb_reset_network_header(skb);
1543 iph = ip_hdr(skb);
1544 if (iph->protocol != IPPROTO_TCP)
1545 return -1;
1546 ip_len = ip_hdrlen(skb);
1547 skb_set_transport_header(skb, ip_len);
1548 *tcph = tcp_hdr(skb);
1549
1550 *hdr_flags = LRO_IPV4 | LRO_TCP;
1551 *iphdr = iph;
1552 return 0;
1553}
1554
1555
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001556/**
1557 * nes_init_nic_qp
1558 */
1559int nes_init_nic_qp(struct nes_device *nesdev, struct net_device *netdev)
1560{
1561 struct nes_hw_cqp_wqe *cqp_wqe;
1562 struct nes_hw_nic_sq_wqe *nic_sqe;
1563 struct nes_hw_nic_qp_context *nic_context;
1564 struct sk_buff *skb;
1565 struct nes_hw_nic_rq_wqe *nic_rqe;
1566 struct nes_vnic *nesvnic = netdev_priv(netdev);
1567 unsigned long flags;
1568 void *vmem;
1569 dma_addr_t pmem;
1570 u64 u64temp;
1571 int ret;
1572 u32 cqp_head;
1573 u32 counter;
1574 u32 wqe_count;
1575 u8 jumbomode=0;
1576
1577 /* Allocate fragment, SQ, RQ, and CQ; Reuse CEQ based on the PCI function */
1578 nesvnic->nic_mem_size = 256 +
1579 (NES_NIC_WQ_SIZE * sizeof(struct nes_first_frag)) +
1580 (NES_NIC_WQ_SIZE * sizeof(struct nes_hw_nic_sq_wqe)) +
1581 (NES_NIC_WQ_SIZE * sizeof(struct nes_hw_nic_rq_wqe)) +
1582 (NES_NIC_WQ_SIZE * 2 * sizeof(struct nes_hw_nic_cqe)) +
1583 sizeof(struct nes_hw_nic_qp_context);
1584
1585 nesvnic->nic_vbase = pci_alloc_consistent(nesdev->pcidev, nesvnic->nic_mem_size,
1586 &nesvnic->nic_pbase);
1587 if (!nesvnic->nic_vbase) {
1588 nes_debug(NES_DBG_INIT, "Unable to allocate memory for NIC host descriptor rings\n");
1589 return -ENOMEM;
1590 }
1591 memset(nesvnic->nic_vbase, 0, nesvnic->nic_mem_size);
1592 nes_debug(NES_DBG_INIT, "Allocated NIC QP structures at %p (phys = %016lX), size = %u.\n",
1593 nesvnic->nic_vbase, (unsigned long)nesvnic->nic_pbase, nesvnic->nic_mem_size);
1594
1595 vmem = (void *)(((unsigned long)nesvnic->nic_vbase + (256 - 1)) &
1596 ~(unsigned long)(256 - 1));
1597 pmem = (dma_addr_t)(((unsigned long long)nesvnic->nic_pbase + (256 - 1)) &
1598 ~(unsigned long long)(256 - 1));
1599
1600 /* Setup the first Fragment buffers */
1601 nesvnic->nic.first_frag_vbase = vmem;
1602
1603 for (counter = 0; counter < NES_NIC_WQ_SIZE; counter++) {
1604 nesvnic->nic.frag_paddr[counter] = pmem;
1605 pmem += sizeof(struct nes_first_frag);
1606 }
1607
1608 /* setup the SQ */
1609 vmem += (NES_NIC_WQ_SIZE * sizeof(struct nes_first_frag));
1610
1611 nesvnic->nic.sq_vbase = (void *)vmem;
1612 nesvnic->nic.sq_pbase = pmem;
1613 nesvnic->nic.sq_head = 0;
1614 nesvnic->nic.sq_tail = 0;
1615 nesvnic->nic.sq_size = NES_NIC_WQ_SIZE;
1616 for (counter = 0; counter < NES_NIC_WQ_SIZE; counter++) {
1617 nic_sqe = &nesvnic->nic.sq_vbase[counter];
1618 nic_sqe->wqe_words[NES_NIC_SQ_WQE_MISC_IDX] =
1619 cpu_to_le32(NES_NIC_SQ_WQE_DISABLE_CHKSUM |
1620 NES_NIC_SQ_WQE_COMPLETION);
1621 nic_sqe->wqe_words[NES_NIC_SQ_WQE_LENGTH_0_TAG_IDX] =
1622 cpu_to_le32((u32)NES_FIRST_FRAG_SIZE << 16);
1623 nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_LOW_IDX] =
1624 cpu_to_le32((u32)nesvnic->nic.frag_paddr[counter]);
1625 nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_HIGH_IDX] =
1626 cpu_to_le32((u32)((u64)nesvnic->nic.frag_paddr[counter] >> 32));
1627 }
1628
1629 nesvnic->get_cqp_request = nes_get_cqp_request;
1630 nesvnic->post_cqp_request = nes_post_cqp_request;
1631 nesvnic->mcrq_mcast_filter = NULL;
1632
1633 spin_lock_init(&nesvnic->nic.sq_lock);
1634 spin_lock_init(&nesvnic->nic.rq_lock);
1635
1636 /* setup the RQ */
1637 vmem += (NES_NIC_WQ_SIZE * sizeof(struct nes_hw_nic_sq_wqe));
1638 pmem += (NES_NIC_WQ_SIZE * sizeof(struct nes_hw_nic_sq_wqe));
1639
1640
1641 nesvnic->nic.rq_vbase = vmem;
1642 nesvnic->nic.rq_pbase = pmem;
1643 nesvnic->nic.rq_head = 0;
1644 nesvnic->nic.rq_tail = 0;
1645 nesvnic->nic.rq_size = NES_NIC_WQ_SIZE;
1646
1647 /* setup the CQ */
1648 vmem += (NES_NIC_WQ_SIZE * sizeof(struct nes_hw_nic_rq_wqe));
1649 pmem += (NES_NIC_WQ_SIZE * sizeof(struct nes_hw_nic_rq_wqe));
1650
1651 if (nesdev->nesadapter->netdev_count > 2)
1652 nesvnic->mcrq_qp_id = nesvnic->nic_index + 32;
1653 else
1654 nesvnic->mcrq_qp_id = nesvnic->nic.qp_id + 4;
1655
1656 nesvnic->nic_cq.cq_vbase = vmem;
1657 nesvnic->nic_cq.cq_pbase = pmem;
1658 nesvnic->nic_cq.cq_head = 0;
1659 nesvnic->nic_cq.cq_size = NES_NIC_WQ_SIZE * 2;
1660
1661 nesvnic->nic_cq.ce_handler = nes_nic_napi_ce_handler;
1662
1663 /* Send CreateCQ request to CQP */
1664 spin_lock_irqsave(&nesdev->cqp.lock, flags);
1665 cqp_head = nesdev->cqp.sq_head;
1666
1667 cqp_wqe = &nesdev->cqp.sq_vbase[cqp_head];
1668 nes_fill_init_cqp_wqe(cqp_wqe, nesdev);
1669
1670 cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] = cpu_to_le32(
1671 NES_CQP_CREATE_CQ | NES_CQP_CQ_CEQ_VALID |
1672 ((u32)nesvnic->nic_cq.cq_size << 16));
1673 cqp_wqe->wqe_words[NES_CQP_WQE_ID_IDX] = cpu_to_le32(
1674 nesvnic->nic_cq.cq_number | ((u32)nesdev->nic_ceq_index << 16));
1675 u64temp = (u64)nesvnic->nic_cq.cq_pbase;
1676 set_wqe_64bit_value(cqp_wqe->wqe_words, NES_CQP_CQ_WQE_PBL_LOW_IDX, u64temp);
1677 cqp_wqe->wqe_words[NES_CQP_CQ_WQE_CQ_CONTEXT_HIGH_IDX] = 0;
1678 u64temp = (unsigned long)&nesvnic->nic_cq;
1679 cqp_wqe->wqe_words[NES_CQP_CQ_WQE_CQ_CONTEXT_LOW_IDX] = cpu_to_le32((u32)(u64temp >> 1));
1680 cqp_wqe->wqe_words[NES_CQP_CQ_WQE_CQ_CONTEXT_HIGH_IDX] =
1681 cpu_to_le32(((u32)((u64temp) >> 33)) & 0x7FFFFFFF);
1682 cqp_wqe->wqe_words[NES_CQP_CQ_WQE_DOORBELL_INDEX_HIGH_IDX] = 0;
1683 if (++cqp_head >= nesdev->cqp.sq_size)
1684 cqp_head = 0;
1685 cqp_wqe = &nesdev->cqp.sq_vbase[cqp_head];
1686 nes_fill_init_cqp_wqe(cqp_wqe, nesdev);
1687
1688 /* Send CreateQP request to CQP */
1689 nic_context = (void *)(&nesvnic->nic_cq.cq_vbase[nesvnic->nic_cq.cq_size]);
1690 nic_context->context_words[NES_NIC_CTX_MISC_IDX] =
1691 cpu_to_le32((u32)NES_NIC_CTX_SIZE |
1692 ((u32)PCI_FUNC(nesdev->pcidev->devfn) << 12));
1693 nes_debug(NES_DBG_INIT, "RX_WINDOW_BUFFER_PAGE_TABLE_SIZE = 0x%08X, RX_WINDOW_BUFFER_SIZE = 0x%08X\n",
1694 nes_read_indexed(nesdev, NES_IDX_RX_WINDOW_BUFFER_PAGE_TABLE_SIZE),
1695 nes_read_indexed(nesdev, NES_IDX_RX_WINDOW_BUFFER_SIZE));
1696 if (nes_read_indexed(nesdev, NES_IDX_RX_WINDOW_BUFFER_SIZE) != 0) {
1697 nic_context->context_words[NES_NIC_CTX_MISC_IDX] |= cpu_to_le32(NES_NIC_BACK_STORE);
1698 }
1699
1700 u64temp = (u64)nesvnic->nic.sq_pbase;
Glenn Streiff7495ab62008-04-29 13:46:54 -07001701 nic_context->context_words[NES_NIC_CTX_SQ_LOW_IDX] = cpu_to_le32((u32)u64temp);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001702 nic_context->context_words[NES_NIC_CTX_SQ_HIGH_IDX] = cpu_to_le32((u32)(u64temp >> 32));
1703 u64temp = (u64)nesvnic->nic.rq_pbase;
Glenn Streiff7495ab62008-04-29 13:46:54 -07001704 nic_context->context_words[NES_NIC_CTX_RQ_LOW_IDX] = cpu_to_le32((u32)u64temp);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001705 nic_context->context_words[NES_NIC_CTX_RQ_HIGH_IDX] = cpu_to_le32((u32)(u64temp >> 32));
1706
1707 cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] = cpu_to_le32(NES_CQP_CREATE_QP |
1708 NES_CQP_QP_TYPE_NIC);
1709 cqp_wqe->wqe_words[NES_CQP_WQE_ID_IDX] = cpu_to_le32(nesvnic->nic.qp_id);
1710 u64temp = (u64)nesvnic->nic_cq.cq_pbase +
1711 (nesvnic->nic_cq.cq_size * sizeof(struct nes_hw_nic_cqe));
1712 set_wqe_64bit_value(cqp_wqe->wqe_words, NES_CQP_QP_WQE_CONTEXT_LOW_IDX, u64temp);
1713
1714 if (++cqp_head >= nesdev->cqp.sq_size)
1715 cqp_head = 0;
1716 nesdev->cqp.sq_head = cqp_head;
1717
1718 barrier();
1719
1720 /* Ring doorbell (2 WQEs) */
1721 nes_write32(nesdev->regs+NES_WQE_ALLOC, 0x02800000 | nesdev->cqp.qp_id);
1722
1723 spin_unlock_irqrestore(&nesdev->cqp.lock, flags);
1724 nes_debug(NES_DBG_INIT, "Waiting for create NIC QP%u to complete.\n",
1725 nesvnic->nic.qp_id);
1726
1727 ret = wait_event_timeout(nesdev->cqp.waitq, (nesdev->cqp.sq_tail == cqp_head),
1728 NES_EVENT_TIMEOUT);
1729 nes_debug(NES_DBG_INIT, "Create NIC QP%u completed, wait_event_timeout ret = %u.\n",
1730 nesvnic->nic.qp_id, ret);
1731 if (!ret) {
1732 nes_debug(NES_DBG_INIT, "NIC QP%u create timeout expired\n", nesvnic->nic.qp_id);
1733 pci_free_consistent(nesdev->pcidev, nesvnic->nic_mem_size, nesvnic->nic_vbase,
1734 nesvnic->nic_pbase);
1735 return -EIO;
1736 }
1737
1738 /* Populate the RQ */
1739 for (counter = 0; counter < (NES_NIC_WQ_SIZE - 1); counter++) {
1740 skb = dev_alloc_skb(nesvnic->max_frame_size);
1741 if (!skb) {
1742 nes_debug(NES_DBG_INIT, "%s: out of memory for receive skb\n", netdev->name);
1743
1744 nes_destroy_nic_qp(nesvnic);
1745 return -ENOMEM;
1746 }
1747
1748 skb->dev = netdev;
1749
1750 pmem = pci_map_single(nesdev->pcidev, skb->data,
1751 nesvnic->max_frame_size, PCI_DMA_FROMDEVICE);
1752
1753 nic_rqe = &nesvnic->nic.rq_vbase[counter];
1754 nic_rqe->wqe_words[NES_NIC_RQ_WQE_LENGTH_1_0_IDX] = cpu_to_le32(nesvnic->max_frame_size);
1755 nic_rqe->wqe_words[NES_NIC_RQ_WQE_LENGTH_3_2_IDX] = 0;
Glenn Streiff7495ab62008-04-29 13:46:54 -07001756 nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_LOW_IDX] = cpu_to_le32((u32)pmem);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001757 nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_HIGH_IDX] = cpu_to_le32((u32)((u64)pmem >> 32));
1758 nesvnic->nic.rx_skb[counter] = skb;
1759 }
1760
1761 wqe_count = NES_NIC_WQ_SIZE - 1;
1762 nesvnic->nic.rq_head = wqe_count;
1763 barrier();
1764 do {
1765 counter = min(wqe_count, ((u32)255));
1766 wqe_count -= counter;
1767 nes_write32(nesdev->regs+NES_WQE_ALLOC, (counter << 24) | nesvnic->nic.qp_id);
1768 } while (wqe_count);
1769 init_timer(&nesvnic->rq_wqes_timer);
1770 nesvnic->rq_wqes_timer.function = nes_rq_wqes_timeout;
1771 nesvnic->rq_wqes_timer.data = (unsigned long)nesvnic;
1772 nes_debug(NES_DBG_INIT, "NAPI support Enabled\n");
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001773 if (nesdev->nesadapter->et_use_adaptive_rx_coalesce)
1774 {
1775 nes_nic_init_timer(nesdev);
1776 if (netdev->mtu > 1500)
1777 jumbomode = 1;
Faisal Latif37dab412008-04-29 13:46:54 -07001778 nes_nic_init_timer_defaults(nesdev, jumbomode);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001779 }
Roland Dreierdd378182008-05-13 11:27:25 -07001780 nesvnic->lro_mgr.max_aggr = nes_lro_max_aggr;
Glenn Streiff7495ab62008-04-29 13:46:54 -07001781 nesvnic->lro_mgr.max_desc = NES_MAX_LRO_DESCRIPTORS;
1782 nesvnic->lro_mgr.lro_arr = nesvnic->lro_desc;
Faisal Latif37dab412008-04-29 13:46:54 -07001783 nesvnic->lro_mgr.get_skb_header = nes_lro_get_skb_hdr;
Glenn Streiff7495ab62008-04-29 13:46:54 -07001784 nesvnic->lro_mgr.features = LRO_F_NAPI | LRO_F_EXTRACT_VLAN_ID;
1785 nesvnic->lro_mgr.dev = netdev;
1786 nesvnic->lro_mgr.ip_summed = CHECKSUM_UNNECESSARY;
Faisal Latif37dab412008-04-29 13:46:54 -07001787 nesvnic->lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY;
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001788 return 0;
1789}
1790
1791
1792/**
1793 * nes_destroy_nic_qp
1794 */
1795void nes_destroy_nic_qp(struct nes_vnic *nesvnic)
1796{
1797 struct nes_device *nesdev = nesvnic->nesdev;
1798 struct nes_hw_cqp_wqe *cqp_wqe;
1799 struct nes_hw_nic_rq_wqe *nic_rqe;
1800 u64 wqe_frag;
1801 u32 cqp_head;
1802 unsigned long flags;
1803 int ret;
1804
1805 /* Free remaining NIC receive buffers */
1806 while (nesvnic->nic.rq_head != nesvnic->nic.rq_tail) {
Glenn Streiff7495ab62008-04-29 13:46:54 -07001807 nic_rqe = &nesvnic->nic.rq_vbase[nesvnic->nic.rq_tail];
1808 wqe_frag = (u64)le32_to_cpu(nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_LOW_IDX]);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001809 wqe_frag |= ((u64)le32_to_cpu(nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_HIGH_IDX])) << 32;
1810 pci_unmap_single(nesdev->pcidev, (dma_addr_t)wqe_frag,
1811 nesvnic->max_frame_size, PCI_DMA_FROMDEVICE);
1812 dev_kfree_skb(nesvnic->nic.rx_skb[nesvnic->nic.rq_tail++]);
1813 nesvnic->nic.rq_tail &= (nesvnic->nic.rq_size - 1);
1814 }
1815
1816 spin_lock_irqsave(&nesdev->cqp.lock, flags);
1817
1818 /* Destroy NIC QP */
1819 cqp_head = nesdev->cqp.sq_head;
1820 cqp_wqe = &nesdev->cqp.sq_vbase[cqp_head];
1821 nes_fill_init_cqp_wqe(cqp_wqe, nesdev);
1822
1823 set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_OPCODE_IDX,
1824 (NES_CQP_DESTROY_QP | NES_CQP_QP_TYPE_NIC));
1825 set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_ID_IDX,
1826 nesvnic->nic.qp_id);
1827
1828 if (++cqp_head >= nesdev->cqp.sq_size)
1829 cqp_head = 0;
1830
1831 cqp_wqe = &nesdev->cqp.sq_vbase[cqp_head];
1832
1833 /* Destroy NIC CQ */
1834 nes_fill_init_cqp_wqe(cqp_wqe, nesdev);
1835 set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_OPCODE_IDX,
1836 (NES_CQP_DESTROY_CQ | ((u32)nesvnic->nic_cq.cq_size << 16)));
1837 set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_ID_IDX,
1838 (nesvnic->nic_cq.cq_number | ((u32)nesdev->nic_ceq_index << 16)));
1839
1840 if (++cqp_head >= nesdev->cqp.sq_size)
1841 cqp_head = 0;
1842
1843 nesdev->cqp.sq_head = cqp_head;
1844 barrier();
1845
1846 /* Ring doorbell (2 WQEs) */
1847 nes_write32(nesdev->regs+NES_WQE_ALLOC, 0x02800000 | nesdev->cqp.qp_id);
1848
1849 spin_unlock_irqrestore(&nesdev->cqp.lock, flags);
1850 nes_debug(NES_DBG_SHUTDOWN, "Waiting for CQP, cqp_head=%u, cqp.sq_head=%u,"
1851 " cqp.sq_tail=%u, cqp.sq_size=%u\n",
1852 cqp_head, nesdev->cqp.sq_head,
1853 nesdev->cqp.sq_tail, nesdev->cqp.sq_size);
1854
1855 ret = wait_event_timeout(nesdev->cqp.waitq, (nesdev->cqp.sq_tail == cqp_head),
1856 NES_EVENT_TIMEOUT);
1857
1858 nes_debug(NES_DBG_SHUTDOWN, "Destroy NIC QP returned, wait_event_timeout ret = %u, cqp_head=%u,"
1859 " cqp.sq_head=%u, cqp.sq_tail=%u\n",
1860 ret, cqp_head, nesdev->cqp.sq_head, nesdev->cqp.sq_tail);
1861 if (!ret) {
1862 nes_debug(NES_DBG_SHUTDOWN, "NIC QP%u destroy timeout expired\n",
1863 nesvnic->nic.qp_id);
1864 }
1865
1866 pci_free_consistent(nesdev->pcidev, nesvnic->nic_mem_size, nesvnic->nic_vbase,
1867 nesvnic->nic_pbase);
1868}
1869
1870/**
1871 * nes_napi_isr
1872 */
1873int nes_napi_isr(struct nes_device *nesdev)
1874{
1875 struct nes_adapter *nesadapter = nesdev->nesadapter;
1876 u32 int_stat;
1877
1878 if (nesdev->napi_isr_ran) {
1879 /* interrupt status has already been read in ISR */
1880 int_stat = nesdev->int_stat;
1881 } else {
1882 int_stat = nes_read32(nesdev->regs + NES_INT_STAT);
1883 nesdev->int_stat = int_stat;
1884 nesdev->napi_isr_ran = 1;
1885 }
1886
1887 int_stat &= nesdev->int_req;
1888 /* iff NIC, process here, else wait for DPC */
1889 if ((int_stat) && ((int_stat & 0x0000ff00) == int_stat)) {
1890 nesdev->napi_isr_ran = 0;
Glenn Streiff7495ab62008-04-29 13:46:54 -07001891 nes_write32(nesdev->regs + NES_INT_STAT,
1892 (int_stat &
1893 ~(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 -08001894
1895 /* Process the CEQs */
1896 nes_process_ceq(nesdev, &nesdev->nesadapter->ceq[nesdev->nic_ceq_index]);
1897
1898 if (unlikely((((nesadapter->et_rx_coalesce_usecs_irq) &&
Glenn Streiff7495ab62008-04-29 13:46:54 -07001899 (!nesadapter->et_use_adaptive_rx_coalesce)) ||
1900 ((nesadapter->et_use_adaptive_rx_coalesce) &&
1901 (nesdev->deepcq_count > nesadapter->et_pkt_rate_low))))) {
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001902 if ((nesdev->int_req & NES_INT_TIMER) == 0) {
1903 /* Enable Periodic timer interrupts */
1904 nesdev->int_req |= NES_INT_TIMER;
1905 /* ack any pending periodic timer interrupts so we don't get an immediate interrupt */
1906 /* TODO: need to also ack other unused periodic timer values, get from nesadapter */
1907 nes_write32(nesdev->regs+NES_TIMER_STAT,
1908 nesdev->timer_int_req | ~(nesdev->nesadapter->timer_int_req));
1909 nes_write32(nesdev->regs+NES_INTF_INT_MASK,
1910 ~(nesdev->intf_int_req | NES_INTF_PERIODIC_TIMER));
1911 }
1912
1913 if (unlikely(nesadapter->et_use_adaptive_rx_coalesce))
1914 {
1915 nes_nic_init_timer(nesdev);
1916 }
1917 /* Enable interrupts, except CEQs */
1918 nes_write32(nesdev->regs+NES_INT_MASK, 0x0000ffff | (~nesdev->int_req));
1919 } else {
1920 /* Enable interrupts, make sure timer is off */
1921 nesdev->int_req &= ~NES_INT_TIMER;
1922 nes_write32(nesdev->regs+NES_INTF_INT_MASK, ~(nesdev->intf_int_req));
1923 nes_write32(nesdev->regs+NES_INT_MASK, ~nesdev->int_req);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001924 }
1925 nesdev->deepcq_count = 0;
1926 return 1;
1927 } else {
1928 return 0;
1929 }
1930}
1931
1932
1933/**
1934 * nes_dpc
1935 */
1936void nes_dpc(unsigned long param)
1937{
1938 struct nes_device *nesdev = (struct nes_device *)param;
1939 struct nes_adapter *nesadapter = nesdev->nesadapter;
1940 u32 counter;
1941 u32 loop_counter = 0;
1942 u32 int_status_bit;
1943 u32 int_stat;
1944 u32 timer_stat;
1945 u32 temp_int_stat;
1946 u32 intf_int_stat;
1947 u32 debug_error;
1948 u32 processed_intf_int = 0;
1949 u16 processed_timer_int = 0;
1950 u16 completion_ints = 0;
1951 u16 timer_ints = 0;
1952
1953 /* nes_debug(NES_DBG_ISR, "\n"); */
1954
1955 do {
1956 timer_stat = 0;
1957 if (nesdev->napi_isr_ran) {
1958 nesdev->napi_isr_ran = 0;
1959 int_stat = nesdev->int_stat;
1960 } else
1961 int_stat = nes_read32(nesdev->regs+NES_INT_STAT);
1962 if (processed_intf_int != 0)
1963 int_stat &= nesdev->int_req & ~NES_INT_INTF;
1964 else
1965 int_stat &= nesdev->int_req;
1966 if (processed_timer_int == 0) {
1967 processed_timer_int = 1;
1968 if (int_stat & NES_INT_TIMER) {
1969 timer_stat = nes_read32(nesdev->regs + NES_TIMER_STAT);
1970 if ((timer_stat & nesdev->timer_int_req) == 0) {
1971 int_stat &= ~NES_INT_TIMER;
1972 }
1973 }
1974 } else {
1975 int_stat &= ~NES_INT_TIMER;
1976 }
1977
1978 if (int_stat) {
Glenn Streiff7495ab62008-04-29 13:46:54 -07001979 if (int_stat & ~(NES_INT_INTF | NES_INT_TIMER | NES_INT_MAC0|
1980 NES_INT_MAC1|NES_INT_MAC2 | NES_INT_MAC3)) {
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001981 /* Ack the interrupts */
1982 nes_write32(nesdev->regs+NES_INT_STAT,
Glenn Streiff7495ab62008-04-29 13:46:54 -07001983 (int_stat & ~(NES_INT_INTF | NES_INT_TIMER | NES_INT_MAC0|
1984 NES_INT_MAC1 | NES_INT_MAC2 | NES_INT_MAC3)));
Glenn Streiff3c2d7742008-02-04 20:20:45 -08001985 }
1986
1987 temp_int_stat = int_stat;
1988 for (counter = 0, int_status_bit = 1; counter < 16; counter++) {
1989 if (int_stat & int_status_bit) {
1990 nes_process_ceq(nesdev, &nesadapter->ceq[counter]);
1991 temp_int_stat &= ~int_status_bit;
1992 completion_ints = 1;
1993 }
1994 if (!(temp_int_stat & 0x0000ffff))
1995 break;
1996 int_status_bit <<= 1;
1997 }
1998
1999 /* Process the AEQ for this pci function */
2000 int_status_bit = 1 << (16 + PCI_FUNC(nesdev->pcidev->devfn));
2001 if (int_stat & int_status_bit) {
2002 nes_process_aeq(nesdev, &nesadapter->aeq[PCI_FUNC(nesdev->pcidev->devfn)]);
2003 }
2004
2005 /* Process the MAC interrupt for this pci function */
2006 int_status_bit = 1 << (24 + nesdev->mac_index);
2007 if (int_stat & int_status_bit) {
2008 nes_process_mac_intr(nesdev, nesdev->mac_index);
2009 }
2010
2011 if (int_stat & NES_INT_TIMER) {
2012 if (timer_stat & nesdev->timer_int_req) {
2013 nes_write32(nesdev->regs + NES_TIMER_STAT,
2014 (timer_stat & nesdev->timer_int_req) |
2015 ~(nesdev->nesadapter->timer_int_req));
2016 timer_ints = 1;
2017 }
2018 }
2019
2020 if (int_stat & NES_INT_INTF) {
2021 processed_intf_int = 1;
2022 intf_int_stat = nes_read32(nesdev->regs+NES_INTF_INT_STAT);
2023 intf_int_stat &= nesdev->intf_int_req;
2024 if (NES_INTF_INT_CRITERR & intf_int_stat) {
2025 debug_error = nes_read_indexed(nesdev, NES_IDX_DEBUG_ERROR_CONTROL_STATUS);
2026 printk(KERN_ERR PFX "Critical Error reported by device!!! 0x%02X\n",
2027 (u16)debug_error);
2028 nes_write_indexed(nesdev, NES_IDX_DEBUG_ERROR_CONTROL_STATUS,
2029 0x01010000 | (debug_error & 0x0000ffff));
2030 /* BUG(); */
2031 if (crit_err_count++ > 10)
2032 nes_write_indexed(nesdev, NES_IDX_DEBUG_ERROR_MASKS1, 1 << 0x17);
2033 }
2034 if (NES_INTF_INT_PCIERR & intf_int_stat) {
2035 printk(KERN_ERR PFX "PCI Error reported by device!!!\n");
2036 BUG();
2037 }
2038 if (NES_INTF_INT_AEQ_OFLOW & intf_int_stat) {
2039 printk(KERN_ERR PFX "AEQ Overflow reported by device!!!\n");
2040 BUG();
2041 }
2042 nes_write32(nesdev->regs+NES_INTF_INT_STAT, intf_int_stat);
2043 }
2044
2045 if (int_stat & NES_INT_TSW) {
2046 }
2047 }
2048 /* Don't use the interface interrupt bit stay in loop */
Glenn Streiff7495ab62008-04-29 13:46:54 -07002049 int_stat &= ~NES_INT_INTF | NES_INT_TIMER | NES_INT_MAC0 |
2050 NES_INT_MAC1 | NES_INT_MAC2 | NES_INT_MAC3;
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002051 } while ((int_stat != 0) && (loop_counter++ < MAX_DPC_ITERATIONS));
2052
2053 if (timer_ints == 1) {
2054 if ((nesadapter->et_rx_coalesce_usecs_irq) || (nesadapter->et_use_adaptive_rx_coalesce)) {
2055 if (completion_ints == 0) {
2056 nesdev->timer_only_int_count++;
2057 if (nesdev->timer_only_int_count>=nesadapter->timer_int_limit) {
2058 nesdev->timer_only_int_count = 0;
2059 nesdev->int_req &= ~NES_INT_TIMER;
2060 nes_write32(nesdev->regs + NES_INTF_INT_MASK, ~(nesdev->intf_int_req));
Glenn Streiff7495ab62008-04-29 13:46:54 -07002061 nes_write32(nesdev->regs + NES_INT_MASK, ~nesdev->int_req);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002062 } else {
Glenn Streiff7495ab62008-04-29 13:46:54 -07002063 nes_write32(nesdev->regs+NES_INT_MASK, 0x0000ffff | (~nesdev->int_req));
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002064 }
2065 } else {
2066 if (unlikely(nesadapter->et_use_adaptive_rx_coalesce))
2067 {
2068 nes_nic_init_timer(nesdev);
2069 }
2070 nesdev->timer_only_int_count = 0;
Glenn Streiff7495ab62008-04-29 13:46:54 -07002071 nes_write32(nesdev->regs+NES_INT_MASK, 0x0000ffff | (~nesdev->int_req));
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002072 }
2073 } else {
2074 nesdev->timer_only_int_count = 0;
2075 nesdev->int_req &= ~NES_INT_TIMER;
2076 nes_write32(nesdev->regs+NES_INTF_INT_MASK, ~(nesdev->intf_int_req));
2077 nes_write32(nesdev->regs+NES_TIMER_STAT,
2078 nesdev->timer_int_req | ~(nesdev->nesadapter->timer_int_req));
2079 nes_write32(nesdev->regs+NES_INT_MASK, ~nesdev->int_req);
2080 }
2081 } else {
2082 if ( (completion_ints == 1) &&
2083 (((nesadapter->et_rx_coalesce_usecs_irq) &&
2084 (!nesadapter->et_use_adaptive_rx_coalesce)) ||
2085 ((nesdev->deepcq_count > nesadapter->et_pkt_rate_low) &&
2086 (nesadapter->et_use_adaptive_rx_coalesce) )) ) {
2087 /* nes_debug(NES_DBG_ISR, "Enabling periodic timer interrupt.\n" ); */
2088 nesdev->timer_only_int_count = 0;
2089 nesdev->int_req |= NES_INT_TIMER;
2090 nes_write32(nesdev->regs+NES_TIMER_STAT,
2091 nesdev->timer_int_req | ~(nesdev->nesadapter->timer_int_req));
2092 nes_write32(nesdev->regs+NES_INTF_INT_MASK,
2093 ~(nesdev->intf_int_req | NES_INTF_PERIODIC_TIMER));
2094 nes_write32(nesdev->regs+NES_INT_MASK, 0x0000ffff | (~nesdev->int_req));
2095 } else {
2096 nes_write32(nesdev->regs+NES_INT_MASK, ~nesdev->int_req);
2097 }
2098 }
2099 nesdev->deepcq_count = 0;
2100}
2101
2102
2103/**
2104 * nes_process_ceq
2105 */
Roland Dreier1a855fbf2008-04-16 21:01:09 -07002106static void nes_process_ceq(struct nes_device *nesdev, struct nes_hw_ceq *ceq)
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002107{
2108 u64 u64temp;
2109 struct nes_hw_cq *cq;
2110 u32 head;
2111 u32 ceq_size;
2112
2113 /* nes_debug(NES_DBG_CQ, "\n"); */
2114 head = ceq->ceq_head;
2115 ceq_size = ceq->ceq_size;
2116
2117 do {
2118 if (le32_to_cpu(ceq->ceq_vbase[head].ceqe_words[NES_CEQE_CQ_CTX_HIGH_IDX]) &
2119 NES_CEQE_VALID) {
Glenn Streiff7495ab62008-04-29 13:46:54 -07002120 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 -08002121 ((u64)(le32_to_cpu(ceq->ceq_vbase[head].ceqe_words[NES_CEQE_CQ_CTX_LOW_IDX])));
2122 u64temp <<= 1;
2123 cq = *((struct nes_hw_cq **)&u64temp);
2124 /* nes_debug(NES_DBG_CQ, "pCQ = %p\n", cq); */
2125 barrier();
2126 ceq->ceq_vbase[head].ceqe_words[NES_CEQE_CQ_CTX_HIGH_IDX] = 0;
2127
2128 /* call the event handler */
2129 cq->ce_handler(nesdev, cq);
2130
2131 if (++head >= ceq_size)
2132 head = 0;
2133 } else {
2134 break;
2135 }
2136
2137 } while (1);
2138
2139 ceq->ceq_head = head;
2140}
2141
2142
2143/**
2144 * nes_process_aeq
2145 */
Roland Dreier1a855fbf2008-04-16 21:01:09 -07002146static void nes_process_aeq(struct nes_device *nesdev, struct nes_hw_aeq *aeq)
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002147{
Glenn Streiff7495ab62008-04-29 13:46:54 -07002148 /* u64 u64temp; */
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002149 u32 head;
2150 u32 aeq_size;
2151 u32 aeqe_misc;
2152 u32 aeqe_cq_id;
2153 struct nes_hw_aeqe volatile *aeqe;
2154
2155 head = aeq->aeq_head;
2156 aeq_size = aeq->aeq_size;
2157
2158 do {
2159 aeqe = &aeq->aeq_vbase[head];
2160 if ((le32_to_cpu(aeqe->aeqe_words[NES_AEQE_MISC_IDX]) & NES_AEQE_VALID) == 0)
2161 break;
2162 aeqe_misc = le32_to_cpu(aeqe->aeqe_words[NES_AEQE_MISC_IDX]);
2163 aeqe_cq_id = le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX]);
2164 if (aeqe_misc & (NES_AEQE_QP|NES_AEQE_CQ)) {
2165 if (aeqe_cq_id >= NES_FIRST_QPN) {
2166 /* dealing with an accelerated QP related AE */
Glenn Streiff7495ab62008-04-29 13:46:54 -07002167 /*
2168 * u64temp = (((u64)(le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_HIGH_IDX]))) << 32) |
2169 * ((u64)(le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_LOW_IDX])));
2170 */
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002171 nes_process_iwarp_aeqe(nesdev, (struct nes_hw_aeqe *)aeqe);
2172 } else {
2173 /* TODO: dealing with a CQP related AE */
2174 nes_debug(NES_DBG_AEQ, "Processing CQP related AE, misc = 0x%04X\n",
2175 (u16)(aeqe_misc >> 16));
2176 }
2177 }
2178
2179 aeqe->aeqe_words[NES_AEQE_MISC_IDX] = 0;
2180
2181 if (++head >= aeq_size)
2182 head = 0;
2183 }
2184 while (1);
2185 aeq->aeq_head = head;
2186}
2187
2188static void nes_reset_link(struct nes_device *nesdev, u32 mac_index)
2189{
2190 struct nes_adapter *nesadapter = nesdev->nesadapter;
2191 u32 reset_value;
2192 u32 i=0;
2193 u32 u32temp;
2194
2195 if (nesadapter->hw_rev == NE020_REV) {
2196 return;
2197 }
2198 mh_detected++;
2199
2200 reset_value = nes_read32(nesdev->regs+NES_SOFTWARE_RESET);
2201
2202 if ((mac_index == 0) || ((mac_index == 1) && (nesadapter->OneG_Mode)))
2203 reset_value |= 0x0000001d;
2204 else
2205 reset_value |= 0x0000002d;
2206
2207 if (4 <= (nesadapter->link_interrupt_count[mac_index] / ((u16)NES_MAX_LINK_INTERRUPTS))) {
2208 if ((!nesadapter->OneG_Mode) && (nesadapter->port_count == 2)) {
2209 nesadapter->link_interrupt_count[0] = 0;
2210 nesadapter->link_interrupt_count[1] = 0;
2211 u32temp = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1);
2212 if (0x00000040 & u32temp)
2213 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, 0x0000F088);
2214 else
2215 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, 0x0000F0C8);
2216
2217 reset_value |= 0x0000003d;
2218 }
2219 nesadapter->link_interrupt_count[mac_index] = 0;
2220 }
2221
2222 nes_write32(nesdev->regs+NES_SOFTWARE_RESET, reset_value);
2223
2224 while (((nes_read32(nesdev->regs+NES_SOFTWARE_RESET)
2225 & 0x00000040) != 0x00000040) && (i++ < 5000));
2226
2227 if (0x0000003d == (reset_value & 0x0000003d)) {
2228 u32 pcs_control_status0, pcs_control_status1;
2229
2230 for (i = 0; i < 10; i++) {
2231 pcs_control_status0 = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0);
2232 pcs_control_status1 = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + 0x200);
2233 if (((0x0F000000 == (pcs_control_status0 & 0x0F000000))
2234 && (pcs_control_status0 & 0x00100000))
2235 || ((0x0F000000 == (pcs_control_status1 & 0x0F000000))
2236 && (pcs_control_status1 & 0x00100000)))
2237 continue;
2238 else
2239 break;
2240 }
2241 if (10 == i) {
2242 u32temp = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1);
2243 if (0x00000040 & u32temp)
2244 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, 0x0000F088);
2245 else
2246 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, 0x0000F0C8);
2247
2248 nes_write32(nesdev->regs+NES_SOFTWARE_RESET, reset_value);
2249
2250 while (((nes_read32(nesdev->regs + NES_SOFTWARE_RESET)
2251 & 0x00000040) != 0x00000040) && (i++ < 5000));
2252 }
2253 }
2254}
2255
2256/**
2257 * nes_process_mac_intr
2258 */
Roland Dreier1a855fbf2008-04-16 21:01:09 -07002259static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number)
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002260{
2261 unsigned long flags;
2262 u32 pcs_control_status;
2263 struct nes_adapter *nesadapter = nesdev->nesadapter;
2264 struct nes_vnic *nesvnic;
2265 u32 mac_status;
2266 u32 mac_index = nesdev->mac_index;
2267 u32 u32temp;
2268 u16 phy_data;
2269 u16 temp_phy_data;
Eric Schneider0e1de5d2008-04-29 13:46:54 -07002270 u32 pcs_val = 0x0f0f0000;
2271 u32 pcs_mask = 0x0f1f0000;
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002272
2273 spin_lock_irqsave(&nesadapter->phy_lock, flags);
2274 if (nesadapter->mac_sw_state[mac_number] != NES_MAC_SW_IDLE) {
2275 spin_unlock_irqrestore(&nesadapter->phy_lock, flags);
2276 return;
2277 }
2278 nesadapter->mac_sw_state[mac_number] = NES_MAC_SW_INTERRUPT;
2279 spin_unlock_irqrestore(&nesadapter->phy_lock, flags);
2280
2281 /* ack the MAC interrupt */
2282 mac_status = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (mac_index * 0x200));
2283 /* Clear the interrupt */
2284 nes_write_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (mac_index * 0x200), mac_status);
2285
2286 nes_debug(NES_DBG_PHY, "MAC%u interrupt status = 0x%X.\n", mac_number, mac_status);
2287
2288 if (mac_status & (NES_MAC_INT_LINK_STAT_CHG | NES_MAC_INT_XGMII_EXT)) {
2289 nesdev->link_status_interrupts++;
2290 if (0 == (++nesadapter->link_interrupt_count[mac_index] % ((u16)NES_MAX_LINK_INTERRUPTS))) {
2291 spin_lock_irqsave(&nesadapter->phy_lock, flags);
2292 nes_reset_link(nesdev, mac_index);
2293 spin_unlock_irqrestore(&nesadapter->phy_lock, flags);
2294 }
2295 /* read the PHY interrupt status register */
Chien Tungfcb7ad32008-09-30 14:49:44 -07002296 if ((nesadapter->OneG_Mode) &&
2297 (nesadapter->phy_type[mac_index] != NES_PHY_TYPE_PUMA_1G)) {
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002298 do {
2299 nes_read_1G_phy_reg(nesdev, 0x1a,
2300 nesadapter->phy_index[mac_index], &phy_data);
2301 nes_debug(NES_DBG_PHY, "Phy%d data from register 0x1a = 0x%X.\n",
2302 nesadapter->phy_index[mac_index], phy_data);
2303 } while (phy_data&0x8000);
2304
2305 temp_phy_data = 0;
2306 do {
2307 nes_read_1G_phy_reg(nesdev, 0x11,
2308 nesadapter->phy_index[mac_index], &phy_data);
2309 nes_debug(NES_DBG_PHY, "Phy%d data from register 0x11 = 0x%X.\n",
2310 nesadapter->phy_index[mac_index], phy_data);
2311 if (temp_phy_data == phy_data)
2312 break;
2313 temp_phy_data = phy_data;
2314 } while (1);
2315
2316 nes_read_1G_phy_reg(nesdev, 0x1e,
2317 nesadapter->phy_index[mac_index], &phy_data);
2318 nes_debug(NES_DBG_PHY, "Phy%d data from register 0x1e = 0x%X.\n",
2319 nesadapter->phy_index[mac_index], phy_data);
2320
2321 nes_read_1G_phy_reg(nesdev, 1,
2322 nesadapter->phy_index[mac_index], &phy_data);
2323 nes_debug(NES_DBG_PHY, "1G phy%u data from register 1 = 0x%X\n",
2324 nesadapter->phy_index[mac_index], phy_data);
2325
2326 if (temp_phy_data & 0x1000) {
2327 nes_debug(NES_DBG_PHY, "The Link is up according to the PHY\n");
2328 phy_data = 4;
2329 } else {
2330 nes_debug(NES_DBG_PHY, "The Link is down according to the PHY\n");
2331 }
2332 }
2333 nes_debug(NES_DBG_PHY, "Eth SERDES Common Status: 0=0x%08X, 1=0x%08X\n",
2334 nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_STATUS0),
2335 nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_STATUS0+0x200));
Eric Schneider0e1de5d2008-04-29 13:46:54 -07002336
2337 if (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_PUMA_1G) {
2338 switch (mac_index) {
2339 case 1:
2340 case 3:
2341 pcs_control_status = nes_read_indexed(nesdev,
2342 NES_IDX_PHY_PCS_CONTROL_STATUS0 + 0x200);
2343 break;
2344 default:
2345 pcs_control_status = nes_read_indexed(nesdev,
2346 NES_IDX_PHY_PCS_CONTROL_STATUS0);
2347 break;
2348 }
2349 } else {
2350 pcs_control_status = nes_read_indexed(nesdev,
2351 NES_IDX_PHY_PCS_CONTROL_STATUS0 + ((mac_index & 1) * 0x200));
2352 pcs_control_status = nes_read_indexed(nesdev,
2353 NES_IDX_PHY_PCS_CONTROL_STATUS0 + ((mac_index & 1) * 0x200));
2354 }
2355
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002356 nes_debug(NES_DBG_PHY, "PCS PHY Control/Status%u: 0x%08X\n",
2357 mac_index, pcs_control_status);
Eric Schneider0e1de5d2008-04-29 13:46:54 -07002358 if ((nesadapter->OneG_Mode) &&
2359 (nesadapter->phy_type[mac_index] != NES_PHY_TYPE_PUMA_1G)) {
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002360 u32temp = 0x01010000;
2361 if (nesadapter->port_count > 2) {
2362 u32temp |= 0x02020000;
2363 }
2364 if ((pcs_control_status & u32temp)!= u32temp) {
2365 phy_data = 0;
2366 nes_debug(NES_DBG_PHY, "PCS says the link is down\n");
2367 }
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002368 } else {
Eric Schneider0e1de5d2008-04-29 13:46:54 -07002369 switch (nesadapter->phy_type[mac_index]) {
2370 case NES_PHY_TYPE_IRIS:
2371 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1);
2372 temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
2373 u32temp = 20;
2374 do {
2375 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1);
2376 phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
2377 if ((phy_data == temp_phy_data) || (!(--u32temp)))
2378 break;
2379 temp_phy_data = phy_data;
2380 } while (1);
2381 nes_debug(NES_DBG_PHY, "%s: Phy data = 0x%04X, link was %s.\n",
2382 __func__, phy_data, nesadapter->mac_link_down[mac_index] ? "DOWN" : "UP");
2383 break;
2384
2385 case NES_PHY_TYPE_ARGUS:
2386 /* clear the alarms */
2387 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0x0008);
2388 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0xc001);
2389 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0xc002);
2390 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0xc005);
2391 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0xc006);
2392 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 0x9003);
2393 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 0x9004);
2394 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 0x9005);
2395 /* check link status */
2396 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1);
2397 temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
2398 u32temp = 100;
2399 do {
2400 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1);
2401
2402 phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
2403 if ((phy_data == temp_phy_data) || (!(--u32temp)))
2404 break;
2405 temp_phy_data = phy_data;
2406 } while (1);
2407 nes_debug(NES_DBG_PHY, "%s: Phy data = 0x%04X, link was %s.\n",
2408 __func__, phy_data, nesadapter->mac_link_down ? "DOWN" : "UP");
2409 break;
2410
2411 case NES_PHY_TYPE_PUMA_1G:
2412 if (mac_index < 2)
2413 pcs_val = pcs_mask = 0x01010000;
2414 else
2415 pcs_val = pcs_mask = 0x02020000;
2416 /* fall through */
2417 default:
2418 phy_data = (pcs_val == (pcs_control_status & pcs_mask)) ? 0x4 : 0x0;
2419 break;
2420 }
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002421 }
2422
2423 if (phy_data & 0x0004) {
2424 nesadapter->mac_link_down[mac_index] = 0;
2425 list_for_each_entry(nesvnic, &nesadapter->nesvnic_list[mac_index], list) {
2426 nes_debug(NES_DBG_PHY, "The Link is UP!!. linkup was %d\n",
2427 nesvnic->linkup);
2428 if (nesvnic->linkup == 0) {
Eric Schneider0e1de5d2008-04-29 13:46:54 -07002429 printk(PFX "The Link is now up for port %s, netdev %p.\n",
2430 nesvnic->netdev->name, nesvnic->netdev);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002431 if (netif_queue_stopped(nesvnic->netdev))
2432 netif_start_queue(nesvnic->netdev);
2433 nesvnic->linkup = 1;
2434 netif_carrier_on(nesvnic->netdev);
2435 }
2436 }
2437 } else {
2438 nesadapter->mac_link_down[mac_index] = 1;
2439 list_for_each_entry(nesvnic, &nesadapter->nesvnic_list[mac_index], list) {
2440 nes_debug(NES_DBG_PHY, "The Link is Down!!. linkup was %d\n",
2441 nesvnic->linkup);
2442 if (nesvnic->linkup == 1) {
Eric Schneider0e1de5d2008-04-29 13:46:54 -07002443 printk(PFX "The Link is now down for port %s, netdev %p.\n",
2444 nesvnic->netdev->name, nesvnic->netdev);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002445 if (!(netif_queue_stopped(nesvnic->netdev)))
2446 netif_stop_queue(nesvnic->netdev);
2447 nesvnic->linkup = 0;
2448 netif_carrier_off(nesvnic->netdev);
2449 }
2450 }
2451 }
2452 }
2453
2454 nesadapter->mac_sw_state[mac_number] = NES_MAC_SW_IDLE;
2455}
2456
2457
2458
Roland Dreier1a855fbf2008-04-16 21:01:09 -07002459static void nes_nic_napi_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq)
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002460{
2461 struct nes_vnic *nesvnic = container_of(cq, struct nes_vnic, nic_cq);
2462
2463 netif_rx_schedule(nesdev->netdev[nesvnic->netdev_index], &nesvnic->napi);
2464}
2465
2466
2467/* The MAX_RQES_TO_PROCESS defines how many max read requests to complete before
2468* getting out of nic_ce_handler
2469*/
2470#define MAX_RQES_TO_PROCESS 384
2471
2472/**
2473 * nes_nic_ce_handler
2474 */
2475void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq)
2476{
2477 u64 u64temp;
2478 dma_addr_t bus_address;
2479 struct nes_hw_nic *nesnic;
2480 struct nes_vnic *nesvnic = container_of(cq, struct nes_vnic, nic_cq);
2481 struct nes_adapter *nesadapter = nesdev->nesadapter;
2482 struct nes_hw_nic_rq_wqe *nic_rqe;
2483 struct nes_hw_nic_sq_wqe *nic_sqe;
2484 struct sk_buff *skb;
2485 struct sk_buff *rx_skb;
2486 __le16 *wqe_fragment_length;
2487 u32 head;
2488 u32 cq_size;
2489 u32 rx_pkt_size;
2490 u32 cqe_count=0;
2491 u32 cqe_errv;
2492 u32 cqe_misc;
2493 u16 wqe_fragment_index = 1; /* first fragment (0) is used by copy buffer */
2494 u16 vlan_tag;
2495 u16 pkt_type;
2496 u16 rqes_processed = 0;
2497 u8 sq_cqes = 0;
Faisal Latif37dab412008-04-29 13:46:54 -07002498 u8 nes_use_lro = 0;
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002499
2500 head = cq->cq_head;
2501 cq_size = cq->cq_size;
2502 cq->cqes_pending = 1;
Faisal Latif37dab412008-04-29 13:46:54 -07002503 if (nesvnic->netdev->features & NETIF_F_LRO)
2504 nes_use_lro = 1;
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002505 do {
2506 if (le32_to_cpu(cq->cq_vbase[head].cqe_words[NES_NIC_CQE_MISC_IDX]) &
2507 NES_NIC_CQE_VALID) {
2508 nesnic = &nesvnic->nic;
2509 cqe_misc = le32_to_cpu(cq->cq_vbase[head].cqe_words[NES_NIC_CQE_MISC_IDX]);
2510 if (cqe_misc & NES_NIC_CQE_SQ) {
2511 sq_cqes++;
2512 wqe_fragment_index = 1;
2513 nic_sqe = &nesnic->sq_vbase[nesnic->sq_tail];
2514 skb = nesnic->tx_skb[nesnic->sq_tail];
2515 wqe_fragment_length = (__le16 *)&nic_sqe->wqe_words[NES_NIC_SQ_WQE_LENGTH_0_TAG_IDX];
2516 /* bump past the vlan tag */
2517 wqe_fragment_length++;
2518 if (le16_to_cpu(wqe_fragment_length[wqe_fragment_index]) != 0) {
Glenn Streiff7495ab62008-04-29 13:46:54 -07002519 u64temp = (u64) le32_to_cpu(nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_LOW_IDX +
2520 wqe_fragment_index * 2]);
2521 u64temp += ((u64)le32_to_cpu(nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_HIGH_IDX +
2522 wqe_fragment_index * 2])) << 32;
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002523 bus_address = (dma_addr_t)u64temp;
2524 if (test_and_clear_bit(nesnic->sq_tail, nesnic->first_frag_overflow)) {
2525 pci_unmap_single(nesdev->pcidev,
2526 bus_address,
2527 le16_to_cpu(wqe_fragment_length[wqe_fragment_index++]),
2528 PCI_DMA_TODEVICE);
2529 }
2530 for (; wqe_fragment_index < 5; wqe_fragment_index++) {
2531 if (wqe_fragment_length[wqe_fragment_index]) {
Glenn Streiff7495ab62008-04-29 13:46:54 -07002532 u64temp = le32_to_cpu(nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_LOW_IDX +
2533 wqe_fragment_index * 2]);
2534 u64temp += ((u64)le32_to_cpu(nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_HIGH_IDX
2535 + wqe_fragment_index * 2])) <<32;
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002536 bus_address = (dma_addr_t)u64temp;
2537 pci_unmap_page(nesdev->pcidev,
2538 bus_address,
2539 le16_to_cpu(wqe_fragment_length[wqe_fragment_index]),
2540 PCI_DMA_TODEVICE);
2541 } else
2542 break;
2543 }
2544 if (skb)
2545 dev_kfree_skb_any(skb);
2546 }
2547 nesnic->sq_tail++;
2548 nesnic->sq_tail &= nesnic->sq_size-1;
2549 if (sq_cqes > 128) {
2550 barrier();
2551 /* restart the queue if it had been stopped */
2552 if (netif_queue_stopped(nesvnic->netdev))
2553 netif_wake_queue(nesvnic->netdev);
2554 sq_cqes = 0;
2555 }
2556 } else {
2557 rqes_processed ++;
2558
2559 cq->rx_cqes_completed++;
2560 cq->rx_pkts_indicated++;
2561 rx_pkt_size = cqe_misc & 0x0000ffff;
2562 nic_rqe = &nesnic->rq_vbase[nesnic->rq_tail];
2563 /* Get the skb */
2564 rx_skb = nesnic->rx_skb[nesnic->rq_tail];
2565 nic_rqe = &nesnic->rq_vbase[nesvnic->nic.rq_tail];
2566 bus_address = (dma_addr_t)le32_to_cpu(nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_LOW_IDX]);
2567 bus_address += ((u64)le32_to_cpu(nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_HIGH_IDX])) << 32;
2568 pci_unmap_single(nesdev->pcidev, bus_address,
2569 nesvnic->max_frame_size, PCI_DMA_FROMDEVICE);
2570 /* rx_skb->tail = rx_skb->data + rx_pkt_size; */
2571 /* rx_skb->len = rx_pkt_size; */
2572 rx_skb->len = 0; /* TODO: see if this is necessary */
2573 skb_put(rx_skb, rx_pkt_size);
2574 rx_skb->protocol = eth_type_trans(rx_skb, nesvnic->netdev);
2575 nesnic->rq_tail++;
2576 nesnic->rq_tail &= nesnic->rq_size - 1;
2577
2578 atomic_inc(&nesvnic->rx_skbs_needed);
2579 if (atomic_read(&nesvnic->rx_skbs_needed) > (nesvnic->nic.rq_size>>1)) {
2580 nes_write32(nesdev->regs+NES_CQE_ALLOC,
2581 cq->cq_number | (cqe_count << 16));
Glenn Streiff7495ab62008-04-29 13:46:54 -07002582 /* nesadapter->tune_timer.cq_count += cqe_count; */
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002583 nesdev->currcq_count += cqe_count;
2584 cqe_count = 0;
2585 nes_replenish_nic_rq(nesvnic);
2586 }
2587 pkt_type = (u16)(le32_to_cpu(cq->cq_vbase[head].cqe_words[NES_NIC_CQE_TAG_PKT_TYPE_IDX]));
2588 cqe_errv = (cqe_misc & NES_NIC_CQE_ERRV_MASK) >> NES_NIC_CQE_ERRV_SHIFT;
2589 rx_skb->ip_summed = CHECKSUM_NONE;
2590
2591 if ((NES_PKT_TYPE_TCPV4_BITS == (pkt_type & NES_PKT_TYPE_TCPV4_MASK)) ||
2592 (NES_PKT_TYPE_UDPV4_BITS == (pkt_type & NES_PKT_TYPE_UDPV4_MASK))) {
2593 if ((cqe_errv &
2594 (NES_NIC_ERRV_BITS_IPV4_CSUM_ERR | NES_NIC_ERRV_BITS_TCPUDP_CSUM_ERR |
2595 NES_NIC_ERRV_BITS_IPH_ERR | NES_NIC_ERRV_BITS_WQE_OVERRUN)) == 0) {
2596 if (nesvnic->rx_checksum_disabled == 0) {
2597 rx_skb->ip_summed = CHECKSUM_UNNECESSARY;
2598 }
2599 } else
2600 nes_debug(NES_DBG_CQ, "%s: unsuccessfully checksummed TCP or UDP packet."
2601 " errv = 0x%X, pkt_type = 0x%X.\n",
2602 nesvnic->netdev->name, cqe_errv, pkt_type);
2603
2604 } else if ((pkt_type & NES_PKT_TYPE_IPV4_MASK) == NES_PKT_TYPE_IPV4_BITS) {
2605 if ((cqe_errv &
2606 (NES_NIC_ERRV_BITS_IPV4_CSUM_ERR | NES_NIC_ERRV_BITS_IPH_ERR |
2607 NES_NIC_ERRV_BITS_WQE_OVERRUN)) == 0) {
2608 if (nesvnic->rx_checksum_disabled == 0) {
2609 rx_skb->ip_summed = CHECKSUM_UNNECESSARY;
2610 /* nes_debug(NES_DBG_CQ, "%s: Reporting successfully checksummed IPv4 packet.\n",
2611 nesvnic->netdev->name); */
2612 }
2613 } else
2614 nes_debug(NES_DBG_CQ, "%s: unsuccessfully checksummed TCP or UDP packet."
2615 " errv = 0x%X, pkt_type = 0x%X.\n",
2616 nesvnic->netdev->name, cqe_errv, pkt_type);
2617 }
2618 /* nes_debug(NES_DBG_CQ, "pkt_type=%x, APBVT_MASK=%x\n",
2619 pkt_type, (pkt_type & NES_PKT_TYPE_APBVT_MASK)); */
2620
2621 if ((pkt_type & NES_PKT_TYPE_APBVT_MASK) == NES_PKT_TYPE_APBVT_BITS) {
2622 nes_cm_recv(rx_skb, nesvnic->netdev);
2623 } else {
2624 if ((cqe_misc & NES_NIC_CQE_TAG_VALID) && (nesvnic->vlan_grp != NULL)) {
2625 vlan_tag = (u16)(le32_to_cpu(
2626 cq->cq_vbase[head].cqe_words[NES_NIC_CQE_TAG_PKT_TYPE_IDX])
2627 >> 16);
2628 nes_debug(NES_DBG_CQ, "%s: Reporting stripped VLAN packet. Tag = 0x%04X\n",
2629 nesvnic->netdev->name, vlan_tag);
Faisal Latif37dab412008-04-29 13:46:54 -07002630 if (nes_use_lro)
2631 lro_vlan_hwaccel_receive_skb(&nesvnic->lro_mgr, rx_skb,
2632 nesvnic->vlan_grp, vlan_tag, NULL);
2633 else
2634 nes_vlan_rx(rx_skb, nesvnic->vlan_grp, vlan_tag);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002635 } else {
Faisal Latif37dab412008-04-29 13:46:54 -07002636 if (nes_use_lro)
2637 lro_receive_skb(&nesvnic->lro_mgr, rx_skb, NULL);
2638 else
2639 nes_netif_rx(rx_skb);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002640 }
2641 }
2642
2643 nesvnic->netdev->last_rx = jiffies;
2644 /* nesvnic->netstats.rx_packets++; */
2645 /* nesvnic->netstats.rx_bytes += rx_pkt_size; */
2646 }
2647
2648 cq->cq_vbase[head].cqe_words[NES_NIC_CQE_MISC_IDX] = 0;
2649 /* Accounting... */
2650 cqe_count++;
2651 if (++head >= cq_size)
2652 head = 0;
2653 if (cqe_count == 255) {
2654 /* Replenish Nic CQ */
2655 nes_write32(nesdev->regs+NES_CQE_ALLOC,
2656 cq->cq_number | (cqe_count << 16));
Glenn Streiff7495ab62008-04-29 13:46:54 -07002657 /* nesdev->nesadapter->tune_timer.cq_count += cqe_count; */
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002658 nesdev->currcq_count += cqe_count;
2659 cqe_count = 0;
2660 }
2661
2662 if (cq->rx_cqes_completed >= nesvnic->budget)
2663 break;
2664 } else {
2665 cq->cqes_pending = 0;
2666 break;
2667 }
2668
2669 } while (1);
2670
Faisal Latif37dab412008-04-29 13:46:54 -07002671 if (nes_use_lro)
2672 lro_flush_all(&nesvnic->lro_mgr);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002673 if (sq_cqes) {
2674 barrier();
2675 /* restart the queue if it had been stopped */
2676 if (netif_queue_stopped(nesvnic->netdev))
2677 netif_wake_queue(nesvnic->netdev);
2678 }
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002679 cq->cq_head = head;
2680 /* nes_debug(NES_DBG_CQ, "CQ%u Processed = %u cqes, new head = %u.\n",
2681 cq->cq_number, cqe_count, cq->cq_head); */
2682 cq->cqe_allocs_pending = cqe_count;
2683 if (unlikely(nesadapter->et_use_adaptive_rx_coalesce))
2684 {
Glenn Streiff7495ab62008-04-29 13:46:54 -07002685 /* nesdev->nesadapter->tune_timer.cq_count += cqe_count; */
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002686 nesdev->currcq_count += cqe_count;
2687 nes_nic_tune_timer(nesdev);
2688 }
2689 if (atomic_read(&nesvnic->rx_skbs_needed))
2690 nes_replenish_nic_rq(nesvnic);
Faisal Latif37dab412008-04-29 13:46:54 -07002691}
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002692
2693
2694/**
2695 * nes_cqp_ce_handler
2696 */
Roland Dreier1a855fbf2008-04-16 21:01:09 -07002697static void nes_cqp_ce_handler(struct nes_device *nesdev, struct nes_hw_cq *cq)
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002698{
2699 u64 u64temp;
2700 unsigned long flags;
2701 struct nes_hw_cqp *cqp = NULL;
2702 struct nes_cqp_request *cqp_request;
2703 struct nes_hw_cqp_wqe *cqp_wqe;
2704 u32 head;
2705 u32 cq_size;
2706 u32 cqe_count=0;
2707 u32 error_code;
2708 /* u32 counter; */
2709
2710 head = cq->cq_head;
2711 cq_size = cq->cq_size;
2712
2713 do {
2714 /* process the CQE */
2715 /* nes_debug(NES_DBG_CQP, "head=%u cqe_words=%08X\n", head,
2716 le32_to_cpu(cq->cq_vbase[head].cqe_words[NES_CQE_OPCODE_IDX])); */
2717
2718 if (le32_to_cpu(cq->cq_vbase[head].cqe_words[NES_CQE_OPCODE_IDX]) & NES_CQE_VALID) {
2719 u64temp = (((u64)(le32_to_cpu(cq->cq_vbase[head].
Glenn Streiff7495ab62008-04-29 13:46:54 -07002720 cqe_words[NES_CQE_COMP_COMP_CTX_HIGH_IDX]))) << 32) |
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002721 ((u64)(le32_to_cpu(cq->cq_vbase[head].
2722 cqe_words[NES_CQE_COMP_COMP_CTX_LOW_IDX])));
2723 cqp = *((struct nes_hw_cqp **)&u64temp);
2724
2725 error_code = le32_to_cpu(cq->cq_vbase[head].cqe_words[NES_CQE_ERROR_CODE_IDX]);
2726 if (error_code) {
2727 nes_debug(NES_DBG_CQP, "Bad Completion code for opcode 0x%02X from CQP,"
2728 " Major/Minor codes = 0x%04X:%04X.\n",
2729 le32_to_cpu(cq->cq_vbase[head].cqe_words[NES_CQE_OPCODE_IDX])&0x3f,
2730 (u16)(error_code >> 16),
2731 (u16)error_code);
2732 nes_debug(NES_DBG_CQP, "cqp: qp_id=%u, sq_head=%u, sq_tail=%u\n",
2733 cqp->qp_id, cqp->sq_head, cqp->sq_tail);
2734 }
2735
2736 u64temp = (((u64)(le32_to_cpu(nesdev->cqp.sq_vbase[cqp->sq_tail].
Glenn Streiff7495ab62008-04-29 13:46:54 -07002737 wqe_words[NES_CQP_WQE_COMP_SCRATCH_HIGH_IDX]))) << 32) |
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002738 ((u64)(le32_to_cpu(nesdev->cqp.sq_vbase[cqp->sq_tail].
2739 wqe_words[NES_CQP_WQE_COMP_SCRATCH_LOW_IDX])));
2740 cqp_request = *((struct nes_cqp_request **)&u64temp);
2741 if (cqp_request) {
2742 if (cqp_request->waiting) {
2743 /* nes_debug(NES_DBG_CQP, "%s: Waking up requestor\n"); */
2744 cqp_request->major_code = (u16)(error_code >> 16);
2745 cqp_request->minor_code = (u16)error_code;
2746 barrier();
2747 cqp_request->request_done = 1;
2748 wake_up(&cqp_request->waitq);
Roland Dreier1ff66e82008-07-14 23:48:49 -07002749 nes_put_cqp_request(nesdev, cqp_request);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002750 } else {
Roland Dreier1ff66e82008-07-14 23:48:49 -07002751 if (cqp_request->callback)
2752 cqp_request->cqp_callback(nesdev, cqp_request);
2753 nes_free_cqp_request(nesdev, cqp_request);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002754 }
2755 } else {
2756 wake_up(&nesdev->cqp.waitq);
2757 }
2758
2759 cq->cq_vbase[head].cqe_words[NES_CQE_OPCODE_IDX] = 0;
Glenn Streiff7495ab62008-04-29 13:46:54 -07002760 nes_write32(nesdev->regs + NES_CQE_ALLOC, cq->cq_number | (1 << 16));
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002761 if (++cqp->sq_tail >= cqp->sq_size)
2762 cqp->sq_tail = 0;
2763
2764 /* Accounting... */
2765 cqe_count++;
2766 if (++head >= cq_size)
2767 head = 0;
2768 } else {
2769 break;
2770 }
2771 } while (1);
2772 cq->cq_head = head;
2773
2774 spin_lock_irqsave(&nesdev->cqp.lock, flags);
2775 while ((!list_empty(&nesdev->cqp_pending_reqs)) &&
2776 ((((nesdev->cqp.sq_tail+nesdev->cqp.sq_size)-nesdev->cqp.sq_head) &
2777 (nesdev->cqp.sq_size - 1)) != 1)) {
2778 cqp_request = list_entry(nesdev->cqp_pending_reqs.next,
2779 struct nes_cqp_request, list);
2780 list_del_init(&cqp_request->list);
2781 head = nesdev->cqp.sq_head++;
2782 nesdev->cqp.sq_head &= nesdev->cqp.sq_size-1;
2783 cqp_wqe = &nesdev->cqp.sq_vbase[head];
2784 memcpy(cqp_wqe, &cqp_request->cqp_wqe, sizeof(*cqp_wqe));
2785 barrier();
2786 cqp_wqe->wqe_words[NES_CQP_WQE_COMP_SCRATCH_LOW_IDX] =
2787 cpu_to_le32((u32)((unsigned long)cqp_request));
2788 cqp_wqe->wqe_words[NES_CQP_WQE_COMP_SCRATCH_HIGH_IDX] =
2789 cpu_to_le32((u32)(upper_32_bits((unsigned long)cqp_request)));
2790 nes_debug(NES_DBG_CQP, "CQP request %p (opcode 0x%02X) put on CQPs SQ wqe%u.\n",
2791 cqp_request, le32_to_cpu(cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX])&0x3f, head);
2792 /* Ring doorbell (1 WQEs) */
2793 barrier();
2794 nes_write32(nesdev->regs+NES_WQE_ALLOC, 0x01800000 | nesdev->cqp.qp_id);
2795 }
2796 spin_unlock_irqrestore(&nesdev->cqp.lock, flags);
2797
2798 /* Arm the CCQ */
2799 nes_write32(nesdev->regs+NES_CQE_ALLOC, NES_CQE_ALLOC_NOTIFY_NEXT |
2800 cq->cq_number);
2801 nes_read32(nesdev->regs+NES_CQE_ALLOC);
2802}
2803
2804
2805/**
2806 * nes_process_iwarp_aeqe
2807 */
Roland Dreier1a855fbf2008-04-16 21:01:09 -07002808static void nes_process_iwarp_aeqe(struct nes_device *nesdev,
2809 struct nes_hw_aeqe *aeqe)
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002810{
2811 u64 context;
2812 u64 aeqe_context = 0;
2813 unsigned long flags;
2814 struct nes_qp *nesqp;
2815 int resource_allocated;
2816 /* struct iw_cm_id *cm_id; */
2817 struct nes_adapter *nesadapter = nesdev->nesadapter;
2818 struct ib_event ibevent;
2819 /* struct iw_cm_event cm_event; */
2820 u32 aeq_info;
2821 u32 next_iwarp_state = 0;
2822 u16 async_event_id;
2823 u8 tcp_state;
2824 u8 iwarp_state;
2825
2826 nes_debug(NES_DBG_AEQ, "\n");
2827 aeq_info = le32_to_cpu(aeqe->aeqe_words[NES_AEQE_MISC_IDX]);
2828 if ((NES_AEQE_INBOUND_RDMA&aeq_info) || (!(NES_AEQE_QP&aeq_info))) {
Glenn Streiff7495ab62008-04-29 13:46:54 -07002829 context = le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_LOW_IDX]);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002830 context += ((u64)le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_HIGH_IDX])) << 32;
2831 } else {
2832 aeqe_context = le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_LOW_IDX]);
2833 aeqe_context += ((u64)le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_HIGH_IDX])) << 32;
2834 context = (unsigned long)nesadapter->qp_table[le32_to_cpu(
Glenn Streiff7495ab62008-04-29 13:46:54 -07002835 aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX]) - NES_FIRST_QPN];
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002836 BUG_ON(!context);
2837 }
2838
2839 async_event_id = (u16)aeq_info;
2840 tcp_state = (aeq_info & NES_AEQE_TCP_STATE_MASK) >> NES_AEQE_TCP_STATE_SHIFT;
2841 iwarp_state = (aeq_info & NES_AEQE_IWARP_STATE_MASK) >> NES_AEQE_IWARP_STATE_SHIFT;
2842 nes_debug(NES_DBG_AEQ, "aeid = 0x%04X, qp-cq id = %d, aeqe = %p,"
2843 " Tcp state = %s, iWARP state = %s\n",
2844 async_event_id,
2845 le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX]), aeqe,
2846 nes_tcp_state_str[tcp_state], nes_iwarp_state_str[iwarp_state]);
2847
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002848 switch (async_event_id) {
2849 case NES_AEQE_AEID_LLP_FIN_RECEIVED:
2850 nesqp = *((struct nes_qp **)&context);
2851 if (atomic_inc_return(&nesqp->close_timer_started) == 1) {
2852 nesqp->cm_id->add_ref(nesqp->cm_id);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002853 schedule_nes_timer(nesqp->cm_node, (struct sk_buff *)nesqp,
2854 NES_TIMER_TYPE_CLOSE, 1, 0);
2855 nes_debug(NES_DBG_AEQ, "QP%u Not decrementing QP refcount (%d),"
2856 " need ae to finish up, original_last_aeq = 0x%04X."
2857 " last_aeq = 0x%04X, scheduling timer. TCP state = %d\n",
2858 nesqp->hwqp.qp_id, atomic_read(&nesqp->refcount),
2859 async_event_id, nesqp->last_aeq, tcp_state);
2860 }
2861 if ((tcp_state != NES_AEQE_TCP_STATE_CLOSE_WAIT) ||
2862 (nesqp->ibqp_state != IB_QPS_RTS)) {
2863 /* FIN Received but tcp state or IB state moved on,
2864 should expect a close complete */
2865 return;
2866 }
2867 case NES_AEQE_AEID_LLP_CLOSE_COMPLETE:
2868 case NES_AEQE_AEID_LLP_CONNECTION_RESET:
2869 case NES_AEQE_AEID_TERMINATE_SENT:
2870 case NES_AEQE_AEID_RDMAP_ROE_BAD_LLP_CLOSE:
2871 case NES_AEQE_AEID_RESET_SENT:
2872 nesqp = *((struct nes_qp **)&context);
2873 if (async_event_id == NES_AEQE_AEID_RESET_SENT) {
2874 tcp_state = NES_AEQE_TCP_STATE_CLOSED;
2875 }
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002876 spin_lock_irqsave(&nesqp->lock, flags);
2877 nesqp->hw_iwarp_state = iwarp_state;
2878 nesqp->hw_tcp_state = tcp_state;
2879 nesqp->last_aeq = async_event_id;
2880
2881 if ((tcp_state == NES_AEQE_TCP_STATE_CLOSED) ||
2882 (tcp_state == NES_AEQE_TCP_STATE_TIME_WAIT)) {
2883 nesqp->hte_added = 0;
2884 spin_unlock_irqrestore(&nesqp->lock, flags);
2885 nes_debug(NES_DBG_AEQ, "issuing hw modifyqp for QP%u to remove hte\n",
2886 nesqp->hwqp.qp_id);
2887 nes_hw_modify_qp(nesdev, nesqp,
2888 NES_CQP_QP_IWARP_STATE_ERROR | NES_CQP_QP_DEL_HTE, 0);
2889 spin_lock_irqsave(&nesqp->lock, flags);
2890 }
2891
2892 if ((nesqp->ibqp_state == IB_QPS_RTS) &&
2893 ((tcp_state == NES_AEQE_TCP_STATE_CLOSE_WAIT) ||
2894 (async_event_id == NES_AEQE_AEID_LLP_CONNECTION_RESET))) {
2895 switch (nesqp->hw_iwarp_state) {
2896 case NES_AEQE_IWARP_STATE_RTS:
2897 next_iwarp_state = NES_CQP_QP_IWARP_STATE_CLOSING;
2898 nesqp->hw_iwarp_state = NES_AEQE_IWARP_STATE_CLOSING;
2899 break;
2900 case NES_AEQE_IWARP_STATE_TERMINATE:
2901 next_iwarp_state = NES_CQP_QP_IWARP_STATE_TERMINATE;
2902 nesqp->hw_iwarp_state = NES_AEQE_IWARP_STATE_TERMINATE;
2903 if (async_event_id == NES_AEQE_AEID_RDMAP_ROE_BAD_LLP_CLOSE) {
2904 next_iwarp_state |= 0x02000000;
2905 nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED;
2906 }
2907 break;
2908 default:
2909 next_iwarp_state = 0;
2910 }
2911 spin_unlock_irqrestore(&nesqp->lock, flags);
2912 if (next_iwarp_state) {
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002913 nes_debug(NES_DBG_AEQ, "issuing hw modifyqp for QP%u. next state = 0x%08X,"
2914 " also added another reference\n",
2915 nesqp->hwqp.qp_id, next_iwarp_state);
2916 nes_hw_modify_qp(nesdev, nesqp, next_iwarp_state, 0);
2917 }
2918 nes_cm_disconn(nesqp);
2919 } else {
2920 if (async_event_id == NES_AEQE_AEID_LLP_FIN_RECEIVED) {
2921 /* FIN Received but ib state not RTS,
2922 close complete will be on its way */
2923 spin_unlock_irqrestore(&nesqp->lock, flags);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002924 return;
2925 }
2926 spin_unlock_irqrestore(&nesqp->lock, flags);
2927 if (async_event_id == NES_AEQE_AEID_RDMAP_ROE_BAD_LLP_CLOSE) {
2928 next_iwarp_state = NES_CQP_QP_IWARP_STATE_TERMINATE | 0x02000000;
2929 nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED;
2930 nes_debug(NES_DBG_AEQ, "issuing hw modifyqp for QP%u. next state = 0x%08X,"
2931 " also added another reference\n",
2932 nesqp->hwqp.qp_id, next_iwarp_state);
2933 nes_hw_modify_qp(nesdev, nesqp, next_iwarp_state, 0);
2934 }
2935 nes_cm_disconn(nesqp);
2936 }
2937 break;
2938 case NES_AEQE_AEID_LLP_TERMINATE_RECEIVED:
2939 nesqp = *((struct nes_qp **)&context);
2940 spin_lock_irqsave(&nesqp->lock, flags);
2941 nesqp->hw_iwarp_state = iwarp_state;
2942 nesqp->hw_tcp_state = tcp_state;
2943 nesqp->last_aeq = async_event_id;
2944 spin_unlock_irqrestore(&nesqp->lock, flags);
2945 nes_debug(NES_DBG_AEQ, "Processing an NES_AEQE_AEID_LLP_TERMINATE_RECEIVED"
2946 " event on QP%u \n Q2 Data:\n",
2947 nesqp->hwqp.qp_id);
2948 if (nesqp->ibqp.event_handler) {
2949 ibevent.device = nesqp->ibqp.device;
2950 ibevent.element.qp = &nesqp->ibqp;
2951 ibevent.event = IB_EVENT_QP_FATAL;
2952 nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context);
2953 }
2954 if ((tcp_state == NES_AEQE_TCP_STATE_CLOSE_WAIT) ||
2955 ((nesqp->ibqp_state == IB_QPS_RTS)&&
2956 (async_event_id == NES_AEQE_AEID_LLP_CONNECTION_RESET))) {
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002957 nes_cm_disconn(nesqp);
2958 } else {
2959 nesqp->in_disconnect = 0;
2960 wake_up(&nesqp->kick_waitq);
2961 }
2962 break;
2963 case NES_AEQE_AEID_LLP_TOO_MANY_RETRIES:
2964 nesqp = *((struct nes_qp **)&context);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08002965 spin_lock_irqsave(&nesqp->lock, flags);
2966 nesqp->hw_iwarp_state = NES_AEQE_IWARP_STATE_ERROR;
2967 nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED;
2968 nesqp->last_aeq = async_event_id;
2969 if (nesqp->cm_id) {
2970 nes_debug(NES_DBG_AEQ, "Processing an NES_AEQE_AEID_LLP_TOO_MANY_RETRIES"
2971 " event on QP%u, remote IP = 0x%08X \n",
2972 nesqp->hwqp.qp_id,
2973 ntohl(nesqp->cm_id->remote_addr.sin_addr.s_addr));
2974 } else {
2975 nes_debug(NES_DBG_AEQ, "Processing an NES_AEQE_AEID_LLP_TOO_MANY_RETRIES"
2976 " event on QP%u \n",
2977 nesqp->hwqp.qp_id);
2978 }
2979 spin_unlock_irqrestore(&nesqp->lock, flags);
2980 next_iwarp_state = NES_CQP_QP_IWARP_STATE_ERROR | NES_CQP_QP_RESET;
2981 nes_hw_modify_qp(nesdev, nesqp, next_iwarp_state, 0);
2982 if (nesqp->ibqp.event_handler) {
2983 ibevent.device = nesqp->ibqp.device;
2984 ibevent.element.qp = &nesqp->ibqp;
2985 ibevent.event = IB_EVENT_QP_FATAL;
2986 nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context);
2987 }
2988 break;
2989 case NES_AEQE_AEID_AMP_BAD_STAG_INDEX:
2990 if (NES_AEQE_INBOUND_RDMA&aeq_info) {
2991 nesqp = nesadapter->qp_table[le32_to_cpu(
2992 aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX])-NES_FIRST_QPN];
2993 } else {
2994 /* TODO: get the actual WQE and mask off wqe index */
2995 context &= ~((u64)511);
2996 nesqp = *((struct nes_qp **)&context);
2997 }
2998 spin_lock_irqsave(&nesqp->lock, flags);
2999 nesqp->hw_iwarp_state = iwarp_state;
3000 nesqp->hw_tcp_state = tcp_state;
3001 nesqp->last_aeq = async_event_id;
3002 spin_unlock_irqrestore(&nesqp->lock, flags);
3003 nes_debug(NES_DBG_AEQ, "Processing an NES_AEQE_AEID_AMP_BAD_STAG_INDEX event on QP%u\n",
3004 nesqp->hwqp.qp_id);
3005 if (nesqp->ibqp.event_handler) {
3006 ibevent.device = nesqp->ibqp.device;
3007 ibevent.element.qp = &nesqp->ibqp;
3008 ibevent.event = IB_EVENT_QP_ACCESS_ERR;
3009 nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context);
3010 }
3011 break;
3012 case NES_AEQE_AEID_AMP_UNALLOCATED_STAG:
3013 nesqp = *((struct nes_qp **)&context);
3014 spin_lock_irqsave(&nesqp->lock, flags);
3015 nesqp->hw_iwarp_state = iwarp_state;
3016 nesqp->hw_tcp_state = tcp_state;
3017 nesqp->last_aeq = async_event_id;
3018 spin_unlock_irqrestore(&nesqp->lock, flags);
3019 nes_debug(NES_DBG_AEQ, "Processing an NES_AEQE_AEID_AMP_UNALLOCATED_STAG event on QP%u\n",
3020 nesqp->hwqp.qp_id);
3021 if (nesqp->ibqp.event_handler) {
3022 ibevent.device = nesqp->ibqp.device;
3023 ibevent.element.qp = &nesqp->ibqp;
3024 ibevent.event = IB_EVENT_QP_ACCESS_ERR;
3025 nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context);
3026 }
3027 break;
3028 case NES_AEQE_AEID_PRIV_OPERATION_DENIED:
3029 nesqp = nesadapter->qp_table[le32_to_cpu(aeqe->aeqe_words
3030 [NES_AEQE_COMP_QP_CQ_ID_IDX])-NES_FIRST_QPN];
3031 spin_lock_irqsave(&nesqp->lock, flags);
3032 nesqp->hw_iwarp_state = iwarp_state;
3033 nesqp->hw_tcp_state = tcp_state;
3034 nesqp->last_aeq = async_event_id;
3035 spin_unlock_irqrestore(&nesqp->lock, flags);
3036 nes_debug(NES_DBG_AEQ, "Processing an NES_AEQE_AEID_PRIV_OPERATION_DENIED event on QP%u,"
3037 " nesqp = %p, AE reported %p\n",
3038 nesqp->hwqp.qp_id, nesqp, *((struct nes_qp **)&context));
3039 if (nesqp->ibqp.event_handler) {
3040 ibevent.device = nesqp->ibqp.device;
3041 ibevent.element.qp = &nesqp->ibqp;
3042 ibevent.event = IB_EVENT_QP_ACCESS_ERR;
3043 nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context);
3044 }
3045 break;
3046 case NES_AEQE_AEID_CQ_OPERATION_ERROR:
3047 context <<= 1;
3048 nes_debug(NES_DBG_AEQ, "Processing an NES_AEQE_AEID_CQ_OPERATION_ERROR event on CQ%u, %p\n",
3049 le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX]), (void *)(unsigned long)context);
3050 resource_allocated = nes_is_resource_allocated(nesadapter, nesadapter->allocated_cqs,
3051 le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX]));
3052 if (resource_allocated) {
3053 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 -07003054 __func__, le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX]));
Glenn Streiff3c2d7742008-02-04 20:20:45 -08003055 }
3056 break;
3057 case NES_AEQE_AEID_DDP_UBE_DDP_MESSAGE_TOO_LONG_FOR_AVAILABLE_BUFFER:
3058 nesqp = nesadapter->qp_table[le32_to_cpu(
3059 aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX])-NES_FIRST_QPN];
3060 spin_lock_irqsave(&nesqp->lock, flags);
3061 nesqp->hw_iwarp_state = iwarp_state;
3062 nesqp->hw_tcp_state = tcp_state;
3063 nesqp->last_aeq = async_event_id;
3064 spin_unlock_irqrestore(&nesqp->lock, flags);
3065 nes_debug(NES_DBG_AEQ, "Processing an NES_AEQE_AEID_DDP_UBE_DDP_MESSAGE_TOO_LONG"
3066 "_FOR_AVAILABLE_BUFFER event on QP%u\n",
3067 nesqp->hwqp.qp_id);
3068 if (nesqp->ibqp.event_handler) {
3069 ibevent.device = nesqp->ibqp.device;
3070 ibevent.element.qp = &nesqp->ibqp;
3071 ibevent.event = IB_EVENT_QP_ACCESS_ERR;
3072 nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context);
3073 }
3074 /* tell cm to disconnect, cm will queue work to thread */
Glenn Streiff3c2d7742008-02-04 20:20:45 -08003075 nes_cm_disconn(nesqp);
3076 break;
3077 case NES_AEQE_AEID_DDP_UBE_INVALID_MSN_NO_BUFFER_AVAILABLE:
3078 nesqp = *((struct nes_qp **)&context);
3079 spin_lock_irqsave(&nesqp->lock, flags);
3080 nesqp->hw_iwarp_state = iwarp_state;
3081 nesqp->hw_tcp_state = tcp_state;
3082 nesqp->last_aeq = async_event_id;
3083 spin_unlock_irqrestore(&nesqp->lock, flags);
3084 nes_debug(NES_DBG_AEQ, "Processing an NES_AEQE_AEID_DDP_UBE_INVALID_MSN"
3085 "_NO_BUFFER_AVAILABLE event on QP%u\n",
3086 nesqp->hwqp.qp_id);
3087 if (nesqp->ibqp.event_handler) {
3088 ibevent.device = nesqp->ibqp.device;
3089 ibevent.element.qp = &nesqp->ibqp;
3090 ibevent.event = IB_EVENT_QP_FATAL;
3091 nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context);
3092 }
3093 /* tell cm to disconnect, cm will queue work to thread */
Glenn Streiff3c2d7742008-02-04 20:20:45 -08003094 nes_cm_disconn(nesqp);
3095 break;
3096 case NES_AEQE_AEID_LLP_RECEIVED_MPA_CRC_ERROR:
3097 nesqp = *((struct nes_qp **)&context);
3098 spin_lock_irqsave(&nesqp->lock, flags);
3099 nesqp->hw_iwarp_state = iwarp_state;
3100 nesqp->hw_tcp_state = tcp_state;
3101 nesqp->last_aeq = async_event_id;
3102 spin_unlock_irqrestore(&nesqp->lock, flags);
3103 nes_debug(NES_DBG_AEQ, "Processing an NES_AEQE_AEID_LLP_RECEIVED_MPA_CRC_ERROR"
3104 " event on QP%u \n Q2 Data:\n",
3105 nesqp->hwqp.qp_id);
3106 if (nesqp->ibqp.event_handler) {
3107 ibevent.device = nesqp->ibqp.device;
3108 ibevent.element.qp = &nesqp->ibqp;
3109 ibevent.event = IB_EVENT_QP_FATAL;
3110 nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context);
3111 }
3112 /* tell cm to disconnect, cm will queue work to thread */
Glenn Streiff3c2d7742008-02-04 20:20:45 -08003113 nes_cm_disconn(nesqp);
3114 break;
3115 /* TODO: additional AEs need to be here */
3116 default:
3117 nes_debug(NES_DBG_AEQ, "Processing an iWARP related AE for QP, misc = 0x%04X\n",
3118 async_event_id);
3119 break;
3120 }
3121
3122}
3123
3124
3125/**
3126 * nes_iwarp_ce_handler
3127 */
3128void nes_iwarp_ce_handler(struct nes_device *nesdev, struct nes_hw_cq *hw_cq)
3129{
3130 struct nes_cq *nescq = container_of(hw_cq, struct nes_cq, hw_cq);
3131
3132 /* nes_debug(NES_DBG_CQ, "Processing completion event for iWARP CQ%u.\n",
3133 nescq->hw_cq.cq_number); */
3134 nes_write32(nesdev->regs+NES_CQ_ACK, nescq->hw_cq.cq_number);
3135
3136 if (nescq->ibcq.comp_handler)
3137 nescq->ibcq.comp_handler(&nescq->ibcq, nescq->ibcq.cq_context);
3138
3139 return;
3140}
3141
3142
3143/**
3144 * nes_manage_apbvt()
3145 */
3146int nes_manage_apbvt(struct nes_vnic *nesvnic, u32 accel_local_port,
3147 u32 nic_index, u32 add_port)
3148{
3149 struct nes_device *nesdev = nesvnic->nesdev;
3150 struct nes_hw_cqp_wqe *cqp_wqe;
Glenn Streiff3c2d7742008-02-04 20:20:45 -08003151 struct nes_cqp_request *cqp_request;
3152 int ret = 0;
3153 u16 major_code;
3154
3155 /* Send manage APBVT request to CQP */
3156 cqp_request = nes_get_cqp_request(nesdev);
3157 if (cqp_request == NULL) {
3158 nes_debug(NES_DBG_QP, "Failed to get a cqp_request.\n");
3159 return -ENOMEM;
3160 }
3161 cqp_request->waiting = 1;
3162 cqp_wqe = &cqp_request->cqp_wqe;
3163
3164 nes_debug(NES_DBG_QP, "%s APBV for local port=%u(0x%04x), nic_index=%u\n",
3165 (add_port == NES_MANAGE_APBVT_ADD) ? "ADD" : "DEL",
3166 accel_local_port, accel_local_port, nic_index);
3167
3168 nes_fill_init_cqp_wqe(cqp_wqe, nesdev);
3169 set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_OPCODE_IDX, (NES_CQP_MANAGE_APBVT |
3170 ((add_port == NES_MANAGE_APBVT_ADD) ? NES_CQP_APBVT_ADD : 0)));
3171 set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_ID_IDX,
3172 ((nic_index << NES_CQP_APBVT_NIC_SHIFT) | accel_local_port));
3173
3174 nes_debug(NES_DBG_QP, "Waiting for CQP completion for APBVT.\n");
3175
3176 atomic_set(&cqp_request->refcount, 2);
Roland Dreier8294f292008-07-14 23:48:49 -07003177 nes_post_cqp_request(nesdev, cqp_request);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08003178
3179 if (add_port == NES_MANAGE_APBVT_ADD)
3180 ret = wait_event_timeout(cqp_request->waitq, (cqp_request->request_done != 0),
3181 NES_EVENT_TIMEOUT);
3182 nes_debug(NES_DBG_QP, "Completed, ret=%u, CQP Major:Minor codes = 0x%04X:0x%04X\n",
3183 ret, cqp_request->major_code, cqp_request->minor_code);
3184 major_code = cqp_request->major_code;
Roland Dreier1ff66e82008-07-14 23:48:49 -07003185
3186 nes_put_cqp_request(nesdev, cqp_request);
3187
Glenn Streiff3c2d7742008-02-04 20:20:45 -08003188 if (!ret)
3189 return -ETIME;
3190 else if (major_code)
3191 return -EIO;
3192 else
3193 return 0;
3194}
3195
3196
3197/**
3198 * nes_manage_arp_cache
3199 */
3200void nes_manage_arp_cache(struct net_device *netdev, unsigned char *mac_addr,
3201 u32 ip_addr, u32 action)
3202{
3203 struct nes_hw_cqp_wqe *cqp_wqe;
3204 struct nes_vnic *nesvnic = netdev_priv(netdev);
3205 struct nes_device *nesdev;
3206 struct nes_cqp_request *cqp_request;
3207 int arp_index;
3208
3209 nesdev = nesvnic->nesdev;
3210 arp_index = nes_arp_table(nesdev, ip_addr, mac_addr, action);
3211 if (arp_index == -1) {
3212 return;
3213 }
3214
3215 /* update the ARP entry */
3216 cqp_request = nes_get_cqp_request(nesdev);
3217 if (cqp_request == NULL) {
3218 nes_debug(NES_DBG_NETDEV, "Failed to get a cqp_request.\n");
3219 return;
3220 }
3221 cqp_request->waiting = 0;
3222 cqp_wqe = &cqp_request->cqp_wqe;
3223 nes_fill_init_cqp_wqe(cqp_wqe, nesdev);
3224
3225 cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] = cpu_to_le32(
3226 NES_CQP_MANAGE_ARP_CACHE | NES_CQP_ARP_PERM);
3227 cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] |= cpu_to_le32(
3228 (u32)PCI_FUNC(nesdev->pcidev->devfn) << NES_CQP_ARP_AEQ_INDEX_SHIFT);
3229 cqp_wqe->wqe_words[NES_CQP_WQE_ID_IDX] = cpu_to_le32(arp_index);
3230
3231 if (action == NES_ARP_ADD) {
3232 cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] |= cpu_to_le32(NES_CQP_ARP_VALID);
3233 cqp_wqe->wqe_words[NES_CQP_ARP_WQE_MAC_ADDR_LOW_IDX] = cpu_to_le32(
3234 (((u32)mac_addr[2]) << 24) | (((u32)mac_addr[3]) << 16) |
Glenn Streiff7495ab62008-04-29 13:46:54 -07003235 (((u32)mac_addr[4]) << 8) | (u32)mac_addr[5]);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08003236 cqp_wqe->wqe_words[NES_CQP_ARP_WQE_MAC_HIGH_IDX] = cpu_to_le32(
3237 (((u32)mac_addr[0]) << 16) | (u32)mac_addr[1]);
3238 } else {
3239 cqp_wqe->wqe_words[NES_CQP_ARP_WQE_MAC_ADDR_LOW_IDX] = 0;
3240 cqp_wqe->wqe_words[NES_CQP_ARP_WQE_MAC_HIGH_IDX] = 0;
3241 }
3242
3243 nes_debug(NES_DBG_NETDEV, "Not waiting for CQP, cqp.sq_head=%u, cqp.sq_tail=%u\n",
3244 nesdev->cqp.sq_head, nesdev->cqp.sq_tail);
3245
3246 atomic_set(&cqp_request->refcount, 1);
Roland Dreier8294f292008-07-14 23:48:49 -07003247 nes_post_cqp_request(nesdev, cqp_request);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08003248}
3249
3250
3251/**
3252 * flush_wqes
3253 */
3254void flush_wqes(struct nes_device *nesdev, struct nes_qp *nesqp,
3255 u32 which_wq, u32 wait_completion)
3256{
Glenn Streiff3c2d7742008-02-04 20:20:45 -08003257 struct nes_cqp_request *cqp_request;
3258 struct nes_hw_cqp_wqe *cqp_wqe;
3259 int ret;
3260
3261 cqp_request = nes_get_cqp_request(nesdev);
3262 if (cqp_request == NULL) {
3263 nes_debug(NES_DBG_QP, "Failed to get a cqp_request.\n");
3264 return;
3265 }
3266 if (wait_completion) {
3267 cqp_request->waiting = 1;
3268 atomic_set(&cqp_request->refcount, 2);
3269 } else {
3270 cqp_request->waiting = 0;
3271 }
3272 cqp_wqe = &cqp_request->cqp_wqe;
3273 nes_fill_init_cqp_wqe(cqp_wqe, nesdev);
3274
3275 cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] =
3276 cpu_to_le32(NES_CQP_FLUSH_WQES | which_wq);
3277 cqp_wqe->wqe_words[NES_CQP_WQE_ID_IDX] = cpu_to_le32(nesqp->hwqp.qp_id);
3278
Roland Dreier8294f292008-07-14 23:48:49 -07003279 nes_post_cqp_request(nesdev, cqp_request);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08003280
3281 if (wait_completion) {
3282 /* Wait for CQP */
3283 ret = wait_event_timeout(cqp_request->waitq, (cqp_request->request_done != 0),
3284 NES_EVENT_TIMEOUT);
3285 nes_debug(NES_DBG_QP, "Flush SQ QP WQEs completed, ret=%u,"
3286 " CQP Major:Minor codes = 0x%04X:0x%04X\n",
3287 ret, cqp_request->major_code, cqp_request->minor_code);
Roland Dreier1ff66e82008-07-14 23:48:49 -07003288 nes_put_cqp_request(nesdev, cqp_request);
Glenn Streiff3c2d7742008-02-04 20:20:45 -08003289 }
3290}