Skip to content

Commit d76a60b

Browse files
refactormanJeff Kirsher
authored andcommitted
ice: Add support for VLANs and offloads
This patch adds support for VLANs. When a VLAN is created a switch filter is added to direct the VLAN traffic to the corresponding VSI. When a VLAN is deleted, the filter is deleted as well. This patch also adds support for the following hardware offloads. 1) VLAN tag insertion/stripping 2) Receive Side Scaling (RSS) 3) Tx checksum and TCP segmentation 4) Rx checksum Signed-off-by: Anirudh Venkataramanan <[email protected]> Tested-by: Tony Brelinski <[email protected]> Signed-off-by: Jeff Kirsher <[email protected]>
1 parent 2b245cb commit d76a60b

File tree

10 files changed

+1631
-16
lines changed

10 files changed

+1631
-16
lines changed

drivers/net/ethernet/intel/ice/ice.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@
2323
#include <linux/delay.h>
2424
#include <linux/bitmap.h>
2525
#include <linux/log2.h>
26+
#include <linux/ip.h>
27+
#include <linux/ipv6.h>
2628
#include <linux/if_bridge.h>
29+
#include <net/ipv6.h>
2730
#include "ice_devids.h"
2831
#include "ice_type.h"
2932
#include "ice_txrx.h"
@@ -47,6 +50,8 @@
4750
#define ICE_MAX_SCATTER_RXQS 16
4851
#define ICE_Q_WAIT_RETRY_LIMIT 10
4952
#define ICE_Q_WAIT_MAX_RETRY (5 * ICE_Q_WAIT_RETRY_LIMIT)
53+
#define ICE_MAX_LG_RSS_QS 256
54+
#define ICE_MAX_SMALL_RSS_QS 8
5055
#define ICE_RES_VALID_BIT 0x8000
5156
#define ICE_RES_MISC_VEC_ID (ICE_RES_VALID_BIT - 1)
5257
#define ICE_INVAL_Q_INDEX 0xffff
@@ -62,6 +67,7 @@
6267

6368
#define ICE_TX_DESC(R, i) (&(((struct ice_tx_desc *)((R)->desc))[i]))
6469
#define ICE_RX_DESC(R, i) (&(((union ice_32b_rx_flex_desc *)((R)->desc))[i]))
70+
#define ICE_TX_CTX_DESC(R, i) (&(((struct ice_tx_ctx_desc *)((R)->desc))[i]))
6571

6672
#define ice_for_each_txq(vsi, i) \
6773
for ((i) = 0; (i) < (vsi)->num_txq; (i)++)
@@ -113,6 +119,7 @@ struct ice_vsi {
113119
irqreturn_t (*irq_handler)(int irq, void *data);
114120

115121
DECLARE_BITMAP(state, __ICE_STATE_NBITS);
122+
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
116123
int num_q_vectors;
117124
int base_vector;
118125
enum ice_vsi_type type;
@@ -122,6 +129,13 @@ struct ice_vsi {
122129
/* Interrupt thresholds */
123130
u16 work_lmt;
124131

132+
/* RSS config */
133+
u16 rss_table_size; /* HW RSS table size */
134+
u16 rss_size; /* Allocated RSS queues */
135+
u8 *rss_hkey_user; /* User configured hash keys */
136+
u8 *rss_lut_user; /* User configured lookup table entries */
137+
u8 rss_lut_type; /* used to configure Get/Set RSS LUT AQ call */
138+
125139
u16 max_frame;
126140
u16 rx_buf_len;
127141

@@ -181,6 +195,7 @@ struct ice_pf {
181195
struct mutex avail_q_mutex; /* protects access to avail_[rx|tx]qs */
182196
struct mutex sw_mutex; /* lock for protecting VSI alloc flow */
183197
u32 msg_enable;
198+
u32 hw_csum_rx_error;
184199
u32 oicr_idx; /* Other interrupt cause vector index */
185200
u32 num_lan_msix; /* Total MSIX vectors for base driver */
186201
u32 num_avail_msix; /* remaining MSIX vectors left unclaimed */
@@ -224,4 +239,8 @@ static inline void ice_irq_dynamic_ena(struct ice_hw *hw, struct ice_vsi *vsi,
224239
wr32(hw, GLINT_DYN_CTL(vector), val);
225240
}
226241

242+
int ice_set_rss(struct ice_vsi *vsi, u8 *seed, u8 *lut, u16 lut_size);
243+
int ice_get_rss(struct ice_vsi *vsi, u8 *seed, u8 *lut, u16 lut_size);
244+
void ice_fill_rss_lut(u8 *lut, u16 rss_table_size, u16 rss_size);
245+
227246
#endif /* _ICE_H_ */

drivers/net/ethernet/intel/ice/ice_adminq_cmd.h

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -968,6 +968,60 @@ struct ice_aqc_nvm {
968968
__le32 addr_low;
969969
};
970970

971+
/* Get/Set RSS key (indirect 0x0B04/0x0B02) */
972+
struct ice_aqc_get_set_rss_key {
973+
#define ICE_AQC_GSET_RSS_KEY_VSI_VALID BIT(15)
974+
#define ICE_AQC_GSET_RSS_KEY_VSI_ID_S 0
975+
#define ICE_AQC_GSET_RSS_KEY_VSI_ID_M (0x3FF << ICE_AQC_GSET_RSS_KEY_VSI_ID_S)
976+
__le16 vsi_id;
977+
u8 reserved[6];
978+
__le32 addr_high;
979+
__le32 addr_low;
980+
};
981+
982+
#define ICE_AQC_GET_SET_RSS_KEY_DATA_RSS_KEY_SIZE 0x28
983+
#define ICE_AQC_GET_SET_RSS_KEY_DATA_HASH_KEY_SIZE 0xC
984+
985+
struct ice_aqc_get_set_rss_keys {
986+
u8 standard_rss_key[ICE_AQC_GET_SET_RSS_KEY_DATA_RSS_KEY_SIZE];
987+
u8 extended_hash_key[ICE_AQC_GET_SET_RSS_KEY_DATA_HASH_KEY_SIZE];
988+
};
989+
990+
/* Get/Set RSS LUT (indirect 0x0B05/0x0B03) */
991+
struct ice_aqc_get_set_rss_lut {
992+
#define ICE_AQC_GSET_RSS_LUT_VSI_VALID BIT(15)
993+
#define ICE_AQC_GSET_RSS_LUT_VSI_ID_S 0
994+
#define ICE_AQC_GSET_RSS_LUT_VSI_ID_M (0x1FF << ICE_AQC_GSET_RSS_LUT_VSI_ID_S)
995+
__le16 vsi_id;
996+
#define ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_S 0
997+
#define ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_M \
998+
(0x3 << ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_S)
999+
1000+
#define ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_VSI 0
1001+
#define ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_PF 1
1002+
#define ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_GLOBAL 2
1003+
1004+
#define ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_S 2
1005+
#define ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_M \
1006+
(0x3 << ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_S)
1007+
1008+
#define ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_128 128
1009+
#define ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_128_FLAG 0
1010+
#define ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_512 512
1011+
#define ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_512_FLAG 1
1012+
#define ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_2K 2048
1013+
#define ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_2K_FLAG 2
1014+
1015+
#define ICE_AQC_GSET_RSS_LUT_GLOBAL_IDX_S 4
1016+
#define ICE_AQC_GSET_RSS_LUT_GLOBAL_IDX_M \
1017+
(0xF << ICE_AQC_GSET_RSS_LUT_GLOBAL_IDX_S)
1018+
1019+
__le16 flags;
1020+
__le32 reserved;
1021+
__le32 addr_high;
1022+
__le32 addr_low;
1023+
};
1024+
9711025
/* Add TX LAN Queues (indirect 0x0C30) */
9721026
struct ice_aqc_add_txqs {
9731027
u8 num_qgrps;
@@ -1089,6 +1143,8 @@ struct ice_aq_desc {
10891143
struct ice_aqc_query_txsched_res query_sched_res;
10901144
struct ice_aqc_add_move_delete_elem add_move_delete_elem;
10911145
struct ice_aqc_nvm nvm;
1146+
struct ice_aqc_get_set_rss_lut get_set_rss_lut;
1147+
struct ice_aqc_get_set_rss_key get_set_rss_key;
10921148
struct ice_aqc_add_txqs add_txqs;
10931149
struct ice_aqc_dis_txqs dis_txqs;
10941150
struct ice_aqc_add_get_update_free_vsi vsi_cmd;
@@ -1171,6 +1227,12 @@ enum ice_adminq_opc {
11711227
/* NVM commands */
11721228
ice_aqc_opc_nvm_read = 0x0701,
11731229

1230+
/* RSS commands */
1231+
ice_aqc_opc_set_rss_key = 0x0B02,
1232+
ice_aqc_opc_set_rss_lut = 0x0B03,
1233+
ice_aqc_opc_get_rss_key = 0x0B04,
1234+
ice_aqc_opc_get_rss_lut = 0x0B05,
1235+
11741236
/* TX queue handling commands/events */
11751237
ice_aqc_opc_add_txqs = 0x0C30,
11761238
ice_aqc_opc_dis_txqs = 0x0C31,

drivers/net/ethernet/intel/ice/ice_common.c

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1261,6 +1261,194 @@ void ice_clear_pxe_mode(struct ice_hw *hw)
12611261
ice_aq_clear_pxe_mode(hw);
12621262
}
12631263

1264+
/**
1265+
* __ice_aq_get_set_rss_lut
1266+
* @hw: pointer to the hardware structure
1267+
* @vsi_id: VSI FW index
1268+
* @lut_type: LUT table type
1269+
* @lut: pointer to the LUT buffer provided by the caller
1270+
* @lut_size: size of the LUT buffer
1271+
* @glob_lut_idx: global LUT index
1272+
* @set: set true to set the table, false to get the table
1273+
*
1274+
* Internal function to get (0x0B05) or set (0x0B03) RSS look up table
1275+
*/
1276+
static enum ice_status
1277+
__ice_aq_get_set_rss_lut(struct ice_hw *hw, u16 vsi_id, u8 lut_type, u8 *lut,
1278+
u16 lut_size, u8 glob_lut_idx, bool set)
1279+
{
1280+
struct ice_aqc_get_set_rss_lut *cmd_resp;
1281+
struct ice_aq_desc desc;
1282+
enum ice_status status;
1283+
u16 flags = 0;
1284+
1285+
cmd_resp = &desc.params.get_set_rss_lut;
1286+
1287+
if (set) {
1288+
ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_rss_lut);
1289+
desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
1290+
} else {
1291+
ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_rss_lut);
1292+
}
1293+
1294+
cmd_resp->vsi_id = cpu_to_le16(((vsi_id <<
1295+
ICE_AQC_GSET_RSS_LUT_VSI_ID_S) &
1296+
ICE_AQC_GSET_RSS_LUT_VSI_ID_M) |
1297+
ICE_AQC_GSET_RSS_LUT_VSI_VALID);
1298+
1299+
switch (lut_type) {
1300+
case ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_VSI:
1301+
case ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_PF:
1302+
case ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_GLOBAL:
1303+
flags |= ((lut_type << ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_S) &
1304+
ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_M);
1305+
break;
1306+
default:
1307+
status = ICE_ERR_PARAM;
1308+
goto ice_aq_get_set_rss_lut_exit;
1309+
}
1310+
1311+
if (lut_type == ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_GLOBAL) {
1312+
flags |= ((glob_lut_idx << ICE_AQC_GSET_RSS_LUT_GLOBAL_IDX_S) &
1313+
ICE_AQC_GSET_RSS_LUT_GLOBAL_IDX_M);
1314+
1315+
if (!set)
1316+
goto ice_aq_get_set_rss_lut_send;
1317+
} else if (lut_type == ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_PF) {
1318+
if (!set)
1319+
goto ice_aq_get_set_rss_lut_send;
1320+
} else {
1321+
goto ice_aq_get_set_rss_lut_send;
1322+
}
1323+
1324+
/* LUT size is only valid for Global and PF table types */
1325+
if (lut_size == ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_128) {
1326+
flags |= (ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_128_FLAG <<
1327+
ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_S) &
1328+
ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_M;
1329+
} else if (lut_size == ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_512) {
1330+
flags |= (ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_512_FLAG <<
1331+
ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_S) &
1332+
ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_M;
1333+
} else if ((lut_size == ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_2K) &&
1334+
(lut_type == ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_PF)) {
1335+
flags |= (ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_2K_FLAG <<
1336+
ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_S) &
1337+
ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_M;
1338+
} else {
1339+
status = ICE_ERR_PARAM;
1340+
goto ice_aq_get_set_rss_lut_exit;
1341+
}
1342+
1343+
ice_aq_get_set_rss_lut_send:
1344+
cmd_resp->flags = cpu_to_le16(flags);
1345+
status = ice_aq_send_cmd(hw, &desc, lut, lut_size, NULL);
1346+
1347+
ice_aq_get_set_rss_lut_exit:
1348+
return status;
1349+
}
1350+
1351+
/**
1352+
* ice_aq_get_rss_lut
1353+
* @hw: pointer to the hardware structure
1354+
* @vsi_id: VSI FW index
1355+
* @lut_type: LUT table type
1356+
* @lut: pointer to the LUT buffer provided by the caller
1357+
* @lut_size: size of the LUT buffer
1358+
*
1359+
* get the RSS lookup table, PF or VSI type
1360+
*/
1361+
enum ice_status
1362+
ice_aq_get_rss_lut(struct ice_hw *hw, u16 vsi_id, u8 lut_type, u8 *lut,
1363+
u16 lut_size)
1364+
{
1365+
return __ice_aq_get_set_rss_lut(hw, vsi_id, lut_type, lut, lut_size, 0,
1366+
false);
1367+
}
1368+
1369+
/**
1370+
* ice_aq_set_rss_lut
1371+
* @hw: pointer to the hardware structure
1372+
* @vsi_id: VSI FW index
1373+
* @lut_type: LUT table type
1374+
* @lut: pointer to the LUT buffer provided by the caller
1375+
* @lut_size: size of the LUT buffer
1376+
*
1377+
* set the RSS lookup table, PF or VSI type
1378+
*/
1379+
enum ice_status
1380+
ice_aq_set_rss_lut(struct ice_hw *hw, u16 vsi_id, u8 lut_type, u8 *lut,
1381+
u16 lut_size)
1382+
{
1383+
return __ice_aq_get_set_rss_lut(hw, vsi_id, lut_type, lut, lut_size, 0,
1384+
true);
1385+
}
1386+
1387+
/**
1388+
* __ice_aq_get_set_rss_key
1389+
* @hw: pointer to the hw struct
1390+
* @vsi_id: VSI FW index
1391+
* @key: pointer to key info struct
1392+
* @set: set true to set the key, false to get the key
1393+
*
1394+
* get (0x0B04) or set (0x0B02) the RSS key per VSI
1395+
*/
1396+
static enum
1397+
ice_status __ice_aq_get_set_rss_key(struct ice_hw *hw, u16 vsi_id,
1398+
struct ice_aqc_get_set_rss_keys *key,
1399+
bool set)
1400+
{
1401+
struct ice_aqc_get_set_rss_key *cmd_resp;
1402+
u16 key_size = sizeof(*key);
1403+
struct ice_aq_desc desc;
1404+
1405+
cmd_resp = &desc.params.get_set_rss_key;
1406+
1407+
if (set) {
1408+
ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_rss_key);
1409+
desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
1410+
} else {
1411+
ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_rss_key);
1412+
}
1413+
1414+
cmd_resp->vsi_id = cpu_to_le16(((vsi_id <<
1415+
ICE_AQC_GSET_RSS_KEY_VSI_ID_S) &
1416+
ICE_AQC_GSET_RSS_KEY_VSI_ID_M) |
1417+
ICE_AQC_GSET_RSS_KEY_VSI_VALID);
1418+
1419+
return ice_aq_send_cmd(hw, &desc, key, key_size, NULL);
1420+
}
1421+
1422+
/**
1423+
* ice_aq_get_rss_key
1424+
* @hw: pointer to the hw struct
1425+
* @vsi_id: VSI FW index
1426+
* @key: pointer to key info struct
1427+
*
1428+
* get the RSS key per VSI
1429+
*/
1430+
enum ice_status
1431+
ice_aq_get_rss_key(struct ice_hw *hw, u16 vsi_id,
1432+
struct ice_aqc_get_set_rss_keys *key)
1433+
{
1434+
return __ice_aq_get_set_rss_key(hw, vsi_id, key, false);
1435+
}
1436+
1437+
/**
1438+
* ice_aq_set_rss_key
1439+
* @hw: pointer to the hw struct
1440+
* @vsi_id: VSI FW index
1441+
* @keys: pointer to key info struct
1442+
*
1443+
* set the RSS key per VSI
1444+
*/
1445+
enum ice_status
1446+
ice_aq_set_rss_key(struct ice_hw *hw, u16 vsi_id,
1447+
struct ice_aqc_get_set_rss_keys *keys)
1448+
{
1449+
return __ice_aq_get_set_rss_key(hw, vsi_id, keys, true);
1450+
}
1451+
12641452
/**
12651453
* ice_aq_add_lan_txq
12661454
* @hw: pointer to the hardware structure

drivers/net/ethernet/intel/ice/ice_common.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,19 @@ enum ice_status ice_get_caps(struct ice_hw *hw);
3333
enum ice_status
3434
ice_write_rxq_ctx(struct ice_hw *hw, struct ice_rlan_ctx *rlan_ctx,
3535
u32 rxq_index);
36+
37+
enum ice_status
38+
ice_aq_get_rss_lut(struct ice_hw *hw, u16 vsi_id, u8 lut_type, u8 *lut,
39+
u16 lut_size);
40+
enum ice_status
41+
ice_aq_set_rss_lut(struct ice_hw *hw, u16 vsi_id, u8 lut_type, u8 *lut,
42+
u16 lut_size);
43+
enum ice_status
44+
ice_aq_get_rss_key(struct ice_hw *hw, u16 vsi_id,
45+
struct ice_aqc_get_set_rss_keys *keys);
46+
enum ice_status
47+
ice_aq_set_rss_key(struct ice_hw *hw, u16 vsi_id,
48+
struct ice_aqc_get_set_rss_keys *keys);
3649
bool ice_check_sq_alive(struct ice_hw *hw, struct ice_ctl_q_info *cq);
3750
enum ice_status ice_aq_q_shutdown(struct ice_hw *hw, bool unloading);
3851
void ice_fill_dflt_direct_cmd_desc(struct ice_aq_desc *desc, u16 opcode);

0 commit comments

Comments
 (0)