@@ -1219,22 +1219,99 @@ int efx_mae_enumerate_mports(struct efx_nic *efx)
12191219 return rc ;
12201220}
12211221
1222+ /**
1223+ * efx_mae_allocate_pedit_mac() - allocate pedit MAC address in HW.
1224+ * @efx: NIC we're installing a pedit MAC address on
1225+ * @ped: pedit MAC action to be installed
1226+ *
1227+ * Attempts to install @ped in HW and populates its id with an index of this
1228+ * entry in the firmware MAC address table on success.
1229+ *
1230+ * Return: negative value on error, 0 in success.
1231+ */
1232+ int efx_mae_allocate_pedit_mac (struct efx_nic * efx ,
1233+ struct efx_tc_mac_pedit_action * ped )
1234+ {
1235+ MCDI_DECLARE_BUF (outbuf , MC_CMD_MAE_MAC_ADDR_ALLOC_OUT_LEN );
1236+ MCDI_DECLARE_BUF (inbuf , MC_CMD_MAE_MAC_ADDR_ALLOC_IN_LEN );
1237+ size_t outlen ;
1238+ int rc ;
1239+
1240+ BUILD_BUG_ON (MC_CMD_MAE_MAC_ADDR_ALLOC_IN_MAC_ADDR_LEN !=
1241+ sizeof (ped -> h_addr ));
1242+ memcpy (MCDI_PTR (inbuf , MAE_MAC_ADDR_ALLOC_IN_MAC_ADDR ), ped -> h_addr ,
1243+ sizeof (ped -> h_addr ));
1244+ rc = efx_mcdi_rpc (efx , MC_CMD_MAE_MAC_ADDR_ALLOC , inbuf , sizeof (inbuf ),
1245+ outbuf , sizeof (outbuf ), & outlen );
1246+ if (rc )
1247+ return rc ;
1248+ if (outlen < sizeof (outbuf ))
1249+ return - EIO ;
1250+ ped -> fw_id = MCDI_DWORD (outbuf , MAE_MAC_ADDR_ALLOC_OUT_MAC_ID );
1251+ return 0 ;
1252+ }
1253+
1254+ /**
1255+ * efx_mae_free_pedit_mac() - free pedit MAC address in HW.
1256+ * @efx: NIC we're installing a pedit MAC address on
1257+ * @ped: pedit MAC action that needs to be freed
1258+ *
1259+ * Frees @ped in HW, check that firmware did not free a different one and clears
1260+ * the id (which denotes the index of the entry in the MAC address table).
1261+ */
1262+ void efx_mae_free_pedit_mac (struct efx_nic * efx ,
1263+ struct efx_tc_mac_pedit_action * ped )
1264+ {
1265+ MCDI_DECLARE_BUF (outbuf , MC_CMD_MAE_MAC_ADDR_FREE_OUT_LEN (1 ));
1266+ MCDI_DECLARE_BUF (inbuf , MC_CMD_MAE_MAC_ADDR_FREE_IN_LEN (1 ));
1267+ size_t outlen ;
1268+ int rc ;
1269+
1270+ MCDI_SET_DWORD (inbuf , MAE_MAC_ADDR_FREE_IN_MAC_ID , ped -> fw_id );
1271+ rc = efx_mcdi_rpc (efx , MC_CMD_MAE_MAC_ADDR_FREE , inbuf ,
1272+ sizeof (inbuf ), outbuf , sizeof (outbuf ), & outlen );
1273+ if (rc || outlen < sizeof (outbuf ))
1274+ return ;
1275+ /* FW freed a different ID than we asked for, should also never happen.
1276+ * Warn because it means we've now got a different idea to the FW of
1277+ * what MAC addresses exist, which could cause mayhem later.
1278+ */
1279+ if (WARN_ON (MCDI_DWORD (outbuf , MAE_MAC_ADDR_FREE_OUT_FREED_MAC_ID ) != ped -> fw_id ))
1280+ return ;
1281+ /* We're probably about to free @ped, but let's just make sure its
1282+ * fw_id is blatted so that it won't look valid if it leaks out.
1283+ */
1284+ ped -> fw_id = MC_CMD_MAE_MAC_ADDR_ALLOC_OUT_MAC_ID_NULL ;
1285+ }
1286+
12221287int efx_mae_alloc_action_set (struct efx_nic * efx , struct efx_tc_action_set * act )
12231288{
12241289 MCDI_DECLARE_BUF (outbuf , MC_CMD_MAE_ACTION_SET_ALLOC_OUT_LEN );
12251290 MCDI_DECLARE_BUF (inbuf , MC_CMD_MAE_ACTION_SET_ALLOC_IN_LEN );
12261291 size_t outlen ;
12271292 int rc ;
12281293
1229- MCDI_POPULATE_DWORD_3 (inbuf , MAE_ACTION_SET_ALLOC_IN_FLAGS ,
1294+ MCDI_POPULATE_DWORD_4 (inbuf , MAE_ACTION_SET_ALLOC_IN_FLAGS ,
12301295 MAE_ACTION_SET_ALLOC_IN_VLAN_PUSH , act -> vlan_push ,
12311296 MAE_ACTION_SET_ALLOC_IN_VLAN_POP , act -> vlan_pop ,
1232- MAE_ACTION_SET_ALLOC_IN_DECAP , act -> decap );
1297+ MAE_ACTION_SET_ALLOC_IN_DECAP , act -> decap ,
1298+ MAE_ACTION_SET_ALLOC_IN_DO_DECR_IP_TTL ,
1299+ act -> do_ttl_dec );
1300+
1301+ if (act -> src_mac )
1302+ MCDI_SET_DWORD (inbuf , MAE_ACTION_SET_ALLOC_IN_SRC_MAC_ID ,
1303+ act -> src_mac -> fw_id );
1304+ else
1305+ MCDI_SET_DWORD (inbuf , MAE_ACTION_SET_ALLOC_IN_SRC_MAC_ID ,
1306+ MC_CMD_MAE_MAC_ADDR_ALLOC_OUT_MAC_ID_NULL );
1307+
1308+ if (act -> dst_mac )
1309+ MCDI_SET_DWORD (inbuf , MAE_ACTION_SET_ALLOC_IN_DST_MAC_ID ,
1310+ act -> dst_mac -> fw_id );
1311+ else
1312+ MCDI_SET_DWORD (inbuf , MAE_ACTION_SET_ALLOC_IN_DST_MAC_ID ,
1313+ MC_CMD_MAE_MAC_ADDR_ALLOC_OUT_MAC_ID_NULL );
12331314
1234- MCDI_SET_DWORD (inbuf , MAE_ACTION_SET_ALLOC_IN_SRC_MAC_ID ,
1235- MC_CMD_MAE_MAC_ADDR_ALLOC_OUT_MAC_ID_NULL );
1236- MCDI_SET_DWORD (inbuf , MAE_ACTION_SET_ALLOC_IN_DST_MAC_ID ,
1237- MC_CMD_MAE_MAC_ADDR_ALLOC_OUT_MAC_ID_NULL );
12381315 if (act -> count && !WARN_ON (!act -> count -> cnt ))
12391316 MCDI_SET_DWORD (inbuf , MAE_ACTION_SET_ALLOC_IN_COUNTER_ID ,
12401317 act -> count -> cnt -> fw_id );
0 commit comments