aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/qlogic/qlcnic
diff options
context:
space:
mode:
authorSony Chacko <sony.chacko@qlogic.com>2012-12-31 22:20:19 -0500
committerDavid S. Miller <davem@davemloft.net>2013-01-02 05:43:26 -0500
commit7f9664525f9cb507de9198a395a111371413f230 (patch)
tree3afa3c469348de2847dc2e82a2dfa9583c2fb617 /drivers/net/ethernet/qlogic/qlcnic
parenta15ebd371992dbadb8a30367fd80cb5cd73b8fb1 (diff)
qlcnic: 83xx memory map and HW access routines
83xx adapter register map. 83xx hardware interface routines. Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com> Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com> Signed-off-by: Sritej Velaga <sritej.velaga@qlogic.com> Signed-off-by: Sony Chacko <sony.chacko@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/qlogic/qlcnic')
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/Makefile2
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic.h76
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c1719
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h250
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h10
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c47
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h17
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c3
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c2
9 files changed, 2094 insertions, 32 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/Makefile b/drivers/net/ethernet/qlogic/qlcnic/Makefile
index c4b8ced83829..f8d85aec26b7 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/Makefile
+++ b/drivers/net/ethernet/qlogic/qlcnic/Makefile
@@ -6,4 +6,4 @@ obj-$(CONFIG_QLCNIC) := qlcnic.o
6 6
7qlcnic-y := qlcnic_hw.o qlcnic_main.o qlcnic_init.o \ 7qlcnic-y := qlcnic_hw.o qlcnic_main.o qlcnic_init.o \
8 qlcnic_ethtool.o qlcnic_ctx.o qlcnic_io.o \ 8 qlcnic_ethtool.o qlcnic_ctx.o qlcnic_io.o \
9 qlcnic_sysfs.o qlcnic_minidump.o 9 qlcnic_sysfs.o qlcnic_minidump.o qlcnic_83xx_hw.o
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index 5c5c57813cdd..2b7adda619bb 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -33,6 +33,8 @@
33#include <linux/if_vlan.h> 33#include <linux/if_vlan.h>
34 34
35#include "qlcnic_hdr.h" 35#include "qlcnic_hdr.h"
36#include "qlcnic_hw.h"
37#include "qlcnic_83xx_hw.h"
36 38
37#define _QLCNIC_LINUX_MAJOR 5 39#define _QLCNIC_LINUX_MAJOR 5
38#define _QLCNIC_LINUX_MINOR 0 40#define _QLCNIC_LINUX_MINOR 0
@@ -96,7 +98,6 @@
96#define TX_STOP_THRESH ((MAX_SKB_FRAGS >> 2) + MAX_TSO_HEADER_DESC \ 98#define TX_STOP_THRESH ((MAX_SKB_FRAGS >> 2) + MAX_TSO_HEADER_DESC \
97 + MGMT_CMD_DESC_RESV) 99 + MGMT_CMD_DESC_RESV)
98#define QLCNIC_MAX_TX_TIMEOUTS 2 100#define QLCNIC_MAX_TX_TIMEOUTS 2
99
100/* 101/*
101 * Following are the states of the Phantom. Phantom will set them and 102 * Following are the states of the Phantom. Phantom will set them and
102 * Host will read to check if the fields are correct. 103 * Host will read to check if the fields are correct.
@@ -399,10 +400,16 @@ struct qlcnic_hardware_context {
399 u32 temp; 400 u32 temp;
400 u32 int_vec_bit; 401 u32 int_vec_bit;
401 u32 fw_hal_version; 402 u32 fw_hal_version;
403 u32 port_config;
402 struct qlcnic_hardware_ops *hw_ops; 404 struct qlcnic_hardware_ops *hw_ops;
403 struct qlcnic_nic_intr_coalesce coal; 405 struct qlcnic_nic_intr_coalesce coal;
404 struct qlcnic_fw_dump fw_dump; 406 struct qlcnic_fw_dump fw_dump;
407 struct qlcnic_intrpt_config *intr_tbl;
405 u32 *reg_tbl; 408 u32 *reg_tbl;
409 u32 *ext_reg_tbl;
410 u32 mbox_aen[QLC_83XX_MBX_AEN_CNT];
411 u32 mbox_reg[4];
412 spinlock_t mbx_lock;
406}; 413};
407 414
408struct qlcnic_adapter_stats { 415struct qlcnic_adapter_stats {
@@ -423,6 +430,7 @@ struct qlcnic_adapter_stats {
423 u64 null_rxbuf; 430 u64 null_rxbuf;
424 u64 rx_dma_map_error; 431 u64 rx_dma_map_error;
425 u64 tx_dma_map_error; 432 u64 tx_dma_map_error;
433 u64 spurious_intr;
426}; 434};
427 435
428/* 436/*
@@ -461,6 +469,8 @@ struct qlcnic_host_sds_ring {
461} ____cacheline_internodealigned_in_smp; 469} ____cacheline_internodealigned_in_smp;
462 470
463struct qlcnic_host_tx_ring { 471struct qlcnic_host_tx_ring {
472 void __iomem *crb_intr_mask;
473 char name[IFNAMSIZ+4];
464 u16 ctx_id; 474 u16 ctx_id;
465 u32 producer; 475 u32 producer;
466 u32 sw_consumer; 476 u32 sw_consumer;
@@ -761,7 +771,7 @@ struct qlcnic_mac_list_s {
761 */ 771 */
762 772
763#define QLCNIC_C2H_OPCODE_CONFIG_LOOPBACK 0x8f 773#define QLCNIC_C2H_OPCODE_CONFIG_LOOPBACK 0x8f
764#define QLCNIC_C2H_OPCODE_GET_LINKEVENT_RESPONSE 141 774#define QLCNIC_C2H_OPCODE_GET_LINKEVENT_RESPONSE 0x8D
765 775
766#define VPORT_MISS_MODE_DROP 0 /* drop all unmatched */ 776#define VPORT_MISS_MODE_DROP 0 /* drop all unmatched */
767#define VPORT_MISS_MODE_ACCEPT_ALL 1 /* accept all packets */ 777#define VPORT_MISS_MODE_ACCEPT_ALL 1 /* accept all packets */
@@ -854,7 +864,7 @@ struct qlcnic_ipaddr {
854 864
855#define QLCNIC_MSI_ENABLED 0x02 865#define QLCNIC_MSI_ENABLED 0x02
856#define QLCNIC_MSIX_ENABLED 0x04 866#define QLCNIC_MSIX_ENABLED 0x04
857#define QLCNIC_LRO_ENABLED 0x08 867#define QLCNIC_LRO_ENABLED 0x01
858#define QLCNIC_LRO_DISABLED 0x00 868#define QLCNIC_LRO_DISABLED 0x00
859#define QLCNIC_BRIDGE_ENABLED 0X10 869#define QLCNIC_BRIDGE_ENABLED 0X10
860#define QLCNIC_DIAG_ENABLED 0x20 870#define QLCNIC_DIAG_ENABLED 0x20
@@ -894,6 +904,7 @@ struct qlcnic_ipaddr {
894#define QLCNIC_FILTER_AGE 80 904#define QLCNIC_FILTER_AGE 80
895#define QLCNIC_READD_AGE 20 905#define QLCNIC_READD_AGE 20
896#define QLCNIC_LB_MAX_FILTERS 64 906#define QLCNIC_LB_MAX_FILTERS 64
907#define QLCNIC_LB_BUCKET_SIZE 32
897 908
898/* QLCNIC Driver Error Code */ 909/* QLCNIC Driver Error Code */
899#define QLCNIC_FW_NOT_RESPOND 51 910#define QLCNIC_FW_NOT_RESPOND 51
@@ -911,7 +922,8 @@ struct qlcnic_filter {
911struct qlcnic_filter_hash { 922struct qlcnic_filter_hash {
912 struct hlist_head *fhead; 923 struct hlist_head *fhead;
913 u8 fnum; 924 u8 fnum;
914 u8 fmax; 925 u16 fmax;
926 u16 fbucket_size;
915}; 927};
916 928
917struct qlcnic_adapter { 929struct qlcnic_adapter {
@@ -933,6 +945,7 @@ struct qlcnic_adapter {
933 945
934 u8 max_rds_rings; 946 u8 max_rds_rings;
935 u8 max_sds_rings; 947 u8 max_sds_rings;
948 u8 rx_csum;
936 u8 portnum; 949 u8 portnum;
937 950
938 u8 fw_wait_cnt; 951 u8 fw_wait_cnt;
@@ -968,7 +981,9 @@ struct qlcnic_adapter {
968 void __iomem *isr_int_vec; 981 void __iomem *isr_int_vec;
969 982
970 struct msix_entry *msix_entries; 983 struct msix_entry *msix_entries;
984 struct workqueue_struct *qlcnic_wq;
971 struct delayed_work fw_work; 985 struct delayed_work fw_work;
986 struct delayed_work idc_aen_work;
972 987
973 struct qlcnic_filter_hash fhash; 988 struct qlcnic_filter_hash fhash;
974 989
@@ -994,7 +1009,24 @@ struct qlcnic_info_le {
994 __le16 max_rx_ques; 1009 __le16 max_rx_ques;
995 __le16 min_tx_bw; 1010 __le16 min_tx_bw;
996 __le16 max_tx_bw; 1011 __le16 max_tx_bw;
997 u8 reserved2[104]; 1012 __le32 op_type;
1013 __le16 max_bw_reg_offset;
1014 __le16 max_linkspeed_reg_offset;
1015 __le32 capability1;
1016 __le32 capability2;
1017 __le32 capability3;
1018 __le16 max_tx_mac_filters;
1019 __le16 max_rx_mcast_mac_filters;
1020 __le16 max_rx_ucast_mac_filters;
1021 __le16 max_rx_ip_addr;
1022 __le16 max_rx_lro_flow;
1023 __le16 max_rx_status_rings;
1024 __le16 max_rx_buf_rings;
1025 __le16 max_tx_vlan_keys;
1026 u8 total_pf;
1027 u8 total_rss_engines;
1028 __le16 max_vports;
1029 u8 reserved2[64];
998} __packed; 1030} __packed;
999 1031
1000struct qlcnic_info { 1032struct qlcnic_info {
@@ -1010,6 +1042,23 @@ struct qlcnic_info {
1010 u16 max_rx_ques; 1042 u16 max_rx_ques;
1011 u16 min_tx_bw; 1043 u16 min_tx_bw;
1012 u16 max_tx_bw; 1044 u16 max_tx_bw;
1045 u32 op_type;
1046 u16 max_bw_reg_offset;
1047 u16 max_linkspeed_reg_offset;
1048 u32 capability1;
1049 u32 capability2;
1050 u32 capability3;
1051 u16 max_tx_mac_filters;
1052 u16 max_rx_mcast_mac_filters;
1053 u16 max_rx_ucast_mac_filters;
1054 u16 max_rx_ip_addr;
1055 u16 max_rx_lro_flow;
1056 u16 max_rx_status_rings;
1057 u16 max_rx_buf_rings;
1058 u16 max_tx_vlan_keys;
1059 u8 total_pf;
1060 u8 total_rss_engines;
1061 u16 max_vports;
1013}; 1062};
1014 1063
1015struct qlcnic_pci_info_le { 1064struct qlcnic_pci_info_le {
@@ -1023,7 +1072,9 @@ struct qlcnic_pci_info_le {
1023 __le16 reserved1[2]; 1072 __le16 reserved1[2];
1024 1073
1025 u8 mac[ETH_ALEN]; 1074 u8 mac[ETH_ALEN];
1026 u8 reserved2[106]; 1075 __le16 func_count;
1076 u8 reserved2[104];
1077
1027} __packed; 1078} __packed;
1028 1079
1029struct qlcnic_pci_info { 1080struct qlcnic_pci_info {
@@ -1034,6 +1085,7 @@ struct qlcnic_pci_info {
1034 u16 tx_min_bw; 1085 u16 tx_min_bw;
1035 u16 tx_max_bw; 1086 u16 tx_max_bw;
1036 u8 mac[ETH_ALEN]; 1087 u8 mac[ETH_ALEN];
1088 u16 func_count;
1037}; 1089};
1038 1090
1039struct qlcnic_npar_info { 1091struct qlcnic_npar_info {
@@ -1375,6 +1427,7 @@ netdev_tx_t qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
1375int qlcnic_set_max_rss(struct qlcnic_adapter *adapter, u8 data); 1427int qlcnic_set_max_rss(struct qlcnic_adapter *adapter, u8 data);
1376int qlcnic_validate_max_rss(struct net_device *netdev, u8, u8); 1428int qlcnic_validate_max_rss(struct net_device *netdev, u8, u8);
1377void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter); 1429void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter);
1430int qlcnic_enable_msix(struct qlcnic_adapter *, u32);
1378 1431
1379/* eSwitch management functions */ 1432/* eSwitch management functions */
1380int qlcnic_config_switch_port(struct qlcnic_adapter *, 1433int qlcnic_config_switch_port(struct qlcnic_adapter *,
@@ -1394,6 +1447,7 @@ void qlcnic_napi_del(struct qlcnic_adapter *);
1394 1447
1395int qlcnic_alloc_sds_rings(struct qlcnic_recv_context *, int); 1448int qlcnic_alloc_sds_rings(struct qlcnic_recv_context *, int);
1396void qlcnic_free_sds_rings(struct qlcnic_recv_context *); 1449void qlcnic_free_sds_rings(struct qlcnic_recv_context *);
1450void qlcnic_advert_link_change(struct qlcnic_adapter *, int);
1397void qlcnic_free_tx_rings(struct qlcnic_adapter *); 1451void qlcnic_free_tx_rings(struct qlcnic_adapter *);
1398int qlcnic_alloc_tx_rings(struct qlcnic_adapter *, struct net_device *); 1452int qlcnic_alloc_tx_rings(struct qlcnic_adapter *, struct net_device *);
1399 1453
@@ -1502,7 +1556,7 @@ static inline void qlcnic_write_crb(struct qlcnic_adapter *adapter, char *buf,
1502 adapter->ahw->hw_ops->write_crb(adapter, buf, offset, size); 1556 adapter->ahw->hw_ops->write_crb(adapter, buf, offset, size);
1503} 1557}
1504 1558
1505static inline u32 qlcnic_hw_read_wx_2M(struct qlcnic_adapter *adapter, 1559static inline int qlcnic_hw_read_wx_2M(struct qlcnic_adapter *adapter,
1506 ulong off) 1560 ulong off)
1507{ 1561{
1508 return adapter->ahw->hw_ops->read_reg(adapter, off); 1562 return adapter->ahw->hw_ops->read_reg(adapter, off);
@@ -1723,6 +1777,7 @@ extern const struct ethtool_ops qlcnic_ethtool_failed_ops;
1723 __func__, ##_args); \ 1777 __func__, ##_args); \
1724 } while (0) 1778 } while (0)
1725 1779
1780#define PCI_DEVICE_ID_QLOGIC_QLE834X 0x8030
1726#define PCI_DEVICE_ID_QLOGIC_QLE824X 0x8020 1781#define PCI_DEVICE_ID_QLOGIC_QLE824X 0x8020
1727static inline bool qlcnic_82xx_check(struct qlcnic_adapter *adapter) 1782static inline bool qlcnic_82xx_check(struct qlcnic_adapter *adapter)
1728{ 1783{
@@ -1730,4 +1785,11 @@ static inline bool qlcnic_82xx_check(struct qlcnic_adapter *adapter)
1730 return (device == PCI_DEVICE_ID_QLOGIC_QLE824X) ? true : false; 1785 return (device == PCI_DEVICE_ID_QLOGIC_QLE824X) ? true : false;
1731} 1786}
1732 1787
1788static inline bool qlcnic_83xx_check(struct qlcnic_adapter *adapter)
1789{
1790 unsigned short device = adapter->pdev->device;
1791 return (device == PCI_DEVICE_ID_QLOGIC_QLE834X) ? true : false;
1792}
1793
1794
1733#endif /* __QLCNIC_H_ */ 1795#endif /* __QLCNIC_H_ */
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
new file mode 100644
index 000000000000..454cd9f2e545
--- /dev/null
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -0,0 +1,1719 @@
1#include "qlcnic.h"
2#include <linux/if_vlan.h>
3#include <linux/ipv6.h>
4#include <linux/ethtool.h>
5#include <linux/interrupt.h>
6
7#define QLCNIC_MAX_TX_QUEUES 1
8
9#define QLCNIC_MBX_RSP(reg) LSW(reg)
10#define QLCNIC_MBX_NUM_REGS(reg) (MSW(reg) & 0x1FF)
11#define QLCNIC_MBX_STATUS(reg) (((reg) >> 25) & 0x7F)
12#define QLCNIC_MBX_HOST(ahw, i) ((ahw)->pci_base0 + ((i) * 4))
13#define QLCNIC_MBX_FW(ahw, i) ((ahw)->pci_base0 + 0x800 + ((i) * 4))
14
15#define RSS_HASHTYPE_IP_TCP 0x3
16
17/* status descriptor mailbox data
18 * @phy_addr: physical address of buffer
19 * @sds_ring_size: buffer size
20 * @intrpt_id: interrupt id
21 * @intrpt_val: source of interrupt
22 */
23struct qlcnic_sds_mbx {
24 u64 phy_addr;
25 u8 rsvd1[16];
26 u16 sds_ring_size;
27 u16 rsvd2[3];
28 u16 intrpt_id;
29 u8 intrpt_val;
30 u8 rsvd3[5];
31} __packed;
32
33/* receive descriptor buffer data
34 * phy_addr_reg: physical address of regular buffer
35 * phy_addr_jmb: physical address of jumbo buffer
36 * reg_ring_sz: size of regular buffer
37 * reg_ring_len: no. of entries in regular buffer
38 * jmb_ring_len: no. of entries in jumbo buffer
39 * jmb_ring_sz: size of jumbo buffer
40 */
41struct qlcnic_rds_mbx {
42 u64 phy_addr_reg;
43 u64 phy_addr_jmb;
44 u16 reg_ring_sz;
45 u16 reg_ring_len;
46 u16 jmb_ring_sz;
47 u16 jmb_ring_len;
48} __packed;
49
50/* host producers for regular and jumbo rings */
51struct __host_producer_mbx {
52 u32 reg_buf;
53 u32 jmb_buf;
54} __packed;
55
56/* Receive context mailbox data outbox registers
57 * @state: state of the context
58 * @vport_id: virtual port id
59 * @context_id: receive context id
60 * @num_pci_func: number of pci functions of the port
61 * @phy_port: physical port id
62 */
63struct qlcnic_rcv_mbx_out {
64 u8 rcv_num;
65 u8 sts_num;
66 u16 ctx_id;
67 u8 state;
68 u8 num_pci_func;
69 u8 phy_port;
70 u8 vport_id;
71 u32 host_csmr[QLCNIC_MAX_RING_SETS];
72 struct __host_producer_mbx host_prod[QLCNIC_MAX_RING_SETS];
73} __packed;
74
75struct qlcnic_add_rings_mbx_out {
76 u8 rcv_num;
77 u8 sts_num;
78 u16 ctx_id;
79 u32 host_csmr[QLCNIC_MAX_RING_SETS];
80 struct __host_producer_mbx host_prod[QLCNIC_MAX_RING_SETS];
81} __packed;
82
83/* Transmit context mailbox inbox registers
84 * @phys_addr: DMA address of the transmit buffer
85 * @cnsmr_index: host consumer index
86 * @size: legth of transmit buffer ring
87 * @intr_id: interrput id
88 * @src: src of interrupt
89 */
90struct qlcnic_tx_mbx {
91 u64 phys_addr;
92 u64 cnsmr_index;
93 u16 size;
94 u16 intr_id;
95 u8 src;
96 u8 rsvd[3];
97} __packed;
98
99/* Transmit context mailbox outbox registers
100 * @host_prod: host producer index
101 * @ctx_id: transmit context id
102 * @state: state of the transmit context
103 */
104struct qlcnic_tx_mbx_out {
105 u32 host_prod;
106 u16 ctx_id;
107 u8 state;
108 u8 rsvd;
109} __packed;
110
111static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = {
112 {QLCNIC_CMD_CONFIGURE_IP_ADDR, 6, 1},
113 {QLCNIC_CMD_CONFIG_INTRPT, 18, 34},
114 {QLCNIC_CMD_CREATE_RX_CTX, 136, 27},
115 {QLCNIC_CMD_DESTROY_RX_CTX, 2, 1},
116 {QLCNIC_CMD_CREATE_TX_CTX, 54, 18},
117 {QLCNIC_CMD_DESTROY_TX_CTX, 2, 1},
118 {QLCNIC_CMD_CONFIGURE_MAC_LEARNING, 2, 1},
119 {QLCNIC_CMD_INTRPT_TEST, 22, 12},
120 {QLCNIC_CMD_SET_MTU, 3, 1},
121 {QLCNIC_CMD_READ_PHY, 4, 2},
122 {QLCNIC_CMD_WRITE_PHY, 5, 1},
123 {QLCNIC_CMD_READ_HW_REG, 4, 1},
124 {QLCNIC_CMD_GET_FLOW_CTL, 4, 2},
125 {QLCNIC_CMD_SET_FLOW_CTL, 4, 1},
126 {QLCNIC_CMD_READ_MAX_MTU, 4, 2},
127 {QLCNIC_CMD_READ_MAX_LRO, 4, 2},
128 {QLCNIC_CMD_MAC_ADDRESS, 4, 3},
129 {QLCNIC_CMD_GET_PCI_INFO, 1, 66},
130 {QLCNIC_CMD_GET_NIC_INFO, 2, 19},
131 {QLCNIC_CMD_SET_NIC_INFO, 32, 1},
132 {QLCNIC_CMD_GET_ESWITCH_CAPABILITY, 4, 3},
133 {QLCNIC_CMD_TOGGLE_ESWITCH, 4, 1},
134 {QLCNIC_CMD_GET_ESWITCH_STATUS, 4, 3},
135 {QLCNIC_CMD_SET_PORTMIRRORING, 4, 1},
136 {QLCNIC_CMD_CONFIGURE_ESWITCH, 4, 1},
137 {QLCNIC_CMD_GET_ESWITCH_PORT_CONFIG, 4, 3},
138 {QLCNIC_CMD_GET_ESWITCH_STATS, 5, 1},
139 {QLCNIC_CMD_CONFIG_PORT, 4, 1},
140 {QLCNIC_CMD_TEMP_SIZE, 1, 4},
141 {QLCNIC_CMD_GET_TEMP_HDR, 5, 5},
142 {QLCNIC_CMD_GET_LINK_EVENT, 2, 1},
143 {QLCNIC_CMD_CONFIG_MAC_VLAN, 4, 3},
144 {QLCNIC_CMD_CONFIG_INTR_COAL, 6, 1},
145 {QLCNIC_CMD_CONFIGURE_RSS, 14, 1},
146 {QLCNIC_CMD_CONFIGURE_LED, 2, 1},
147 {QLCNIC_CMD_CONFIGURE_MAC_RX_MODE, 2, 1},
148 {QLCNIC_CMD_CONFIGURE_HW_LRO, 2, 1},
149 {QLCNIC_CMD_GET_STATISTICS, 2, 80},
150 {QLCNIC_CMD_SET_PORT_CONFIG, 2, 1},
151 {QLCNIC_CMD_GET_PORT_CONFIG, 2, 2},
152 {QLCNIC_CMD_GET_LINK_STATUS, 2, 4},
153 {QLCNIC_CMD_IDC_ACK, 5, 1},
154 {QLCNIC_CMD_INIT_NIC_FUNC, 2, 1},
155 {QLCNIC_CMD_STOP_NIC_FUNC, 2, 1},
156 {QLCNIC_CMD_SET_LED_CONFIG, 5, 1},
157 {QLCNIC_CMD_GET_LED_CONFIG, 1, 5},
158 {QLCNIC_CMD_ADD_RCV_RINGS, 130, 26},
159};
160
161static const u32 qlcnic_83xx_ext_reg_tbl[] = {
162 0x38CC, /* Global Reset */
163 0x38F0, /* Wildcard */
164 0x38FC, /* Informant */
165 0x3038, /* Host MBX ctrl */
166 0x303C, /* FW MBX ctrl */
167 0x355C, /* BOOT LOADER ADDRESS REG */
168 0x3560, /* BOOT LOADER SIZE REG */
169 0x3564, /* FW IMAGE ADDR REG */
170 0x1000, /* MBX intr enable */
171 0x1200, /* Default Intr mask */
172 0x1204, /* Default Interrupt ID */
173 0x3780, /* QLC_83XX_IDC_MAJ_VERSION */
174 0x3784, /* QLC_83XX_IDC_DEV_STATE */
175 0x3788, /* QLC_83XX_IDC_DRV_PRESENCE */
176 0x378C, /* QLC_83XX_IDC_DRV_ACK */
177 0x3790, /* QLC_83XX_IDC_CTRL */
178 0x3794, /* QLC_83XX_IDC_DRV_AUDIT */
179 0x3798, /* QLC_83XX_IDC_MIN_VERSION */
180 0x379C, /* QLC_83XX_RECOVER_DRV_LOCK */
181 0x37A0, /* QLC_83XX_IDC_PF_0 */
182 0x37A4, /* QLC_83XX_IDC_PF_1 */
183 0x37A8, /* QLC_83XX_IDC_PF_2 */
184 0x37AC, /* QLC_83XX_IDC_PF_3 */
185 0x37B0, /* QLC_83XX_IDC_PF_4 */
186 0x37B4, /* QLC_83XX_IDC_PF_5 */
187 0x37B8, /* QLC_83XX_IDC_PF_6 */
188 0x37BC, /* QLC_83XX_IDC_PF_7 */
189 0x37C0, /* QLC_83XX_IDC_PF_8 */
190 0x37C4, /* QLC_83XX_IDC_PF_9 */
191 0x37C8, /* QLC_83XX_IDC_PF_10 */
192 0x37CC, /* QLC_83XX_IDC_PF_11 */
193 0x37D0, /* QLC_83XX_IDC_PF_12 */
194 0x37D4, /* QLC_83XX_IDC_PF_13 */
195 0x37D8, /* QLC_83XX_IDC_PF_14 */
196 0x37DC, /* QLC_83XX_IDC_PF_15 */
197 0x37E0, /* QLC_83XX_IDC_DEV_PARTITION_INFO_1 */
198 0x37E4, /* QLC_83XX_IDC_DEV_PARTITION_INFO_2 */
199 0x37F0, /* QLC_83XX_DRV_OP_MODE */
200 0x37F4, /* QLC_83XX_VNIC_STATE */
201 0x3868, /* QLC_83XX_DRV_LOCK */
202 0x386C, /* QLC_83XX_DRV_UNLOCK */
203 0x3504, /* QLC_83XX_DRV_LOCK_ID */
204 0x34A4, /* QLC_83XX_ASIC_TEMP */
205};
206
207static const u32 qlcnic_83xx_reg_tbl[] = {
208 0x34A8, /* PEG_HALT_STAT1 */
209 0x34AC, /* PEG_HALT_STAT2 */
210 0x34B0, /* FW_HEARTBEAT */
211 0x3500, /* FLASH LOCK_ID */
212 0x3528, /* FW_CAPABILITIES */
213 0x3538, /* Driver active, DRV_REG0 */
214 0x3540, /* Device state, DRV_REG1 */
215 0x3544, /* Driver state, DRV_REG2 */
216 0x3548, /* Driver scratch, DRV_REG3 */
217 0x354C, /* Device partiton info, DRV_REG4 */
218 0x3524, /* Driver IDC ver, DRV_REG5 */
219 0x3550, /* FW_VER_MAJOR */
220 0x3554, /* FW_VER_MINOR */
221 0x3558, /* FW_VER_SUB */
222 0x359C, /* NPAR STATE */
223 0x35FC, /* FW_IMG_VALID */
224 0x3650, /* CMD_PEG_STATE */
225 0x373C, /* RCV_PEG_STATE */
226 0x37B4, /* ASIC TEMP */
227 0x356C, /* FW API */
228 0x3570, /* DRV OP MODE */
229 0x3850, /* FLASH LOCK */
230 0x3854, /* FLASH UNLOCK */
231};
232
233static struct qlcnic_hardware_ops qlcnic_83xx_hw_ops = {
234 .read_crb = qlcnic_83xx_read_crb,
235 .write_crb = qlcnic_83xx_write_crb,
236 .read_reg = qlcnic_83xx_rd_reg_indirect,
237 .write_reg = qlcnic_83xx_wrt_reg_indirect,
238 .get_mac_address = qlcnic_83xx_get_mac_address,
239 .setup_intr = qlcnic_83xx_setup_intr,
240 .alloc_mbx_args = qlcnic_83xx_alloc_mbx_args,
241 .mbx_cmd = qlcnic_83xx_mbx_op,
242 .get_func_no = qlcnic_83xx_get_func_no,
243 .api_lock = qlcnic_83xx_cam_lock,
244 .api_unlock = qlcnic_83xx_cam_unlock,
245 .create_rx_ctx = qlcnic_83xx_create_rx_ctx,
246 .create_tx_ctx = qlcnic_83xx_create_tx_ctx,
247 .setup_link_event = qlcnic_83xx_setup_link_event,
248 .get_nic_info = qlcnic_83xx_get_nic_info,
249 .get_pci_info = qlcnic_83xx_get_pci_info,
250 .set_nic_info = qlcnic_83xx_set_nic_info,
251 .change_macvlan = qlcnic_83xx_sre_macaddr_change,
252 .config_intr_coal = qlcnic_83xx_config_intr_coal,
253 .config_rss = qlcnic_83xx_config_rss,
254 .config_hw_lro = qlcnic_83xx_config_hw_lro,
255 .config_loopback = qlcnic_83xx_set_lb_mode,
256 .clear_loopback = qlcnic_83xx_clear_lb_mode,
257 .config_promisc_mode = qlcnic_83xx_nic_set_promisc,
258 .change_l2_filter = qlcnic_83xx_change_l2_filter,
259 .get_board_info = qlcnic_83xx_get_port_info,
260};
261
262static struct qlcnic_nic_template qlcnic_83xx_ops = {
263 .config_bridged_mode = qlcnic_config_bridged_mode,
264 .config_led = qlcnic_config_led,
265 .config_ipaddr = qlcnic_83xx_config_ipaddr,
266 .clear_legacy_intr = qlcnic_83xx_clear_legacy_intr,
267};
268
269void qlcnic_83xx_register_map(struct qlcnic_hardware_context *ahw)
270{
271 ahw->hw_ops = &qlcnic_83xx_hw_ops;
272 ahw->reg_tbl = (u32 *)qlcnic_83xx_reg_tbl;
273 ahw->ext_reg_tbl = (u32 *)qlcnic_83xx_ext_reg_tbl;
274}
275
276int qlcnic_83xx_get_fw_version(struct qlcnic_adapter *adapter)
277{
278 u32 fw_major, fw_minor, fw_build;
279 struct pci_dev *pdev = adapter->pdev;
280
281 fw_major = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MAJOR);
282 fw_minor = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MINOR);
283 fw_build = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_SUB);
284 adapter->fw_version = QLCNIC_VERSION_CODE(fw_major, fw_minor, fw_build);
285
286 dev_info(&pdev->dev, "Driver v%s, firmware version %d.%d.%d\n",
287 QLCNIC_LINUX_VERSIONID, fw_major, fw_minor, fw_build);
288
289 return adapter->fw_version;
290}
291
292static int __qlcnic_set_win_base(struct qlcnic_adapter *adapter, u32 addr)
293{
294 void __iomem *base;
295 u32 val;
296
297 base = adapter->ahw->pci_base0 +
298 QLC_83XX_CRB_WIN_FUNC(adapter->ahw->pci_func);
299 writel(addr, base);
300 val = readl(base);
301 if (val != addr)
302 return -EIO;
303
304 return 0;
305}
306
307int qlcnic_83xx_rd_reg_indirect(struct qlcnic_adapter *adapter, ulong addr)
308{
309 int ret;
310 struct qlcnic_hardware_context *ahw = adapter->ahw;
311
312 ret = __qlcnic_set_win_base(adapter, (u32) addr);
313 if (!ret) {
314 return QLCRDX(ahw, QLCNIC_WILDCARD);
315 } else {
316 dev_err(&adapter->pdev->dev,
317 "%s failed, addr = 0x%x\n", __func__, (int)addr);
318 return -EIO;
319 }
320}
321
322int qlcnic_83xx_wrt_reg_indirect(struct qlcnic_adapter *adapter, ulong addr,
323 u32 data)
324{
325 int err;
326 struct qlcnic_hardware_context *ahw = adapter->ahw;
327
328 err = __qlcnic_set_win_base(adapter, (u32) addr);
329 if (!err) {
330 QLCWRX(ahw, QLCNIC_WILDCARD, data);
331 return 0;
332 } else {
333 dev_err(&adapter->pdev->dev,
334 "%s failed, addr = 0x%x data = 0x%x\n",
335 __func__, (int)addr, data);
336 return err;
337 }
338}
339
340int qlcnic_83xx_setup_intr(struct qlcnic_adapter *adapter, u8 num_intr)
341{
342 int err, i, num_msix;
343 struct qlcnic_hardware_context *ahw = adapter->ahw;
344
345 if (!num_intr)
346 num_intr = QLCNIC_DEF_NUM_STS_DESC_RINGS;
347 num_msix = rounddown_pow_of_two(min_t(int, num_online_cpus(),
348 num_intr));
349 /* account for AEN interrupt MSI-X based interrupts */
350 num_msix += 1;
351 num_msix += adapter->max_drv_tx_rings;
352 err = qlcnic_enable_msix(adapter, num_msix);
353 if (err == -ENOMEM)
354 return err;
355 if (adapter->flags & QLCNIC_MSIX_ENABLED)
356 num_msix = adapter->ahw->num_msix;
357 else
358 num_msix = 1;
359 /* setup interrupt mapping table for fw */
360 ahw->intr_tbl = vzalloc(num_msix *
361 sizeof(struct qlcnic_intrpt_config));
362 if (!ahw->intr_tbl)
363 return -ENOMEM;
364 if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) {
365 /* MSI-X enablement failed, use legacy interrupt */
366 adapter->tgt_status_reg = ahw->pci_base0 + QLC_83XX_INTX_PTR;
367 adapter->tgt_mask_reg = ahw->pci_base0 + QLC_83XX_INTX_MASK;
368 adapter->isr_int_vec = ahw->pci_base0 + QLC_83XX_INTX_TRGR;
369 adapter->msix_entries[0].vector = adapter->pdev->irq;
370 dev_info(&adapter->pdev->dev, "using legacy interrupt\n");
371 }
372
373 for (i = 0; i < num_msix; i++) {
374 if (adapter->flags & QLCNIC_MSIX_ENABLED)
375 ahw->intr_tbl[i].type = QLCNIC_INTRPT_MSIX;
376 else
377 ahw->intr_tbl[i].type = QLCNIC_INTRPT_INTX;
378 ahw->intr_tbl[i].id = i;
379 ahw->intr_tbl[i].src = 0;
380 }
381 return 0;
382}
383
384inline void qlcnic_83xx_enable_intr(struct qlcnic_adapter *adapter,
385 struct qlcnic_host_sds_ring *sds_ring)
386{
387 writel(0, sds_ring->crb_intr_mask);
388 if (!QLCNIC_IS_MSI_FAMILY(adapter))
389 writel(0, adapter->tgt_mask_reg);
390}
391
392static inline void qlcnic_83xx_get_mbx_data(struct qlcnic_adapter *adapter,
393 struct qlcnic_cmd_args *cmd)
394{
395 int i;
396 for (i = 0; i < cmd->rsp.num; i++)
397 cmd->rsp.arg[i] = readl(QLCNIC_MBX_FW(adapter->ahw, i));
398}
399
400irqreturn_t qlcnic_83xx_clear_legacy_intr(struct qlcnic_adapter *adapter)
401{
402 u32 intr_val;
403 struct qlcnic_hardware_context *ahw = adapter->ahw;
404 int retries = 0;
405
406 intr_val = readl(adapter->tgt_status_reg);
407
408 if (!QLC_83XX_VALID_INTX_BIT31(intr_val))
409 return IRQ_NONE;
410
411 if (QLC_83XX_INTX_FUNC(intr_val) != adapter->ahw->pci_func) {
412 adapter->stats.spurious_intr++;
413 return IRQ_NONE;
414 }
415 /* clear the interrupt trigger control register */
416 writel(0, adapter->isr_int_vec);
417 do {
418 intr_val = readl(adapter->tgt_status_reg);
419 if (QLC_83XX_INTX_FUNC(intr_val) != ahw->pci_func)
420 break;
421 retries++;
422 } while (QLC_83XX_VALID_INTX_BIT30(intr_val) &&
423 (retries < QLC_83XX_LEGACY_INTX_MAX_RETRY));
424
425 if (retries == QLC_83XX_LEGACY_INTX_MAX_RETRY) {
426 dev_info(&adapter->pdev->dev,
427 "Reached maximum retries to clear legacy interrupt\n");
428 return IRQ_NONE;
429 }
430
431 mdelay(QLC_83XX_LEGACY_INTX_DELAY);
432
433 return IRQ_HANDLED;
434}
435
436irqreturn_t qlcnic_83xx_tmp_intr(int irq, void *data)
437{
438 struct qlcnic_host_sds_ring *sds_ring = data;
439 struct qlcnic_adapter *adapter = sds_ring->adapter;
440
441 if (adapter->flags & QLCNIC_MSIX_ENABLED)
442 goto done;
443
444 if (adapter->nic_ops->clear_legacy_intr(adapter) == IRQ_NONE)
445 return IRQ_NONE;
446
447done:
448 adapter->ahw->diag_cnt++;
449 qlcnic_83xx_enable_intr(adapter, sds_ring);
450
451 return IRQ_HANDLED;
452}
453
454void qlcnic_83xx_free_mbx_intr(struct qlcnic_adapter *adapter)
455{
456 u32 val = 0;
457 u32 num_msix = adapter->ahw->num_msix - 1;
458
459 val = (num_msix << 8);
460
461 QLCWRX(adapter->ahw, QLCNIC_MBX_INTR_ENBL, val);
462 if (adapter->flags & QLCNIC_MSIX_ENABLED)
463 free_irq(adapter->msix_entries[num_msix].vector, adapter);
464}
465
466int qlcnic_83xx_setup_mbx_intr(struct qlcnic_adapter *adapter)
467{
468 irq_handler_t handler;
469 u32 val;
470 char name[32];
471 int err = 0;
472 unsigned long flags = 0;
473
474 if (!(adapter->flags & QLCNIC_MSI_ENABLED) &&
475 !(adapter->flags & QLCNIC_MSIX_ENABLED))
476 flags |= IRQF_SHARED;
477
478 if (adapter->flags & QLCNIC_MSIX_ENABLED) {
479 handler = qlcnic_83xx_handle_aen;
480 val = adapter->msix_entries[adapter->ahw->num_msix - 1].vector;
481 snprintf(name, (IFNAMSIZ + 4),
482 "%s[%s]", adapter->netdev->name, "aen");
483 err = request_irq(val, handler, flags, name, adapter);
484 if (err) {
485 dev_err(&adapter->pdev->dev,
486 "failed to register MBX interrupt\n");
487 return err;
488 }
489 }
490
491 /* Enable mailbox interrupt */
492 qlcnic_83xx_enable_mbx_intrpt(adapter);
493 if (adapter->flags & QLCNIC_MSIX_ENABLED)
494 err = qlcnic_83xx_config_intrpt(adapter, 1);
495
496 return err;
497}
498
499void qlcnic_83xx_get_func_no(struct qlcnic_adapter *adapter)
500{
501 u32 val = QLCRDX(adapter->ahw, QLCNIC_INFORMANT);
502 adapter->ahw->pci_func = val & 0xf;
503}
504
505int qlcnic_83xx_cam_lock(struct qlcnic_adapter *adapter)
506{
507 void __iomem *addr;
508 u32 val, limit = 0;
509
510 struct qlcnic_hardware_context *ahw = adapter->ahw;
511
512 addr = ahw->pci_base0 + QLC_83XX_SEM_LOCK_FUNC(ahw->pci_func);
513 do {
514 val = readl(addr);
515 if (val) {
516 /* write the function number to register */
517 QLC_SHARED_REG_WR32(adapter, QLCNIC_FLASH_LOCK_OWNER,
518 ahw->pci_func);
519 return 0;
520 }
521 usleep_range(1000, 2000);
522 } while (++limit <= QLCNIC_PCIE_SEM_TIMEOUT);
523
524 return -EIO;
525}
526
527void qlcnic_83xx_cam_unlock(struct qlcnic_adapter *adapter)
528{
529 void __iomem *addr;
530 u32 val;
531 struct qlcnic_hardware_context *ahw = adapter->ahw;
532
533 addr = ahw->pci_base0 + QLC_83XX_SEM_UNLOCK_FUNC(ahw->pci_func);
534 val = readl(addr);
535}
536
537void qlcnic_83xx_read_crb(struct qlcnic_adapter *adapter, char *buf,
538 loff_t offset, size_t size)
539{
540 int ret;
541 u32 data;
542
543 if (qlcnic_api_lock(adapter)) {
544 dev_err(&adapter->pdev->dev,
545 "%s: failed to acquire lock. addr offset 0x%x\n",
546 __func__, (u32)offset);
547 return;
548 }
549
550 ret = qlcnic_83xx_rd_reg_indirect(adapter, (u32) offset);
551 qlcnic_api_unlock(adapter);
552
553 if (ret == -EIO) {
554 dev_err(&adapter->pdev->dev,
555 "%s: failed. addr offset 0x%x\n",
556 __func__, (u32)offset);
557 return;
558 }
559 data = ret;
560 memcpy(buf, &data, size);
561}
562
563void qlcnic_83xx_write_crb(struct qlcnic_adapter *adapter, char *buf,
564 loff_t offset, size_t size)
565{
566 u32 data;
567
568 memcpy(&data, buf, size);
569 qlcnic_83xx_wrt_reg_indirect(adapter, (u32) offset, data);
570}
571
572int qlcnic_83xx_get_port_info(struct qlcnic_adapter *adapter)
573{
574 int status;
575
576 status = qlcnic_83xx_get_port_config(adapter);
577 if (status) {
578 dev_err(&adapter->pdev->dev,
579 "Get Port Info failed\n");
580 } else {
581 if (QLC_83XX_SFP_10G_CAPABLE(adapter->ahw->port_config))
582 adapter->ahw->port_type = QLCNIC_XGBE;
583 else
584 adapter->ahw->port_type = QLCNIC_GBE;
585 if (QLC_83XX_AUTONEG(adapter->ahw->port_config))
586 adapter->ahw->link_autoneg = AUTONEG_ENABLE;
587 }
588 return status;
589}
590
591void qlcnic_83xx_enable_mbx_intrpt(struct qlcnic_adapter *adapter)
592{
593 u32 val;
594
595 if (adapter->flags & QLCNIC_MSIX_ENABLED)
596 val = BIT_2 | ((adapter->ahw->num_msix - 1) << 8);
597 else
598 val = BIT_2;
599 QLCWRX(adapter->ahw, QLCNIC_MBX_INTR_ENBL, val);
600}
601
602void qlcnic_83xx_check_vf(struct qlcnic_adapter *adapter,
603 const struct pci_device_id *ent)
604{
605 u32 op_mode, priv_level;
606 struct qlcnic_hardware_context *ahw = adapter->ahw;
607
608 /* Determine FW API version */
609 ahw->fw_hal_version = 2;
610 /* Find PCI function number */
611 qlcnic_get_func_no(adapter);
612
613 /* Determine function privilege level */
614 op_mode = QLCRDX(adapter->ahw, QLC_83XX_DRV_OP_MODE);
615 if (op_mode == QLC_83XX_DEFAULT_OPMODE)
616 priv_level = QLCNIC_MGMT_FUNC;
617 else
618 priv_level = QLC_83XX_GET_FUNC_PRIVILEGE(op_mode,
619 ahw->pci_func);
620
621 if (priv_level == QLCNIC_NON_PRIV_FUNC) {
622 ahw->op_mode = QLCNIC_NON_PRIV_FUNC;
623 dev_info(&adapter->pdev->dev,
624 "HAL Version: %d Non Privileged function\n",
625 ahw->fw_hal_version);
626 adapter->nic_ops = &qlcnic_vf_ops;
627 } else {
628 adapter->nic_ops = &qlcnic_83xx_ops;
629 }
630}
631
632static void qlcnic_83xx_handle_link_aen(struct qlcnic_adapter *adapter,
633 u32 data[]);
634static void qlcnic_83xx_handle_idc_comp_aen(struct qlcnic_adapter *adapter,
635 u32 data[]);
636
637static void qlcnic_dump_mbx(struct qlcnic_adapter *adapter,
638 struct qlcnic_cmd_args *cmd)
639{
640 int i;
641
642 dev_info(&adapter->pdev->dev,
643 "Host MBX regs(%d)\n", cmd->req.num);
644 for (i = 0; i < cmd->req.num; i++) {
645 if (i && !(i % 8))
646 pr_info("\n");
647 pr_info("%08x ", cmd->req.arg[i]);
648 }
649 pr_info("\n");
650 dev_info(&adapter->pdev->dev,
651 "FW MBX regs(%d)\n", cmd->rsp.num);
652 for (i = 0; i < cmd->rsp.num; i++) {
653 if (i && !(i % 8))
654 pr_info("\n");
655 pr_info("%08x ", cmd->rsp.arg[i]);
656 }
657 pr_info("\n");
658}
659
660static u32 qlcnic_83xx_mbx_poll(struct qlcnic_adapter *adapter)
661{
662 u32 data;
663 unsigned long wait_time = 0;
664 struct qlcnic_hardware_context *ahw = adapter->ahw;
665 /* wait for mailbox completion */
666 do {
667 data = QLCRDX(ahw, QLCNIC_FW_MBX_CTRL);
668 if (++wait_time > QLCNIC_MBX_TIMEOUT) {
669 data = QLCNIC_RCODE_TIMEOUT;
670 break;
671 }
672 mdelay(1);
673 } while (!data);
674 return data;
675}
676
677int qlcnic_83xx_mbx_op(struct qlcnic_adapter *adapter,
678 struct qlcnic_cmd_args *cmd)
679{
680 int i;
681 u16 opcode;
682 u8 mbx_err_code, mac_cmd_rcode;
683 u32 rsp, mbx_val, fw_data, rsp_num, mbx_cmd, temp, fw[8];
684 struct qlcnic_hardware_context *ahw = adapter->ahw;
685
686 opcode = LSW(cmd->req.arg[0]);
687 spin_lock(&ahw->mbx_lock);
688 mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL);
689
690 if (mbx_val) {
691 QLCDB(adapter, DRV,
692 "Mailbox cmd attempted, 0x%x\n", opcode);
693 QLCDB(adapter, DRV,
694 "Mailbox not available, 0x%x, collect FW dump\n",
695 mbx_val);
696 cmd->rsp.arg[0] = QLCNIC_RCODE_TIMEOUT;
697 spin_unlock(&ahw->mbx_lock);
698 return cmd->rsp.arg[0];
699 }
700
701 /* Fill in mailbox registers */
702 mbx_cmd = cmd->req.arg[0];
703 writel(mbx_cmd, QLCNIC_MBX_HOST(ahw, 0));
704 for (i = 1; i < cmd->req.num; i++)
705 writel(cmd->req.arg[i], QLCNIC_MBX_HOST(ahw, i));
706
707 /* Signal FW about the impending command */
708 QLCWRX(ahw, QLCNIC_HOST_MBX_CTRL, QLCNIC_SET_OWNER);
709poll:
710 rsp = qlcnic_83xx_mbx_poll(adapter);
711 /* Get the FW response data */
712 fw_data = readl(QLCNIC_MBX_FW(ahw, 0));
713 mbx_err_code = QLCNIC_MBX_STATUS(fw_data);
714 rsp_num = QLCNIC_MBX_NUM_REGS(fw_data);
715 opcode = QLCNIC_MBX_RSP(fw_data);
716
717 if (rsp != QLCNIC_RCODE_TIMEOUT) {
718 if (opcode == QLCNIC_MBX_LINK_EVENT) {
719 for (i = 0; i < rsp_num; i++) {
720 temp = readl(QLCNIC_MBX_FW(ahw, i));
721 fw[i] = temp;
722 }
723 qlcnic_83xx_handle_link_aen(adapter, fw);
724 /* clear fw mbx control register */
725 QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
726 mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL);
727 if (mbx_val)
728 goto poll;
729 } else if (opcode == QLCNIC_MBX_COMP_EVENT) {
730 for (i = 0; i < rsp_num; i++) {
731 temp = readl(QLCNIC_MBX_FW(ahw, i));
732 fw[i] = temp;
733 }
734 qlcnic_83xx_handle_idc_comp_aen(adapter, fw);
735 /* clear fw mbx control register */
736 QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
737 mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL);
738 if (mbx_val)
739 goto poll;
740 } else if (opcode == QLCNIC_MBX_REQUEST_EVENT) {
741 /* IDC Request Notification */
742 for (i = 0; i < rsp_num; i++) {
743 temp = readl(QLCNIC_MBX_FW(ahw, i));
744 fw[i] = temp;
745 }
746 for (i = 0; i < QLC_83XX_MBX_AEN_CNT; i++) {
747 temp = QLCNIC_MBX_RSP(fw[i]);
748 adapter->ahw->mbox_aen[i] = temp;
749 }
750 queue_delayed_work(adapter->qlcnic_wq,
751 &adapter->idc_aen_work, 0);
752 /* clear fw mbx control register */
753 QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
754 mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL);
755 if (mbx_val)
756 goto poll;
757 } else if ((mbx_err_code == QLCNIC_MBX_RSP_OK) ||
758 (mbx_err_code == QLCNIC_MBX_PORT_RSP_OK)) {
759 qlcnic_83xx_get_mbx_data(adapter, cmd);
760 rsp = QLCNIC_RCODE_SUCCESS;
761 } else {
762 qlcnic_83xx_get_mbx_data(adapter, cmd);
763 if (opcode == QLCNIC_CMD_CONFIG_MAC_VLAN) {
764 fw_data = readl(QLCNIC_MBX_FW(ahw, 2));
765 mac_cmd_rcode = (u8)fw_data;
766 if (mac_cmd_rcode == QLC_83XX_NO_NIC_RESOURCE ||
767 mac_cmd_rcode == QLC_83XX_MAC_PRESENT ||
768 mac_cmd_rcode == QLC_83XX_MAC_ABSENT) {
769 rsp = QLCNIC_RCODE_SUCCESS;
770 goto out;
771 }
772 }
773 dev_info(&adapter->pdev->dev,
774 "MBX command 0x%x failed with err:0x%x\n",
775 opcode, mbx_err_code);
776 rsp = mbx_err_code;
777 qlcnic_dump_mbx(adapter, cmd);
778 }
779 } else {
780 dev_info(&adapter->pdev->dev,
781 "MBX command 0x%x timed out\n", opcode);
782 qlcnic_dump_mbx(adapter, cmd);
783 }
784out:
785 /* clear fw mbx control register */
786 QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
787 spin_unlock(&ahw->mbx_lock);
788 return rsp;
789}
790
791int qlcnic_83xx_alloc_mbx_args(struct qlcnic_cmd_args *mbx,
792 struct qlcnic_adapter *adapter, u32 type)
793{
794 int i, size;
795 u32 temp;
796 const struct qlcnic_mailbox_metadata *mbx_tbl;
797
798 mbx_tbl = qlcnic_83xx_mbx_tbl;
799 size = ARRAY_SIZE(qlcnic_83xx_mbx_tbl);
800 for (i = 0; i < size; i++) {
801 if (type == mbx_tbl[i].cmd) {
802 mbx->req.num = mbx_tbl[i].in_args;
803 mbx->rsp.num = mbx_tbl[i].out_args;
804 mbx->req.arg = kcalloc(mbx->req.num, sizeof(u32),
805 GFP_ATOMIC);
806 if (!mbx->req.arg)
807 return -ENOMEM;
808 mbx->rsp.arg = kcalloc(mbx->rsp.num, sizeof(u32),
809 GFP_ATOMIC);
810 if (!mbx->rsp.arg) {
811 kfree(mbx->req.arg);
812 mbx->req.arg = NULL;
813 return -ENOMEM;
814 }
815 memset(mbx->req.arg, 0, sizeof(u32) * mbx->req.num);
816 memset(mbx->rsp.arg, 0, sizeof(u32) * mbx->rsp.num);
817 temp = adapter->ahw->fw_hal_version << 29;
818 mbx->req.arg[0] = (type | (mbx->req.num << 16) | temp);
819 break;
820 }
821 }
822 return 0;
823}
824
825void qlcnic_83xx_idc_aen_work(struct work_struct *work)
826{
827 struct qlcnic_adapter *adapter;
828 struct qlcnic_cmd_args cmd;
829 int i, err = 0;
830
831 adapter = container_of(work, struct qlcnic_adapter, idc_aen_work.work);
832 qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_IDC_ACK);
833
834 for (i = 1; i < QLC_83XX_MBX_AEN_CNT; i++)
835 cmd.req.arg[i] = adapter->ahw->mbox_aen[i];
836
837 err = qlcnic_issue_cmd(adapter, &cmd);
838 if (err)
839 dev_info(&adapter->pdev->dev,
840 "%s: Mailbox IDC ACK failed.\n", __func__);
841 qlcnic_free_mbx_args(&cmd);
842}
843
844static void qlcnic_83xx_handle_idc_comp_aen(struct qlcnic_adapter *adapter,
845 u32 data[])
846{
847 dev_dbg(&adapter->pdev->dev, "Completion AEN:0x%x.\n",
848 QLCNIC_MBX_RSP(data[0]));
849 return;
850}
851
852void qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
853{
854 u32 mask, resp, event[QLC_83XX_MBX_AEN_CNT];
855 int i;
856 struct qlcnic_hardware_context *ahw = adapter->ahw;
857
858 if (!spin_trylock(&ahw->mbx_lock)) {
859 mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
860 writel(0, adapter->ahw->pci_base0 + mask);
861 return;
862 }
863 resp = QLCRDX(ahw, QLCNIC_FW_MBX_CTRL);
864
865 if (!(resp & QLCNIC_SET_OWNER))
866 goto out;
867
868 for (i = 0; i < QLC_83XX_MBX_AEN_CNT; i++)
869 event[i] = readl(QLCNIC_MBX_FW(ahw, i));
870
871 switch (QLCNIC_MBX_RSP(event[0])) {
872
873 case QLCNIC_MBX_LINK_EVENT:
874 qlcnic_83xx_handle_link_aen(adapter, event);
875 break;
876 case QLCNIC_MBX_COMP_EVENT:
877 qlcnic_83xx_handle_idc_comp_aen(adapter, event);
878 break;
879 case QLCNIC_MBX_REQUEST_EVENT:
880 for (i = 0; i < QLC_83XX_MBX_AEN_CNT; i++)
881 adapter->ahw->mbox_aen[i] = QLCNIC_MBX_RSP(event[i]);
882 queue_delayed_work(adapter->qlcnic_wq,
883 &adapter->idc_aen_work, 0);
884 break;
885 case QLCNIC_MBX_TIME_EXTEND_EVENT:
886 break;
887 case QLCNIC_MBX_SFP_INSERT_EVENT:
888 dev_info(&adapter->pdev->dev, "SFP+ Insert AEN:0x%x.\n",
889 QLCNIC_MBX_RSP(event[0]));
890 break;
891 case QLCNIC_MBX_SFP_REMOVE_EVENT:
892 dev_info(&adapter->pdev->dev, "SFP Removed AEN:0x%x.\n",
893 QLCNIC_MBX_RSP(event[0]));
894 break;
895 default:
896 dev_dbg(&adapter->pdev->dev, "Unsupported AEN:0x%x.\n",
897 QLCNIC_MBX_RSP(event[0]));
898 break;
899 }
900
901 QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
902out:
903 mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
904 writel(0, adapter->ahw->pci_base0 + mask);
905 spin_unlock(&ahw->mbx_lock);
906}
907
908static int qlcnic_83xx_add_rings(struct qlcnic_adapter *adapter)
909{
910 int index, i, err, sds_mbx_size;
911 u32 *buf, intrpt_id, intr_mask;
912 u16 context_id;
913 u8 num_sds;
914 struct qlcnic_cmd_args cmd;
915 struct qlcnic_host_sds_ring *sds;
916 struct qlcnic_sds_mbx sds_mbx;
917 struct qlcnic_add_rings_mbx_out *mbx_out;
918 struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
919 struct qlcnic_hardware_context *ahw = adapter->ahw;
920
921 sds_mbx_size = sizeof(struct qlcnic_sds_mbx);
922 context_id = recv_ctx->context_id;
923 num_sds = (adapter->max_sds_rings - QLCNIC_MAX_RING_SETS);
924 ahw->hw_ops->alloc_mbx_args(&cmd, adapter,
925 QLCNIC_CMD_ADD_RCV_RINGS);
926 cmd.req.arg[1] = 0 | (num_sds << 8) | (context_id << 16);
927
928 /* set up status rings, mbx 2-81 */
929 index = 2;
930 for (i = 8; i < adapter->max_sds_rings; i++) {
931 memset(&sds_mbx, 0, sds_mbx_size);
932 sds = &recv_ctx->sds_rings[i];
933 sds->consumer = 0;
934 memset(sds->desc_head, 0, STATUS_DESC_RINGSIZE(sds));
935 sds_mbx.phy_addr = sds->phys_addr;
936 sds_mbx.sds_ring_size = sds->num_desc;
937
938 if (adapter->flags & QLCNIC_MSIX_ENABLED)
939 intrpt_id = ahw->intr_tbl[i].id;
940 else
941 intrpt_id = QLCRDX(ahw, QLCNIC_DEF_INT_ID);
942
943 if (adapter->ahw->diag_test != QLCNIC_LOOPBACK_TEST)
944 sds_mbx.intrpt_id = intrpt_id;
945 else
946 sds_mbx.intrpt_id = 0xffff;
947 sds_mbx.intrpt_val = 0;
948 buf = &cmd.req.arg[index];
949 memcpy(buf, &sds_mbx, sds_mbx_size);
950 index += sds_mbx_size / sizeof(u32);
951 }
952
953 /* send the mailbox command */
954 err = ahw->hw_ops->mbx_cmd(adapter, &cmd);
955 if (err) {
956 dev_err(&adapter->pdev->dev,
957 "Failed to add rings %d\n", err);
958 goto out;
959 }
960
961 mbx_out = (struct qlcnic_add_rings_mbx_out *)&cmd.rsp.arg[1];
962 index = 0;
963 /* status descriptor ring */
964 for (i = 8; i < adapter->max_sds_rings; i++) {
965 sds = &recv_ctx->sds_rings[i];
966 sds->crb_sts_consumer = ahw->pci_base0 +
967 mbx_out->host_csmr[index];
968 if (adapter->flags & QLCNIC_MSIX_ENABLED)
969 intr_mask = ahw->intr_tbl[i].src;
970 else
971 intr_mask = QLCRDX(ahw, QLCNIC_DEF_INT_MASK);
972
973 sds->crb_intr_mask = ahw->pci_base0 + intr_mask;
974 index++;
975 }
976out:
977 qlcnic_free_mbx_args(&cmd);
978 return err;
979}
980
981int qlcnic_83xx_create_rx_ctx(struct qlcnic_adapter *adapter)
982{
983 int i, err, index, sds_mbx_size, rds_mbx_size;
984 u8 num_sds, num_rds;
985 u32 *buf, intrpt_id, intr_mask, cap = 0;
986 struct qlcnic_host_sds_ring *sds;
987 struct qlcnic_host_rds_ring *rds;
988 struct qlcnic_sds_mbx sds_mbx;
989 struct qlcnic_rds_mbx rds_mbx;
990 struct qlcnic_cmd_args cmd;
991 struct qlcnic_rcv_mbx_out *mbx_out;
992 struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
993 struct qlcnic_hardware_context *ahw = adapter->ahw;
994 num_rds = adapter->max_rds_rings;
995
996 if (adapter->max_sds_rings <= QLCNIC_MAX_RING_SETS)
997 num_sds = adapter->max_sds_rings;
998 else
999 num_sds = QLCNIC_MAX_RING_SETS;
1000
1001 sds_mbx_size = sizeof(struct qlcnic_sds_mbx);
1002 rds_mbx_size = sizeof(struct qlcnic_rds_mbx);
1003 cap = QLCNIC_CAP0_LEGACY_CONTEXT;
1004
1005 if (adapter->flags & QLCNIC_FW_LRO_MSS_CAP)
1006 cap |= QLC_83XX_FW_CAP_LRO_MSS;
1007
1008 /* set mailbox hdr and capabilities */
1009 qlcnic_alloc_mbx_args(&cmd, adapter,
1010 QLCNIC_CMD_CREATE_RX_CTX);
1011 cmd.req.arg[1] = cap;
1012 cmd.req.arg[5] = 1 | (num_rds << 5) | (num_sds << 8) |
1013 (QLC_83XX_HOST_RDS_MODE_UNIQUE << 16);
1014 /* set up status rings, mbx 8-57/87 */
1015 index = QLC_83XX_HOST_SDS_MBX_IDX;
1016 for (i = 0; i < num_sds; i++) {
1017 memset(&sds_mbx, 0, sds_mbx_size);
1018 sds = &recv_ctx->sds_rings[i];
1019 sds->consumer = 0;
1020 memset(sds->desc_head, 0, STATUS_DESC_RINGSIZE(sds));
1021 sds_mbx.phy_addr = sds->phys_addr;
1022 sds_mbx.sds_ring_size = sds->num_desc;
1023 if (adapter->flags & QLCNIC_MSIX_ENABLED)
1024 intrpt_id = ahw->intr_tbl[i].id;
1025 else
1026 intrpt_id = QLCRDX(ahw, QLCNIC_DEF_INT_ID);
1027 if (adapter->ahw->diag_test != QLCNIC_LOOPBACK_TEST)
1028 sds_mbx.intrpt_id = intrpt_id;
1029 else
1030 sds_mbx.intrpt_id = 0xffff;
1031 sds_mbx.intrpt_val = 0;
1032 buf = &cmd.req.arg[index];
1033 memcpy(buf, &sds_mbx, sds_mbx_size);
1034 index += sds_mbx_size / sizeof(u32);
1035 }
1036 /* set up receive rings, mbx 88-111/135 */
1037 index = QLCNIC_HOST_RDS_MBX_IDX;
1038 rds = &recv_ctx->rds_rings[0];
1039 rds->producer = 0;
1040 memset(&rds_mbx, 0, rds_mbx_size);
1041 rds_mbx.phy_addr_reg = rds->phys_addr;
1042 rds_mbx.reg_ring_sz = rds->dma_size;
1043 rds_mbx.reg_ring_len = rds->num_desc;
1044 /* Jumbo ring */
1045 rds = &recv_ctx->rds_rings[1];
1046 rds->producer = 0;
1047 rds_mbx.phy_addr_jmb = rds->phys_addr;
1048 rds_mbx.jmb_ring_sz = rds->dma_size;
1049 rds_mbx.jmb_ring_len = rds->num_desc;
1050 buf = &cmd.req.arg[index];
1051 memcpy(buf, &rds_mbx, rds_mbx_size);
1052
1053 /* send the mailbox command */
1054 err = ahw->hw_ops->mbx_cmd(adapter, &cmd);
1055 if (err) {
1056 dev_err(&adapter->pdev->dev,
1057 "Failed to create Rx ctx in firmware%d\n", err);
1058 goto out;
1059 }
1060 mbx_out = (struct qlcnic_rcv_mbx_out *)&cmd.rsp.arg[1];
1061 recv_ctx->context_id = mbx_out->ctx_id;
1062 recv_ctx->state = mbx_out->state;
1063 recv_ctx->virt_port = mbx_out->vport_id;
1064 dev_info(&adapter->pdev->dev, "Rx Context[%d] Created, state:0x%x\n",
1065 recv_ctx->context_id, recv_ctx->state);
1066 /* Receive descriptor ring */
1067 /* Standard ring */
1068 rds = &recv_ctx->rds_rings[0];
1069 rds->crb_rcv_producer = ahw->pci_base0 +
1070 mbx_out->host_prod[0].reg_buf;
1071 /* Jumbo ring */
1072 rds = &recv_ctx->rds_rings[1];
1073 rds->crb_rcv_producer = ahw->pci_base0 +
1074 mbx_out->host_prod[0].jmb_buf;
1075 /* status descriptor ring */
1076 for (i = 0; i < num_sds; i++) {
1077 sds = &recv_ctx->sds_rings[i];
1078 sds->crb_sts_consumer = ahw->pci_base0 +
1079 mbx_out->host_csmr[i];
1080 if (adapter->flags & QLCNIC_MSIX_ENABLED)
1081 intr_mask = ahw->intr_tbl[i].src;
1082 else
1083 intr_mask = QLCRDX(ahw, QLCNIC_DEF_INT_MASK);
1084 sds->crb_intr_mask = ahw->pci_base0 + intr_mask;
1085 }
1086
1087 if (adapter->max_sds_rings > QLCNIC_MAX_RING_SETS)
1088 err = qlcnic_83xx_add_rings(adapter);
1089out:
1090 qlcnic_free_mbx_args(&cmd);
1091 return err;
1092}
1093
1094int qlcnic_83xx_create_tx_ctx(struct qlcnic_adapter *adapter,
1095 struct qlcnic_host_tx_ring *tx, int ring)
1096{
1097 int err;
1098 u16 msix_id;
1099 u32 *buf, intr_mask;
1100 struct qlcnic_cmd_args cmd;
1101 struct qlcnic_tx_mbx mbx;
1102 struct qlcnic_tx_mbx_out *mbx_out;
1103 struct qlcnic_hardware_context *ahw = adapter->ahw;
1104
1105 /* Reset host resources */
1106 tx->producer = 0;
1107 tx->sw_consumer = 0;
1108 *(tx->hw_consumer) = 0;
1109
1110 memset(&mbx, 0, sizeof(struct qlcnic_tx_mbx));
1111
1112 /* setup mailbox inbox registerss */
1113 mbx.phys_addr = tx->phys_addr;
1114 mbx.cnsmr_index = tx->hw_cons_phys_addr;
1115 mbx.size = tx->num_desc;
1116 if (adapter->flags & QLCNIC_MSIX_ENABLED)
1117 msix_id = ahw->intr_tbl[adapter->max_sds_rings + ring].id;
1118 else
1119 msix_id = QLCRDX(ahw, QLCNIC_DEF_INT_ID);
1120 if (adapter->ahw->diag_test != QLCNIC_LOOPBACK_TEST)
1121 mbx.intr_id = msix_id;
1122 else
1123 mbx.intr_id = 0xffff;
1124 mbx.src = 0;
1125
1126 qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CREATE_TX_CTX);
1127 cmd.req.arg[1] = QLCNIC_CAP0_LEGACY_CONTEXT;
1128 cmd.req.arg[5] = QLCNIC_MAX_TX_QUEUES;
1129 buf = &cmd.req.arg[6];
1130 memcpy(buf, &mbx, sizeof(struct qlcnic_tx_mbx));
1131 /* send the mailbox command*/
1132 err = qlcnic_issue_cmd(adapter, &cmd);
1133 if (err) {
1134 dev_err(&adapter->pdev->dev,
1135 "Failed to create Tx ctx in firmware 0x%x\n", err);
1136 goto out;
1137 }
1138 mbx_out = (struct qlcnic_tx_mbx_out *)&cmd.rsp.arg[2];
1139 tx->crb_cmd_producer = ahw->pci_base0 + mbx_out->host_prod;
1140 tx->ctx_id = mbx_out->ctx_id;
1141 if (adapter->flags & QLCNIC_MSIX_ENABLED) {
1142 intr_mask = ahw->intr_tbl[adapter->max_sds_rings + ring].src;
1143 tx->crb_intr_mask = ahw->pci_base0 + intr_mask;
1144 }
1145 dev_info(&adapter->pdev->dev, "Tx Context[0x%x] Created, state:0x%x\n",
1146 tx->ctx_id, mbx_out->state);
1147out:
1148 qlcnic_free_mbx_args(&cmd);
1149 return err;
1150}
1151
1152void qlcnic_83xx_register_nic_idc_func(struct qlcnic_adapter *adapter,
1153 int enable)
1154{
1155 struct qlcnic_cmd_args cmd;
1156 int status;
1157
1158 if (enable) {
1159 qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_INIT_NIC_FUNC);
1160 cmd.req.arg[1] = 1 | BIT_0;
1161 } else {
1162 qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_STOP_NIC_FUNC);
1163 cmd.req.arg[1] = 0 | BIT_0;
1164 }
1165 status = qlcnic_issue_cmd(adapter, &cmd);
1166 if (status)
1167 dev_err(&adapter->pdev->dev,
1168 "Failed to %s in NIC IDC function event.\n",
1169 (enable ? "register" : "unregister"));
1170
1171 qlcnic_free_mbx_args(&cmd);
1172}
1173
1174int qlcnic_83xx_set_port_config(struct qlcnic_adapter *adapter)
1175{
1176 struct qlcnic_cmd_args cmd;
1177 int err;
1178
1179 qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_SET_PORT_CONFIG);
1180 cmd.req.arg[1] = adapter->ahw->port_config;
1181 err = qlcnic_issue_cmd(adapter, &cmd);
1182 if (err)
1183 dev_info(&adapter->pdev->dev, "Set Port Config failed.\n");
1184 qlcnic_free_mbx_args(&cmd);
1185 return err;
1186}
1187
1188int qlcnic_83xx_get_port_config(struct qlcnic_adapter *adapter)
1189{
1190 struct qlcnic_cmd_args cmd;
1191 int err;
1192
1193 qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_PORT_CONFIG);
1194 err = qlcnic_issue_cmd(adapter, &cmd);
1195 if (err)
1196 dev_info(&adapter->pdev->dev, "Get Port config failed\n");
1197 else
1198 adapter->ahw->port_config = cmd.rsp.arg[1];
1199 qlcnic_free_mbx_args(&cmd);
1200 return err;
1201}
1202
1203int qlcnic_83xx_setup_link_event(struct qlcnic_adapter *adapter, int enable)
1204{
1205 int err;
1206 u32 temp;
1207 struct qlcnic_cmd_args cmd;
1208
1209 qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_LINK_EVENT);
1210 temp = adapter->recv_ctx->context_id << 16;
1211 cmd.req.arg[1] = (enable ? 1 : 0) | BIT_8 | temp;
1212 err = qlcnic_issue_cmd(adapter, &cmd);
1213 if (err)
1214 dev_info(&adapter->pdev->dev,
1215 "Setup linkevent mailbox failed\n");
1216 qlcnic_free_mbx_args(&cmd);
1217 return err;
1218}
1219
1220int qlcnic_83xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode)
1221{
1222 int err;
1223 u32 temp;
1224 struct qlcnic_cmd_args cmd;
1225
1226 if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
1227 return -EIO;
1228
1229 qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIGURE_MAC_RX_MODE);
1230 temp = adapter->recv_ctx->context_id << 16;
1231 cmd.req.arg[1] = (mode ? 1 : 0) | temp;
1232 err = qlcnic_issue_cmd(adapter, &cmd);
1233 if (err)
1234 dev_info(&adapter->pdev->dev,
1235 "Promiscous mode config failed\n");
1236 qlcnic_free_mbx_args(&cmd);
1237
1238 return err;
1239}
1240
1241int qlcnic_83xx_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
1242{
1243 struct qlcnic_hardware_context *ahw = adapter->ahw;
1244 int status = 0;
1245 u32 config;
1246
1247 status = qlcnic_83xx_get_port_config(adapter);
1248 if (status)
1249 return status;
1250
1251 config = ahw->port_config;
1252
1253 if (mode == QLCNIC_ILB_MODE)
1254 ahw->port_config |= QLC_83XX_CFG_LOOPBACK_HSS;
1255 if (mode == QLCNIC_ELB_MODE)
1256 ahw->port_config |= QLC_83XX_CFG_LOOPBACK_EXT;
1257
1258 status = qlcnic_83xx_set_port_config(adapter);
1259 if (status) {
1260 dev_err(&adapter->pdev->dev,
1261 "Failed to Set Loopback Mode = 0x%x.\n",
1262 ahw->port_config);
1263 ahw->port_config = config;
1264 return status;
1265 }
1266
1267 qlcnic_sre_macaddr_change(adapter, adapter->mac_addr, 0,
1268 QLCNIC_MAC_ADD);
1269 return status;
1270}
1271
1272int qlcnic_83xx_clear_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
1273{
1274 struct qlcnic_hardware_context *ahw = adapter->ahw;
1275 int status = 0;
1276 u32 config = ahw->port_config;
1277
1278 if (mode == QLCNIC_ILB_MODE)
1279 ahw->port_config &= ~QLC_83XX_CFG_LOOPBACK_HSS;
1280 if (mode == QLCNIC_ELB_MODE)
1281 ahw->port_config &= ~QLC_83XX_CFG_LOOPBACK_EXT;
1282
1283 status = qlcnic_83xx_set_port_config(adapter);
1284 if (status) {
1285 dev_err(&adapter->pdev->dev,
1286 "Failed to Clear Loopback Mode = 0x%x.\n",
1287 ahw->port_config);
1288 ahw->port_config = config;
1289 return status;
1290 }
1291
1292 qlcnic_sre_macaddr_change(adapter, adapter->mac_addr, 0,
1293 QLCNIC_MAC_DEL);
1294 return status;
1295}
1296
1297void qlcnic_83xx_config_ipaddr(struct qlcnic_adapter *adapter, __be32 ip,
1298 int mode)
1299{
1300 int err;
1301 u32 temp;
1302 struct qlcnic_cmd_args cmd;
1303
1304 qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIGURE_IP_ADDR);
1305 if (mode == QLCNIC_IP_UP) {
1306 temp = adapter->recv_ctx->context_id << 16;
1307 cmd.req.arg[1] = 1 | temp;
1308 } else {
1309 temp = adapter->recv_ctx->context_id << 16;
1310 cmd.req.arg[1] = 2 | temp;
1311 }
1312 cmd.req.arg[2] = ntohl(ip);
1313
1314 err = qlcnic_issue_cmd(adapter, &cmd);
1315 if (err != QLCNIC_RCODE_SUCCESS)
1316 dev_err(&adapter->netdev->dev,
1317 "could not notify %s IP 0x%x request\n",
1318 (mode == QLCNIC_IP_UP) ? "Add" : "Remove", ip);
1319 qlcnic_free_mbx_args(&cmd);
1320}
1321
1322int qlcnic_83xx_config_hw_lro(struct qlcnic_adapter *adapter, int mode)
1323{
1324 int err;
1325 u32 temp, arg1;
1326 struct qlcnic_cmd_args cmd;
1327
1328 if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
1329 return 0;
1330
1331 qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIGURE_HW_LRO);
1332 temp = adapter->recv_ctx->context_id << 16;
1333 arg1 = (mode ? (BIT_0 | BIT_1 | BIT_3) : 0) | temp;
1334 cmd.req.arg[1] = arg1;
1335
1336 err = qlcnic_issue_cmd(adapter, &cmd);
1337 if (err)
1338 dev_info(&adapter->pdev->dev, "LRO config failed\n");
1339 qlcnic_free_mbx_args(&cmd);
1340
1341 return err;
1342}
1343
1344int qlcnic_83xx_config_rss(struct qlcnic_adapter *adapter, int enable)
1345{
1346 int err;
1347 u32 word;
1348 struct qlcnic_cmd_args cmd;
1349 const u64 key[] = { 0xbeac01fa6a42b73bULL, 0x8030f20c77cb2da3ULL,
1350 0xae7b30b4d0ca2bcbULL, 0x43a38fb04167253dULL,
1351 0x255b0ec26d5a56daULL };
1352
1353 qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIGURE_RSS);
1354
1355 /*
1356 * RSS request:
1357 * bits 3-0: Rsvd
1358 * 5-4: hash_type_ipv4
1359 * 7-6: hash_type_ipv6
1360 * 8: enable
1361 * 9: use indirection table
1362 * 16-31: indirection table mask
1363 */
1364 word = ((u32)(RSS_HASHTYPE_IP_TCP & 0x3) << 4) |
1365 ((u32)(RSS_HASHTYPE_IP_TCP & 0x3) << 6) |
1366 ((u32)(enable & 0x1) << 8) |
1367 ((0x7ULL) << 16);
1368 cmd.req.arg[1] = (adapter->recv_ctx->context_id);
1369 cmd.req.arg[2] = word;
1370 memcpy(&cmd.req.arg[4], key, sizeof(key));
1371
1372 err = qlcnic_issue_cmd(adapter, &cmd);
1373
1374 if (err)
1375 dev_info(&adapter->pdev->dev, "RSS config failed\n");
1376 qlcnic_free_mbx_args(&cmd);
1377
1378 return err;
1379
1380}
1381
1382int qlcnic_83xx_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr,
1383 __le16 vlan_id, u8 op)
1384{
1385 int err;
1386 u32 *buf;
1387 struct qlcnic_cmd_args cmd;
1388 struct qlcnic_macvlan_mbx mv;
1389
1390 if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
1391 return -EIO;
1392
1393 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_MAC_VLAN);
1394 if (err)
1395 return err;
1396 cmd.req.arg[1] = op | (1 << 8) |
1397 (adapter->recv_ctx->context_id << 16);
1398
1399 mv.vlan = le16_to_cpu(vlan_id);
1400 memcpy(&mv.mac, addr, ETH_ALEN);
1401 buf = &cmd.req.arg[2];
1402 memcpy(buf, &mv, sizeof(struct qlcnic_macvlan_mbx));
1403 err = qlcnic_issue_cmd(adapter, &cmd);
1404 if (err)
1405 dev_err(&adapter->pdev->dev,
1406 "MAC-VLAN %s to CAM failed, err=%d.\n",
1407 ((op == 1) ? "add " : "delete "), err);
1408 qlcnic_free_mbx_args(&cmd);
1409 return err;
1410}
1411
1412void qlcnic_83xx_change_l2_filter(struct qlcnic_adapter *adapter, u64 *addr,
1413 __le16 vlan_id)
1414{
1415 u8 mac[ETH_ALEN];
1416 memcpy(&mac, addr, ETH_ALEN);
1417 qlcnic_83xx_sre_macaddr_change(adapter, mac, vlan_id, QLCNIC_MAC_ADD);
1418}
1419
1420void qlcnic_83xx_configure_mac(struct qlcnic_adapter *adapter, u8 *mac,
1421 u8 type, struct qlcnic_cmd_args *cmd)
1422{
1423 switch (type) {
1424 case QLCNIC_SET_STATION_MAC:
1425 case QLCNIC_SET_FAC_DEF_MAC:
1426 memcpy(&cmd->req.arg[2], mac, sizeof(u32));
1427 memcpy(&cmd->req.arg[3], &mac[4], sizeof(u16));
1428 break;
1429 }
1430 cmd->req.arg[1] = type;
1431}
1432
1433int qlcnic_83xx_get_mac_address(struct qlcnic_adapter *adapter, u8 *mac)
1434{
1435 int err, i;
1436 struct qlcnic_cmd_args cmd;
1437 u32 mac_low, mac_high;
1438
1439 qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_MAC_ADDRESS);
1440 qlcnic_83xx_configure_mac(adapter, mac, QLCNIC_GET_CURRENT_MAC, &cmd);
1441 err = qlcnic_issue_cmd(adapter, &cmd);
1442
1443 if (err == QLCNIC_RCODE_SUCCESS) {
1444 mac_low = cmd.rsp.arg[1];
1445 mac_high = cmd.rsp.arg[2];
1446
1447 for (i = 0; i < 2; i++)
1448 mac[i] = (u8) (mac_high >> ((1 - i) * 8));
1449 for (i = 2; i < 6; i++)
1450 mac[i] = (u8) (mac_low >> ((5 - i) * 8));
1451 } else {
1452 dev_err(&adapter->pdev->dev, "Failed to get mac address%d\n",
1453 err);
1454 err = -EIO;
1455 }
1456 qlcnic_free_mbx_args(&cmd);
1457 return err;
1458}
1459
1460void qlcnic_83xx_config_intr_coal(struct qlcnic_adapter *adapter)
1461{
1462 int err;
1463 u32 temp;
1464 struct qlcnic_cmd_args cmd;
1465 struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal;
1466
1467 if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
1468 return;
1469
1470 qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_INTR_COAL);
1471 cmd.req.arg[1] = 1 | (adapter->recv_ctx->context_id << 16);
1472 cmd.req.arg[3] = coal->flag;
1473 temp = coal->rx_time_us << 16;
1474 cmd.req.arg[2] = coal->rx_packets | temp;
1475 err = qlcnic_issue_cmd(adapter, &cmd);
1476 if (err != QLCNIC_RCODE_SUCCESS)
1477 dev_info(&adapter->pdev->dev,
1478 "Failed to send interrupt coalescence parameters\n");
1479 qlcnic_free_mbx_args(&cmd);
1480}
1481
1482static void qlcnic_83xx_handle_link_aen(struct qlcnic_adapter *adapter,
1483 u32 data[])
1484{
1485 u8 link_status, duplex;
1486 /* link speed */
1487 link_status = LSB(data[3]) & 1;
1488 adapter->ahw->link_speed = MSW(data[2]);
1489 adapter->ahw->link_autoneg = MSB(MSW(data[3]));
1490 adapter->ahw->module_type = MSB(LSW(data[3]));
1491 duplex = LSB(MSW(data[3]));
1492 if (duplex)
1493 adapter->ahw->link_duplex = DUPLEX_FULL;
1494 else
1495 adapter->ahw->link_duplex = DUPLEX_HALF;
1496 adapter->ahw->has_link_events = 1;
1497 qlcnic_advert_link_change(adapter, link_status);
1498}
1499
1500irqreturn_t qlcnic_83xx_handle_aen(int irq, void *data)
1501{
1502 struct qlcnic_adapter *adapter = data;
1503 qlcnic_83xx_process_aen(adapter);
1504 return IRQ_HANDLED;
1505}
1506
1507int qlcnic_enable_eswitch(struct qlcnic_adapter *adapter, u8 port, u8 enable)
1508{
1509 int err = -EIO;
1510 struct qlcnic_cmd_args cmd;
1511
1512 if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC) {
1513 dev_err(&adapter->pdev->dev,
1514 "%s: Error, invoked by non management func\n",
1515 __func__);
1516 return err;
1517 }
1518
1519 qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_TOGGLE_ESWITCH);
1520 cmd.req.arg[1] = (port & 0xf) | BIT_4;
1521 err = qlcnic_issue_cmd(adapter, &cmd);
1522
1523 if (err != QLCNIC_RCODE_SUCCESS) {
1524 dev_err(&adapter->pdev->dev, "Failed to enable eswitch%d\n",
1525 err);
1526 err = -EIO;
1527 }
1528 qlcnic_free_mbx_args(&cmd);
1529
1530 return err;
1531
1532}
1533
1534int qlcnic_83xx_set_nic_info(struct qlcnic_adapter *adapter,
1535 struct qlcnic_info *nic)
1536{
1537 int i, err = -EIO;
1538 struct qlcnic_cmd_args cmd;
1539
1540 if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC) {
1541 dev_err(&adapter->pdev->dev,
1542 "%s: Error, invoked by non management func\n",
1543 __func__);
1544 return err;
1545 }
1546
1547 qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_SET_NIC_INFO);
1548 cmd.req.arg[1] = (nic->pci_func << 16);
1549 cmd.req.arg[2] = 0x1 << 16;
1550 cmd.req.arg[3] = nic->phys_port | (nic->switch_mode << 16);
1551 cmd.req.arg[4] = nic->capabilities;
1552 cmd.req.arg[5] = (nic->max_mac_filters & 0xFF) | ((nic->max_mtu) << 16);
1553 cmd.req.arg[6] = (nic->max_tx_ques) | ((nic->max_rx_ques) << 16);
1554 cmd.req.arg[7] = (nic->min_tx_bw) | ((nic->max_tx_bw) << 16);
1555 for (i = 8; i < 32; i++)
1556 cmd.req.arg[i] = 0;
1557
1558 err = qlcnic_issue_cmd(adapter, &cmd);
1559
1560 if (err != QLCNIC_RCODE_SUCCESS) {
1561 dev_err(&adapter->pdev->dev, "Failed to set nic info%d\n",
1562 err);
1563 err = -EIO;
1564 }
1565
1566 qlcnic_free_mbx_args(&cmd);
1567
1568 return err;
1569}
1570
1571int qlcnic_83xx_get_nic_info(struct qlcnic_adapter *adapter,
1572 struct qlcnic_info *npar_info, u8 func_id)
1573{
1574 int err;
1575 u32 temp;
1576 u8 op = 0;
1577 struct qlcnic_cmd_args cmd;
1578
1579 qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_NIC_INFO);
1580 if (func_id != adapter->ahw->pci_func) {
1581 temp = func_id << 16;
1582 cmd.req.arg[1] = op | BIT_31 | temp;
1583 } else {
1584 cmd.req.arg[1] = adapter->ahw->pci_func << 16;
1585 }
1586 err = qlcnic_issue_cmd(adapter, &cmd);
1587 if (err) {
1588 dev_info(&adapter->pdev->dev,
1589 "Failed to get nic info %d\n", err);
1590 goto out;
1591 }
1592
1593 npar_info->op_type = cmd.rsp.arg[1];
1594 npar_info->pci_func = cmd.rsp.arg[2] & 0xFFFF;
1595 npar_info->op_mode = (cmd.rsp.arg[2] & 0xFFFF0000) >> 16;
1596 npar_info->phys_port = cmd.rsp.arg[3] & 0xFFFF;
1597 npar_info->switch_mode = (cmd.rsp.arg[3] & 0xFFFF0000) >> 16;
1598 npar_info->capabilities = cmd.rsp.arg[4];
1599 npar_info->max_mac_filters = cmd.rsp.arg[5] & 0xFF;
1600 npar_info->max_mtu = (cmd.rsp.arg[5] & 0xFFFF0000) >> 16;
1601 npar_info->max_tx_ques = cmd.rsp.arg[6] & 0xFFFF;
1602 npar_info->max_rx_ques = (cmd.rsp.arg[6] & 0xFFFF0000) >> 16;
1603 npar_info->min_tx_bw = cmd.rsp.arg[7] & 0xFFFF;
1604 npar_info->max_tx_bw = (cmd.rsp.arg[7] & 0xFFFF0000) >> 16;
1605 if (cmd.rsp.arg[8] & 0x1)
1606 npar_info->max_bw_reg_offset = (cmd.rsp.arg[8] & 0x7FFE) >> 1;
1607 if (cmd.rsp.arg[8] & 0x10000) {
1608 temp = (cmd.rsp.arg[8] & 0x7FFE0000) >> 17;
1609 npar_info->max_linkspeed_reg_offset = temp;
1610 }
1611
1612out:
1613 qlcnic_free_mbx_args(&cmd);
1614 return err;
1615}
1616
1617int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *adapter,
1618 struct qlcnic_pci_info *pci_info)
1619{
1620 int i, err = 0, j = 0;
1621 u32 temp;
1622 struct qlcnic_cmd_args cmd;
1623
1624 qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_PCI_INFO);
1625 err = qlcnic_issue_cmd(adapter, &cmd);
1626
1627 adapter->ahw->act_pci_func = 0;
1628 if (err == QLCNIC_RCODE_SUCCESS) {
1629 pci_info->func_count = cmd.rsp.arg[1] & 0xFF;
1630 dev_info(&adapter->pdev->dev,
1631 "%s: total functions = %d\n",
1632 __func__, pci_info->func_count);
1633 for (i = 2, j = 0; j < QLCNIC_MAX_PCI_FUNC; j++, pci_info++) {
1634 pci_info->id = cmd.rsp.arg[i] & 0xFFFF;
1635 pci_info->active = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16;
1636 i++;
1637 pci_info->type = cmd.rsp.arg[i] & 0xFFFF;
1638 if (pci_info->type == QLCNIC_TYPE_NIC)
1639 adapter->ahw->act_pci_func++;
1640 temp = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16;
1641 pci_info->default_port = temp;
1642 i++;
1643 pci_info->tx_min_bw = cmd.rsp.arg[i] & 0xFFFF;
1644 temp = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16;
1645 pci_info->tx_max_bw = temp;
1646 i = i + 2;
1647 memcpy(pci_info->mac, &cmd.rsp.arg[i], ETH_ALEN - 2);
1648 i++;
1649 memcpy(pci_info->mac + sizeof(u32), &cmd.rsp.arg[i], 2);
1650 i = i + 3;
1651
1652 dev_info(&adapter->pdev->dev, "%s:\n"
1653 "\tid = %d active = %d type = %d\n"
1654 "\tport = %d min bw = %d max bw = %d\n"
1655 "\tmac_addr = %pM\n", __func__,
1656 pci_info->id, pci_info->active, pci_info->type,
1657 pci_info->default_port, pci_info->tx_min_bw,
1658 pci_info->tx_max_bw, pci_info->mac);
1659 }
1660 } else {
1661 dev_err(&adapter->pdev->dev, "Failed to get PCI Info%d\n",
1662 err);
1663 err = -EIO;
1664 }
1665
1666 qlcnic_free_mbx_args(&cmd);
1667
1668 return err;
1669}
1670
1671int qlcnic_83xx_config_intrpt(struct qlcnic_adapter *adapter, bool op_type)
1672{
1673 int i, index, err;
1674 bool type;
1675 u8 max_ints;
1676 u32 val, temp;
1677 struct qlcnic_cmd_args cmd;
1678
1679 max_ints = adapter->ahw->num_msix;
1680 qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_INTRPT);
1681 cmd.req.arg[1] = max_ints;
1682 for (i = 0, index = 2; i < max_ints; i++) {
1683 type = op_type ? QLCNIC_INTRPT_ADD : QLCNIC_INTRPT_DEL;
1684 val = type | (adapter->ahw->intr_tbl[i].type << 4);
1685 if (adapter->ahw->intr_tbl[i].type == QLCNIC_INTRPT_MSIX)
1686 val |= (adapter->ahw->intr_tbl[i].id << 16);
1687 cmd.req.arg[index++] = val;
1688 }
1689 err = qlcnic_issue_cmd(adapter, &cmd);
1690 if (err) {
1691 dev_err(&adapter->pdev->dev,
1692 "Failed to configure interrupts 0x%x\n", err);
1693 goto out;
1694 }
1695
1696 max_ints = cmd.rsp.arg[1];
1697 for (i = 0, index = 2; i < max_ints; i++, index += 2) {
1698 val = cmd.rsp.arg[index];
1699 if (LSB(val)) {
1700 dev_info(&adapter->pdev->dev,
1701 "Can't configure interrupt %d\n",
1702 adapter->ahw->intr_tbl[i].id);
1703 continue;
1704 }
1705 if (op_type) {
1706 adapter->ahw->intr_tbl[i].id = MSW(val);
1707 adapter->ahw->intr_tbl[i].enabled = 1;
1708 temp = cmd.rsp.arg[index + 1];
1709 adapter->ahw->intr_tbl[i].src = temp;
1710 } else {
1711 adapter->ahw->intr_tbl[i].id = i;
1712 adapter->ahw->intr_tbl[i].enabled = 0;
1713 adapter->ahw->intr_tbl[i].src = 0;
1714 }
1715 }
1716out:
1717 qlcnic_free_mbx_args(&cmd);
1718 return err;
1719}
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
new file mode 100644
index 000000000000..9d707be27ca2
--- /dev/null
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
@@ -0,0 +1,250 @@
1#ifndef __QLCNIC_83XX_HW_H
2#define __QLCNIC_83XX_HW_H
3
4#include <linux/types.h>
5#include <linux/etherdevice.h>
6#include "qlcnic_hw.h"
7
8/* Directly mapped registers */
9#define QLC_83XX_CRB_WIN_BASE 0x3800
10#define QLC_83XX_CRB_WIN_FUNC(f) (QLC_83XX_CRB_WIN_BASE+((f)*4))
11#define QLC_83XX_SEM_LOCK_BASE 0x3840
12#define QLC_83XX_SEM_UNLOCK_BASE 0x3844
13#define QLC_83XX_SEM_LOCK_FUNC(f) (QLC_83XX_SEM_LOCK_BASE+((f)*8))
14#define QLC_83XX_SEM_UNLOCK_FUNC(f) (QLC_83XX_SEM_UNLOCK_BASE+((f)*8))
15#define QLC_83XX_LINK_STATE(f) (0x3698+((f) > 7 ? 4 : 0))
16#define QLC_83XX_LINK_SPEED(f) (0x36E0+(((f) >> 2) * 4))
17#define QLC_83XX_LINK_SPEED_FACTOR 10
18#define QLC_83xx_FUNC_VAL(v, f) ((v) & (1 << (f * 4)))
19#define QLC_83XX_INTX_PTR 0x38C0
20#define QLC_83XX_INTX_TRGR 0x38C4
21#define QLC_83XX_INTX_MASK 0x38C8
22
23#define QLC_83XX_DRV_LOCK_WAIT_COUNTER 100
24#define QLC_83XX_DRV_LOCK_WAIT_DELAY 20
25#define QLC_83XX_NEED_DRV_LOCK_RECOVERY 1
26#define QLC_83XX_DRV_LOCK_RECOVERY_IN_PROGRESS 2
27#define QLC_83XX_MAX_DRV_LOCK_RECOVERY_ATTEMPT 3
28#define QLC_83XX_DRV_LOCK_RECOVERY_DELAY 200
29#define QLC_83XX_DRV_LOCK_RECOVERY_STATUS_MASK 0x3
30
31#define QLC_83XX_NO_NIC_RESOURCE 0x5
32#define QLC_83XX_MAC_PRESENT 0xC
33#define QLC_83XX_MAC_ABSENT 0xD
34
35
36#define QLC_83XX_FLASH_SECTOR_SIZE (64 * 1024)
37
38/* PEG status definitions */
39#define QLC_83XX_CMDPEG_COMPLETE 0xff01
40#define QLC_83XX_VALID_INTX_BIT30(val) ((val) & BIT_30)
41#define QLC_83XX_VALID_INTX_BIT31(val) ((val) & BIT_31)
42#define QLC_83XX_INTX_FUNC(val) ((val) & 0xFF)
43#define QLC_83XX_LEGACY_INTX_MAX_RETRY 100
44#define QLC_83XX_LEGACY_INTX_DELAY 4
45#define QLC_83XX_REG_DESC 1
46#define QLC_83XX_LRO_DESC 2
47#define QLC_83XX_CTRL_DESC 3
48#define QLC_83XX_FW_CAPABILITY_TSO BIT_6
49#define QLC_83XX_FW_CAP_LRO_MSS BIT_17
50#define QLC_83XX_HOST_RDS_MODE_UNIQUE 0
51#define QLC_83XX_HOST_SDS_MBX_IDX 8
52
53#define QLCNIC_HOST_RDS_MBX_IDX 88
54#define QLCNIC_MAX_RING_SETS 8
55
56struct qlcnic_intrpt_config {
57 u8 type;
58 u8 enabled;
59 u16 id;
60 u32 src;
61};
62
63struct qlcnic_macvlan_mbx {
64 u8 mac[ETH_ALEN];
65 u16 vlan;
66};
67
68
69/* Mailbox process AEN count */
70#define QLC_83XX_IDC_COMP_AEN 3
71#define QLC_83XX_MBX_AEN_CNT 5
72#define QLC_83XX_MODULE_LOADED 1
73#define QLC_83XX_MBX_READY 2
74#define QLC_83XX_MBX_AEN_ACK 3
75#define QLC_83XX_SFP_PRESENT(data) ((data) & 3)
76#define QLC_83XX_SFP_ERR(data) (((data) >> 2) & 3)
77#define QLC_83XX_SFP_MODULE_TYPE(data) (((data) >> 4) & 0x1F)
78#define QLC_83XX_SFP_CU_LENGTH(data) (LSB((data) >> 16))
79#define QLC_83XX_SFP_TX_FAULT(data) ((data) & BIT_10)
80#define QLC_83XX_SFP_10G_CAPABLE(data) ((data) & BIT_11)
81#define QLC_83XX_LINK_STATS(data) ((data) & BIT_0)
82#define QLC_83XX_CURRENT_LINK_SPEED(data) (((data) >> 3) & 7)
83#define QLC_83XX_LINK_PAUSE(data) (((data) >> 6) & 3)
84#define QLC_83XX_LINK_LB(data) (((data) >> 8) & 7)
85#define QLC_83XX_LINK_FEC(data) ((data) & BIT_12)
86#define QLC_83XX_LINK_EEE(data) ((data) & BIT_13)
87#define QLC_83XX_DCBX(data) (((data) >> 28) & 7)
88#define QLC_83XX_AUTONEG(data) ((data) & BIT_15)
89#define QLC_83XX_CFG_STD_PAUSE (1 << 5)
90#define QLC_83XX_CFG_STD_TX_PAUSE (1 << 20)
91#define QLC_83XX_CFG_STD_RX_PAUSE (2 << 20)
92#define QLC_83XX_CFG_STD_TX_RX_PAUSE (3 << 20)
93#define QLC_83XX_ENABLE_AUTONEG (1 << 15)
94#define QLC_83XX_CFG_LOOPBACK_HSS (2 << 1)
95#define QLC_83XX_CFG_LOOPBACK_PHY (3 << 1)
96#define QLC_83XX_CFG_LOOPBACK_EXT (4 << 1)
97
98/* LED configuration settings */
99#define QLC_83XX_ENABLE_BEACON 0xe
100#define QLC_83XX_LED_RATE 0xff
101#define QLC_83XX_LED_ACT (1 << 10)
102#define QLC_83XX_LED_MOD (0 << 13)
103#define QLC_83XX_LED_CONFIG (QLC_83XX_LED_RATE | QLC_83XX_LED_ACT | \
104 QLC_83XX_LED_MOD)
105
106#define QLC_83XX_10M_LINK 1
107#define QLC_83XX_100M_LINK 2
108#define QLC_83XX_1G_LINK 3
109#define QLC_83XX_10G_LINK 4
110#define QLC_83XX_STAT_TX 3
111#define QLC_83XX_STAT_RX 2
112#define QLC_83XX_STAT_MAC 1
113#define QLC_83XX_TX_STAT_REGS 14
114#define QLC_83XX_RX_STAT_REGS 40
115#define QLC_83XX_MAC_STAT_REGS 80
116
117#define QLC_83XX_GET_FUNC_PRIVILEGE(VAL, FN) (0x3 & ((VAL) >> (FN * 2)))
118#define QLC_83XX_SET_FUNC_OPMODE(VAL, FN) ((VAL) << (FN * 2))
119#define QLC_83XX_DEFAULT_OPMODE 0x55555555
120#define QLC_83XX_PRIVLEGED_FUNC 0x1
121#define QLC_83XX_VIRTUAL_FUNC 0x2
122
123#define QLC_83XX_LB_MAX_FILTERS 2048
124#define QLC_83XX_LB_BUCKET_SIZE 256
125#define QLC_83XX_MINIMUM_VECTOR 3
126
127#define QLC_83XX_GET_FUNC_MODE_FROM_NPAR_INFO(val) (val & 0x80000000)
128#define QLC_83XX_GET_LRO_CAPABILITY(val) (val & 0x20)
129#define QLC_83XX_GET_LSO_CAPABILITY(val) (val & 0x40)
130#define QLC_83XX_GET_LSO_CAPABILITY(val) (val & 0x40)
131#define QLC_83XX_GET_HW_LRO_CAPABILITY(val) (val & 0x400)
132#define QLC_83XX_GET_VLAN_ALIGN_CAPABILITY(val) (val & 0x4000)
133#define QLC_83XX_VIRTUAL_NIC_MODE 0xFF
134#define QLC_83XX_DEFAULT_MODE 0x0
135#define QLCNIC_BRDTYPE_83XX_10G 0x0083
136
137/* Additional registers in 83xx */
138enum qlc_83xx_ext_regs {
139 QLCNIC_GLOBAL_RESET = 0,
140 QLCNIC_WILDCARD,
141 QLCNIC_INFORMANT,
142 QLCNIC_HOST_MBX_CTRL,
143 QLCNIC_FW_MBX_CTRL,
144 QLCNIC_BOOTLOADER_ADDR,
145 QLCNIC_BOOTLOADER_SIZE,
146 QLCNIC_FW_IMAGE_ADDR,
147 QLCNIC_MBX_INTR_ENBL,
148 QLCNIC_DEF_INT_MASK,
149 QLCNIC_DEF_INT_ID,
150 QLC_83XX_IDC_MAJ_VERSION,
151 QLC_83XX_IDC_DEV_STATE,
152 QLC_83XX_IDC_DRV_PRESENCE,
153 QLC_83XX_IDC_DRV_ACK,
154 QLC_83XX_IDC_CTRL,
155 QLC_83XX_IDC_DRV_AUDIT,
156 QLC_83XX_IDC_MIN_VERSION,
157 QLC_83XX_RECOVER_DRV_LOCK,
158 QLC_83XX_IDC_PF_0,
159 QLC_83XX_IDC_PF_1,
160 QLC_83XX_IDC_PF_2,
161 QLC_83XX_IDC_PF_3,
162 QLC_83XX_IDC_PF_4,
163 QLC_83XX_IDC_PF_5,
164 QLC_83XX_IDC_PF_6,
165 QLC_83XX_IDC_PF_7,
166 QLC_83XX_IDC_PF_8,
167 QLC_83XX_IDC_PF_9,
168 QLC_83XX_IDC_PF_10,
169 QLC_83XX_IDC_PF_11,
170 QLC_83XX_IDC_PF_12,
171 QLC_83XX_IDC_PF_13,
172 QLC_83XX_IDC_PF_14,
173 QLC_83XX_IDC_PF_15,
174 QLC_83XX_IDC_DEV_PARTITION_INFO_1,
175 QLC_83XX_IDC_DEV_PARTITION_INFO_2,
176 QLC_83XX_DRV_OP_MODE,
177 QLC_83XX_VNIC_STATE,
178 QLC_83XX_DRV_LOCK,
179 QLC_83XX_DRV_UNLOCK,
180 QLC_83XX_DRV_LOCK_ID,
181 QLC_83XX_ASIC_TEMP,
182};
183
184/* 83xx funcitons */
185int qlcnic_83xx_get_fw_version(struct qlcnic_adapter *);
186int qlcnic_83xx_mbx_op(struct qlcnic_adapter *, struct qlcnic_cmd_args *);
187int qlcnic_83xx_setup_intr(struct qlcnic_adapter *, u8);
188void qlcnic_83xx_get_func_no(struct qlcnic_adapter *);
189int qlcnic_83xx_cam_lock(struct qlcnic_adapter *);
190void qlcnic_83xx_cam_unlock(struct qlcnic_adapter *);
191int qlcnic_send_ctrl_op(struct qlcnic_adapter *, struct qlcnic_cmd_args *, u32);
192void qlcnic_83xx_write_crb(struct qlcnic_adapter *, char *, loff_t, size_t);
193void qlcnic_83xx_read_crb(struct qlcnic_adapter *, char *, loff_t, size_t);
194int qlcnic_83xx_rd_reg_indirect(struct qlcnic_adapter *, ulong);
195int qlcnic_83xx_wrt_reg_indirect(struct qlcnic_adapter *, ulong, u32);
196void qlcnic_83xx_process_rcv_diag(struct qlcnic_adapter *,
197 struct qlcnic_host_sds_ring *, int, u64 []);
198int qlcnic_83xx_nic_set_promisc(struct qlcnic_adapter *, u32);
199int qlcnic_83xx_set_lb_mode(struct qlcnic_adapter *, u8);
200int qlcnic_83xx_clear_lb_mode(struct qlcnic_adapter *, u8);
201int qlcnic_83xx_config_hw_lro(struct qlcnic_adapter *, int);
202int qlcnic_83xx_config_rss(struct qlcnic_adapter *, int);
203int qlcnic_83xx_config_intr_coalesce(struct qlcnic_adapter *);
204void qlcnic_83xx_change_l2_filter(struct qlcnic_adapter *, u64 *, __le16);
205int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *, struct qlcnic_pci_info *);
206int qlcnic_83xx_set_nic_info(struct qlcnic_adapter *, struct qlcnic_info *);
207void qlcnic_83xx_register_nic_idc_func(struct qlcnic_adapter *, int);
208
209void qlcnic_ind_wr(struct qlcnic_adapter *, u32, u32);
210int qlcnic_ind_rd(struct qlcnic_adapter *, u32);
211void qlcnic_83xx_get_stats(struct qlcnic_adapter *,
212 struct ethtool_stats *, u64 *);
213int qlcnic_83xx_create_rx_ctx(struct qlcnic_adapter *);
214int qlcnic_83xx_create_tx_ctx(struct qlcnic_adapter *,
215 struct qlcnic_host_tx_ring *, int);
216int qlcnic_83xx_get_nic_info(struct qlcnic_adapter *, struct qlcnic_info *, u8);
217int qlcnic_83xx_setup_link_event(struct qlcnic_adapter *, int);
218void qlcnic_83xx_process_rcv_ring_diag(struct qlcnic_host_sds_ring *);
219int qlcnic_83xx_config_intrpt(struct qlcnic_adapter *, bool);
220int qlcnic_83xx_sre_macaddr_change(struct qlcnic_adapter *, u8 *, __le16, u8);
221int qlcnic_83xx_get_mac_address(struct qlcnic_adapter *, u8 *);
222void qlcnic_83xx_configure_mac(struct qlcnic_adapter *, u8 *, u8,
223 struct qlcnic_cmd_args *);
224int qlcnic_83xx_alloc_mbx_args(struct qlcnic_cmd_args *,
225 struct qlcnic_adapter *, u32);
226void qlcnic_free_mbx_args(struct qlcnic_cmd_args *);
227void qlcnic_set_npar_data(struct qlcnic_adapter *, const struct qlcnic_info *,
228 struct qlcnic_info *);
229void qlcnic_83xx_config_intr_coal(struct qlcnic_adapter *);
230irqreturn_t qlcnic_83xx_handle_aen(int, void *);
231int qlcnic_83xx_get_port_info(struct qlcnic_adapter *);
232void qlcnic_83xx_enable_mbx_intrpt(struct qlcnic_adapter *);
233irqreturn_t qlcnic_83xx_clear_legacy_intr(struct qlcnic_adapter *);
234irqreturn_t qlcnic_83xx_tmp_intr(int, void *);
235void qlcnic_83xx_enable_intr(struct qlcnic_adapter *,
236 struct qlcnic_host_sds_ring *);
237void qlcnic_83xx_check_vf(struct qlcnic_adapter *,
238 const struct pci_device_id *);
239void qlcnic_83xx_process_aen(struct qlcnic_adapter *);
240int qlcnic_83xx_get_port_config(struct qlcnic_adapter *);
241int qlcnic_83xx_set_port_config(struct qlcnic_adapter *);
242int qlcnic_enable_eswitch(struct qlcnic_adapter *, u8, u8);
243int qlcnic_83xx_get_nic_configuration(struct qlcnic_adapter *);
244int qlcnic_83xx_config_default_opmode(struct qlcnic_adapter *);
245int qlcnic_83xx_setup_mbx_intr(struct qlcnic_adapter *);
246void qlcnic_83xx_free_mbx_intr(struct qlcnic_adapter *);
247void qlcnic_83xx_register_map(struct qlcnic_hardware_context *);
248void qlcnic_83xx_idc_aen_work(struct work_struct *);
249void qlcnic_83xx_config_ipaddr(struct qlcnic_adapter *, __be32, int);
250#endif
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h
index fa2b8c63eedb..458b9aea2bb4 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h
@@ -493,7 +493,7 @@ enum {
493#define QLCNIC_NIU_GB_MAC_CONFIG_1(I) \ 493#define QLCNIC_NIU_GB_MAC_CONFIG_1(I) \
494 (QLCNIC_CRB_NIU + 0x30004 + (I)*0x10000) 494 (QLCNIC_CRB_NIU + 0x30004 + (I)*0x10000)
495 495
496 496#define MAX_CTL_CHECK 1000
497#define TEST_AGT_CTRL (0x00) 497#define TEST_AGT_CTRL (0x00)
498 498
499#define TA_CTL_START BIT_0 499#define TA_CTL_START BIT_0
@@ -749,6 +749,9 @@ enum {
749#define QLCNIC_HEARTBEAT_PERIOD_MSECS 200 749#define QLCNIC_HEARTBEAT_PERIOD_MSECS 200
750#define QLCNIC_HEARTBEAT_CHECK_RETRY_COUNT 45 750#define QLCNIC_HEARTBEAT_CHECK_RETRY_COUNT 45
751 751
752#define QLCNIC_MAX_MC_COUNT 38
753#define QLCNIC_WATCHDOG_TIMEOUTVALUE 5
754
752#define ISR_MSI_INT_TRIGGER(FUNC) (QLCNIC_PCIX_PS_REG(PCIX_MSI_F(FUNC))) 755#define ISR_MSI_INT_TRIGGER(FUNC) (QLCNIC_PCIX_PS_REG(PCIX_MSI_F(FUNC)))
753#define ISR_LEGACY_INT_TRIGGERED(VAL) (((VAL) & 0x300) == 0x200) 756#define ISR_LEGACY_INT_TRIGGERED(VAL) (((VAL) & 0x300) == 0x200)
754 757
@@ -801,7 +804,8 @@ static const u32 MIU_TEST_READ_DATA[] = {
801enum { 804enum {
802 QLCNIC_MGMT_FUNC = 0, 805 QLCNIC_MGMT_FUNC = 0,
803 QLCNIC_PRIV_FUNC = 1, 806 QLCNIC_PRIV_FUNC = 1,
804 QLCNIC_NON_PRIV_FUNC = 2 807 QLCNIC_NON_PRIV_FUNC = 2,
808 QLCNIC_UNKNOWN_FUNC_MODE = 3
805}; 809};
806 810
807enum { 811enum {
@@ -1018,6 +1022,8 @@ enum {
1018#define QLCNIC_NIU_PROMISC_MODE 1 1022#define QLCNIC_NIU_PROMISC_MODE 1
1019#define QLCNIC_NIU_ALLMULTI_MODE 2 1023#define QLCNIC_NIU_ALLMULTI_MODE 2
1020 1024
1025#define QLCNIC_PCIE_SEM_TIMEOUT 10000
1026
1021struct crb_128M_2M_sub_block_map { 1027struct crb_128M_2M_sub_block_map {
1022 unsigned valid; 1028 unsigned valid;
1023 unsigned start_128M; 1029 unsigned start_128M;
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
index 284618be3402..d692aa8d4054 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
@@ -344,21 +344,26 @@ qlcnic_pcie_sem_unlock(struct qlcnic_adapter *adapter, int sem)
344 QLCRD32(adapter, QLCNIC_PCIE_REG(PCIE_SEM_UNLOCK(sem))); 344 QLCRD32(adapter, QLCNIC_PCIE_REG(PCIE_SEM_UNLOCK(sem)));
345} 345}
346 346
347static int qlcnic_ind_rd(struct qlcnic_adapter *adapter, u32 addr) 347int qlcnic_ind_rd(struct qlcnic_adapter *adapter, u32 addr)
348{ 348{
349 u32 data; 349 u32 data;
350 350
351 if (qlcnic_82xx_check(adapter)) 351 if (qlcnic_82xx_check(adapter))
352 qlcnic_read_window_reg(addr, adapter->ahw->pci_base0, &data); 352 qlcnic_read_window_reg(addr, adapter->ahw->pci_base0, &data);
353 else 353 else {
354 return -EIO; 354 data = qlcnic_83xx_rd_reg_indirect(adapter, addr);
355 if (data == -EIO)
356 return -EIO;
357 }
355 return data; 358 return data;
356} 359}
357 360
358static void qlcnic_ind_wr(struct qlcnic_adapter *adapter, u32 addr, u32 data) 361void qlcnic_ind_wr(struct qlcnic_adapter *adapter, u32 addr, u32 data)
359{ 362{
360 if (qlcnic_82xx_check(adapter)) 363 if (qlcnic_82xx_check(adapter))
361 qlcnic_write_window_reg(addr, adapter->ahw->pci_base0, data); 364 qlcnic_write_window_reg(addr, adapter->ahw->pci_base0, data);
365 else
366 qlcnic_83xx_wrt_reg_indirect(adapter, addr, data);
362} 367}
363 368
364static int 369static int
@@ -553,19 +558,20 @@ void qlcnic_prune_lb_filters(struct qlcnic_adapter *adapter)
553 struct qlcnic_filter *tmp_fil; 558 struct qlcnic_filter *tmp_fil;
554 struct hlist_node *tmp_hnode, *n; 559 struct hlist_node *tmp_hnode, *n;
555 struct hlist_head *head; 560 struct hlist_head *head;
556 int i; 561 int i, time;
562 u8 cmd;
557 563
558 for (i = 0; i < adapter->fhash.fmax; i++) { 564 for (i = 0; i < adapter->fhash.fbucket_size; i++) {
559 head = &(adapter->fhash.fhead[i]); 565 head = &(adapter->fhash.fhead[i]);
560 566 hlist_for_each_entry_safe(tmp_fil, tmp_hnode, n, head, fnode) {
561 hlist_for_each_entry_safe(tmp_fil, tmp_hnode, n, head, fnode) 567 cmd = tmp_fil->vlan_id ? QLCNIC_MAC_VLAN_DEL :
562 { 568 QLCNIC_MAC_DEL;
563 if (jiffies > 569 time = tmp_fil->ftime;
564 (QLCNIC_FILTER_AGE * HZ + tmp_fil->ftime)) { 570 if (jiffies > (QLCNIC_FILTER_AGE * HZ + time)) {
565 qlcnic_sre_macaddr_change(adapter, 571 qlcnic_sre_macaddr_change(adapter,
566 tmp_fil->faddr, tmp_fil->vlan_id, 572 tmp_fil->faddr,
567 tmp_fil->vlan_id ? QLCNIC_MAC_VLAN_DEL : 573 tmp_fil->vlan_id,
568 QLCNIC_MAC_DEL); 574 cmd);
569 spin_lock_bh(&adapter->mac_learn_lock); 575 spin_lock_bh(&adapter->mac_learn_lock);
570 adapter->fhash.fnum--; 576 adapter->fhash.fnum--;
571 hlist_del(&tmp_fil->fnode); 577 hlist_del(&tmp_fil->fnode);
@@ -582,14 +588,17 @@ void qlcnic_delete_lb_filters(struct qlcnic_adapter *adapter)
582 struct hlist_node *tmp_hnode, *n; 588 struct hlist_node *tmp_hnode, *n;
583 struct hlist_head *head; 589 struct hlist_head *head;
584 int i; 590 int i;
591 u8 cmd;
585 592
586 for (i = 0; i < adapter->fhash.fmax; i++) { 593 for (i = 0; i < adapter->fhash.fbucket_size; i++) {
587 head = &(adapter->fhash.fhead[i]); 594 head = &(adapter->fhash.fhead[i]);
588
589 hlist_for_each_entry_safe(tmp_fil, tmp_hnode, n, head, fnode) { 595 hlist_for_each_entry_safe(tmp_fil, tmp_hnode, n, head, fnode) {
590 qlcnic_sre_macaddr_change(adapter, tmp_fil->faddr, 596 cmd = tmp_fil->vlan_id ? QLCNIC_MAC_VLAN_DEL :
591 tmp_fil->vlan_id, tmp_fil->vlan_id ? 597 QLCNIC_MAC_DEL;
592 QLCNIC_MAC_VLAN_DEL : QLCNIC_MAC_DEL); 598 qlcnic_sre_macaddr_change(adapter,
599 tmp_fil->faddr,
600 tmp_fil->vlan_id,
601 cmd);
593 spin_lock_bh(&adapter->mac_learn_lock); 602 spin_lock_bh(&adapter->mac_learn_lock);
594 adapter->fhash.fnum--; 603 adapter->fhash.fnum--;
595 hlist_del(&tmp_fil->fnode); 604 hlist_del(&tmp_fil->fnode);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h
index 937d75f939aa..9673e2bcff06 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h
@@ -36,6 +36,14 @@ enum qlcnic_regs {
36#define QLC_SHARED_REG_WR32(a, addr, value) \ 36#define QLC_SHARED_REG_WR32(a, addr, value) \
37 writel(value, ((a)->ahw->pci_base0) + ((a)->ahw->reg_tbl[addr])) 37 writel(value, ((a)->ahw->pci_base0) + ((a)->ahw->reg_tbl[addr]))
38 38
39/* Read from a direct address offset from BAR0, additional registers */
40#define QLCRDX(ahw, addr) \
41 readl(((ahw)->pci_base0) + ((ahw)->ext_reg_tbl[addr]))
42
43/* Write to a direct address offset from BAR0, additional registers */
44#define QLCWRX(ahw, addr, value) \
45 writel(value, (((ahw)->pci_base0) + ((ahw)->ext_reg_tbl[addr])))
46
39#define QLCNIC_CMD_CONFIGURE_IP_ADDR 0x1 47#define QLCNIC_CMD_CONFIGURE_IP_ADDR 0x1
40#define QLCNIC_CMD_CONFIG_INTRPT 0x2 48#define QLCNIC_CMD_CONFIG_INTRPT 0x2
41#define QLCNIC_CMD_CREATE_RX_CTX 0x7 49#define QLCNIC_CMD_CREATE_RX_CTX 0x7
@@ -85,6 +93,7 @@ enum qlcnic_regs {
85#define QLCNIC_CMD_GET_LINK_STATUS 0x68 93#define QLCNIC_CMD_GET_LINK_STATUS 0x68
86#define QLCNIC_CMD_SET_LED_CONFIG 0x69 94#define QLCNIC_CMD_SET_LED_CONFIG 0x69
87#define QLCNIC_CMD_GET_LED_CONFIG 0x6A 95#define QLCNIC_CMD_GET_LED_CONFIG 0x6A
96#define QLCNIC_CMD_ADD_RCV_RINGS 0x0B
88 97
89#define QLCNIC_INTRPT_INTX 1 98#define QLCNIC_INTRPT_INTX 1
90#define QLCNIC_INTRPT_MSIX 3 99#define QLCNIC_INTRPT_MSIX 3
@@ -110,6 +119,13 @@ struct qlcnic_mailbox_metadata {
110 u32 out_args; 119 u32 out_args;
111}; 120};
112 121
122/* Mailbox ownership */
123#define QLCNIC_GET_OWNER(val) ((val) & (BIT_0 | BIT_1))
124
125#define QLCNIC_SET_OWNER 1
126#define QLCNIC_CLR_OWNER 0
127#define QLCNIC_MBX_TIMEOUT 10000
128
113#define QLCNIC_MBX_RSP_OK 1 129#define QLCNIC_MBX_RSP_OK 1
114#define QLCNIC_MBX_PORT_RSP_OK 0x1a 130#define QLCNIC_MBX_PORT_RSP_OK 0x1a
115 131
@@ -166,4 +182,5 @@ int qlcnic_82xx_api_lock(struct qlcnic_adapter *);
166void qlcnic_82xx_api_unlock(struct qlcnic_adapter *); 182void qlcnic_82xx_api_unlock(struct qlcnic_adapter *);
167void qlcnic_82xx_napi_enable(struct qlcnic_adapter *); 183void qlcnic_82xx_napi_enable(struct qlcnic_adapter *);
168void qlcnic_82xx_napi_disable(struct qlcnic_adapter *); 184void qlcnic_82xx_napi_disable(struct qlcnic_adapter *);
185void qlcnic_82xx_napi_del(struct qlcnic_adapter *);
169#endif /* __QLCNIC_HW_H_ */ 186#endif /* __QLCNIC_HW_H_ */
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
index 8d9202fe2dee..d678e6d763e1 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
@@ -487,8 +487,7 @@ drop_packet:
487 return NETDEV_TX_OK; 487 return NETDEV_TX_OK;
488} 488}
489 489
490static void qlcnic_advert_link_change(struct qlcnic_adapter *adapter, 490void qlcnic_advert_link_change(struct qlcnic_adapter *adapter, int linkup)
491 int linkup)
492{ 491{
493 struct net_device *netdev = adapter->netdev; 492 struct net_device *netdev = adapter->netdev;
494 493
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 73b4f670e1c2..9498b39770bb 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -347,7 +347,7 @@ static struct qlcnic_hardware_ops qlcnic_hw_ops = {
347 .get_board_info = qlcnic_82xx_get_board_info, 347 .get_board_info = qlcnic_82xx_get_board_info,
348}; 348};
349 349
350static int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix) 350int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix)
351{ 351{
352 struct pci_dev *pdev = adapter->pdev; 352 struct pci_dev *pdev = adapter->pdev;
353 int err = -1; 353 int err = -1;