You've already forked linux-rockchip
mirror of
https://github.com/armbian/linux-rockchip.git
synced 2026-01-06 11:08:10 -08:00
ice: Implement filter sync, NDO operations and bump version
This patch implements multiple pieces of functionality: 1. Added ice_vsi_sync_filters, which is called through the service task to push filter updates to the hardware. 2. Add support to enable/disable promiscuous mode on an interface. Enabling/disabling promiscuous mode on an interface results in addition/removal of a promisc filter rule through ice_vsi_sync_filters. 3. Implement handlers for ndo_set_mac_address, ndo_change_mtu, ndo_poll_controller and ndo_set_rx_mode. This patch also marks the end of the driver addition by bumping up the driver version. Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com> Tested-by: Tony Brelinski <tonyx.brelinski@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
committed by
Jeff Kirsher
parent
0b28b702e7
commit
e94d447866
@@ -125,11 +125,20 @@ enum ice_state {
|
||||
__ICE_SUSPENDED, /* set on module remove path */
|
||||
__ICE_RESET_FAILED, /* set by reset/rebuild */
|
||||
__ICE_ADMINQ_EVENT_PENDING,
|
||||
__ICE_FLTR_OVERFLOW_PROMISC,
|
||||
__ICE_CFG_BUSY,
|
||||
__ICE_SERVICE_SCHED,
|
||||
__ICE_STATE_NBITS /* must be last */
|
||||
};
|
||||
|
||||
enum ice_vsi_flags {
|
||||
ICE_VSI_FLAG_UMAC_FLTR_CHANGED,
|
||||
ICE_VSI_FLAG_MMAC_FLTR_CHANGED,
|
||||
ICE_VSI_FLAG_VLAN_FLTR_CHANGED,
|
||||
ICE_VSI_FLAG_PROMISC_CHANGED,
|
||||
ICE_VSI_FLAG_NBITS /* must be last */
|
||||
};
|
||||
|
||||
/* struct that defines a VSI, associated with a dev */
|
||||
struct ice_vsi {
|
||||
struct net_device *netdev;
|
||||
@@ -144,7 +153,9 @@ struct ice_vsi {
|
||||
|
||||
u64 tx_linearize;
|
||||
DECLARE_BITMAP(state, __ICE_STATE_NBITS);
|
||||
DECLARE_BITMAP(flags, ICE_VSI_FLAG_NBITS);
|
||||
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
|
||||
unsigned int current_netdev_flags;
|
||||
u32 tx_restart;
|
||||
u32 tx_busy;
|
||||
u32 rx_buf_failed;
|
||||
@@ -175,6 +186,9 @@ struct ice_vsi {
|
||||
struct ice_eth_stats eth_stats;
|
||||
struct ice_eth_stats eth_stats_prev;
|
||||
|
||||
struct list_head tmp_sync_list; /* MAC filters to be synced */
|
||||
struct list_head tmp_unsync_list; /* MAC filters to be unsynced */
|
||||
|
||||
bool irqs_ready;
|
||||
bool current_isup; /* Sync 'link up' logging */
|
||||
bool stat_offsets_loaded;
|
||||
|
||||
@@ -135,6 +135,24 @@ struct ice_aqc_manage_mac_read_resp {
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
};
|
||||
|
||||
/* Manage MAC address, write command - direct (0x0108) */
|
||||
struct ice_aqc_manage_mac_write {
|
||||
u8 port_num;
|
||||
u8 flags;
|
||||
#define ICE_AQC_MAN_MAC_WR_MC_MAG_EN BIT(0)
|
||||
#define ICE_AQC_MAN_MAC_WR_WOL_LAA_PFR_KEEP BIT(1)
|
||||
#define ICE_AQC_MAN_MAC_WR_S 6
|
||||
#define ICE_AQC_MAN_MAC_WR_M (3 << ICE_AQC_MAN_MAC_WR_S)
|
||||
#define ICE_AQC_MAN_MAC_UPDATE_LAA 0
|
||||
#define ICE_AQC_MAN_MAC_UPDATE_LAA_WOL (BIT(0) << ICE_AQC_MAN_MAC_WR_S)
|
||||
/* High 16 bits of MAC address in big endian order */
|
||||
__be16 sah;
|
||||
/* Low 32 bits of MAC address in big endian order */
|
||||
__be32 sal;
|
||||
__le32 addr_high;
|
||||
__le32 addr_low;
|
||||
};
|
||||
|
||||
/* Clear PXE Command and response (direct 0x0110) */
|
||||
struct ice_aqc_clear_pxe {
|
||||
u8 rx_cnt;
|
||||
@@ -1214,6 +1232,7 @@ struct ice_aq_desc {
|
||||
struct ice_aqc_q_shutdown q_shutdown;
|
||||
struct ice_aqc_req_res res_owner;
|
||||
struct ice_aqc_manage_mac_read mac_read;
|
||||
struct ice_aqc_manage_mac_write mac_write;
|
||||
struct ice_aqc_clear_pxe clear_pxe;
|
||||
struct ice_aqc_list_caps get_cap;
|
||||
struct ice_aqc_get_phy_caps get_phy;
|
||||
@@ -1258,6 +1277,7 @@ enum ice_aq_err {
|
||||
ICE_AQ_RC_ENOMEM = 9, /* Out of memory */
|
||||
ICE_AQ_RC_EBUSY = 12, /* Device or resource busy */
|
||||
ICE_AQ_RC_EEXIST = 13, /* object already exists */
|
||||
ICE_AQ_RC_ENOSPC = 16, /* No space left or allocation failure */
|
||||
};
|
||||
|
||||
/* Admin Queue command opcodes */
|
||||
@@ -1276,6 +1296,7 @@ enum ice_adminq_opc {
|
||||
|
||||
/* manage MAC address */
|
||||
ice_aqc_opc_manage_mac_read = 0x0107,
|
||||
ice_aqc_opc_manage_mac_write = 0x0108,
|
||||
|
||||
/* PXE */
|
||||
ice_aqc_opc_clear_pxe_mode = 0x0110,
|
||||
|
||||
@@ -1232,6 +1232,34 @@ enum ice_status ice_get_caps(struct ice_hw *hw)
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_aq_manage_mac_write - manage MAC address write command
|
||||
* @hw: pointer to the hw struct
|
||||
* @mac_addr: MAC address to be written as LAA/LAA+WoL/Port address
|
||||
* @flags: flags to control write behavior
|
||||
* @cd: pointer to command details structure or NULL
|
||||
*
|
||||
* This function is used to write MAC address to the NVM (0x0108).
|
||||
*/
|
||||
enum ice_status
|
||||
ice_aq_manage_mac_write(struct ice_hw *hw, u8 *mac_addr, u8 flags,
|
||||
struct ice_sq_cd *cd)
|
||||
{
|
||||
struct ice_aqc_manage_mac_write *cmd;
|
||||
struct ice_aq_desc desc;
|
||||
|
||||
cmd = &desc.params.mac_write;
|
||||
ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_manage_mac_write);
|
||||
|
||||
cmd->flags = flags;
|
||||
|
||||
/* Prep values for flags, sah, sal */
|
||||
cmd->sah = htons(*((u16 *)mac_addr));
|
||||
cmd->sal = htonl(*((u32 *)(mac_addr + 2)));
|
||||
|
||||
return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_aq_clear_pxe_mode
|
||||
* @hw: pointer to the hw struct
|
||||
|
||||
@@ -58,6 +58,9 @@ enum ice_status
|
||||
ice_aq_send_cmd(struct ice_hw *hw, struct ice_aq_desc *desc,
|
||||
void *buf, u16 buf_size, struct ice_sq_cd *cd);
|
||||
enum ice_status ice_aq_get_fw_ver(struct ice_hw *hw, struct ice_sq_cd *cd);
|
||||
enum ice_status
|
||||
ice_aq_manage_mac_write(struct ice_hw *hw, u8 *mac_addr, u8 flags,
|
||||
struct ice_sq_cd *cd);
|
||||
enum ice_status ice_clear_pf_cfg(struct ice_hw *hw);
|
||||
enum ice_status
|
||||
ice_set_fc(struct ice_port_info *pi, u8 *aq_failures, bool atomic_restart);
|
||||
|
||||
@@ -353,6 +353,18 @@ enum ice_tx_desc_len_fields {
|
||||
ICE_TX_DESC_LEN_L4_LEN_S = 14 /* 4 BITS */
|
||||
};
|
||||
|
||||
#define ICE_TXD_QW1_MACLEN_M (0x7FUL << ICE_TX_DESC_LEN_MACLEN_S)
|
||||
#define ICE_TXD_QW1_IPLEN_M (0x7FUL << ICE_TX_DESC_LEN_IPLEN_S)
|
||||
#define ICE_TXD_QW1_L4LEN_M (0xFUL << ICE_TX_DESC_LEN_L4_LEN_S)
|
||||
|
||||
/* Tx descriptor field limits in bytes */
|
||||
#define ICE_TXD_MACLEN_MAX ((ICE_TXD_QW1_MACLEN_M >> \
|
||||
ICE_TX_DESC_LEN_MACLEN_S) * ICE_BYTES_PER_WORD)
|
||||
#define ICE_TXD_IPLEN_MAX ((ICE_TXD_QW1_IPLEN_M >> \
|
||||
ICE_TX_DESC_LEN_IPLEN_S) * ICE_BYTES_PER_DWORD)
|
||||
#define ICE_TXD_L4LEN_MAX ((ICE_TXD_QW1_L4LEN_M >> \
|
||||
ICE_TX_DESC_LEN_L4_LEN_S) * ICE_BYTES_PER_DWORD)
|
||||
|
||||
#define ICE_TXD_QW1_TX_BUF_SZ_S 34
|
||||
#define ICE_TXD_QW1_L2TAG1_S 48
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1626,6 +1626,83 @@ ice_remove_mac_exit:
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_cfg_dflt_vsi - add filter rule to set/unset given VSI as default
|
||||
* VSI for the switch (represented by swid)
|
||||
* @hw: pointer to the hardware structure
|
||||
* @vsi_id: number of VSI to set as default
|
||||
* @set: true to add the above mentioned switch rule, false to remove it
|
||||
* @direction: ICE_FLTR_RX or ICE_FLTR_TX
|
||||
*/
|
||||
enum ice_status
|
||||
ice_cfg_dflt_vsi(struct ice_hw *hw, u16 vsi_id, bool set, u8 direction)
|
||||
{
|
||||
struct ice_aqc_sw_rules_elem *s_rule;
|
||||
struct ice_fltr_info f_info;
|
||||
enum ice_adminq_opc opcode;
|
||||
enum ice_status status;
|
||||
u16 s_rule_size;
|
||||
|
||||
s_rule_size = set ? ICE_SW_RULE_RX_TX_ETH_HDR_SIZE :
|
||||
ICE_SW_RULE_RX_TX_NO_HDR_SIZE;
|
||||
s_rule = devm_kzalloc(ice_hw_to_dev(hw), s_rule_size, GFP_KERNEL);
|
||||
if (!s_rule)
|
||||
return ICE_ERR_NO_MEMORY;
|
||||
|
||||
memset(&f_info, 0, sizeof(f_info));
|
||||
|
||||
f_info.lkup_type = ICE_SW_LKUP_DFLT;
|
||||
f_info.flag = direction;
|
||||
f_info.fltr_act = ICE_FWD_TO_VSI;
|
||||
f_info.fwd_id.vsi_id = vsi_id;
|
||||
|
||||
if (f_info.flag & ICE_FLTR_RX) {
|
||||
f_info.src = hw->port_info->lport;
|
||||
if (!set)
|
||||
f_info.fltr_rule_id =
|
||||
hw->port_info->dflt_rx_vsi_rule_id;
|
||||
} else if (f_info.flag & ICE_FLTR_TX) {
|
||||
f_info.src = vsi_id;
|
||||
if (!set)
|
||||
f_info.fltr_rule_id =
|
||||
hw->port_info->dflt_tx_vsi_rule_id;
|
||||
}
|
||||
|
||||
if (set)
|
||||
opcode = ice_aqc_opc_add_sw_rules;
|
||||
else
|
||||
opcode = ice_aqc_opc_remove_sw_rules;
|
||||
|
||||
ice_fill_sw_rule(hw, &f_info, s_rule, opcode);
|
||||
|
||||
status = ice_aq_sw_rules(hw, s_rule, s_rule_size, 1, opcode, NULL);
|
||||
if (status || !(f_info.flag & ICE_FLTR_TX_RX))
|
||||
goto out;
|
||||
if (set) {
|
||||
u16 index = le16_to_cpu(s_rule->pdata.lkup_tx_rx.index);
|
||||
|
||||
if (f_info.flag & ICE_FLTR_TX) {
|
||||
hw->port_info->dflt_tx_vsi_num = vsi_id;
|
||||
hw->port_info->dflt_tx_vsi_rule_id = index;
|
||||
} else if (f_info.flag & ICE_FLTR_RX) {
|
||||
hw->port_info->dflt_rx_vsi_num = vsi_id;
|
||||
hw->port_info->dflt_rx_vsi_rule_id = index;
|
||||
}
|
||||
} else {
|
||||
if (f_info.flag & ICE_FLTR_TX) {
|
||||
hw->port_info->dflt_tx_vsi_num = ICE_DFLT_VSI_INVAL;
|
||||
hw->port_info->dflt_tx_vsi_rule_id = ICE_INVAL_ACT;
|
||||
} else if (f_info.flag & ICE_FLTR_RX) {
|
||||
hw->port_info->dflt_rx_vsi_num = ICE_DFLT_VSI_INVAL;
|
||||
hw->port_info->dflt_rx_vsi_rule_id = ICE_INVAL_ACT;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
devm_kfree(ice_hw_to_dev(hw), s_rule);
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_remove_vlan_internal - Remove one VLAN based filter rule
|
||||
* @hw: pointer to the hardware structure
|
||||
|
||||
@@ -155,5 +155,7 @@ enum ice_status ice_remove_mac(struct ice_hw *hw, struct list_head *m_lst);
|
||||
void ice_remove_vsi_fltr(struct ice_hw *hw, u16 vsi_id);
|
||||
enum ice_status ice_add_vlan(struct ice_hw *hw, struct list_head *m_list);
|
||||
enum ice_status ice_remove_vlan(struct ice_hw *hw, struct list_head *v_list);
|
||||
enum ice_status
|
||||
ice_cfg_dflt_vsi(struct ice_hw *hw, u16 vsi_id, bool set, u8 direction);
|
||||
|
||||
#endif /* _ICE_SWITCH_H_ */
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
#include "ice_controlq.h"
|
||||
#include "ice_lan_tx_rx.h"
|
||||
|
||||
#define ICE_BYTES_PER_WORD 2
|
||||
#define ICE_BYTES_PER_DWORD 4
|
||||
|
||||
static inline bool ice_is_tc_ena(u8 bitmap, u8 tc)
|
||||
{
|
||||
return test_bit(tc, (unsigned long *)&bitmap);
|
||||
@@ -227,7 +230,9 @@ struct ice_port_info {
|
||||
u8 port_state;
|
||||
#define ICE_SCHED_PORT_STATE_INIT 0x0
|
||||
#define ICE_SCHED_PORT_STATE_READY 0x1
|
||||
u16 dflt_tx_vsi_rule_id;
|
||||
u16 dflt_tx_vsi_num;
|
||||
u16 dflt_rx_vsi_rule_id;
|
||||
u16 dflt_rx_vsi_num;
|
||||
struct ice_fc_info fc;
|
||||
struct ice_mac_info mac;
|
||||
|
||||
Reference in New Issue
Block a user