Merge "atlantic forwarding driver v1.0.30"

This commit is contained in:
qctecmdr 2020-02-03 19:30:01 -08:00 committed by Gerrit - the friendly Code Review server
commit 32e310dcb8
17 changed files with 971 additions and 504 deletions

View File

@ -46,4 +46,4 @@ atlantic-fwd-$(CONFIG_MACSEC) += atl_macsec.o macsec/macsec_api.o
atlantic-fwd-$(CONFIG_AQFWD_QCOM) += atl_qcom.o
atlantic-fwd-$(CONFIG_AQFWD_QCOM_IPA) += atl_qcom_ipa.o
CFLAGS_atl_trace.o := -I$(src)
ccflags-y += -I$(src)

View File

@ -18,13 +18,14 @@
#include <linux/netdevice.h>
#include <linux/moduleparam.h>
#define ATL_VERSION "1.0.29"
#define ATL_VERSION "1.0.30"
struct atl_nic;
enum atl_fwd_notify;
#include "atl_compat.h"
#include "atl_hw.h"
#include "atl_log.h"
#include "atl_ring_desc.h"
#include "atl_stats.h"
@ -279,47 +280,6 @@ extern unsigned int atl_tx_clean_budget;
extern unsigned int atl_tx_free_low;
extern unsigned int atl_tx_free_high;
/* Logging conviniency macros.
*
* atl_dev_xxx are for low-level contexts and implicitly reference
* struct atl_hw *hw;
*
* atl_nic_xxx are for high-level contexts and implicitly reference
* struct atl_nic *nic; */
#define atl_dev_dbg(fmt, args...) \
dev_dbg(&hw->pdev->dev, fmt, ## args)
#define atl_dev_info(fmt, args...) \
dev_info(&hw->pdev->dev, fmt, ## args)
#define atl_dev_warn(fmt, args...) \
dev_warn(&hw->pdev->dev, fmt, ## args)
#define atl_dev_err(fmt, args...) \
dev_err(&hw->pdev->dev, fmt, ## args)
#define atl_nic_dbg(fmt, args...) \
dev_dbg(&nic->hw.pdev->dev, fmt, ## args)
#define atl_nic_info(fmt, args...) \
dev_info(&nic->hw.pdev->dev, fmt, ## args)
#define atl_nic_warn(fmt, args...) \
dev_warn(&nic->hw.pdev->dev, fmt, ## args)
#define atl_nic_err(fmt, args...) \
dev_err(&nic->hw.pdev->dev, fmt, ## args)
#define atl_dev_init_warn(fmt, args...) \
do { \
if (hw) \
atl_dev_warn(fmt, ## args); \
else \
printk(KERN_WARNING "%s: " fmt, atl_driver_name, ##args); \
} while(0)
#define atl_dev_init_err(fmt, args...) \
do { \
if (hw) \
atl_dev_warn(fmt, ## args); \
else \
printk(KERN_ERR "%s: " fmt, atl_driver_name, ##args); \
} while(0)
#define atl_module_param(_name, _type, _mode) \
module_param_named(_name, atl_ ## _name, _type, _mode)
@ -383,16 +343,6 @@ static inline int atl_fwd_suspend_rings(struct atl_nic *nic) { return 0; }
static inline int atl_fwd_resume_rings(struct atl_nic *nic) { return 0; }
#endif
int atl_get_lpi_timer(struct atl_nic *nic, uint32_t *lpi_delay);
int atl_mdio_hwsem_get(struct atl_hw *hw);
void atl_mdio_hwsem_put(struct atl_hw *hw);
int __atl_mdio_read(struct atl_hw *hw, uint8_t prtad, uint8_t mmd,
uint16_t addr, uint16_t *val);
int atl_mdio_read(struct atl_hw *hw, uint8_t prtad, uint8_t mmd,
uint16_t addr, uint16_t *val);
int __atl_mdio_write(struct atl_hw *hw, uint8_t prtad, uint8_t mmd,
uint16_t addr, uint16_t val);
int atl_mdio_write(struct atl_hw *hw, uint8_t prtad, uint8_t mmd,
uint16_t addr, uint16_t val);
void atl_refresh_rxfs(struct atl_nic *nic);
void atl_schedule_work(struct atl_nic *nic);
int atl_hwmon_init(struct atl_nic *nic);

View File

@ -11,6 +11,7 @@
#include <linux/pm_runtime.h>
#include "atl_common.h"
#include "atl_mdio.h"
#include "atl_ring.h"
#include "atl_fwdnl.h"
@ -1968,7 +1969,8 @@ static void atl_refresh_rxf_desc(struct atl_nic *nic,
desc->update_rxf(nic, idx);
atl_set_vlan_promisc(&nic->hw, (nic->ndev->flags & IFF_PROMISC) ||
nic->rxf_vlan.promisc_count);
nic->rxf_vlan.promisc_count ||
!nic->rxf_vlan.vlans_active);
}
void atl_refresh_rxfs(struct atl_nic *nic)
@ -1979,7 +1981,8 @@ void atl_refresh_rxfs(struct atl_nic *nic)
atl_refresh_rxf_desc(nic, desc);
atl_set_vlan_promisc(&nic->hw, (nic->ndev->flags & IFF_PROMISC) ||
nic->rxf_vlan.promisc_count);
nic->rxf_vlan.promisc_count ||
!nic->rxf_vlan.vlans_active);
}
static bool atl_vlan_pull_from_promisc(struct atl_nic *nic, uint32_t idx)
@ -2020,7 +2023,8 @@ static bool atl_vlan_pull_from_promisc(struct atl_nic *nic, uint32_t idx)
kfree(map);
atl_set_vlan_promisc(&nic->hw, (nic->ndev->flags & IFF_PROMISC) ||
vlan->promisc_count);
vlan->promisc_count ||
!vlan->vlans_active);
return true;
}
@ -2206,8 +2210,11 @@ int atl_vlan_rx_add_vid(struct net_device *ndev, __be16 proto, u16 vid)
if (idx == ATL_VIDX_NONE) {
/* VID not found and no unused filters */
vlan->promisc_count++;
atl_set_vlan_promisc(&nic->hw, (ndev->flags & IFF_PROMISC) ||
vlan->promisc_count);
if (pm_runtime_active(&nic->hw.pdev->dev))
atl_set_vlan_promisc(&nic->hw,
(ndev->flags & IFF_PROMISC) ||
vlan->promisc_count ||
!vlan->vlans_active);
return 0;
}
@ -2216,8 +2223,7 @@ int atl_vlan_rx_add_vid(struct net_device *ndev, __be16 proto, u16 vid)
idx &= ATL_VIDX_MASK;
vlan->cmd[idx] = ATL_VLAN_EN | ATL_RXF_ACT_TOHOST | vid;
vlan->count++;
atl_rxf_update_vlan(nic, idx);
return 0;
goto update_vlan;
}
idx &= ATL_VIDX_MASK;
@ -2230,7 +2236,14 @@ int atl_vlan_rx_add_vid(struct net_device *ndev, __be16 proto, u16 vid)
__func__, vid, idx);
vlan->cmd[idx] = ATL_RXF_EN | ATL_RXF_ACT_TOHOST | vid;
update_vlan:
atl_rxf_update_vlan(nic, idx);
if (pm_runtime_active(&nic->hw.pdev->dev))
atl_set_vlan_promisc(&nic->hw,
(nic->ndev->flags & IFF_PROMISC) ||
vlan->promisc_count ||
!vlan->vlans_active);
return 0;
}
@ -2253,9 +2266,7 @@ int atl_vlan_rx_kill_vid(struct net_device *ndev, __be16 proto, u16 vid)
if (!(idx & ATL_VIDX_FOUND)) {
/* VID not present in filters, decrease promisc count */
vlan->promisc_count--;
atl_set_vlan_promisc(&nic->hw, (ndev->flags & IFF_PROMISC) ||
vlan->promisc_count);
return 0;
goto update_vlan_promisc;
}
idx &= ATL_VIDX_MASK;
@ -2271,6 +2282,11 @@ int atl_vlan_rx_kill_vid(struct net_device *ndev, __be16 proto, u16 vid)
if (!atl_vlan_pull_from_promisc(nic, idx))
atl_rxf_update_vlan(nic, idx);
update_vlan_promisc:
if (pm_runtime_active(&nic->hw.pdev->dev))
atl_set_vlan_promisc(&nic->hw, (ndev->flags & IFF_PROMISC) ||
vlan->promisc_count ||
!vlan->vlans_active);
return 0;
}

View File

@ -787,6 +787,13 @@ int atl_fwd_receive_skb(struct net_device *ndev, struct sk_buff *skb)
}
EXPORT_SYMBOL(atl_fwd_receive_skb);
int atl_fwd_napi_receive_skb(struct net_device *ndev, struct sk_buff *skb)
{
skb->protocol = eth_type_trans(skb, ndev);
return netif_receive_skb(skb);
}
EXPORT_SYMBOL(atl_fwd_napi_receive_skb);
int atl_fwd_transmit_skb(struct net_device *ndev, struct sk_buff *skb)
{
skb->dev = ndev;

View File

@ -13,7 +13,7 @@
#include "atl_common.h"
/* Each incompatible API change bumps the API version */
#define ATL_FWD_API_VERSION 2
#define ATL_FWD_API_VERSION 3
struct atl_fwd_event;
@ -361,6 +361,17 @@ int atl_fwd_disable_event(struct atl_fwd_event *evt);
int atl_fwd_receive_skb(struct net_device *ndev, struct sk_buff *skb);
int atl_fwd_transmit_skb(struct net_device *ndev, struct sk_buff *skb);
/**
* atl_fwd_napi_receive_skb() - post skb to the network stack
*
* @ndev: network device
* @skb: buffer to post
*
* This function may only be called from softirq context and interrupts
* should be enabled.
*/
int atl_fwd_napi_receive_skb(struct net_device *ndev, struct sk_buff *skb);
/**
* atl_fwd_register_notifier() - Register notifier for reset of device
*

View File

@ -603,9 +603,15 @@ void atl_start_hw_global(struct atl_nic *nic)
atl_set_bits(hw, ATL_INTR_AUTO_MASK, BIT(0));
/* Enable status auto-clear on link intr generation */
atl_set_bits(hw, ATL_INTR_AUTO_CLEAR, BIT(0));
} else
} else {
/* Enable legacy INTx mode and status clear-on-read */
atl_write(hw, ATL_INTR_CTRL, BIT(7));
/* Clear the registers, which might have been set on previous
* driver load and might interfere with legacy IRQ handling
*/
atl_write(hw, ATL_INTR_AUTO_MASK, 0);
atl_write(hw, ATL_INTR_AUTO_CLEAR, 0);
}
/* Map link interrupt to cause 0 */
atl_write(hw, ATL_INTR_GEN_INTR_MAP4, BIT(7) | (0 << 0));
@ -623,7 +629,7 @@ void atl_start_hw_global(struct atl_nic *nic)
static void atl_set_all_multi(struct atl_hw *hw, bool all_multi)
{
atl_write_bit(hw, ATL_RX_MC_FLT_MSK, 14, all_multi);
atl_write(hw, ATL_RX_MC_FLT(0), all_multi ? 0x80010000 : 0);
atl_write(hw, ATL_RX_MC_FLT(0), all_multi ? 0x80010FFF : 0x00010FFF);
}
void atl_set_rx_mode(struct net_device *ndev)
@ -638,6 +644,9 @@ void atl_set_rx_mode(struct net_device *ndev)
int i = 1; /* UC filter 0 reserved for MAC address */
struct netdev_hw_addr *hwaddr;
if (!pm_runtime_active(&nic->hw.pdev->dev))
return;
if (is_multicast_enabled)
mc_count = netdev_mc_count(ndev);
@ -647,11 +656,12 @@ void atl_set_rx_mode(struct net_device *ndev)
all_multi_needed |= 1;
/* Enable promisc VLAN mode iff IFF_PROMISC explicitly
/* Enable promisc VLAN mode if IFF_PROMISC explicitly
* requested or too many VIDs registered
*/
atl_set_vlan_promisc(hw,
ndev->flags & IFF_PROMISC || nic->rxf_vlan.promisc_count);
ndev->flags & IFF_PROMISC || nic->rxf_vlan.promisc_count ||
!nic->rxf_vlan.vlans_active);
atl_write_bit(hw, ATL_RX_FLT_CTRL1, 3, promisc_needed);
if (promisc_needed)
@ -660,13 +670,11 @@ void atl_set_rx_mode(struct net_device *ndev)
netdev_for_each_uc_addr(hwaddr, ndev)
atl_set_uc_flt(hw, i++, hwaddr->addr);
if (is_multicast_enabled) {
atl_set_all_multi(hw, all_multi_needed);
atl_set_all_multi(hw, is_multicast_enabled && all_multi_needed);
if (!all_multi_needed)
netdev_for_each_mc_addr(hwaddr, ndev)
atl_set_uc_flt(hw, i++, hwaddr->addr);
}
if (is_multicast_enabled && !all_multi_needed)
netdev_for_each_mc_addr(hwaddr, ndev)
atl_set_uc_flt(hw, i++, hwaddr->addr);
while (i < ATL_UC_FLT_NUM)
atl_disable_uc_flt(hw, i++);

View File

@ -14,11 +14,9 @@
#include <linux/if_ether.h>
#include <linux/mutex.h>
#include <linux/types.h>
#ifdef NETIF_F_HW_MACSEC
#include <net/macsec.h>
#endif
#include "atl_fw.h"
#include "atl_macsec.h"
#include "atl_regs.h"
union atl_desc;
@ -73,107 +71,6 @@ enum atl_nic_state {
ATL_ST_START_NEEDED,
ATL_ST_DETACHED,
};
#ifdef NETIF_F_HW_MACSEC
#define ATL_MACSEC_MAX_SC 32
#define ATL_MACSEC_MAX_SA 32
enum atl_macsec_sc_sa {
atl_macsec_sa_sc_4sa_8sc,
atl_macsec_sa_sc_not_used,
atl_macsec_sa_sc_2sa_16sc,
atl_macsec_sa_sc_1sa_32sc,
};
struct atl_macsec_common_stats {
/* Ingress Common Counters */
struct {
uint64_t ctl_pkts;
uint64_t tagged_miss_pkts;
uint64_t untagged_miss_pkts;
uint64_t notag_pkts;
uint64_t untagged_pkts;
uint64_t bad_tag_pkts;
uint64_t no_sci_pkts;
uint64_t unknown_sci_pkts;
uint64_t ctrl_prt_pass_pkts;
uint64_t unctrl_prt_pass_pkts;
uint64_t ctrl_prt_fail_pkts;
uint64_t unctrl_prt_fail_pkts;
uint64_t too_long_pkts;
uint64_t igpoc_ctl_pkts;
uint64_t ecc_error_pkts;
uint64_t unctrl_hit_drop_redir;
} in;
/* Egress Common Counters */
struct {
uint64_t ctl_pkts;
uint64_t unknown_sa_pkts;
uint64_t untagged_pkts;
uint64_t too_long;
uint64_t ecc_error_pkts;
uint64_t unctrl_hit_drop_redir;
} out;
};
/* Ingress SA Counters */
struct atl_macsec_rx_sa_stats {
uint64_t untagged_hit_pkts;
uint64_t ctrl_hit_drop_redir_pkts;
uint64_t not_using_sa;
uint64_t unused_sa;
uint64_t not_valid_pkts;
uint64_t invalid_pkts;
uint64_t ok_pkts;
uint64_t late_pkts;
uint64_t delayed_pkts;
uint64_t unchecked_pkts;
uint64_t validated_octets;
uint64_t decrypted_octets;
};
/* Egress SA Counters */
struct atl_macsec_tx_sa_stats {
uint64_t sa_hit_drop_redirect;
uint64_t sa_protected2_pkts;
uint64_t sa_protected_pkts;
uint64_t sa_encrypted_pkts;
};
/* Egress SC Counters */
struct atl_macsec_tx_sc_stats {
uint64_t sc_protected_pkts;
uint64_t sc_encrypted_pkts;
uint64_t sc_protected_octets;
uint64_t sc_encrypted_octets;
};
struct atl_macsec_cfg {
enum atl_macsec_sc_sa sc_sa;
/* Egress channel configuration */
unsigned long txsc_idx_busy;
struct atl_macsec_txsc {
uint32_t hw_sc_idx;
unsigned long tx_sa_idx_busy;
const struct macsec_secy *sw_secy;
/* It is not OK to store key in driver but it is until ... */
u8 tx_sa_key[MACSEC_NUM_AN][MACSEC_KEYID_LEN];
struct atl_macsec_tx_sc_stats stats;
struct atl_macsec_tx_sa_stats tx_sa_stats[MACSEC_NUM_AN];
} atl_txsc[ATL_MACSEC_MAX_SC];
/* Ingress channel configuration */
unsigned long rxsc_idx_busy;
struct atl_macsec_rxsc {
uint32_t hw_sc_idx;
unsigned long rx_sa_idx_busy;
const struct macsec_secy *sw_secy;
const struct macsec_rx_sc *sw_rxsc;
/* TODO: we shouldn't store keys in the driver */
u8 rx_sa_key[MACSEC_NUM_AN][MACSEC_KEYID_LEN];
struct atl_macsec_rx_sa_stats rx_sa_stats[MACSEC_NUM_AN];
} atl_rxsc[ATL_MACSEC_MAX_SC];
struct atl_macsec_common_stats stats;
};
#endif
#define ATL_WAKE_SUPPORTED (WAKE_MAGIC | WAKE_PHY)
struct atl_hw {

View File

@ -0,0 +1,75 @@
/*
* aQuantia Corporation Network Driver
* Copyright (C) 2019 aQuantia Corporation. All rights reserved
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*/
#ifndef _ATL_LOG_H_
#define _ATL_LOG_H_
#ifdef __KERNEL__
#include <linux/device.h>
/* Logging conveniency macros.
*
* atl_dev_xxx are for low-level contexts and implicitly reference
* struct atl_hw *hw;
*
* atl_nic_xxx are for high-level contexts and implicitly reference
* struct atl_nic *nic;
*/
#define atl_dev_dbg(fmt, args...) \
dev_dbg(&hw->pdev->dev, fmt, ## args)
#define atl_dev_info(fmt, args...) \
dev_info(&hw->pdev->dev, fmt, ## args)
#define atl_dev_warn(fmt, args...) \
dev_warn(&hw->pdev->dev, fmt, ## args)
#define atl_dev_err(fmt, args...) \
dev_err(&hw->pdev->dev, fmt, ## args)
#define atl_nic_dbg(fmt, args...) \
dev_dbg(&nic->hw.pdev->dev, fmt, ## args)
#define atl_nic_info(fmt, args...) \
dev_info(&nic->hw.pdev->dev, fmt, ## args)
#define atl_nic_warn(fmt, args...) \
dev_warn(&nic->hw.pdev->dev, fmt, ## args)
#define atl_nic_err(fmt, args...) \
dev_err(&nic->hw.pdev->dev, fmt, ## args)
#define atl_dev_init_warn(fmt, args...) \
do { \
if (hw) \
atl_dev_warn(fmt, ## args); \
else \
printk(KERN_WARNING "%s: " fmt, atl_driver_name, ##args); \
} while (0)
#define atl_dev_init_err(fmt, args...) \
do { \
if (hw) \
atl_dev_err(fmt, ## args); \
else \
printk(KERN_ERR "%s: " fmt, atl_driver_name, ##args); \
} while (0)
#else /* __KERNEL__ */
/* Logging is disabled in case of unit tests */
#define atl_dev_dbg(fmt, args...)
#define atl_dev_info(fmt, args...)
#define atl_dev_warn(fmt, args...)
#define atl_dev_err(fmt, args...)
#define atl_nic_dbg(fmt, args...)
#define atl_nic_info(fmt, args...)
#define atl_nic_warn(fmt, args...)
#define atl_nic_err(fmt, args...)
#define atl_dev_init_warn(fmt, args...)
#define atl_dev_init_err(fmt, args...)
#endif /* __KERNEL__ */
#endif /* _ATL_LOG_H_ */

View File

@ -9,7 +9,7 @@
#include "atl_common.h"
#ifdef NETIF_F_HW_MACSEC
#include <net/macsec.h>
#include "atl_macsec.h"
#include <linux/rtnetlink.h>
#include "macsec/macsec_api.h"
@ -17,10 +17,23 @@
#define ATL_MACSEC_KEY_LEN_192_BIT 24
#define ATL_MACSEC_KEY_LEN_256_BIT 32
static int atl_clear_txsc(struct atl_hw *hw,
const struct atl_macsec_txsc *tx_sc);
static int atl_clear_rxsc(struct atl_hw *hw,
const struct atl_macsec_rxsc *rx_sc);
enum atl_clear_type {
/* update HW configuration */
ATL_CLEAR_HW = BIT(0),
/* update SW configuration (busy bits, pointers) */
ATL_CLEAR_SW = BIT(1),
};
static int atl_clear_txsc(struct atl_nic *nic, const int txsc_idx,
enum atl_clear_type clear_type);
static int atl_clear_txsa(struct atl_nic *nic, struct atl_macsec_txsc *atl_txsc,
const int sa_num, enum atl_clear_type clear_type);
static int atl_clear_rxsc(struct atl_nic *nic, const int rxsc_idx,
enum atl_clear_type clear_type);
static int atl_clear_rxsa(struct atl_nic *nic, struct atl_macsec_rxsc *atl_rxsc,
const int sa_num, enum atl_clear_type clear_type);
static int atl_clear_secy(struct atl_nic *nic, const struct macsec_secy *secy,
enum atl_clear_type clear_type);
static int atl_macsec_apply_cfg(struct atl_hw *hw);
static int atl_macsec_apply_secy_cfg(struct atl_hw *hw,
const struct macsec_secy *secy);
@ -106,7 +119,7 @@ static void atl_rotate_keys(uint32_t (*key)[8], int key_len)
(*key)[0] = swab32(tmp[5]);
(*key)[1] = swab32(tmp[4]);
(*key)[2] = swab32(tmp[3]);
(*key)[3] = swab32(tmp[0]);
(*key)[3] = swab32(tmp[2]);
(*key)[4] = swab32(tmp[1]);
(*key)[5] = swab32(tmp[0]);
} else if (key_len == ATL_MACSEC_KEY_LEN_256_BIT) {
@ -131,9 +144,12 @@ static int atl_macsec_get_common_stats(struct atl_hw *hw,
{
AQ_API_SEC_EgressCommonCounters egress_counters;
AQ_API_SEC_IngressCommonCounters ingress_counters;
int ret;
/* MACSEC counters */
AQ_API_GetIngressCommonCounters(hw, &ingress_counters);
ret = AQ_API_GetIngressCommonCounters(hw, &ingress_counters);
if (unlikely(ret))
return ret;
stats->in.ctl_pkts = STATS_2x32_TO_64(ingress_counters.ctl_pkts);
stats->in.tagged_miss_pkts =
@ -165,7 +181,9 @@ static int atl_macsec_get_common_stats(struct atl_hw *hw,
stats->in.unctrl_hit_drop_redir =
STATS_2x32_TO_64(ingress_counters.unctrl_hit_drop_redir);
AQ_API_GetEgressCommonCounters(hw, &egress_counters);
ret = AQ_API_GetEgressCommonCounters(hw, &egress_counters);
if (unlikely(ret))
return ret;
stats->out.ctl_pkts = STATS_2x32_TO_64(egress_counters.ctl_pkt);
stats->out.unknown_sa_pkts =
STATS_2x32_TO_64(egress_counters.unknown_sa_pkts);
@ -187,7 +205,7 @@ static int atl_macsec_get_rx_sa_stats(struct atl_hw *hw, int sa_idx,
int ret;
ret = AQ_API_GetIngressSACounters(hw, &i_sa_counters, sa_idx);
if (ret)
if (unlikely(ret))
return ret;
stats->untagged_hit_pkts =
@ -217,7 +235,7 @@ static int atl_macsec_get_tx_sa_stats(struct atl_hw *hw, int sa_idx,
int ret;
ret = AQ_API_GetEgressSACounters(hw, &e_sa_counters, sa_idx);
if (ret)
if (unlikely(ret))
return ret;
stats->sa_hit_drop_redirect =
@ -238,7 +256,7 @@ static int atl_macsec_get_tx_sa_next_pn(struct atl_hw *hw, int sa_idx, u32 *pn)
int ret;
ret = AQ_API_GetEgressSARecord(hw, &matchSARecord, sa_idx);
if (!ret)
if (likely(!ret))
*pn = matchSARecord.next_pn;
return ret;
@ -250,7 +268,7 @@ static int atl_macsec_get_rx_sa_next_pn(struct atl_hw *hw, int sa_idx, u32 *pn)
int ret;
ret = AQ_API_GetIngressSARecord(hw, &matchSARecord, sa_idx);
if (!ret)
if (likely(!ret))
*pn = (!matchSARecord.sat_nextpn) ? matchSARecord.next_pn : 0;
return ret;
@ -263,7 +281,7 @@ static int atl_macsec_get_tx_sc_stats(struct atl_hw *hw, int sc_idx,
int ret;
ret = AQ_API_GetEgressSCCounters(hw, &e_sc_counters, sc_idx);
if (ret)
if (unlikely(ret))
return ret;
stats->sc_protected_pkts =
@ -435,29 +453,8 @@ static int atl_mdo_dev_open(struct macsec_context *ctx)
static int atl_mdo_dev_stop(struct macsec_context *ctx)
{
struct atl_nic *nic = netdev_priv(ctx->netdev);
int txsc_idx = atl_get_txsc_idx_from_secy(&nic->hw, ctx->secy);
struct atl_hw *hw = &nic->hw;
int ret = 0;
ret = atl_clear_txsc(hw, &hw->macsec_cfg.atl_txsc[txsc_idx]);
if (ret)
return ret;
struct macsec_rx_sc *rx_sc;
uint32_t rxsc_idx;
for (rx_sc = rcu_dereference_bh(ctx->secy->rx_sc); rx_sc;
rx_sc = rcu_dereference_bh(rx_sc->next)) {
rxsc_idx = atl_get_rxsc_idx_from_rxsc(hw, rx_sc);
WARN_ON(rxsc_idx < 0);
if (unlikely(rxsc_idx < 0))
continue;
ret = atl_clear_rxsc(hw, &hw->macsec_cfg.atl_rxsc[rxsc_idx]);
if (ret)
return ret;
}
return ret;
return atl_clear_secy(nic, ctx->secy, ATL_CLEAR_HW);
}
static int atl_set_txsc(struct atl_hw *hw, int txsc_idx)
@ -472,10 +469,9 @@ static int atl_set_txsc(struct atl_hw *hw, int txsc_idx)
ether_addr_to_mac(matchEgressClassRecord.mac_sa,
secy->netdev->dev_addr);
dev_dbg(&hw->pdev->dev,
"set secy: sci %#llx, sc_idx=%d, protect=%d, curr_an=%d\n",
secy->sci, sc_idx, secy->protect_frames,
secy->tx_sc.encoding_sa);
atl_dev_dbg("set secy: sci %#llx, sc_idx=%d, protect=%d, curr_an=%d\n",
secy->sci, sc_idx, secy->protect_frames,
secy->tx_sc.encoding_sa);
matchEgressClassRecord.sci[1] = swab32(secy->sci & 0xffffffff);
matchEgressClassRecord.sci[0] = swab32(secy->sci >> 32);
@ -624,8 +620,8 @@ static int atl_mdo_add_secy(struct macsec_context *ctx)
hw->macsec_cfg.atl_txsc[txsc_idx].hw_sc_idx =
to_hw_sc_idx(txsc_idx, sc_sa);
hw->macsec_cfg.atl_txsc[txsc_idx].sw_secy = secy;
dev_dbg(&hw->pdev->dev, "add secy: txsc_idx=%d, sc_idx=%d\n", txsc_idx,
hw->macsec_cfg.atl_txsc[txsc_idx].hw_sc_idx);
atl_dev_dbg("add secy: txsc_idx=%d, sc_idx=%d\n", txsc_idx,
hw->macsec_cfg.atl_txsc[txsc_idx].hw_sc_idx);
if (netif_carrier_ok(nic->ndev) && netif_running(secy->netdev))
ret = atl_set_txsc(hw, txsc_idx);
@ -657,46 +653,51 @@ static int atl_mdo_upd_secy(struct macsec_context *ctx)
return ret;
}
static int atl_clear_txsc(struct atl_hw *hw,
const struct atl_macsec_txsc *tx_sc)
static int atl_clear_txsc(struct atl_nic *nic, const int txsc_idx,
enum atl_clear_type clear_type)
{
int txsc_idx = atl_get_txsc_idx_from_secy(hw, tx_sc->sw_secy);
struct atl_hw *hw = &nic->hw;
struct atl_macsec_txsc *tx_sc = &hw->macsec_cfg.atl_txsc[txsc_idx];
AQ_API_SEC_EgressClassRecord matchEgressClassRecord = { 0 };
AQ_API_SEC_EgressSCRecord matchSCRecord = { 0 };
int ret;
int ret = 0;
int sa_num;
ret = AQ_API_SetEgressClassRecord(hw, &matchEgressClassRecord,
txsc_idx);
if (ret)
return ret;
for_each_set_bit (sa_num, &tx_sc->tx_sa_idx_busy, ATL_MACSEC_MAX_SA) {
ret = atl_clear_txsa(nic, tx_sc, sa_num, clear_type);
if (ret)
return ret;
}
matchSCRecord.fresh = 1;
return AQ_API_SetEgressSCRecord(hw, &matchSCRecord, tx_sc->hw_sc_idx);
if (clear_type & ATL_CLEAR_HW) {
ret = AQ_API_SetEgressClassRecord(hw, &matchEgressClassRecord,
txsc_idx);
if (ret)
return ret;
matchSCRecord.fresh = 1;
ret = AQ_API_SetEgressSCRecord(hw, &matchSCRecord,
tx_sc->hw_sc_idx);
if (ret)
return ret;
}
if (clear_type & ATL_CLEAR_SW) {
clear_bit(txsc_idx, &hw->macsec_cfg.txsc_idx_busy);
hw->macsec_cfg.atl_txsc[txsc_idx].sw_secy = NULL;
}
return ret;
}
static int atl_mdo_del_secy(struct macsec_context *ctx)
{
struct atl_nic *nic = netdev_priv(ctx->netdev);
int txsc_idx = atl_get_txsc_idx_from_secy(&nic->hw, ctx->secy);
struct atl_hw *hw = &nic->hw;
struct macsec_rx_sc *rx_sc;
int rxsc_idx;
int ret = 0;
if (ctx->prepare)
return 0;
atl_mdo_dev_stop(ctx);
clear_bit(txsc_idx, &hw->macsec_cfg.txsc_idx_busy);
for (rx_sc = rcu_dereference_bh(ctx->secy->rx_sc); rx_sc;
rx_sc = rcu_dereference_bh(rx_sc->next)) {
rxsc_idx = atl_get_rxsc_idx_from_rxsc(hw, rx_sc);
clear_bit(rxsc_idx, &hw->macsec_cfg.rxsc_idx_busy);
}
hw->macsec_cfg.atl_txsc[txsc_idx].sw_secy = NULL;
return ret;
return atl_clear_secy(nic, ctx->secy, ATL_CLEAR_HW | ATL_CLEAR_SW);
}
static int atl_update_txsa(struct atl_hw *hw, unsigned int sc_idx,
@ -704,38 +705,36 @@ static int atl_update_txsa(struct atl_hw *hw, unsigned int sc_idx,
const struct macsec_tx_sa *tx_sa,
const unsigned char *key, unsigned char an)
{
int ret = 0;
unsigned int sa_idx;
dev_dbg(&hw->pdev->dev, "set tx_sa %d: active=%d, next_pn=%d\n", an,
tx_sa->active, tx_sa->next_pn);
sa_idx = sc_idx | an;
AQ_API_SEC_EgressSAKeyRecord matchKeyRecord = { 0 };
AQ_API_SEC_EgressSARecord matchSARecord = { 0 };
unsigned int sa_idx = sc_idx | an;
int ret = 0;
atl_dev_dbg("set tx_sa %d: active=%d, next_pn=%d\n", an, tx_sa->active,
tx_sa->next_pn);
matchSARecord.valid = tx_sa->active;
matchSARecord.fresh = 1;
matchSARecord.next_pn = tx_sa->next_pn;
ret = AQ_API_SetEgressSARecord(hw, &matchSARecord, sa_idx);
if (ret) {
dev_err(&hw->pdev->dev,
"AQ_API_SetEgressSARecord failed with %d\n", ret);
atl_dev_err("AQ_API_SetEgressSARecord failed with %d\n", ret);
return ret;
}
if (key) {
AQ_API_SEC_EgressSAKeyRecord matchKeyRecord = { 0 };
memcpy(&matchKeyRecord.key, key, secy->key_len);
if (!key)
return ret;
atl_rotate_keys(&matchKeyRecord.key, secy->key_len);
memcpy(&matchKeyRecord.key, key, secy->key_len);
atl_rotate_keys(&matchKeyRecord.key, secy->key_len);
ret = AQ_API_SetEgressSAKeyRecord(hw, &matchKeyRecord, sa_idx);
if (ret)
atl_dev_err("AQ_API_SetEgressSAKeyRecord failed with %d\n",
ret);
ret = AQ_API_SetEgressSAKeyRecord(hw, &matchKeyRecord, sa_idx);
if (ret)
dev_err(&hw->pdev->dev,
"AQ_API_SetEgressSAKeyRecord failed with %d\n",
ret);
}
return ret;
}
@ -781,23 +780,17 @@ static int atl_mdo_upd_txsa(struct macsec_context *ctx)
return 0;
}
static int atl_mdo_del_txsa(struct macsec_context *ctx)
static int atl_clear_txsa(struct atl_nic *nic, struct atl_macsec_txsc *atl_txsc,
const int sa_num, enum atl_clear_type clear_type)
{
struct atl_nic *nic = netdev_priv(ctx->netdev);
int txsc_idx = atl_get_txsc_idx_from_secy(&nic->hw, ctx->secy);
int sa_idx = atl_txsc->hw_sc_idx | sa_num;
struct atl_hw *hw = &nic->hw;
struct atl_macsec_txsc *atl_txsc = &hw->macsec_cfg.atl_txsc[txsc_idx];
int sa_idx;
int ret = 0;
if (ctx->prepare)
return 0;
if (clear_type & ATL_CLEAR_SW)
clear_bit(sa_num, &atl_txsc->tx_sa_idx_busy);
sa_idx = atl_txsc->hw_sc_idx | ctx->sa.assoc_num;
clear_bit(ctx->sa.assoc_num, &atl_txsc->tx_sa_idx_busy);
if (netif_carrier_ok(nic->ndev)) {
if ((clear_type & ATL_CLEAR_HW) && netif_carrier_ok(nic->ndev)) {
AQ_API_SEC_EgressSARecord matchSARecord = { 0 };
matchSARecord.fresh = 1;
@ -813,6 +806,18 @@ static int atl_mdo_del_txsa(struct macsec_context *ctx)
return 0;
}
static int atl_mdo_del_txsa(struct macsec_context *ctx)
{
struct atl_nic *nic = netdev_priv(ctx->netdev);
int txsc_idx = atl_get_txsc_idx_from_secy(&nic->hw, ctx->secy);
if (ctx->prepare)
return 0;
return atl_clear_txsa(nic, &nic->hw.macsec_cfg.atl_txsc[txsc_idx],
ctx->sa.assoc_num, ATL_CLEAR_HW | ATL_CLEAR_SW);
}
static int atl_rxsc_validate_frames(const enum macsec_validation_type validate)
{
switch (validate) {
@ -842,9 +847,8 @@ static int atl_set_rxsc(struct atl_hw *hw, const uint32_t rxsc_idx)
AQ_API_SEC_IngressSCRecord sc_record = { 0 };
int ret = 0;
dev_dbg(&hw->pdev->dev,
"set rx_sc: rxsc_idx=%d, sci %#llx, hw_sc_idx=%d\n", rxsc_idx,
rx_sc->sci, hw_sc_idx);
atl_dev_dbg("set rx_sc: rxsc_idx=%d, sci %#llx, hw_sc_idx=%d\n",
rxsc_idx, rx_sc->sci, hw_sc_idx);
pre_class_record.sci[1] = swab32(rx_sc->sci & 0xffffffff);
pre_class_record.sci[0] = swab32(rx_sc->sci >> 32);
@ -865,9 +869,8 @@ static int atl_set_rxsc(struct atl_hw *hw, const uint32_t rxsc_idx)
ret = AQ_API_SetIngressPreClassRecord(hw, &pre_class_record,
2 * rxsc_idx + 1);
if (ret) {
dev_err(&hw->pdev->dev,
"AQ_API_SetIngressPreClassRecord failed with %d\n",
ret);
atl_dev_err("AQ_API_SetIngressPreClassRecord failed with %d\n",
ret);
return ret;
}
@ -878,9 +881,8 @@ static int atl_set_rxsc(struct atl_hw *hw, const uint32_t rxsc_idx)
ret = AQ_API_SetIngressPreClassRecord(hw, &pre_class_record,
2 * rxsc_idx);
if (ret) {
dev_err(&hw->pdev->dev,
"AQ_API_SetIngressPreClassRecord failed with %d\n",
ret);
atl_dev_err("AQ_API_SetIngressPreClassRecord failed with %d\n",
ret);
return ret;
}
@ -895,8 +897,7 @@ static int atl_set_rxsc(struct atl_hw *hw, const uint32_t rxsc_idx)
ret = AQ_API_SetIngressSCRecord(hw, &sc_record, hw_sc_idx);
if (ret) {
dev_err(&hw->pdev->dev,
"AQ_API_SetIngressSCRecord failed with %d\n", ret);
atl_dev_err("AQ_API_SetIngressSCRecord failed with %d\n", ret);
return ret;
}
@ -924,10 +925,9 @@ static int atl_mdo_add_rxsc(struct macsec_context *ctx)
cfg->atl_rxsc[rxsc_idx].hw_sc_idx = to_hw_sc_idx(rxsc_idx, cfg->sc_sa);
cfg->atl_rxsc[rxsc_idx].sw_secy = ctx->secy;
cfg->atl_rxsc[rxsc_idx].sw_rxsc = ctx->rx_sc;
dev_dbg(&nic->hw.pdev->dev,
"add rxsc: rxsc_idx=%u, hw_sc_idx=%u, rxsc=%p\n", rxsc_idx,
cfg->atl_rxsc[rxsc_idx].hw_sc_idx,
cfg->atl_rxsc[rxsc_idx].sw_rxsc);
atl_nic_dbg("add rxsc: rxsc_idx=%u, hw_sc_idx=%u, rxsc=%p\n", rxsc_idx,
cfg->atl_rxsc[rxsc_idx].hw_sc_idx,
cfg->atl_rxsc[rxsc_idx].sw_rxsc);
if (netif_carrier_ok(nic->ndev) && netif_running(ctx->secy->netdev))
ret = atl_set_rxsc(&nic->hw, rxsc_idx);
@ -957,43 +957,63 @@ static int atl_mdo_upd_rxsc(struct macsec_context *ctx)
return 0;
}
static int atl_clear_rxsc(struct atl_hw *hw,
const struct atl_macsec_rxsc *rx_sc)
static int atl_clear_rxsc(struct atl_nic *nic, const int rxsc_idx,
enum atl_clear_type clear_type)
{
int rxsc_idx = atl_get_rxsc_idx_from_rxsc(hw, rx_sc->sw_rxsc);
AQ_API_SEC_IngressPreClassRecord pre_class_record = { 0 };
AQ_API_SEC_IngressSCRecord sc_record = { 0 };
int ret;
struct atl_hw *hw = &nic->hw;
struct atl_macsec_rxsc *rx_sc = &hw->macsec_cfg.atl_rxsc[rxsc_idx];
int ret = 0;
int sa_num;
ret = AQ_API_SetIngressPreClassRecord(hw, &pre_class_record,
2 * rxsc_idx);
if (ret) {
dev_err(&hw->pdev->dev,
"AQ_API_SetIngressPreClassRecord failed with %d\n",
ret);
return ret;
for_each_set_bit (sa_num, &rx_sc->rx_sa_idx_busy, ATL_MACSEC_MAX_SA) {
ret = atl_clear_rxsa(nic, rx_sc, sa_num, clear_type);
if (ret)
return ret;
}
ret = AQ_API_SetIngressPreClassRecord(hw, &pre_class_record,
2 * rxsc_idx + 1);
if (ret) {
dev_err(&hw->pdev->dev,
"AQ_API_SetIngressPreClassRecord failed with %d\n",
ret);
return ret;
if (clear_type & ATL_CLEAR_HW) {
AQ_API_SEC_IngressPreClassRecord pre_class_record = { 0 };
AQ_API_SEC_IngressSCRecord sc_record = { 0 };
ret = AQ_API_SetIngressPreClassRecord(hw, &pre_class_record,
2 * rxsc_idx);
if (ret) {
atl_dev_err(
"AQ_API_SetIngressPreClassRecord failed with %d\n",
ret);
return ret;
}
ret = AQ_API_SetIngressPreClassRecord(hw, &pre_class_record,
2 * rxsc_idx + 1);
if (ret) {
atl_dev_err(
"AQ_API_SetIngressPreClassRecord failed with %d\n",
ret);
return ret;
}
sc_record.fresh = 1;
ret = AQ_API_SetIngressSCRecord(hw, &sc_record,
rx_sc->hw_sc_idx);
if (ret)
return ret;
}
sc_record.fresh = 1;
return AQ_API_SetIngressSCRecord(hw, &sc_record, rx_sc->hw_sc_idx);
if (clear_type & ATL_CLEAR_SW) {
clear_bit(rxsc_idx, &hw->macsec_cfg.rxsc_idx_busy);
hw->macsec_cfg.atl_rxsc[rxsc_idx].sw_secy = NULL;
hw->macsec_cfg.atl_rxsc[rxsc_idx].sw_rxsc = NULL;
}
return ret;
}
static int atl_mdo_del_rxsc(struct macsec_context *ctx)
{
struct atl_nic *nic = netdev_priv(ctx->netdev);
int rxsc_idx = atl_get_rxsc_idx_from_rxsc(&nic->hw, ctx->rx_sc);
struct atl_macsec_cfg *cfg = &nic->hw.macsec_cfg;
struct atl_hw *hw = &nic->hw;
int ret = 0;
enum atl_clear_type clear_type = ATL_CLEAR_SW;
if (rxsc_idx < 0)
return -ENOENT;
@ -1002,13 +1022,9 @@ static int atl_mdo_del_rxsc(struct macsec_context *ctx)
return 0;
if (netif_carrier_ok(nic->ndev))
ret = atl_clear_rxsc(hw, &cfg->atl_rxsc[rxsc_idx]);
clear_type |= ATL_CLEAR_HW;
clear_bit(rxsc_idx, &cfg->rxsc_idx_busy);
cfg->atl_rxsc[rxsc_idx].sw_secy = NULL;
cfg->atl_rxsc[rxsc_idx].sw_rxsc = NULL;
return ret;
return atl_clear_rxsc(nic, rxsc_idx, clear_type);
}
static int atl_update_rxsa(struct atl_hw *hw, const unsigned int sc_idx,
@ -1021,8 +1037,8 @@ static int atl_update_rxsa(struct atl_hw *hw, const unsigned int sc_idx,
const int sa_idx = sc_idx | an;
int ret = 0;
dev_dbg(&hw->pdev->dev, "set rx_sa %d: active=%d, next_pn=%d\n", an,
rx_sa->active, rx_sa->next_pn);
atl_dev_dbg("set rx_sa %d: active=%d, next_pn=%d\n", an, rx_sa->active,
rx_sa->next_pn);
sa_record.valid = rx_sa->active;
sa_record.fresh = 1;
@ -1030,37 +1046,36 @@ static int atl_update_rxsa(struct atl_hw *hw, const unsigned int sc_idx,
ret = AQ_API_SetIngressSARecord(hw, &sa_record, sa_idx);
if (ret) {
dev_err(&hw->pdev->dev,
"AQ_API_SetIngressSARecord failed with %d\n", ret);
atl_dev_err("AQ_API_SetIngressSARecord failed with %d\n", ret);
return ret;
}
if (key) {
memcpy(&sa_key_record.key, key, secy->key_len);
if (!key)
return ret;
switch (secy->key_len) {
case ATL_MACSEC_KEY_LEN_128_BIT:
sa_key_record.key_len = 0;
break;
case ATL_MACSEC_KEY_LEN_192_BIT:
sa_key_record.key_len = 1;
break;
case ATL_MACSEC_KEY_LEN_256_BIT:
sa_key_record.key_len = 2;
break;
default:
return -1;
}
memcpy(&sa_key_record.key, key, secy->key_len);
atl_rotate_keys(&sa_key_record.key, secy->key_len);
ret = AQ_API_SetIngressSAKeyRecord(hw, &sa_key_record, sa_idx);
if (ret)
dev_err(&hw->pdev->dev,
"AQ_API_SetIngressSAKeyRecord failed with %d\n",
ret);
switch (secy->key_len) {
case ATL_MACSEC_KEY_LEN_128_BIT:
sa_key_record.key_len = 0;
break;
case ATL_MACSEC_KEY_LEN_192_BIT:
sa_key_record.key_len = 1;
break;
case ATL_MACSEC_KEY_LEN_256_BIT:
sa_key_record.key_len = 2;
break;
default:
return -1;
}
atl_rotate_keys(&sa_key_record.key, secy->key_len);
ret = AQ_API_SetIngressSAKeyRecord(hw, &sa_key_record, sa_idx);
if (ret)
atl_dev_err("AQ_API_SetIngressSAKeyRecord failed with %d\n",
ret);
return ret;
}
@ -1111,26 +1126,17 @@ static int atl_mdo_upd_rxsa(struct macsec_context *ctx)
return 0;
}
static int atl_mdo_del_rxsa(struct macsec_context *ctx)
static int atl_clear_rxsa(struct atl_nic *nic, struct atl_macsec_rxsc *atl_rxsc,
const int sa_num, enum atl_clear_type clear_type)
{
struct atl_nic *nic = netdev_priv(ctx->netdev);
const struct macsec_rx_sc *rx_sc = ctx->sa.rx_sa->sc;
const int rxsc_idx = atl_get_rxsc_idx_from_rxsc(&nic->hw, rx_sc);
int sa_idx = atl_rxsc->hw_sc_idx | sa_num;
struct atl_hw *hw = &nic->hw;
struct atl_macsec_rxsc *atl_rxsc = &hw->macsec_cfg.atl_rxsc[rxsc_idx];
int sa_idx;
int ret = 0;
WARN_ON(rxsc_idx < 0);
if (clear_type & ATL_CLEAR_SW)
clear_bit(sa_num, &atl_rxsc->rx_sa_idx_busy);
if (ctx->prepare)
return 0;
sa_idx = atl_rxsc->hw_sc_idx | ctx->sa.assoc_num;
clear_bit(ctx->sa.assoc_num, &atl_rxsc->rx_sa_idx_busy);
if (netif_carrier_ok(nic->ndev)) {
if ((clear_type & ATL_CLEAR_HW) && netif_carrier_ok(nic->ndev)) {
AQ_API_SEC_IngressSAKeyRecord sa_key_record = { 0 };
AQ_API_SEC_IngressSARecord sa_record = { 0 };
@ -1142,7 +1148,22 @@ static int atl_mdo_del_rxsa(struct macsec_context *ctx)
return AQ_API_SetIngressSAKeyRecord(hw, &sa_key_record, sa_idx);
}
return 0;
return ret;
}
static int atl_mdo_del_rxsa(struct macsec_context *ctx)
{
struct atl_nic *nic = netdev_priv(ctx->netdev);
const struct macsec_rx_sc *rx_sc = ctx->sa.rx_sa->sc;
const int rxsc_idx = atl_get_rxsc_idx_from_rxsc(&nic->hw, rx_sc);
WARN_ON(rxsc_idx < 0);
if (ctx->prepare)
return 0;
return atl_clear_rxsa(nic, &nic->hw.macsec_cfg.atl_rxsc[rxsc_idx],
ctx->sa.assoc_num, ATL_CLEAR_HW | ATL_CLEAR_SW);
}
static int atl_mdo_get_dev_stats(struct macsec_context *ctx)
@ -1346,6 +1367,36 @@ static int atl_macsec_apply_rxsc_cfg(struct atl_hw *hw, const int rxsc_idx)
return ret;
}
static int atl_clear_secy(struct atl_nic *nic, const struct macsec_secy *secy,
enum atl_clear_type clear_type)
{
int txsc_idx = atl_get_txsc_idx_from_secy(&nic->hw, secy);
struct atl_hw *hw = &nic->hw;
struct macsec_rx_sc *rx_sc;
int rxsc_idx;
int ret = 0;
if (txsc_idx >= 0) {
ret = atl_clear_txsc(nic, txsc_idx, clear_type);
if (ret)
return ret;
}
for (rx_sc = rcu_dereference_bh(secy->rx_sc); rx_sc;
rx_sc = rcu_dereference_bh(rx_sc->next)) {
rxsc_idx = atl_get_rxsc_idx_from_rxsc(hw, rx_sc);
WARN_ON(rxsc_idx < 0);
if (rxsc_idx < 0)
continue;
ret = atl_clear_rxsc(nic, rxsc_idx, clear_type);
if (ret)
return ret;
}
return ret;
}
static int atl_macsec_apply_secy_cfg(struct atl_hw *hw,
const struct macsec_secy *secy)
{
@ -1457,12 +1508,17 @@ void atl_macsec_check_txsa_expiration(struct atl_nic *nic)
enum atl_macsec_sc_sa sc_sa;
struct macsec_tx_sa *tx_sa;
unsigned char an = 0;
int ret;
int i;
sc_sa = hw->macsec_cfg.sc_sa;
AQ_API_GetEgressSAExpired(hw, &egress_sa_expired);
AQ_API_GetEgressSAThresholdExpired(hw, &egress_sa_threshold_expired);
ret = AQ_API_GetEgressSAExpired(hw, &egress_sa_expired);
if (unlikely(ret))
return;
ret = AQ_API_GetEgressSAThresholdExpired(hw,
&egress_sa_threshold_expired);
for (i = 0; i < ATL_MACSEC_MAX_SA; i++) {
if (egress_sa_expired & BIT(i)) {
@ -1484,6 +1540,13 @@ void atl_macsec_check_txsa_expiration(struct atl_nic *nic)
continue;
}
if (unlikely(!(atl_txsc->tx_sa_idx_busy & BIT(an)))) {
netdev_warn(
nic->ndev,
"PN threshold expired on invalid TX SA");
continue;
}
tx_sa = atl_txsc->sw_secy->tx_sc.sa[an];
spin_lock_bh(&tx_sa->lock);
@ -1496,7 +1559,9 @@ void atl_macsec_check_txsa_expiration(struct atl_nic *nic)
}
AQ_API_SetEgressSAExpired(hw, egress_sa_expired);
AQ_API_SetEgressSAThresholdExpired(hw, egress_sa_threshold_expired);
if (likely(!ret))
AQ_API_SetEgressSAThresholdExpired(hw,
egress_sa_threshold_expired);
}
void atl_macsec_work(struct atl_nic *nic)

View File

@ -0,0 +1,125 @@
/*
* aQuantia Corporation Network Driver
* Copyright (C) 2019 aQuantia Corporation. All rights reserved
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*/
#ifndef _ATL_MACSEC_H_
#define _ATL_MACSEC_H_
#include <linux/netdevice.h>
#ifdef NETIF_F_HW_MACSEC
#include "net/macsec.h"
#define ATL_MACSEC_MAX_SC 32
#define ATL_MACSEC_MAX_SA 32
enum atl_macsec_sc_sa {
atl_macsec_sa_sc_4sa_8sc,
atl_macsec_sa_sc_not_used,
atl_macsec_sa_sc_2sa_16sc,
atl_macsec_sa_sc_1sa_32sc,
};
struct atl_macsec_common_stats {
/* Ingress Common Counters */
struct {
uint64_t ctl_pkts;
uint64_t tagged_miss_pkts;
uint64_t untagged_miss_pkts;
uint64_t notag_pkts;
uint64_t untagged_pkts;
uint64_t bad_tag_pkts;
uint64_t no_sci_pkts;
uint64_t unknown_sci_pkts;
uint64_t ctrl_prt_pass_pkts;
uint64_t unctrl_prt_pass_pkts;
uint64_t ctrl_prt_fail_pkts;
uint64_t unctrl_prt_fail_pkts;
uint64_t too_long_pkts;
uint64_t igpoc_ctl_pkts;
uint64_t ecc_error_pkts;
uint64_t unctrl_hit_drop_redir;
} in;
/* Egress Common Counters */
struct {
uint64_t ctl_pkts;
uint64_t unknown_sa_pkts;
uint64_t untagged_pkts;
uint64_t too_long;
uint64_t ecc_error_pkts;
uint64_t unctrl_hit_drop_redir;
} out;
};
/* Ingress SA Counters */
struct atl_macsec_rx_sa_stats {
uint64_t untagged_hit_pkts;
uint64_t ctrl_hit_drop_redir_pkts;
uint64_t not_using_sa;
uint64_t unused_sa;
uint64_t not_valid_pkts;
uint64_t invalid_pkts;
uint64_t ok_pkts;
uint64_t late_pkts;
uint64_t delayed_pkts;
uint64_t unchecked_pkts;
uint64_t validated_octets;
uint64_t decrypted_octets;
};
/* Egress SA Counters */
struct atl_macsec_tx_sa_stats {
uint64_t sa_hit_drop_redirect;
uint64_t sa_protected2_pkts;
uint64_t sa_protected_pkts;
uint64_t sa_encrypted_pkts;
};
/* Egress SC Counters */
struct atl_macsec_tx_sc_stats {
uint64_t sc_protected_pkts;
uint64_t sc_encrypted_pkts;
uint64_t sc_protected_octets;
uint64_t sc_encrypted_octets;
};
struct atl_macsec_txsc {
uint32_t hw_sc_idx;
unsigned long tx_sa_idx_busy;
const struct macsec_secy *sw_secy;
/* It is not OK to store key in driver but it is until ... */
uint8_t tx_sa_key[MACSEC_NUM_AN][MACSEC_KEYID_LEN];
struct atl_macsec_tx_sc_stats stats;
struct atl_macsec_tx_sa_stats tx_sa_stats[MACSEC_NUM_AN];
};
struct atl_macsec_rxsc {
uint32_t hw_sc_idx;
unsigned long rx_sa_idx_busy;
const struct macsec_secy *sw_secy;
const struct macsec_rx_sc *sw_rxsc;
/* TODO: we shouldn't store keys in the driver */
uint8_t rx_sa_key[MACSEC_NUM_AN][MACSEC_KEYID_LEN];
struct atl_macsec_rx_sa_stats rx_sa_stats[MACSEC_NUM_AN];
};
struct atl_macsec_cfg {
enum atl_macsec_sc_sa sc_sa;
/* Egress channel configuration */
unsigned long txsc_idx_busy;
struct atl_macsec_txsc atl_txsc[ATL_MACSEC_MAX_SC];
/* Ingress channel configuration */
unsigned long rxsc_idx_busy;
struct atl_macsec_rxsc atl_rxsc[ATL_MACSEC_MAX_SC];
struct atl_macsec_common_stats stats;
};
#endif /* NETIF_F_HW_MACSEC */
#endif /* _ATL_MACSEC_H_ */

View File

@ -193,7 +193,7 @@ static int atl_set_mac_address(struct net_device *ndev, void *priv)
ether_addr_copy(hw->mac_addr, addr->sa_data);
ether_addr_copy(ndev->dev_addr, addr->sa_data);
if (netif_running(ndev))
if (netif_running(ndev) && pm_runtime_active(&nic->hw.pdev->dev))
atl_set_uc_flt(hw, 0, hw->mac_addr);
return 0;

View File

@ -0,0 +1,26 @@
/*
* aQuantia Corporation Network Driver
* Copyright (C) 2019 aQuantia Corporation. All rights reserved
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*/
#ifndef _ATL_MDIO_H_
#define _ATL_MDIO_H_
#include "atl_hw.h"
int atl_mdio_hwsem_get(struct atl_hw *hw);
void atl_mdio_hwsem_put(struct atl_hw *hw);
int __atl_mdio_read(struct atl_hw *hw, uint8_t prtad, uint8_t mmd,
uint16_t addr, uint16_t *val);
int atl_mdio_read(struct atl_hw *hw, uint8_t prtad, uint8_t mmd,
uint16_t addr, uint16_t *val);
int __atl_mdio_write(struct atl_hw *hw, uint8_t prtad, uint8_t mmd,
uint16_t addr, uint16_t val);
int atl_mdio_write(struct atl_hw *hw, uint8_t prtad, uint8_t mmd,
uint16_t addr, uint16_t val);
#endif /* _ATL_MDIO_H_ */

View File

@ -120,6 +120,7 @@ static netdev_tx_t atl_map_xmit_skb(struct sk_buff *skb,
desc->daddr = cpu_to_le64(daddr);
while (len > ATL_DATA_PER_TXD) {
desc->len = cpu_to_le16(ATL_DATA_PER_TXD);
trace_atl_tx_descr(ring->qvec->idx, idx, (u64 *)desc);
WRITE_ONCE(ring->hw.descs[idx].tx, *desc);
bump_ptr(idx, ring, 1);
daddr += ATL_DATA_PER_TXD;
@ -131,6 +132,7 @@ static netdev_tx_t atl_map_xmit_skb(struct sk_buff *skb,
if (!frags)
break;
trace_atl_tx_descr(ring->qvec->idx, idx, (u64 *)desc);
WRITE_ONCE(ring->hw.descs[idx].tx, *desc);
bump_ptr(idx, ring, 1);
txbuf = &ring->txbufs[idx];
@ -148,6 +150,7 @@ static netdev_tx_t atl_map_xmit_skb(struct sk_buff *skb,
#if defined(ATL_TX_DESC_WB) || defined(ATL_TX_HEAD_WB)
desc->cmd |= tx_desc_cmd_wb;
#endif
trace_atl_tx_descr(ring->qvec->idx, idx, (u64 *)desc);
WRITE_ONCE(ring->hw.descs[idx].tx, *desc);
first_buf->last = idx;
bump_ptr(idx, ring, 1);
@ -230,6 +233,7 @@ static uint32_t atl_insert_context(struct atl_txbuf *txbuf,
if (tx_cmd) {
ctx->type = tx_desc_type_context;
ctx->idx = 0;
trace_atl_tx_context_descr(ring->qvec->idx, ring->tail, (u64 *)ctx);
COMMIT_DESC(ring, ring->tail, scratch);
bump_tail(ring, 1);
}
@ -397,6 +401,7 @@ static bool atl_clean_tx(struct atl_desc_ring *ring)
/* work around HW bugs in checksum calculation:
* - packets less than 60 octets
* - ip, tcp or udp checksum is 0xFFFF
* - non-zero padding
*/
static bool atl_checksum_workaround(struct sk_buff *skb,
struct atl_rx_desc_wb *desc)
@ -404,19 +409,25 @@ static bool atl_checksum_workaround(struct sk_buff *skb,
int ip_header_offset = 14;
int l4_header_offset = 0;
struct iphdr *ip;
struct ipv6hdr *ipv6;
struct tcphdr *tcp;
struct udphdr *udp;
if (desc->pkt_len <= 60)
return true;
if ((desc->pkt_type & atl_rx_pkt_type_vlan_msk) ==
atl_rx_pkt_type_vlan)
ip_header_offset += 4;
if (((desc->pkt_type & atl_rx_pkt_type_vlan_msk) ==
atl_rx_pkt_type_vlan) &&
!(desc->rx_estat & atl_rx_estat_vlan_stripped))
ip_header_offset += sizeof(struct vlan_hdr);
if ((desc->pkt_type & atl_rx_pkt_type_vlan_msk) ==
atl_rx_pkt_type_dbl_vlan)
ip_header_offset += 8;
atl_rx_pkt_type_dbl_vlan) {
if (desc->rx_estat & atl_rx_estat_vlan_stripped)
ip_header_offset += sizeof(struct vlan_hdr);
else
ip_header_offset += sizeof(struct vlan_hdr) * 2;
}
switch (desc->pkt_type & atl_rx_pkt_type_l3_msk) {
case atl_rx_pkt_type_ipv4:
@ -425,9 +436,17 @@ static bool atl_checksum_workaround(struct sk_buff *skb,
if (ip->check == 0xFFFF)
return true;
l4_header_offset = ip->ihl << 2;
/* padding inside Ethernet frame */
if (ntohs(ip->tot_len) + ip_header_offset < desc->pkt_len)
return true;
break;
case atl_rx_pkt_type_ipv6:
ipv6 = (struct ipv6hdr *) &skb->data[ip_header_offset];
l4_header_offset = ip_header_offset + sizeof(struct ipv6hdr);
/* padding inside Ethernet frame */
if (ip_header_offset + sizeof(struct ipv6hdr) +
ntohs(ipv6->payload_len) < desc->pkt_len)
return true;
break;
default:
return false;
@ -446,6 +465,9 @@ static bool atl_checksum_workaround(struct sk_buff *skb,
l4_header_offset];
if (udp->check == 0xFFFF)
return true;
/* padding inside IP frame */
if (l4_header_offset + ntohs(udp->len) < desc->pkt_len)
return true;
break;
default:
return false;
@ -1069,6 +1091,8 @@ int atl_clean_rx(struct atl_desc_ring *ring, int budget,
break;
DESC_RMB();
trace_atl_rx_descr(ring->qvec->idx, ring->head, (u64 *)wb);
skb = atl_process_rx_frag(ring, rxbuf, wb);
/* Treat allocation errors as transient and retry later */

View File

@ -220,6 +220,49 @@ TRACE_EVENT(atl_tx_descr,
__entry->rsvd1, __entry->des_typ)
);
TRACE_EVENT(atl_tx_context_descr,
TP_PROTO(int ring_idx, unsigned int pointer, u64 *descr),
TP_ARGS(ring_idx, pointer, descr),
TP_STRUCT__entry(
__field(unsigned int, ring_idx)
__field(unsigned int, pointer)
/* Tx Context Descriptor */
__field(u16, out_len)
__field(u8, tun_len)
__field(u64, resvd3)
__field(u16, mss_len)
__field(u8, l4_len)
__field(u8, l3_len)
__field(u8, l2_len)
__field(u8, ct_cmd)
__field(u16, vlan_tag)
__field(u8, ct_idx)
__field(u8, des_typ)
),
TP_fast_assign(
__entry->ring_idx = ring_idx;
__entry->pointer = pointer;
__entry->out_len = DESCR_FIELD(descr[0], 63, 48);
__entry->tun_len = DESCR_FIELD(descr[0], 47, 40);
__entry->resvd3 = DESCR_FIELD(descr[0], 39, 0);
__entry->mss_len = DESCR_FIELD(descr[1], 63, 48);
__entry->l4_len = DESCR_FIELD(descr[1], 47, 40);
__entry->l3_len = DESCR_FIELD(descr[1], 39, 31);
__entry->l2_len = DESCR_FIELD(descr[1], 30, 24);
__entry->ct_cmd = DESCR_FIELD(descr[1], 23, 20);
__entry->vlan_tag = DESCR_FIELD(descr[1], 19, 4);
__entry->ct_idx = DESCR_FIELD(descr[1], 3, 3);
__entry->des_typ = DESCR_FIELD(descr[1], 2, 0);
),
TP_printk("ring=%d descr=%u out_len=%u tun_len=%u resvd3=%llu mss_len=%u l4_len=%u l3_len=%u l2_len=0x%x ct_cmd=%u vlan_tag=%u ct_idx=%u des_typ=0x%x",
__entry->ring_idx, __entry->pointer, __entry->out_len,
__entry->tun_len, __entry->resvd3, __entry->mss_len,
__entry->l4_len, __entry->l3_len, __entry->l2_len,
__entry->ct_cmd, __entry->vlan_tag, __entry->ct_idx,
__entry->des_typ)
);
#endif /* _ATL_TRACE_H */
#undef TRACE_INCLUDE_PATH

View File

@ -2,6 +2,7 @@
#include "macsec_api.h"
#include "MSS_Ingress_registers.h"
#include "MSS_Egress_registers.h"
#include "atl_mdio.h"
#define MMD_GLOBAL 0x1E
@ -66,6 +67,7 @@ int GetRawSECIngressRecordVal(struct atl_hw *hw, uint16_t* packedRecVal, uint8_t
{
struct mssIngressLutAddressControlRegister_t tableSelReg;
struct mssIngressLutControlRegister_t readWriteReg;
int ret;
unsigned int i;
@ -92,17 +94,25 @@ int GetRawSECIngressRecordVal(struct atl_hw *hw, uint16_t* packedRecVal, uint8_t
readWriteReg.bits_0.mssIngressLutWrite = 0;
/*Write register (EUR/CAL: 1E.8080) */
atl_mdio_write(hw, 0, MMD_GLOBAL, mssIngressLutAddressControlRegister_ADDR, tableSelReg.word_0);
ret = atl_mdio_write(hw, 0, MMD_GLOBAL, mssIngressLutAddressControlRegister_ADDR, tableSelReg.word_0);
if (unlikely(ret))
return ret;
/*Write register (EUR/CAL: 1E.8081) */
atl_mdio_write(hw, 0, MMD_GLOBAL, mssIngressLutControlRegister_ADDR, readWriteReg.word_0);
ret = atl_mdio_write(hw, 0, MMD_GLOBAL, mssIngressLutControlRegister_ADDR, readWriteReg.word_0);
if (unlikely(ret))
return ret;
memset(packedRecVal, 0, sizeof(uint16_t) * numWords);
/* Read the data buffer registers into the packed record words. */
for (i = 0; i < numWords; i += 2)
{
atl_mdio_read(hw, 0, MMD_GLOBAL, mssIngressLutDataControlRegister_ADDR + i, &packedRecVal[i]);
atl_mdio_read(hw, 0, MMD_GLOBAL, mssIngressLutDataControlRegister_ADDR + i + 1, &packedRecVal[i + 1]);
ret = atl_mdio_read(hw, 0, MMD_GLOBAL, mssIngressLutDataControlRegister_ADDR + i, &packedRecVal[i]);
if (unlikely(ret))
return ret;
ret = atl_mdio_read(hw, 0, MMD_GLOBAL, mssIngressLutDataControlRegister_ADDR + i + 1, &packedRecVal[i + 1]);
if (unlikely(ret))
return ret;
}
return 0;
@ -169,6 +179,7 @@ int GetRawSECEgressRecordVal(struct atl_hw *hw, uint16_t* packedRecVal, uint8_t
{
struct mssEgressLutAddressControlRegister_t tableSelReg;
struct mssEgressLutControlRegister_t readWriteReg;
int ret;
unsigned int i;
@ -199,17 +210,25 @@ int GetRawSECEgressRecordVal(struct atl_hw *hw, uint16_t* packedRecVal, uint8_t
readWriteReg.bits_0.mssEgressLutWrite = 0;
/*Write register (EUR/CAL: 1E.5080) */
atl_mdio_write(hw, 0, MMD_GLOBAL, mssEgressLutAddressControlRegister_ADDR, tableSelReg.word_0);
ret = atl_mdio_write(hw, 0, MMD_GLOBAL, mssEgressLutAddressControlRegister_ADDR, tableSelReg.word_0);
if (unlikely(ret))
return ret;
/*Write register (EUR/CAL: 1E.5081) */
atl_mdio_write(hw, 0, MMD_GLOBAL, mssEgressLutControlRegister_ADDR, readWriteReg.word_0);
ret = atl_mdio_write(hw, 0, MMD_GLOBAL, mssEgressLutControlRegister_ADDR, readWriteReg.word_0);
if (unlikely(ret))
return ret;
memset(packedRecVal, 0, sizeof(uint16_t) * numWords);
/* Read the data buffer registers into the packed record words. */
for (i = 0; i < numWords; i += 2)
{
atl_mdio_read(hw, 0, MMD_GLOBAL, mssEgressLutDataControlRegister_ADDR + i, &packedRecVal[i]);
atl_mdio_read(hw, 0, MMD_GLOBAL, mssEgressLutDataControlRegister_ADDR + i + 1, &packedRecVal[i + 1]);
ret = atl_mdio_read(hw, 0, MMD_GLOBAL, mssEgressLutDataControlRegister_ADDR + i, &packedRecVal[i]);
if (unlikely(ret))
return ret;
ret = atl_mdio_read(hw, 0, MMD_GLOBAL, mssEgressLutDataControlRegister_ADDR + i + 1, &packedRecVal[i + 1]);
if (unlikely(ret))
return ret;
}
return 0;
@ -232,14 +251,13 @@ int AQ_API_SetIngressPreCTLFRecord(struct atl_hw *hw, const AQ_API_SEC_IngressPr
packedRecVal[5] = (packedRecVal[5] & 0xFFF0) | (((rec->match_type >> 0) & 0xF) << 0);
packedRecVal[5] = (packedRecVal[5] & 0xFFEF) | (((rec->action >> 0) & 0x1) << 4);
SetRawSECIngressRecordVal(hw, packedRecVal, 6, 0, ROWOFFSET_INGRESSPRECTLFRECORD + tableIndex);
return 0;
return SetRawSECIngressRecordVal(hw, packedRecVal, 6, 0, ROWOFFSET_INGRESSPRECTLFRECORD + tableIndex);
}
int AQ_API_GetIngressPreCTLFRecord(struct atl_hw *hw, AQ_API_SEC_IngressPreCTLFRecord* rec, uint16_t tableIndex)
{
uint16_t packedRecVal[6];
int ret;
if (tableIndex >= NUMROWS_INGRESSPRECTLFRECORD)
return -EINVAL;
@ -251,12 +269,16 @@ int AQ_API_GetIngressPreCTLFRecord(struct atl_hw *hw, AQ_API_SEC_IngressPreCTLFR
* so don't bother; odd-numbered rows are not readable. */
if ((tableIndex % 2) > 0)
{
GetRawSECIngressRecordVal(hw, packedRecVal, 6, 0, ROWOFFSET_INGRESSPRECTLFRECORD + tableIndex - 1);
ret = GetRawSECIngressRecordVal(hw, packedRecVal, 6, 0, ROWOFFSET_INGRESSPRECTLFRECORD + tableIndex - 1);
if (unlikely(ret))
return ret;
}
memset(rec, 0, sizeof(AQ_API_SEC_IngressPreCTLFRecord));
GetRawSECIngressRecordVal(hw, packedRecVal, 6, 0, ROWOFFSET_INGRESSPRECTLFRECORD + tableIndex);
ret = GetRawSECIngressRecordVal(hw, packedRecVal, 6, 0, ROWOFFSET_INGRESSPRECTLFRECORD + tableIndex);
if (unlikely(ret))
return ret;
rec->sa_da[0] = (rec->sa_da[0] & 0xFFFF0000) | (((packedRecVal[0] >> 0) & 0xFFFF) << 0);
rec->sa_da[0] = (rec->sa_da[0] & 0x0000FFFF) | (((packedRecVal[1] >> 0) & 0xFFFF) << 16);
@ -352,14 +374,13 @@ int AQ_API_SetIngressPreClassRecord(struct atl_hw *hw, const AQ_API_SEC_IngressP
packedRecVal[19] = (packedRecVal[19] & 0xFF7F) | (((rec->valid >> 0) & 0x1) << 7);
SetRawSECIngressRecordVal(hw, packedRecVal, 20, 1, ROWOFFSET_INGRESSPRECLASSRECORD + tableIndex);
return 0;
return SetRawSECIngressRecordVal(hw, packedRecVal, 20, 1, ROWOFFSET_INGRESSPRECLASSRECORD + tableIndex);
}
int AQ_API_GetIngressPreClassRecord(struct atl_hw *hw, AQ_API_SEC_IngressPreClassRecord* rec, uint16_t tableIndex)
{
uint16_t packedRecVal[20];
int ret;
if (tableIndex >= NUMROWS_INGRESSPRECLASSRECORD)
return -EINVAL;
@ -371,13 +392,17 @@ int AQ_API_GetIngressPreClassRecord(struct atl_hw *hw, AQ_API_SEC_IngressPreClas
* so don't bother; odd-numbered rows are not readable. */
if ((tableIndex % 2) > 0)
{
GetRawSECIngressRecordVal(hw, packedRecVal, 20, 1,
ROWOFFSET_INGRESSPRECLASSRECORD + tableIndex - 1);
ret = GetRawSECIngressRecordVal(hw, packedRecVal, 20, 1,
ROWOFFSET_INGRESSPRECLASSRECORD + tableIndex - 1);
if (unlikely(ret))
return ret;
}
memset(rec, 0, sizeof(AQ_API_SEC_IngressPreClassRecord));
GetRawSECIngressRecordVal(hw, packedRecVal, 20, 1, ROWOFFSET_INGRESSPRECLASSRECORD + tableIndex);
ret = GetRawSECIngressRecordVal(hw, packedRecVal, 20, 1, ROWOFFSET_INGRESSPRECLASSRECORD + tableIndex);
if (unlikely(ret))
return ret;
rec->sci[0] = (rec->sci[0] & 0xFFFF0000) | (((packedRecVal[0] >> 0) & 0xFFFF) << 0);
rec->sci[0] = (rec->sci[0] & 0x0000FFFF) | (((packedRecVal[1] >> 0) & 0xFFFF) << 16);
@ -486,21 +511,22 @@ int AQ_API_SetIngressSCRecord(struct atl_hw *hw, const AQ_API_SEC_IngressSCRecor
packedRecVal[7] = (packedRecVal[7] & 0x7FFF) | (((rec->valid >> 0) & 0x1) << 15);
SetRawSECIngressRecordVal(hw, packedRecVal, 8, 3, ROWOFFSET_INGRESSSCRECORD + tableIndex);
return 0;
return SetRawSECIngressRecordVal(hw, packedRecVal, 8, 3, ROWOFFSET_INGRESSSCRECORD + tableIndex);
}
int AQ_API_GetIngressSCRecord(struct atl_hw *hw, AQ_API_SEC_IngressSCRecord* rec, uint16_t tableIndex)
{
uint16_t packedRecVal[8];
int ret;
if (tableIndex >= NUMROWS_INGRESSSCRECORD)
return -EINVAL;
memset(rec, 0, sizeof(AQ_API_SEC_IngressSCRecord));
GetRawSECIngressRecordVal(hw, packedRecVal, 8, 3, ROWOFFSET_INGRESSSCRECORD + tableIndex);
ret = GetRawSECIngressRecordVal(hw, packedRecVal, 8, 3, ROWOFFSET_INGRESSSCRECORD + tableIndex);
if (unlikely(ret))
return ret;
rec->stop_time = (rec->stop_time & 0xFFFF0000) | (((packedRecVal[0] >> 0) & 0xFFFF) << 0);
rec->stop_time = (rec->stop_time & 0x0000FFFF) | (((packedRecVal[1] >> 0) & 0xFFFF) << 16);
@ -559,21 +585,22 @@ int AQ_API_SetIngressSARecord(struct atl_hw *hw, const AQ_API_SEC_IngressSARecor
packedRecVal[7] = (packedRecVal[7] & 0x7FFF) | (((rec->valid >> 0) & 0x1) << 15);
SetRawSECIngressRecordVal(hw, packedRecVal, 8, 3, ROWOFFSET_INGRESSSARECORD + tableIndex);
return 0;
return SetRawSECIngressRecordVal(hw, packedRecVal, 8, 3, ROWOFFSET_INGRESSSARECORD + tableIndex);
}
int AQ_API_GetIngressSARecord(struct atl_hw *hw, AQ_API_SEC_IngressSARecord* rec, uint16_t tableIndex)
{
uint16_t packedRecVal[8];
int ret;
if (tableIndex >= NUMROWS_INGRESSSARECORD)
return -EINVAL;
memset(rec, 0, sizeof(AQ_API_SEC_IngressSARecord));
GetRawSECIngressRecordVal(hw, packedRecVal, 8, 3, ROWOFFSET_INGRESSSARECORD + tableIndex);
ret = GetRawSECIngressRecordVal(hw, packedRecVal, 8, 3, ROWOFFSET_INGRESSSARECORD + tableIndex);
if (unlikely(ret))
return ret;
rec->stop_time = (rec->stop_time & 0xFFFF0000) | (((packedRecVal[0] >> 0) & 0xFFFF) << 0);
rec->stop_time = (rec->stop_time & 0x0000FFFF) | (((packedRecVal[1] >> 0) & 0xFFFF) << 16);
@ -633,21 +660,22 @@ int AQ_API_SetIngressSAKeyRecord(struct atl_hw *hw, const AQ_API_SEC_IngressSAKe
packedRecVal[16] = (packedRecVal[16] & 0xFFFC) | (((rec->key_len >> 0) & 0x3) << 0);
SetRawSECIngressRecordVal(hw, packedRecVal, 18, 2, ROWOFFSET_INGRESSSAKEYRECORD + tableIndex);
return 0;
return SetRawSECIngressRecordVal(hw, packedRecVal, 18, 2, ROWOFFSET_INGRESSSAKEYRECORD + tableIndex);
}
int AQ_API_GetIngressSAKeyRecord(struct atl_hw *hw, AQ_API_SEC_IngressSAKeyRecord* rec, uint16_t tableIndex)
{
uint16_t packedRecVal[18];
int ret;
if (tableIndex >= NUMROWS_INGRESSSAKEYRECORD)
return -EINVAL;
memset(rec, 0, sizeof(AQ_API_SEC_IngressSAKeyRecord));
GetRawSECIngressRecordVal(hw, packedRecVal, 18, 2, ROWOFFSET_INGRESSSAKEYRECORD + tableIndex);
ret = GetRawSECIngressRecordVal(hw, packedRecVal, 18, 2, ROWOFFSET_INGRESSSAKEYRECORD + tableIndex);
if (unlikely(ret))
return ret;
rec->key[0] = (rec->key[0] & 0xFFFF0000) | (((packedRecVal[0] >> 0) & 0xFFFF) << 0);
rec->key[0] = (rec->key[0] & 0x0000FFFF) | (((packedRecVal[1] >> 0) & 0xFFFF) << 16);
@ -750,14 +778,13 @@ int AQ_API_SetIngressPostClassRecord(struct atl_hw *hw, const AQ_API_SEC_Ingress
packedRecVal[7] = (packedRecVal[7] & 0x7FFF) | (((rec->valid >> 0) & 0x1) << 15);
SetRawSECIngressRecordVal(hw, packedRecVal, 8, 4, ROWOFFSET_INGRESSPOSTCLASSRECORD + tableIndex);
return 0;
return SetRawSECIngressRecordVal(hw, packedRecVal, 8, 4, ROWOFFSET_INGRESSPOSTCLASSRECORD + tableIndex);
}
int AQ_API_GetIngressPostClassRecord(struct atl_hw *hw, AQ_API_SEC_IngressPostClassRecord* rec, uint16_t tableIndex)
{
uint16_t packedRecVal[8];
int ret;
if (tableIndex >= NUMROWS_INGRESSPOSTCLASSRECORD)
return -EINVAL;
@ -769,12 +796,16 @@ int AQ_API_GetIngressPostClassRecord(struct atl_hw *hw, AQ_API_SEC_IngressPostCl
* so don't bother; odd-numbered rows are not readable. */
if ((tableIndex % 2) > 0)
{
GetRawSECIngressRecordVal(hw, packedRecVal, 8, 4, ROWOFFSET_INGRESSPOSTCLASSRECORD + tableIndex - 1);
ret = GetRawSECIngressRecordVal(hw, packedRecVal, 8, 4, ROWOFFSET_INGRESSPOSTCLASSRECORD + tableIndex - 1);
if (unlikely(ret))
return ret;
}
memset(rec, 0, sizeof(AQ_API_SEC_IngressPostClassRecord));
GetRawSECIngressRecordVal(hw, packedRecVal, 8, 4, ROWOFFSET_INGRESSPOSTCLASSRECORD + tableIndex);
ret = GetRawSECIngressRecordVal(hw, packedRecVal, 8, 4, ROWOFFSET_INGRESSPOSTCLASSRECORD + tableIndex);
if (unlikely(ret))
return ret;
rec->byte0 = (rec->byte0 & 0xFFFFFF00) | (((packedRecVal[0] >> 0) & 0xFF) << 0);
@ -865,14 +896,13 @@ int AQ_API_SetIngressPostCTLFRecord(struct atl_hw *hw, const AQ_API_SEC_IngressP
packedRecVal[5] = (packedRecVal[5] & 0xFFEF) | (((rec->action >> 0) & 0x1) << 4);
SetRawSECIngressRecordVal(hw, packedRecVal, 6, 5, ROWOFFSET_INGRESSPOSTCTLFRECORD + tableIndex);
return 0;
return SetRawSECIngressRecordVal(hw, packedRecVal, 6, 5, ROWOFFSET_INGRESSPOSTCTLFRECORD + tableIndex);
}
int AQ_API_GetIngressPostCTLFRecord(struct atl_hw *hw, AQ_API_SEC_IngressPostCTLFRecord* rec, uint16_t tableIndex)
{
uint16_t packedRecVal[6];
int ret;
if (tableIndex >= NUMROWS_INGRESSPOSTCTLFRECORD)
return -EINVAL;
@ -884,12 +914,16 @@ int AQ_API_GetIngressPostCTLFRecord(struct atl_hw *hw, AQ_API_SEC_IngressPostCTL
* so don't bother; odd-numbered rows are not readable. */
if ((tableIndex % 2) > 0)
{
GetRawSECIngressRecordVal(hw, packedRecVal, 6, 5, ROWOFFSET_INGRESSPOSTCTLFRECORD + tableIndex - 1);
ret = GetRawSECIngressRecordVal(hw, packedRecVal, 6, 5, ROWOFFSET_INGRESSPOSTCTLFRECORD + tableIndex - 1);
if (unlikely(ret))
return ret;
}
memset(rec, 0, sizeof(AQ_API_SEC_IngressPostCTLFRecord));
GetRawSECIngressRecordVal(hw, packedRecVal, 6, 5, ROWOFFSET_INGRESSPOSTCTLFRECORD + tableIndex);
ret = GetRawSECIngressRecordVal(hw, packedRecVal, 6, 5, ROWOFFSET_INGRESSPOSTCTLFRECORD + tableIndex);
if (unlikely(ret))
return ret;
rec->sa_da[0] = (rec->sa_da[0] & 0xFFFF0000) | (((packedRecVal[0] >> 0) & 0xFFFF) << 0);
rec->sa_da[0] = (rec->sa_da[0] & 0x0000FFFF) | (((packedRecVal[1] >> 0) & 0xFFFF) << 16);
@ -929,14 +963,13 @@ int AQ_API_SetEgressCTLFRecord(struct atl_hw *hw, const AQ_API_SEC_EgressCTLFRec
packedRecVal[5] = (packedRecVal[5] & 0xFFEF) | (((rec->action >> 0) & 0x1) << 4);
SetRawSECEgressRecordVal(hw, packedRecVal, 6, 0, ROWOFFSET_EGRESSCTLFRECORD + tableIndex);
return 0;
return SetRawSECEgressRecordVal(hw, packedRecVal, 6, 0, ROWOFFSET_EGRESSCTLFRECORD + tableIndex);
}
int AQ_API_GetEgressCTLFRecord(struct atl_hw *hw, AQ_API_SEC_EgressCTLFRecord* rec, uint16_t tableIndex)
{
uint16_t packedRecVal[6];
int ret;
if (tableIndex >= NUMROWS_EGRESSCTLFRECORD)
return -EINVAL;
@ -948,12 +981,16 @@ int AQ_API_GetEgressCTLFRecord(struct atl_hw *hw, AQ_API_SEC_EgressCTLFRecord* r
* so don't bother; odd-numbered rows are not readable. */
if ((tableIndex % 2) > 0)
{
GetRawSECEgressRecordVal(hw, packedRecVal, 6, 0, ROWOFFSET_EGRESSCTLFRECORD + tableIndex - 1);
ret = GetRawSECEgressRecordVal(hw, packedRecVal, 6, 0, ROWOFFSET_EGRESSCTLFRECORD + tableIndex - 1);
if (unlikely(ret))
return ret;
}
memset(rec, 0, sizeof(AQ_API_SEC_EgressCTLFRecord));
GetRawSECEgressRecordVal(hw, packedRecVal, 6, 0, ROWOFFSET_EGRESSCTLFRECORD + tableIndex);
ret = GetRawSECEgressRecordVal(hw, packedRecVal, 6, 0, ROWOFFSET_EGRESSCTLFRECORD + tableIndex);
if (unlikely(ret))
return ret;
rec->sa_da[0] = (rec->sa_da[0] & 0xFFFF0000) | (((packedRecVal[0] >> 0) & 0xFFFF) << 0);
rec->sa_da[0] = (rec->sa_da[0] & 0x0000FFFF) | (((packedRecVal[1] >> 0) & 0xFFFF) << 16);
@ -1094,14 +1131,13 @@ int AQ_API_SetEgressClassRecord(struct atl_hw *hw, const AQ_API_SEC_EgressClassR
packedRecVal[26] = (packedRecVal[26] & 0xFFF7) | (((rec->valid >> 0) & 0x1) << 3);
SetRawSECEgressRecordVal(hw, packedRecVal, 28, 1, ROWOFFSET_EGRESSCLASSRECORD + tableIndex);
return 0;
return SetRawSECEgressRecordVal(hw, packedRecVal, 28, 1, ROWOFFSET_EGRESSCLASSRECORD + tableIndex);
}
int AQ_API_GetEgressClassRecord(struct atl_hw *hw, AQ_API_SEC_EgressClassRecord* rec, uint16_t tableIndex)
{
uint16_t packedRecVal[28];
int ret;
if (tableIndex >= NUMROWS_EGRESSCLASSRECORD)
return -EINVAL;
@ -1112,12 +1148,16 @@ int AQ_API_GetEgressClassRecord(struct atl_hw *hw, AQ_API_SEC_EgressClassRecord*
* odd-numbered rows. For HHD devices: this workaround will not work,
* so don't bother; odd-numbered rows are not readable. */
if ((tableIndex % 2) > 0) {
GetRawSECEgressRecordVal(hw, packedRecVal, 28, 1, ROWOFFSET_EGRESSCLASSRECORD + tableIndex - 1);
ret = GetRawSECEgressRecordVal(hw, packedRecVal, 28, 1, ROWOFFSET_EGRESSCLASSRECORD + tableIndex - 1);
if (unlikely(ret))
return ret;
}
memset(rec, 0, sizeof(AQ_API_SEC_EgressClassRecord));
GetRawSECEgressRecordVal(hw, packedRecVal, 28, 1, ROWOFFSET_EGRESSCLASSRECORD + tableIndex);
ret = GetRawSECEgressRecordVal(hw, packedRecVal, 28, 1, ROWOFFSET_EGRESSCLASSRECORD + tableIndex);
if (unlikely(ret))
return ret;
rec->vlan_id = (rec->vlan_id & 0xFFFFF000) | (((packedRecVal[0] >> 0) & 0xFFF) << 0);
@ -1270,21 +1310,22 @@ int AQ_API_SetEgressSCRecord(struct atl_hw *hw, const AQ_API_SEC_EgressSCRecord*
packedRecVal[7] = (packedRecVal[7] & 0x7FFF) | (((rec->valid >> 0) & 0x1) << 15);
SetRawSECEgressRecordVal(hw, packedRecVal, 8, 2, ROWOFFSET_EGRESSSCRECORD + tableIndex);
return 0;
return SetRawSECEgressRecordVal(hw, packedRecVal, 8, 2, ROWOFFSET_EGRESSSCRECORD + tableIndex);
}
int AQ_API_GetEgressSCRecord(struct atl_hw *hw, AQ_API_SEC_EgressSCRecord* rec, uint16_t tableIndex)
{
uint16_t packedRecVal[8];
int ret;
if (tableIndex >= NUMROWS_EGRESSSCRECORD)
return -EINVAL;
memset(rec, 0, sizeof(AQ_API_SEC_EgressSCRecord));
GetRawSECEgressRecordVal(hw, packedRecVal, 8, 2, ROWOFFSET_EGRESSSCRECORD + tableIndex);
ret = GetRawSECEgressRecordVal(hw, packedRecVal, 8, 2, ROWOFFSET_EGRESSSCRECORD + tableIndex);
if (unlikely(ret))
return ret;
rec->start_time = (rec->start_time & 0xFFFF0000) | (((packedRecVal[0] >> 0) & 0xFFFF) << 0);
rec->start_time = (rec->start_time & 0x0000FFFF) | (((packedRecVal[1] >> 0) & 0xFFFF) << 16);
@ -1338,21 +1379,22 @@ int AQ_API_SetEgressSARecord(struct atl_hw *hw, const AQ_API_SEC_EgressSARecord*
packedRecVal[7] = (packedRecVal[7] & 0x7FFF) | (((rec->valid >> 0) & 0x1) << 15);
SetRawSECEgressRecordVal(hw, packedRecVal, 8, 2, ROWOFFSET_EGRESSSARECORD + tableIndex);
return 0;
return SetRawSECEgressRecordVal(hw, packedRecVal, 8, 2, ROWOFFSET_EGRESSSARECORD + tableIndex);
}
int AQ_API_GetEgressSARecord(struct atl_hw *hw, AQ_API_SEC_EgressSARecord* rec, uint16_t tableIndex)
{
uint16_t packedRecVal[8];
int ret;
if (tableIndex >= NUMROWS_EGRESSSARECORD)
return -EINVAL;
memset(rec, 0, sizeof(AQ_API_SEC_EgressSARecord));
GetRawSECEgressRecordVal(hw, packedRecVal, 8, 2, ROWOFFSET_EGRESSSARECORD + tableIndex);
ret = GetRawSECEgressRecordVal(hw, packedRecVal, 8, 2, ROWOFFSET_EGRESSSARECORD + tableIndex);
if (unlikely(ret))
return ret;
rec->start_time = (rec->start_time & 0xFFFF0000) | (((packedRecVal[0] >> 0) & 0xFFFF) << 0);
rec->start_time = (rec->start_time & 0x0000FFFF) | (((packedRecVal[1] >> 0) & 0xFFFF) << 16);
@ -1375,6 +1417,7 @@ int AQ_API_GetEgressSARecord(struct atl_hw *hw, AQ_API_SEC_EgressSARecord* rec,
int AQ_API_SetEgressSAKeyRecord(struct atl_hw *hw, const AQ_API_SEC_EgressSAKeyRecord* rec, uint16_t tableIndex)
{
uint16_t packedRecVal[16];
int ret;
if (tableIndex >= NUMROWS_EGRESSSAKEYRECORD)
return -EINVAL;
@ -1405,8 +1448,12 @@ int AQ_API_SetEgressSAKeyRecord(struct atl_hw *hw, const AQ_API_SEC_EgressSAKeyR
packedRecVal[14] = (packedRecVal[14] & 0x0000) | (((rec->key[7] >> 0) & 0xFFFF) << 0);
packedRecVal[15] = (packedRecVal[15] & 0x0000) | (((rec->key[7] >> 16) & 0xFFFF) << 0);
SetRawSECEgressRecordVal(hw, packedRecVal, 8, 2, ROWOFFSET_EGRESSSAKEYRECORD + tableIndex);
SetRawSECEgressRecordVal(hw, packedRecVal + 8, 8, 2, ROWOFFSET_EGRESSSAKEYRECORD + tableIndex - 32);
ret = SetRawSECEgressRecordVal(hw, packedRecVal, 8, 2, ROWOFFSET_EGRESSSAKEYRECORD + tableIndex);
if (unlikely(ret))
return ret;
ret = SetRawSECEgressRecordVal(hw, packedRecVal + 8, 8, 2, ROWOFFSET_EGRESSSAKEYRECORD + tableIndex - 32);
if (unlikely(ret))
return ret;
return 0;
}
@ -1414,14 +1461,19 @@ int AQ_API_SetEgressSAKeyRecord(struct atl_hw *hw, const AQ_API_SEC_EgressSAKeyR
int AQ_API_GetEgressSAKeyRecord(struct atl_hw *hw, AQ_API_SEC_EgressSAKeyRecord* rec, uint16_t tableIndex)
{
uint16_t packedRecVal[16];
int ret;
if (tableIndex >= NUMROWS_EGRESSSAKEYRECORD)
return -EINVAL;
memset(rec, 0, sizeof(AQ_API_SEC_EgressSAKeyRecord));
GetRawSECEgressRecordVal(hw, packedRecVal, 8, 2, ROWOFFSET_EGRESSSAKEYRECORD + tableIndex);
GetRawSECEgressRecordVal(hw, packedRecVal + 8, 8, 2, ROWOFFSET_EGRESSSAKEYRECORD + tableIndex - 32);
ret = GetRawSECEgressRecordVal(hw, packedRecVal, 8, 2, ROWOFFSET_EGRESSSAKEYRECORD + tableIndex);
if (unlikely(ret))
return ret;
ret = GetRawSECEgressRecordVal(hw, packedRecVal + 8, 8, 2, ROWOFFSET_EGRESSSAKEYRECORD + tableIndex - 32);
if (unlikely(ret))
return ret;
rec->key[0] = (rec->key[0] & 0xFFFF0000) | (((packedRecVal[0] >> 0) & 0xFFFF) << 0);
rec->key[0] = (rec->key[0] & 0x0000FFFF) | (((packedRecVal[1] >> 0) & 0xFFFF) << 16);
@ -1453,25 +1505,34 @@ int AQ_API_GetEgressSAKeyRecord(struct atl_hw *hw, AQ_API_SEC_EgressSAKeyRecord*
int AQ_API_GetEgressSCCounters(struct atl_hw *hw, AQ_API_SEC_EgressSCCounters* counters, uint16_t SCIndex)
{
uint16_t packedRecVal[4];
int ret;
if (SCIndex >= NUMROWS_EGRESSSCRECORD)
return -EINVAL;
memset(counters, 0, sizeof(AQ_API_SEC_EgressSCCounters));
GetRawSECEgressRecordVal(hw, packedRecVal, 4, 3, SCIndex * 8 + 4);
ret = GetRawSECEgressRecordVal(hw, packedRecVal, 4, 3, SCIndex * 8 + 4);
if (unlikely(ret))
return ret;
counters->sc_protected_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
counters->sc_protected_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
GetRawSECEgressRecordVal(hw, packedRecVal, 4, 3, SCIndex * 8 + 5);
ret = GetRawSECEgressRecordVal(hw, packedRecVal, 4, 3, SCIndex * 8 + 5);
if (unlikely(ret))
return ret;
counters->sc_encrypted_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
counters->sc_encrypted_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
GetRawSECEgressRecordVal(hw, packedRecVal, 4, 3, SCIndex * 8 + 6);
ret = GetRawSECEgressRecordVal(hw, packedRecVal, 4, 3, SCIndex * 8 + 6);
if (unlikely(ret))
return ret;
counters->sc_protected_octets[0] = packedRecVal[0] | (packedRecVal[1] << 16);
counters->sc_protected_octets[1] = packedRecVal[2] | (packedRecVal[3] << 16);
GetRawSECEgressRecordVal(hw, packedRecVal, 4, 3, SCIndex * 8 + 7);
ret = GetRawSECEgressRecordVal(hw, packedRecVal, 4, 3, SCIndex * 8 + 7);
if (unlikely(ret))
return ret;
counters->sc_encrypted_octets[0] = packedRecVal[0] | (packedRecVal[1] << 16);
counters->sc_encrypted_octets[1] = packedRecVal[2] | (packedRecVal[3] << 16);
@ -1481,25 +1542,34 @@ int AQ_API_GetEgressSCCounters(struct atl_hw *hw, AQ_API_SEC_EgressSCCounters* c
int AQ_API_GetEgressSACounters(struct atl_hw *hw, AQ_API_SEC_EgressSACounters* counters, uint16_t SAIndex)
{
uint16_t packedRecVal[4];
int ret;
if (SAIndex >= NUMROWS_EGRESSSARECORD)
return -EINVAL;
memset(counters, 0, sizeof(AQ_API_SEC_EgressSACounters));
GetRawSECEgressRecordVal(hw, packedRecVal, 4, 3, SAIndex * 8 + 0);
ret = GetRawSECEgressRecordVal(hw, packedRecVal, 4, 3, SAIndex * 8 + 0);
if (unlikely(ret))
return ret;
counters->sa_hit_drop_redirect[0] = packedRecVal[0] | (packedRecVal[1] << 16);
counters->sa_hit_drop_redirect[1] = packedRecVal[2] | (packedRecVal[3] << 16);
GetRawSECEgressRecordVal(hw, packedRecVal, 4, 3, SAIndex * 8 + 1);
ret = GetRawSECEgressRecordVal(hw, packedRecVal, 4, 3, SAIndex * 8 + 1);
if (unlikely(ret))
return ret;
counters->sa_protected2_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
counters->sa_protected2_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
GetRawSECEgressRecordVal(hw, packedRecVal, 4, 3, SAIndex * 8 + 2);
ret = GetRawSECEgressRecordVal(hw, packedRecVal, 4, 3, SAIndex * 8 + 2);
if (unlikely(ret))
return ret;
counters->sa_protected_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
counters->sa_protected_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
GetRawSECEgressRecordVal(hw, packedRecVal, 4, 3, SAIndex * 8 + 3);
ret = GetRawSECEgressRecordVal(hw, packedRecVal, 4, 3, SAIndex * 8 + 3);
if (unlikely(ret))
return ret;
counters->sa_encrypted_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
counters->sa_encrypted_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
@ -1509,30 +1579,43 @@ int AQ_API_GetEgressSACounters(struct atl_hw *hw, AQ_API_SEC_EgressSACounters* c
int AQ_API_GetEgressCommonCounters(struct atl_hw *hw, AQ_API_SEC_EgressCommonCounters* counters)
{
uint16_t packedRecVal[4];
int ret;
memset(counters, 0, sizeof(AQ_API_SEC_EgressCommonCounters));
GetRawSECEgressRecordVal(hw, packedRecVal, 4, 3, 256 + 0);
ret = GetRawSECEgressRecordVal(hw, packedRecVal, 4, 3, 256 + 0);
if (unlikely(ret))
return ret;
counters->ctl_pkt[0] = packedRecVal[0] | (packedRecVal[1] << 16);
counters->ctl_pkt[1] = packedRecVal[2] | (packedRecVal[3] << 16);
GetRawSECEgressRecordVal(hw, packedRecVal, 4, 3, 256 + 1);
ret = GetRawSECEgressRecordVal(hw, packedRecVal, 4, 3, 256 + 1);
if (unlikely(ret))
return ret;
counters->unknown_sa_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
counters->unknown_sa_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
GetRawSECEgressRecordVal(hw, packedRecVal, 4, 3, 256 + 2);
ret = GetRawSECEgressRecordVal(hw, packedRecVal, 4, 3, 256 + 2);
if (unlikely(ret))
return ret;
counters->untagged_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
counters->untagged_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
GetRawSECEgressRecordVal(hw, packedRecVal, 4, 3, 256 + 3);
ret = GetRawSECEgressRecordVal(hw, packedRecVal, 4, 3, 256 + 3);
if (unlikely(ret))
return ret;
counters->too_long[0] = packedRecVal[0] | (packedRecVal[1] << 16);
counters->too_long[1] = packedRecVal[2] | (packedRecVal[3] << 16);
GetRawSECEgressRecordVal(hw, packedRecVal, 4, 3, 256 + 4);
ret = GetRawSECEgressRecordVal(hw, packedRecVal, 4, 3, 256 + 4);
if (unlikely(ret))
return ret;
counters->ecc_error_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
counters->ecc_error_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
GetRawSECEgressRecordVal(hw, packedRecVal, 4, 3, 256 + 5);
ret = GetRawSECEgressRecordVal(hw, packedRecVal, 4, 3, 256 + 5);
if (unlikely(ret))
return ret;
counters->unctrl_hit_drop_redir[0] = packedRecVal[0] | (packedRecVal[1] << 16);
counters->unctrl_hit_drop_redir[1] = packedRecVal[2] | (packedRecVal[3] << 16);
@ -1542,6 +1625,7 @@ int AQ_API_GetEgressCommonCounters(struct atl_hw *hw, AQ_API_SEC_EgressCommonCou
int AQ_API_ClearEgressCounters(struct atl_hw *hw)
{
struct mssEgressControlRegister_t controlReg;
int ret;
memset(&controlReg, 0, sizeof(struct mssEgressControlRegister_t));
@ -1556,9 +1640,13 @@ int AQ_API_ClearEgressCounters(struct atl_hw *hw)
/* Toggle the Egress MIB clear bit 0->1->0 */
/*Read register (EUR/CAL: 1E.5002) */
atl_mdio_read(hw, 0, MMD_GLOBAL, mssEgressControlRegister_ADDR, &controlReg.word_0);
ret = atl_mdio_read(hw, 0, MMD_GLOBAL, mssEgressControlRegister_ADDR, &controlReg.word_0);
if (unlikely(ret))
return ret;
/*Read register (EUR/CAL: 1E.5002 + 1) */
atl_mdio_read(hw, 0, MMD_GLOBAL, mssEgressControlRegister_ADDR + 4, &controlReg.word_1);
ret = atl_mdio_read(hw, 0, MMD_GLOBAL, mssEgressControlRegister_ADDR + 4, &controlReg.word_1);
if (unlikely(ret))
return ret;
/*Assign to local representation of bitfield (EUR/CAL: 1E.5002.B) */
controlReg.bits_0.mssEgressClearCounter = 0;
@ -1567,25 +1655,37 @@ int AQ_API_ClearEgressCounters(struct atl_hw *hw)
//controlReg.bits_1.mssEgressClearCounter = 0;
/*Write register (EUR/CAL: 1E.5002) */
atl_mdio_write(hw, 0, MMD_GLOBAL, mssEgressControlRegister_ADDR, controlReg.word_0);
ret = atl_mdio_write(hw, 0, MMD_GLOBAL, mssEgressControlRegister_ADDR, controlReg.word_0);
if (unlikely(ret))
return ret;
/*Write register (EUR/CAL: 1E.5002 + 1) */
atl_mdio_write(hw, 0, MMD_GLOBAL, mssEgressControlRegister_ADDR + 4, controlReg.word_1);
ret = atl_mdio_write(hw, 0, MMD_GLOBAL, mssEgressControlRegister_ADDR + 4, controlReg.word_1);
if (unlikely(ret))
return ret;
/*Assign to local representation of bitfield (EUR/CAL: 1E.5002.B) */
controlReg.bits_0.mssEgressClearCounter = 1;
//controlReg.bits_1.mssEgressClearCounter = 1;
/*Write register (EUR/CAL: 1E.5002) */
atl_mdio_write(hw, 0, MMD_GLOBAL, mssEgressControlRegister_ADDR, controlReg.word_0);
ret = atl_mdio_write(hw, 0, MMD_GLOBAL, mssEgressControlRegister_ADDR, controlReg.word_0);
if (unlikely(ret))
return ret;
/*Write register (EUR/CAL: 1E.5002 + 1) */
atl_mdio_write(hw, 0, MMD_GLOBAL, mssEgressControlRegister_ADDR + 4, controlReg.word_1);
ret = atl_mdio_write(hw, 0, MMD_GLOBAL, mssEgressControlRegister_ADDR + 4, controlReg.word_1);
if (unlikely(ret))
return ret;
/*Assign to local representation of bitfield (EUR/CAL: 1E.5002.B) */
controlReg.bits_0.mssEgressClearCounter = 0;
//controlReg.bits_1.mssEgressClearCounter = 0;
/*Write register (EUR/CAL: 1E.5002) */
atl_mdio_write(hw, 0, MMD_GLOBAL, mssEgressControlRegister_ADDR, controlReg.word_0);
ret = atl_mdio_write(hw, 0, MMD_GLOBAL, mssEgressControlRegister_ADDR, controlReg.word_0);
if (unlikely(ret))
return ret;
/*Write register (EUR/CAL: 1E.5002 + 1) */
atl_mdio_write(hw, 0, MMD_GLOBAL, mssEgressControlRegister_ADDR + 4, controlReg.word_1);
ret = atl_mdio_write(hw, 0, MMD_GLOBAL, mssEgressControlRegister_ADDR + 4, controlReg.word_1);
if (unlikely(ret))
return ret;
return 0;
}
@ -1593,57 +1693,82 @@ int AQ_API_ClearEgressCounters(struct atl_hw *hw)
int AQ_API_GetIngressSACounters(struct atl_hw *hw, AQ_API_SEC_IngressSACounters* counters, uint16_t SAIndex)
{
uint16_t packedRecVal[4];
int ret;
if (SAIndex >= NUMROWS_INGRESSSARECORD)
return -EINVAL;
memset(counters, 0, sizeof(AQ_API_SEC_IngressSACounters));
GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, SAIndex * 12 + 0);
ret = GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, SAIndex * 12 + 0);
if (unlikely(ret))
return ret;
counters->untagged_hit_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
counters->untagged_hit_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, SAIndex * 12 + 1);
ret = GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, SAIndex * 12 + 1);
if (unlikely(ret))
return ret;
counters->ctrl_hit_drop_redir_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
counters->ctrl_hit_drop_redir_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, SAIndex * 12 + 2);
ret = GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, SAIndex * 12 + 2);
if (unlikely(ret))
return ret;
counters->not_using_sa[0] = packedRecVal[0] | (packedRecVal[1] << 16);
counters->not_using_sa[1] = packedRecVal[2] | (packedRecVal[3] << 16);
GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, SAIndex * 12 + 3);
ret = GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, SAIndex * 12 + 3);
if (unlikely(ret))
return ret;
counters->unused_sa[0] = packedRecVal[0] | (packedRecVal[1] << 16);
counters->unused_sa[1] = packedRecVal[2] | (packedRecVal[3] << 16);
GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, SAIndex * 12 + 4);
ret = GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, SAIndex * 12 + 4);
if (unlikely(ret))
return ret;
counters->not_valid_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
counters->not_valid_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, SAIndex * 12 + 5);
ret = GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, SAIndex * 12 + 5);
if (unlikely(ret))
return ret;
counters->invalid_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
counters->invalid_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, SAIndex * 12 + 6);
ret = GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, SAIndex * 12 + 6);
if (unlikely(ret))
return ret;
counters->ok_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
counters->ok_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, SAIndex * 12 + 7);
ret = GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, SAIndex * 12 + 7);
if (unlikely(ret))
return ret;
counters->late_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
counters->late_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, SAIndex * 12 + 8);
ret = GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, SAIndex * 12 + 8);
if (unlikely(ret))
return ret;
counters->delayed_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
counters->delayed_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, SAIndex * 12 + 9);
ret = GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, SAIndex * 12 + 9);
if (unlikely(ret))
return ret;
counters->unchecked_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
counters->unchecked_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, SAIndex * 12 + 10);
ret = GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, SAIndex * 12 + 10);
if (unlikely(ret))
return ret;
counters->validated_octets[0] = packedRecVal[0] | (packedRecVal[1] << 16);
counters->validated_octets[1] = packedRecVal[2] | (packedRecVal[3] << 16);
GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, SAIndex * 12 + 11);
ret = GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, SAIndex * 12 + 11);
if (unlikely(ret))
return ret;
counters->decrypted_octets[0] = packedRecVal[0] | (packedRecVal[1] << 16);
counters->decrypted_octets[1] = packedRecVal[2] | (packedRecVal[3] << 16);
@ -1653,70 +1778,103 @@ int AQ_API_GetIngressSACounters(struct atl_hw *hw, AQ_API_SEC_IngressSACounters*
int AQ_API_GetIngressCommonCounters(struct atl_hw *hw, AQ_API_SEC_IngressCommonCounters* counters)
{
uint16_t packedRecVal[4];
int ret;
memset(counters, 0, sizeof(AQ_API_SEC_IngressCommonCounters));
GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 0);
ret = GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 0);
if (unlikely(ret))
return ret;
counters->ctl_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
counters->ctl_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 1);
ret = GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 1);
if (unlikely(ret))
return ret;
counters->tagged_miss_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
counters->tagged_miss_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 2);
ret = GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 2);
if (unlikely(ret))
return ret;
counters->untagged_miss_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
counters->untagged_miss_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 3);
ret = GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 3);
if (unlikely(ret))
return ret;
counters->notag_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
counters->notag_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 4);
ret = GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 4);
if (unlikely(ret))
return ret;
counters->untagged_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
counters->untagged_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 5);
ret = GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 5);
if (unlikely(ret))
return ret;
counters->bad_tag_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
counters->bad_tag_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 6);
ret = GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 6);
if (unlikely(ret))
return ret;
counters->no_sci_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
counters->no_sci_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 7);
ret = GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 7);
if (unlikely(ret))
return ret;
counters->unknown_sci_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
counters->unknown_sci_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 8);
ret = GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 8);
if (unlikely(ret))
return ret;
counters->ctrl_prt_pass_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
counters->ctrl_prt_pass_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 9);
ret = GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 9);
if (unlikely(ret))
return ret;
counters->unctrl_prt_pass_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
counters->unctrl_prt_pass_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 10);
ret = GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 10);
if (unlikely(ret))
return ret;
counters->ctrl_prt_fail_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
counters->ctrl_prt_fail_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 11);
ret = GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 11);
if (unlikely(ret))
return ret;
counters->unctrl_prt_fail_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
counters->unctrl_prt_fail_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 12);
ret = GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 12);
if (unlikely(ret))
return ret;
counters->too_long_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
counters->too_long_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 13);
ret = GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 13);
if (unlikely(ret))
return ret;
counters->igpoc_ctl_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
counters->igpoc_ctl_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 14);
ret = GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 14);
if (unlikely(ret))
return ret;
counters->ecc_error_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
counters->ecc_error_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 15);
ret = GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 15);
if (unlikely(ret))
return ret;
counters->unctrl_hit_drop_redir[0] = packedRecVal[0] | (packedRecVal[1] << 16);
counters->unctrl_hit_drop_redir[1] = packedRecVal[2] | (packedRecVal[3] << 16);
@ -1726,6 +1884,7 @@ int AQ_API_GetIngressCommonCounters(struct atl_hw *hw, AQ_API_SEC_IngressCommonC
int AQ_API_ClearIngressCounters(struct atl_hw *hw)
{
struct mssIngressControlRegister_t controlReg;
int ret;
memset(&controlReg, 0, sizeof(struct mssIngressControlRegister_t));
@ -1739,9 +1898,13 @@ int AQ_API_ClearIngressCounters(struct atl_hw *hw)
/* Toggle the Ingress MIB clear bit 0->1->0 */
/*Read register (EUR/CAL: 1E.800E) */
atl_mdio_read(hw, 0, MMD_GLOBAL, mssIngressControlRegister_ADDR, &controlReg.word_0);
ret = atl_mdio_read(hw, 0, MMD_GLOBAL, mssIngressControlRegister_ADDR, &controlReg.word_0);
if (unlikely(ret))
return ret;
/*Read register (EUR/CAL: 1E.800E + 1) */
atl_mdio_read(hw, 0, MMD_GLOBAL, mssIngressControlRegister_ADDR +4, &controlReg.word_1);
ret = atl_mdio_read(hw, 0, MMD_GLOBAL, mssIngressControlRegister_ADDR +4, &controlReg.word_1);
if (unlikely(ret))
return ret;
/*Assign to local representation of bitfield (EUR/CAL: 1E.800E.8) */
@ -1749,23 +1912,35 @@ int AQ_API_ClearIngressCounters(struct atl_hw *hw)
controlReg.bits_0.mssIngressClearCount = 0;
/*Write register (EUR/CAL: 1E.800E) */
atl_mdio_write(hw, 0, MMD_GLOBAL, mssIngressControlRegister_ADDR, controlReg.word_0);
ret = atl_mdio_write(hw, 0, MMD_GLOBAL, mssIngressControlRegister_ADDR, controlReg.word_0);
if (unlikely(ret))
return ret;
/*Write register (EUR/CAL: 1E.800E + 1) */
atl_mdio_write(hw, 0, MMD_GLOBAL, mssIngressControlRegister_ADDR + 4, controlReg.word_1);
ret = atl_mdio_write(hw, 0, MMD_GLOBAL, mssIngressControlRegister_ADDR + 4, controlReg.word_1);
if (unlikely(ret))
return ret;
/*Assign to local representation of bitfield (EUR/CAL: 1E.800E.8) */
controlReg.bits_0.mssIngressClearCount = 1;
/*Write register (EUR/CAL: 1E.800E) */
atl_mdio_write(hw, 0, MMD_GLOBAL, mssIngressControlRegister_ADDR, controlReg.word_0);
ret = atl_mdio_write(hw, 0, MMD_GLOBAL, mssIngressControlRegister_ADDR, controlReg.word_0);
if (unlikely(ret))
return ret;
/*Write register (EUR/CAL: 1E.800E + 1) */
atl_mdio_write(hw, 0, MMD_GLOBAL, mssIngressControlRegister_ADDR + 4, controlReg.word_1);
ret = atl_mdio_write(hw, 0, MMD_GLOBAL, mssIngressControlRegister_ADDR + 4, controlReg.word_1);
if (unlikely(ret))
return ret;
/*Assign to local representation of bitfield (EUR/CAL: 1E.800E.8) */
controlReg.bits_0.mssIngressClearCount = 0;
/*Write register (EUR/CAL: 1E.800E) */
atl_mdio_write(hw, 0, MMD_GLOBAL, mssIngressControlRegister_ADDR, controlReg.word_0);
ret = atl_mdio_write(hw, 0, MMD_GLOBAL, mssIngressControlRegister_ADDR, controlReg.word_0);
if (unlikely(ret))
return ret;
/*Write register (EUR/CAL: 1E.800E + 1) */
atl_mdio_write(hw, 0, MMD_GLOBAL, mssIngressControlRegister_ADDR + 4, controlReg.word_1);
ret = atl_mdio_write(hw, 0, MMD_GLOBAL, mssIngressControlRegister_ADDR + 4, controlReg.word_1);
if (unlikely(ret))
return ret;
return 0;
}
@ -1773,10 +1948,18 @@ int AQ_API_ClearIngressCounters(struct atl_hw *hw)
int AQ_API_GetEgressSAExpired(struct atl_hw *hw, uint32_t *expired)
{
uint16_t val;
int ret;
ret = atl_mdio_read(hw, 0, MMD_GLOBAL, mssEgressSaExpiredStatusRegister_ADDR, &val);
if (unlikely(ret))
return ret;
atl_mdio_read(hw, 0, MMD_GLOBAL, mssEgressSaExpiredStatusRegister_ADDR, &val);
*expired = val;
atl_mdio_read(hw, 0, MMD_GLOBAL, mssEgressSaExpiredStatusRegister_ADDR + 1, &val);
ret = atl_mdio_read(hw, 0, MMD_GLOBAL, mssEgressSaExpiredStatusRegister_ADDR + 1, &val);
if (unlikely(ret))
return ret;
*expired |= val << 16;
return 0;
@ -1785,10 +1968,18 @@ int AQ_API_GetEgressSAExpired(struct atl_hw *hw, uint32_t *expired)
int AQ_API_GetEgressSAThresholdExpired(struct atl_hw *hw, uint32_t *expired)
{
uint16_t val;
int ret;
ret = atl_mdio_read(hw, 0, MMD_GLOBAL, mssEgressSaThresholdExpiredStatusRegister_ADDR, &val);
if (unlikely(ret))
return ret;
atl_mdio_read(hw, 0, MMD_GLOBAL, mssEgressSaThresholdExpiredStatusRegister_ADDR, &val);
*expired = val;
atl_mdio_read(hw, 0, MMD_GLOBAL, mssEgressSaThresholdExpiredStatusRegister_ADDR + 1, &val);
ret = atl_mdio_read(hw, 0, MMD_GLOBAL, mssEgressSaThresholdExpiredStatusRegister_ADDR + 1, &val);
if (unlikely(ret))
return ret;
*expired |= val << 16;
return 0;
@ -1796,16 +1987,30 @@ int AQ_API_GetEgressSAThresholdExpired(struct atl_hw *hw, uint32_t *expired)
int AQ_API_SetEgressSAExpired(struct atl_hw *hw, uint32_t expired)
{
atl_mdio_write(hw, 0, MMD_GLOBAL, mssEgressSaExpiredStatusRegister_ADDR, expired & 0xFFFF);
atl_mdio_write(hw, 0, MMD_GLOBAL, mssEgressSaExpiredStatusRegister_ADDR + 1, expired >> 16);
int ret;
ret = atl_mdio_write(hw, 0, MMD_GLOBAL, mssEgressSaExpiredStatusRegister_ADDR, expired & 0xFFFF);
if (unlikely(ret))
return ret;
ret = atl_mdio_write(hw, 0, MMD_GLOBAL, mssEgressSaExpiredStatusRegister_ADDR + 1, expired >> 16);
if (unlikely(ret))
return ret;
return 0;
}
int AQ_API_SetEgressSAThresholdExpired(struct atl_hw *hw, uint32_t expired)
{
atl_mdio_write(hw, 0, MMD_GLOBAL, mssEgressSaThresholdExpiredStatusRegister_ADDR, expired & 0xFFFF);
atl_mdio_write(hw, 0, MMD_GLOBAL, mssEgressSaThresholdExpiredStatusRegister_ADDR + 1, expired >> 16);
int ret;
ret = atl_mdio_write(hw, 0, MMD_GLOBAL, mssEgressSaThresholdExpiredStatusRegister_ADDR, expired & 0xFFFF);
if (unlikely(ret))
return ret;
ret = atl_mdio_write(hw, 0, MMD_GLOBAL, mssEgressSaThresholdExpiredStatusRegister_ADDR + 1, expired >> 16);
if (unlikely(ret))
return ret;
return 0;
}

View File

@ -1,7 +1,7 @@
#ifndef __MACSEC_API_H__
#define __MACSEC_API_H__
#include "../atl_common.h"
#include "atl_hw.h"
#include "macsec_struct.h"

View File

@ -1,3 +1,18 @@
Version 1.0.30
==============
[ATLDRV-1217] - FWD driver refactoring for unit tests
[ATLDRV-1102] - TCP/UDP checksum workaround for non-zero padded packets doesn't work
[ATLDRV-1138] - vlan promiscuous mode is not enabled, when deleting the last vlan interface
[ATLDRV-1139] - after ifconfig -multicast Unicast filters registers have valid values for multicast addresses
[ATLDRV-1174] - FWD: deleting MacSec iface doesn't clear Ingress/Egress SA and SAKey records
[ATLDRV-1193] - No link UP if driver was started in MSI mode before being started in legacy mode
[ATLDRV-1208] - Driver crashes after link down up in D3 state
[ATLDRV-1209] - FWD: Kernel panic after configuring macsec
[ATLDRV-1218] - Kernel panic upon macsec0 deletion
[ATLDRV-1220] - AQ069: atl_fwd_receive_skb() support NAPI
[ATLDRV-1222] - atl_rotate_keys() produces unexpected results for 192-bit keys (24-bytes)
[ATLDRV-1194] - Add trace of descriptors for normal traffic
Version 1.0.29
==============
[ATLDRV-1139] - after ifconfig -multicast Unicast filters registers have valid values for multicast addresses