aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/qlcnic/qlcnic_hw.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/net/qlcnic/qlcnic_hw.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'drivers/net/qlcnic/qlcnic_hw.c')
-rw-r--r--drivers/net/qlcnic/qlcnic_hw.c743
1 files changed, 609 insertions, 134 deletions
diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c
index e08c8b0556a4..a5d9fbf9d816 100644
--- a/drivers/net/qlcnic/qlcnic_hw.c
+++ b/drivers/net/qlcnic/qlcnic_hw.c
@@ -1,31 +1,15 @@
1/* 1/*
2 * Copyright (C) 2009 - QLogic Corporation. 2 * QLogic qlcnic NIC Driver
3 * All rights reserved. 3 * Copyright (c) 2009-2010 QLogic Corporation
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 * 4 *
5 * See LICENSE.qlcnic for copyright and licensing details.
23 */ 6 */
24 7
25#include "qlcnic.h" 8#include "qlcnic.h"
26 9
27#include <linux/slab.h> 10#include <linux/slab.h>
28#include <net/ip.h> 11#include <net/ip.h>
12#include <linux/bitops.h>
29 13
30#define MASK(n) ((1ULL<<(n))-1) 14#define MASK(n) ((1ULL<<(n))-1)
31#define OCM_WIN_P3P(addr) (addr & 0xffc0000) 15#define OCM_WIN_P3P(addr) (addr & 0xffc0000)
@@ -297,8 +281,8 @@ qlcnic_pcie_sem_lock(struct qlcnic_adapter *adapter, int sem, u32 id_reg)
297 break; 281 break;
298 if (++timeout >= QLCNIC_PCIE_SEM_TIMEOUT) { 282 if (++timeout >= QLCNIC_PCIE_SEM_TIMEOUT) {
299 dev_err(&adapter->pdev->dev, 283 dev_err(&adapter->pdev->dev,
300 "Failed to acquire sem=%d lock;reg_id=%d\n", 284 "Failed to acquire sem=%d lock; holdby=%d\n",
301 sem, id_reg); 285 sem, id_reg ? QLCRD32(adapter, id_reg) : -1);
302 return -EIO; 286 return -EIO;
303 } 287 }
304 msleep(1); 288 msleep(1);
@@ -375,10 +359,11 @@ qlcnic_send_cmd_descs(struct qlcnic_adapter *adapter,
375 359
376static int 360static int
377qlcnic_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr, 361qlcnic_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr,
378 unsigned op) 362 __le16 vlan_id, unsigned op)
379{ 363{
380 struct qlcnic_nic_req req; 364 struct qlcnic_nic_req req;
381 struct qlcnic_mac_req *mac_req; 365 struct qlcnic_mac_req *mac_req;
366 struct qlcnic_vlan_req *vlan_req;
382 u64 word; 367 u64 word;
383 368
384 memset(&req, 0, sizeof(struct qlcnic_nic_req)); 369 memset(&req, 0, sizeof(struct qlcnic_nic_req));
@@ -391,10 +376,13 @@ qlcnic_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr,
391 mac_req->op = op; 376 mac_req->op = op;
392 memcpy(mac_req->mac_addr, addr, 6); 377 memcpy(mac_req->mac_addr, addr, 6);
393 378
379 vlan_req = (struct qlcnic_vlan_req *)&req.words[1];
380 vlan_req->vlan_id = vlan_id;
381
394 return qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); 382 return qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
395} 383}
396 384
397static int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter, u8 *addr) 385static int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter, const u8 *addr)
398{ 386{
399 struct list_head *head; 387 struct list_head *head;
400 struct qlcnic_mac_list_s *cur; 388 struct qlcnic_mac_list_s *cur;
@@ -415,7 +403,7 @@ static int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter, u8 *addr)
415 memcpy(cur->mac_addr, addr, ETH_ALEN); 403 memcpy(cur->mac_addr, addr, ETH_ALEN);
416 404
417 if (qlcnic_sre_macaddr_change(adapter, 405 if (qlcnic_sre_macaddr_change(adapter,
418 cur->mac_addr, QLCNIC_MAC_ADD)) { 406 cur->mac_addr, 0, QLCNIC_MAC_ADD)) {
419 kfree(cur); 407 kfree(cur);
420 return -EIO; 408 return -EIO;
421 } 409 }
@@ -428,7 +416,9 @@ void qlcnic_set_multi(struct net_device *netdev)
428{ 416{
429 struct qlcnic_adapter *adapter = netdev_priv(netdev); 417 struct qlcnic_adapter *adapter = netdev_priv(netdev);
430 struct netdev_hw_addr *ha; 418 struct netdev_hw_addr *ha;
431 u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 419 static const u8 bcast_addr[ETH_ALEN] = {
420 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
421 };
432 u32 mode = VPORT_MISS_MODE_DROP; 422 u32 mode = VPORT_MISS_MODE_DROP;
433 423
434 if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state)) 424 if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state))
@@ -438,7 +428,8 @@ void qlcnic_set_multi(struct net_device *netdev)
438 qlcnic_nic_add_mac(adapter, bcast_addr); 428 qlcnic_nic_add_mac(adapter, bcast_addr);
439 429
440 if (netdev->flags & IFF_PROMISC) { 430 if (netdev->flags & IFF_PROMISC) {
441 mode = VPORT_MISS_MODE_ACCEPT_ALL; 431 if (!(adapter->flags & QLCNIC_PROMISC_DISABLED))
432 mode = VPORT_MISS_MODE_ACCEPT_ALL;
442 goto send_fw_cmd; 433 goto send_fw_cmd;
443 } 434 }
444 435
@@ -467,7 +458,7 @@ int qlcnic_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode)
467 458
468 req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23); 459 req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23);
469 460
470 word = QLCNIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE | 461 word = QLCNIC_H2C_OPCODE_SET_MAC_RECEIVE_MODE |
471 ((u64)adapter->portnum << 16); 462 ((u64)adapter->portnum << 16);
472 req.req_hdr = cpu_to_le64(word); 463 req.req_hdr = cpu_to_le64(word);
473 464
@@ -485,13 +476,62 @@ void qlcnic_free_mac_list(struct qlcnic_adapter *adapter)
485 while (!list_empty(head)) { 476 while (!list_empty(head)) {
486 cur = list_entry(head->next, struct qlcnic_mac_list_s, list); 477 cur = list_entry(head->next, struct qlcnic_mac_list_s, list);
487 qlcnic_sre_macaddr_change(adapter, 478 qlcnic_sre_macaddr_change(adapter,
488 cur->mac_addr, QLCNIC_MAC_DEL); 479 cur->mac_addr, 0, QLCNIC_MAC_DEL);
489 list_del(&cur->list); 480 list_del(&cur->list);
490 kfree(cur); 481 kfree(cur);
491 } 482 }
492} 483}
493 484
494#define QLCNIC_CONFIG_INTR_COALESCE 3 485void qlcnic_prune_lb_filters(struct qlcnic_adapter *adapter)
486{
487 struct qlcnic_filter *tmp_fil;
488 struct hlist_node *tmp_hnode, *n;
489 struct hlist_head *head;
490 int i;
491
492 for (i = 0; i < adapter->fhash.fmax; i++) {
493 head = &(adapter->fhash.fhead[i]);
494
495 hlist_for_each_entry_safe(tmp_fil, tmp_hnode, n, head, fnode)
496 {
497 if (jiffies >
498 (QLCNIC_FILTER_AGE * HZ + tmp_fil->ftime)) {
499 qlcnic_sre_macaddr_change(adapter,
500 tmp_fil->faddr, tmp_fil->vlan_id,
501 tmp_fil->vlan_id ? QLCNIC_MAC_VLAN_DEL :
502 QLCNIC_MAC_DEL);
503 spin_lock_bh(&adapter->mac_learn_lock);
504 adapter->fhash.fnum--;
505 hlist_del(&tmp_fil->fnode);
506 spin_unlock_bh(&adapter->mac_learn_lock);
507 kfree(tmp_fil);
508 }
509 }
510 }
511}
512
513void qlcnic_delete_lb_filters(struct qlcnic_adapter *adapter)
514{
515 struct qlcnic_filter *tmp_fil;
516 struct hlist_node *tmp_hnode, *n;
517 struct hlist_head *head;
518 int i;
519
520 for (i = 0; i < adapter->fhash.fmax; i++) {
521 head = &(adapter->fhash.fhead[i]);
522
523 hlist_for_each_entry_safe(tmp_fil, tmp_hnode, n, head, fnode) {
524 qlcnic_sre_macaddr_change(adapter, tmp_fil->faddr,
525 tmp_fil->vlan_id, tmp_fil->vlan_id ?
526 QLCNIC_MAC_VLAN_DEL : QLCNIC_MAC_DEL);
527 spin_lock_bh(&adapter->mac_learn_lock);
528 adapter->fhash.fnum--;
529 hlist_del(&tmp_fil->fnode);
530 spin_unlock_bh(&adapter->mac_learn_lock);
531 kfree(tmp_fil);
532 }
533 }
534}
495 535
496/* 536/*
497 * Send the interrupt coalescing parameter set by ethtool to the card. 537 * Send the interrupt coalescing parameter set by ethtool to the card.
@@ -499,25 +539,25 @@ void qlcnic_free_mac_list(struct qlcnic_adapter *adapter)
499int qlcnic_config_intr_coalesce(struct qlcnic_adapter *adapter) 539int qlcnic_config_intr_coalesce(struct qlcnic_adapter *adapter)
500{ 540{
501 struct qlcnic_nic_req req; 541 struct qlcnic_nic_req req;
502 u64 word[6]; 542 int rv;
503 int rv, i;
504 543
505 memset(&req, 0, sizeof(struct qlcnic_nic_req)); 544 memset(&req, 0, sizeof(struct qlcnic_nic_req));
506 545
507 req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23); 546 req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23);
508 547
509 word[0] = QLCNIC_CONFIG_INTR_COALESCE | ((u64)adapter->portnum << 16); 548 req.req_hdr = cpu_to_le64(QLCNIC_CONFIG_INTR_COALESCE |
510 req.req_hdr = cpu_to_le64(word[0]); 549 ((u64) adapter->portnum << 16));
511
512 memcpy(&word[0], &adapter->coal, sizeof(adapter->coal));
513 for (i = 0; i < 6; i++)
514 req.words[i] = cpu_to_le64(word[i]);
515 550
551 req.words[0] = cpu_to_le64(((u64) adapter->ahw->coal.flag) << 32);
552 req.words[2] = cpu_to_le64(adapter->ahw->coal.rx_packets |
553 ((u64) adapter->ahw->coal.rx_time_us) << 16);
554 req.words[5] = cpu_to_le64(adapter->ahw->coal.timer_out |
555 ((u64) adapter->ahw->coal.type) << 32 |
556 ((u64) adapter->ahw->coal.sts_ring_mask) << 40);
516 rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); 557 rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
517 if (rv != 0) 558 if (rv != 0)
518 dev_err(&adapter->netdev->dev, 559 dev_err(&adapter->netdev->dev,
519 "Could not send interrupt coalescing parameters\n"); 560 "Could not send interrupt coalescing parameters\n");
520
521 return rv; 561 return rv;
522} 562}
523 563
@@ -527,7 +567,7 @@ int qlcnic_config_hw_lro(struct qlcnic_adapter *adapter, int enable)
527 u64 word; 567 u64 word;
528 int rv; 568 int rv;
529 569
530 if ((adapter->flags & QLCNIC_LRO_ENABLED) == enable) 570 if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state))
531 return 0; 571 return 0;
532 572
533 memset(&req, 0, sizeof(struct qlcnic_nic_req)); 573 memset(&req, 0, sizeof(struct qlcnic_nic_req));
@@ -544,8 +584,6 @@ int qlcnic_config_hw_lro(struct qlcnic_adapter *adapter, int enable)
544 dev_err(&adapter->netdev->dev, 584 dev_err(&adapter->netdev->dev,
545 "Could not send configure hw lro request\n"); 585 "Could not send configure hw lro request\n");
546 586
547 adapter->flags ^= QLCNIC_LRO_ENABLED;
548
549 return rv; 587 return rv;
550} 588}
551 589
@@ -587,10 +625,11 @@ int qlcnic_config_rss(struct qlcnic_adapter *adapter, int enable)
587 u64 word; 625 u64 word;
588 int i, rv; 626 int i, rv;
589 627
590 const u64 key[] = { 0xbeac01fa6a42b73bULL, 0x8030f20c77cb2da3ULL, 628 static const u64 key[] = {
591 0xae7b30b4d0ca2bcbULL, 0x43a38fb04167253dULL, 629 0xbeac01fa6a42b73bULL, 0x8030f20c77cb2da3ULL,
592 0x255b0ec26d5a56daULL }; 630 0xae7b30b4d0ca2bcbULL, 0x43a38fb04167253dULL,
593 631 0x255b0ec26d5a56daULL
632 };
594 633
595 memset(&req, 0, sizeof(struct qlcnic_nic_req)); 634 memset(&req, 0, sizeof(struct qlcnic_nic_req));
596 req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23); 635 req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23);
@@ -623,9 +662,10 @@ int qlcnic_config_rss(struct qlcnic_adapter *adapter, int enable)
623 return rv; 662 return rv;
624} 663}
625 664
626int qlcnic_config_ipaddr(struct qlcnic_adapter *adapter, u32 ip, int cmd) 665int qlcnic_config_ipaddr(struct qlcnic_adapter *adapter, __be32 ip, int cmd)
627{ 666{
628 struct qlcnic_nic_req req; 667 struct qlcnic_nic_req req;
668 struct qlcnic_ipaddr *ipa;
629 u64 word; 669 u64 word;
630 int rv; 670 int rv;
631 671
@@ -636,7 +676,8 @@ int qlcnic_config_ipaddr(struct qlcnic_adapter *adapter, u32 ip, int cmd)
636 req.req_hdr = cpu_to_le64(word); 676 req.req_hdr = cpu_to_le64(word);
637 677
638 req.words[0] = cpu_to_le64(cmd); 678 req.words[0] = cpu_to_le64(cmd);
639 req.words[1] = cpu_to_le64(ip); 679 ipa = (struct qlcnic_ipaddr *)&req.words[1];
680 ipa->ipv4 = ip;
640 681
641 rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); 682 rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
642 if (rv != 0) 683 if (rv != 0)
@@ -674,6 +715,9 @@ int qlcnic_send_lro_cleanup(struct qlcnic_adapter *adapter)
674 u64 word; 715 u64 word;
675 int rv; 716 int rv;
676 717
718 if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state))
719 return 0;
720
677 memset(&req, 0, sizeof(struct qlcnic_nic_req)); 721 memset(&req, 0, sizeof(struct qlcnic_nic_req));
678 req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23); 722 req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23);
679 723
@@ -701,9 +745,9 @@ int qlcnic_change_mtu(struct net_device *netdev, int mtu)
701 struct qlcnic_adapter *adapter = netdev_priv(netdev); 745 struct qlcnic_adapter *adapter = netdev_priv(netdev);
702 int rc = 0; 746 int rc = 0;
703 747
704 if (mtu > P3_MAX_MTU) { 748 if (mtu < P3P_MIN_MTU || mtu > P3P_MAX_MTU) {
705 dev_err(&adapter->netdev->dev, "mtu > %d bytes unsupported\n", 749 dev_err(&adapter->netdev->dev, "%d bytes < mtu < %d bytes"
706 P3_MAX_MTU); 750 " not supported\n", P3P_MAX_MTU, P3P_MIN_MTU);
707 return -EINVAL; 751 return -EINVAL;
708 } 752 }
709 753
@@ -715,15 +759,39 @@ int qlcnic_change_mtu(struct net_device *netdev, int mtu)
715 return rc; 759 return rc;
716} 760}
717 761
718int qlcnic_get_mac_addr(struct qlcnic_adapter *adapter, u8 *mac) 762
763u32 qlcnic_fix_features(struct net_device *netdev, u32 features)
764{
765 struct qlcnic_adapter *adapter = netdev_priv(netdev);
766
767 if ((adapter->flags & QLCNIC_ESWITCH_ENABLED)) {
768 u32 changed = features ^ netdev->features;
769 features ^= changed & (NETIF_F_ALL_CSUM | NETIF_F_RXCSUM);
770 }
771
772 if (!(features & NETIF_F_RXCSUM))
773 features &= ~NETIF_F_LRO;
774
775 return features;
776}
777
778
779int qlcnic_set_features(struct net_device *netdev, u32 features)
719{ 780{
720 u32 crbaddr; 781 struct qlcnic_adapter *adapter = netdev_priv(netdev);
721 int pci_func = adapter->ahw.pci_func; 782 u32 changed = netdev->features ^ features;
783 int hw_lro = (features & NETIF_F_LRO) ? QLCNIC_LRO_ENABLED : 0;
784
785 if (!(changed & NETIF_F_LRO))
786 return 0;
722 787
723 crbaddr = CRB_MAC_BLOCK_START + 788 netdev->features = features ^ NETIF_F_LRO;
724 (4 * ((pci_func/2) * 3)) + (4 * (pci_func & 1));
725 789
726 qlcnic_fetch_mac(adapter, crbaddr, crbaddr+4, pci_func & 1, mac); 790 if (qlcnic_config_hw_lro(adapter, hw_lro))
791 return -EIO;
792
793 if ((hw_lro == 0) && qlcnic_send_lro_cleanup(adapter))
794 return -EIO;
727 795
728 return 0; 796 return 0;
729} 797}
@@ -754,7 +822,7 @@ qlcnic_pci_get_crb_addr_2M(struct qlcnic_adapter *adapter,
754 m = &crb_128M_2M_map[CRB_BLK(off)].sub_block[CRB_SUBBLK(off)]; 822 m = &crb_128M_2M_map[CRB_BLK(off)].sub_block[CRB_SUBBLK(off)];
755 823
756 if (m->valid && (m->start_128M <= off) && (m->end_128M > off)) { 824 if (m->valid && (m->start_128M <= off) && (m->end_128M > off)) {
757 *addr = adapter->ahw.pci_base0 + m->start_2M + 825 *addr = adapter->ahw->pci_base0 + m->start_2M +
758 (off - m->start_128M); 826 (off - m->start_128M);
759 return 0; 827 return 0;
760 } 828 }
@@ -762,7 +830,7 @@ qlcnic_pci_get_crb_addr_2M(struct qlcnic_adapter *adapter,
762 /* 830 /*
763 * Not in direct map, use crb window 831 * Not in direct map, use crb window
764 */ 832 */
765 *addr = adapter->ahw.pci_base0 + CRB_INDIRECT_2M + (off & MASK(16)); 833 *addr = adapter->ahw->pci_base0 + CRB_INDIRECT_2M + (off & MASK(16));
766 return 1; 834 return 1;
767} 835}
768 836
@@ -775,7 +843,7 @@ static int
775qlcnic_pci_set_crbwindow_2M(struct qlcnic_adapter *adapter, ulong off) 843qlcnic_pci_set_crbwindow_2M(struct qlcnic_adapter *adapter, ulong off)
776{ 844{
777 u32 window; 845 u32 window;
778 void __iomem *addr = adapter->ahw.pci_base0 + CRB_WINDOW_2M; 846 void __iomem *addr = adapter->ahw->pci_base0 + CRB_WINDOW_2M;
779 847
780 off -= QLCNIC_PCI_CRBSPACE; 848 off -= QLCNIC_PCI_CRBSPACE;
781 849
@@ -812,13 +880,13 @@ qlcnic_hw_write_wx_2M(struct qlcnic_adapter *adapter, ulong off, u32 data)
812 880
813 if (rv > 0) { 881 if (rv > 0) {
814 /* indirect access */ 882 /* indirect access */
815 write_lock_irqsave(&adapter->ahw.crb_lock, flags); 883 write_lock_irqsave(&adapter->ahw->crb_lock, flags);
816 crb_win_lock(adapter); 884 crb_win_lock(adapter);
817 rv = qlcnic_pci_set_crbwindow_2M(adapter, off); 885 rv = qlcnic_pci_set_crbwindow_2M(adapter, off);
818 if (!rv) 886 if (!rv)
819 writel(data, addr); 887 writel(data, addr);
820 crb_win_unlock(adapter); 888 crb_win_unlock(adapter);
821 write_unlock_irqrestore(&adapter->ahw.crb_lock, flags); 889 write_unlock_irqrestore(&adapter->ahw->crb_lock, flags);
822 return rv; 890 return rv;
823 } 891 }
824 892
@@ -843,12 +911,12 @@ qlcnic_hw_read_wx_2M(struct qlcnic_adapter *adapter, ulong off)
843 911
844 if (rv > 0) { 912 if (rv > 0) {
845 /* indirect access */ 913 /* indirect access */
846 write_lock_irqsave(&adapter->ahw.crb_lock, flags); 914 write_lock_irqsave(&adapter->ahw->crb_lock, flags);
847 crb_win_lock(adapter); 915 crb_win_lock(adapter);
848 if (!qlcnic_pci_set_crbwindow_2M(adapter, off)) 916 if (!qlcnic_pci_set_crbwindow_2M(adapter, off))
849 data = readl(addr); 917 data = readl(addr);
850 crb_win_unlock(adapter); 918 crb_win_unlock(adapter);
851 write_unlock_irqrestore(&adapter->ahw.crb_lock, flags); 919 write_unlock_irqrestore(&adapter->ahw->crb_lock, flags);
852 return data; 920 return data;
853 } 921 }
854 922
@@ -878,9 +946,9 @@ qlcnic_pci_set_window_2M(struct qlcnic_adapter *adapter,
878 946
879 window = OCM_WIN_P3P(addr); 947 window = OCM_WIN_P3P(addr);
880 948
881 writel(window, adapter->ahw.ocm_win_crb); 949 writel(window, adapter->ahw->ocm_win_crb);
882 /* read back to flush */ 950 /* read back to flush */
883 readl(adapter->ahw.ocm_win_crb); 951 readl(adapter->ahw->ocm_win_crb);
884 952
885 *start = QLCNIC_PCI_OCM0_2M + GET_MEM_OFFS_2M(addr); 953 *start = QLCNIC_PCI_OCM0_2M + GET_MEM_OFFS_2M(addr);
886 return 0; 954 return 0;
@@ -894,13 +962,13 @@ qlcnic_pci_mem_access_direct(struct qlcnic_adapter *adapter, u64 off,
894 int ret; 962 int ret;
895 u32 start; 963 u32 start;
896 964
897 mutex_lock(&adapter->ahw.mem_lock); 965 mutex_lock(&adapter->ahw->mem_lock);
898 966
899 ret = qlcnic_pci_set_window_2M(adapter, off, &start); 967 ret = qlcnic_pci_set_window_2M(adapter, off, &start);
900 if (ret != 0) 968 if (ret != 0)
901 goto unlock; 969 goto unlock;
902 970
903 addr = adapter->ahw.pci_base0 + start; 971 addr = adapter->ahw->pci_base0 + start;
904 972
905 if (op == 0) /* read */ 973 if (op == 0) /* read */
906 *data = readq(addr); 974 *data = readq(addr);
@@ -908,7 +976,7 @@ qlcnic_pci_mem_access_direct(struct qlcnic_adapter *adapter, u64 off,
908 writeq(*data, addr); 976 writeq(*data, addr);
909 977
910unlock: 978unlock:
911 mutex_unlock(&adapter->ahw.mem_lock); 979 mutex_unlock(&adapter->ahw->mem_lock);
912 980
913 return ret; 981 return ret;
914} 982}
@@ -916,23 +984,23 @@ unlock:
916void 984void
917qlcnic_pci_camqm_read_2M(struct qlcnic_adapter *adapter, u64 off, u64 *data) 985qlcnic_pci_camqm_read_2M(struct qlcnic_adapter *adapter, u64 off, u64 *data)
918{ 986{
919 void __iomem *addr = adapter->ahw.pci_base0 + 987 void __iomem *addr = adapter->ahw->pci_base0 +
920 QLCNIC_PCI_CAMQM_2M_BASE + (off - QLCNIC_PCI_CAMQM); 988 QLCNIC_PCI_CAMQM_2M_BASE + (off - QLCNIC_PCI_CAMQM);
921 989
922 mutex_lock(&adapter->ahw.mem_lock); 990 mutex_lock(&adapter->ahw->mem_lock);
923 *data = readq(addr); 991 *data = readq(addr);
924 mutex_unlock(&adapter->ahw.mem_lock); 992 mutex_unlock(&adapter->ahw->mem_lock);
925} 993}
926 994
927void 995void
928qlcnic_pci_camqm_write_2M(struct qlcnic_adapter *adapter, u64 off, u64 data) 996qlcnic_pci_camqm_write_2M(struct qlcnic_adapter *adapter, u64 off, u64 data)
929{ 997{
930 void __iomem *addr = adapter->ahw.pci_base0 + 998 void __iomem *addr = adapter->ahw->pci_base0 +
931 QLCNIC_PCI_CAMQM_2M_BASE + (off - QLCNIC_PCI_CAMQM); 999 QLCNIC_PCI_CAMQM_2M_BASE + (off - QLCNIC_PCI_CAMQM);
932 1000
933 mutex_lock(&adapter->ahw.mem_lock); 1001 mutex_lock(&adapter->ahw->mem_lock);
934 writeq(data, addr); 1002 writeq(data, addr);
935 mutex_unlock(&adapter->ahw.mem_lock); 1003 mutex_unlock(&adapter->ahw->mem_lock);
936} 1004}
937 1005
938#define MAX_CTL_CHECK 1000 1006#define MAX_CTL_CHECK 1000
@@ -971,7 +1039,7 @@ qlcnic_pci_mem_write_2M(struct qlcnic_adapter *adapter,
971correct: 1039correct:
972 off8 = off & ~0xf; 1040 off8 = off & ~0xf;
973 1041
974 mutex_lock(&adapter->ahw.mem_lock); 1042 mutex_lock(&adapter->ahw->mem_lock);
975 1043
976 writel(off8, (mem_crb + MIU_TEST_AGT_ADDR_LO)); 1044 writel(off8, (mem_crb + MIU_TEST_AGT_ADDR_LO));
977 writel(0, (mem_crb + MIU_TEST_AGT_ADDR_HI)); 1045 writel(0, (mem_crb + MIU_TEST_AGT_ADDR_HI));
@@ -1023,7 +1091,7 @@ correct:
1023 ret = 0; 1091 ret = 0;
1024 1092
1025done: 1093done:
1026 mutex_unlock(&adapter->ahw.mem_lock); 1094 mutex_unlock(&adapter->ahw->mem_lock);
1027 1095
1028 return ret; 1096 return ret;
1029} 1097}
@@ -1065,7 +1133,7 @@ qlcnic_pci_mem_read_2M(struct qlcnic_adapter *adapter,
1065correct: 1133correct:
1066 off8 = off & ~0xf; 1134 off8 = off & ~0xf;
1067 1135
1068 mutex_lock(&adapter->ahw.mem_lock); 1136 mutex_lock(&adapter->ahw->mem_lock);
1069 1137
1070 writel(off8, (mem_crb + MIU_TEST_AGT_ADDR_LO)); 1138 writel(off8, (mem_crb + MIU_TEST_AGT_ADDR_LO));
1071 writel(0, (mem_crb + MIU_TEST_AGT_ADDR_HI)); 1139 writel(0, (mem_crb + MIU_TEST_AGT_ADDR_HI));
@@ -1095,7 +1163,7 @@ correct:
1095 ret = 0; 1163 ret = 0;
1096 } 1164 }
1097 1165
1098 mutex_unlock(&adapter->ahw.mem_lock); 1166 mutex_unlock(&adapter->ahw->mem_lock);
1099 1167
1100 return ret; 1168 return ret;
1101} 1169}
@@ -1119,39 +1187,39 @@ int qlcnic_get_board_info(struct qlcnic_adapter *adapter)
1119 if (qlcnic_rom_fast_read(adapter, offset, &board_type)) 1187 if (qlcnic_rom_fast_read(adapter, offset, &board_type))
1120 return -EIO; 1188 return -EIO;
1121 1189
1122 adapter->ahw.board_type = board_type; 1190 adapter->ahw->board_type = board_type;
1123 1191
1124 if (board_type == QLCNIC_BRDTYPE_P3_4_GB_MM) { 1192 if (board_type == QLCNIC_BRDTYPE_P3P_4_GB_MM) {
1125 u32 gpio = QLCRD32(adapter, QLCNIC_ROMUSB_GLB_PAD_GPIO_I); 1193 u32 gpio = QLCRD32(adapter, QLCNIC_ROMUSB_GLB_PAD_GPIO_I);
1126 if ((gpio & 0x8000) == 0) 1194 if ((gpio & 0x8000) == 0)
1127 board_type = QLCNIC_BRDTYPE_P3_10G_TP; 1195 board_type = QLCNIC_BRDTYPE_P3P_10G_TP;
1128 } 1196 }
1129 1197
1130 switch (board_type) { 1198 switch (board_type) {
1131 case QLCNIC_BRDTYPE_P3_HMEZ: 1199 case QLCNIC_BRDTYPE_P3P_HMEZ:
1132 case QLCNIC_BRDTYPE_P3_XG_LOM: 1200 case QLCNIC_BRDTYPE_P3P_XG_LOM:
1133 case QLCNIC_BRDTYPE_P3_10G_CX4: 1201 case QLCNIC_BRDTYPE_P3P_10G_CX4:
1134 case QLCNIC_BRDTYPE_P3_10G_CX4_LP: 1202 case QLCNIC_BRDTYPE_P3P_10G_CX4_LP:
1135 case QLCNIC_BRDTYPE_P3_IMEZ: 1203 case QLCNIC_BRDTYPE_P3P_IMEZ:
1136 case QLCNIC_BRDTYPE_P3_10G_SFP_PLUS: 1204 case QLCNIC_BRDTYPE_P3P_10G_SFP_PLUS:
1137 case QLCNIC_BRDTYPE_P3_10G_SFP_CT: 1205 case QLCNIC_BRDTYPE_P3P_10G_SFP_CT:
1138 case QLCNIC_BRDTYPE_P3_10G_SFP_QT: 1206 case QLCNIC_BRDTYPE_P3P_10G_SFP_QT:
1139 case QLCNIC_BRDTYPE_P3_10G_XFP: 1207 case QLCNIC_BRDTYPE_P3P_10G_XFP:
1140 case QLCNIC_BRDTYPE_P3_10000_BASE_T: 1208 case QLCNIC_BRDTYPE_P3P_10000_BASE_T:
1141 adapter->ahw.port_type = QLCNIC_XGBE; 1209 adapter->ahw->port_type = QLCNIC_XGBE;
1142 break; 1210 break;
1143 case QLCNIC_BRDTYPE_P3_REF_QG: 1211 case QLCNIC_BRDTYPE_P3P_REF_QG:
1144 case QLCNIC_BRDTYPE_P3_4_GB: 1212 case QLCNIC_BRDTYPE_P3P_4_GB:
1145 case QLCNIC_BRDTYPE_P3_4_GB_MM: 1213 case QLCNIC_BRDTYPE_P3P_4_GB_MM:
1146 adapter->ahw.port_type = QLCNIC_GBE; 1214 adapter->ahw->port_type = QLCNIC_GBE;
1147 break; 1215 break;
1148 case QLCNIC_BRDTYPE_P3_10G_TP: 1216 case QLCNIC_BRDTYPE_P3P_10G_TP:
1149 adapter->ahw.port_type = (adapter->portnum < 2) ? 1217 adapter->ahw->port_type = (adapter->portnum < 2) ?
1150 QLCNIC_XGBE : QLCNIC_GBE; 1218 QLCNIC_XGBE : QLCNIC_GBE;
1151 break; 1219 break;
1152 default: 1220 default:
1153 dev_err(&pdev->dev, "unknown board type %x\n", board_type); 1221 dev_err(&pdev->dev, "unknown board type %x\n", board_type);
1154 adapter->ahw.port_type = QLCNIC_XGBE; 1222 adapter->ahw->port_type = QLCNIC_XGBE;
1155 break; 1223 break;
1156 } 1224 }
1157 1225
@@ -1195,54 +1263,461 @@ int qlcnic_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate)
1195 return rv; 1263 return rv;
1196} 1264}
1197 1265
1198static int qlcnic_set_fw_loopback(struct qlcnic_adapter *adapter, u32 flag) 1266/* FW dump related functions */
1267static u32
1268qlcnic_dump_crb(struct qlcnic_adapter *adapter, struct qlcnic_dump_entry *entry,
1269 u32 *buffer)
1199{ 1270{
1200 struct qlcnic_nic_req req; 1271 int i;
1201 int rv; 1272 u32 addr, data;
1202 u64 word; 1273 struct __crb *crb = &entry->region.crb;
1274 void __iomem *base = adapter->ahw->pci_base0;
1275
1276 addr = crb->addr;
1277
1278 for (i = 0; i < crb->no_ops; i++) {
1279 QLCNIC_RD_DUMP_REG(addr, base, &data);
1280 *buffer++ = cpu_to_le32(addr);
1281 *buffer++ = cpu_to_le32(data);
1282 addr += crb->stride;
1283 }
1284 return crb->no_ops * 2 * sizeof(u32);
1285}
1203 1286
1204 memset(&req, 0, sizeof(struct qlcnic_nic_req)); 1287static u32
1205 req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23); 1288qlcnic_dump_ctrl(struct qlcnic_adapter *adapter,
1289 struct qlcnic_dump_entry *entry, u32 *buffer)
1290{
1291 int i, k, timeout = 0;
1292 void __iomem *base = adapter->ahw->pci_base0;
1293 u32 addr, data;
1294 u8 opcode, no_ops;
1295 struct __ctrl *ctr = &entry->region.ctrl;
1296 struct qlcnic_dump_template_hdr *t_hdr = adapter->ahw->fw_dump.tmpl_hdr;
1297
1298 addr = ctr->addr;
1299 no_ops = ctr->no_ops;
1300
1301 for (i = 0; i < no_ops; i++) {
1302 k = 0;
1303 opcode = 0;
1304 for (k = 0; k < 8; k++) {
1305 if (!(ctr->opcode & (1 << k)))
1306 continue;
1307 switch (1 << k) {
1308 case QLCNIC_DUMP_WCRB:
1309 QLCNIC_WR_DUMP_REG(addr, base, ctr->val1);
1310 break;
1311 case QLCNIC_DUMP_RWCRB:
1312 QLCNIC_RD_DUMP_REG(addr, base, &data);
1313 QLCNIC_WR_DUMP_REG(addr, base, data);
1314 break;
1315 case QLCNIC_DUMP_ANDCRB:
1316 QLCNIC_RD_DUMP_REG(addr, base, &data);
1317 QLCNIC_WR_DUMP_REG(addr, base,
1318 (data & ctr->val2));
1319 break;
1320 case QLCNIC_DUMP_ORCRB:
1321 QLCNIC_RD_DUMP_REG(addr, base, &data);
1322 QLCNIC_WR_DUMP_REG(addr, base,
1323 (data | ctr->val3));
1324 break;
1325 case QLCNIC_DUMP_POLLCRB:
1326 while (timeout <= ctr->timeout) {
1327 QLCNIC_RD_DUMP_REG(addr, base, &data);
1328 if ((data & ctr->val2) == ctr->val1)
1329 break;
1330 msleep(1);
1331 timeout++;
1332 }
1333 if (timeout > ctr->timeout) {
1334 dev_info(&adapter->pdev->dev,
1335 "Timed out, aborting poll CRB\n");
1336 return -EINVAL;
1337 }
1338 break;
1339 case QLCNIC_DUMP_RD_SAVE:
1340 if (ctr->index_a)
1341 addr = t_hdr->saved_state[ctr->index_a];
1342 QLCNIC_RD_DUMP_REG(addr, base, &data);
1343 t_hdr->saved_state[ctr->index_v] = data;
1344 break;
1345 case QLCNIC_DUMP_WRT_SAVED:
1346 if (ctr->index_v)
1347 data = t_hdr->saved_state[ctr->index_v];
1348 else
1349 data = ctr->val1;
1350 if (ctr->index_a)
1351 addr = t_hdr->saved_state[ctr->index_a];
1352 QLCNIC_WR_DUMP_REG(addr, base, data);
1353 break;
1354 case QLCNIC_DUMP_MOD_SAVE_ST:
1355 data = t_hdr->saved_state[ctr->index_v];
1356 data <<= ctr->shl_val;
1357 data >>= ctr->shr_val;
1358 if (ctr->val2)
1359 data &= ctr->val2;
1360 data |= ctr->val3;
1361 data += ctr->val1;
1362 t_hdr->saved_state[ctr->index_v] = data;
1363 break;
1364 default:
1365 dev_info(&adapter->pdev->dev,
1366 "Unknown opcode\n");
1367 break;
1368 }
1369 }
1370 addr += ctr->stride;
1371 }
1372 return 0;
1373}
1206 1374
1207 word = QLCNIC_H2C_OPCODE_CONFIG_LOOPBACK | 1375static u32
1208 ((u64)adapter->portnum << 16); 1376qlcnic_dump_mux(struct qlcnic_adapter *adapter, struct qlcnic_dump_entry *entry,
1209 req.req_hdr = cpu_to_le64(word); 1377 u32 *buffer)
1210 req.words[0] = cpu_to_le64(flag); 1378{
1379 int loop;
1380 u32 val, data = 0;
1381 struct __mux *mux = &entry->region.mux;
1382 void __iomem *base = adapter->ahw->pci_base0;
1383
1384 val = mux->val;
1385 for (loop = 0; loop < mux->no_ops; loop++) {
1386 QLCNIC_WR_DUMP_REG(mux->addr, base, val);
1387 QLCNIC_RD_DUMP_REG(mux->read_addr, base, &data);
1388 *buffer++ = cpu_to_le32(val);
1389 *buffer++ = cpu_to_le32(data);
1390 val += mux->val_stride;
1391 }
1392 return 2 * mux->no_ops * sizeof(u32);
1393}
1211 1394
1212 rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); 1395static u32
1213 if (rv) 1396qlcnic_dump_que(struct qlcnic_adapter *adapter, struct qlcnic_dump_entry *entry,
1214 dev_err(&adapter->pdev->dev, 1397 u32 *buffer)
1215 "%sting loopback mode failed.\n", 1398{
1216 flag ? "Set" : "Reset"); 1399 int i, loop;
1217 return rv; 1400 u32 cnt, addr, data, que_id = 0;
1401 void __iomem *base = adapter->ahw->pci_base0;
1402 struct __queue *que = &entry->region.que;
1403
1404 addr = que->read_addr;
1405 cnt = que->read_addr_cnt;
1406
1407 for (loop = 0; loop < que->no_ops; loop++) {
1408 QLCNIC_WR_DUMP_REG(que->sel_addr, base, que_id);
1409 addr = que->read_addr;
1410 for (i = 0; i < cnt; i++) {
1411 QLCNIC_RD_DUMP_REG(addr, base, &data);
1412 *buffer++ = cpu_to_le32(data);
1413 addr += que->read_addr_stride;
1414 }
1415 que_id += que->stride;
1416 }
1417 return que->no_ops * cnt * sizeof(u32);
1218} 1418}
1219 1419
1220int qlcnic_set_ilb_mode(struct qlcnic_adapter *adapter) 1420static u32
1421qlcnic_dump_ocm(struct qlcnic_adapter *adapter, struct qlcnic_dump_entry *entry,
1422 u32 *buffer)
1221{ 1423{
1222 if (qlcnic_set_fw_loopback(adapter, 1)) 1424 int i;
1223 return -EIO; 1425 u32 data;
1426 void __iomem *addr;
1427 struct __ocm *ocm = &entry->region.ocm;
1224 1428
1225 if (qlcnic_nic_set_promisc(adapter, 1429 addr = adapter->ahw->pci_base0 + ocm->read_addr;
1226 VPORT_MISS_MODE_ACCEPT_ALL)) { 1430 for (i = 0; i < ocm->no_ops; i++) {
1227 qlcnic_set_fw_loopback(adapter, 0); 1431 data = readl(addr);
1228 return -EIO; 1432 *buffer++ = cpu_to_le32(data);
1433 addr += ocm->read_addr_stride;
1229 } 1434 }
1435 return ocm->no_ops * sizeof(u32);
1436}
1230 1437
1231 msleep(1000); 1438static u32
1232 return 0; 1439qlcnic_read_rom(struct qlcnic_adapter *adapter, struct qlcnic_dump_entry *entry,
1440 u32 *buffer)
1441{
1442 int i, count = 0;
1443 u32 fl_addr, size, val, lck_val, addr;
1444 struct __mem *rom = &entry->region.mem;
1445 void __iomem *base = adapter->ahw->pci_base0;
1446
1447 fl_addr = rom->addr;
1448 size = rom->size/4;
1449lock_try:
1450 lck_val = readl(base + QLCNIC_FLASH_SEM2_LK);
1451 if (!lck_val && count < MAX_CTL_CHECK) {
1452 msleep(10);
1453 count++;
1454 goto lock_try;
1455 }
1456 writel(adapter->ahw->pci_func, (base + QLCNIC_FLASH_LOCK_ID));
1457 for (i = 0; i < size; i++) {
1458 addr = fl_addr & 0xFFFF0000;
1459 QLCNIC_WR_DUMP_REG(FLASH_ROM_WINDOW, base, addr);
1460 addr = LSW(fl_addr) + FLASH_ROM_DATA;
1461 QLCNIC_RD_DUMP_REG(addr, base, &val);
1462 fl_addr += 4;
1463 *buffer++ = cpu_to_le32(val);
1464 }
1465 readl(base + QLCNIC_FLASH_SEM2_ULK);
1466 return rom->size;
1233} 1467}
1234 1468
1235void qlcnic_clear_ilb_mode(struct qlcnic_adapter *adapter) 1469static u32
1470qlcnic_dump_l1_cache(struct qlcnic_adapter *adapter,
1471 struct qlcnic_dump_entry *entry, u32 *buffer)
1236{ 1472{
1237 int mode = VPORT_MISS_MODE_DROP; 1473 int i;
1238 struct net_device *netdev = adapter->netdev; 1474 u32 cnt, val, data, addr;
1475 void __iomem *base = adapter->ahw->pci_base0;
1476 struct __cache *l1 = &entry->region.cache;
1477
1478 val = l1->init_tag_val;
1479
1480 for (i = 0; i < l1->no_ops; i++) {
1481 QLCNIC_WR_DUMP_REG(l1->addr, base, val);
1482 QLCNIC_WR_DUMP_REG(l1->ctrl_addr, base, LSW(l1->ctrl_val));
1483 addr = l1->read_addr;
1484 cnt = l1->read_addr_num;
1485 while (cnt) {
1486 QLCNIC_RD_DUMP_REG(addr, base, &data);
1487 *buffer++ = cpu_to_le32(data);
1488 addr += l1->read_addr_stride;
1489 cnt--;
1490 }
1491 val += l1->stride;
1492 }
1493 return l1->no_ops * l1->read_addr_num * sizeof(u32);
1494}
1239 1495
1240 qlcnic_set_fw_loopback(adapter, 0); 1496static u32
1497qlcnic_dump_l2_cache(struct qlcnic_adapter *adapter,
1498 struct qlcnic_dump_entry *entry, u32 *buffer)
1499{
1500 int i;
1501 u32 cnt, val, data, addr;
1502 u8 poll_mask, poll_to, time_out = 0;
1503 void __iomem *base = adapter->ahw->pci_base0;
1504 struct __cache *l2 = &entry->region.cache;
1505
1506 val = l2->init_tag_val;
1507 poll_mask = LSB(MSW(l2->ctrl_val));
1508 poll_to = MSB(MSW(l2->ctrl_val));
1509
1510 for (i = 0; i < l2->no_ops; i++) {
1511 QLCNIC_WR_DUMP_REG(l2->addr, base, val);
1512 do {
1513 QLCNIC_WR_DUMP_REG(l2->ctrl_addr, base,
1514 LSW(l2->ctrl_val));
1515 QLCNIC_RD_DUMP_REG(l2->ctrl_addr, base, &data);
1516 if (!(data & poll_mask))
1517 break;
1518 msleep(1);
1519 time_out++;
1520 } while (time_out <= poll_to);
1521 if (time_out > poll_to)
1522 return -EINVAL;
1523
1524 addr = l2->read_addr;
1525 cnt = l2->read_addr_num;
1526 while (cnt) {
1527 QLCNIC_RD_DUMP_REG(addr, base, &data);
1528 *buffer++ = cpu_to_le32(data);
1529 addr += l2->read_addr_stride;
1530 cnt--;
1531 }
1532 val += l2->stride;
1533 }
1534 return l2->no_ops * l2->read_addr_num * sizeof(u32);
1535}
1241 1536
1242 if (netdev->flags & IFF_PROMISC) 1537static u32
1243 mode = VPORT_MISS_MODE_ACCEPT_ALL; 1538qlcnic_read_memory(struct qlcnic_adapter *adapter,
1244 else if (netdev->flags & IFF_ALLMULTI) 1539 struct qlcnic_dump_entry *entry, u32 *buffer)
1245 mode = VPORT_MISS_MODE_ACCEPT_MULTI; 1540{
1541 u32 addr, data, test, ret = 0;
1542 int i, reg_read;
1543 struct __mem *mem = &entry->region.mem;
1544 void __iomem *base = adapter->ahw->pci_base0;
1545
1546 reg_read = mem->size;
1547 addr = mem->addr;
1548 /* check for data size of multiple of 16 and 16 byte alignment */
1549 if ((addr & 0xf) || (reg_read%16)) {
1550 dev_info(&adapter->pdev->dev,
1551 "Unaligned memory addr:0x%x size:0x%x\n",
1552 addr, reg_read);
1553 return -EINVAL;
1554 }
1246 1555
1247 qlcnic_nic_set_promisc(adapter, mode); 1556 mutex_lock(&adapter->ahw->mem_lock);
1557
1558 while (reg_read != 0) {
1559 QLCNIC_WR_DUMP_REG(MIU_TEST_ADDR_LO, base, addr);
1560 QLCNIC_WR_DUMP_REG(MIU_TEST_ADDR_HI, base, 0);
1561 QLCNIC_WR_DUMP_REG(MIU_TEST_CTR, base,
1562 TA_CTL_ENABLE | TA_CTL_START);
1563
1564 for (i = 0; i < MAX_CTL_CHECK; i++) {
1565 QLCNIC_RD_DUMP_REG(MIU_TEST_CTR, base, &test);
1566 if (!(test & TA_CTL_BUSY))
1567 break;
1568 }
1569 if (i == MAX_CTL_CHECK) {
1570 if (printk_ratelimit()) {
1571 dev_err(&adapter->pdev->dev,
1572 "failed to read through agent\n");
1573 ret = -EINVAL;
1574 goto out;
1575 }
1576 }
1577 for (i = 0; i < 4; i++) {
1578 QLCNIC_RD_DUMP_REG(MIU_TEST_READ_DATA[i], base, &data);
1579 *buffer++ = cpu_to_le32(data);
1580 }
1581 addr += 16;
1582 reg_read -= 16;
1583 ret += 16;
1584 }
1585out:
1586 mutex_unlock(&adapter->ahw->mem_lock);
1587 return mem->size;
1588}
1589
1590static u32
1591qlcnic_dump_nop(struct qlcnic_adapter *adapter,
1592 struct qlcnic_dump_entry *entry, u32 *buffer)
1593{
1594 entry->hdr.flags |= QLCNIC_DUMP_SKIP;
1595 return 0;
1596}
1597
1598struct qlcnic_dump_operations fw_dump_ops[] = {
1599 { QLCNIC_DUMP_NOP, qlcnic_dump_nop },
1600 { QLCNIC_DUMP_READ_CRB, qlcnic_dump_crb },
1601 { QLCNIC_DUMP_READ_MUX, qlcnic_dump_mux },
1602 { QLCNIC_DUMP_QUEUE, qlcnic_dump_que },
1603 { QLCNIC_DUMP_BRD_CONFIG, qlcnic_read_rom },
1604 { QLCNIC_DUMP_READ_OCM, qlcnic_dump_ocm },
1605 { QLCNIC_DUMP_PEG_REG, qlcnic_dump_ctrl },
1606 { QLCNIC_DUMP_L1_DTAG, qlcnic_dump_l1_cache },
1607 { QLCNIC_DUMP_L1_ITAG, qlcnic_dump_l1_cache },
1608 { QLCNIC_DUMP_L1_DATA, qlcnic_dump_l1_cache },
1609 { QLCNIC_DUMP_L1_INST, qlcnic_dump_l1_cache },
1610 { QLCNIC_DUMP_L2_DTAG, qlcnic_dump_l2_cache },
1611 { QLCNIC_DUMP_L2_ITAG, qlcnic_dump_l2_cache },
1612 { QLCNIC_DUMP_L2_DATA, qlcnic_dump_l2_cache },
1613 { QLCNIC_DUMP_L2_INST, qlcnic_dump_l2_cache },
1614 { QLCNIC_DUMP_READ_ROM, qlcnic_read_rom },
1615 { QLCNIC_DUMP_READ_MEM, qlcnic_read_memory },
1616 { QLCNIC_DUMP_READ_CTRL, qlcnic_dump_ctrl },
1617 { QLCNIC_DUMP_TLHDR, qlcnic_dump_nop },
1618 { QLCNIC_DUMP_RDEND, qlcnic_dump_nop },
1619};
1620
1621/* Walk the template and collect dump for each entry in the dump template */
1622static int
1623qlcnic_valid_dump_entry(struct device *dev, struct qlcnic_dump_entry *entry,
1624 u32 size)
1625{
1626 int ret = 1;
1627 if (size != entry->hdr.cap_size) {
1628 dev_info(dev,
1629 "Invalidate dump, Type:%d\tMask:%d\tSize:%dCap_size:%d\n",
1630 entry->hdr.type, entry->hdr.mask, size, entry->hdr.cap_size);
1631 dev_info(dev, "Aborting further dump capture\n");
1632 ret = 0;
1633 }
1634 return ret;
1635}
1636
1637int qlcnic_dump_fw(struct qlcnic_adapter *adapter)
1638{
1639 u32 *buffer;
1640 char mesg[64];
1641 char *msg[] = {mesg, NULL};
1642 int i, k, ops_cnt, ops_index, dump_size = 0;
1643 u32 entry_offset, dump, no_entries, buf_offset = 0;
1644 struct qlcnic_dump_entry *entry;
1645 struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1646 struct qlcnic_dump_template_hdr *tmpl_hdr = fw_dump->tmpl_hdr;
1647
1648 if (fw_dump->clr) {
1649 dev_info(&adapter->pdev->dev,
1650 "Previous dump not cleared, not capturing dump\n");
1651 return -EIO;
1652 }
1653 /* Calculate the size for dump data area only */
1654 for (i = 2, k = 1; (i & QLCNIC_DUMP_MASK_MAX); i <<= 1, k++)
1655 if (i & tmpl_hdr->drv_cap_mask)
1656 dump_size += tmpl_hdr->cap_sizes[k];
1657 if (!dump_size)
1658 return -EIO;
1659
1660 fw_dump->data = vzalloc(dump_size);
1661 if (!fw_dump->data) {
1662 dev_info(&adapter->pdev->dev,
1663 "Unable to allocate (%d KB) for fw dump\n",
1664 dump_size/1024);
1665 return -ENOMEM;
1666 }
1667 buffer = fw_dump->data;
1668 fw_dump->size = dump_size;
1669 no_entries = tmpl_hdr->num_entries;
1670 ops_cnt = ARRAY_SIZE(fw_dump_ops);
1671 entry_offset = tmpl_hdr->offset;
1672 tmpl_hdr->sys_info[0] = QLCNIC_DRIVER_VERSION;
1673 tmpl_hdr->sys_info[1] = adapter->fw_version;
1674
1675 for (i = 0; i < no_entries; i++) {
1676 entry = (struct qlcnic_dump_entry *) ((void *) tmpl_hdr +
1677 entry_offset);
1678 if (!(entry->hdr.mask & tmpl_hdr->drv_cap_mask)) {
1679 entry->hdr.flags |= QLCNIC_DUMP_SKIP;
1680 entry_offset += entry->hdr.offset;
1681 continue;
1682 }
1683 /* Find the handler for this entry */
1684 ops_index = 0;
1685 while (ops_index < ops_cnt) {
1686 if (entry->hdr.type == fw_dump_ops[ops_index].opcode)
1687 break;
1688 ops_index++;
1689 }
1690 if (ops_index == ops_cnt) {
1691 dev_info(&adapter->pdev->dev,
1692 "Invalid entry type %d, exiting dump\n",
1693 entry->hdr.type);
1694 goto error;
1695 }
1696 /* Collect dump for this entry */
1697 dump = fw_dump_ops[ops_index].handler(adapter, entry, buffer);
1698 if (dump && !qlcnic_valid_dump_entry(&adapter->pdev->dev, entry,
1699 dump))
1700 entry->hdr.flags |= QLCNIC_DUMP_SKIP;
1701 buf_offset += entry->hdr.cap_size;
1702 entry_offset += entry->hdr.offset;
1703 buffer = fw_dump->data + buf_offset;
1704 }
1705 if (dump_size != buf_offset) {
1706 dev_info(&adapter->pdev->dev,
1707 "Captured(%d) and expected size(%d) do not match\n",
1708 buf_offset, dump_size);
1709 goto error;
1710 } else {
1711 fw_dump->clr = 1;
1712 snprintf(mesg, sizeof(mesg), "FW dump for device: %d\n",
1713 adapter->pdev->devfn);
1714 dev_info(&adapter->pdev->dev, "Dump data, %d bytes captured\n",
1715 fw_dump->size);
1716 /* Send a udev event to notify availability of FW dump */
1717 kobject_uevent_env(&adapter->pdev->dev.kobj, KOBJ_CHANGE, msg);
1718 return 0;
1719 }
1720error:
1721 vfree(fw_dump->data);
1722 return -EINVAL;
1248} 1723}