aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/qlogic/qlcnic
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-04-02 23:53:45 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-04-02 23:53:45 -0400
commitcd6362befe4cc7bf589a5236d2a780af2d47bcc9 (patch)
tree3bd4e13ec3f92a00dc4f6c3d65e820b54dbfe46e /drivers/net/ethernet/qlogic/qlcnic
parent0f1b1e6d73cb989ce2c071edc57deade3b084dfe (diff)
parentb1586f099ba897542ece36e8a23c1a62907261ef (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking updates from David Miller: "Here is my initial pull request for the networking subsystem during this merge window: 1) Support for ESN in AH (RFC 4302) from Fan Du. 2) Add full kernel doc for ethtool command structures, from Ben Hutchings. 3) Add BCM7xxx PHY driver, from Florian Fainelli. 4) Export computed TCP rate information in netlink socket dumps, from Eric Dumazet. 5) Allow IPSEC SA to be dumped partially using a filter, from Nicolas Dichtel. 6) Convert many drivers to pci_enable_msix_range(), from Alexander Gordeev. 7) Record SKB timestamps more efficiently, from Eric Dumazet. 8) Switch to microsecond resolution for TCP round trip times, also from Eric Dumazet. 9) Clean up and fix 6lowpan fragmentation handling by making use of the existing inet_frag api for it's implementation. 10) Add TX grant mapping to xen-netback driver, from Zoltan Kiss. 11) Auto size SKB lengths when composing netlink messages based upon past message sizes used, from Eric Dumazet. 12) qdisc dumps can take a long time, add a cond_resched(), From Eric Dumazet. 13) Sanitize netpoll core and drivers wrt. SKB handling semantics. Get rid of never-used-in-tree netpoll RX handling. From Eric W Biederman. 14) Support inter-address-family and namespace changing in VTI tunnel driver(s). From Steffen Klassert. 15) Add Altera TSE driver, from Vince Bridgers. 16) Optimizing csum_replace2() so that it doesn't adjust the checksum by checksumming the entire header, from Eric Dumazet. 17) Expand BPF internal implementation for faster interpreting, more direct translations into JIT'd code, and much cleaner uses of BPF filtering in non-socket ocntexts. From Daniel Borkmann and Alexei Starovoitov" * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1976 commits) netpoll: Use skb_irq_freeable to make zap_completion_queue safe. net: Add a test to see if a skb is freeable in irq context qlcnic: Fix build failure due to undefined reference to `vxlan_get_rx_port' net: ptp: move PTP classifier in its own file net: sxgbe: make "core_ops" static net: sxgbe: fix logical vs bitwise operation net: sxgbe: sxgbe_mdio_register() frees the bus Call efx_set_channels() before efx->type->dimension_resources() xen-netback: disable rogue vif in kthread context net/mlx4: Set proper build dependancy with vxlan be2net: fix build dependency on VxLAN mac802154: make csma/cca parameters per-wpan mac802154: allow only one WPAN to be up at any given time net: filter: minor: fix kdoc in __sk_run_filter netlink: don't compare the nul-termination in nla_strcmp can: c_can: Avoid led toggling for every packet. can: c_can: Simplify TX interrupt cleanup can: c_can: Store dlc private can: c_can: Reduce register access can: c_can: Make the code readable ...
Diffstat (limited to 'drivers/net/ethernet/qlogic/qlcnic')
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic.h121
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c10
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h11
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c91
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c23
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c22
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h9
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c179
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c85
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c233
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c6
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c102
12 files changed, 710 insertions, 182 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index f19f81cde134..f31bb5e9d8a9 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -38,8 +38,8 @@
38 38
39#define _QLCNIC_LINUX_MAJOR 5 39#define _QLCNIC_LINUX_MAJOR 5
40#define _QLCNIC_LINUX_MINOR 3 40#define _QLCNIC_LINUX_MINOR 3
41#define _QLCNIC_LINUX_SUBVERSION 55 41#define _QLCNIC_LINUX_SUBVERSION 57
42#define QLCNIC_LINUX_VERSIONID "5.3.55" 42#define QLCNIC_LINUX_VERSIONID "5.3.57"
43#define QLCNIC_DRV_IDC_VER 0x01 43#define QLCNIC_DRV_IDC_VER 0x01
44#define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ 44#define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\
45 (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) 45 (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION))
@@ -169,11 +169,20 @@ struct cmd_desc_type0 {
169 169
170 __le64 addr_buffer2; 170 __le64 addr_buffer2;
171 171
172 __le16 reference_handle; 172 __le16 encap_descr; /* 15:10 offset of outer L3 header,
173 * 9:6 number of 32bit words in outer L3 header,
174 * 5 offload outer L4 checksum,
175 * 4 offload outer L3 checksum,
176 * 3 Inner L4 type, TCP=0, UDP=1,
177 * 2 Inner L3 type, IPv4=0, IPv6=1,
178 * 1 Outer L3 type,IPv4=0, IPv6=1,
179 * 0 type of encapsulation, GRE=0, VXLAN=1
180 */
173 __le16 mss; 181 __le16 mss;
174 u8 port_ctxid; /* 7:4 ctxid 3:0 port */ 182 u8 port_ctxid; /* 7:4 ctxid 3:0 port */
175 u8 total_hdr_length; /* LSO only : MAC+IP+TCP Hdr size */ 183 u8 hdr_length; /* LSO only : MAC+IP+TCP Hdr size */
176 __le16 conn_id; /* IPSec offoad only */ 184 u8 outer_hdr_length; /* Encapsulation only */
185 u8 rsvd1;
177 186
178 __le64 addr_buffer3; 187 __le64 addr_buffer3;
179 __le64 addr_buffer1; 188 __le64 addr_buffer1;
@@ -183,7 +192,9 @@ struct cmd_desc_type0 {
183 __le64 addr_buffer4; 192 __le64 addr_buffer4;
184 193
185 u8 eth_addr[ETH_ALEN]; 194 u8 eth_addr[ETH_ALEN];
186 __le16 vlan_TCI; 195 __le16 vlan_TCI; /* In case of encapsulation,
196 * this is for outer VLAN
197 */
187 198
188} __attribute__ ((aligned(64))); 199} __attribute__ ((aligned(64)));
189 200
@@ -394,7 +405,7 @@ struct qlcnic_nic_intr_coalesce {
394 u32 timer_out; 405 u32 timer_out;
395}; 406};
396 407
397struct qlcnic_dump_template_hdr { 408struct qlcnic_83xx_dump_template_hdr {
398 u32 type; 409 u32 type;
399 u32 offset; 410 u32 offset;
400 u32 size; 411 u32 size;
@@ -411,15 +422,42 @@ struct qlcnic_dump_template_hdr {
411 u32 rsvd[0]; 422 u32 rsvd[0];
412}; 423};
413 424
425struct qlcnic_82xx_dump_template_hdr {
426 u32 type;
427 u32 offset;
428 u32 size;
429 u32 cap_mask;
430 u32 num_entries;
431 u32 version;
432 u32 timestamp;
433 u32 checksum;
434 u32 drv_cap_mask;
435 u32 sys_info[3];
436 u32 saved_state[16];
437 u32 cap_sizes[8];
438 u32 rsvd[7];
439 u32 capabilities;
440 u32 rsvd1[0];
441};
442
414struct qlcnic_fw_dump { 443struct qlcnic_fw_dump {
415 u8 clr; /* flag to indicate if dump is cleared */ 444 u8 clr; /* flag to indicate if dump is cleared */
416 bool enable; /* enable/disable dump */ 445 bool enable; /* enable/disable dump */
417 u32 size; /* total size of the dump */ 446 u32 size; /* total size of the dump */
447 u32 cap_mask; /* Current capture mask */
418 void *data; /* dump data area */ 448 void *data; /* dump data area */
419 struct qlcnic_dump_template_hdr *tmpl_hdr; 449 void *tmpl_hdr;
420 dma_addr_t phys_addr; 450 dma_addr_t phys_addr;
421 void *dma_buffer; 451 void *dma_buffer;
422 bool use_pex_dma; 452 bool use_pex_dma;
453 /* Read only elements which are common between 82xx and 83xx
454 * template header. Update these values immediately after we read
455 * template header from Firmware
456 */
457 u32 tmpl_hdr_size;
458 u32 version;
459 u32 num_entries;
460 u32 offset;
423}; 461};
424 462
425/* 463/*
@@ -497,6 +535,7 @@ struct qlcnic_hardware_context {
497 u8 extend_lb_time; 535 u8 extend_lb_time;
498 u8 phys_port_id[ETH_ALEN]; 536 u8 phys_port_id[ETH_ALEN];
499 u8 lb_mode; 537 u8 lb_mode;
538 u16 vxlan_port;
500}; 539};
501 540
502struct qlcnic_adapter_stats { 541struct qlcnic_adapter_stats {
@@ -511,6 +550,9 @@ struct qlcnic_adapter_stats {
511 u64 txbytes; 550 u64 txbytes;
512 u64 lrobytes; 551 u64 lrobytes;
513 u64 lso_frames; 552 u64 lso_frames;
553 u64 encap_lso_frames;
554 u64 encap_tx_csummed;
555 u64 encap_rx_csummed;
514 u64 xmit_on; 556 u64 xmit_on;
515 u64 xmit_off; 557 u64 xmit_off;
516 u64 skb_alloc_failure; 558 u64 skb_alloc_failure;
@@ -872,6 +914,10 @@ struct qlcnic_mac_vlan_list {
872#define QLCNIC_FW_CAPABILITY_2_BEACON BIT_7 914#define QLCNIC_FW_CAPABILITY_2_BEACON BIT_7
873#define QLCNIC_FW_CAPABILITY_2_PER_PORT_ESWITCH_CFG BIT_9 915#define QLCNIC_FW_CAPABILITY_2_PER_PORT_ESWITCH_CFG BIT_9
874 916
917#define QLCNIC_83XX_FW_CAPAB_ENCAP_RX_OFFLOAD BIT_0
918#define QLCNIC_83XX_FW_CAPAB_ENCAP_TX_OFFLOAD BIT_1
919#define QLCNIC_83XX_FW_CAPAB_ENCAP_CKO_OFFLOAD BIT_4
920
875/* module types */ 921/* module types */
876#define LINKEVENT_MODULE_NOT_PRESENT 1 922#define LINKEVENT_MODULE_NOT_PRESENT 1
877#define LINKEVENT_MODULE_OPTICAL_UNKNOWN 2 923#define LINKEVENT_MODULE_OPTICAL_UNKNOWN 2
@@ -966,6 +1012,11 @@ struct qlcnic_ipaddr {
966#define QLCNIC_HAS_PHYS_PORT_ID 0x40000 1012#define QLCNIC_HAS_PHYS_PORT_ID 0x40000
967#define QLCNIC_TSS_RSS 0x80000 1013#define QLCNIC_TSS_RSS 0x80000
968 1014
1015#ifdef CONFIG_QLCNIC_VXLAN
1016#define QLCNIC_ADD_VXLAN_PORT 0x100000
1017#define QLCNIC_DEL_VXLAN_PORT 0x200000
1018#endif
1019
969#define QLCNIC_IS_MSI_FAMILY(adapter) \ 1020#define QLCNIC_IS_MSI_FAMILY(adapter) \
970 ((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED)) 1021 ((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED))
971#define QLCNIC_IS_TSO_CAPABLE(adapter) \ 1022#define QLCNIC_IS_TSO_CAPABLE(adapter) \
@@ -1769,10 +1820,28 @@ struct qlcnic_hardware_ops {
1769 struct qlcnic_host_tx_ring *); 1820 struct qlcnic_host_tx_ring *);
1770 void (*disable_tx_intr) (struct qlcnic_adapter *, 1821 void (*disable_tx_intr) (struct qlcnic_adapter *,
1771 struct qlcnic_host_tx_ring *); 1822 struct qlcnic_host_tx_ring *);
1823 u32 (*get_saved_state)(void *, u32);
1824 void (*set_saved_state)(void *, u32, u32);
1825 void (*cache_tmpl_hdr_values)(struct qlcnic_fw_dump *);
1826 u32 (*get_cap_size)(void *, int);
1827 void (*set_sys_info)(void *, int, u32);
1828 void (*store_cap_mask)(void *, u32);
1772}; 1829};
1773 1830
1774extern struct qlcnic_nic_template qlcnic_vf_ops; 1831extern struct qlcnic_nic_template qlcnic_vf_ops;
1775 1832
1833static inline bool qlcnic_encap_tx_offload(struct qlcnic_adapter *adapter)
1834{
1835 return adapter->ahw->extra_capability[0] &
1836 QLCNIC_83XX_FW_CAPAB_ENCAP_TX_OFFLOAD;
1837}
1838
1839static inline bool qlcnic_encap_rx_offload(struct qlcnic_adapter *adapter)
1840{
1841 return adapter->ahw->extra_capability[0] &
1842 QLCNIC_83XX_FW_CAPAB_ENCAP_RX_OFFLOAD;
1843}
1844
1776static inline int qlcnic_start_firmware(struct qlcnic_adapter *adapter) 1845static inline int qlcnic_start_firmware(struct qlcnic_adapter *adapter)
1777{ 1846{
1778 return adapter->nic_ops->start_firmware(adapter); 1847 return adapter->nic_ops->start_firmware(adapter);
@@ -2007,6 +2076,42 @@ static inline void qlcnic_read_phys_port_id(struct qlcnic_adapter *adapter)
2007 adapter->ahw->hw_ops->read_phys_port_id(adapter); 2076 adapter->ahw->hw_ops->read_phys_port_id(adapter);
2008} 2077}
2009 2078
2079static inline u32 qlcnic_get_saved_state(struct qlcnic_adapter *adapter,
2080 void *t_hdr, u32 index)
2081{
2082 return adapter->ahw->hw_ops->get_saved_state(t_hdr, index);
2083}
2084
2085static inline void qlcnic_set_saved_state(struct qlcnic_adapter *adapter,
2086 void *t_hdr, u32 index, u32 value)
2087{
2088 adapter->ahw->hw_ops->set_saved_state(t_hdr, index, value);
2089}
2090
2091static inline void qlcnic_cache_tmpl_hdr_values(struct qlcnic_adapter *adapter,
2092 struct qlcnic_fw_dump *fw_dump)
2093{
2094 adapter->ahw->hw_ops->cache_tmpl_hdr_values(fw_dump);
2095}
2096
2097static inline u32 qlcnic_get_cap_size(struct qlcnic_adapter *adapter,
2098 void *tmpl_hdr, int index)
2099{
2100 return adapter->ahw->hw_ops->get_cap_size(tmpl_hdr, index);
2101}
2102
2103static inline void qlcnic_set_sys_info(struct qlcnic_adapter *adapter,
2104 void *tmpl_hdr, int idx, u32 value)
2105{
2106 adapter->ahw->hw_ops->set_sys_info(tmpl_hdr, idx, value);
2107}
2108
2109static inline void qlcnic_store_cap_mask(struct qlcnic_adapter *adapter,
2110 void *tmpl_hdr, u32 mask)
2111{
2112 adapter->ahw->hw_ops->store_cap_mask(tmpl_hdr, mask);
2113}
2114
2010static inline void qlcnic_dev_request_reset(struct qlcnic_adapter *adapter, 2115static inline void qlcnic_dev_request_reset(struct qlcnic_adapter *adapter,
2011 u32 key) 2116 u32 key)
2012{ 2117{
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
index 27c4f131863b..b7cffb46a75d 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -77,7 +77,7 @@ static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = {
77 {QLCNIC_CMD_GET_PORT_CONFIG, 2, 2}, 77 {QLCNIC_CMD_GET_PORT_CONFIG, 2, 2},
78 {QLCNIC_CMD_GET_LINK_STATUS, 2, 4}, 78 {QLCNIC_CMD_GET_LINK_STATUS, 2, 4},
79 {QLCNIC_CMD_IDC_ACK, 5, 1}, 79 {QLCNIC_CMD_IDC_ACK, 5, 1},
80 {QLCNIC_CMD_INIT_NIC_FUNC, 2, 1}, 80 {QLCNIC_CMD_INIT_NIC_FUNC, 3, 1},
81 {QLCNIC_CMD_STOP_NIC_FUNC, 2, 1}, 81 {QLCNIC_CMD_STOP_NIC_FUNC, 2, 1},
82 {QLCNIC_CMD_SET_LED_CONFIG, 5, 1}, 82 {QLCNIC_CMD_SET_LED_CONFIG, 5, 1},
83 {QLCNIC_CMD_GET_LED_CONFIG, 1, 5}, 83 {QLCNIC_CMD_GET_LED_CONFIG, 1, 5},
@@ -87,6 +87,7 @@ static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = {
87 {QLCNIC_CMD_BC_EVENT_SETUP, 2, 1}, 87 {QLCNIC_CMD_BC_EVENT_SETUP, 2, 1},
88 {QLCNIC_CMD_DCB_QUERY_CAP, 1, 2}, 88 {QLCNIC_CMD_DCB_QUERY_CAP, 1, 2},
89 {QLCNIC_CMD_DCB_QUERY_PARAM, 1, 50}, 89 {QLCNIC_CMD_DCB_QUERY_PARAM, 1, 50},
90 {QLCNIC_CMD_SET_INGRESS_ENCAP, 2, 1},
90}; 91};
91 92
92const u32 qlcnic_83xx_ext_reg_tbl[] = { 93const u32 qlcnic_83xx_ext_reg_tbl[] = {
@@ -203,7 +204,12 @@ static struct qlcnic_hardware_ops qlcnic_83xx_hw_ops = {
203 .disable_sds_intr = qlcnic_83xx_disable_sds_intr, 204 .disable_sds_intr = qlcnic_83xx_disable_sds_intr,
204 .enable_tx_intr = qlcnic_83xx_enable_tx_intr, 205 .enable_tx_intr = qlcnic_83xx_enable_tx_intr,
205 .disable_tx_intr = qlcnic_83xx_disable_tx_intr, 206 .disable_tx_intr = qlcnic_83xx_disable_tx_intr,
206 207 .get_saved_state = qlcnic_83xx_get_saved_state,
208 .set_saved_state = qlcnic_83xx_set_saved_state,
209 .cache_tmpl_hdr_values = qlcnic_83xx_cache_tmpl_hdr_values,
210 .get_cap_size = qlcnic_83xx_get_cap_size,
211 .set_sys_info = qlcnic_83xx_set_sys_info,
212 .store_cap_mask = qlcnic_83xx_store_cap_mask,
207}; 213};
208 214
209static struct qlcnic_nic_template qlcnic_83xx_ops = { 215static struct qlcnic_nic_template qlcnic_83xx_ops = {
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
index f92485ca21d1..88d809c35633 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
@@ -308,6 +308,8 @@ struct qlc_83xx_reset {
308#define QLC_83XX_IDC_FLASH_PARAM_ADDR 0x3e8020 308#define QLC_83XX_IDC_FLASH_PARAM_ADDR 0x3e8020
309 309
310struct qlcnic_adapter; 310struct qlcnic_adapter;
311struct qlcnic_fw_dump;
312
311struct qlc_83xx_idc { 313struct qlc_83xx_idc {
312 int (*state_entry) (struct qlcnic_adapter *); 314 int (*state_entry) (struct qlcnic_adapter *);
313 u64 sec_counter; 315 u64 sec_counter;
@@ -526,8 +528,9 @@ enum qlc_83xx_ext_regs {
526}; 528};
527 529
528/* Initialize/Stop NIC command bit definitions */ 530/* Initialize/Stop NIC command bit definitions */
529#define QLC_REGISTER_DCB_AEN BIT_1
530#define QLC_REGISTER_LB_IDC BIT_0 531#define QLC_REGISTER_LB_IDC BIT_0
532#define QLC_REGISTER_DCB_AEN BIT_1
533#define QLC_83XX_MULTI_TENANCY_INFO BIT_29
531#define QLC_INIT_FW_RESOURCES BIT_31 534#define QLC_INIT_FW_RESOURCES BIT_31
532 535
533/* 83xx funcitons */ 536/* 83xx funcitons */
@@ -650,4 +653,10 @@ int qlcnic_83xx_check_vnic_state(struct qlcnic_adapter *);
650void qlcnic_83xx_aer_stop_poll_work(struct qlcnic_adapter *); 653void qlcnic_83xx_aer_stop_poll_work(struct qlcnic_adapter *);
651int qlcnic_83xx_aer_reset(struct qlcnic_adapter *); 654int qlcnic_83xx_aer_reset(struct qlcnic_adapter *);
652void qlcnic_83xx_aer_start_poll_work(struct qlcnic_adapter *); 655void qlcnic_83xx_aer_start_poll_work(struct qlcnic_adapter *);
656u32 qlcnic_83xx_get_saved_state(void *, u32);
657void qlcnic_83xx_set_saved_state(void *, u32, u32);
658void qlcnic_83xx_cache_tmpl_hdr_values(struct qlcnic_fw_dump *);
659u32 qlcnic_83xx_get_cap_size(void *, int);
660void qlcnic_83xx_set_sys_info(void *, int, u32);
661void qlcnic_83xx_store_cap_mask(void *, u32);
653#endif 662#endif
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
index 90a2dda351ec..b48737dcd3c5 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
@@ -1020,10 +1020,99 @@ static int qlcnic_83xx_idc_check_state_validity(struct qlcnic_adapter *adapter,
1020 return 0; 1020 return 0;
1021} 1021}
1022 1022
1023#ifdef CONFIG_QLCNIC_VXLAN
1024#define QLC_83XX_ENCAP_TYPE_VXLAN BIT_1
1025#define QLC_83XX_MATCH_ENCAP_ID BIT_2
1026#define QLC_83XX_SET_VXLAN_UDP_DPORT BIT_3
1027#define QLC_83XX_VXLAN_UDP_DPORT(PORT) ((PORT & 0xffff) << 16)
1028
1029#define QLCNIC_ENABLE_INGRESS_ENCAP_PARSING 1
1030#define QLCNIC_DISABLE_INGRESS_ENCAP_PARSING 0
1031
1032static int qlcnic_set_vxlan_port(struct qlcnic_adapter *adapter)
1033{
1034 u16 port = adapter->ahw->vxlan_port;
1035 struct qlcnic_cmd_args cmd;
1036 int ret = 0;
1037
1038 memset(&cmd, 0, sizeof(cmd));
1039
1040 ret = qlcnic_alloc_mbx_args(&cmd, adapter,
1041 QLCNIC_CMD_INIT_NIC_FUNC);
1042 if (ret)
1043 return ret;
1044
1045 cmd.req.arg[1] = QLC_83XX_MULTI_TENANCY_INFO;
1046 cmd.req.arg[2] = QLC_83XX_ENCAP_TYPE_VXLAN |
1047 QLC_83XX_SET_VXLAN_UDP_DPORT |
1048 QLC_83XX_VXLAN_UDP_DPORT(port);
1049
1050 ret = qlcnic_issue_cmd(adapter, &cmd);
1051 if (ret)
1052 netdev_err(adapter->netdev,
1053 "Failed to set VXLAN port %d in adapter\n",
1054 port);
1055
1056 qlcnic_free_mbx_args(&cmd);
1057
1058 return ret;
1059}
1060
1061static int qlcnic_set_vxlan_parsing(struct qlcnic_adapter *adapter,
1062 bool state)
1063{
1064 u16 vxlan_port = adapter->ahw->vxlan_port;
1065 struct qlcnic_cmd_args cmd;
1066 int ret = 0;
1067
1068 memset(&cmd, 0, sizeof(cmd));
1069
1070 ret = qlcnic_alloc_mbx_args(&cmd, adapter,
1071 QLCNIC_CMD_SET_INGRESS_ENCAP);
1072 if (ret)
1073 return ret;
1074
1075 cmd.req.arg[1] = state ? QLCNIC_ENABLE_INGRESS_ENCAP_PARSING :
1076 QLCNIC_DISABLE_INGRESS_ENCAP_PARSING;
1077
1078 ret = qlcnic_issue_cmd(adapter, &cmd);
1079 if (ret)
1080 netdev_err(adapter->netdev,
1081 "Failed to %s VXLAN parsing for port %d\n",
1082 state ? "enable" : "disable", vxlan_port);
1083 else
1084 netdev_info(adapter->netdev,
1085 "%s VXLAN parsing for port %d\n",
1086 state ? "Enabled" : "Disabled", vxlan_port);
1087
1088 qlcnic_free_mbx_args(&cmd);
1089
1090 return ret;
1091}
1092#endif
1093
1023static void qlcnic_83xx_periodic_tasks(struct qlcnic_adapter *adapter) 1094static void qlcnic_83xx_periodic_tasks(struct qlcnic_adapter *adapter)
1024{ 1095{
1025 if (adapter->fhash.fnum) 1096 if (adapter->fhash.fnum)
1026 qlcnic_prune_lb_filters(adapter); 1097 qlcnic_prune_lb_filters(adapter);
1098
1099#ifdef CONFIG_QLCNIC_VXLAN
1100 if (adapter->flags & QLCNIC_ADD_VXLAN_PORT) {
1101 if (qlcnic_set_vxlan_port(adapter))
1102 return;
1103
1104 if (qlcnic_set_vxlan_parsing(adapter, true))
1105 return;
1106
1107 adapter->flags &= ~QLCNIC_ADD_VXLAN_PORT;
1108 } else if (adapter->flags & QLCNIC_DEL_VXLAN_PORT) {
1109 if (qlcnic_set_vxlan_parsing(adapter, false))
1110 return;
1111
1112 adapter->ahw->vxlan_port = 0;
1113 adapter->flags &= ~QLCNIC_DEL_VXLAN_PORT;
1114 }
1115#endif
1027} 1116}
1028 1117
1029/** 1118/**
@@ -1301,7 +1390,7 @@ static int qlcnic_83xx_copy_fw_file(struct qlcnic_adapter *adapter)
1301 addr = (u64)dest; 1390 addr = (u64)dest;
1302 1391
1303 ret = qlcnic_83xx_ms_mem_write128(adapter, addr, 1392 ret = qlcnic_83xx_ms_mem_write128(adapter, addr,
1304 (u32 *)p_cache, size / 16); 1393 p_cache, size / 16);
1305 if (ret) { 1394 if (ret) {
1306 dev_err(&adapter->pdev->dev, "MS memory write failed\n"); 1395 dev_err(&adapter->pdev->dev, "MS memory write failed\n");
1307 release_firmware(fw); 1396 release_firmware(fw);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
index acee1a5d80c6..5bacf5210aed 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
@@ -47,6 +47,12 @@ static const struct qlcnic_stats qlcnic_gstrings_stats[] = {
47 {"lro_pkts", QLC_SIZEOF(stats.lro_pkts), QLC_OFF(stats.lro_pkts)}, 47 {"lro_pkts", QLC_SIZEOF(stats.lro_pkts), QLC_OFF(stats.lro_pkts)},
48 {"lrobytes", QLC_SIZEOF(stats.lrobytes), QLC_OFF(stats.lrobytes)}, 48 {"lrobytes", QLC_SIZEOF(stats.lrobytes), QLC_OFF(stats.lrobytes)},
49 {"lso_frames", QLC_SIZEOF(stats.lso_frames), QLC_OFF(stats.lso_frames)}, 49 {"lso_frames", QLC_SIZEOF(stats.lso_frames), QLC_OFF(stats.lso_frames)},
50 {"encap_lso_frames", QLC_SIZEOF(stats.encap_lso_frames),
51 QLC_OFF(stats.encap_lso_frames)},
52 {"encap_tx_csummed", QLC_SIZEOF(stats.encap_tx_csummed),
53 QLC_OFF(stats.encap_tx_csummed)},
54 {"encap_rx_csummed", QLC_SIZEOF(stats.encap_rx_csummed),
55 QLC_OFF(stats.encap_rx_csummed)},
50 {"skb_alloc_failure", QLC_SIZEOF(stats.skb_alloc_failure), 56 {"skb_alloc_failure", QLC_SIZEOF(stats.skb_alloc_failure),
51 QLC_OFF(stats.skb_alloc_failure)}, 57 QLC_OFF(stats.skb_alloc_failure)},
52 {"mac_filter_limit_overrun", QLC_SIZEOF(stats.mac_filter_limit_overrun), 58 {"mac_filter_limit_overrun", QLC_SIZEOF(stats.mac_filter_limit_overrun),
@@ -1639,14 +1645,14 @@ qlcnic_get_dump_flag(struct net_device *netdev, struct ethtool_dump *dump)
1639 } 1645 }
1640 1646
1641 if (fw_dump->clr) 1647 if (fw_dump->clr)
1642 dump->len = fw_dump->tmpl_hdr->size + fw_dump->size; 1648 dump->len = fw_dump->tmpl_hdr_size + fw_dump->size;
1643 else 1649 else
1644 dump->len = 0; 1650 dump->len = 0;
1645 1651
1646 if (!qlcnic_check_fw_dump_state(adapter)) 1652 if (!qlcnic_check_fw_dump_state(adapter))
1647 dump->flag = ETH_FW_DUMP_DISABLE; 1653 dump->flag = ETH_FW_DUMP_DISABLE;
1648 else 1654 else
1649 dump->flag = fw_dump->tmpl_hdr->drv_cap_mask; 1655 dump->flag = fw_dump->cap_mask;
1650 1656
1651 dump->version = adapter->fw_version; 1657 dump->version = adapter->fw_version;
1652 return 0; 1658 return 0;
@@ -1671,9 +1677,10 @@ qlcnic_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump,
1671 netdev_info(netdev, "Dump not available\n"); 1677 netdev_info(netdev, "Dump not available\n");
1672 return -EINVAL; 1678 return -EINVAL;
1673 } 1679 }
1680
1674 /* Copy template header first */ 1681 /* Copy template header first */
1675 copy_sz = fw_dump->tmpl_hdr->size; 1682 copy_sz = fw_dump->tmpl_hdr_size;
1676 hdr_ptr = (u32 *) fw_dump->tmpl_hdr; 1683 hdr_ptr = (u32 *)fw_dump->tmpl_hdr;
1677 data = buffer; 1684 data = buffer;
1678 for (i = 0; i < copy_sz/sizeof(u32); i++) 1685 for (i = 0; i < copy_sz/sizeof(u32); i++)
1679 *data++ = cpu_to_le32(*hdr_ptr++); 1686 *data++ = cpu_to_le32(*hdr_ptr++);
@@ -1681,7 +1688,7 @@ qlcnic_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump,
1681 /* Copy captured dump data */ 1688 /* Copy captured dump data */
1682 memcpy(buffer + copy_sz, fw_dump->data, fw_dump->size); 1689 memcpy(buffer + copy_sz, fw_dump->data, fw_dump->size);
1683 dump->len = copy_sz + fw_dump->size; 1690 dump->len = copy_sz + fw_dump->size;
1684 dump->flag = fw_dump->tmpl_hdr->drv_cap_mask; 1691 dump->flag = fw_dump->cap_mask;
1685 1692
1686 /* Free dump area once data has been captured */ 1693 /* Free dump area once data has been captured */
1687 vfree(fw_dump->data); 1694 vfree(fw_dump->data);
@@ -1703,7 +1710,11 @@ static int qlcnic_set_dump_mask(struct qlcnic_adapter *adapter, u32 mask)
1703 return -EOPNOTSUPP; 1710 return -EOPNOTSUPP;
1704 } 1711 }
1705 1712
1706 fw_dump->tmpl_hdr->drv_cap_mask = mask; 1713 fw_dump->cap_mask = mask;
1714
1715 /* Store new capture mask in template header as well*/
1716 qlcnic_store_cap_mask(adapter, fw_dump->tmpl_hdr, mask);
1717
1707 netdev_info(netdev, "Driver mask changed to: 0x%x\n", mask); 1718 netdev_info(netdev, "Driver mask changed to: 0x%x\n", mask);
1708 return 0; 1719 return 0;
1709} 1720}
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
index 03d18a0be6ce..9f3adf4e70b5 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
@@ -317,9 +317,7 @@ static void qlcnic_write_window_reg(u32 addr, void __iomem *bar0, u32 data)
317int 317int
318qlcnic_pcie_sem_lock(struct qlcnic_adapter *adapter, int sem, u32 id_reg) 318qlcnic_pcie_sem_lock(struct qlcnic_adapter *adapter, int sem, u32 id_reg)
319{ 319{
320 int timeout = 0; 320 int timeout = 0, err = 0, done = 0;
321 int err = 0;
322 u32 done = 0;
323 321
324 while (!done) { 322 while (!done) {
325 done = QLCRD32(adapter, QLCNIC_PCIE_REG(PCIE_SEM_LOCK(sem)), 323 done = QLCRD32(adapter, QLCNIC_PCIE_REG(PCIE_SEM_LOCK(sem)),
@@ -327,10 +325,20 @@ qlcnic_pcie_sem_lock(struct qlcnic_adapter *adapter, int sem, u32 id_reg)
327 if (done == 1) 325 if (done == 1)
328 break; 326 break;
329 if (++timeout >= QLCNIC_PCIE_SEM_TIMEOUT) { 327 if (++timeout >= QLCNIC_PCIE_SEM_TIMEOUT) {
330 dev_err(&adapter->pdev->dev, 328 if (id_reg) {
331 "Failed to acquire sem=%d lock; holdby=%d\n", 329 done = QLCRD32(adapter, id_reg, &err);
332 sem, 330 if (done != -1)
333 id_reg ? QLCRD32(adapter, id_reg, &err) : -1); 331 dev_err(&adapter->pdev->dev,
332 "Failed to acquire sem=%d lock held by=%d\n",
333 sem, done);
334 else
335 dev_err(&adapter->pdev->dev,
336 "Failed to acquire sem=%d lock",
337 sem);
338 } else {
339 dev_err(&adapter->pdev->dev,
340 "Failed to acquire sem=%d lock", sem);
341 }
334 return -EIO; 342 return -EIO;
335 } 343 }
336 msleep(1); 344 msleep(1);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h
index 63d75617d445..cbe2399c30a0 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h
@@ -98,6 +98,7 @@ enum qlcnic_regs {
98#define QLCNIC_CMD_GET_LINK_EVENT 0x48 98#define QLCNIC_CMD_GET_LINK_EVENT 0x48
99#define QLCNIC_CMD_CONFIGURE_MAC_RX_MODE 0x49 99#define QLCNIC_CMD_CONFIGURE_MAC_RX_MODE 0x49
100#define QLCNIC_CMD_CONFIGURE_HW_LRO 0x4A 100#define QLCNIC_CMD_CONFIGURE_HW_LRO 0x4A
101#define QLCNIC_CMD_SET_INGRESS_ENCAP 0x4E
101#define QLCNIC_CMD_INIT_NIC_FUNC 0x60 102#define QLCNIC_CMD_INIT_NIC_FUNC 0x60
102#define QLCNIC_CMD_STOP_NIC_FUNC 0x61 103#define QLCNIC_CMD_STOP_NIC_FUNC 0x61
103#define QLCNIC_CMD_IDC_ACK 0x63 104#define QLCNIC_CMD_IDC_ACK 0x63
@@ -161,6 +162,7 @@ struct qlcnic_host_sds_ring;
161struct qlcnic_host_tx_ring; 162struct qlcnic_host_tx_ring;
162struct qlcnic_hardware_context; 163struct qlcnic_hardware_context;
163struct qlcnic_adapter; 164struct qlcnic_adapter;
165struct qlcnic_fw_dump;
164 166
165int qlcnic_82xx_hw_read_wx_2M(struct qlcnic_adapter *adapter, ulong, int *); 167int qlcnic_82xx_hw_read_wx_2M(struct qlcnic_adapter *adapter, ulong, int *);
166int qlcnic_82xx_hw_write_wx_2M(struct qlcnic_adapter *, ulong, u32); 168int qlcnic_82xx_hw_write_wx_2M(struct qlcnic_adapter *, ulong, u32);
@@ -213,4 +215,11 @@ int qlcnic_82xx_shutdown(struct pci_dev *);
213int qlcnic_82xx_resume(struct qlcnic_adapter *); 215int qlcnic_82xx_resume(struct qlcnic_adapter *);
214void qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter, u8 failed); 216void qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter, u8 failed);
215void qlcnic_fw_poll_work(struct work_struct *work); 217void qlcnic_fw_poll_work(struct work_struct *work);
218
219u32 qlcnic_82xx_get_saved_state(void *, u32);
220void qlcnic_82xx_set_saved_state(void *, u32, u32);
221void qlcnic_82xx_cache_tmpl_hdr_values(struct qlcnic_fw_dump *);
222u32 qlcnic_82xx_get_cap_size(void *, int);
223void qlcnic_82xx_set_sys_info(void *, int, u32);
224void qlcnic_82xx_store_cap_mask(void *, u32);
216#endif /* __QLCNIC_HW_H_ */ 225#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 54ebf300332a..173b3d12991f 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
@@ -13,16 +13,19 @@
13 13
14#include "qlcnic.h" 14#include "qlcnic.h"
15 15
16#define TX_ETHER_PKT 0x01 16#define QLCNIC_TX_ETHER_PKT 0x01
17#define TX_TCP_PKT 0x02 17#define QLCNIC_TX_TCP_PKT 0x02
18#define TX_UDP_PKT 0x03 18#define QLCNIC_TX_UDP_PKT 0x03
19#define TX_IP_PKT 0x04 19#define QLCNIC_TX_IP_PKT 0x04
20#define TX_TCP_LSO 0x05 20#define QLCNIC_TX_TCP_LSO 0x05
21#define TX_TCP_LSO6 0x06 21#define QLCNIC_TX_TCP_LSO6 0x06
22#define TX_TCPV6_PKT 0x0b 22#define QLCNIC_TX_ENCAP_PKT 0x07
23#define TX_UDPV6_PKT 0x0c 23#define QLCNIC_TX_ENCAP_LSO 0x08
24#define FLAGS_VLAN_TAGGED 0x10 24#define QLCNIC_TX_TCPV6_PKT 0x0b
25#define FLAGS_VLAN_OOB 0x40 25#define QLCNIC_TX_UDPV6_PKT 0x0c
26
27#define QLCNIC_FLAGS_VLAN_TAGGED 0x10
28#define QLCNIC_FLAGS_VLAN_OOB 0x40
26 29
27#define qlcnic_set_tx_vlan_tci(cmd_desc, v) \ 30#define qlcnic_set_tx_vlan_tci(cmd_desc, v) \
28 (cmd_desc)->vlan_TCI = cpu_to_le16(v); 31 (cmd_desc)->vlan_TCI = cpu_to_le16(v);
@@ -364,6 +367,101 @@ static void qlcnic_send_filter(struct qlcnic_adapter *adapter,
364 spin_unlock(&adapter->mac_learn_lock); 367 spin_unlock(&adapter->mac_learn_lock);
365} 368}
366 369
370#define QLCNIC_ENCAP_VXLAN_PKT BIT_0
371#define QLCNIC_ENCAP_OUTER_L3_IP6 BIT_1
372#define QLCNIC_ENCAP_INNER_L3_IP6 BIT_2
373#define QLCNIC_ENCAP_INNER_L4_UDP BIT_3
374#define QLCNIC_ENCAP_DO_L3_CSUM BIT_4
375#define QLCNIC_ENCAP_DO_L4_CSUM BIT_5
376
377static int qlcnic_tx_encap_pkt(struct qlcnic_adapter *adapter,
378 struct cmd_desc_type0 *first_desc,
379 struct sk_buff *skb,
380 struct qlcnic_host_tx_ring *tx_ring)
381{
382 u8 opcode = 0, inner_hdr_len = 0, outer_hdr_len = 0, total_hdr_len = 0;
383 int copied, copy_len, descr_size;
384 u32 producer = tx_ring->producer;
385 struct cmd_desc_type0 *hwdesc;
386 u16 flags = 0, encap_descr = 0;
387
388 opcode = QLCNIC_TX_ETHER_PKT;
389 encap_descr = QLCNIC_ENCAP_VXLAN_PKT;
390
391 if (skb_is_gso(skb)) {
392 inner_hdr_len = skb_inner_transport_header(skb) +
393 inner_tcp_hdrlen(skb) -
394 skb_inner_mac_header(skb);
395
396 /* VXLAN header size = 8 */
397 outer_hdr_len = skb_transport_offset(skb) + 8 +
398 sizeof(struct udphdr);
399 first_desc->outer_hdr_length = outer_hdr_len;
400 total_hdr_len = inner_hdr_len + outer_hdr_len;
401 encap_descr |= QLCNIC_ENCAP_DO_L3_CSUM |
402 QLCNIC_ENCAP_DO_L4_CSUM;
403 first_desc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size);
404 first_desc->hdr_length = inner_hdr_len;
405
406 /* Copy inner and outer headers in Tx descriptor(s)
407 * If total_hdr_len > cmd_desc_type0, use multiple
408 * descriptors
409 */
410 copied = 0;
411 descr_size = (int)sizeof(struct cmd_desc_type0);
412 while (copied < total_hdr_len) {
413 copy_len = min(descr_size, (total_hdr_len - copied));
414 hwdesc = &tx_ring->desc_head[producer];
415 tx_ring->cmd_buf_arr[producer].skb = NULL;
416 skb_copy_from_linear_data_offset(skb, copied,
417 (char *)hwdesc,
418 copy_len);
419 copied += copy_len;
420 producer = get_next_index(producer, tx_ring->num_desc);
421 }
422
423 tx_ring->producer = producer;
424
425 /* Make sure updated tx_ring->producer is visible
426 * for qlcnic_tx_avail()
427 */
428 smp_mb();
429 adapter->stats.encap_lso_frames++;
430
431 opcode = QLCNIC_TX_ENCAP_LSO;
432 } else if (skb->ip_summed == CHECKSUM_PARTIAL) {
433 if (inner_ip_hdr(skb)->version == 6) {
434 if (inner_ipv6_hdr(skb)->nexthdr == IPPROTO_UDP)
435 encap_descr |= QLCNIC_ENCAP_INNER_L4_UDP;
436 } else {
437 if (inner_ip_hdr(skb)->protocol == IPPROTO_UDP)
438 encap_descr |= QLCNIC_ENCAP_INNER_L4_UDP;
439 }
440
441 adapter->stats.encap_tx_csummed++;
442 opcode = QLCNIC_TX_ENCAP_PKT;
443 }
444
445 /* Prepare first 16 bits of byte offset 16 of Tx descriptor */
446 if (ip_hdr(skb)->version == 6)
447 encap_descr |= QLCNIC_ENCAP_OUTER_L3_IP6;
448
449 /* outer IP header's size in 32bit words size*/
450 encap_descr |= (skb_network_header_len(skb) >> 2) << 6;
451
452 /* outer IP header offset */
453 encap_descr |= skb_network_offset(skb) << 10;
454 first_desc->encap_descr = cpu_to_le16(encap_descr);
455
456 first_desc->tcp_hdr_offset = skb_inner_transport_header(skb) -
457 skb->data;
458 first_desc->ip_hdr_offset = skb_inner_network_offset(skb);
459
460 qlcnic_set_tx_flags_opcode(first_desc, flags, opcode);
461
462 return 0;
463}
464
367static int qlcnic_tx_pkt(struct qlcnic_adapter *adapter, 465static int qlcnic_tx_pkt(struct qlcnic_adapter *adapter,
368 struct cmd_desc_type0 *first_desc, struct sk_buff *skb, 466 struct cmd_desc_type0 *first_desc, struct sk_buff *skb,
369 struct qlcnic_host_tx_ring *tx_ring) 467 struct qlcnic_host_tx_ring *tx_ring)
@@ -378,11 +476,11 @@ static int qlcnic_tx_pkt(struct qlcnic_adapter *adapter,
378 476
379 if (protocol == ETH_P_8021Q) { 477 if (protocol == ETH_P_8021Q) {
380 vh = (struct vlan_ethhdr *)skb->data; 478 vh = (struct vlan_ethhdr *)skb->data;
381 flags = FLAGS_VLAN_TAGGED; 479 flags = QLCNIC_FLAGS_VLAN_TAGGED;
382 vlan_tci = ntohs(vh->h_vlan_TCI); 480 vlan_tci = ntohs(vh->h_vlan_TCI);
383 protocol = ntohs(vh->h_vlan_encapsulated_proto); 481 protocol = ntohs(vh->h_vlan_encapsulated_proto);
384 } else if (vlan_tx_tag_present(skb)) { 482 } else if (vlan_tx_tag_present(skb)) {
385 flags = FLAGS_VLAN_OOB; 483 flags = QLCNIC_FLAGS_VLAN_OOB;
386 vlan_tci = vlan_tx_tag_get(skb); 484 vlan_tci = vlan_tx_tag_get(skb);
387 } 485 }
388 if (unlikely(adapter->tx_pvid)) { 486 if (unlikely(adapter->tx_pvid)) {
@@ -391,7 +489,7 @@ static int qlcnic_tx_pkt(struct qlcnic_adapter *adapter,
391 if (vlan_tci && (adapter->flags & QLCNIC_TAGGING_ENABLED)) 489 if (vlan_tci && (adapter->flags & QLCNIC_TAGGING_ENABLED))
392 goto set_flags; 490 goto set_flags;
393 491
394 flags = FLAGS_VLAN_OOB; 492 flags = QLCNIC_FLAGS_VLAN_OOB;
395 vlan_tci = adapter->tx_pvid; 493 vlan_tci = adapter->tx_pvid;
396 } 494 }
397set_flags: 495set_flags:
@@ -402,25 +500,26 @@ set_flags:
402 flags |= BIT_0; 500 flags |= BIT_0;
403 memcpy(&first_desc->eth_addr, skb->data, ETH_ALEN); 501 memcpy(&first_desc->eth_addr, skb->data, ETH_ALEN);
404 } 502 }
405 opcode = TX_ETHER_PKT; 503 opcode = QLCNIC_TX_ETHER_PKT;
406 if (skb_is_gso(skb)) { 504 if (skb_is_gso(skb)) {
407 hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); 505 hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
408 first_desc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size); 506 first_desc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size);
409 first_desc->total_hdr_length = hdr_len; 507 first_desc->hdr_length = hdr_len;
410 opcode = (protocol == ETH_P_IPV6) ? TX_TCP_LSO6 : TX_TCP_LSO; 508 opcode = (protocol == ETH_P_IPV6) ? QLCNIC_TX_TCP_LSO6 :
509 QLCNIC_TX_TCP_LSO;
411 510
412 /* For LSO, we need to copy the MAC/IP/TCP headers into 511 /* For LSO, we need to copy the MAC/IP/TCP headers into
413 * the descriptor ring */ 512 * the descriptor ring */
414 copied = 0; 513 copied = 0;
415 offset = 2; 514 offset = 2;
416 515
417 if (flags & FLAGS_VLAN_OOB) { 516 if (flags & QLCNIC_FLAGS_VLAN_OOB) {
418 first_desc->total_hdr_length += VLAN_HLEN; 517 first_desc->hdr_length += VLAN_HLEN;
419 first_desc->tcp_hdr_offset = VLAN_HLEN; 518 first_desc->tcp_hdr_offset = VLAN_HLEN;
420 first_desc->ip_hdr_offset = VLAN_HLEN; 519 first_desc->ip_hdr_offset = VLAN_HLEN;
421 520
422 /* Only in case of TSO on vlan device */ 521 /* Only in case of TSO on vlan device */
423 flags |= FLAGS_VLAN_TAGGED; 522 flags |= QLCNIC_FLAGS_VLAN_TAGGED;
424 523
425 /* Create a TSO vlan header template for firmware */ 524 /* Create a TSO vlan header template for firmware */
426 hwdesc = &tx_ring->desc_head[producer]; 525 hwdesc = &tx_ring->desc_head[producer];
@@ -464,16 +563,16 @@ set_flags:
464 l4proto = ip_hdr(skb)->protocol; 563 l4proto = ip_hdr(skb)->protocol;
465 564
466 if (l4proto == IPPROTO_TCP) 565 if (l4proto == IPPROTO_TCP)
467 opcode = TX_TCP_PKT; 566 opcode = QLCNIC_TX_TCP_PKT;
468 else if (l4proto == IPPROTO_UDP) 567 else if (l4proto == IPPROTO_UDP)
469 opcode = TX_UDP_PKT; 568 opcode = QLCNIC_TX_UDP_PKT;
470 } else if (protocol == ETH_P_IPV6) { 569 } else if (protocol == ETH_P_IPV6) {
471 l4proto = ipv6_hdr(skb)->nexthdr; 570 l4proto = ipv6_hdr(skb)->nexthdr;
472 571
473 if (l4proto == IPPROTO_TCP) 572 if (l4proto == IPPROTO_TCP)
474 opcode = TX_TCPV6_PKT; 573 opcode = QLCNIC_TX_TCPV6_PKT;
475 else if (l4proto == IPPROTO_UDP) 574 else if (l4proto == IPPROTO_UDP)
476 opcode = TX_UDPV6_PKT; 575 opcode = QLCNIC_TX_UDPV6_PKT;
477 } 576 }
478 } 577 }
479 first_desc->tcp_hdr_offset += skb_transport_offset(skb); 578 first_desc->tcp_hdr_offset += skb_transport_offset(skb);
@@ -563,6 +662,8 @@ netdev_tx_t qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
563 struct ethhdr *phdr; 662 struct ethhdr *phdr;
564 int i, k, frag_count, delta = 0; 663 int i, k, frag_count, delta = 0;
565 u32 producer, num_txd; 664 u32 producer, num_txd;
665 u16 protocol;
666 bool l4_is_udp = false;
566 667
567 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) { 668 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
568 netif_tx_stop_all_queues(netdev); 669 netif_tx_stop_all_queues(netdev);
@@ -653,8 +754,23 @@ netdev_tx_t qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
653 tx_ring->producer = get_next_index(producer, num_txd); 754 tx_ring->producer = get_next_index(producer, num_txd);
654 smp_mb(); 755 smp_mb();
655 756
656 if (unlikely(qlcnic_tx_pkt(adapter, first_desc, skb, tx_ring))) 757 protocol = ntohs(skb->protocol);
657 goto unwind_buff; 758 if (protocol == ETH_P_IP)
759 l4_is_udp = ip_hdr(skb)->protocol == IPPROTO_UDP;
760 else if (protocol == ETH_P_IPV6)
761 l4_is_udp = ipv6_hdr(skb)->nexthdr == IPPROTO_UDP;
762
763 /* Check if it is a VXLAN packet */
764 if (!skb->encapsulation || !l4_is_udp ||
765 !qlcnic_encap_tx_offload(adapter)) {
766 if (unlikely(qlcnic_tx_pkt(adapter, first_desc, skb,
767 tx_ring)))
768 goto unwind_buff;
769 } else {
770 if (unlikely(qlcnic_tx_encap_pkt(adapter, first_desc,
771 skb, tx_ring)))
772 goto unwind_buff;
773 }
658 774
659 if (adapter->drv_mac_learn) 775 if (adapter->drv_mac_learn)
660 qlcnic_send_filter(adapter, first_desc, skb); 776 qlcnic_send_filter(adapter, first_desc, skb);
@@ -1587,6 +1703,13 @@ static inline int qlcnic_83xx_is_lb_pkt(u64 sts_data, int lro_pkt)
1587 return (sts_data & QLC_83XX_NORMAL_LB_PKT) ? 1 : 0; 1703 return (sts_data & QLC_83XX_NORMAL_LB_PKT) ? 1 : 0;
1588} 1704}
1589 1705
1706#define QLCNIC_ENCAP_LENGTH_MASK 0x7f
1707
1708static inline u8 qlcnic_encap_length(u64 sts_data)
1709{
1710 return sts_data & QLCNIC_ENCAP_LENGTH_MASK;
1711}
1712
1590static struct qlcnic_rx_buffer * 1713static struct qlcnic_rx_buffer *
1591qlcnic_83xx_process_rcv(struct qlcnic_adapter *adapter, 1714qlcnic_83xx_process_rcv(struct qlcnic_adapter *adapter,
1592 struct qlcnic_host_sds_ring *sds_ring, 1715 struct qlcnic_host_sds_ring *sds_ring,
@@ -1637,6 +1760,12 @@ qlcnic_83xx_process_rcv(struct qlcnic_adapter *adapter,
1637 1760
1638 skb->protocol = eth_type_trans(skb, netdev); 1761 skb->protocol = eth_type_trans(skb, netdev);
1639 1762
1763 if (qlcnic_encap_length(sts_data[1]) &&
1764 skb->ip_summed == CHECKSUM_UNNECESSARY) {
1765 skb->encapsulation = 1;
1766 adapter->stats.encap_rx_csummed++;
1767 }
1768
1640 if (vid != 0xffff) 1769 if (vid != 0xffff)
1641 __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vid); 1770 __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vid);
1642 1771
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 1222865cfb73..309d05640883 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -21,6 +21,9 @@
21#include <linux/aer.h> 21#include <linux/aer.h>
22#include <linux/log2.h> 22#include <linux/log2.h>
23#include <linux/pci.h> 23#include <linux/pci.h>
24#ifdef CONFIG_QLCNIC_VXLAN
25#include <net/vxlan.h>
26#endif
24 27
25MODULE_DESCRIPTION("QLogic 1/10 GbE Converged/Intelligent Ethernet Driver"); 28MODULE_DESCRIPTION("QLogic 1/10 GbE Converged/Intelligent Ethernet Driver");
26MODULE_LICENSE("GPL"); 29MODULE_LICENSE("GPL");
@@ -90,7 +93,6 @@ static void qlcnic_82xx_io_resume(struct pci_dev *);
90static void qlcnic_82xx_set_mac_filter_count(struct qlcnic_adapter *); 93static void qlcnic_82xx_set_mac_filter_count(struct qlcnic_adapter *);
91static pci_ers_result_t qlcnic_82xx_io_error_detected(struct pci_dev *, 94static pci_ers_result_t qlcnic_82xx_io_error_detected(struct pci_dev *,
92 pci_channel_state_t); 95 pci_channel_state_t);
93
94static u32 qlcnic_vlan_tx_check(struct qlcnic_adapter *adapter) 96static u32 qlcnic_vlan_tx_check(struct qlcnic_adapter *adapter)
95{ 97{
96 struct qlcnic_hardware_context *ahw = adapter->ahw; 98 struct qlcnic_hardware_context *ahw = adapter->ahw;
@@ -462,6 +464,37 @@ static int qlcnic_get_phys_port_id(struct net_device *netdev,
462 return 0; 464 return 0;
463} 465}
464 466
467#ifdef CONFIG_QLCNIC_VXLAN
468static void qlcnic_add_vxlan_port(struct net_device *netdev,
469 sa_family_t sa_family, __be16 port)
470{
471 struct qlcnic_adapter *adapter = netdev_priv(netdev);
472 struct qlcnic_hardware_context *ahw = adapter->ahw;
473
474 /* Adapter supports only one VXLAN port. Use very first port
475 * for enabling offload
476 */
477 if (!qlcnic_encap_rx_offload(adapter) || ahw->vxlan_port)
478 return;
479
480 ahw->vxlan_port = ntohs(port);
481 adapter->flags |= QLCNIC_ADD_VXLAN_PORT;
482}
483
484static void qlcnic_del_vxlan_port(struct net_device *netdev,
485 sa_family_t sa_family, __be16 port)
486{
487 struct qlcnic_adapter *adapter = netdev_priv(netdev);
488 struct qlcnic_hardware_context *ahw = adapter->ahw;
489
490 if (!qlcnic_encap_rx_offload(adapter) || !ahw->vxlan_port ||
491 (ahw->vxlan_port != ntohs(port)))
492 return;
493
494 adapter->flags |= QLCNIC_DEL_VXLAN_PORT;
495}
496#endif
497
465static const struct net_device_ops qlcnic_netdev_ops = { 498static const struct net_device_ops qlcnic_netdev_ops = {
466 .ndo_open = qlcnic_open, 499 .ndo_open = qlcnic_open,
467 .ndo_stop = qlcnic_close, 500 .ndo_stop = qlcnic_close,
@@ -480,6 +513,10 @@ static const struct net_device_ops qlcnic_netdev_ops = {
480 .ndo_fdb_del = qlcnic_fdb_del, 513 .ndo_fdb_del = qlcnic_fdb_del,
481 .ndo_fdb_dump = qlcnic_fdb_dump, 514 .ndo_fdb_dump = qlcnic_fdb_dump,
482 .ndo_get_phys_port_id = qlcnic_get_phys_port_id, 515 .ndo_get_phys_port_id = qlcnic_get_phys_port_id,
516#ifdef CONFIG_QLCNIC_VXLAN
517 .ndo_add_vxlan_port = qlcnic_add_vxlan_port,
518 .ndo_del_vxlan_port = qlcnic_del_vxlan_port,
519#endif
483#ifdef CONFIG_NET_POLL_CONTROLLER 520#ifdef CONFIG_NET_POLL_CONTROLLER
484 .ndo_poll_controller = qlcnic_poll_controller, 521 .ndo_poll_controller = qlcnic_poll_controller,
485#endif 522#endif
@@ -561,6 +598,12 @@ static struct qlcnic_hardware_ops qlcnic_hw_ops = {
561 .disable_sds_intr = qlcnic_82xx_disable_sds_intr, 598 .disable_sds_intr = qlcnic_82xx_disable_sds_intr,
562 .enable_tx_intr = qlcnic_82xx_enable_tx_intr, 599 .enable_tx_intr = qlcnic_82xx_enable_tx_intr,
563 .disable_tx_intr = qlcnic_82xx_disable_tx_intr, 600 .disable_tx_intr = qlcnic_82xx_disable_tx_intr,
601 .get_saved_state = qlcnic_82xx_get_saved_state,
602 .set_saved_state = qlcnic_82xx_set_saved_state,
603 .cache_tmpl_hdr_values = qlcnic_82xx_cache_tmpl_hdr_values,
604 .get_cap_size = qlcnic_82xx_get_cap_size,
605 .set_sys_info = qlcnic_82xx_set_sys_info,
606 .store_cap_mask = qlcnic_82xx_store_cap_mask,
564}; 607};
565 608
566static int qlcnic_check_multi_tx_capability(struct qlcnic_adapter *adapter) 609static int qlcnic_check_multi_tx_capability(struct qlcnic_adapter *adapter)
@@ -684,7 +727,7 @@ restore:
684int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix) 727int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix)
685{ 728{
686 struct pci_dev *pdev = adapter->pdev; 729 struct pci_dev *pdev = adapter->pdev;
687 int err = -1, vector; 730 int err, vector;
688 731
689 if (!adapter->msix_entries) { 732 if (!adapter->msix_entries) {
690 adapter->msix_entries = kcalloc(num_msix, 733 adapter->msix_entries = kcalloc(num_msix,
@@ -701,13 +744,17 @@ enable_msix:
701 for (vector = 0; vector < num_msix; vector++) 744 for (vector = 0; vector < num_msix; vector++)
702 adapter->msix_entries[vector].entry = vector; 745 adapter->msix_entries[vector].entry = vector;
703 746
704 err = pci_enable_msix(pdev, adapter->msix_entries, num_msix); 747 err = pci_enable_msix_range(pdev,
705 if (err == 0) { 748 adapter->msix_entries, 1, num_msix);
749
750 if (err == num_msix) {
706 adapter->flags |= QLCNIC_MSIX_ENABLED; 751 adapter->flags |= QLCNIC_MSIX_ENABLED;
707 adapter->ahw->num_msix = num_msix; 752 adapter->ahw->num_msix = num_msix;
708 dev_info(&pdev->dev, "using msi-x interrupts\n"); 753 dev_info(&pdev->dev, "using msi-x interrupts\n");
709 return err; 754 return 0;
710 } else if (err > 0) { 755 } else if (err > 0) {
756 pci_disable_msix(pdev);
757
711 dev_info(&pdev->dev, 758 dev_info(&pdev->dev,
712 "Unable to allocate %d MSI-X vectors, Available vectors %d\n", 759 "Unable to allocate %d MSI-X vectors, Available vectors %d\n",
713 num_msix, err); 760 num_msix, err);
@@ -715,12 +762,12 @@ enable_msix:
715 if (qlcnic_82xx_check(adapter)) { 762 if (qlcnic_82xx_check(adapter)) {
716 num_msix = rounddown_pow_of_two(err); 763 num_msix = rounddown_pow_of_two(err);
717 if (err < QLCNIC_82XX_MINIMUM_VECTOR) 764 if (err < QLCNIC_82XX_MINIMUM_VECTOR)
718 return -EIO; 765 return -ENOSPC;
719 } else { 766 } else {
720 num_msix = rounddown_pow_of_two(err - 1); 767 num_msix = rounddown_pow_of_two(err - 1);
721 num_msix += 1; 768 num_msix += 1;
722 if (err < QLCNIC_83XX_MINIMUM_VECTOR) 769 if (err < QLCNIC_83XX_MINIMUM_VECTOR)
723 return -EIO; 770 return -ENOSPC;
724 } 771 }
725 772
726 if (qlcnic_82xx_check(adapter) && 773 if (qlcnic_82xx_check(adapter) &&
@@ -747,7 +794,7 @@ enable_msix:
747 } 794 }
748 } 795 }
749 796
750 return err; 797 return -EIO;
751} 798}
752 799
753static int qlcnic_82xx_calculate_msix_vector(struct qlcnic_adapter *adapter) 800static int qlcnic_82xx_calculate_msix_vector(struct qlcnic_adapter *adapter)
@@ -1934,6 +1981,11 @@ qlcnic_attach(struct qlcnic_adapter *adapter)
1934 1981
1935 qlcnic_create_sysfs_entries(adapter); 1982 qlcnic_create_sysfs_entries(adapter);
1936 1983
1984#ifdef CONFIG_QLCNIC_VXLAN
1985 if (qlcnic_encap_rx_offload(adapter))
1986 vxlan_get_rx_port(netdev);
1987#endif
1988
1937 adapter->is_up = QLCNIC_ADAPTER_UP_MAGIC; 1989 adapter->is_up = QLCNIC_ADAPTER_UP_MAGIC;
1938 return 0; 1990 return 0;
1939 1991
@@ -2196,6 +2248,19 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, struct net_device *netdev,
2196 if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO) 2248 if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO)
2197 netdev->features |= NETIF_F_LRO; 2249 netdev->features |= NETIF_F_LRO;
2198 2250
2251 if (qlcnic_encap_tx_offload(adapter)) {
2252 netdev->features |= NETIF_F_GSO_UDP_TUNNEL;
2253
2254 /* encapsulation Tx offload supported by Adapter */
2255 netdev->hw_enc_features = NETIF_F_IP_CSUM |
2256 NETIF_F_GSO_UDP_TUNNEL |
2257 NETIF_F_TSO |
2258 NETIF_F_TSO6;
2259 }
2260
2261 if (qlcnic_encap_rx_offload(adapter))
2262 netdev->hw_enc_features |= NETIF_F_RXCSUM;
2263
2199 netdev->hw_features = netdev->features; 2264 netdev->hw_features = netdev->features;
2200 netdev->priv_flags |= IFF_UNICAST_FLT; 2265 netdev->priv_flags |= IFF_UNICAST_FLT;
2201 netdev->irq = adapter->msix_entries[0].vector; 2266 netdev->irq = adapter->msix_entries[0].vector;
@@ -2442,8 +2507,8 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
2442 if (err) { 2507 if (err) {
2443 switch (err) { 2508 switch (err) {
2444 case -ENOTRECOVERABLE: 2509 case -ENOTRECOVERABLE:
2445 dev_err(&pdev->dev, "Adapter initialization failed due to a faulty hardware. Please reboot\n"); 2510 dev_err(&pdev->dev, "Adapter initialization failed due to a faulty hardware\n");
2446 dev_err(&pdev->dev, "If reboot doesn't help, please replace the adapter with new one and return the faulty adapter for repair\n"); 2511 dev_err(&pdev->dev, "Please replace the adapter with new one and return the faulty adapter for repair\n");
2447 goto err_out_free_hw; 2512 goto err_out_free_hw;
2448 case -ENOMEM: 2513 case -ENOMEM:
2449 dev_err(&pdev->dev, "Adapter initialization failed. Please reboot\n"); 2514 dev_err(&pdev->dev, "Adapter initialization failed. Please reboot\n");
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c
index 7763962e2ec4..37b979b1266b 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c
@@ -211,6 +211,107 @@ enum qlcnic_minidump_opcode {
211 QLCNIC_DUMP_RDEND = 255 211 QLCNIC_DUMP_RDEND = 255
212}; 212};
213 213
214inline u32 qlcnic_82xx_get_saved_state(void *t_hdr, u32 index)
215{
216 struct qlcnic_82xx_dump_template_hdr *hdr = t_hdr;
217
218 return hdr->saved_state[index];
219}
220
221inline void qlcnic_82xx_set_saved_state(void *t_hdr, u32 index,
222 u32 value)
223{
224 struct qlcnic_82xx_dump_template_hdr *hdr = t_hdr;
225
226 hdr->saved_state[index] = value;
227}
228
229void qlcnic_82xx_cache_tmpl_hdr_values(struct qlcnic_fw_dump *fw_dump)
230{
231 struct qlcnic_82xx_dump_template_hdr *hdr;
232
233 hdr = fw_dump->tmpl_hdr;
234 fw_dump->tmpl_hdr_size = hdr->size;
235 fw_dump->version = hdr->version;
236 fw_dump->num_entries = hdr->num_entries;
237 fw_dump->offset = hdr->offset;
238
239 hdr->drv_cap_mask = hdr->cap_mask;
240 fw_dump->cap_mask = hdr->cap_mask;
241}
242
243inline u32 qlcnic_82xx_get_cap_size(void *t_hdr, int index)
244{
245 struct qlcnic_82xx_dump_template_hdr *hdr = t_hdr;
246
247 return hdr->cap_sizes[index];
248}
249
250void qlcnic_82xx_set_sys_info(void *t_hdr, int idx, u32 value)
251{
252 struct qlcnic_82xx_dump_template_hdr *hdr = t_hdr;
253
254 hdr->sys_info[idx] = value;
255}
256
257void qlcnic_82xx_store_cap_mask(void *tmpl_hdr, u32 mask)
258{
259 struct qlcnic_82xx_dump_template_hdr *hdr = tmpl_hdr;
260
261 hdr->drv_cap_mask = mask;
262}
263
264inline u32 qlcnic_83xx_get_saved_state(void *t_hdr, u32 index)
265{
266 struct qlcnic_83xx_dump_template_hdr *hdr = t_hdr;
267
268 return hdr->saved_state[index];
269}
270
271inline void qlcnic_83xx_set_saved_state(void *t_hdr, u32 index,
272 u32 value)
273{
274 struct qlcnic_83xx_dump_template_hdr *hdr = t_hdr;
275
276 hdr->saved_state[index] = value;
277}
278
279void qlcnic_83xx_cache_tmpl_hdr_values(struct qlcnic_fw_dump *fw_dump)
280{
281 struct qlcnic_83xx_dump_template_hdr *hdr;
282
283 hdr = fw_dump->tmpl_hdr;
284 fw_dump->tmpl_hdr_size = hdr->size;
285 fw_dump->version = hdr->version;
286 fw_dump->num_entries = hdr->num_entries;
287 fw_dump->offset = hdr->offset;
288
289 hdr->drv_cap_mask = hdr->cap_mask;
290 fw_dump->cap_mask = hdr->cap_mask;
291}
292
293inline u32 qlcnic_83xx_get_cap_size(void *t_hdr, int index)
294{
295 struct qlcnic_83xx_dump_template_hdr *hdr = t_hdr;
296
297 return hdr->cap_sizes[index];
298}
299
300void qlcnic_83xx_set_sys_info(void *t_hdr, int idx, u32 value)
301{
302 struct qlcnic_83xx_dump_template_hdr *hdr = t_hdr;
303
304 hdr->sys_info[idx] = value;
305}
306
307void qlcnic_83xx_store_cap_mask(void *tmpl_hdr, u32 mask)
308{
309 struct qlcnic_83xx_dump_template_hdr *hdr;
310
311 hdr = tmpl_hdr;
312 hdr->drv_cap_mask = mask;
313}
314
214struct qlcnic_dump_operations { 315struct qlcnic_dump_operations {
215 enum qlcnic_minidump_opcode opcode; 316 enum qlcnic_minidump_opcode opcode;
216 u32 (*handler)(struct qlcnic_adapter *, struct qlcnic_dump_entry *, 317 u32 (*handler)(struct qlcnic_adapter *, struct qlcnic_dump_entry *,
@@ -238,11 +339,11 @@ static u32 qlcnic_dump_crb(struct qlcnic_adapter *adapter,
238static u32 qlcnic_dump_ctrl(struct qlcnic_adapter *adapter, 339static u32 qlcnic_dump_ctrl(struct qlcnic_adapter *adapter,
239 struct qlcnic_dump_entry *entry, __le32 *buffer) 340 struct qlcnic_dump_entry *entry, __le32 *buffer)
240{ 341{
342 void *hdr = adapter->ahw->fw_dump.tmpl_hdr;
343 struct __ctrl *ctr = &entry->region.ctrl;
241 int i, k, timeout = 0; 344 int i, k, timeout = 0;
242 u32 addr, data; 345 u32 addr, data, temp;
243 u8 no_ops; 346 u8 no_ops;
244 struct __ctrl *ctr = &entry->region.ctrl;
245 struct qlcnic_dump_template_hdr *t_hdr = adapter->ahw->fw_dump.tmpl_hdr;
246 347
247 addr = ctr->addr; 348 addr = ctr->addr;
248 no_ops = ctr->no_ops; 349 no_ops = ctr->no_ops;
@@ -285,29 +386,42 @@ static u32 qlcnic_dump_ctrl(struct qlcnic_adapter *adapter,
285 } 386 }
286 break; 387 break;
287 case QLCNIC_DUMP_RD_SAVE: 388 case QLCNIC_DUMP_RD_SAVE:
288 if (ctr->index_a) 389 temp = ctr->index_a;
289 addr = t_hdr->saved_state[ctr->index_a]; 390 if (temp)
391 addr = qlcnic_get_saved_state(adapter,
392 hdr,
393 temp);
290 data = qlcnic_ind_rd(adapter, addr); 394 data = qlcnic_ind_rd(adapter, addr);
291 t_hdr->saved_state[ctr->index_v] = data; 395 qlcnic_set_saved_state(adapter, hdr,
396 ctr->index_v, data);
292 break; 397 break;
293 case QLCNIC_DUMP_WRT_SAVED: 398 case QLCNIC_DUMP_WRT_SAVED:
294 if (ctr->index_v) 399 temp = ctr->index_v;
295 data = t_hdr->saved_state[ctr->index_v]; 400 if (temp)
401 data = qlcnic_get_saved_state(adapter,
402 hdr,
403 temp);
296 else 404 else
297 data = ctr->val1; 405 data = ctr->val1;
298 if (ctr->index_a) 406
299 addr = t_hdr->saved_state[ctr->index_a]; 407 temp = ctr->index_a;
408 if (temp)
409 addr = qlcnic_get_saved_state(adapter,
410 hdr,
411 temp);
300 qlcnic_ind_wr(adapter, addr, data); 412 qlcnic_ind_wr(adapter, addr, data);
301 break; 413 break;
302 case QLCNIC_DUMP_MOD_SAVE_ST: 414 case QLCNIC_DUMP_MOD_SAVE_ST:
303 data = t_hdr->saved_state[ctr->index_v]; 415 data = qlcnic_get_saved_state(adapter, hdr,
416 ctr->index_v);
304 data <<= ctr->shl_val; 417 data <<= ctr->shl_val;
305 data >>= ctr->shr_val; 418 data >>= ctr->shr_val;
306 if (ctr->val2) 419 if (ctr->val2)
307 data &= ctr->val2; 420 data &= ctr->val2;
308 data |= ctr->val3; 421 data |= ctr->val3;
309 data += ctr->val1; 422 data += ctr->val1;
310 t_hdr->saved_state[ctr->index_v] = data; 423 qlcnic_set_saved_state(adapter, hdr,
424 ctr->index_v, data);
311 break; 425 break;
312 default: 426 default:
313 dev_info(&adapter->pdev->dev, 427 dev_info(&adapter->pdev->dev,
@@ -544,7 +658,7 @@ out:
544static int qlcnic_start_pex_dma(struct qlcnic_adapter *adapter, 658static int qlcnic_start_pex_dma(struct qlcnic_adapter *adapter,
545 struct __mem *mem) 659 struct __mem *mem)
546{ 660{
547 struct qlcnic_dump_template_hdr *tmpl_hdr; 661 struct qlcnic_83xx_dump_template_hdr *tmpl_hdr;
548 struct device *dev = &adapter->pdev->dev; 662 struct device *dev = &adapter->pdev->dev;
549 u32 dma_no, dma_base_addr, temp_addr; 663 u32 dma_no, dma_base_addr, temp_addr;
550 int i, ret, dma_sts; 664 int i, ret, dma_sts;
@@ -596,7 +710,7 @@ static u32 qlcnic_read_memory_pexdma(struct qlcnic_adapter *adapter,
596 struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump; 710 struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
597 u32 temp, dma_base_addr, size = 0, read_size = 0; 711 u32 temp, dma_base_addr, size = 0, read_size = 0;
598 struct qlcnic_pex_dma_descriptor *dma_descr; 712 struct qlcnic_pex_dma_descriptor *dma_descr;
599 struct qlcnic_dump_template_hdr *tmpl_hdr; 713 struct qlcnic_83xx_dump_template_hdr *tmpl_hdr;
600 struct device *dev = &adapter->pdev->dev; 714 struct device *dev = &adapter->pdev->dev;
601 dma_addr_t dma_phys_addr; 715 dma_addr_t dma_phys_addr;
602 void *dma_buffer; 716 void *dma_buffer;
@@ -938,8 +1052,8 @@ static int
938qlcnic_fw_flash_get_minidump_temp_size(struct qlcnic_adapter *adapter, 1052qlcnic_fw_flash_get_minidump_temp_size(struct qlcnic_adapter *adapter,
939 struct qlcnic_cmd_args *cmd) 1053 struct qlcnic_cmd_args *cmd)
940{ 1054{
941 struct qlcnic_dump_template_hdr tmp_hdr; 1055 struct qlcnic_83xx_dump_template_hdr tmp_hdr;
942 u32 size = sizeof(struct qlcnic_dump_template_hdr) / sizeof(u32); 1056 u32 size = sizeof(tmp_hdr) / sizeof(u32);
943 int ret = 0; 1057 int ret = 0;
944 1058
945 if (qlcnic_82xx_check(adapter)) 1059 if (qlcnic_82xx_check(adapter))
@@ -1027,17 +1141,19 @@ free_mem:
1027 return err; 1141 return err;
1028} 1142}
1029 1143
1144#define QLCNIC_TEMPLATE_VERSION (0x20001)
1145
1030int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter) 1146int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter)
1031{ 1147{
1032 int err;
1033 u32 temp_size = 0;
1034 u32 version, csum, *tmp_buf;
1035 struct qlcnic_hardware_context *ahw; 1148 struct qlcnic_hardware_context *ahw;
1036 struct qlcnic_dump_template_hdr *tmpl_hdr; 1149 struct qlcnic_fw_dump *fw_dump;
1150 u32 version, csum, *tmp_buf;
1037 u8 use_flash_temp = 0; 1151 u8 use_flash_temp = 0;
1152 u32 temp_size = 0;
1153 int err;
1038 1154
1039 ahw = adapter->ahw; 1155 ahw = adapter->ahw;
1040 1156 fw_dump = &ahw->fw_dump;
1041 err = qlcnic_fw_get_minidump_temp_size(adapter, &version, &temp_size, 1157 err = qlcnic_fw_get_minidump_temp_size(adapter, &version, &temp_size,
1042 &use_flash_temp); 1158 &use_flash_temp);
1043 if (err) { 1159 if (err) {
@@ -1046,11 +1162,11 @@ int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter)
1046 return -EIO; 1162 return -EIO;
1047 } 1163 }
1048 1164
1049 ahw->fw_dump.tmpl_hdr = vzalloc(temp_size); 1165 fw_dump->tmpl_hdr = vzalloc(temp_size);
1050 if (!ahw->fw_dump.tmpl_hdr) 1166 if (!fw_dump->tmpl_hdr)
1051 return -ENOMEM; 1167 return -ENOMEM;
1052 1168
1053 tmp_buf = (u32 *)ahw->fw_dump.tmpl_hdr; 1169 tmp_buf = (u32 *)fw_dump->tmpl_hdr;
1054 if (use_flash_temp) 1170 if (use_flash_temp)
1055 goto flash_temp; 1171 goto flash_temp;
1056 1172
@@ -1065,8 +1181,8 @@ flash_temp:
1065 dev_err(&adapter->pdev->dev, 1181 dev_err(&adapter->pdev->dev,
1066 "Failed to get minidump template header %d\n", 1182 "Failed to get minidump template header %d\n",
1067 err); 1183 err);
1068 vfree(ahw->fw_dump.tmpl_hdr); 1184 vfree(fw_dump->tmpl_hdr);
1069 ahw->fw_dump.tmpl_hdr = NULL; 1185 fw_dump->tmpl_hdr = NULL;
1070 return -EIO; 1186 return -EIO;
1071 } 1187 }
1072 } 1188 }
@@ -1076,21 +1192,22 @@ flash_temp:
1076 if (csum) { 1192 if (csum) {
1077 dev_err(&adapter->pdev->dev, 1193 dev_err(&adapter->pdev->dev,
1078 "Template header checksum validation failed\n"); 1194 "Template header checksum validation failed\n");
1079 vfree(ahw->fw_dump.tmpl_hdr); 1195 vfree(fw_dump->tmpl_hdr);
1080 ahw->fw_dump.tmpl_hdr = NULL; 1196 fw_dump->tmpl_hdr = NULL;
1081 return -EIO; 1197 return -EIO;
1082 } 1198 }
1083 1199
1084 tmpl_hdr = ahw->fw_dump.tmpl_hdr; 1200 qlcnic_cache_tmpl_hdr_values(adapter, fw_dump);
1085 tmpl_hdr->drv_cap_mask = tmpl_hdr->cap_mask; 1201
1086 dev_info(&adapter->pdev->dev, 1202 dev_info(&adapter->pdev->dev,
1087 "Default minidump capture mask 0x%x\n", 1203 "Default minidump capture mask 0x%x\n",
1088 tmpl_hdr->cap_mask); 1204 fw_dump->cap_mask);
1089 1205
1090 if ((tmpl_hdr->version & 0xfffff) >= 0x20001) 1206 if (qlcnic_83xx_check(adapter) &&
1091 ahw->fw_dump.use_pex_dma = true; 1207 (fw_dump->version & 0xfffff) >= QLCNIC_TEMPLATE_VERSION)
1208 fw_dump->use_pex_dma = true;
1092 else 1209 else
1093 ahw->fw_dump.use_pex_dma = false; 1210 fw_dump->use_pex_dma = false;
1094 1211
1095 qlcnic_enable_fw_dump_state(adapter); 1212 qlcnic_enable_fw_dump_state(adapter);
1096 1213
@@ -1099,21 +1216,22 @@ flash_temp:
1099 1216
1100int qlcnic_dump_fw(struct qlcnic_adapter *adapter) 1217int qlcnic_dump_fw(struct qlcnic_adapter *adapter)
1101{ 1218{
1102 __le32 *buffer;
1103 u32 ocm_window;
1104 char mesg[64];
1105 char *msg[] = {mesg, NULL};
1106 int i, k, ops_cnt, ops_index, dump_size = 0;
1107 u32 entry_offset, dump, no_entries, buf_offset = 0;
1108 struct qlcnic_dump_entry *entry;
1109 struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump; 1219 struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1110 struct qlcnic_dump_template_hdr *tmpl_hdr = fw_dump->tmpl_hdr;
1111 static const struct qlcnic_dump_operations *fw_dump_ops; 1220 static const struct qlcnic_dump_operations *fw_dump_ops;
1221 struct qlcnic_83xx_dump_template_hdr *hdr_83xx;
1222 u32 entry_offset, dump, no_entries, buf_offset = 0;
1223 int i, k, ops_cnt, ops_index, dump_size = 0;
1112 struct device *dev = &adapter->pdev->dev; 1224 struct device *dev = &adapter->pdev->dev;
1113 struct qlcnic_hardware_context *ahw; 1225 struct qlcnic_hardware_context *ahw;
1114 void *temp_buffer; 1226 struct qlcnic_dump_entry *entry;
1227 void *temp_buffer, *tmpl_hdr;
1228 u32 ocm_window;
1229 __le32 *buffer;
1230 char mesg[64];
1231 char *msg[] = {mesg, NULL};
1115 1232
1116 ahw = adapter->ahw; 1233 ahw = adapter->ahw;
1234 tmpl_hdr = fw_dump->tmpl_hdr;
1117 1235
1118 /* Return if we don't have firmware dump template header */ 1236 /* Return if we don't have firmware dump template header */
1119 if (!tmpl_hdr) 1237 if (!tmpl_hdr)
@@ -1133,8 +1251,9 @@ int qlcnic_dump_fw(struct qlcnic_adapter *adapter)
1133 netif_info(adapter->ahw, drv, adapter->netdev, "Take FW dump\n"); 1251 netif_info(adapter->ahw, drv, adapter->netdev, "Take FW dump\n");
1134 /* Calculate the size for dump data area only */ 1252 /* Calculate the size for dump data area only */
1135 for (i = 2, k = 1; (i & QLCNIC_DUMP_MASK_MAX); i <<= 1, k++) 1253 for (i = 2, k = 1; (i & QLCNIC_DUMP_MASK_MAX); i <<= 1, k++)
1136 if (i & tmpl_hdr->drv_cap_mask) 1254 if (i & fw_dump->cap_mask)
1137 dump_size += tmpl_hdr->cap_sizes[k]; 1255 dump_size += qlcnic_get_cap_size(adapter, tmpl_hdr, k);
1256
1138 if (!dump_size) 1257 if (!dump_size)
1139 return -EIO; 1258 return -EIO;
1140 1259
@@ -1144,10 +1263,10 @@ int qlcnic_dump_fw(struct qlcnic_adapter *adapter)
1144 1263
1145 buffer = fw_dump->data; 1264 buffer = fw_dump->data;
1146 fw_dump->size = dump_size; 1265 fw_dump->size = dump_size;
1147 no_entries = tmpl_hdr->num_entries; 1266 no_entries = fw_dump->num_entries;
1148 entry_offset = tmpl_hdr->offset; 1267 entry_offset = fw_dump->offset;
1149 tmpl_hdr->sys_info[0] = QLCNIC_DRIVER_VERSION; 1268 qlcnic_set_sys_info(adapter, tmpl_hdr, 0, QLCNIC_DRIVER_VERSION);
1150 tmpl_hdr->sys_info[1] = adapter->fw_version; 1269 qlcnic_set_sys_info(adapter, tmpl_hdr, 1, adapter->fw_version);
1151 1270
1152 if (fw_dump->use_pex_dma) { 1271 if (fw_dump->use_pex_dma) {
1153 temp_buffer = dma_alloc_coherent(dev, QLC_PEX_DMA_READ_SIZE, 1272 temp_buffer = dma_alloc_coherent(dev, QLC_PEX_DMA_READ_SIZE,
@@ -1163,16 +1282,17 @@ int qlcnic_dump_fw(struct qlcnic_adapter *adapter)
1163 ops_cnt = ARRAY_SIZE(qlcnic_fw_dump_ops); 1282 ops_cnt = ARRAY_SIZE(qlcnic_fw_dump_ops);
1164 fw_dump_ops = qlcnic_fw_dump_ops; 1283 fw_dump_ops = qlcnic_fw_dump_ops;
1165 } else { 1284 } else {
1285 hdr_83xx = tmpl_hdr;
1166 ops_cnt = ARRAY_SIZE(qlcnic_83xx_fw_dump_ops); 1286 ops_cnt = ARRAY_SIZE(qlcnic_83xx_fw_dump_ops);
1167 fw_dump_ops = qlcnic_83xx_fw_dump_ops; 1287 fw_dump_ops = qlcnic_83xx_fw_dump_ops;
1168 ocm_window = tmpl_hdr->ocm_wnd_reg[adapter->ahw->pci_func]; 1288 ocm_window = hdr_83xx->ocm_wnd_reg[ahw->pci_func];
1169 tmpl_hdr->saved_state[QLC_83XX_OCM_INDEX] = ocm_window; 1289 hdr_83xx->saved_state[QLC_83XX_OCM_INDEX] = ocm_window;
1170 tmpl_hdr->saved_state[QLC_83XX_PCI_INDEX] = ahw->pci_func; 1290 hdr_83xx->saved_state[QLC_83XX_PCI_INDEX] = ahw->pci_func;
1171 } 1291 }
1172 1292
1173 for (i = 0; i < no_entries; i++) { 1293 for (i = 0; i < no_entries; i++) {
1174 entry = (void *)tmpl_hdr + entry_offset; 1294 entry = tmpl_hdr + entry_offset;
1175 if (!(entry->hdr.mask & tmpl_hdr->drv_cap_mask)) { 1295 if (!(entry->hdr.mask & fw_dump->cap_mask)) {
1176 entry->hdr.flags |= QLCNIC_DUMP_SKIP; 1296 entry->hdr.flags |= QLCNIC_DUMP_SKIP;
1177 entry_offset += entry->hdr.offset; 1297 entry_offset += entry->hdr.offset;
1178 continue; 1298 continue;
@@ -1209,8 +1329,9 @@ int qlcnic_dump_fw(struct qlcnic_adapter *adapter)
1209 1329
1210 fw_dump->clr = 1; 1330 fw_dump->clr = 1;
1211 snprintf(mesg, sizeof(mesg), "FW_DUMP=%s", adapter->netdev->name); 1331 snprintf(mesg, sizeof(mesg), "FW_DUMP=%s", adapter->netdev->name);
1212 dev_info(dev, "%s: Dump data %d bytes captured, template header size %d bytes\n", 1332 netdev_info(adapter->netdev,
1213 adapter->netdev->name, fw_dump->size, tmpl_hdr->size); 1333 "Dump data %d bytes captured, template header size %d bytes\n",
1334 fw_dump->size, fw_dump->tmpl_hdr_size);
1214 /* Send a udev event to notify availability of FW dump */ 1335 /* Send a udev event to notify availability of FW dump */
1215 kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, msg); 1336 kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, msg);
1216 1337
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c
index e5277a632671..14f748cbf0de 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c
@@ -15,6 +15,7 @@
15#define QLC_MAC_OPCODE_MASK 0x7 15#define QLC_MAC_OPCODE_MASK 0x7
16#define QLC_VF_FLOOD_BIT BIT_16 16#define QLC_VF_FLOOD_BIT BIT_16
17#define QLC_FLOOD_MODE 0x5 17#define QLC_FLOOD_MODE 0x5
18#define QLC_SRIOV_ALLOW_VLAN0 BIT_19
18 19
19static int qlcnic_sriov_pf_get_vport_handle(struct qlcnic_adapter *, u8); 20static int qlcnic_sriov_pf_get_vport_handle(struct qlcnic_adapter *, u8);
20 21
@@ -335,8 +336,11 @@ static int qlcnic_sriov_pf_cfg_vlan_filtering(struct qlcnic_adapter *adapter,
335 return err; 336 return err;
336 337
337 cmd.req.arg[1] = 0x4; 338 cmd.req.arg[1] = 0x4;
338 if (enable) 339 if (enable) {
339 cmd.req.arg[1] |= BIT_16; 340 cmd.req.arg[1] |= BIT_16;
341 if (qlcnic_84xx_check(adapter))
342 cmd.req.arg[1] |= QLC_SRIOV_ALLOW_VLAN0;
343 }
340 344
341 err = qlcnic_issue_cmd(adapter, &cmd); 345 err = qlcnic_issue_cmd(adapter, &cmd);
342 if (err) 346 if (err)
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c
index 3d64113a35af..448d156c3d08 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c
@@ -350,33 +350,15 @@ static ssize_t qlcnic_sysfs_write_mem(struct file *filp, struct kobject *kobj,
350 return size; 350 return size;
351} 351}
352 352
353static u32 qlcnic_get_pci_func_count(struct qlcnic_adapter *adapter)
354{
355 struct qlcnic_hardware_context *ahw = adapter->ahw;
356 u32 count = 0;
357
358 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
359 return ahw->total_nic_func;
360
361 if (ahw->total_pci_func <= QLC_DEFAULT_VNIC_COUNT)
362 count = QLC_DEFAULT_VNIC_COUNT;
363 else
364 count = ahw->max_vnic_func;
365
366 return count;
367}
368
369int qlcnic_is_valid_nic_func(struct qlcnic_adapter *adapter, u8 pci_func) 353int qlcnic_is_valid_nic_func(struct qlcnic_adapter *adapter, u8 pci_func)
370{ 354{
371 u32 pci_func_count = qlcnic_get_pci_func_count(adapter);
372 int i; 355 int i;
373 356
374 for (i = 0; i < pci_func_count; i++) { 357 for (i = 0; i < adapter->ahw->max_vnic_func; i++) {
375 if (adapter->npars[i].pci_func == pci_func) 358 if (adapter->npars[i].pci_func == pci_func)
376 return i; 359 return i;
377 } 360 }
378 361 return -EINVAL;
379 return -1;
380} 362}
381 363
382static int validate_pm_config(struct qlcnic_adapter *adapter, 364static int validate_pm_config(struct qlcnic_adapter *adapter,
@@ -464,23 +446,21 @@ static ssize_t qlcnic_sysfs_read_pm_config(struct file *filp,
464{ 446{
465 struct device *dev = container_of(kobj, struct device, kobj); 447 struct device *dev = container_of(kobj, struct device, kobj);
466 struct qlcnic_adapter *adapter = dev_get_drvdata(dev); 448 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
467 u32 pci_func_count = qlcnic_get_pci_func_count(adapter);
468 struct qlcnic_pm_func_cfg *pm_cfg; 449 struct qlcnic_pm_func_cfg *pm_cfg;
469 int i, pm_cfg_size;
470 u8 pci_func; 450 u8 pci_func;
451 u32 count;
452 int i;
471 453
472 pm_cfg_size = pci_func_count * sizeof(*pm_cfg); 454 memset(buf, 0, size);
473 if (size != pm_cfg_size)
474 return QL_STATUS_INVALID_PARAM;
475
476 memset(buf, 0, pm_cfg_size);
477 pm_cfg = (struct qlcnic_pm_func_cfg *)buf; 455 pm_cfg = (struct qlcnic_pm_func_cfg *)buf;
478 456 count = size / sizeof(struct qlcnic_pm_func_cfg);
479 for (i = 0; i < pci_func_count; i++) { 457 for (i = 0; i < adapter->ahw->total_nic_func; i++) {
480 pci_func = adapter->npars[i].pci_func; 458 pci_func = adapter->npars[i].pci_func;
481 if (!adapter->npars[i].active) 459 if (pci_func >= count) {
460 dev_dbg(dev, "%s: Total nic functions[%d], App sent function count[%d]\n",
461 __func__, adapter->ahw->total_nic_func, count);
482 continue; 462 continue;
483 463 }
484 if (!adapter->npars[i].eswitch_status) 464 if (!adapter->npars[i].eswitch_status)
485 continue; 465 continue;
486 466
@@ -494,7 +474,6 @@ static ssize_t qlcnic_sysfs_read_pm_config(struct file *filp,
494static int validate_esw_config(struct qlcnic_adapter *adapter, 474static int validate_esw_config(struct qlcnic_adapter *adapter,
495 struct qlcnic_esw_func_cfg *esw_cfg, int count) 475 struct qlcnic_esw_func_cfg *esw_cfg, int count)
496{ 476{
497 u32 pci_func_count = qlcnic_get_pci_func_count(adapter);
498 struct qlcnic_hardware_context *ahw = adapter->ahw; 477 struct qlcnic_hardware_context *ahw = adapter->ahw;
499 int i, ret; 478 int i, ret;
500 u32 op_mode; 479 u32 op_mode;
@@ -507,7 +486,7 @@ static int validate_esw_config(struct qlcnic_adapter *adapter,
507 486
508 for (i = 0; i < count; i++) { 487 for (i = 0; i < count; i++) {
509 pci_func = esw_cfg[i].pci_func; 488 pci_func = esw_cfg[i].pci_func;
510 if (pci_func >= pci_func_count) 489 if (pci_func >= ahw->max_vnic_func)
511 return QL_STATUS_INVALID_PARAM; 490 return QL_STATUS_INVALID_PARAM;
512 491
513 if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC) 492 if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC)
@@ -642,23 +621,21 @@ static ssize_t qlcnic_sysfs_read_esw_config(struct file *file,
642{ 621{
643 struct device *dev = container_of(kobj, struct device, kobj); 622 struct device *dev = container_of(kobj, struct device, kobj);
644 struct qlcnic_adapter *adapter = dev_get_drvdata(dev); 623 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
645 u32 pci_func_count = qlcnic_get_pci_func_count(adapter);
646 struct qlcnic_esw_func_cfg *esw_cfg; 624 struct qlcnic_esw_func_cfg *esw_cfg;
647 size_t esw_cfg_size; 625 u8 pci_func;
648 u8 i, pci_func; 626 u32 count;
649 627 int i;
650 esw_cfg_size = pci_func_count * sizeof(*esw_cfg);
651 if (size != esw_cfg_size)
652 return QL_STATUS_INVALID_PARAM;
653 628
654 memset(buf, 0, esw_cfg_size); 629 memset(buf, 0, size);
655 esw_cfg = (struct qlcnic_esw_func_cfg *)buf; 630 esw_cfg = (struct qlcnic_esw_func_cfg *)buf;
656 631 count = size / sizeof(struct qlcnic_esw_func_cfg);
657 for (i = 0; i < pci_func_count; i++) { 632 for (i = 0; i < adapter->ahw->total_nic_func; i++) {
658 pci_func = adapter->npars[i].pci_func; 633 pci_func = adapter->npars[i].pci_func;
659 if (!adapter->npars[i].active) 634 if (pci_func >= count) {
635 dev_dbg(dev, "%s: Total nic functions[%d], App sent function count[%d]\n",
636 __func__, adapter->ahw->total_nic_func, count);
660 continue; 637 continue;
661 638 }
662 if (!adapter->npars[i].eswitch_status) 639 if (!adapter->npars[i].eswitch_status)
663 continue; 640 continue;
664 641
@@ -741,23 +718,24 @@ static ssize_t qlcnic_sysfs_read_npar_config(struct file *file,
741{ 718{
742 struct device *dev = container_of(kobj, struct device, kobj); 719 struct device *dev = container_of(kobj, struct device, kobj);
743 struct qlcnic_adapter *adapter = dev_get_drvdata(dev); 720 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
744 u32 pci_func_count = qlcnic_get_pci_func_count(adapter);
745 struct qlcnic_npar_func_cfg *np_cfg; 721 struct qlcnic_npar_func_cfg *np_cfg;
746 struct qlcnic_info nic_info; 722 struct qlcnic_info nic_info;
747 size_t np_cfg_size;
748 int i, ret; 723 int i, ret;
749 724 u32 count;
750 np_cfg_size = pci_func_count * sizeof(*np_cfg);
751 if (size != np_cfg_size)
752 return QL_STATUS_INVALID_PARAM;
753 725
754 memset(&nic_info, 0, sizeof(struct qlcnic_info)); 726 memset(&nic_info, 0, sizeof(struct qlcnic_info));
755 memset(buf, 0, np_cfg_size); 727 memset(buf, 0, size);
756 np_cfg = (struct qlcnic_npar_func_cfg *)buf; 728 np_cfg = (struct qlcnic_npar_func_cfg *)buf;
757 729
758 for (i = 0; i < pci_func_count; i++) { 730 count = size / sizeof(struct qlcnic_npar_func_cfg);
731 for (i = 0; i < adapter->ahw->total_nic_func; i++) {
759 if (qlcnic_is_valid_nic_func(adapter, i) < 0) 732 if (qlcnic_is_valid_nic_func(adapter, i) < 0)
760 continue; 733 continue;
734 if (adapter->npars[i].pci_func >= count) {
735 dev_dbg(dev, "%s: Total nic functions[%d], App sent function count[%d]\n",
736 __func__, adapter->ahw->total_nic_func, count);
737 continue;
738 }
761 ret = qlcnic_get_nic_info(adapter, &nic_info, i); 739 ret = qlcnic_get_nic_info(adapter, &nic_info, i);
762 if (ret) 740 if (ret)
763 return ret; 741 return ret;
@@ -783,7 +761,6 @@ static ssize_t qlcnic_sysfs_get_port_stats(struct file *file,
783{ 761{
784 struct device *dev = container_of(kobj, struct device, kobj); 762 struct device *dev = container_of(kobj, struct device, kobj);
785 struct qlcnic_adapter *adapter = dev_get_drvdata(dev); 763 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
786 u32 pci_func_count = qlcnic_get_pci_func_count(adapter);
787 struct qlcnic_esw_statistics port_stats; 764 struct qlcnic_esw_statistics port_stats;
788 int ret; 765 int ret;
789 766
@@ -793,7 +770,7 @@ static ssize_t qlcnic_sysfs_get_port_stats(struct file *file,
793 if (size != sizeof(struct qlcnic_esw_statistics)) 770 if (size != sizeof(struct qlcnic_esw_statistics))
794 return QL_STATUS_INVALID_PARAM; 771 return QL_STATUS_INVALID_PARAM;
795 772
796 if (offset >= pci_func_count) 773 if (offset >= adapter->ahw->max_vnic_func)
797 return QL_STATUS_INVALID_PARAM; 774 return QL_STATUS_INVALID_PARAM;
798 775
799 memset(&port_stats, 0, size); 776 memset(&port_stats, 0, size);
@@ -884,13 +861,12 @@ static ssize_t qlcnic_sysfs_clear_port_stats(struct file *file,
884 861
885 struct device *dev = container_of(kobj, struct device, kobj); 862 struct device *dev = container_of(kobj, struct device, kobj);
886 struct qlcnic_adapter *adapter = dev_get_drvdata(dev); 863 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
887 u32 pci_func_count = qlcnic_get_pci_func_count(adapter);
888 int ret; 864 int ret;
889 865
890 if (qlcnic_83xx_check(adapter)) 866 if (qlcnic_83xx_check(adapter))
891 return QLC_STATUS_UNSUPPORTED_CMD; 867 return QLC_STATUS_UNSUPPORTED_CMD;
892 868
893 if (offset >= pci_func_count) 869 if (offset >= adapter->ahw->max_vnic_func)
894 return QL_STATUS_INVALID_PARAM; 870 return QL_STATUS_INVALID_PARAM;
895 871
896 ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_PORT, offset, 872 ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_PORT, offset,
@@ -914,17 +890,12 @@ static ssize_t qlcnic_sysfs_read_pci_config(struct file *file,
914{ 890{
915 struct device *dev = container_of(kobj, struct device, kobj); 891 struct device *dev = container_of(kobj, struct device, kobj);
916 struct qlcnic_adapter *adapter = dev_get_drvdata(dev); 892 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
917 u32 pci_func_count = qlcnic_get_pci_func_count(adapter);
918 struct qlcnic_pci_func_cfg *pci_cfg; 893 struct qlcnic_pci_func_cfg *pci_cfg;
919 struct qlcnic_pci_info *pci_info; 894 struct qlcnic_pci_info *pci_info;
920 size_t pci_cfg_sz;
921 int i, ret; 895 int i, ret;
896 u32 count;
922 897
923 pci_cfg_sz = pci_func_count * sizeof(*pci_cfg); 898 pci_info = kcalloc(size, sizeof(*pci_info), GFP_KERNEL);
924 if (size != pci_cfg_sz)
925 return QL_STATUS_INVALID_PARAM;
926
927 pci_info = kcalloc(pci_func_count, sizeof(*pci_info), GFP_KERNEL);
928 if (!pci_info) 899 if (!pci_info)
929 return -ENOMEM; 900 return -ENOMEM;
930 901
@@ -935,7 +906,8 @@ static ssize_t qlcnic_sysfs_read_pci_config(struct file *file,
935 } 906 }
936 907
937 pci_cfg = (struct qlcnic_pci_func_cfg *)buf; 908 pci_cfg = (struct qlcnic_pci_func_cfg *)buf;
938 for (i = 0; i < pci_func_count; i++) { 909 count = size / sizeof(struct qlcnic_pci_func_cfg);
910 for (i = 0; i < count; i++) {
939 pci_cfg[i].pci_func = pci_info[i].id; 911 pci_cfg[i].pci_func = pci_info[i].id;
940 pci_cfg[i].func_type = pci_info[i].type; 912 pci_cfg[i].func_type = pci_info[i].type;
941 pci_cfg[i].func_state = 0; 913 pci_cfg[i].func_state = 0;