Skip to content

Commit

Permalink
be2net: add FW cmds needed for VxLAN offloads
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Sathya Perla authored and David S. Miller committed Mar 28, 2014
1 parent e125003 commit a401801
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 58 deletions.
135 changes: 102 additions & 33 deletions drivers/net/ethernet/emulex/benet/be_cmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -3503,14 +3503,11 @@ int be_cmd_get_profile_config(struct be_adapter *adapter,
return status;
}

/* Currently only Lancer uses this command and it supports version 0 only
* Uses sync mcc
*/
int be_cmd_set_profile_config(struct be_adapter *adapter, u32 bps,
u8 domain)
int be_cmd_set_profile_config(struct be_adapter *adapter, void *desc,
int size, u8 version, u8 domain)
{
struct be_mcc_wrb *wrb;
struct be_cmd_req_set_profile_config *req;
struct be_mcc_wrb *wrb;
int status;

spin_lock_bh(&adapter->mcc_lock);
Expand All @@ -3522,44 +3519,116 @@ int be_cmd_set_profile_config(struct be_adapter *adapter, u32 bps,
}

req = embedded_payload(wrb);

be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
OPCODE_COMMON_SET_PROFILE_CONFIG, sizeof(*req),
wrb, NULL);
req->hdr.version = version;
req->hdr.domain = domain;
req->desc_count = cpu_to_le32(1);
req->nic_desc.hdr.desc_type = NIC_RESOURCE_DESC_TYPE_V0;
req->nic_desc.hdr.desc_len = RESOURCE_DESC_SIZE_V0;
req->nic_desc.flags = (1 << QUN) | (1 << IMM) | (1 << NOSV);
req->nic_desc.pf_num = adapter->pf_number;
req->nic_desc.vf_num = domain;

/* Mark fields invalid */
req->nic_desc.unicast_mac_count = 0xFFFF;
req->nic_desc.mcc_count = 0xFFFF;
req->nic_desc.vlan_count = 0xFFFF;
req->nic_desc.mcast_mac_count = 0xFFFF;
req->nic_desc.txq_count = 0xFFFF;
req->nic_desc.rq_count = 0xFFFF;
req->nic_desc.rssq_count = 0xFFFF;
req->nic_desc.lro_count = 0xFFFF;
req->nic_desc.cq_count = 0xFFFF;
req->nic_desc.toe_conn_count = 0xFFFF;
req->nic_desc.eq_count = 0xFFFF;
req->nic_desc.link_param = 0xFF;
req->nic_desc.bw_min = 0xFFFFFFFF;
req->nic_desc.acpi_params = 0xFF;
req->nic_desc.wol_param = 0x0F;

/* Change BW */
req->nic_desc.bw_min = cpu_to_le32(bps);
req->nic_desc.bw_max = cpu_to_le32(bps);
memcpy(req->desc, desc, size);

status = be_mcc_notify_wait(adapter);
err:
spin_unlock_bh(&adapter->mcc_lock);
return status;
}

/* Mark all fields invalid */
void be_reset_nic_desc(struct be_nic_res_desc *nic)
{
memset(nic, 0, sizeof(*nic));
nic->unicast_mac_count = 0xFFFF;
nic->mcc_count = 0xFFFF;
nic->vlan_count = 0xFFFF;
nic->mcast_mac_count = 0xFFFF;
nic->txq_count = 0xFFFF;
nic->rq_count = 0xFFFF;
nic->rssq_count = 0xFFFF;
nic->lro_count = 0xFFFF;
nic->cq_count = 0xFFFF;
nic->toe_conn_count = 0xFFFF;
nic->eq_count = 0xFFFF;
nic->link_param = 0xFF;
nic->acpi_params = 0xFF;
nic->wol_param = 0x0F;
nic->bw_min = 0xFFFFFFFF;
nic->bw_max = 0xFFFFFFFF;
}

int be_cmd_config_qos(struct be_adapter *adapter, u32 bps, u8 domain)
{
if (lancer_chip(adapter)) {
struct be_nic_res_desc nic_desc;

be_reset_nic_desc(&nic_desc);
nic_desc.hdr.desc_type = NIC_RESOURCE_DESC_TYPE_V0;
nic_desc.hdr.desc_len = RESOURCE_DESC_SIZE_V0;
nic_desc.flags = (1 << QUN_SHIFT) | (1 << IMM_SHIFT) |
(1 << NOSV_SHIFT);
nic_desc.pf_num = adapter->pf_number;
nic_desc.vf_num = domain;
nic_desc.bw_max = cpu_to_le32(bps);

return be_cmd_set_profile_config(adapter, &nic_desc,
RESOURCE_DESC_SIZE_V0,
0, domain);
} else {
return be_cmd_set_qos(adapter, bps, domain);
}
}

int be_cmd_manage_iface(struct be_adapter *adapter, u32 iface, u8 op)
{
struct be_mcc_wrb *wrb;
struct be_cmd_req_manage_iface_filters *req;
int status;

if (iface == 0xFFFFFFFF)
return -1;

spin_lock_bh(&adapter->mcc_lock);

wrb = wrb_from_mccq(adapter);
if (!wrb) {
status = -EBUSY;
goto err;
}
req = embedded_payload(wrb);

be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
OPCODE_COMMON_MANAGE_IFACE_FILTERS, sizeof(*req),
wrb, NULL);
req->op = op;
req->target_iface_id = cpu_to_le32(iface);

status = be_mcc_notify_wait(adapter);
err:
spin_unlock_bh(&adapter->mcc_lock);
return status;
}

int be_cmd_set_vxlan_port(struct be_adapter *adapter, __be16 port)
{
struct be_port_res_desc port_desc;

memset(&port_desc, 0, sizeof(port_desc));
port_desc.hdr.desc_type = PORT_RESOURCE_DESC_TYPE_V1;
port_desc.hdr.desc_len = RESOURCE_DESC_SIZE_V1;
port_desc.flags = (1 << IMM_SHIFT) | (1 << NOSV_SHIFT);
port_desc.link_num = adapter->hba_port_num;
if (port) {
port_desc.nv_flags = NV_TYPE_VXLAN | (1 << SOCVID_SHIFT) |
(1 << RCVID_SHIFT);
port_desc.nv_port = swab16(port);
} else {
port_desc.nv_flags = NV_TYPE_DISABLED;
port_desc.nv_port = 0;
}

return be_cmd_set_profile_config(adapter, &port_desc,
RESOURCE_DESC_SIZE_V1, 1, 0);
}

int be_cmd_get_if_id(struct be_adapter *adapter, struct be_vf_cfg *vf_cfg,
int vf_num)
{
Expand Down
69 changes: 50 additions & 19 deletions drivers/net/ethernet/emulex/benet/be_cmds.h
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ struct be_mcc_mailbox {
#define OPCODE_COMMON_GET_FN_PRIVILEGES 170
#define OPCODE_COMMON_READ_OBJECT 171
#define OPCODE_COMMON_WRITE_OBJECT 172
#define OPCODE_COMMON_MANAGE_IFACE_FILTERS 193
#define OPCODE_COMMON_GET_IFACE_LIST 194
#define OPCODE_COMMON_ENABLE_DISABLE_VF 196

Expand Down Expand Up @@ -1824,18 +1825,33 @@ struct be_cmd_req_set_ext_fat_caps {
#define PORT_RESOURCE_DESC_TYPE_V1 0x55
#define MAX_RESOURCE_DESC 264

/* QOS unit number */
#define QUN 4
/* Immediate */
#define IMM 6
/* No save */
#define NOSV 7
#define IMM_SHIFT 6 /* Immediate */
#define NOSV_SHIFT 7 /* No save */

struct be_res_desc_hdr {
u8 desc_type;
u8 desc_len;
} __packed;

struct be_port_res_desc {
struct be_res_desc_hdr hdr;
u8 rsvd0;
u8 flags;
u8 link_num;
u8 mc_type;
u16 rsvd1;

#define NV_TYPE_MASK 0x3 /* bits 0-1 */
#define NV_TYPE_DISABLED 1
#define NV_TYPE_VXLAN 3
#define SOCVID_SHIFT 2 /* Strip outer vlan */
#define RCVID_SHIFT 4 /* Report vlan */
u8 nv_flags;
u8 rsvd2;
__le16 nv_port; /* vxlan/gre port */
u32 rsvd3[19];
} __packed;

struct be_pcie_res_desc {
struct be_res_desc_hdr hdr;
u8 rsvd0;
Expand All @@ -1856,6 +1872,8 @@ struct be_pcie_res_desc {
struct be_nic_res_desc {
struct be_res_desc_hdr hdr;
u8 rsvd1;

#define QUN_SHIFT 4 /* QoS is in absolute units */
u8 flags;
u8 vf_num;
u8 rsvd2;
Expand Down Expand Up @@ -1896,16 +1914,6 @@ enum mc_type {
vNIC2 = 0x07
};

struct be_port_res_desc {
struct be_res_desc_hdr hdr;
u8 rsvd0;
u8 flags;
u8 rsvd1;
u8 mc_type;
u16 rsvd2;
u32 rsvd3[20];
} __packed;

/* Is BE in a multi-channel mode */
static inline bool be_is_mc(struct be_adapter *adapter)
{
Expand Down Expand Up @@ -1940,7 +1948,7 @@ struct be_cmd_req_set_profile_config {
struct be_cmd_req_hdr hdr;
u32 rsvd;
u32 desc_count;
struct be_nic_res_desc nic_desc;
u8 desc[RESOURCE_DESC_SIZE_V1];
};

struct be_cmd_resp_set_profile_config {
Expand Down Expand Up @@ -1999,6 +2007,26 @@ struct be_cmd_req_set_ll_link {
u32 link_config; /* Bit 0: UP_DOWN, Bit 9: PLINK */
};

/************** Manage IFACE Filters *******************/
#define OP_CONVERT_NORMAL_TO_TUNNEL 0
#define OP_CONVERT_TUNNEL_TO_NORMAL 1

struct be_cmd_req_manage_iface_filters {
struct be_cmd_req_hdr hdr;
u8 op;
u8 rsvd0;
u8 flags;
u8 rsvd1;
u32 tunnel_iface_id;
u32 target_iface_id;
u8 mac[6];
u16 vlan_tag;
u32 tenant_id;
u32 filter_id;
u32 cap_flags;
u32 cap_control_flags;
} __packed;

int be_pci_fnum_get(struct be_adapter *adapter);
int be_fw_wait_ready(struct be_adapter *adapter);
int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
Expand Down Expand Up @@ -2073,7 +2101,7 @@ int be_cmd_get_seeprom_data(struct be_adapter *adapter,
int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num,
u8 loopback_type, u8 enable);
int be_cmd_get_phy_info(struct be_adapter *adapter);
int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain);
int be_cmd_config_qos(struct be_adapter *adapter, u32 bps, u8 domain);
void be_detect_error(struct be_adapter *adapter);
int be_cmd_get_die_temperature(struct be_adapter *adapter);
int be_cmd_get_cntl_attributes(struct be_adapter *adapter);
Expand Down Expand Up @@ -2114,11 +2142,14 @@ int be_cmd_get_func_config(struct be_adapter *adapter,
struct be_resources *res);
int be_cmd_get_profile_config(struct be_adapter *adapter,
struct be_resources *res, u8 domain);
int be_cmd_set_profile_config(struct be_adapter *adapter, u32 bps, u8 domain);
int be_cmd_set_profile_config(struct be_adapter *adapter, void *desc,
int size, u8 version, u8 domain);
int be_cmd_get_active_profile(struct be_adapter *adapter, u16 *profile);
int be_cmd_get_if_id(struct be_adapter *adapter, struct be_vf_cfg *vf_cfg,
int vf_num);
int be_cmd_enable_vf(struct be_adapter *adapter, u8 domain);
int be_cmd_intr_set(struct be_adapter *adapter, bool intr_enable);
int be_cmd_set_logical_link_config(struct be_adapter *adapter,
int link_state, u8 domain);
int be_cmd_set_vxlan_port(struct be_adapter *adapter, __be16 port);
int be_cmd_manage_iface(struct be_adapter *adapter, u32 iface, u8 op);
8 changes: 2 additions & 6 deletions drivers/net/ethernet/emulex/benet/be_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1346,11 +1346,7 @@ static int be_set_vf_tx_rate(struct net_device *netdev,
return -EINVAL;
}

if (lancer_chip(adapter))
status = be_cmd_set_profile_config(adapter, rate / 10, vf + 1);
else
status = be_cmd_set_qos(adapter, rate / 10, vf + 1);

status = be_cmd_config_qos(adapter, rate / 10, vf + 1);
if (status)
dev_err(&adapter->pdev->dev,
"tx rate %d on VF %d failed\n", rate, vf);
Expand Down Expand Up @@ -3124,7 +3120,7 @@ static int be_vf_setup(struct be_adapter *adapter)
* Allow full available bandwidth
*/
if (BE3_chip(adapter) && !old_vfs)
be_cmd_set_qos(adapter, 1000, vf+1);
be_cmd_config_qos(adapter, 1000, vf + 1);

status = be_cmd_link_status_query(adapter, &lnk_speed,
NULL, vf + 1);
Expand Down

0 comments on commit a401801

Please sign in to comment.