diff options
author | David S. Miller <davem@davemloft.net> | 2014-03-28 14:25:02 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-03-28 14:25:02 -0400 |
commit | 1d784724dbb518a63535e79d7074fbaa38305605 (patch) | |
tree | af9e9a3b0cd7f514f1c41bab0e7c58dc3ca214fd | |
parent | e1250037de22b99694ebfd37b867a3f591b0dc39 (diff) | |
parent | c9c47142f6bf4684c13b571b312b67f3830f1d86 (diff) |
Merge branch 'be2net-next'
Sathya Perla says:
====================
be2net: add vxlan offload support
The first patch adds the FW cmds needed to configure the Skyhawk-R
chip for supporting VxLAN offloads. The second patch implements the
ndo_add/del_vxlan_port() methods and the plumbing for supporting
RX/TX csum, TSO and RSS steering offloads for VxLAN traffic.
v2 changes:
NETIF_F_SG need not be set for hw_enc_features by the driver as it is
done by the stack.
v3 changes:
* Defer FW cmds needed for VxLAN offloads to a workqueue
* Reset FW to VxLAN offloads disabled state in the unload path
v4 changes:
* Revert the usage of workqueue (introduced in v3) to implement
ndo_add/del_vxlan_port() as it is currently not needed (none of the
FW cmd calls sleep.) Suggested by David M.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be.h | 7 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_cmds.c | 135 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_cmds.h | 69 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_hw.h | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_main.c | 132 |
5 files changed, 279 insertions, 67 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h index a587c8aa27ed..8ccaa2520dc3 100644 --- a/drivers/net/ethernet/emulex/benet/be.h +++ b/drivers/net/ethernet/emulex/benet/be.h | |||
@@ -296,6 +296,7 @@ struct be_rx_compl_info { | |||
296 | u8 qnq; | 296 | u8 qnq; |
297 | u8 pkt_type; | 297 | u8 pkt_type; |
298 | u8 ip_frag; | 298 | u8 ip_frag; |
299 | u8 tunneled; | ||
299 | }; | 300 | }; |
300 | 301 | ||
301 | struct be_rx_obj { | 302 | struct be_rx_obj { |
@@ -371,10 +372,11 @@ enum vf_state { | |||
371 | #define BE_FLAGS_WORKER_SCHEDULED (1 << 3) | 372 | #define BE_FLAGS_WORKER_SCHEDULED (1 << 3) |
372 | #define BE_FLAGS_VLAN_PROMISC (1 << 4) | 373 | #define BE_FLAGS_VLAN_PROMISC (1 << 4) |
373 | #define BE_FLAGS_NAPI_ENABLED (1 << 9) | 374 | #define BE_FLAGS_NAPI_ENABLED (1 << 9) |
374 | #define BE_UC_PMAC_COUNT 30 | ||
375 | #define BE_VF_UC_PMAC_COUNT 2 | ||
376 | #define BE_FLAGS_QNQ_ASYNC_EVT_RCVD (1 << 11) | 375 | #define BE_FLAGS_QNQ_ASYNC_EVT_RCVD (1 << 11) |
376 | #define BE_FLAGS_VXLAN_OFFLOADS (1 << 12) | ||
377 | 377 | ||
378 | #define BE_UC_PMAC_COUNT 30 | ||
379 | #define BE_VF_UC_PMAC_COUNT 2 | ||
378 | /* Ethtool set_dump flags */ | 380 | /* Ethtool set_dump flags */ |
379 | #define LANCER_INITIATE_FW_DUMP 0x1 | 381 | #define LANCER_INITIATE_FW_DUMP 0x1 |
380 | 382 | ||
@@ -494,6 +496,7 @@ struct be_adapter { | |||
494 | u32 sli_family; | 496 | u32 sli_family; |
495 | u8 hba_port_num; | 497 | u8 hba_port_num; |
496 | u16 pvid; | 498 | u16 pvid; |
499 | __be16 vxlan_port; | ||
497 | struct phy_info phy; | 500 | struct phy_info phy; |
498 | u8 wol_cap; | 501 | u8 wol_cap; |
499 | bool wol_en; | 502 | bool wol_en; |
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index cf5afe72f12f..d1ec15af0d24 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c | |||
@@ -3503,14 +3503,11 @@ err: | |||
3503 | return status; | 3503 | return status; |
3504 | } | 3504 | } |
3505 | 3505 | ||
3506 | /* Currently only Lancer uses this command and it supports version 0 only | 3506 | int be_cmd_set_profile_config(struct be_adapter *adapter, void *desc, |
3507 | * Uses sync mcc | 3507 | int size, u8 version, u8 domain) |
3508 | */ | ||
3509 | int be_cmd_set_profile_config(struct be_adapter *adapter, u32 bps, | ||
3510 | u8 domain) | ||
3511 | { | 3508 | { |
3512 | struct be_mcc_wrb *wrb; | ||
3513 | struct be_cmd_req_set_profile_config *req; | 3509 | struct be_cmd_req_set_profile_config *req; |
3510 | struct be_mcc_wrb *wrb; | ||
3514 | int status; | 3511 | int status; |
3515 | 3512 | ||
3516 | spin_lock_bh(&adapter->mcc_lock); | 3513 | spin_lock_bh(&adapter->mcc_lock); |
@@ -3522,44 +3519,116 @@ int be_cmd_set_profile_config(struct be_adapter *adapter, u32 bps, | |||
3522 | } | 3519 | } |
3523 | 3520 | ||
3524 | req = embedded_payload(wrb); | 3521 | req = embedded_payload(wrb); |
3525 | |||
3526 | be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | 3522 | be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, |
3527 | OPCODE_COMMON_SET_PROFILE_CONFIG, sizeof(*req), | 3523 | OPCODE_COMMON_SET_PROFILE_CONFIG, sizeof(*req), |
3528 | wrb, NULL); | 3524 | wrb, NULL); |
3525 | req->hdr.version = version; | ||
3529 | req->hdr.domain = domain; | 3526 | req->hdr.domain = domain; |
3530 | req->desc_count = cpu_to_le32(1); | 3527 | req->desc_count = cpu_to_le32(1); |
3531 | req->nic_desc.hdr.desc_type = NIC_RESOURCE_DESC_TYPE_V0; | 3528 | memcpy(req->desc, desc, size); |
3532 | req->nic_desc.hdr.desc_len = RESOURCE_DESC_SIZE_V0; | 3529 | |
3533 | req->nic_desc.flags = (1 << QUN) | (1 << IMM) | (1 << NOSV); | ||
3534 | req->nic_desc.pf_num = adapter->pf_number; | ||
3535 | req->nic_desc.vf_num = domain; | ||
3536 | |||
3537 | /* Mark fields invalid */ | ||
3538 | req->nic_desc.unicast_mac_count = 0xFFFF; | ||
3539 | req->nic_desc.mcc_count = 0xFFFF; | ||
3540 | req->nic_desc.vlan_count = 0xFFFF; | ||
3541 | req->nic_desc.mcast_mac_count = 0xFFFF; | ||
3542 | req->nic_desc.txq_count = 0xFFFF; | ||
3543 | req->nic_desc.rq_count = 0xFFFF; | ||
3544 | req->nic_desc.rssq_count = 0xFFFF; | ||
3545 | req->nic_desc.lro_count = 0xFFFF; | ||
3546 | req->nic_desc.cq_count = 0xFFFF; | ||
3547 | req->nic_desc.toe_conn_count = 0xFFFF; | ||
3548 | req->nic_desc.eq_count = 0xFFFF; | ||
3549 | req->nic_desc.link_param = 0xFF; | ||
3550 | req->nic_desc.bw_min = 0xFFFFFFFF; | ||
3551 | req->nic_desc.acpi_params = 0xFF; | ||
3552 | req->nic_desc.wol_param = 0x0F; | ||
3553 | |||
3554 | /* Change BW */ | ||
3555 | req->nic_desc.bw_min = cpu_to_le32(bps); | ||
3556 | req->nic_desc.bw_max = cpu_to_le32(bps); | ||
3557 | status = be_mcc_notify_wait(adapter); | 3530 | status = be_mcc_notify_wait(adapter); |
3558 | err: | 3531 | err: |
3559 | spin_unlock_bh(&adapter->mcc_lock); | 3532 | spin_unlock_bh(&adapter->mcc_lock); |
3560 | return status; | 3533 | return status; |
3561 | } | 3534 | } |
3562 | 3535 | ||
3536 | /* Mark all fields invalid */ | ||
3537 | void be_reset_nic_desc(struct be_nic_res_desc *nic) | ||
3538 | { | ||
3539 | memset(nic, 0, sizeof(*nic)); | ||
3540 | nic->unicast_mac_count = 0xFFFF; | ||
3541 | nic->mcc_count = 0xFFFF; | ||
3542 | nic->vlan_count = 0xFFFF; | ||
3543 | nic->mcast_mac_count = 0xFFFF; | ||
3544 | nic->txq_count = 0xFFFF; | ||
3545 | nic->rq_count = 0xFFFF; | ||
3546 | nic->rssq_count = 0xFFFF; | ||
3547 | nic->lro_count = 0xFFFF; | ||
3548 | nic->cq_count = 0xFFFF; | ||
3549 | nic->toe_conn_count = 0xFFFF; | ||
3550 | nic->eq_count = 0xFFFF; | ||
3551 | nic->link_param = 0xFF; | ||
3552 | nic->acpi_params = 0xFF; | ||
3553 | nic->wol_param = 0x0F; | ||
3554 | nic->bw_min = 0xFFFFFFFF; | ||
3555 | nic->bw_max = 0xFFFFFFFF; | ||
3556 | } | ||
3557 | |||
3558 | int be_cmd_config_qos(struct be_adapter *adapter, u32 bps, u8 domain) | ||
3559 | { | ||
3560 | if (lancer_chip(adapter)) { | ||
3561 | struct be_nic_res_desc nic_desc; | ||
3562 | |||
3563 | be_reset_nic_desc(&nic_desc); | ||
3564 | nic_desc.hdr.desc_type = NIC_RESOURCE_DESC_TYPE_V0; | ||
3565 | nic_desc.hdr.desc_len = RESOURCE_DESC_SIZE_V0; | ||
3566 | nic_desc.flags = (1 << QUN_SHIFT) | (1 << IMM_SHIFT) | | ||
3567 | (1 << NOSV_SHIFT); | ||
3568 | nic_desc.pf_num = adapter->pf_number; | ||
3569 | nic_desc.vf_num = domain; | ||
3570 | nic_desc.bw_max = cpu_to_le32(bps); | ||
3571 | |||
3572 | return be_cmd_set_profile_config(adapter, &nic_desc, | ||
3573 | RESOURCE_DESC_SIZE_V0, | ||
3574 | 0, domain); | ||
3575 | } else { | ||
3576 | return be_cmd_set_qos(adapter, bps, domain); | ||
3577 | } | ||
3578 | } | ||
3579 | |||
3580 | int be_cmd_manage_iface(struct be_adapter *adapter, u32 iface, u8 op) | ||
3581 | { | ||
3582 | struct be_mcc_wrb *wrb; | ||
3583 | struct be_cmd_req_manage_iface_filters *req; | ||
3584 | int status; | ||
3585 | |||
3586 | if (iface == 0xFFFFFFFF) | ||
3587 | return -1; | ||
3588 | |||
3589 | spin_lock_bh(&adapter->mcc_lock); | ||
3590 | |||
3591 | wrb = wrb_from_mccq(adapter); | ||
3592 | if (!wrb) { | ||
3593 | status = -EBUSY; | ||
3594 | goto err; | ||
3595 | } | ||
3596 | req = embedded_payload(wrb); | ||
3597 | |||
3598 | be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | ||
3599 | OPCODE_COMMON_MANAGE_IFACE_FILTERS, sizeof(*req), | ||
3600 | wrb, NULL); | ||
3601 | req->op = op; | ||
3602 | req->target_iface_id = cpu_to_le32(iface); | ||
3603 | |||
3604 | status = be_mcc_notify_wait(adapter); | ||
3605 | err: | ||
3606 | spin_unlock_bh(&adapter->mcc_lock); | ||
3607 | return status; | ||
3608 | } | ||
3609 | |||
3610 | int be_cmd_set_vxlan_port(struct be_adapter *adapter, __be16 port) | ||
3611 | { | ||
3612 | struct be_port_res_desc port_desc; | ||
3613 | |||
3614 | memset(&port_desc, 0, sizeof(port_desc)); | ||
3615 | port_desc.hdr.desc_type = PORT_RESOURCE_DESC_TYPE_V1; | ||
3616 | port_desc.hdr.desc_len = RESOURCE_DESC_SIZE_V1; | ||
3617 | port_desc.flags = (1 << IMM_SHIFT) | (1 << NOSV_SHIFT); | ||
3618 | port_desc.link_num = adapter->hba_port_num; | ||
3619 | if (port) { | ||
3620 | port_desc.nv_flags = NV_TYPE_VXLAN | (1 << SOCVID_SHIFT) | | ||
3621 | (1 << RCVID_SHIFT); | ||
3622 | port_desc.nv_port = swab16(port); | ||
3623 | } else { | ||
3624 | port_desc.nv_flags = NV_TYPE_DISABLED; | ||
3625 | port_desc.nv_port = 0; | ||
3626 | } | ||
3627 | |||
3628 | return be_cmd_set_profile_config(adapter, &port_desc, | ||
3629 | RESOURCE_DESC_SIZE_V1, 1, 0); | ||
3630 | } | ||
3631 | |||
3563 | int be_cmd_get_if_id(struct be_adapter *adapter, struct be_vf_cfg *vf_cfg, | 3632 | int be_cmd_get_if_id(struct be_adapter *adapter, struct be_vf_cfg *vf_cfg, |
3564 | int vf_num) | 3633 | int vf_num) |
3565 | { | 3634 | { |
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h index fda3e8851e17..b60e4d53c1c9 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.h +++ b/drivers/net/ethernet/emulex/benet/be_cmds.h | |||
@@ -222,6 +222,7 @@ struct be_mcc_mailbox { | |||
222 | #define OPCODE_COMMON_GET_FN_PRIVILEGES 170 | 222 | #define OPCODE_COMMON_GET_FN_PRIVILEGES 170 |
223 | #define OPCODE_COMMON_READ_OBJECT 171 | 223 | #define OPCODE_COMMON_READ_OBJECT 171 |
224 | #define OPCODE_COMMON_WRITE_OBJECT 172 | 224 | #define OPCODE_COMMON_WRITE_OBJECT 172 |
225 | #define OPCODE_COMMON_MANAGE_IFACE_FILTERS 193 | ||
225 | #define OPCODE_COMMON_GET_IFACE_LIST 194 | 226 | #define OPCODE_COMMON_GET_IFACE_LIST 194 |
226 | #define OPCODE_COMMON_ENABLE_DISABLE_VF 196 | 227 | #define OPCODE_COMMON_ENABLE_DISABLE_VF 196 |
227 | 228 | ||
@@ -1824,18 +1825,33 @@ struct be_cmd_req_set_ext_fat_caps { | |||
1824 | #define PORT_RESOURCE_DESC_TYPE_V1 0x55 | 1825 | #define PORT_RESOURCE_DESC_TYPE_V1 0x55 |
1825 | #define MAX_RESOURCE_DESC 264 | 1826 | #define MAX_RESOURCE_DESC 264 |
1826 | 1827 | ||
1827 | /* QOS unit number */ | 1828 | #define IMM_SHIFT 6 /* Immediate */ |
1828 | #define QUN 4 | 1829 | #define NOSV_SHIFT 7 /* No save */ |
1829 | /* Immediate */ | ||
1830 | #define IMM 6 | ||
1831 | /* No save */ | ||
1832 | #define NOSV 7 | ||
1833 | 1830 | ||
1834 | struct be_res_desc_hdr { | 1831 | struct be_res_desc_hdr { |
1835 | u8 desc_type; | 1832 | u8 desc_type; |
1836 | u8 desc_len; | 1833 | u8 desc_len; |
1837 | } __packed; | 1834 | } __packed; |
1838 | 1835 | ||
1836 | struct be_port_res_desc { | ||
1837 | struct be_res_desc_hdr hdr; | ||
1838 | u8 rsvd0; | ||
1839 | u8 flags; | ||
1840 | u8 link_num; | ||
1841 | u8 mc_type; | ||
1842 | u16 rsvd1; | ||
1843 | |||
1844 | #define NV_TYPE_MASK 0x3 /* bits 0-1 */ | ||
1845 | #define NV_TYPE_DISABLED 1 | ||
1846 | #define NV_TYPE_VXLAN 3 | ||
1847 | #define SOCVID_SHIFT 2 /* Strip outer vlan */ | ||
1848 | #define RCVID_SHIFT 4 /* Report vlan */ | ||
1849 | u8 nv_flags; | ||
1850 | u8 rsvd2; | ||
1851 | __le16 nv_port; /* vxlan/gre port */ | ||
1852 | u32 rsvd3[19]; | ||
1853 | } __packed; | ||
1854 | |||
1839 | struct be_pcie_res_desc { | 1855 | struct be_pcie_res_desc { |
1840 | struct be_res_desc_hdr hdr; | 1856 | struct be_res_desc_hdr hdr; |
1841 | u8 rsvd0; | 1857 | u8 rsvd0; |
@@ -1856,6 +1872,8 @@ struct be_pcie_res_desc { | |||
1856 | struct be_nic_res_desc { | 1872 | struct be_nic_res_desc { |
1857 | struct be_res_desc_hdr hdr; | 1873 | struct be_res_desc_hdr hdr; |
1858 | u8 rsvd1; | 1874 | u8 rsvd1; |
1875 | |||
1876 | #define QUN_SHIFT 4 /* QoS is in absolute units */ | ||
1859 | u8 flags; | 1877 | u8 flags; |
1860 | u8 vf_num; | 1878 | u8 vf_num; |
1861 | u8 rsvd2; | 1879 | u8 rsvd2; |
@@ -1896,16 +1914,6 @@ enum mc_type { | |||
1896 | vNIC2 = 0x07 | 1914 | vNIC2 = 0x07 |
1897 | }; | 1915 | }; |
1898 | 1916 | ||
1899 | struct be_port_res_desc { | ||
1900 | struct be_res_desc_hdr hdr; | ||
1901 | u8 rsvd0; | ||
1902 | u8 flags; | ||
1903 | u8 rsvd1; | ||
1904 | u8 mc_type; | ||
1905 | u16 rsvd2; | ||
1906 | u32 rsvd3[20]; | ||
1907 | } __packed; | ||
1908 | |||
1909 | /* Is BE in a multi-channel mode */ | 1917 | /* Is BE in a multi-channel mode */ |
1910 | static inline bool be_is_mc(struct be_adapter *adapter) | 1918 | static inline bool be_is_mc(struct be_adapter *adapter) |
1911 | { | 1919 | { |
@@ -1940,7 +1948,7 @@ struct be_cmd_req_set_profile_config { | |||
1940 | struct be_cmd_req_hdr hdr; | 1948 | struct be_cmd_req_hdr hdr; |
1941 | u32 rsvd; | 1949 | u32 rsvd; |
1942 | u32 desc_count; | 1950 | u32 desc_count; |
1943 | struct be_nic_res_desc nic_desc; | 1951 | u8 desc[RESOURCE_DESC_SIZE_V1]; |
1944 | }; | 1952 | }; |
1945 | 1953 | ||
1946 | struct be_cmd_resp_set_profile_config { | 1954 | struct be_cmd_resp_set_profile_config { |
@@ -1999,6 +2007,26 @@ struct be_cmd_req_set_ll_link { | |||
1999 | u32 link_config; /* Bit 0: UP_DOWN, Bit 9: PLINK */ | 2007 | u32 link_config; /* Bit 0: UP_DOWN, Bit 9: PLINK */ |
2000 | }; | 2008 | }; |
2001 | 2009 | ||
2010 | /************** Manage IFACE Filters *******************/ | ||
2011 | #define OP_CONVERT_NORMAL_TO_TUNNEL 0 | ||
2012 | #define OP_CONVERT_TUNNEL_TO_NORMAL 1 | ||
2013 | |||
2014 | struct be_cmd_req_manage_iface_filters { | ||
2015 | struct be_cmd_req_hdr hdr; | ||
2016 | u8 op; | ||
2017 | u8 rsvd0; | ||
2018 | u8 flags; | ||
2019 | u8 rsvd1; | ||
2020 | u32 tunnel_iface_id; | ||
2021 | u32 target_iface_id; | ||
2022 | u8 mac[6]; | ||
2023 | u16 vlan_tag; | ||
2024 | u32 tenant_id; | ||
2025 | u32 filter_id; | ||
2026 | u32 cap_flags; | ||
2027 | u32 cap_control_flags; | ||
2028 | } __packed; | ||
2029 | |||
2002 | int be_pci_fnum_get(struct be_adapter *adapter); | 2030 | int be_pci_fnum_get(struct be_adapter *adapter); |
2003 | int be_fw_wait_ready(struct be_adapter *adapter); | 2031 | int be_fw_wait_ready(struct be_adapter *adapter); |
2004 | int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, | 2032 | int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, |
@@ -2073,7 +2101,7 @@ int be_cmd_get_seeprom_data(struct be_adapter *adapter, | |||
2073 | int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num, | 2101 | int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num, |
2074 | u8 loopback_type, u8 enable); | 2102 | u8 loopback_type, u8 enable); |
2075 | int be_cmd_get_phy_info(struct be_adapter *adapter); | 2103 | int be_cmd_get_phy_info(struct be_adapter *adapter); |
2076 | int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain); | 2104 | int be_cmd_config_qos(struct be_adapter *adapter, u32 bps, u8 domain); |
2077 | void be_detect_error(struct be_adapter *adapter); | 2105 | void be_detect_error(struct be_adapter *adapter); |
2078 | int be_cmd_get_die_temperature(struct be_adapter *adapter); | 2106 | int be_cmd_get_die_temperature(struct be_adapter *adapter); |
2079 | int be_cmd_get_cntl_attributes(struct be_adapter *adapter); | 2107 | int be_cmd_get_cntl_attributes(struct be_adapter *adapter); |
@@ -2114,7 +2142,8 @@ int be_cmd_get_func_config(struct be_adapter *adapter, | |||
2114 | struct be_resources *res); | 2142 | struct be_resources *res); |
2115 | int be_cmd_get_profile_config(struct be_adapter *adapter, | 2143 | int be_cmd_get_profile_config(struct be_adapter *adapter, |
2116 | struct be_resources *res, u8 domain); | 2144 | struct be_resources *res, u8 domain); |
2117 | int be_cmd_set_profile_config(struct be_adapter *adapter, u32 bps, u8 domain); | 2145 | int be_cmd_set_profile_config(struct be_adapter *adapter, void *desc, |
2146 | int size, u8 version, u8 domain); | ||
2118 | int be_cmd_get_active_profile(struct be_adapter *adapter, u16 *profile); | 2147 | int be_cmd_get_active_profile(struct be_adapter *adapter, u16 *profile); |
2119 | int be_cmd_get_if_id(struct be_adapter *adapter, struct be_vf_cfg *vf_cfg, | 2148 | int be_cmd_get_if_id(struct be_adapter *adapter, struct be_vf_cfg *vf_cfg, |
2120 | int vf_num); | 2149 | int vf_num); |
@@ -2122,3 +2151,5 @@ int be_cmd_enable_vf(struct be_adapter *adapter, u8 domain); | |||
2122 | int be_cmd_intr_set(struct be_adapter *adapter, bool intr_enable); | 2151 | int be_cmd_intr_set(struct be_adapter *adapter, bool intr_enable); |
2123 | int be_cmd_set_logical_link_config(struct be_adapter *adapter, | 2152 | int be_cmd_set_logical_link_config(struct be_adapter *adapter, |
2124 | int link_state, u8 domain); | 2153 | int link_state, u8 domain); |
2154 | int be_cmd_set_vxlan_port(struct be_adapter *adapter, __be16 port); | ||
2155 | int be_cmd_manage_iface(struct be_adapter *adapter, u32 iface, u8 op); | ||
diff --git a/drivers/net/ethernet/emulex/benet/be_hw.h b/drivers/net/ethernet/emulex/benet/be_hw.h index 28ac8dd0beaa..3bd198550edb 100644 --- a/drivers/net/ethernet/emulex/benet/be_hw.h +++ b/drivers/net/ethernet/emulex/benet/be_hw.h | |||
@@ -407,7 +407,8 @@ struct amap_eth_rx_compl_v1 { | |||
407 | u8 vntagp; /* dword 2 */ | 407 | u8 vntagp; /* dword 2 */ |
408 | u8 header_len[8]; /* dword 2 */ | 408 | u8 header_len[8]; /* dword 2 */ |
409 | u8 header_split[2]; /* dword 2 */ | 409 | u8 header_split[2]; /* dword 2 */ |
410 | u8 rsvd1[13]; /* dword 2 */ | 410 | u8 rsvd1[12]; /* dword 2 */ |
411 | u8 tunneled; | ||
411 | u8 valid; /* dword 2 */ | 412 | u8 valid; /* dword 2 */ |
412 | u8 rsshash[32]; /* dword 3 */ | 413 | u8 rsshash[32]; /* dword 3 */ |
413 | } __packed; | 414 | } __packed; |
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index a61f967f9ca1..c89dc85ad8d6 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/aer.h> | 23 | #include <linux/aer.h> |
24 | #include <linux/if_bridge.h> | 24 | #include <linux/if_bridge.h> |
25 | #include <net/busy_poll.h> | 25 | #include <net/busy_poll.h> |
26 | #include <net/vxlan.h> | ||
26 | 27 | ||
27 | MODULE_VERSION(DRV_VER); | 28 | MODULE_VERSION(DRV_VER); |
28 | MODULE_DEVICE_TABLE(pci, be_dev_ids); | 29 | MODULE_DEVICE_TABLE(pci, be_dev_ids); |
@@ -718,10 +719,23 @@ static inline u16 be_get_tx_vlan_tag(struct be_adapter *adapter, | |||
718 | return vlan_tag; | 719 | return vlan_tag; |
719 | } | 720 | } |
720 | 721 | ||
722 | /* Used only for IP tunnel packets */ | ||
723 | static u16 skb_inner_ip_proto(struct sk_buff *skb) | ||
724 | { | ||
725 | return (inner_ip_hdr(skb)->version == 4) ? | ||
726 | inner_ip_hdr(skb)->protocol : inner_ipv6_hdr(skb)->nexthdr; | ||
727 | } | ||
728 | |||
729 | static u16 skb_ip_proto(struct sk_buff *skb) | ||
730 | { | ||
731 | return (ip_hdr(skb)->version == 4) ? | ||
732 | ip_hdr(skb)->protocol : ipv6_hdr(skb)->nexthdr; | ||
733 | } | ||
734 | |||
721 | static void wrb_fill_hdr(struct be_adapter *adapter, struct be_eth_hdr_wrb *hdr, | 735 | static void wrb_fill_hdr(struct be_adapter *adapter, struct be_eth_hdr_wrb *hdr, |
722 | struct sk_buff *skb, u32 wrb_cnt, u32 len, bool skip_hw_vlan) | 736 | struct sk_buff *skb, u32 wrb_cnt, u32 len, bool skip_hw_vlan) |
723 | { | 737 | { |
724 | u16 vlan_tag; | 738 | u16 vlan_tag, proto; |
725 | 739 | ||
726 | memset(hdr, 0, sizeof(*hdr)); | 740 | memset(hdr, 0, sizeof(*hdr)); |
727 | 741 | ||
@@ -734,9 +748,15 @@ static void wrb_fill_hdr(struct be_adapter *adapter, struct be_eth_hdr_wrb *hdr, | |||
734 | if (skb_is_gso_v6(skb) && !lancer_chip(adapter)) | 748 | if (skb_is_gso_v6(skb) && !lancer_chip(adapter)) |
735 | AMAP_SET_BITS(struct amap_eth_hdr_wrb, lso6, hdr, 1); | 749 | AMAP_SET_BITS(struct amap_eth_hdr_wrb, lso6, hdr, 1); |
736 | } else if (skb->ip_summed == CHECKSUM_PARTIAL) { | 750 | } else if (skb->ip_summed == CHECKSUM_PARTIAL) { |
737 | if (is_tcp_pkt(skb)) | 751 | if (skb->encapsulation) { |
752 | AMAP_SET_BITS(struct amap_eth_hdr_wrb, ipcs, hdr, 1); | ||
753 | proto = skb_inner_ip_proto(skb); | ||
754 | } else { | ||
755 | proto = skb_ip_proto(skb); | ||
756 | } | ||
757 | if (proto == IPPROTO_TCP) | ||
738 | AMAP_SET_BITS(struct amap_eth_hdr_wrb, tcpcs, hdr, 1); | 758 | AMAP_SET_BITS(struct amap_eth_hdr_wrb, tcpcs, hdr, 1); |
739 | else if (is_udp_pkt(skb)) | 759 | else if (proto == IPPROTO_UDP) |
740 | AMAP_SET_BITS(struct amap_eth_hdr_wrb, udpcs, hdr, 1); | 760 | AMAP_SET_BITS(struct amap_eth_hdr_wrb, udpcs, hdr, 1); |
741 | } | 761 | } |
742 | 762 | ||
@@ -1346,11 +1366,7 @@ static int be_set_vf_tx_rate(struct net_device *netdev, | |||
1346 | return -EINVAL; | 1366 | return -EINVAL; |
1347 | } | 1367 | } |
1348 | 1368 | ||
1349 | if (lancer_chip(adapter)) | 1369 | status = be_cmd_config_qos(adapter, rate / 10, vf + 1); |
1350 | status = be_cmd_set_profile_config(adapter, rate / 10, vf + 1); | ||
1351 | else | ||
1352 | status = be_cmd_set_qos(adapter, rate / 10, vf + 1); | ||
1353 | |||
1354 | if (status) | 1370 | if (status) |
1355 | dev_err(&adapter->pdev->dev, | 1371 | dev_err(&adapter->pdev->dev, |
1356 | "tx rate %d on VF %d failed\n", rate, vf); | 1372 | "tx rate %d on VF %d failed\n", rate, vf); |
@@ -1471,9 +1487,10 @@ static void be_rx_stats_update(struct be_rx_obj *rxo, | |||
1471 | static inline bool csum_passed(struct be_rx_compl_info *rxcp) | 1487 | static inline bool csum_passed(struct be_rx_compl_info *rxcp) |
1472 | { | 1488 | { |
1473 | /* L4 checksum is not reliable for non TCP/UDP packets. | 1489 | /* L4 checksum is not reliable for non TCP/UDP packets. |
1474 | * Also ignore ipcksm for ipv6 pkts */ | 1490 | * Also ignore ipcksm for ipv6 pkts |
1491 | */ | ||
1475 | return (rxcp->tcpf || rxcp->udpf) && rxcp->l4_csum && | 1492 | return (rxcp->tcpf || rxcp->udpf) && rxcp->l4_csum && |
1476 | (rxcp->ip_csum || rxcp->ipv6); | 1493 | (rxcp->ip_csum || rxcp->ipv6) && !rxcp->err; |
1477 | } | 1494 | } |
1478 | 1495 | ||
1479 | static struct be_rx_page_info *get_rx_page_info(struct be_rx_obj *rxo) | 1496 | static struct be_rx_page_info *get_rx_page_info(struct be_rx_obj *rxo) |
@@ -1616,6 +1633,8 @@ static void be_rx_compl_process(struct be_rx_obj *rxo, struct napi_struct *napi, | |||
1616 | skb_record_rx_queue(skb, rxo - &adapter->rx_obj[0]); | 1633 | skb_record_rx_queue(skb, rxo - &adapter->rx_obj[0]); |
1617 | if (netdev->features & NETIF_F_RXHASH) | 1634 | if (netdev->features & NETIF_F_RXHASH) |
1618 | skb_set_hash(skb, rxcp->rss_hash, PKT_HASH_TYPE_L3); | 1635 | skb_set_hash(skb, rxcp->rss_hash, PKT_HASH_TYPE_L3); |
1636 | |||
1637 | skb->encapsulation = rxcp->tunneled; | ||
1619 | skb_mark_napi_id(skb, napi); | 1638 | skb_mark_napi_id(skb, napi); |
1620 | 1639 | ||
1621 | if (rxcp->vlanf) | 1640 | if (rxcp->vlanf) |
@@ -1672,6 +1691,8 @@ static void be_rx_compl_process_gro(struct be_rx_obj *rxo, | |||
1672 | skb_record_rx_queue(skb, rxo - &adapter->rx_obj[0]); | 1691 | skb_record_rx_queue(skb, rxo - &adapter->rx_obj[0]); |
1673 | if (adapter->netdev->features & NETIF_F_RXHASH) | 1692 | if (adapter->netdev->features & NETIF_F_RXHASH) |
1674 | skb_set_hash(skb, rxcp->rss_hash, PKT_HASH_TYPE_L3); | 1693 | skb_set_hash(skb, rxcp->rss_hash, PKT_HASH_TYPE_L3); |
1694 | |||
1695 | skb->encapsulation = rxcp->tunneled; | ||
1675 | skb_mark_napi_id(skb, napi); | 1696 | skb_mark_napi_id(skb, napi); |
1676 | 1697 | ||
1677 | if (rxcp->vlanf) | 1698 | if (rxcp->vlanf) |
@@ -1708,6 +1729,8 @@ static void be_parse_rx_compl_v1(struct be_eth_rx_compl *compl, | |||
1708 | compl); | 1729 | compl); |
1709 | } | 1730 | } |
1710 | rxcp->port = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, port, compl); | 1731 | rxcp->port = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, port, compl); |
1732 | rxcp->tunneled = | ||
1733 | AMAP_GET_BITS(struct amap_eth_rx_compl_v1, tunneled, compl); | ||
1711 | } | 1734 | } |
1712 | 1735 | ||
1713 | static void be_parse_rx_compl_v0(struct be_eth_rx_compl *compl, | 1736 | static void be_parse_rx_compl_v0(struct be_eth_rx_compl *compl, |
@@ -2838,6 +2861,9 @@ static int be_open(struct net_device *netdev) | |||
2838 | 2861 | ||
2839 | netif_tx_start_all_queues(netdev); | 2862 | netif_tx_start_all_queues(netdev); |
2840 | be_roce_dev_open(adapter); | 2863 | be_roce_dev_open(adapter); |
2864 | |||
2865 | if (skyhawk_chip(adapter)) | ||
2866 | vxlan_get_rx_port(netdev); | ||
2841 | return 0; | 2867 | return 0; |
2842 | err: | 2868 | err: |
2843 | be_close(adapter->netdev); | 2869 | be_close(adapter->netdev); |
@@ -2993,6 +3019,19 @@ static void be_mac_clear(struct be_adapter *adapter) | |||
2993 | } | 3019 | } |
2994 | } | 3020 | } |
2995 | 3021 | ||
3022 | static void be_disable_vxlan_offloads(struct be_adapter *adapter) | ||
3023 | { | ||
3024 | if (adapter->flags & BE_FLAGS_VXLAN_OFFLOADS) | ||
3025 | be_cmd_manage_iface(adapter, adapter->if_handle, | ||
3026 | OP_CONVERT_TUNNEL_TO_NORMAL); | ||
3027 | |||
3028 | if (adapter->vxlan_port) | ||
3029 | be_cmd_set_vxlan_port(adapter, 0); | ||
3030 | |||
3031 | adapter->flags &= ~BE_FLAGS_VXLAN_OFFLOADS; | ||
3032 | adapter->vxlan_port = 0; | ||
3033 | } | ||
3034 | |||
2996 | static int be_clear(struct be_adapter *adapter) | 3035 | static int be_clear(struct be_adapter *adapter) |
2997 | { | 3036 | { |
2998 | be_cancel_worker(adapter); | 3037 | be_cancel_worker(adapter); |
@@ -3000,6 +3039,8 @@ static int be_clear(struct be_adapter *adapter) | |||
3000 | if (sriov_enabled(adapter)) | 3039 | if (sriov_enabled(adapter)) |
3001 | be_vf_clear(adapter); | 3040 | be_vf_clear(adapter); |
3002 | 3041 | ||
3042 | be_disable_vxlan_offloads(adapter); | ||
3043 | |||
3003 | /* delete the primary mac along with the uc-mac list */ | 3044 | /* delete the primary mac along with the uc-mac list */ |
3004 | be_mac_clear(adapter); | 3045 | be_mac_clear(adapter); |
3005 | 3046 | ||
@@ -3124,7 +3165,7 @@ static int be_vf_setup(struct be_adapter *adapter) | |||
3124 | * Allow full available bandwidth | 3165 | * Allow full available bandwidth |
3125 | */ | 3166 | */ |
3126 | if (BE3_chip(adapter) && !old_vfs) | 3167 | if (BE3_chip(adapter) && !old_vfs) |
3127 | be_cmd_set_qos(adapter, 1000, vf+1); | 3168 | be_cmd_config_qos(adapter, 1000, vf + 1); |
3128 | 3169 | ||
3129 | status = be_cmd_link_status_query(adapter, &lnk_speed, | 3170 | status = be_cmd_link_status_query(adapter, &lnk_speed, |
3130 | NULL, vf + 1); | 3171 | NULL, vf + 1); |
@@ -4124,6 +4165,65 @@ static int be_ndo_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq, | |||
4124 | BRIDGE_MODE_VEPA : BRIDGE_MODE_VEB); | 4165 | BRIDGE_MODE_VEPA : BRIDGE_MODE_VEB); |
4125 | } | 4166 | } |
4126 | 4167 | ||
4168 | static void be_add_vxlan_port(struct net_device *netdev, sa_family_t sa_family, | ||
4169 | __be16 port) | ||
4170 | { | ||
4171 | struct be_adapter *adapter = netdev_priv(netdev); | ||
4172 | struct device *dev = &adapter->pdev->dev; | ||
4173 | int status; | ||
4174 | |||
4175 | if (lancer_chip(adapter) || BEx_chip(adapter)) | ||
4176 | return; | ||
4177 | |||
4178 | if (adapter->flags & BE_FLAGS_VXLAN_OFFLOADS) { | ||
4179 | dev_warn(dev, "Cannot add UDP port %d for VxLAN offloads\n", | ||
4180 | be16_to_cpu(port)); | ||
4181 | dev_info(dev, | ||
4182 | "Only one UDP port supported for VxLAN offloads\n"); | ||
4183 | return; | ||
4184 | } | ||
4185 | |||
4186 | status = be_cmd_manage_iface(adapter, adapter->if_handle, | ||
4187 | OP_CONVERT_NORMAL_TO_TUNNEL); | ||
4188 | if (status) { | ||
4189 | dev_warn(dev, "Failed to convert normal interface to tunnel\n"); | ||
4190 | goto err; | ||
4191 | } | ||
4192 | |||
4193 | status = be_cmd_set_vxlan_port(adapter, port); | ||
4194 | if (status) { | ||
4195 | dev_warn(dev, "Failed to add VxLAN port\n"); | ||
4196 | goto err; | ||
4197 | } | ||
4198 | adapter->flags |= BE_FLAGS_VXLAN_OFFLOADS; | ||
4199 | adapter->vxlan_port = port; | ||
4200 | |||
4201 | dev_info(dev, "Enabled VxLAN offloads for UDP port %d\n", | ||
4202 | be16_to_cpu(port)); | ||
4203 | return; | ||
4204 | err: | ||
4205 | be_disable_vxlan_offloads(adapter); | ||
4206 | return; | ||
4207 | } | ||
4208 | |||
4209 | static void be_del_vxlan_port(struct net_device *netdev, sa_family_t sa_family, | ||
4210 | __be16 port) | ||
4211 | { | ||
4212 | struct be_adapter *adapter = netdev_priv(netdev); | ||
4213 | |||
4214 | if (lancer_chip(adapter) || BEx_chip(adapter)) | ||
4215 | return; | ||
4216 | |||
4217 | if (adapter->vxlan_port != port) | ||
4218 | return; | ||
4219 | |||
4220 | be_disable_vxlan_offloads(adapter); | ||
4221 | |||
4222 | dev_info(&adapter->pdev->dev, | ||
4223 | "Disabled VxLAN offloads for UDP port %d\n", | ||
4224 | be16_to_cpu(port)); | ||
4225 | } | ||
4226 | |||
4127 | static const struct net_device_ops be_netdev_ops = { | 4227 | static const struct net_device_ops be_netdev_ops = { |
4128 | .ndo_open = be_open, | 4228 | .ndo_open = be_open, |
4129 | .ndo_stop = be_close, | 4229 | .ndo_stop = be_close, |
@@ -4146,14 +4246,22 @@ static const struct net_device_ops be_netdev_ops = { | |||
4146 | .ndo_bridge_setlink = be_ndo_bridge_setlink, | 4246 | .ndo_bridge_setlink = be_ndo_bridge_setlink, |
4147 | .ndo_bridge_getlink = be_ndo_bridge_getlink, | 4247 | .ndo_bridge_getlink = be_ndo_bridge_getlink, |
4148 | #ifdef CONFIG_NET_RX_BUSY_POLL | 4248 | #ifdef CONFIG_NET_RX_BUSY_POLL |
4149 | .ndo_busy_poll = be_busy_poll | 4249 | .ndo_busy_poll = be_busy_poll, |
4150 | #endif | 4250 | #endif |
4251 | .ndo_add_vxlan_port = be_add_vxlan_port, | ||
4252 | .ndo_del_vxlan_port = be_del_vxlan_port, | ||
4151 | }; | 4253 | }; |
4152 | 4254 | ||
4153 | static void be_netdev_init(struct net_device *netdev) | 4255 | static void be_netdev_init(struct net_device *netdev) |
4154 | { | 4256 | { |
4155 | struct be_adapter *adapter = netdev_priv(netdev); | 4257 | struct be_adapter *adapter = netdev_priv(netdev); |
4156 | 4258 | ||
4259 | if (skyhawk_chip(adapter)) { | ||
4260 | netdev->hw_enc_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | | ||
4261 | NETIF_F_TSO | NETIF_F_TSO6 | | ||
4262 | NETIF_F_GSO_UDP_TUNNEL; | ||
4263 | netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL; | ||
4264 | } | ||
4157 | netdev->hw_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 | | 4265 | netdev->hw_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 | |
4158 | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM | | 4266 | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM | |
4159 | NETIF_F_HW_VLAN_CTAG_TX; | 4267 | NETIF_F_HW_VLAN_CTAG_TX; |