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