]> bbs.cooldavid.org Git - net-next-2.6.git/blob - drivers/net/qlcnic/qlcnic_ctx.c
qlcnic: fix memory leaks
[net-next-2.6.git] / drivers / net / qlcnic / qlcnic_ctx.c
1 /*
2  * Copyright (C) 2009 - QLogic Corporation.
3  * All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18  * MA  02111-1307, USA.
19  *
20  * The full GNU General Public License is included in this distribution
21  * in the file called "COPYING".
22  *
23  */
24
25 #include "qlcnic.h"
26
27 static u32
28 qlcnic_poll_rsp(struct qlcnic_adapter *adapter)
29 {
30         u32 rsp;
31         int timeout = 0;
32
33         do {
34                 /* give atleast 1ms for firmware to respond */
35                 msleep(1);
36
37                 if (++timeout > QLCNIC_OS_CRB_RETRY_COUNT)
38                         return QLCNIC_CDRP_RSP_TIMEOUT;
39
40                 rsp = QLCRD32(adapter, QLCNIC_CDRP_CRB_OFFSET);
41         } while (!QLCNIC_CDRP_IS_RSP(rsp));
42
43         return rsp;
44 }
45
46 u32
47 qlcnic_issue_cmd(struct qlcnic_adapter *adapter,
48         u32 pci_fn, u32 version, u32 arg1, u32 arg2, u32 arg3, u32 cmd)
49 {
50         u32 rsp;
51         u32 signature;
52         u32 rcode = QLCNIC_RCODE_SUCCESS;
53         struct pci_dev *pdev = adapter->pdev;
54
55         signature = QLCNIC_CDRP_SIGNATURE_MAKE(pci_fn, version);
56
57         /* Acquire semaphore before accessing CRB */
58         if (qlcnic_api_lock(adapter))
59                 return QLCNIC_RCODE_TIMEOUT;
60
61         QLCWR32(adapter, QLCNIC_SIGN_CRB_OFFSET, signature);
62         QLCWR32(adapter, QLCNIC_ARG1_CRB_OFFSET, arg1);
63         QLCWR32(adapter, QLCNIC_ARG2_CRB_OFFSET, arg2);
64         QLCWR32(adapter, QLCNIC_ARG3_CRB_OFFSET, arg3);
65         QLCWR32(adapter, QLCNIC_CDRP_CRB_OFFSET, QLCNIC_CDRP_FORM_CMD(cmd));
66
67         rsp = qlcnic_poll_rsp(adapter);
68
69         if (rsp == QLCNIC_CDRP_RSP_TIMEOUT) {
70                 dev_err(&pdev->dev, "card response timeout.\n");
71                 rcode = QLCNIC_RCODE_TIMEOUT;
72         } else if (rsp == QLCNIC_CDRP_RSP_FAIL) {
73                 rcode = QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET);
74                 dev_err(&pdev->dev, "failed card response code:0x%x\n",
75                                 rcode);
76         }
77
78         /* Release semaphore */
79         qlcnic_api_unlock(adapter);
80
81         return rcode;
82 }
83
84 int
85 qlcnic_fw_cmd_set_mtu(struct qlcnic_adapter *adapter, int mtu)
86 {
87         struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
88
89         if (recv_ctx->state == QLCNIC_HOST_CTX_STATE_ACTIVE) {
90                 if (qlcnic_issue_cmd(adapter,
91                                 adapter->ahw.pci_func,
92                                 QLCHAL_VERSION,
93                                 recv_ctx->context_id,
94                                 mtu,
95                                 0,
96                                 QLCNIC_CDRP_CMD_SET_MTU)) {
97
98                         dev_err(&adapter->pdev->dev, "Failed to set mtu\n");
99                         return -EIO;
100                 }
101         }
102
103         return 0;
104 }
105
106 static int
107 qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter)
108 {
109         void *addr;
110         struct qlcnic_hostrq_rx_ctx *prq;
111         struct qlcnic_cardrsp_rx_ctx *prsp;
112         struct qlcnic_hostrq_rds_ring *prq_rds;
113         struct qlcnic_hostrq_sds_ring *prq_sds;
114         struct qlcnic_cardrsp_rds_ring *prsp_rds;
115         struct qlcnic_cardrsp_sds_ring *prsp_sds;
116         struct qlcnic_host_rds_ring *rds_ring;
117         struct qlcnic_host_sds_ring *sds_ring;
118
119         dma_addr_t hostrq_phys_addr, cardrsp_phys_addr;
120         u64 phys_addr;
121
122         int i, nrds_rings, nsds_rings;
123         size_t rq_size, rsp_size;
124         u32 cap, reg, val;
125         int err;
126
127         struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
128
129         nrds_rings = adapter->max_rds_rings;
130         nsds_rings = adapter->max_sds_rings;
131
132         rq_size =
133                 SIZEOF_HOSTRQ_RX(struct qlcnic_hostrq_rx_ctx, nrds_rings,
134                                                 nsds_rings);
135         rsp_size =
136                 SIZEOF_CARDRSP_RX(struct qlcnic_cardrsp_rx_ctx, nrds_rings,
137                                                 nsds_rings);
138
139         addr = pci_alloc_consistent(adapter->pdev,
140                                 rq_size, &hostrq_phys_addr);
141         if (addr == NULL)
142                 return -ENOMEM;
143         prq = (struct qlcnic_hostrq_rx_ctx *)addr;
144
145         addr = pci_alloc_consistent(adapter->pdev,
146                         rsp_size, &cardrsp_phys_addr);
147         if (addr == NULL) {
148                 err = -ENOMEM;
149                 goto out_free_rq;
150         }
151         prsp = (struct qlcnic_cardrsp_rx_ctx *)addr;
152
153         prq->host_rsp_dma_addr = cpu_to_le64(cardrsp_phys_addr);
154
155         cap = (QLCNIC_CAP0_LEGACY_CONTEXT | QLCNIC_CAP0_LEGACY_MN);
156         cap |= (QLCNIC_CAP0_JUMBO_CONTIGUOUS | QLCNIC_CAP0_LRO_CONTIGUOUS);
157
158         prq->capabilities[0] = cpu_to_le32(cap);
159         prq->host_int_crb_mode =
160                 cpu_to_le32(QLCNIC_HOST_INT_CRB_MODE_SHARED);
161         prq->host_rds_crb_mode =
162                 cpu_to_le32(QLCNIC_HOST_RDS_CRB_MODE_UNIQUE);
163
164         prq->num_rds_rings = cpu_to_le16(nrds_rings);
165         prq->num_sds_rings = cpu_to_le16(nsds_rings);
166         prq->rds_ring_offset = cpu_to_le32(0);
167
168         val = le32_to_cpu(prq->rds_ring_offset) +
169                 (sizeof(struct qlcnic_hostrq_rds_ring) * nrds_rings);
170         prq->sds_ring_offset = cpu_to_le32(val);
171
172         prq_rds = (struct qlcnic_hostrq_rds_ring *)(prq->data +
173                         le32_to_cpu(prq->rds_ring_offset));
174
175         for (i = 0; i < nrds_rings; i++) {
176
177                 rds_ring = &recv_ctx->rds_rings[i];
178
179                 prq_rds[i].host_phys_addr = cpu_to_le64(rds_ring->phys_addr);
180                 prq_rds[i].ring_size = cpu_to_le32(rds_ring->num_desc);
181                 prq_rds[i].ring_kind = cpu_to_le32(i);
182                 prq_rds[i].buff_size = cpu_to_le64(rds_ring->dma_size);
183         }
184
185         prq_sds = (struct qlcnic_hostrq_sds_ring *)(prq->data +
186                         le32_to_cpu(prq->sds_ring_offset));
187
188         for (i = 0; i < nsds_rings; i++) {
189
190                 sds_ring = &recv_ctx->sds_rings[i];
191
192                 prq_sds[i].host_phys_addr = cpu_to_le64(sds_ring->phys_addr);
193                 prq_sds[i].ring_size = cpu_to_le32(sds_ring->num_desc);
194                 prq_sds[i].msi_index = cpu_to_le16(i);
195         }
196
197         phys_addr = hostrq_phys_addr;
198         err = qlcnic_issue_cmd(adapter,
199                         adapter->ahw.pci_func,
200                         QLCHAL_VERSION,
201                         (u32)(phys_addr >> 32),
202                         (u32)(phys_addr & 0xffffffff),
203                         rq_size,
204                         QLCNIC_CDRP_CMD_CREATE_RX_CTX);
205         if (err) {
206                 dev_err(&adapter->pdev->dev,
207                         "Failed to create rx ctx in firmware%d\n", err);
208                 goto out_free_rsp;
209         }
210
211
212         prsp_rds = ((struct qlcnic_cardrsp_rds_ring *)
213                          &prsp->data[le32_to_cpu(prsp->rds_ring_offset)]);
214
215         for (i = 0; i < le16_to_cpu(prsp->num_rds_rings); i++) {
216                 rds_ring = &recv_ctx->rds_rings[i];
217
218                 reg = le32_to_cpu(prsp_rds[i].host_producer_crb);
219                 rds_ring->crb_rcv_producer = qlcnic_get_ioaddr(adapter,
220                                 QLCNIC_REG(reg - 0x200));
221         }
222
223         prsp_sds = ((struct qlcnic_cardrsp_sds_ring *)
224                         &prsp->data[le32_to_cpu(prsp->sds_ring_offset)]);
225
226         for (i = 0; i < le16_to_cpu(prsp->num_sds_rings); i++) {
227                 sds_ring = &recv_ctx->sds_rings[i];
228
229                 reg = le32_to_cpu(prsp_sds[i].host_consumer_crb);
230                 sds_ring->crb_sts_consumer = qlcnic_get_ioaddr(adapter,
231                                 QLCNIC_REG(reg - 0x200));
232
233                 reg = le32_to_cpu(prsp_sds[i].interrupt_crb);
234                 sds_ring->crb_intr_mask = qlcnic_get_ioaddr(adapter,
235                                 QLCNIC_REG(reg - 0x200));
236         }
237
238         recv_ctx->state = le32_to_cpu(prsp->host_ctx_state);
239         recv_ctx->context_id = le16_to_cpu(prsp->context_id);
240         recv_ctx->virt_port = prsp->virt_port;
241
242 out_free_rsp:
243         pci_free_consistent(adapter->pdev, rsp_size, prsp, cardrsp_phys_addr);
244 out_free_rq:
245         pci_free_consistent(adapter->pdev, rq_size, prq, hostrq_phys_addr);
246         return err;
247 }
248
249 static void
250 qlcnic_fw_cmd_destroy_rx_ctx(struct qlcnic_adapter *adapter)
251 {
252         struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
253
254         if (qlcnic_issue_cmd(adapter,
255                         adapter->ahw.pci_func,
256                         QLCHAL_VERSION,
257                         recv_ctx->context_id,
258                         QLCNIC_DESTROY_CTX_RESET,
259                         0,
260                         QLCNIC_CDRP_CMD_DESTROY_RX_CTX)) {
261
262                 dev_err(&adapter->pdev->dev,
263                         "Failed to destroy rx ctx in firmware\n");
264         }
265 }
266
267 static int
268 qlcnic_fw_cmd_create_tx_ctx(struct qlcnic_adapter *adapter)
269 {
270         struct qlcnic_hostrq_tx_ctx     *prq;
271         struct qlcnic_hostrq_cds_ring   *prq_cds;
272         struct qlcnic_cardrsp_tx_ctx    *prsp;
273         void    *rq_addr, *rsp_addr;
274         size_t  rq_size, rsp_size;
275         u32     temp;
276         int     err;
277         u64     phys_addr;
278         dma_addr_t      rq_phys_addr, rsp_phys_addr;
279         struct qlcnic_host_tx_ring *tx_ring = adapter->tx_ring;
280
281         rq_size = SIZEOF_HOSTRQ_TX(struct qlcnic_hostrq_tx_ctx);
282         rq_addr = pci_alloc_consistent(adapter->pdev,
283                 rq_size, &rq_phys_addr);
284         if (!rq_addr)
285                 return -ENOMEM;
286
287         rsp_size = SIZEOF_CARDRSP_TX(struct qlcnic_cardrsp_tx_ctx);
288         rsp_addr = pci_alloc_consistent(adapter->pdev,
289                 rsp_size, &rsp_phys_addr);
290         if (!rsp_addr) {
291                 err = -ENOMEM;
292                 goto out_free_rq;
293         }
294
295         memset(rq_addr, 0, rq_size);
296         prq = (struct qlcnic_hostrq_tx_ctx *)rq_addr;
297
298         memset(rsp_addr, 0, rsp_size);
299         prsp = (struct qlcnic_cardrsp_tx_ctx *)rsp_addr;
300
301         prq->host_rsp_dma_addr = cpu_to_le64(rsp_phys_addr);
302
303         temp = (QLCNIC_CAP0_LEGACY_CONTEXT | QLCNIC_CAP0_LEGACY_MN |
304                                         QLCNIC_CAP0_LSO);
305         prq->capabilities[0] = cpu_to_le32(temp);
306
307         prq->host_int_crb_mode =
308                 cpu_to_le32(QLCNIC_HOST_INT_CRB_MODE_SHARED);
309
310         prq->interrupt_ctl = 0;
311         prq->msi_index = 0;
312         prq->cmd_cons_dma_addr = cpu_to_le64(tx_ring->hw_cons_phys_addr);
313
314         prq_cds = &prq->cds_ring;
315
316         prq_cds->host_phys_addr = cpu_to_le64(tx_ring->phys_addr);
317         prq_cds->ring_size = cpu_to_le32(tx_ring->num_desc);
318
319         phys_addr = rq_phys_addr;
320         err = qlcnic_issue_cmd(adapter,
321                         adapter->ahw.pci_func,
322                         QLCHAL_VERSION,
323                         (u32)(phys_addr >> 32),
324                         ((u32)phys_addr & 0xffffffff),
325                         rq_size,
326                         QLCNIC_CDRP_CMD_CREATE_TX_CTX);
327
328         if (err == QLCNIC_RCODE_SUCCESS) {
329                 temp = le32_to_cpu(prsp->cds_ring.host_producer_crb);
330                 tx_ring->crb_cmd_producer = qlcnic_get_ioaddr(adapter,
331                                 QLCNIC_REG(temp - 0x200));
332
333                 adapter->tx_context_id =
334                         le16_to_cpu(prsp->context_id);
335         } else {
336                 dev_err(&adapter->pdev->dev,
337                         "Failed to create tx ctx in firmware%d\n", err);
338                 err = -EIO;
339         }
340
341         pci_free_consistent(adapter->pdev, rsp_size, rsp_addr, rsp_phys_addr);
342
343 out_free_rq:
344         pci_free_consistent(adapter->pdev, rq_size, rq_addr, rq_phys_addr);
345
346         return err;
347 }
348
349 static void
350 qlcnic_fw_cmd_destroy_tx_ctx(struct qlcnic_adapter *adapter)
351 {
352         if (qlcnic_issue_cmd(adapter,
353                         adapter->ahw.pci_func,
354                         QLCHAL_VERSION,
355                         adapter->tx_context_id,
356                         QLCNIC_DESTROY_CTX_RESET,
357                         0,
358                         QLCNIC_CDRP_CMD_DESTROY_TX_CTX)) {
359
360                 dev_err(&adapter->pdev->dev,
361                         "Failed to destroy tx ctx in firmware\n");
362         }
363 }
364
365 int
366 qlcnic_fw_cmd_query_phy(struct qlcnic_adapter *adapter, u32 reg, u32 *val)
367 {
368
369         if (qlcnic_issue_cmd(adapter,
370                         adapter->ahw.pci_func,
371                         QLCHAL_VERSION,
372                         reg,
373                         0,
374                         0,
375                         QLCNIC_CDRP_CMD_READ_PHY)) {
376
377                 return -EIO;
378         }
379
380         return QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET);
381 }
382
383 int
384 qlcnic_fw_cmd_set_phy(struct qlcnic_adapter *adapter, u32 reg, u32 val)
385 {
386         return qlcnic_issue_cmd(adapter,
387                         adapter->ahw.pci_func,
388                         QLCHAL_VERSION,
389                         reg,
390                         val,
391                         0,
392                         QLCNIC_CDRP_CMD_WRITE_PHY);
393 }
394
395 int qlcnic_alloc_hw_resources(struct qlcnic_adapter *adapter)
396 {
397         void *addr;
398         int err;
399         int ring;
400         struct qlcnic_recv_context *recv_ctx;
401         struct qlcnic_host_rds_ring *rds_ring;
402         struct qlcnic_host_sds_ring *sds_ring;
403         struct qlcnic_host_tx_ring *tx_ring;
404
405         struct pci_dev *pdev = adapter->pdev;
406
407         recv_ctx = &adapter->recv_ctx;
408         tx_ring = adapter->tx_ring;
409
410         tx_ring->hw_consumer = (__le32 *)pci_alloc_consistent(pdev, sizeof(u32),
411                                                 &tx_ring->hw_cons_phys_addr);
412         if (tx_ring->hw_consumer == NULL) {
413                 dev_err(&pdev->dev, "failed to allocate tx consumer\n");
414                 return -ENOMEM;
415         }
416         *(tx_ring->hw_consumer) = 0;
417
418         /* cmd desc ring */
419         addr = pci_alloc_consistent(pdev, TX_DESC_RINGSIZE(tx_ring),
420                         &tx_ring->phys_addr);
421
422         if (addr == NULL) {
423                 dev_err(&pdev->dev, "failed to allocate tx desc ring\n");
424                 err = -ENOMEM;
425                 goto err_out_free;
426         }
427
428         tx_ring->desc_head = (struct cmd_desc_type0 *)addr;
429
430         for (ring = 0; ring < adapter->max_rds_rings; ring++) {
431                 rds_ring = &recv_ctx->rds_rings[ring];
432                 addr = pci_alloc_consistent(adapter->pdev,
433                                 RCV_DESC_RINGSIZE(rds_ring),
434                                 &rds_ring->phys_addr);
435                 if (addr == NULL) {
436                         dev_err(&pdev->dev,
437                                 "failed to allocate rds ring [%d]\n", ring);
438                         err = -ENOMEM;
439                         goto err_out_free;
440                 }
441                 rds_ring->desc_head = (struct rcv_desc *)addr;
442
443         }
444
445         for (ring = 0; ring < adapter->max_sds_rings; ring++) {
446                 sds_ring = &recv_ctx->sds_rings[ring];
447
448                 addr = pci_alloc_consistent(adapter->pdev,
449                                 STATUS_DESC_RINGSIZE(sds_ring),
450                                 &sds_ring->phys_addr);
451                 if (addr == NULL) {
452                         dev_err(&pdev->dev,
453                                 "failed to allocate sds ring [%d]\n", ring);
454                         err = -ENOMEM;
455                         goto err_out_free;
456                 }
457                 sds_ring->desc_head = (struct status_desc *)addr;
458         }
459
460
461         err = qlcnic_fw_cmd_create_rx_ctx(adapter);
462         if (err)
463                 goto err_out_free;
464         err = qlcnic_fw_cmd_create_tx_ctx(adapter);
465         if (err)
466                 goto err_out_free;
467
468         set_bit(__QLCNIC_FW_ATTACHED, &adapter->state);
469         return 0;
470
471 err_out_free:
472         qlcnic_free_hw_resources(adapter);
473         return err;
474 }
475
476 void qlcnic_free_hw_resources(struct qlcnic_adapter *adapter)
477 {
478         struct qlcnic_recv_context *recv_ctx;
479         struct qlcnic_host_rds_ring *rds_ring;
480         struct qlcnic_host_sds_ring *sds_ring;
481         struct qlcnic_host_tx_ring *tx_ring;
482         int ring;
483
484
485         if (test_and_clear_bit(__QLCNIC_FW_ATTACHED, &adapter->state)) {
486                 qlcnic_fw_cmd_destroy_rx_ctx(adapter);
487                 qlcnic_fw_cmd_destroy_tx_ctx(adapter);
488
489                 /* Allow dma queues to drain after context reset */
490                 msleep(20);
491         }
492
493         recv_ctx = &adapter->recv_ctx;
494
495         tx_ring = adapter->tx_ring;
496         if (tx_ring->hw_consumer != NULL) {
497                 pci_free_consistent(adapter->pdev,
498                                 sizeof(u32),
499                                 tx_ring->hw_consumer,
500                                 tx_ring->hw_cons_phys_addr);
501                 tx_ring->hw_consumer = NULL;
502         }
503
504         if (tx_ring->desc_head != NULL) {
505                 pci_free_consistent(adapter->pdev,
506                                 TX_DESC_RINGSIZE(tx_ring),
507                                 tx_ring->desc_head, tx_ring->phys_addr);
508                 tx_ring->desc_head = NULL;
509         }
510
511         for (ring = 0; ring < adapter->max_rds_rings; ring++) {
512                 rds_ring = &recv_ctx->rds_rings[ring];
513
514                 if (rds_ring->desc_head != NULL) {
515                         pci_free_consistent(adapter->pdev,
516                                         RCV_DESC_RINGSIZE(rds_ring),
517                                         rds_ring->desc_head,
518                                         rds_ring->phys_addr);
519                         rds_ring->desc_head = NULL;
520                 }
521         }
522
523         for (ring = 0; ring < adapter->max_sds_rings; ring++) {
524                 sds_ring = &recv_ctx->sds_rings[ring];
525
526                 if (sds_ring->desc_head != NULL) {
527                         pci_free_consistent(adapter->pdev,
528                                 STATUS_DESC_RINGSIZE(sds_ring),
529                                 sds_ring->desc_head,
530                                 sds_ring->phys_addr);
531                         sds_ring->desc_head = NULL;
532                 }
533         }
534 }
535