Skip to content

Commit

Permalink
Merge branch 'qed-arfs'
Browse files Browse the repository at this point in the history
Manish Chopra says:

====================
qed/qede: aRFS support

This series adds support for Accelerated Flow Steering
in qede driver for TCP/UDP over IPv4/IPv6 protocols.

Please consider applying this series to "net-next"
====================

Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
davem330 committed Apr 17, 2017
2 parents 53a759c + e4917d4 commit 7ca9511
Show file tree
Hide file tree
Showing 14 changed files with 1,027 additions and 8 deletions.
2 changes: 2 additions & 0 deletions drivers/net/ethernet/qlogic/qed/qed.h
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,8 @@ struct qed_hwfn {
u8 dcbx_no_edpm;
u8 db_bar_no_edpm;

struct qed_ptt *p_arfs_ptt;

/* p_ptp_ptt is valid for leading HWFN only */
struct qed_ptt *p_ptp_ptt;
struct qed_simd_fp_handler simd_proto_handler[64];
Expand Down
13 changes: 10 additions & 3 deletions drivers/net/ethernet/qlogic/qed/qed_cxt.c
Original file line number Diff line number Diff line change
Expand Up @@ -219,9 +219,6 @@ struct qed_cxt_mngr {
*/
u32 vf_count;

/* total number of SRQ's for this hwfn */
u32 srq_count;

/* Acquired CIDs */
struct qed_cid_acquired_map acquired[MAX_CONN_TYPES];

Expand All @@ -237,6 +234,12 @@ struct qed_cxt_mngr {
u32 t2_num_pages;
u64 first_free;
u64 last_free;

/* total number of SRQ's for this hwfn */
u32 srq_count;

/* Maximal number of L2 steering filters */
u32 arfs_count;
};
static bool src_proto(enum protocol_type type)
{
Expand Down Expand Up @@ -291,6 +294,9 @@ static void qed_cxt_src_iids(struct qed_cxt_mngr *p_mngr,
iids->pf_cids += p_mngr->conn_cfg[i].cid_count;
iids->per_vf_cids += p_mngr->conn_cfg[i].cids_per_vf;
}

/* Add L2 filtering filters in addition */
iids->pf_cids += p_mngr->arfs_count;
}

/* counts the iids for the Timers block configuration */
Expand Down Expand Up @@ -2007,6 +2013,7 @@ int qed_cxt_set_pf_params(struct qed_hwfn *p_hwfn, u32 rdma_tasks)

qed_cxt_set_proto_cid_count(p_hwfn, PROTOCOLID_ETH,
p_params->num_cons, 1);
p_hwfn->p_cxt_mngr->arfs_count = p_params->num_arfs_filters;
break;
}
case QED_PCI_FCOE:
Expand Down
187 changes: 187 additions & 0 deletions drivers/net/ethernet/qlogic/qed/qed_hsi.h
Original file line number Diff line number Diff line change
Expand Up @@ -3473,6 +3473,11 @@ void qed_set_geneve_dest_port(struct qed_hwfn *p_hwfn,
void qed_set_geneve_enable(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt,
bool eth_geneve_enable, bool ip_geneve_enable);
void qed_set_rfs_mode_disable(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt, u16 pf_id);
void qed_set_rfs_mode_enable(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
u16 pf_id, bool tcp, bool udp,
bool ipv4, bool ipv6);

#define YSTORM_FLOW_CONTROL_MODE_OFFSET (IRO[0].base)
#define YSTORM_FLOW_CONTROL_MODE_SIZE (IRO[0].size)
Expand Down Expand Up @@ -4862,6 +4867,18 @@ struct eth_vport_tx_mode {
__le16 reserved2[3];
};

enum gft_filter_update_action {
GFT_ADD_FILTER,
GFT_DELETE_FILTER,
MAX_GFT_FILTER_UPDATE_ACTION
};

enum gft_logic_filter_type {
GFT_FILTER_TYPE,
RFS_FILTER_TYPE,
MAX_GFT_LOGIC_FILTER_TYPE
};

/* Ramrod data for rx queue start ramrod */
struct rx_queue_start_ramrod_data {
__le16 rx_queue_id;
Expand Down Expand Up @@ -4932,6 +4949,16 @@ struct rx_udp_filter_data {
__le32 tenant_id;
};

struct rx_update_gft_filter_data {
struct regpair pkt_hdr_addr;
__le16 pkt_hdr_length;
__le16 rx_qid_or_action_icid;
u8 vport_id;
u8 filter_type;
u8 filter_action;
u8 reserved;
};

/* Ramrod data for rx queue start ramrod */
struct tx_queue_start_ramrod_data {
__le16 sb_id;
Expand Down Expand Up @@ -5075,6 +5102,166 @@ struct vport_update_ramrod_data {
struct eth_vport_rss_config rss_config;
};

struct gft_cam_line {
__le32 camline;
#define GFT_CAM_LINE_VALID_MASK 0x1
#define GFT_CAM_LINE_VALID_SHIFT 0
#define GFT_CAM_LINE_DATA_MASK 0x3FFF
#define GFT_CAM_LINE_DATA_SHIFT 1
#define GFT_CAM_LINE_MASK_BITS_MASK 0x3FFF
#define GFT_CAM_LINE_MASK_BITS_SHIFT 15
#define GFT_CAM_LINE_RESERVED1_MASK 0x7
#define GFT_CAM_LINE_RESERVED1_SHIFT 29
};

struct gft_cam_line_mapped {
__le32 camline;
#define GFT_CAM_LINE_MAPPED_VALID_MASK 0x1
#define GFT_CAM_LINE_MAPPED_VALID_SHIFT 0
#define GFT_CAM_LINE_MAPPED_IP_VERSION_MASK 0x1
#define GFT_CAM_LINE_MAPPED_IP_VERSION_SHIFT 1
#define GFT_CAM_LINE_MAPPED_TUNNEL_IP_VERSION_MASK 0x1
#define GFT_CAM_LINE_MAPPED_TUNNEL_IP_VERSION_SHIFT 2
#define GFT_CAM_LINE_MAPPED_UPPER_PROTOCOL_TYPE_MASK 0xF
#define GFT_CAM_LINE_MAPPED_UPPER_PROTOCOL_TYPE_SHIFT 3
#define GFT_CAM_LINE_MAPPED_TUNNEL_TYPE_MASK 0xF
#define GFT_CAM_LINE_MAPPED_TUNNEL_TYPE_SHIFT 7
#define GFT_CAM_LINE_MAPPED_PF_ID_MASK 0xF
#define GFT_CAM_LINE_MAPPED_PF_ID_SHIFT 11
#define GFT_CAM_LINE_MAPPED_IP_VERSION_MASK_MASK 0x1
#define GFT_CAM_LINE_MAPPED_IP_VERSION_MASK_SHIFT 15
#define GFT_CAM_LINE_MAPPED_TUNNEL_IP_VERSION_MASK_MASK 0x1
#define GFT_CAM_LINE_MAPPED_TUNNEL_IP_VERSION_MASK_SHIFT 16
#define GFT_CAM_LINE_MAPPED_UPPER_PROTOCOL_TYPE_MASK_MASK 0xF
#define GFT_CAM_LINE_MAPPED_UPPER_PROTOCOL_TYPE_MASK_SHIFT 17
#define GFT_CAM_LINE_MAPPED_TUNNEL_TYPE_MASK_MASK 0xF
#define GFT_CAM_LINE_MAPPED_TUNNEL_TYPE_MASK_SHIFT 21
#define GFT_CAM_LINE_MAPPED_PF_ID_MASK_MASK 0xF
#define GFT_CAM_LINE_MAPPED_PF_ID_MASK_SHIFT 25
#define GFT_CAM_LINE_MAPPED_RESERVED1_MASK 0x7
#define GFT_CAM_LINE_MAPPED_RESERVED1_SHIFT 29
};

union gft_cam_line_union {
struct gft_cam_line cam_line;
struct gft_cam_line_mapped cam_line_mapped;
};

enum gft_profile_ip_version {
GFT_PROFILE_IPV4 = 0,
GFT_PROFILE_IPV6 = 1,
MAX_GFT_PROFILE_IP_VERSION
};

enum gft_profile_upper_protocol_type {
GFT_PROFILE_ROCE_PROTOCOL = 0,
GFT_PROFILE_RROCE_PROTOCOL = 1,
GFT_PROFILE_FCOE_PROTOCOL = 2,
GFT_PROFILE_ICMP_PROTOCOL = 3,
GFT_PROFILE_ARP_PROTOCOL = 4,
GFT_PROFILE_USER_TCP_SRC_PORT_1_INNER = 5,
GFT_PROFILE_USER_TCP_DST_PORT_1_INNER = 6,
GFT_PROFILE_TCP_PROTOCOL = 7,
GFT_PROFILE_USER_UDP_DST_PORT_1_INNER = 8,
GFT_PROFILE_USER_UDP_DST_PORT_2_OUTER = 9,
GFT_PROFILE_UDP_PROTOCOL = 10,
GFT_PROFILE_USER_IP_1_INNER = 11,
GFT_PROFILE_USER_IP_2_OUTER = 12,
GFT_PROFILE_USER_ETH_1_INNER = 13,
GFT_PROFILE_USER_ETH_2_OUTER = 14,
GFT_PROFILE_RAW = 15,
MAX_GFT_PROFILE_UPPER_PROTOCOL_TYPE
};

struct gft_ram_line {
__le32 low32bits;
#define GFT_RAM_LINE_VLAN_SELECT_MASK 0x3
#define GFT_RAM_LINE_VLAN_SELECT_SHIFT 0
#define GFT_RAM_LINE_TUNNEL_ENTROPHY_MASK 0x1
#define GFT_RAM_LINE_TUNNEL_ENTROPHY_SHIFT 2
#define GFT_RAM_LINE_TUNNEL_TTL_EQUAL_ONE_MASK 0x1
#define GFT_RAM_LINE_TUNNEL_TTL_EQUAL_ONE_SHIFT 3
#define GFT_RAM_LINE_TUNNEL_TTL_MASK 0x1
#define GFT_RAM_LINE_TUNNEL_TTL_SHIFT 4
#define GFT_RAM_LINE_TUNNEL_ETHERTYPE_MASK 0x1
#define GFT_RAM_LINE_TUNNEL_ETHERTYPE_SHIFT 5
#define GFT_RAM_LINE_TUNNEL_DST_PORT_MASK 0x1
#define GFT_RAM_LINE_TUNNEL_DST_PORT_SHIFT 6
#define GFT_RAM_LINE_TUNNEL_SRC_PORT_MASK 0x1
#define GFT_RAM_LINE_TUNNEL_SRC_PORT_SHIFT 7
#define GFT_RAM_LINE_TUNNEL_DSCP_MASK 0x1
#define GFT_RAM_LINE_TUNNEL_DSCP_SHIFT 8
#define GFT_RAM_LINE_TUNNEL_OVER_IP_PROTOCOL_MASK 0x1
#define GFT_RAM_LINE_TUNNEL_OVER_IP_PROTOCOL_SHIFT 9
#define GFT_RAM_LINE_TUNNEL_DST_IP_MASK 0x1
#define GFT_RAM_LINE_TUNNEL_DST_IP_SHIFT 10
#define GFT_RAM_LINE_TUNNEL_SRC_IP_MASK 0x1
#define GFT_RAM_LINE_TUNNEL_SRC_IP_SHIFT 11
#define GFT_RAM_LINE_TUNNEL_PRIORITY_MASK 0x1
#define GFT_RAM_LINE_TUNNEL_PRIORITY_SHIFT 12
#define GFT_RAM_LINE_TUNNEL_PROVIDER_VLAN_MASK 0x1
#define GFT_RAM_LINE_TUNNEL_PROVIDER_VLAN_SHIFT 13
#define GFT_RAM_LINE_TUNNEL_VLAN_MASK 0x1
#define GFT_RAM_LINE_TUNNEL_VLAN_SHIFT 14
#define GFT_RAM_LINE_TUNNEL_DST_MAC_MASK 0x1
#define GFT_RAM_LINE_TUNNEL_DST_MAC_SHIFT 15
#define GFT_RAM_LINE_TUNNEL_SRC_MAC_MASK 0x1
#define GFT_RAM_LINE_TUNNEL_SRC_MAC_SHIFT 16
#define GFT_RAM_LINE_TTL_EQUAL_ONE_MASK 0x1
#define GFT_RAM_LINE_TTL_EQUAL_ONE_SHIFT 17
#define GFT_RAM_LINE_TTL_MASK 0x1
#define GFT_RAM_LINE_TTL_SHIFT 18
#define GFT_RAM_LINE_ETHERTYPE_MASK 0x1
#define GFT_RAM_LINE_ETHERTYPE_SHIFT 19
#define GFT_RAM_LINE_RESERVED0_MASK 0x1
#define GFT_RAM_LINE_RESERVED0_SHIFT 20
#define GFT_RAM_LINE_TCP_FLAG_FIN_MASK 0x1
#define GFT_RAM_LINE_TCP_FLAG_FIN_SHIFT 21
#define GFT_RAM_LINE_TCP_FLAG_SYN_MASK 0x1
#define GFT_RAM_LINE_TCP_FLAG_SYN_SHIFT 22
#define GFT_RAM_LINE_TCP_FLAG_RST_MASK 0x1
#define GFT_RAM_LINE_TCP_FLAG_RST_SHIFT 23
#define GFT_RAM_LINE_TCP_FLAG_PSH_MASK 0x1
#define GFT_RAM_LINE_TCP_FLAG_PSH_SHIFT 24
#define GFT_RAM_LINE_TCP_FLAG_ACK_MASK 0x1
#define GFT_RAM_LINE_TCP_FLAG_ACK_SHIFT 25
#define GFT_RAM_LINE_TCP_FLAG_URG_MASK 0x1
#define GFT_RAM_LINE_TCP_FLAG_URG_SHIFT 26
#define GFT_RAM_LINE_TCP_FLAG_ECE_MASK 0x1
#define GFT_RAM_LINE_TCP_FLAG_ECE_SHIFT 27
#define GFT_RAM_LINE_TCP_FLAG_CWR_MASK 0x1
#define GFT_RAM_LINE_TCP_FLAG_CWR_SHIFT 28
#define GFT_RAM_LINE_TCP_FLAG_NS_MASK 0x1
#define GFT_RAM_LINE_TCP_FLAG_NS_SHIFT 29
#define GFT_RAM_LINE_DST_PORT_MASK 0x1
#define GFT_RAM_LINE_DST_PORT_SHIFT 30
#define GFT_RAM_LINE_SRC_PORT_MASK 0x1
#define GFT_RAM_LINE_SRC_PORT_SHIFT 31
__le32 high32bits;
#define GFT_RAM_LINE_DSCP_MASK 0x1
#define GFT_RAM_LINE_DSCP_SHIFT 0
#define GFT_RAM_LINE_OVER_IP_PROTOCOL_MASK 0x1
#define GFT_RAM_LINE_OVER_IP_PROTOCOL_SHIFT 1
#define GFT_RAM_LINE_DST_IP_MASK 0x1
#define GFT_RAM_LINE_DST_IP_SHIFT 2
#define GFT_RAM_LINE_SRC_IP_MASK 0x1
#define GFT_RAM_LINE_SRC_IP_SHIFT 3
#define GFT_RAM_LINE_PRIORITY_MASK 0x1
#define GFT_RAM_LINE_PRIORITY_SHIFT 4
#define GFT_RAM_LINE_PROVIDER_VLAN_MASK 0x1
#define GFT_RAM_LINE_PROVIDER_VLAN_SHIFT 5
#define GFT_RAM_LINE_VLAN_MASK 0x1
#define GFT_RAM_LINE_VLAN_SHIFT 6
#define GFT_RAM_LINE_DST_MAC_MASK 0x1
#define GFT_RAM_LINE_DST_MAC_SHIFT 7
#define GFT_RAM_LINE_SRC_MAC_MASK 0x1
#define GFT_RAM_LINE_SRC_MAC_SHIFT 8
#define GFT_RAM_LINE_TENANT_ID_MASK 0x1
#define GFT_RAM_LINE_TENANT_ID_SHIFT 9
#define GFT_RAM_LINE_RESERVED1_MASK 0x3FFFFF
#define GFT_RAM_LINE_RESERVED1_SHIFT 10
};

struct mstorm_eth_conn_ag_ctx {
u8 byte0;
u8 byte1;
Expand Down
129 changes: 129 additions & 0 deletions drivers/net/ethernet/qlogic/qed/qed_init_fw_funcs.c
Original file line number Diff line number Diff line change
Expand Up @@ -961,3 +961,132 @@ void qed_set_geneve_enable(struct qed_hwfn *p_hwfn,
qed_wr(p_hwfn, p_ptt, DORQ_REG_L2_EDPM_TUNNEL_NGE_IP_EN,
ip_geneve_enable ? 1 : 0);
}

#define T_ETH_PACKET_MATCH_RFS_EVENTID 25
#define PARSER_ETH_CONN_CM_HDR (0x0)
#define CAM_LINE_SIZE sizeof(u32)
#define RAM_LINE_SIZE sizeof(u64)
#define REG_SIZE sizeof(u32)

void qed_set_rfs_mode_disable(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt, u16 pf_id)
{
union gft_cam_line_union camline;
struct gft_ram_line ramline;
u32 *p_ramline, i;

p_ramline = (u32 *)&ramline;

/*stop using gft logic */
qed_wr(p_hwfn, p_ptt, PRS_REG_SEARCH_GFT, 0);
qed_wr(p_hwfn, p_ptt, PRS_REG_CM_HDR_GFT, 0x0);
memset(&camline, 0, sizeof(union gft_cam_line_union));
qed_wr(p_hwfn, p_ptt, PRS_REG_GFT_CAM + CAM_LINE_SIZE * pf_id,
camline.cam_line_mapped.camline);
memset(&ramline, 0, sizeof(union gft_cam_line_union));

for (i = 0; i < RAM_LINE_SIZE / REG_SIZE; i++) {
u32 hw_addr = PRS_REG_GFT_PROFILE_MASK_RAM;

hw_addr += (RAM_LINE_SIZE * pf_id + i * REG_SIZE);

qed_wr(p_hwfn, p_ptt, hw_addr, *(p_ramline + i));
}
}

void qed_set_rfs_mode_enable(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
u16 pf_id, bool tcp, bool udp,
bool ipv4, bool ipv6)
{
u32 rfs_cm_hdr_event_id, *p_ramline;
union gft_cam_line_union camline;
struct gft_ram_line ramline;
int i;

rfs_cm_hdr_event_id = qed_rd(p_hwfn, p_ptt, PRS_REG_CM_HDR_GFT);
p_ramline = (u32 *)&ramline;

if (!ipv6 && !ipv4)
DP_NOTICE(p_hwfn,
"set_rfs_mode_enable: must accept at least on of - ipv4 or ipv6");
if (!tcp && !udp)
DP_NOTICE(p_hwfn,
"set_rfs_mode_enable: must accept at least on of - udp or tcp");

rfs_cm_hdr_event_id |= T_ETH_PACKET_MATCH_RFS_EVENTID <<
PRS_REG_CM_HDR_GFT_EVENT_ID_SHIFT;
rfs_cm_hdr_event_id |= PARSER_ETH_CONN_CM_HDR <<
PRS_REG_CM_HDR_GFT_CM_HDR_SHIFT;
qed_wr(p_hwfn, p_ptt, PRS_REG_CM_HDR_GFT, rfs_cm_hdr_event_id);

/* Configure Registers for RFS mode */
qed_wr(p_hwfn, p_ptt, PRS_REG_SEARCH_GFT, 1);
qed_wr(p_hwfn, p_ptt, PRS_REG_LOAD_L2_FILTER, 0);
camline.cam_line_mapped.camline = 0;

/* cam line is now valid!! */
SET_FIELD(camline.cam_line_mapped.camline,
GFT_CAM_LINE_MAPPED_VALID, 1);

/* filters are per PF!! */
SET_FIELD(camline.cam_line_mapped.camline,
GFT_CAM_LINE_MAPPED_PF_ID_MASK, 1);
SET_FIELD(camline.cam_line_mapped.camline,
GFT_CAM_LINE_MAPPED_PF_ID, pf_id);
if (!(tcp && udp)) {
SET_FIELD(camline.cam_line_mapped.camline,
GFT_CAM_LINE_MAPPED_UPPER_PROTOCOL_TYPE_MASK, 1);
if (tcp)
SET_FIELD(camline.cam_line_mapped.camline,
GFT_CAM_LINE_MAPPED_UPPER_PROTOCOL_TYPE,
GFT_PROFILE_TCP_PROTOCOL);
else
SET_FIELD(camline.cam_line_mapped.camline,
GFT_CAM_LINE_MAPPED_UPPER_PROTOCOL_TYPE,
GFT_PROFILE_UDP_PROTOCOL);
}

if (!(ipv4 && ipv6)) {
SET_FIELD(camline.cam_line_mapped.camline,
GFT_CAM_LINE_MAPPED_IP_VERSION_MASK, 1);
if (ipv4)
SET_FIELD(camline.cam_line_mapped.camline,
GFT_CAM_LINE_MAPPED_IP_VERSION,
GFT_PROFILE_IPV4);
else
SET_FIELD(camline.cam_line_mapped.camline,
GFT_CAM_LINE_MAPPED_IP_VERSION,
GFT_PROFILE_IPV6);
}

/* write characteristics to cam */
qed_wr(p_hwfn, p_ptt, PRS_REG_GFT_CAM + CAM_LINE_SIZE * pf_id,
camline.cam_line_mapped.camline);
camline.cam_line_mapped.camline = qed_rd(p_hwfn, p_ptt,
PRS_REG_GFT_CAM +
CAM_LINE_SIZE * pf_id);

/* write line to RAM - compare to filter 4 tuple */
ramline.low32bits = 0;
ramline.high32bits = 0;
SET_FIELD(ramline.high32bits, GFT_RAM_LINE_DST_IP, 1);
SET_FIELD(ramline.high32bits, GFT_RAM_LINE_SRC_IP, 1);
SET_FIELD(ramline.low32bits, GFT_RAM_LINE_SRC_PORT, 1);
SET_FIELD(ramline.low32bits, GFT_RAM_LINE_DST_PORT, 1);

/* each iteration write to reg */
for (i = 0; i < RAM_LINE_SIZE / REG_SIZE; i++)
qed_wr(p_hwfn, p_ptt,
PRS_REG_GFT_PROFILE_MASK_RAM + RAM_LINE_SIZE * pf_id +
i * REG_SIZE, *(p_ramline + i));

/* set default profile so that no filter match will happen */
ramline.low32bits = 0xffff;
ramline.high32bits = 0xffff;

for (i = 0; i < RAM_LINE_SIZE / REG_SIZE; i++)
qed_wr(p_hwfn, p_ptt,
PRS_REG_GFT_PROFILE_MASK_RAM + RAM_LINE_SIZE *
PRS_GFT_CAM_LINES_NO_MATCH + i * REG_SIZE,
*(p_ramline + i));
}
Loading

0 comments on commit 7ca9511

Please sign in to comment.