diff options
author | Sathya Perla <sathya.perla@emulex.com> | 2014-03-27 01:16:18 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-03-28 14:24:54 -0400 |
commit | a401801c6ed141f8cee735775a501ea9e3e6aaed (patch) | |
tree | 6884a16eaf12ec50f307b9b93ce177cfec2aabfd | |
parent | e1250037de22b99694ebfd37b867a3f591b0dc39 (diff) |
be2net: add FW cmds needed for VxLAN offloads
This patch adds support for the FW cmds needed for VxLAN offloads
on Skyhawk-R:
1) The VxLAN UDP port needs to be configured via the port-desc of
SET_PROFILE_CONFIG_v1 cmd.
This patch re-factors the be_set_profile_config() code (used so far
only for setting VF QoS) to be used to set any type of descriptor.
2) The MANAGE_IFACE_FILTERS cmds is needed to convert a normal interface
into a tunnel interface. This allows for RSS to work even on the inner
TCP/UDP headers of VxLAN traffic.
Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-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_main.c | 8 |
3 files changed, 154 insertions, 58 deletions
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_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index a61f967f9ca1..8790e5497ba0 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c | |||
@@ -1346,11 +1346,7 @@ static int be_set_vf_tx_rate(struct net_device *netdev, | |||
1346 | return -EINVAL; | 1346 | return -EINVAL; |
1347 | } | 1347 | } |
1348 | 1348 | ||
1349 | if (lancer_chip(adapter)) | 1349 | 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) | 1350 | if (status) |
1355 | dev_err(&adapter->pdev->dev, | 1351 | dev_err(&adapter->pdev->dev, |
1356 | "tx rate %d on VF %d failed\n", rate, vf); | 1352 | "tx rate %d on VF %d failed\n", rate, vf); |
@@ -3124,7 +3120,7 @@ static int be_vf_setup(struct be_adapter *adapter) | |||
3124 | * Allow full available bandwidth | 3120 | * Allow full available bandwidth |
3125 | */ | 3121 | */ |
3126 | if (BE3_chip(adapter) && !old_vfs) | 3122 | if (BE3_chip(adapter) && !old_vfs) |
3127 | be_cmd_set_qos(adapter, 1000, vf+1); | 3123 | be_cmd_config_qos(adapter, 1000, vf + 1); |
3128 | 3124 | ||
3129 | status = be_cmd_link_status_query(adapter, &lnk_speed, | 3125 | status = be_cmd_link_status_query(adapter, &lnk_speed, |
3130 | NULL, vf + 1); | 3126 | NULL, vf + 1); |