Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6
[pandora-kernel.git] / drivers / net / netxen / netxen_nic_ctx.c
1 /*
2  * Copyright (C) 2003 - 2009 NetXen, Inc.
3  * Copyright (C) 2009 - QLogic Corporation.
4  * All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
19  * MA  02111-1307, USA.
20  *
21  * The full GNU General Public License is included in this distribution
22  * in the file called "COPYING".
23  *
24  */
25
26 #include "netxen_nic_hw.h"
27 #include "netxen_nic.h"
28
29 #define NXHAL_VERSION   1
30
31 static u32
32 netxen_poll_rsp(struct netxen_adapter *adapter)
33 {
34         u32 rsp = NX_CDRP_RSP_OK;
35         int     timeout = 0;
36
37         do {
38                 /* give atleast 1ms for firmware to respond */
39                 msleep(1);
40
41                 if (++timeout > NX_OS_CRB_RETRY_COUNT)
42                         return NX_CDRP_RSP_TIMEOUT;
43
44                 rsp = NXRD32(adapter, NX_CDRP_CRB_OFFSET);
45         } while (!NX_CDRP_IS_RSP(rsp));
46
47         return rsp;
48 }
49
50 static u32
51 netxen_issue_cmd(struct netxen_adapter *adapter,
52         u32 pci_fn, u32 version, u32 arg1, u32 arg2, u32 arg3, u32 cmd)
53 {
54         u32 rsp;
55         u32 signature = 0;
56         u32 rcode = NX_RCODE_SUCCESS;
57
58         signature = NX_CDRP_SIGNATURE_MAKE(pci_fn, version);
59
60         /* Acquire semaphore before accessing CRB */
61         if (netxen_api_lock(adapter))
62                 return NX_RCODE_TIMEOUT;
63
64         NXWR32(adapter, NX_SIGN_CRB_OFFSET, signature);
65
66         NXWR32(adapter, NX_ARG1_CRB_OFFSET, arg1);
67
68         NXWR32(adapter, NX_ARG2_CRB_OFFSET, arg2);
69
70         NXWR32(adapter, NX_ARG3_CRB_OFFSET, arg3);
71
72         NXWR32(adapter, NX_CDRP_CRB_OFFSET, NX_CDRP_FORM_CMD(cmd));
73
74         rsp = netxen_poll_rsp(adapter);
75
76         if (rsp == NX_CDRP_RSP_TIMEOUT) {
77                 printk(KERN_ERR "%s: card response timeout.\n",
78                                 netxen_nic_driver_name);
79
80                 rcode = NX_RCODE_TIMEOUT;
81         } else if (rsp == NX_CDRP_RSP_FAIL) {
82                 rcode = NXRD32(adapter, NX_ARG1_CRB_OFFSET);
83
84                 printk(KERN_ERR "%s: failed card response code:0x%x\n",
85                                 netxen_nic_driver_name, rcode);
86         }
87
88         /* Release semaphore */
89         netxen_api_unlock(adapter);
90
91         return rcode;
92 }
93
94 int
95 nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu)
96 {
97         u32 rcode = NX_RCODE_SUCCESS;
98         struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
99
100         if (recv_ctx->state == NX_HOST_CTX_STATE_ACTIVE)
101                 rcode = netxen_issue_cmd(adapter,
102                                 adapter->ahw.pci_func,
103                                 NXHAL_VERSION,
104                                 recv_ctx->context_id,
105                                 mtu,
106                                 0,
107                                 NX_CDRP_CMD_SET_MTU);
108
109         if (rcode != NX_RCODE_SUCCESS)
110                 return -EIO;
111
112         return 0;
113 }
114
115 static int
116 nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
117 {
118         void *addr;
119         nx_hostrq_rx_ctx_t *prq;
120         nx_cardrsp_rx_ctx_t *prsp;
121         nx_hostrq_rds_ring_t *prq_rds;
122         nx_hostrq_sds_ring_t *prq_sds;
123         nx_cardrsp_rds_ring_t *prsp_rds;
124         nx_cardrsp_sds_ring_t *prsp_sds;
125         struct nx_host_rds_ring *rds_ring;
126         struct nx_host_sds_ring *sds_ring;
127
128         dma_addr_t hostrq_phys_addr, cardrsp_phys_addr;
129         u64 phys_addr;
130
131         int i, nrds_rings, nsds_rings;
132         size_t rq_size, rsp_size;
133         u32 cap, reg, val;
134
135         int err;
136
137         struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
138
139         nrds_rings = adapter->max_rds_rings;
140         nsds_rings = adapter->max_sds_rings;
141
142         rq_size =
143                 SIZEOF_HOSTRQ_RX(nx_hostrq_rx_ctx_t, nrds_rings, nsds_rings);
144         rsp_size =
145                 SIZEOF_CARDRSP_RX(nx_cardrsp_rx_ctx_t, nrds_rings, nsds_rings);
146
147         addr = pci_alloc_consistent(adapter->pdev,
148                                 rq_size, &hostrq_phys_addr);
149         if (addr == NULL)
150                 return -ENOMEM;
151         prq = (nx_hostrq_rx_ctx_t *)addr;
152
153         addr = pci_alloc_consistent(adapter->pdev,
154                         rsp_size, &cardrsp_phys_addr);
155         if (addr == NULL) {
156                 err = -ENOMEM;
157                 goto out_free_rq;
158         }
159         prsp = (nx_cardrsp_rx_ctx_t *)addr;
160
161         prq->host_rsp_dma_addr = cpu_to_le64(cardrsp_phys_addr);
162
163         cap = (NX_CAP0_LEGACY_CONTEXT | NX_CAP0_LEGACY_MN);
164         cap |= (NX_CAP0_JUMBO_CONTIGUOUS | NX_CAP0_LRO_CONTIGUOUS);
165
166         prq->capabilities[0] = cpu_to_le32(cap);
167         prq->host_int_crb_mode =
168                 cpu_to_le32(NX_HOST_INT_CRB_MODE_SHARED);
169         prq->host_rds_crb_mode =
170                 cpu_to_le32(NX_HOST_RDS_CRB_MODE_UNIQUE);
171
172         prq->num_rds_rings = cpu_to_le16(nrds_rings);
173         prq->num_sds_rings = cpu_to_le16(nsds_rings);
174         prq->rds_ring_offset = cpu_to_le32(0);
175
176         val = le32_to_cpu(prq->rds_ring_offset) +
177                 (sizeof(nx_hostrq_rds_ring_t) * nrds_rings);
178         prq->sds_ring_offset = cpu_to_le32(val);
179
180         prq_rds = (nx_hostrq_rds_ring_t *)(prq->data +
181                         le32_to_cpu(prq->rds_ring_offset));
182
183         for (i = 0; i < nrds_rings; i++) {
184
185                 rds_ring = &recv_ctx->rds_rings[i];
186
187                 prq_rds[i].host_phys_addr = cpu_to_le64(rds_ring->phys_addr);
188                 prq_rds[i].ring_size = cpu_to_le32(rds_ring->num_desc);
189                 prq_rds[i].ring_kind = cpu_to_le32(i);
190                 prq_rds[i].buff_size = cpu_to_le64(rds_ring->dma_size);
191         }
192
193         prq_sds = (nx_hostrq_sds_ring_t *)(prq->data +
194                         le32_to_cpu(prq->sds_ring_offset));
195
196         for (i = 0; i < nsds_rings; i++) {
197
198                 sds_ring = &recv_ctx->sds_rings[i];
199
200                 prq_sds[i].host_phys_addr = cpu_to_le64(sds_ring->phys_addr);
201                 prq_sds[i].ring_size = cpu_to_le32(sds_ring->num_desc);
202                 prq_sds[i].msi_index = cpu_to_le16(i);
203         }
204
205         phys_addr = hostrq_phys_addr;
206         err = netxen_issue_cmd(adapter,
207                         adapter->ahw.pci_func,
208                         NXHAL_VERSION,
209                         (u32)(phys_addr >> 32),
210                         (u32)(phys_addr & 0xffffffff),
211                         rq_size,
212                         NX_CDRP_CMD_CREATE_RX_CTX);
213         if (err) {
214                 printk(KERN_WARNING
215                         "Failed to create rx ctx in firmware%d\n", err);
216                 goto out_free_rsp;
217         }
218
219
220         prsp_rds = ((nx_cardrsp_rds_ring_t *)
221                          &prsp->data[le32_to_cpu(prsp->rds_ring_offset)]);
222
223         for (i = 0; i < le16_to_cpu(prsp->num_rds_rings); i++) {
224                 rds_ring = &recv_ctx->rds_rings[i];
225
226                 reg = le32_to_cpu(prsp_rds[i].host_producer_crb);
227                 rds_ring->crb_rcv_producer = netxen_get_ioaddr(adapter,
228                                 NETXEN_NIC_REG(reg - 0x200));
229         }
230
231         prsp_sds = ((nx_cardrsp_sds_ring_t *)
232                         &prsp->data[le32_to_cpu(prsp->sds_ring_offset)]);
233
234         for (i = 0; i < le16_to_cpu(prsp->num_sds_rings); i++) {
235                 sds_ring = &recv_ctx->sds_rings[i];
236
237                 reg = le32_to_cpu(prsp_sds[i].host_consumer_crb);
238                 sds_ring->crb_sts_consumer = netxen_get_ioaddr(adapter,
239                                 NETXEN_NIC_REG(reg - 0x200));
240
241                 reg = le32_to_cpu(prsp_sds[i].interrupt_crb);
242                 sds_ring->crb_intr_mask = netxen_get_ioaddr(adapter,
243                                 NETXEN_NIC_REG(reg - 0x200));
244         }
245
246         recv_ctx->state = le32_to_cpu(prsp->host_ctx_state);
247         recv_ctx->context_id = le16_to_cpu(prsp->context_id);
248         recv_ctx->virt_port = prsp->virt_port;
249
250 out_free_rsp:
251         pci_free_consistent(adapter->pdev, rsp_size, prsp, cardrsp_phys_addr);
252 out_free_rq:
253         pci_free_consistent(adapter->pdev, rq_size, prq, hostrq_phys_addr);
254         return err;
255 }
256
257 static void
258 nx_fw_cmd_reset_ctx(struct netxen_adapter *adapter)
259 {
260
261         netxen_issue_cmd(adapter, adapter->ahw.pci_func, NXHAL_VERSION,
262                         adapter->ahw.pci_func, NX_DESTROY_CTX_RESET, 0,
263                         NX_CDRP_CMD_DESTROY_RX_CTX);
264
265         netxen_issue_cmd(adapter, adapter->ahw.pci_func, NXHAL_VERSION,
266                         adapter->ahw.pci_func, NX_DESTROY_CTX_RESET, 0,
267                         NX_CDRP_CMD_DESTROY_TX_CTX);
268 }
269
270 static void
271 nx_fw_cmd_destroy_rx_ctx(struct netxen_adapter *adapter)
272 {
273         struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
274
275         if (netxen_issue_cmd(adapter,
276                         adapter->ahw.pci_func,
277                         NXHAL_VERSION,
278                         recv_ctx->context_id,
279                         NX_DESTROY_CTX_RESET,
280                         0,
281                         NX_CDRP_CMD_DESTROY_RX_CTX)) {
282
283                 printk(KERN_WARNING
284                         "%s: Failed to destroy rx ctx in firmware\n",
285                         netxen_nic_driver_name);
286         }
287 }
288
289 static int
290 nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter)
291 {
292         nx_hostrq_tx_ctx_t      *prq;
293         nx_hostrq_cds_ring_t    *prq_cds;
294         nx_cardrsp_tx_ctx_t     *prsp;
295         void    *rq_addr, *rsp_addr;
296         size_t  rq_size, rsp_size;
297         u32     temp;
298         int     err = 0;
299         u64     offset, phys_addr;
300         dma_addr_t      rq_phys_addr, rsp_phys_addr;
301         struct nx_host_tx_ring *tx_ring = adapter->tx_ring;
302         struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
303
304         rq_size = SIZEOF_HOSTRQ_TX(nx_hostrq_tx_ctx_t);
305         rq_addr = pci_alloc_consistent(adapter->pdev,
306                 rq_size, &rq_phys_addr);
307         if (!rq_addr)
308                 return -ENOMEM;
309
310         rsp_size = SIZEOF_CARDRSP_TX(nx_cardrsp_tx_ctx_t);
311         rsp_addr = pci_alloc_consistent(adapter->pdev,
312                 rsp_size, &rsp_phys_addr);
313         if (!rsp_addr) {
314                 err = -ENOMEM;
315                 goto out_free_rq;
316         }
317
318         memset(rq_addr, 0, rq_size);
319         prq = (nx_hostrq_tx_ctx_t *)rq_addr;
320
321         memset(rsp_addr, 0, rsp_size);
322         prsp = (nx_cardrsp_tx_ctx_t *)rsp_addr;
323
324         prq->host_rsp_dma_addr = cpu_to_le64(rsp_phys_addr);
325
326         temp = (NX_CAP0_LEGACY_CONTEXT | NX_CAP0_LEGACY_MN | NX_CAP0_LSO);
327         prq->capabilities[0] = cpu_to_le32(temp);
328
329         prq->host_int_crb_mode =
330                 cpu_to_le32(NX_HOST_INT_CRB_MODE_SHARED);
331
332         prq->interrupt_ctl = 0;
333         prq->msi_index = 0;
334
335         prq->dummy_dma_addr = cpu_to_le64(adapter->dummy_dma.phys_addr);
336
337         offset = recv_ctx->phys_addr + sizeof(struct netxen_ring_ctx);
338         prq->cmd_cons_dma_addr = cpu_to_le64(offset);
339
340         prq_cds = &prq->cds_ring;
341
342         prq_cds->host_phys_addr = cpu_to_le64(tx_ring->phys_addr);
343         prq_cds->ring_size = cpu_to_le32(tx_ring->num_desc);
344
345         phys_addr = rq_phys_addr;
346         err = netxen_issue_cmd(adapter,
347                         adapter->ahw.pci_func,
348                         NXHAL_VERSION,
349                         (u32)(phys_addr >> 32),
350                         ((u32)phys_addr & 0xffffffff),
351                         rq_size,
352                         NX_CDRP_CMD_CREATE_TX_CTX);
353
354         if (err == NX_RCODE_SUCCESS) {
355                 temp = le32_to_cpu(prsp->cds_ring.host_producer_crb);
356                 tx_ring->crb_cmd_producer = netxen_get_ioaddr(adapter,
357                                 NETXEN_NIC_REG(temp - 0x200));
358 #if 0
359                 adapter->tx_state =
360                         le32_to_cpu(prsp->host_ctx_state);
361 #endif
362                 adapter->tx_context_id =
363                         le16_to_cpu(prsp->context_id);
364         } else {
365                 printk(KERN_WARNING
366                         "Failed to create tx ctx in firmware%d\n", err);
367                 err = -EIO;
368         }
369
370         pci_free_consistent(adapter->pdev, rsp_size, rsp_addr, rsp_phys_addr);
371
372 out_free_rq:
373         pci_free_consistent(adapter->pdev, rq_size, rq_addr, rq_phys_addr);
374
375         return err;
376 }
377
378 static void
379 nx_fw_cmd_destroy_tx_ctx(struct netxen_adapter *adapter)
380 {
381         if (netxen_issue_cmd(adapter,
382                         adapter->ahw.pci_func,
383                         NXHAL_VERSION,
384                         adapter->tx_context_id,
385                         NX_DESTROY_CTX_RESET,
386                         0,
387                         NX_CDRP_CMD_DESTROY_TX_CTX)) {
388
389                 printk(KERN_WARNING
390                         "%s: Failed to destroy tx ctx in firmware\n",
391                         netxen_nic_driver_name);
392         }
393 }
394
395 int
396 nx_fw_cmd_query_phy(struct netxen_adapter *adapter, u32 reg, u32 *val)
397 {
398         u32 rcode;
399
400         rcode = netxen_issue_cmd(adapter,
401                         adapter->ahw.pci_func,
402                         NXHAL_VERSION,
403                         reg,
404                         0,
405                         0,
406                         NX_CDRP_CMD_READ_PHY);
407
408         if (rcode != NX_RCODE_SUCCESS)
409                 return -EIO;
410
411         return NXRD32(adapter, NX_ARG1_CRB_OFFSET);
412 }
413
414 int
415 nx_fw_cmd_set_phy(struct netxen_adapter *adapter, u32 reg, u32 val)
416 {
417         u32 rcode;
418
419         rcode = netxen_issue_cmd(adapter,
420                         adapter->ahw.pci_func,
421                         NXHAL_VERSION,
422                         reg,
423                         val,
424                         0,
425                         NX_CDRP_CMD_WRITE_PHY);
426
427         if (rcode != NX_RCODE_SUCCESS)
428                 return -EIO;
429
430         return 0;
431 }
432
433 static u64 ctx_addr_sig_regs[][3] = {
434         {NETXEN_NIC_REG(0x188), NETXEN_NIC_REG(0x18c), NETXEN_NIC_REG(0x1c0)},
435         {NETXEN_NIC_REG(0x190), NETXEN_NIC_REG(0x194), NETXEN_NIC_REG(0x1c4)},
436         {NETXEN_NIC_REG(0x198), NETXEN_NIC_REG(0x19c), NETXEN_NIC_REG(0x1c8)},
437         {NETXEN_NIC_REG(0x1a0), NETXEN_NIC_REG(0x1a4), NETXEN_NIC_REG(0x1cc)}
438 };
439
440 #define CRB_CTX_ADDR_REG_LO(FUNC_ID)    (ctx_addr_sig_regs[FUNC_ID][0])
441 #define CRB_CTX_ADDR_REG_HI(FUNC_ID)    (ctx_addr_sig_regs[FUNC_ID][2])
442 #define CRB_CTX_SIGNATURE_REG(FUNC_ID)  (ctx_addr_sig_regs[FUNC_ID][1])
443
444 #define lower32(x)      ((u32)((x) & 0xffffffff))
445 #define upper32(x)      ((u32)(((u64)(x) >> 32) & 0xffffffff))
446
447 static struct netxen_recv_crb recv_crb_registers[] = {
448         /* Instance 0 */
449         {
450                 /* crb_rcv_producer: */
451                 {
452                         NETXEN_NIC_REG(0x100),
453                         /* Jumbo frames */
454                         NETXEN_NIC_REG(0x110),
455                         /* LRO */
456                         NETXEN_NIC_REG(0x120)
457                 },
458                 /* crb_sts_consumer: */
459                 {
460                         NETXEN_NIC_REG(0x138),
461                         NETXEN_NIC_REG_2(0x000),
462                         NETXEN_NIC_REG_2(0x004),
463                         NETXEN_NIC_REG_2(0x008),
464                 },
465                 /* sw_int_mask */
466                 {
467                         CRB_SW_INT_MASK_0,
468                         NETXEN_NIC_REG_2(0x044),
469                         NETXEN_NIC_REG_2(0x048),
470                         NETXEN_NIC_REG_2(0x04c),
471                 },
472         },
473         /* Instance 1 */
474         {
475                 /* crb_rcv_producer: */
476                 {
477                         NETXEN_NIC_REG(0x144),
478                         /* Jumbo frames */
479                         NETXEN_NIC_REG(0x154),
480                         /* LRO */
481                         NETXEN_NIC_REG(0x164)
482                 },
483                 /* crb_sts_consumer: */
484                 {
485                         NETXEN_NIC_REG(0x17c),
486                         NETXEN_NIC_REG_2(0x020),
487                         NETXEN_NIC_REG_2(0x024),
488                         NETXEN_NIC_REG_2(0x028),
489                 },
490                 /* sw_int_mask */
491                 {
492                         CRB_SW_INT_MASK_1,
493                         NETXEN_NIC_REG_2(0x064),
494                         NETXEN_NIC_REG_2(0x068),
495                         NETXEN_NIC_REG_2(0x06c),
496                 },
497         },
498         /* Instance 2 */
499         {
500                 /* crb_rcv_producer: */
501                 {
502                         NETXEN_NIC_REG(0x1d8),
503                         /* Jumbo frames */
504                         NETXEN_NIC_REG(0x1f8),
505                         /* LRO */
506                         NETXEN_NIC_REG(0x208)
507                 },
508                 /* crb_sts_consumer: */
509                 {
510                         NETXEN_NIC_REG(0x220),
511                         NETXEN_NIC_REG_2(0x03c),
512                         NETXEN_NIC_REG_2(0x03c),
513                         NETXEN_NIC_REG_2(0x03c),
514                 },
515                 /* sw_int_mask */
516                 {
517                         CRB_SW_INT_MASK_2,
518                         NETXEN_NIC_REG_2(0x03c),
519                         NETXEN_NIC_REG_2(0x03c),
520                         NETXEN_NIC_REG_2(0x03c),
521                 },
522         },
523         /* Instance 3 */
524         {
525                 /* crb_rcv_producer: */
526                 {
527                         NETXEN_NIC_REG(0x22c),
528                         /* Jumbo frames */
529                         NETXEN_NIC_REG(0x23c),
530                         /* LRO */
531                         NETXEN_NIC_REG(0x24c)
532                 },
533                 /* crb_sts_consumer: */
534                 {
535                         NETXEN_NIC_REG(0x264),
536                         NETXEN_NIC_REG_2(0x03c),
537                         NETXEN_NIC_REG_2(0x03c),
538                         NETXEN_NIC_REG_2(0x03c),
539                 },
540                 /* sw_int_mask */
541                 {
542                         CRB_SW_INT_MASK_3,
543                         NETXEN_NIC_REG_2(0x03c),
544                         NETXEN_NIC_REG_2(0x03c),
545                         NETXEN_NIC_REG_2(0x03c),
546                 },
547         },
548 };
549
550 static int
551 netxen_init_old_ctx(struct netxen_adapter *adapter)
552 {
553         struct netxen_recv_context *recv_ctx;
554         struct nx_host_rds_ring *rds_ring;
555         struct nx_host_sds_ring *sds_ring;
556         struct nx_host_tx_ring *tx_ring;
557         int ring;
558         int port = adapter->portnum;
559         struct netxen_ring_ctx *hwctx;
560         u32 signature;
561
562         tx_ring = adapter->tx_ring;
563         recv_ctx = &adapter->recv_ctx;
564         hwctx = recv_ctx->hwctx;
565
566         hwctx->cmd_ring_addr = cpu_to_le64(tx_ring->phys_addr);
567         hwctx->cmd_ring_size = cpu_to_le32(tx_ring->num_desc);
568
569
570         for (ring = 0; ring < adapter->max_rds_rings; ring++) {
571                 rds_ring = &recv_ctx->rds_rings[ring];
572
573                 hwctx->rcv_rings[ring].addr =
574                         cpu_to_le64(rds_ring->phys_addr);
575                 hwctx->rcv_rings[ring].size =
576                         cpu_to_le32(rds_ring->num_desc);
577         }
578
579         for (ring = 0; ring < adapter->max_sds_rings; ring++) {
580                 sds_ring = &recv_ctx->sds_rings[ring];
581
582                 if (ring == 0) {
583                         hwctx->sts_ring_addr = cpu_to_le64(sds_ring->phys_addr);
584                         hwctx->sts_ring_size = cpu_to_le32(sds_ring->num_desc);
585                 }
586                 hwctx->sts_rings[ring].addr = cpu_to_le64(sds_ring->phys_addr);
587                 hwctx->sts_rings[ring].size = cpu_to_le32(sds_ring->num_desc);
588                 hwctx->sts_rings[ring].msi_index = cpu_to_le16(ring);
589         }
590         hwctx->sts_ring_count = cpu_to_le32(adapter->max_sds_rings);
591
592         signature = (adapter->max_sds_rings > 1) ?
593                 NETXEN_CTX_SIGNATURE_V2 : NETXEN_CTX_SIGNATURE;
594
595         NXWR32(adapter, CRB_CTX_ADDR_REG_LO(port),
596                         lower32(recv_ctx->phys_addr));
597         NXWR32(adapter, CRB_CTX_ADDR_REG_HI(port),
598                         upper32(recv_ctx->phys_addr));
599         NXWR32(adapter, CRB_CTX_SIGNATURE_REG(port),
600                         signature | port);
601         return 0;
602 }
603
604 int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
605 {
606         void *addr;
607         int err = 0;
608         int ring;
609         struct netxen_recv_context *recv_ctx;
610         struct nx_host_rds_ring *rds_ring;
611         struct nx_host_sds_ring *sds_ring;
612         struct nx_host_tx_ring *tx_ring;
613
614         struct pci_dev *pdev = adapter->pdev;
615         struct net_device *netdev = adapter->netdev;
616         int port = adapter->portnum;
617
618         recv_ctx = &adapter->recv_ctx;
619         tx_ring = adapter->tx_ring;
620
621         addr = pci_alloc_consistent(pdev,
622                         sizeof(struct netxen_ring_ctx) + sizeof(uint32_t),
623                         &recv_ctx->phys_addr);
624         if (addr == NULL) {
625                 dev_err(&pdev->dev, "failed to allocate hw context\n");
626                 return -ENOMEM;
627         }
628
629         memset(addr, 0, sizeof(struct netxen_ring_ctx));
630         recv_ctx->hwctx = (struct netxen_ring_ctx *)addr;
631         recv_ctx->hwctx->ctx_id = cpu_to_le32(port);
632         recv_ctx->hwctx->cmd_consumer_offset =
633                 cpu_to_le64(recv_ctx->phys_addr +
634                         sizeof(struct netxen_ring_ctx));
635         tx_ring->hw_consumer =
636                 (__le32 *)(((char *)addr) + sizeof(struct netxen_ring_ctx));
637
638         /* cmd desc ring */
639         addr = pci_alloc_consistent(pdev, TX_DESC_RINGSIZE(tx_ring),
640                         &tx_ring->phys_addr);
641
642         if (addr == NULL) {
643                 dev_err(&pdev->dev, "%s: failed to allocate tx desc ring\n",
644                                 netdev->name);
645                 err = -ENOMEM;
646                 goto err_out_free;
647         }
648
649         tx_ring->desc_head = (struct cmd_desc_type0 *)addr;
650
651         for (ring = 0; ring < adapter->max_rds_rings; ring++) {
652                 rds_ring = &recv_ctx->rds_rings[ring];
653                 addr = pci_alloc_consistent(adapter->pdev,
654                                 RCV_DESC_RINGSIZE(rds_ring),
655                                 &rds_ring->phys_addr);
656                 if (addr == NULL) {
657                         dev_err(&pdev->dev,
658                                 "%s: failed to allocate rds ring [%d]\n",
659                                 netdev->name, ring);
660                         err = -ENOMEM;
661                         goto err_out_free;
662                 }
663                 rds_ring->desc_head = (struct rcv_desc *)addr;
664
665                 if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
666                         rds_ring->crb_rcv_producer =
667                                 netxen_get_ioaddr(adapter,
668                         recv_crb_registers[port].crb_rcv_producer[ring]);
669         }
670
671         for (ring = 0; ring < adapter->max_sds_rings; ring++) {
672                 sds_ring = &recv_ctx->sds_rings[ring];
673
674                 addr = pci_alloc_consistent(adapter->pdev,
675                                 STATUS_DESC_RINGSIZE(sds_ring),
676                                 &sds_ring->phys_addr);
677                 if (addr == NULL) {
678                         dev_err(&pdev->dev,
679                                 "%s: failed to allocate sds ring [%d]\n",
680                                 netdev->name, ring);
681                         err = -ENOMEM;
682                         goto err_out_free;
683                 }
684                 sds_ring->desc_head = (struct status_desc *)addr;
685
686                 if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
687                         sds_ring->crb_sts_consumer =
688                                 netxen_get_ioaddr(adapter,
689                                 recv_crb_registers[port].crb_sts_consumer[ring]);
690
691                         sds_ring->crb_intr_mask =
692                                 netxen_get_ioaddr(adapter,
693                                 recv_crb_registers[port].sw_int_mask[ring]);
694                 }
695         }
696
697
698         if (!NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
699                 if (test_and_set_bit(__NX_FW_ATTACHED, &adapter->state))
700                         goto done;
701                 if (reset_devices)
702                         nx_fw_cmd_reset_ctx(adapter);
703                 err = nx_fw_cmd_create_rx_ctx(adapter);
704                 if (err)
705                         goto err_out_free;
706                 err = nx_fw_cmd_create_tx_ctx(adapter);
707                 if (err)
708                         goto err_out_free;
709         } else {
710                 err = netxen_init_old_ctx(adapter);
711                 if (err)
712                         goto err_out_free;
713         }
714
715 done:
716         return 0;
717
718 err_out_free:
719         netxen_free_hw_resources(adapter);
720         return err;
721 }
722
723 void netxen_free_hw_resources(struct netxen_adapter *adapter)
724 {
725         struct netxen_recv_context *recv_ctx;
726         struct nx_host_rds_ring *rds_ring;
727         struct nx_host_sds_ring *sds_ring;
728         struct nx_host_tx_ring *tx_ring;
729         int ring;
730
731         int port = adapter->portnum;
732
733         if (!NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
734                 if (!test_and_clear_bit(__NX_FW_ATTACHED, &adapter->state))
735                         goto done;
736
737                 nx_fw_cmd_destroy_rx_ctx(adapter);
738                 nx_fw_cmd_destroy_tx_ctx(adapter);
739         } else {
740                 netxen_api_lock(adapter);
741                 NXWR32(adapter, CRB_CTX_SIGNATURE_REG(port),
742                                 NETXEN_CTX_D3_RESET | port);
743                 netxen_api_unlock(adapter);
744         }
745
746         /* Allow dma queues to drain after context reset */
747         msleep(20);
748
749 done:
750         recv_ctx = &adapter->recv_ctx;
751
752         if (recv_ctx->hwctx != NULL) {
753                 pci_free_consistent(adapter->pdev,
754                                 sizeof(struct netxen_ring_ctx) +
755                                 sizeof(uint32_t),
756                                 recv_ctx->hwctx,
757                                 recv_ctx->phys_addr);
758                 recv_ctx->hwctx = NULL;
759         }
760
761         tx_ring = adapter->tx_ring;
762         if (tx_ring->desc_head != NULL) {
763                 pci_free_consistent(adapter->pdev,
764                                 TX_DESC_RINGSIZE(tx_ring),
765                                 tx_ring->desc_head, tx_ring->phys_addr);
766                 tx_ring->desc_head = NULL;
767         }
768
769         for (ring = 0; ring < adapter->max_rds_rings; ring++) {
770                 rds_ring = &recv_ctx->rds_rings[ring];
771
772                 if (rds_ring->desc_head != NULL) {
773                         pci_free_consistent(adapter->pdev,
774                                         RCV_DESC_RINGSIZE(rds_ring),
775                                         rds_ring->desc_head,
776                                         rds_ring->phys_addr);
777                         rds_ring->desc_head = NULL;
778                 }
779         }
780
781         for (ring = 0; ring < adapter->max_sds_rings; ring++) {
782                 sds_ring = &recv_ctx->sds_rings[ring];
783
784                 if (sds_ring->desc_head != NULL) {
785                         pci_free_consistent(adapter->pdev,
786                                 STATUS_DESC_RINGSIZE(sds_ring),
787                                 sds_ring->desc_head,
788                                 sds_ring->phys_addr);
789                         sds_ring->desc_head = NULL;
790                 }
791         }
792 }
793