summaryrefslogtreecommitdiff
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/Kconfig2
-rw-r--r--drivers/net/bonding/bond_main.c1
-rw-r--r--drivers/net/bonding/hw_distribution.c208
-rw-r--r--drivers/net/bonding/hw_distribution.h6
-rw-r--r--drivers/net/bonding/hw_oh_pcd.c3
-rw-r--r--drivers/net/can/c_can/c_can.c3
-rw-r--r--drivers/net/can/dev.c10
-rw-r--r--drivers/net/can/sja1000/peak_pci.c14
-rw-r--r--drivers/net/can/slcan.c41
-rw-r--r--drivers/net/can/usb/esd_usb2.c1
-rw-r--r--drivers/net/can/usb/kvaser_usb.c20
-rw-r--r--drivers/net/can/usb/peak_usb/pcan_usb_core.c17
-rw-r--r--drivers/net/can/usb/peak_usb/pcan_usb_pro.c3
-rw-r--r--drivers/net/ethernet/allwinner/sun4i-emac.c1
-rw-r--r--drivers/net/ethernet/atheros/alx/main.c24
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x.h1
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c12
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c19
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c3
-rw-r--r--drivers/net/ethernet/broadcom/tg3.c79
-rw-r--r--drivers/net/ethernet/broadcom/tg3.h3
-rw-r--r--drivers/net/ethernet/brocade/bna/bnad.c13
-rw-r--r--drivers/net/ethernet/cadence/macb.c11
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_main.c12
-rw-r--r--drivers/net/ethernet/emulex/benet/be_main.c2
-rw-r--r--drivers/net/ethernet/freescale/dpa/Kconfig27
-rw-r--r--drivers/net/ethernet/freescale/dpa/Makefile57
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_1588.c11
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_debugfs.c30
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_debugfs.h2
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth.c36
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth.h6
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth_base.c73
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth_base.h10
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth_common.c125
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth_common.h8
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth_generic.c290
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth_generic.h7
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth_macless.c42
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth_proxy.c6
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth_sg.c39
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth_shared.c47
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth_sysfs.c1
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_generic_debugfs.c16
-rw-r--r--drivers/net/ethernet/freescale/dpa/mac-api.c12
-rw-r--r--drivers/net/ethernet/freescale/dpa/mac.c81
-rw-r--r--drivers/net/ethernet/freescale/dpa/offline_port.c128
-rw-r--r--drivers/net/ethernet/freescale/fman/Peripherals/FM/MAC/memac.c19
-rw-r--r--drivers/net/ethernet/freescale/fman/Peripherals/FM/MACSEC/Makefile15
-rw-r--r--drivers/net/ethernet/freescale/fman/Peripherals/FM/MACSEC/fm_macsec.c237
-rw-r--r--drivers/net/ethernet/freescale/fman/Peripherals/FM/MACSEC/fm_macsec.h203
-rw-r--r--drivers/net/ethernet/freescale/fman/Peripherals/FM/MACSEC/fm_macsec_guest.c59
-rw-r--r--drivers/net/ethernet/freescale/fman/Peripherals/FM/MACSEC/fm_macsec_master.c1028
-rw-r--r--drivers/net/ethernet/freescale/fman/Peripherals/FM/MACSEC/fm_macsec_master.h476
-rw-r--r--drivers/net/ethernet/freescale/fman/Peripherals/FM/MACSEC/fm_macsec_secy.c908
-rw-r--r--drivers/net/ethernet/freescale/fman/Peripherals/FM/MACSEC/fm_macsec_secy.h144
-rw-r--r--drivers/net/ethernet/freescale/fman/Peripherals/FM/Makefile1
-rw-r--r--drivers/net/ethernet/freescale/fman/Peripherals/FM/Pcd/fm_cc.c3
-rw-r--r--drivers/net/ethernet/freescale/fman/Peripherals/FM/Pcd/fm_kg.c24
-rw-r--r--drivers/net/ethernet/freescale/fman/Peripherals/FM/Pcd/fm_manip.c25
-rw-r--r--drivers/net/ethernet/freescale/fman/Peripherals/FM/fm.h5
-rw-r--r--drivers/net/ethernet/freescale/fman/Peripherals/FM/inc/fm_common.h4
-rw-r--r--drivers/net/ethernet/freescale/fman/inc/Peripherals/fm_macsec_ext.h1271
-rw-r--r--drivers/net/ethernet/freescale/fman/inc/enet_ext.h2
-rw-r--r--drivers/net/ethernet/freescale/fman/inc/flib/fsl_enet.h1
-rw-r--r--drivers/net/ethernet/freescale/fman/inc/integrations/P3040_P4080_P5020/dpaa_integration_ext.h10
-rw-r--r--drivers/net/ethernet/freescale/fman/inc/integrations/T4240/dpaa_integration_ext.h9
-rw-r--r--drivers/net/ethernet/freescale/fman/inc/xx_common.h2
-rwxr-xr-xdrivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_fm.c2
-rw-r--r--drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_ioctls_fm.c156
-rw-r--r--drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_ioctls_fm_compat.c12
-rw-r--r--drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_ioctls_fm_compat.h13
-rw-r--r--drivers/net/ethernet/freescale/gianfar.c26
-rw-r--r--drivers/net/ethernet/freescale/gianfar.h2
-rw-r--r--drivers/net/ethernet/freescale/gianfar_ethtool.c2
-rw-r--r--drivers/net/ethernet/ibm/ibmveth.c18
-rw-r--r--drivers/net/ethernet/intel/e1000/e1000.h5
-rw-r--r--drivers/net/ethernet/intel/e1000/e1000_main.c27
-rw-r--r--drivers/net/ethernet/intel/e1000e/ich8lan.c2
-rw-r--r--drivers/net/ethernet/intel/e1000e/ich8lan.h2
-rw-r--r--drivers/net/ethernet/intel/e1000e/netdev.c22
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_82575.c7
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_defines.h18
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_hw.h3
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_i210.c66
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_i210.h12
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_phy.c8
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_regs.h1
-rw-r--r--drivers/net/ethernet/intel/igb/igb_ethtool.c17
-rw-r--r--drivers/net/ethernet/intel/igb/igb_main.c73
-rw-r--r--drivers/net/ethernet/intel/igbvf/netdev.c26
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe.h48
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c6
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_main.c36
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c44
-rw-r--r--drivers/net/ethernet/marvell/mvneta.c48
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_cq.c1
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_netdev.c6
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4_en.h1
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/resource_tracker.c2
-rw-r--r--drivers/net/ethernet/myricom/myri10ge/myri10ge.c88
-rw-r--r--drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c4
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c1
-rw-r--r--drivers/net/ethernet/renesas/sh_eth.c31
-rw-r--r--drivers/net/ethernet/renesas/sh_eth.h2
-rw-r--r--drivers/net/ethernet/sfc/nic.c14
-rw-r--r--drivers/net/ethernet/sun/sunvnet.c24
-rw-r--r--drivers/net/ethernet/ti/cpsw.c32
-rw-r--r--drivers/net/ethernet/ti/cpsw_ale.c10
-rw-r--r--drivers/net/ethernet/ti/cpsw_ale.h2
-rw-r--r--drivers/net/hyperv/netvsc_drv.c3
-rw-r--r--drivers/net/ieee802154/fakehard.c13
-rw-r--r--drivers/net/macvlan.c11
-rw-r--r--drivers/net/macvtap.c32
-rw-r--r--drivers/net/ppp/ppp_generic.c2
-rw-r--r--drivers/net/ppp/pppoe.c2
-rw-r--r--drivers/net/ppp/pptp.c6
-rw-r--r--drivers/net/slip/slip.c40
-rw-r--r--drivers/net/slip/slip.h1
-rw-r--r--drivers/net/team/team.c27
-rw-r--r--drivers/net/tun.c22
-rw-r--r--drivers/net/usb/ax88179_178a.c7
-rw-r--r--drivers/net/usb/cdc_mbim.c39
-rw-r--r--drivers/net/usb/qmi_wwan.c42
-rw-r--r--drivers/net/vxlan.c68
-rw-r--r--drivers/net/wireless/ath/ath5k/qcu.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c13
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c13
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.c9
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c15
-rw-r--r--drivers/net/wireless/ath/carl9170/carl9170.h1
-rw-r--r--drivers/net/wireless/ath/carl9170/usb.c31
-rw-r--r--drivers/net/wireless/b43/phy_n.c14
-rw-r--r--drivers/net/wireless/b43/xmit.c10
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/main.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-power.h35
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api.h1
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw.c9
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c25
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h1
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c1
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/drv.c4
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c42
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c4
-rw-r--r--drivers/net/wireless/mwifiex/main.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c7
-rw-r--r--drivers/net/wireless/rt2x00/rt2800.h6
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c6
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c23
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h1
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c24
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c24
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c50
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/hw.c20
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/trx.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/hw.c17
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/sw.c1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/hw.c27
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/trx.c6
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/hw.c18
-rw-r--r--drivers/net/xen-netfront.c5
163 files changed, 6441 insertions, 1291 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 1fc20d1..1ade9f9 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -302,6 +302,7 @@ config MACVLAN
config MACVTAP
tristate "MAC-VLAN based tap driver"
depends on MACVLAN
+ depends on INET
help
This adds a specialized tap character device driver that is based
on the MAC-VLAN network interface, called macvtap. A macvtap device
@@ -373,6 +374,7 @@ config RIONET_RX_SIZE
config TUN
tristate "Universal TUN/TAP device driver support"
+ depends on INET
select CRC32
---help---
TUN/TAP provides packet reception and transmission for user space
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 5cd2cf1..24e45d0 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4647,6 +4647,7 @@ static int __init bonding_init(void)
out:
return res;
err:
+ bond_destroy_debugfs();
rtnl_link_unregister(&bond_link_ops);
err_link:
unregister_pernet_subsys(&bond_net_ops);
diff --git a/drivers/net/bonding/hw_distribution.c b/drivers/net/bonding/hw_distribution.c
index 7e37bf3..afccf70 100644
--- a/drivers/net/bonding/hw_distribution.c
+++ b/drivers/net/bonding/hw_distribution.c
@@ -259,7 +259,7 @@ ssize_t bonding_show_oh_enable(struct device *d,
struct device_attribute *attr, char *buf)
{
- int res = 0;
+ int res = 0, ret;
struct bonding *bond = to_bond(d);
uint16_t channel;
unsigned long fman_dcpid, oh_offset, cell_index;
@@ -280,9 +280,10 @@ ssize_t bonding_show_oh_enable(struct device *d,
if (res)
buf[res-1] = '\n'; /* eat the leftover space */
- if ((bond->params.ohp->oh_en) &&
- (!export_oh_port_info_to_ceetm(bond, &channel,
- &fman_dcpid, &oh_offset, &cell_index)))
+ ret = export_oh_port_info_to_ceetm(bond, &channel, &fman_dcpid,
+ &oh_offset, &cell_index);
+
+ if (!ret && bond->params.ohp->oh_en)
hw_lag_dbg("offline port channel:%d\n", channel);
return res;
@@ -336,27 +337,29 @@ ssize_t bonding_store_oh_enable(struct device *d,
*/
static bool is_dpa_eth_port(struct net_device *netdev)
{
+ int ret;
struct device *dev = (struct device *) &(netdev->dev);
- if ((strlen(dev_driver_string(dev->parent)) >= 7) &&
- strncmp(dev_driver_string(dev->parent), "fsl_dpa", 7) == 0)
- return true;
- else
- return false;
+ if (strlen(dev_driver_string(dev->parent)) >= 7) {
+ ret = strncmp(dev_driver_string(dev->parent), "fsl_dpa", 7);
+ return ret ? false : true;
+ }
+
+ return false;
}
bool are_all_slaves_linkup(struct bonding *bond)
{
- struct slave *slave;
+ struct slave *s;
+
+ bond_for_each_slave(bond, s) {
+ hw_lag_dbg("This slave:%s link status is up:%s\n",
+ s->dev->name, IS_UP(s->dev) ? "true" : "false");
- read_lock(&bond->lock);
- bond_for_each_slave(bond, slave)
- if (!(SLAVE_IS_OK(slave))) {
- read_unlock(&bond->lock);
+ if (!(IS_UP(s->dev)))
return false;
- }
+ }
- read_unlock(&bond->lock);
return true;
}
@@ -514,7 +517,7 @@ struct sk_buff *oh_cleanup_tx_fd(const struct qm_fd *fd)
dma_unmap_single(dpa_bp->dev, addr, dpa_bp->size, dma_dir);
/* retrieve skb back pointer */
- DPA_READ_SKB_PTR(skb, skbh, phys_to_virt(addr), 0);
+ DPA_READ_SKB_PTR(skb, skbh, phys_to_virt((unsigned long)addr), 0);
nr_frags = skb_shinfo(skb)->nr_frags;
if (fd->format == qm_fd_sg) {
@@ -549,7 +552,7 @@ static void dump_parser_result(const struct qm_fd *fd)
void *vaddr;
const fm_prs_result_t *parse_results;
- vaddr = phys_to_virt(addr);
+ vaddr = phys_to_virt((unsigned long)addr);
DPA_BUG_ON(!IS_ALIGNED((unsigned long)vaddr, SMP_CACHE_BYTES));
parse_results = (const fm_prs_result_t *)(vaddr +
@@ -582,7 +585,8 @@ static void show_dbg_info(const struct qm_fd *fd, const char *func_name,
struct sk_buff *skb)
{
#ifdef CONFIG_HW_LAG_DEBUG
- u32 pad, fd_status;
+ u32 fd_status;
+ unsigned long pad;
dma_addr_t addr;
struct ethhdr *eth;
struct iphdr *iph;
@@ -596,7 +600,7 @@ static void show_dbg_info(const struct qm_fd *fd, const char *func_name,
/* find out the pad */
skb_addr = virt_to_phys(skb->head);
- pad = addr - skb_addr;
+ pad = (unsigned long)addr - skb_addr;
/* The skb is currently pointed at head + headroom. The packet
* starts at skb->head + pad + fd offset.
@@ -754,7 +758,7 @@ oh_ingress_tx_default_dqrr(struct qman_portal *portal,
netdev = ((struct dpa_fq *)fq)->net_dev;
if (!netdev) {
pr_err("error netdev == NULL.\n");
- skbh = (struct sk_buff **)phys_to_virt(addr);
+ skbh = (struct sk_buff **)phys_to_virt((unsigned long)addr);
dev_kfree_skb(*skbh);
return qman_cb_dqrr_consume;
}
@@ -791,7 +795,7 @@ oh_ingress_tx_default_dqrr(struct qman_portal *portal,
/* find out the pad */
skb_addr = virt_to_phys(skb->head);
- pad = addr - skb_addr;
+ pad = (u32)(addr - skb_addr);
countptr = __this_cpu_ptr(bp->percpu_count);
(*countptr)--;
@@ -954,12 +958,12 @@ static const struct qman_fq oh_egress_ernq = {
.cb = { .ern = lag_public_egress_ern}
};
-static int oh_add_channel(void *__arg)
+static int op_add_channel(void *__arg)
{
int cpu;
struct qman_portal *portal;
const cpumask_t *cpus = qman_affine_cpus();
- u32 pool = QM_SDQCR_CHANNELS_POOL_CONV((u32)(unsigned long)__arg);
+ u32 pool = QM_SDQCR_CHANNELS_POOL_CONV((u16)(unsigned long)__arg);
for_each_cpu(cpu, cpus) {
portal = (struct qman_portal *)qman_get_affine_portal(cpu);
@@ -969,18 +973,10 @@ static int oh_add_channel(void *__arg)
return 0;
}
-static int init_oh_errq_defq(struct device *dev,
- uint32_t fqid_err, uint32_t fqid_def,
- struct dpa_fq **oh_errq, struct dpa_fq **oh_defq,
- uint16_t *priv_channel)
+static int op_alloc_pool_channel(uint16_t *priv_channel)
{
int errno;
- struct dpa_fq *errq, *defq;
- /* These two vaules come from DPA-Eth driver */
- uint8_t wq_errq = 2, wq_defq = 1;
u32 channel;
- struct qm_mcc_initfq initfq;
- struct qm_fqd fqd;
struct task_struct *kth;
/* Get a channel */
@@ -990,23 +986,33 @@ static int init_oh_errq_defq(struct device *dev,
return errno;
}
- if (channel < 0) {
- errno = channel;
- pr_err("error on dpa_get_channel().\n");
- return errno;
- }
-
/* Start a thread that will walk the cpus with affine portals
* and add this pool channel to each's dequeue mask.
*/
- kth = kthread_run(oh_add_channel, (void *)(unsigned long)channel,
- "oh_add_channel");
+ kth = kthread_run(op_add_channel, (void *)(unsigned long)channel,
+ "op_add_channel");
if (!kth) {
pr_warn("run kthread faild...\n");
return -ENOMEM;
}
+ *priv_channel = (uint16_t)channel;
+
+ return 0;
+}
+
+static int init_oh_errq_defq(struct device *dev,
+ uint32_t fqid_err, uint32_t fqid_def,
+ struct dpa_fq **oh_errq, struct dpa_fq **oh_defq,
+ uint16_t channel)
+{
+ int errno;
+ struct dpa_fq *errq, *defq;
+ /* These two vaules come from DPA-Eth driver */
+ uint8_t wq_errq = 2, wq_defq = 1;
+ struct qm_mcc_initfq initfq;
+
/* Allocate memories for Tx ErrQ and Tx DefQ of oh port */
errq = devm_kzalloc(dev, sizeof(struct dpa_fq), GFP_KERNEL);
if (!errq) {
@@ -1038,7 +1044,6 @@ static int init_oh_errq_defq(struct device *dev,
return errno;
}
- *priv_channel = (uint16_t)channel;
/* Set the FQs init options then init the FQs */
initfq.we_mask = QM_INITFQ_WE_DESTWQ;
initfq.fqd.dest.channel = (uint16_t)channel;
@@ -1063,20 +1068,6 @@ static int init_oh_errq_defq(struct device *dev,
return errno;
}
- errno = qman_query_fq(&errq->fq_base, &fqd);
- hw_lag_dbg("errno of qman_query_fq:0x%08x\n", errno);
- if (fqd.fq_ctrl != initfq.fqd.fq_ctrl) {
- pr_err("queried fq_ctrl=%x, should be=%x\n", fqd.fq_ctrl,
- initfq.fqd.fq_ctrl);
- panic("fail");
- }
- if (memcmp(&fqd.td, &initfq.fqd.td, sizeof(fqd.td))) {
- pr_err("queried td_thresh=%x:%x, should be=%x:%x\n",
- fqd.td.exp, fqd.td.mant,
- initfq.fqd.td.exp, initfq.fqd.td.mant);
- panic("fail");
- }
-
/* init oh ports default fq */
initfq.fqd.dest.wq = wq_defq;
errno = qman_init_fq(&defq->fq_base, QMAN_INITFQ_FLAG_SCHED, &initfq);
@@ -1435,8 +1426,8 @@ int get_oh_info(void)
return -EINVAL;
}
- hw_lag_dbg("Found port id %ud, in node %s\n",
- *p_port_id, dpa_oh_node->full_name);
+ hw_lag_dbg("Found port id %u, in node %s\n",
+ *p_port_id, dpa_oh_node->full_name);
BUG_ON(lenp % sizeof(*p_port_id));
/* Read channel id for the queues */
@@ -1455,7 +1446,7 @@ int get_oh_info(void)
BUG_ON(!oh_of_dev);
oh_dev = &oh_of_dev->dev;
of_dev = of_find_device_by_node(dpa_oh_node);
- BUG_ON(!oh_of_dev);
+ BUG_ON(!of_dev);
dpa_oh_dev = &of_dev->dev;
poh[i].of_dev = of_dev;
poh[i].oh_of_dev = oh_of_dev;
@@ -1466,7 +1457,7 @@ int get_oh_info(void)
poh[i].cell_index = *p_port_id;
poh[i].oh_config = dev_get_drvdata(dpa_oh_dev);
poh[i].p_oh_port_handle = p_oh_port_handle;
- poh[i].oh_channel_id = *p_channel_id;
+ poh[i].oh_channel_id = (uint16_t)*p_channel_id;
oh_port = poh[i].oh_config->oh_port;
fm_port_get_buff_layout_ext_params(oh_port, &params);
poh[i].bpid = params.pool_param[0].id;
@@ -1487,12 +1478,23 @@ int get_oh_info(void)
return -EINVAL;
}
+ if (!poh[i].p_oh_rcv_channel) {
+ uint16_t ch;
+ errno = op_alloc_pool_channel(&ch);
+ if (errno) {
+ pr_err("Get pool channel error.\n");
+ return errno;
+ } else {
+ poh[i].p_oh_rcv_channel = ch;
+ }
+ }
+
errno = init_oh_errq_defq(poh[i].dpa_oh_dev,
poh[i].oh_config->error_fqid,
poh[i].oh_config->default_fqid,
&poh[i].oh_errq,
&poh[i].oh_defq,
- &poh[i].p_oh_rcv_channel);
+ poh[i].p_oh_rcv_channel);
if (errno != BOND_OH_SUCCESS) {
pr_err("error when probe errq or defq.\n");
return errno;
@@ -1575,77 +1577,41 @@ int get_dcp_id_from_dpa_eth_port(struct net_device *netdev)
* Get all information of the offline port which is being used
* by a bundle, such as fman_dcpid, offline port offset, cell index,
* offline port channel. This API is required by CEETM Qos.
- * Regarding fman dpcid, till sdk1.6, there is one fman in p1023, the
- * offset is 0x1000000, for other dpaa socs, the offset of fman0 is
- * 0x400000, the offset of fman1 is 0x500000, hence for current socs,
- * the offset of fman0 <=0x4000000, 0x400000 < fman1 <=0x500000.
- * return BOND_OH_SUCCESS when got all information, otherwise return
- * Non-Zero.
*/
-#define FMAN0_MAX_OFFSET 0x400000
-#define FMAN1_MAX_OFFSET 0x500000
int export_oh_port_info_to_ceetm(struct bonding *bond, uint16_t *channel,
unsigned long *fman_dcpid, unsigned long *oh_offset,
unsigned long *cell_index)
{
- /**
- * split str: "/soc@ffe000000/fman@400000/port@84000", then get
- * the fman@ part and port@ part from them. regex is good enough
- * as below:
- * ret = sscanf((char *) p, "%*[^@]@%*[^@]@%[^/]/port@%s", s1, s2);
- * but the kernel version does not support the method.
- */
- int errno;
- char s1[16] = {0}, s2[16] = {0};
- char *p, *p1;
+ struct oh_port_priv *p = bond->params.ohp;
+ char tmp[] = "cell-index";
- if (!bond->params.ohp) {
+ if (!p) {
pr_err("The bundle has not binded an offline port.\n");
- return 1;
+ return BOND_OH_ERROR;
}
- if (!bond->params.ohp->oh_en) {
+ if (!p->oh_en) {
pr_err("The offline is disabled, to enable it, use sysfs.\n");
- return 2;
+ return BOND_OH_ERROR;
}
- if (!bond->params.ohp->oh_node) {
+ if (!p->oh_node) {
pr_err("The offline node error.\n");
- return 3;
+ return BOND_OH_ERROR;
}
- p = strstr(bond->params.ohp->oh_node->full_name, "fman@");
- p += strlen("fman@");
- p1 = strstr(p, "/port@");
-
- memcpy(s1, p, p1 - p);
-
- p = strstr(p, "/port@");
- p += strlen("/port@");
-
- errno = sscanf((const char *) p, "%s", s2);
- if (errno != 1) {
- pr_err("parser error while process offline port node\n");
- return 4;
+ if (of_property_read_u32(p->oh_node, "reg", (u32 *)oh_offset)) {
+ pr_err("Errors on getting offline port offset.\n");
+ return BOND_OH_ERROR;
}
- errno = kstrtoul(s1, 16, fman_dcpid) | kstrtoul(s2, 16, oh_offset);
- if (errno) {
- pr_err("error on kstrtoul fman_dcpid, of_offset\n");
- return 5;
- }
- if (*fman_dcpid <= FMAN0_MAX_OFFSET) {
- *fman_dcpid = 0;
- } else if ((*fman_dcpid > FMAN0_MAX_OFFSET) &&
- (*fman_dcpid <= FMAN1_MAX_OFFSET)) {
- *fman_dcpid = 1;
- } else {
- pr_err("error on calculating fman dcpid, new soc appears.\n");
- return 6;
+ if (of_property_read_u32(p->oh_node->parent, tmp, (u32 *)fman_dcpid)) {
+ pr_err("Errors on getting fman_dcpid.\n");
+ return BOND_OH_ERROR;
}
- *channel = bond->params.ohp->oh_channel_id;
- *cell_index = bond->params.ohp->cell_index;
+ *channel = (uint16_t)p->oh_channel_id;
+ *cell_index = p->cell_index;
hw_lag_dbg("This oh port mapped to bond has channel:0x%0x\n", *channel);
hw_lag_dbg("fman_dcpid:0x%0lx, oh_offset:0x%0lx, cell-index:%0lx\n",
@@ -1843,8 +1809,8 @@ int oh_tx_csum_enable(struct sk_buff *skb,
parse_result->l3r, parse_result->l4r);
/* At index 0 is IPOffset_1 as defined in the Parse Results */
- parse_result->ip_off[0] = skb_network_offset(skb);
- parse_result->l4_off = skb_transport_offset(skb);
+ parse_result->ip_off[0] = (uint8_t)skb_network_offset(skb);
+ parse_result->l4_off = (uint8_t)skb_transport_offset(skb);
/* Enable L3 (and L4, if TCP or UDP) HW checksum. */
fd->cmd |= FM_FD_CMD_RPD | FM_FD_CMD_DTC;
@@ -1940,8 +1906,8 @@ return_error:
parse_result->l3r, parse_result->l4r);
/* At index 0 is IPOffset_1 as defined in the Parse Results */
- parse_result->ip_off[0] = skb_network_offset(skb);
- parse_result->l4_off = skb_transport_offset(skb);
+ parse_result->ip_off[0] = (uint8_t)skb_network_offset(skb);
+ parse_result->l4_off = (uint8_t)skb_transport_offset(skb);
/* Enable L3 (and L4, if TCP or UDP) HW checksum. */
fd->cmd |= FM_FD_CMD_RPD | FM_FD_CMD_DCL4C;
@@ -2033,7 +1999,7 @@ int __hot dpa_oh_tx(struct sk_buff *skb, struct bonding *bond,
fd.format = qm_fd_contig;
fd.length20 = skb->len;
fd.offset = priv->tx_headroom;
- fd.addr_hi = upper_32_bits(addr);
+ fd.addr_hi = (u8)upper_32_bits(addr);
fd.addr_lo = lower_32_bits(addr);
/* fd.cmd |= FM_FD_CMD_FCO; */
fd.bpid = bp->bpid;
@@ -2113,7 +2079,8 @@ static int get_dpa_slave_info(struct slave *slave, uint16_t *tx_channel)
if (!is_dpa_eth_port(slave->dev) || !(priv->mac_dev))
return BOND_OH_ERROR;
- *tx_channel = fm_get_tx_port_channel(priv->mac_dev->port_dev[TX]);
+ *tx_channel = (uint16_t)fm_get_tx_port_channel(
+ priv->mac_dev->port_dev[TX]);
return BOND_OH_SUCCESS;
}
@@ -2126,7 +2093,8 @@ int get_dpa_slave_info_ex(struct slave *slave, uint16_t *tx_channel,
if (!is_dpa_eth_port(slave->dev) || !(priv->mac_dev))
return BOND_OH_ERROR;
- *tx_channel = fm_get_tx_port_channel(priv->mac_dev->port_dev[TX]);
+ *tx_channel = (uint16_t)fm_get_tx_port_channel(
+ priv->mac_dev->port_dev[TX]);
*egress_fq = priv->egress_fqs[0];
*first_fqid = priv->egress_fqs[0]->fqid;
diff --git a/drivers/net/bonding/hw_distribution.h b/drivers/net/bonding/hw_distribution.h
index 31e2967..da99df7 100644
--- a/drivers/net/bonding/hw_distribution.h
+++ b/drivers/net/bonding/hw_distribution.h
@@ -48,7 +48,7 @@
#include "fm_cc.h"
#include "crc64.h"
-#define OHFRIENDNAMSIZ 10 /* fman0-oh@1, ... fman1-oh@6 */
+#define OHFRIENDNAMSIZ 11 /* fman0-oh@1, ... fman1-oh@6 */
#define OHNODENAMSIZ 24 /* /fsl,dpaa/dpa-fman0-oh@1 */
#define BOND_OH_SUCCESS 0
#define BOND_OH_ERROR -1
@@ -76,11 +76,11 @@
pr_info("LAG:[CPU %d ln %d fn %s] - " fmt, smp_processor_id(), \
__LINE__, __func__, ##arg)
#else
-#define hw_lag_dbg(fmt, arg...)
+#define hw_lag_dbg(fmt, arg...) do {} while (0)
#endif
struct oh_port_priv {
- unsigned int oh_channel_id;
+ uint16_t oh_channel_id;
struct dpa_oh_config_s *oh_config;
struct dpa_fq *pcd_fqs[SLAVES_PER_BOND];
struct dpa_fq *oh_defq, *oh_errq;
diff --git a/drivers/net/bonding/hw_oh_pcd.c b/drivers/net/bonding/hw_oh_pcd.c
index 6111038..9ab5b01 100644
--- a/drivers/net/bonding/hw_oh_pcd.c
+++ b/drivers/net/bonding/hw_oh_pcd.c
@@ -553,6 +553,9 @@ netEnvParams_err:
int release_pcd_mem(struct bonding *bond)
{
+ if (!bond->params.ohp)
+ return BOND_OH_SUCCESS;
+
kfree(bond->params.ohp->prsParam);
kfree(bond->params.ohp->kgParam);
kfree(bond->params.ohp->pcdParam);
diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c
index e59c42b..ae14805 100644
--- a/drivers/net/can/c_can/c_can.c
+++ b/drivers/net/can/c_can/c_can.c
@@ -830,9 +830,6 @@ static int c_can_do_rx_poll(struct net_device *dev, int quota)
continue;
}
- if (msg_ctrl_save & IF_MCONT_EOB)
- return num_rx_pkts;
-
if (!(msg_ctrl_save & IF_MCONT_NEWDAT))
continue;
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c
index 539239d..a4694aa 100644
--- a/drivers/net/can/dev.c
+++ b/drivers/net/can/dev.c
@@ -385,7 +385,7 @@ void can_free_echo_skb(struct net_device *dev, unsigned int idx)
BUG_ON(idx >= priv->echo_skb_max);
if (priv->echo_skb[idx]) {
- kfree_skb(priv->echo_skb[idx]);
+ dev_kfree_skb_any(priv->echo_skb[idx]);
priv->echo_skb[idx] = NULL;
}
}
@@ -643,10 +643,14 @@ static int can_changelink(struct net_device *dev,
if (dev->flags & IFF_UP)
return -EBUSY;
cm = nla_data(data[IFLA_CAN_CTRLMODE]);
- if (cm->flags & ~priv->ctrlmode_supported)
+
+ /* check whether changed bits are allowed to be modified */
+ if (cm->mask & ~priv->ctrlmode_supported)
return -EOPNOTSUPP;
+
+ /* clear bits to be modified and copy the flag values */
priv->ctrlmode &= ~cm->mask;
- priv->ctrlmode |= cm->flags;
+ priv->ctrlmode |= (cm->flags & cm->mask);
}
if (data[IFLA_CAN_BITTIMING]) {
diff --git a/drivers/net/can/sja1000/peak_pci.c b/drivers/net/can/sja1000/peak_pci.c
index 6b6f0ad..7042f5f 100644
--- a/drivers/net/can/sja1000/peak_pci.c
+++ b/drivers/net/can/sja1000/peak_pci.c
@@ -551,7 +551,7 @@ static int peak_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
struct sja1000_priv *priv;
struct peak_pci_chan *chan;
- struct net_device *dev;
+ struct net_device *dev, *prev_dev;
void __iomem *cfg_base, *reg_base;
u16 sub_sys_id, icr;
int i, err, channels;
@@ -687,11 +687,13 @@ failure_remove_channels:
writew(0x0, cfg_base + PITA_ICR + 2);
chan = NULL;
- for (dev = pci_get_drvdata(pdev); dev; dev = chan->prev_dev) {
- unregister_sja1000dev(dev);
- free_sja1000dev(dev);
+ for (dev = pci_get_drvdata(pdev); dev; dev = prev_dev) {
priv = netdev_priv(dev);
chan = priv->priv;
+ prev_dev = chan->prev_dev;
+
+ unregister_sja1000dev(dev);
+ free_sja1000dev(dev);
}
/* free any PCIeC resources too */
@@ -725,10 +727,12 @@ static void peak_pci_remove(struct pci_dev *pdev)
/* Loop over all registered devices */
while (1) {
+ struct net_device *prev_dev = chan->prev_dev;
+
dev_info(&pdev->dev, "removing device %s\n", dev->name);
unregister_sja1000dev(dev);
free_sja1000dev(dev);
- dev = chan->prev_dev;
+ dev = prev_dev;
if (!dev) {
/* do that only for first channel */
diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c
index 25377e5..3c28d1f 100644
--- a/drivers/net/can/slcan.c
+++ b/drivers/net/can/slcan.c
@@ -54,6 +54,7 @@
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/workqueue.h>
#include <linux/can.h>
#include <linux/can/skb.h>
@@ -87,6 +88,7 @@ struct slcan {
struct tty_struct *tty; /* ptr to TTY structure */
struct net_device *dev; /* easy for intr handling */
spinlock_t lock;
+ struct work_struct tx_work; /* Flushes transmit buffer */
/* These are pointers to the malloc()ed frame buffers. */
unsigned char rbuff[SLC_MTU]; /* receiver buffer */
@@ -311,34 +313,44 @@ static void slc_encaps(struct slcan *sl, struct can_frame *cf)
sl->dev->stats.tx_bytes += cf->can_dlc;
}
-/*
- * Called by the driver when there's room for more data. If we have
- * more packets to send, we send them here.
- */
-static void slcan_write_wakeup(struct tty_struct *tty)
+/* Write out any remaining transmit buffer. Scheduled when tty is writable */
+static void slcan_transmit(struct work_struct *work)
{
+ struct slcan *sl = container_of(work, struct slcan, tx_work);
int actual;
- struct slcan *sl = (struct slcan *) tty->disc_data;
+ spin_lock_bh(&sl->lock);
/* First make sure we're connected. */
- if (!sl || sl->magic != SLCAN_MAGIC || !netif_running(sl->dev))
+ if (!sl->tty || sl->magic != SLCAN_MAGIC || !netif_running(sl->dev)) {
+ spin_unlock_bh(&sl->lock);
return;
+ }
- spin_lock(&sl->lock);
if (sl->xleft <= 0) {
/* Now serial buffer is almost free & we can start
* transmission of another packet */
sl->dev->stats.tx_packets++;
- clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
- spin_unlock(&sl->lock);
+ clear_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags);
+ spin_unlock_bh(&sl->lock);
netif_wake_queue(sl->dev);
return;
}
- actual = tty->ops->write(tty, sl->xhead, sl->xleft);
+ actual = sl->tty->ops->write(sl->tty, sl->xhead, sl->xleft);
sl->xleft -= actual;
sl->xhead += actual;
- spin_unlock(&sl->lock);
+ spin_unlock_bh(&sl->lock);
+}
+
+/*
+ * Called by the driver when there's room for more data.
+ * Schedule the transmit.
+ */
+static void slcan_write_wakeup(struct tty_struct *tty)
+{
+ struct slcan *sl = tty->disc_data;
+
+ schedule_work(&sl->tx_work);
}
/* Send a can_frame to a TTY queue. */
@@ -524,6 +536,7 @@ static struct slcan *slc_alloc(dev_t line)
sl->magic = SLCAN_MAGIC;
sl->dev = dev;
spin_lock_init(&sl->lock);
+ INIT_WORK(&sl->tx_work, slcan_transmit);
slcan_devs[i] = dev;
return sl;
@@ -622,8 +635,12 @@ static void slcan_close(struct tty_struct *tty)
if (!sl || sl->magic != SLCAN_MAGIC || sl->tty != tty)
return;
+ spin_lock_bh(&sl->lock);
tty->disc_data = NULL;
sl->tty = NULL;
+ spin_unlock_bh(&sl->lock);
+
+ flush_work(&sl->tx_work);
/* Flush network side */
unregister_netdev(sl->dev);
diff --git a/drivers/net/can/usb/esd_usb2.c b/drivers/net/can/usb/esd_usb2.c
index ac6177d..91654d0 100644
--- a/drivers/net/can/usb/esd_usb2.c
+++ b/drivers/net/can/usb/esd_usb2.c
@@ -1142,6 +1142,7 @@ static void esd_usb2_disconnect(struct usb_interface *intf)
}
}
unlink_all_urbs(dev);
+ kfree(dev);
}
}
diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c
index cc3df8a..63fb90b 100644
--- a/drivers/net/can/usb/kvaser_usb.c
+++ b/drivers/net/can/usb/kvaser_usb.c
@@ -1238,6 +1238,9 @@ static int kvaser_usb_close(struct net_device *netdev)
if (err)
netdev_warn(netdev, "Cannot stop device, error %d\n", err);
+ /* reset tx contexts */
+ kvaser_usb_unlink_tx_urbs(priv);
+
priv->can.state = CAN_STATE_STOPPED;
close_candev(priv->netdev);
@@ -1286,12 +1289,14 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
if (!urb) {
netdev_err(netdev, "No memory left for URBs\n");
stats->tx_dropped++;
- goto nourbmem;
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
}
buf = kmalloc(sizeof(struct kvaser_msg), GFP_ATOMIC);
if (!buf) {
stats->tx_dropped++;
+ dev_kfree_skb(skb);
goto nobufmem;
}
@@ -1326,6 +1331,7 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
}
}
+ /* This should never happen; it implies a flow control bug */
if (!context) {
netdev_warn(netdev, "cannot find free context\n");
ret = NETDEV_TX_BUSY;
@@ -1356,9 +1362,6 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
if (unlikely(err)) {
can_free_echo_skb(netdev, context->echo_index);
- skb = NULL; /* set to NULL to avoid double free in
- * dev_kfree_skb(skb) */
-
atomic_dec(&priv->active_tx_urbs);
usb_unanchor_urb(urb);
@@ -1380,8 +1383,6 @@ releasebuf:
kfree(buf);
nobufmem:
usb_free_urb(urb);
-nourbmem:
- dev_kfree_skb(skb);
return ret;
}
@@ -1493,6 +1494,10 @@ static int kvaser_usb_init_one(struct usb_interface *intf,
struct kvaser_usb_net_priv *priv;
int i, err;
+ err = kvaser_usb_send_simple_msg(dev, CMD_RESET_CHIP, channel);
+ if (err)
+ return err;
+
netdev = alloc_candev(sizeof(*priv), MAX_TX_URBS);
if (!netdev) {
dev_err(&intf->dev, "Cannot alloc candev\n");
@@ -1596,9 +1601,6 @@ static int kvaser_usb_probe(struct usb_interface *intf,
usb_set_intfdata(intf, dev);
- for (i = 0; i < MAX_NET_DEVICES; i++)
- kvaser_usb_send_simple_msg(dev, CMD_RESET_CHIP, i);
-
err = kvaser_usb_get_software_info(dev);
if (err) {
dev_err(&intf->dev,
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
index 0b7a4c3..03e7f0c 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
@@ -734,7 +734,7 @@ static int peak_usb_create_dev(struct peak_usb_adapter *peak_usb_adapter,
dev->cmd_buf = kmalloc(PCAN_USB_MAX_CMD_LEN, GFP_KERNEL);
if (!dev->cmd_buf) {
err = -ENOMEM;
- goto lbl_set_intf_data;
+ goto lbl_free_candev;
}
dev->udev = usb_dev;
@@ -773,7 +773,7 @@ static int peak_usb_create_dev(struct peak_usb_adapter *peak_usb_adapter,
err = register_candev(netdev);
if (err) {
dev_err(&intf->dev, "couldn't register CAN device: %d\n", err);
- goto lbl_free_cmd_buf;
+ goto lbl_restore_intf_data;
}
if (dev->prev_siblings)
@@ -786,14 +786,14 @@ static int peak_usb_create_dev(struct peak_usb_adapter *peak_usb_adapter,
if (dev->adapter->dev_init) {
err = dev->adapter->dev_init(dev);
if (err)
- goto lbl_free_cmd_buf;
+ goto lbl_unregister_candev;
}
/* set bus off */
if (dev->adapter->dev_set_bus) {
err = dev->adapter->dev_set_bus(dev, 0);
if (err)
- goto lbl_free_cmd_buf;
+ goto lbl_unregister_candev;
}
/* get device number early */
@@ -805,11 +805,14 @@ static int peak_usb_create_dev(struct peak_usb_adapter *peak_usb_adapter,
return 0;
-lbl_free_cmd_buf:
- kfree(dev->cmd_buf);
+lbl_unregister_candev:
+ unregister_candev(netdev);
-lbl_set_intf_data:
+lbl_restore_intf_data:
usb_set_intfdata(intf, dev->prev_siblings);
+ kfree(dev->cmd_buf);
+
+lbl_free_candev:
free_candev(netdev);
return err;
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
index 263dd92..f7f796a 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
@@ -333,8 +333,6 @@ static int pcan_usb_pro_send_req(struct peak_usb_device *dev, int req_id,
if (!(dev->state & PCAN_USB_STATE_CONNECTED))
return 0;
- memset(req_addr, '\0', req_size);
-
req_type = USB_TYPE_VENDOR | USB_RECIP_OTHER;
switch (req_id) {
@@ -345,6 +343,7 @@ static int pcan_usb_pro_send_req(struct peak_usb_device *dev, int req_id,
default:
p = usb_rcvctrlpipe(dev->udev, 0);
req_type |= USB_DIR_IN;
+ memset(req_addr, '\0', req_size);
break;
}
diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c
index 46dfb13..81576c6 100644
--- a/drivers/net/ethernet/allwinner/sun4i-emac.c
+++ b/drivers/net/ethernet/allwinner/sun4i-emac.c
@@ -726,6 +726,7 @@ static int emac_open(struct net_device *dev)
ret = emac_mdio_probe(dev);
if (ret < 0) {
+ free_irq(dev->irq, dev);
netdev_err(dev, "cannot probe MDIO bus\n");
return ret;
}
diff --git a/drivers/net/ethernet/atheros/alx/main.c b/drivers/net/ethernet/atheros/alx/main.c
index 6305a5d..754ac8e 100644
--- a/drivers/net/ethernet/atheros/alx/main.c
+++ b/drivers/net/ethernet/atheros/alx/main.c
@@ -184,15 +184,16 @@ static void alx_schedule_reset(struct alx_priv *alx)
schedule_work(&alx->reset_wk);
}
-static bool alx_clean_rx_irq(struct alx_priv *alx, int budget)
+static int alx_clean_rx_irq(struct alx_priv *alx, int budget)
{
struct alx_rx_queue *rxq = &alx->rxq;
struct alx_rrd *rrd;
struct alx_buffer *rxb;
struct sk_buff *skb;
u16 length, rfd_cleaned = 0;
+ int work = 0;
- while (budget > 0) {
+ while (work < budget) {
rrd = &rxq->rrd[rxq->rrd_read_idx];
if (!(rrd->word3 & cpu_to_le32(1 << RRD_UPDATED_SHIFT)))
break;
@@ -203,7 +204,7 @@ static bool alx_clean_rx_irq(struct alx_priv *alx, int budget)
ALX_GET_FIELD(le32_to_cpu(rrd->word0),
RRD_NOR) != 1) {
alx_schedule_reset(alx);
- return 0;
+ return work;
}
rxb = &rxq->bufs[rxq->read_idx];
@@ -243,7 +244,7 @@ static bool alx_clean_rx_irq(struct alx_priv *alx, int budget)
}
napi_gro_receive(&alx->napi, skb);
- budget--;
+ work++;
next_pkt:
if (++rxq->read_idx == alx->rx_ringsz)
@@ -258,21 +259,22 @@ next_pkt:
if (rfd_cleaned)
alx_refill_rx_ring(alx, GFP_ATOMIC);
- return budget > 0;
+ return work;
}
static int alx_poll(struct napi_struct *napi, int budget)
{
struct alx_priv *alx = container_of(napi, struct alx_priv, napi);
struct alx_hw *hw = &alx->hw;
- bool complete = true;
unsigned long flags;
+ bool tx_complete;
+ int work;
- complete = alx_clean_tx_irq(alx) &&
- alx_clean_rx_irq(alx, budget);
+ tx_complete = alx_clean_tx_irq(alx);
+ work = alx_clean_rx_irq(alx, budget);
- if (!complete)
- return 1;
+ if (!tx_complete || work == budget)
+ return budget;
napi_complete(&alx->napi);
@@ -284,7 +286,7 @@ static int alx_poll(struct napi_struct *napi, int budget)
alx_post_write(hw);
- return 0;
+ return work;
}
static irqreturn_t alx_intr_handle(struct alx_priv *alx, u32 intr)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
index c5e375d..930ced0 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
@@ -337,6 +337,7 @@ struct sw_tx_bd {
u8 flags;
/* Set on the first BD descriptor when there is a split BD */
#define BNX2X_TSO_SPLIT_BD (1<<0)
+#define BNX2X_HAS_SECOND_PBD (1<<1)
};
struct sw_rx_page {
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index 0399458..c3ba4bf 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -186,6 +186,12 @@ static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata,
--nbd;
bd_idx = TX_BD(NEXT_TX_IDX(bd_idx));
+ if (tx_buf->flags & BNX2X_HAS_SECOND_PBD) {
+ /* Skip second parse bd... */
+ --nbd;
+ bd_idx = TX_BD(NEXT_TX_IDX(bd_idx));
+ }
+
/* TSO headers+data bds share a common mapping. See bnx2x_tx_split() */
if (tx_buf->flags & BNX2X_TSO_SPLIT_BD) {
tx_data_bd = &txdata->tx_desc_ring[bd_idx].reg_bd;
@@ -755,7 +761,8 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp,
return;
}
- bnx2x_frag_free(fp, new_data);
+ if (new_data)
+ bnx2x_frag_free(fp, new_data);
drop:
/* drop the packet and keep the buffer in the bin */
DP(NETIF_MSG_RX_STATUS,
@@ -3821,6 +3828,9 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* set encapsulation flag in start BD */
SET_FLAG(tx_start_bd->general_data,
ETH_TX_START_BD_TUNNEL_EXIST, 1);
+
+ tx_buf->flags |= BNX2X_HAS_SECOND_PBD;
+
nbd++;
} else if (xmit_type & XMIT_CSUM) {
/* Set PBD in checksum offload case w/o encapsulation */
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
index e8efa1c9..97fe8e6 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
@@ -2864,9 +2864,16 @@ static void bnx2x_self_test(struct net_device *dev,
memset(buf, 0, sizeof(u64) * BNX2X_NUM_TESTS(bp));
+ if (bnx2x_test_nvram(bp) != 0) {
+ if (!IS_MF(bp))
+ buf[4] = 1;
+ else
+ buf[0] = 1;
+ etest->flags |= ETH_TEST_FL_FAILED;
+ }
+
if (!netif_running(dev)) {
- DP(BNX2X_MSG_ETHTOOL,
- "Can't perform self-test when interface is down\n");
+ DP(BNX2X_MSG_ETHTOOL, "Interface is down\n");
return;
}
@@ -2928,13 +2935,7 @@ static void bnx2x_self_test(struct net_device *dev,
/* wait until link state is restored */
bnx2x_wait_for_link(bp, link_up, is_serdes);
}
- if (bnx2x_test_nvram(bp) != 0) {
- if (!IS_MF(bp))
- buf[4] = 1;
- else
- buf[0] = 1;
- etest->flags |= ETH_TEST_FL_FAILED;
- }
+
if (bnx2x_test_intr(bp) != 0) {
if (!IS_MF(bp))
buf[5] = 1;
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
index 9fbeee5..32c92ab 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
@@ -1217,9 +1217,6 @@ static void bnx2x_set_one_vlan_mac_e1h(struct bnx2x *bp,
ETH_VLAN_FILTER_CLASSIFY, config);
}
-#define list_next_entry(pos, member) \
- list_entry((pos)->member.next, typeof(*(pos)), member)
-
/**
* bnx2x_vlan_mac_restore - reconfigure next MAC/VLAN/VLAN-MAC element
*
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index aae7ba6..98ded21 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -337,6 +337,11 @@ static DEFINE_PCI_DEVICE_TABLE(tg3_pci_tbl) = {
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5762)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5725)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5727)},
+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57764)},
+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57767)},
+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57787)},
+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57782)},
+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57786)},
{PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX)},
{PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9MXX)},
{PCI_DEVICE(PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1000)},
@@ -6893,7 +6898,8 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget)
skb->protocol = eth_type_trans(skb, tp->dev);
if (len > (tp->dev->mtu + ETH_HLEN) &&
- skb->protocol != htons(ETH_P_8021Q)) {
+ skb->protocol != htons(ETH_P_8021Q) &&
+ skb->protocol != htons(ETH_P_8021AD)) {
dev_kfree_skb(skb);
goto drop_it_no_recycle;
}
@@ -7885,8 +7891,6 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
entry = tnapi->tx_prod;
base_flags = 0;
- if (skb->ip_summed == CHECKSUM_PARTIAL)
- base_flags |= TXD_FLAG_TCPUDP_CSUM;
mss = skb_shinfo(skb)->gso_size;
if (mss) {
@@ -7902,6 +7906,13 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb) - ETH_HLEN;
+ /* HW/FW can not correctly segment packets that have been
+ * vlan encapsulated.
+ */
+ if (skb->protocol == htons(ETH_P_8021Q) ||
+ skb->protocol == htons(ETH_P_8021AD))
+ return tg3_tso_bug(tp, skb);
+
if (!skb_is_gso_v6(skb)) {
iph->check = 0;
iph->tot_len = htons(mss + hdr_len);
@@ -7948,6 +7959,17 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
base_flags |= tsflags << 12;
}
}
+ } else if (skb->ip_summed == CHECKSUM_PARTIAL) {
+ /* HW/FW can not correctly checksum packets that have been
+ * vlan encapsulated.
+ */
+ if (skb->protocol == htons(ETH_P_8021Q) ||
+ skb->protocol == htons(ETH_P_8021AD)) {
+ if (skb_checksum_help(skb))
+ goto drop;
+ } else {
+ base_flags |= TXD_FLAG_TCPUDP_CSUM;
+ }
}
if (tg3_flag(tp, USE_JUMBO_BDFLAG) &&
@@ -8501,7 +8523,8 @@ static int tg3_init_rings(struct tg3 *tp)
if (tnapi->rx_rcb)
memset(tnapi->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp));
- if (tg3_rx_prodring_alloc(tp, &tnapi->prodring)) {
+ if (tnapi->prodring.rx_std &&
+ tg3_rx_prodring_alloc(tp, &tnapi->prodring)) {
tg3_free_rings(tp);
return -ENOMEM;
}
@@ -12197,7 +12220,9 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e
if (tg3_flag(tp, MAX_RXPEND_64) &&
tp->rx_pending > 63)
tp->rx_pending = 63;
- tp->rx_jumbo_pending = ering->rx_jumbo_pending;
+
+ if (tg3_flag(tp, JUMBO_RING_ENABLE))
+ tp->rx_jumbo_pending = ering->rx_jumbo_pending;
for (i = 0; i < tp->irq_max; i++)
tp->napi[i].tx_pending = ering->tx_pending;
@@ -15758,9 +15783,12 @@ static void tg3_detect_asic_rev(struct tg3 *tp, u32 misc_ctrl_reg)
tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 ||
tp->pdev->device == TG3PCI_DEVICE_TIGON3_5719 ||
tp->pdev->device == TG3PCI_DEVICE_TIGON3_5720 ||
+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_57767 ||
+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_57764 ||
tp->pdev->device == TG3PCI_DEVICE_TIGON3_5762 ||
tp->pdev->device == TG3PCI_DEVICE_TIGON3_5725 ||
- tp->pdev->device == TG3PCI_DEVICE_TIGON3_5727)
+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5727 ||
+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_57787)
reg = TG3PCI_GEN2_PRODID_ASICREV;
else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57781 ||
tp->pdev->device == TG3PCI_DEVICE_TIGON3_57785 ||
@@ -17411,9 +17439,12 @@ static int tg3_init_one(struct pci_dev *pdev,
tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 ||
tp->pdev->device == TG3PCI_DEVICE_TIGON3_5719 ||
tp->pdev->device == TG3PCI_DEVICE_TIGON3_5720 ||
+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_57767 ||
+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_57764 ||
tp->pdev->device == TG3PCI_DEVICE_TIGON3_5762 ||
tp->pdev->device == TG3PCI_DEVICE_TIGON3_5725 ||
- tp->pdev->device == TG3PCI_DEVICE_TIGON3_5727) {
+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5727 ||
+ tp->pdev->device == TG3PCI_DEVICE_TIGON3_57787) {
tg3_flag_set(tp, ENABLE_APE);
tp->aperegs = pci_ioremap_bar(pdev, BAR_2);
if (!tp->aperegs) {
@@ -17541,23 +17572,6 @@ static int tg3_init_one(struct pci_dev *pdev,
goto err_out_apeunmap;
}
- /*
- * Reset chip in case UNDI or EFI driver did not shutdown
- * DMA self test will enable WDMAC and we'll see (spurious)
- * pending DMA on the PCI bus at that point.
- */
- if ((tr32(HOSTCC_MODE) & HOSTCC_MODE_ENABLE) ||
- (tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) {
- tw32(MEMARB_MODE, MEMARB_MODE_ENABLE);
- tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
- }
-
- err = tg3_test_dma(tp);
- if (err) {
- dev_err(&pdev->dev, "DMA engine test failed, aborting\n");
- goto err_out_apeunmap;
- }
-
intmbx = MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW;
rcvmbx = MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW;
sndmbx = MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW;
@@ -17602,6 +17616,23 @@ static int tg3_init_one(struct pci_dev *pdev,
sndmbx += 0xc;
}
+ /*
+ * Reset chip in case UNDI or EFI driver did not shutdown
+ * DMA self test will enable WDMAC and we'll see (spurious)
+ * pending DMA on the PCI bus at that point.
+ */
+ if ((tr32(HOSTCC_MODE) & HOSTCC_MODE_ENABLE) ||
+ (tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) {
+ tw32(MEMARB_MODE, MEMARB_MODE_ENABLE);
+ tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
+ }
+
+ err = tg3_test_dma(tp);
+ if (err) {
+ dev_err(&pdev->dev, "DMA engine test failed, aborting\n");
+ goto err_out_apeunmap;
+ }
+
tg3_init_coal(tp);
pci_set_drvdata(pdev, dev);
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h
index ac50e7c..cf9917b 100644
--- a/drivers/net/ethernet/broadcom/tg3.h
+++ b/drivers/net/ethernet/broadcom/tg3.h
@@ -68,6 +68,9 @@
#define TG3PCI_DEVICE_TIGON3_5762 0x1687
#define TG3PCI_DEVICE_TIGON3_5725 0x1643
#define TG3PCI_DEVICE_TIGON3_5727 0x16f3
+#define TG3PCI_DEVICE_TIGON3_57764 0x1642
+#define TG3PCI_DEVICE_TIGON3_57767 0x1683
+#define TG3PCI_DEVICE_TIGON3_57787 0x1641
/* 0x04 --> 0x2c unused */
#define TG3PCI_SUBVENDOR_ID_BROADCOM PCI_VENDOR_ID_BROADCOM
#define TG3PCI_SUBDEVICE_ID_BROADCOM_95700A6 0x1644
diff --git a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c
index b78e69e..45ce6e2 100644
--- a/drivers/net/ethernet/brocade/bna/bnad.c
+++ b/drivers/net/ethernet/brocade/bna/bnad.c
@@ -3300,17 +3300,12 @@ bnad_pci_init(struct bnad *bnad,
err = pci_request_regions(pdev, BNAD_NAME);
if (err)
goto disable_device;
- if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)) &&
- !dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64))) {
+ if (!dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64))) {
*using_dac = true;
} else {
- err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
- if (err) {
- err = dma_set_coherent_mask(&pdev->dev,
- DMA_BIT_MASK(32));
- if (err)
- goto release_regions;
- }
+ err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+ if (err)
+ goto release_regions;
*using_dac = false;
}
pci_set_master(pdev);
diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c
index 9257869..b020d1c 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -29,7 +29,6 @@
#include <linux/of_device.h>
#include <linux/of_mdio.h>
#include <linux/of_net.h>
-#include <linux/pinctrl/consumer.h>
#include "macb.h"
@@ -1755,7 +1754,6 @@ static int __init macb_probe(struct platform_device *pdev)
struct phy_device *phydev;
u32 config;
int err = -ENXIO;
- struct pinctrl *pinctrl;
const char *mac;
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1764,15 +1762,6 @@ static int __init macb_probe(struct platform_device *pdev)
goto err_out;
}
- pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
- if (IS_ERR(pinctrl)) {
- err = PTR_ERR(pinctrl);
- if (err == -EPROBE_DEFER)
- goto err_out;
-
- dev_warn(&pdev->dev, "No pinctrl provided\n");
- }
-
err = -ENOMEM;
dev = alloc_etherdev(sizeof(*bp));
if (!dev)
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c
index 7b756cf9..c298239 100644
--- a/drivers/net/ethernet/cisco/enic/enic_main.c
+++ b/drivers/net/ethernet/cisco/enic/enic_main.c
@@ -1043,10 +1043,14 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq,
skb->l4_rxhash = true;
}
- if ((netdev->features & NETIF_F_RXCSUM) && !csum_not_calc) {
- skb->csum = htons(checksum);
- skb->ip_summed = CHECKSUM_COMPLETE;
- }
+ /* Hardware does not provide whole packet checksum. It only
+ * provides pseudo checksum. Since hw validates the packet
+ * checksum but not provide us the checksum value. use
+ * CHECSUM_UNNECESSARY.
+ */
+ if ((netdev->features & NETIF_F_RXCSUM) && tcp_udp_csum_ok &&
+ ipv4_csum_ok)
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
if (vlan_stripped)
__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan_tci);
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 2c38cc4..5226c99 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -2632,7 +2632,7 @@ static int be_open(struct net_device *netdev)
for_all_evt_queues(adapter, eqo, i) {
napi_enable(&eqo->napi);
- be_eq_notify(adapter, eqo->q.id, true, false, 0);
+ be_eq_notify(adapter, eqo->q.id, true, true, 0);
}
adapter->flags |= BE_FLAGS_NAPI_ENABLED;
diff --git a/drivers/net/ethernet/freescale/dpa/Kconfig b/drivers/net/ethernet/freescale/dpa/Kconfig
index a459141..844bdfe 100644
--- a/drivers/net/ethernet/freescale/dpa/Kconfig
+++ b/drivers/net/ethernet/freescale/dpa/Kconfig
@@ -1,5 +1,5 @@
menuconfig FSL_DPAA_ETH
- bool "DPAA Ethernet"
+ tristate "DPAA Ethernet"
depends on FSL_SOC && FSL_BMAN && FSL_QMAN && FSL_FMAN
select PHYLIB
---help---
@@ -49,6 +49,25 @@ config FSL_CAPWAP_BRIDGE_ZMC
endif # FSL_CAPWAP
+config FSL_DPAA_ADVANCED_DRIVERS
+ bool "Advanced DPAA Ethernet drivers"
+ depends on FSL_DPAA_ETH
+ default y
+ ---help---
+ Besides the standard DPAA Ethernet driver there are available other flavours
+ of DPAA drivers that support advanced scenarios:
+ - DPAA Shared MAC driver
+ - DPAA MAC-less driver
+ - DPAA Proxy initialization driver (for USDPAA)
+ Select this to also build the advanced drivers.
+
+config FSL_DPAA_GENERIC_DRIVER
+ bool "Generic DPAA Ethernet driver"
+ depends on FSL_DPAA_ETH
+ default y
+ ---help---
+ This enables the DPAA Generic driver (oNIC).
+
config FSL_DPAA_ETH_JUMBO_FRAME
bool "Optimize for jumbo frames"
default n
@@ -62,14 +81,14 @@ config FSL_DPAA_ETH_JUMBO_FRAME
the system memory.
config FSL_DPAA_TS
- tristate "Linux compliant timestamping"
+ bool "Linux compliant timestamping"
depends on FSL_DPAA_ETH
default n
---help---
Enable Linux API compliant timestamping support.
config FSL_DPAA_1588
- tristate "IEEE 1588-compliant timestamping"
+ bool "IEEE 1588-compliant timestamping"
depends on FSL_DPAA_ETH
select FSL_DPAA_TS
default n
@@ -143,7 +162,7 @@ config FSL_DPAA_INGRESS_CS_THRESHOLD
Traffic piling up above this value will be rejected by QMan and discarded by FMan.
config FSL_DPAA_ETH_DEBUGFS
- tristate "DPAA Ethernet debugfs interface"
+ bool "DPAA Ethernet debugfs interface"
depends on DEBUG_FS && FSL_DPAA_ETH
default y
---help---
diff --git a/drivers/net/ethernet/freescale/dpa/Makefile b/drivers/net/ethernet/freescale/dpa/Makefile
index 929db39..1d1b506 100644
--- a/drivers/net/ethernet/freescale/dpa/Makefile
+++ b/drivers/net/ethernet/freescale/dpa/Makefile
@@ -8,26 +8,47 @@ include $(srctree)/drivers/net/ethernet/freescale/fman/ncsw_config.mk
ccflags-y += -I$(NET_DPA)
-obj-$(CONFIG_FSL_DPAA_1588) += dpaa_1588.o
-# dpaa_debugfs needs to be initialized before dpaa_eth
-obj-$(CONFIG_FSL_DPAA_ETH_DEBUGFS) += dpaa_debugfs.o dpaa_generic_debugfs.o
-obj-$(CONFIG_FSL_DPAA_ETH) += fsl-mac.o fsl-dpa.o fsl-dpa-common.o \
- fsl-dpa-base.o fsl-dpa-shared.o fsl-dpa-proxy.o fsl-dpa-macless.o \
- fsl-dpa-generic.o
-obj-$(CONFIG_FSL_DPAA_OFFLINE_PORTS) += fsl-oh.o
+obj-$(CONFIG_FSL_DPAA_ETH) += fsl_mac.o fsl_dpa.o
obj-$(CONFIG_PTP_1588_CLOCK_DPAA) += dpaa_ptp.o
-fsl-dpa-objs := dpaa_ethtool.o dpaa_eth_sysfs.o \
- dpaa_eth.o dpaa_eth_sg.o
-fsl-dpa-common-objs := dpaa_eth_common.o
-fsl-dpa-base-objs := dpaa_eth_base.o
-fsl-dpa-shared-objs := dpaa_eth_shared.o
-fsl-dpa-proxy-objs := dpaa_eth_proxy.o
-fsl-dpa-macless-objs := dpaa_eth_macless.o
-fsl-dpa-generic-objs := dpaa_eth_generic.o dpaa_eth_generic_sysfs.o \
- dpaa_generic_ethtool.o
-fsl-mac-objs := mac.o mac-api.o
-fsl-oh-objs := offline_port.o
+fsl_dpa-objs += dpaa_ethtool.o dpaa_eth_sysfs.o dpaa_eth.o dpaa_eth_sg.o dpaa_eth_common.o
+ifeq ($(CONFIG_FSL_DPAA_ETH_DEBUGFS),y)
+fsl_dpa-objs += dpaa_debugfs.o
+endif
+ifeq ($(CONFIG_FSL_DPAA_1588),y)
+fsl_dpa-objs += dpaa_1588.o
+endif
+
+fsl_mac-objs += mac.o mac-api.o
+
+# Advanced drivers
+ifeq ($(CONFIG_FSL_DPAA_ADVANCED_DRIVERS),y)
+obj-$(CONFIG_FSL_DPAA_ETH) += fsl_advanced.o
+
+fsl_advanced-objs += dpaa_eth_base.o
+# suport for multiple drivers per kernel module comes in kernel 3.14
+# so we are forced to generate several modules for the advanced drivers
+fsl_proxy-objs += dpaa_eth_proxy.o
+fsl_shared-objs += dpaa_eth_shared.o
+fsl_macless-objs += dpaa_eth_macless.o
+
+ifeq ($(CONFIG_FSL_DPAA_OFFLINE_PORTS),y)
+obj-$(CONFIG_FSL_DPAA_ETH) += fsl_oh.o
+
+fsl_oh-objs += offline_port.o
+endif
+endif
+
+# Generic driver
+ifeq ($(CONFIG_FSL_DPAA_GENERIC_DRIVER),y)
+obj-$(CONFIG_FSL_DPAA_ETH) += fsl_generic.o
+
+fsl_generic-objs += dpaa_eth_generic.o dpaa_eth_generic_sysfs.o dpaa_generic_ethtool.o
+ifeq ($(CONFIG_FSL_DPAA_ETH_DEBUGFS),y)
+fsl_generic-objs += dpaa_generic_debugfs.o
+endif
+endif
+
obj-$(CONFIG_FSL_CAPWAP) += capwap/
# Needed by the tracing framework
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_1588.c b/drivers/net/ethernet/freescale/dpa/dpaa_1588.c
index 9f66640..3bf8cbc 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_1588.c
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_1588.c
@@ -578,14 +578,3 @@ void dpa_ptp_cleanup(struct dpa_priv_s *priv)
kfree(tsu);
}
EXPORT_SYMBOL(dpa_ptp_cleanup);
-
-static int __init __cold dpa_ptp_load(void)
-{
- return 0;
-}
-module_init(dpa_ptp_load);
-
-static void __exit __cold dpa_ptp_unload(void)
-{
-}
-module_exit(dpa_ptp_unload);
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_debugfs.c b/drivers/net/ethernet/freescale/dpa/dpaa_debugfs.c
index 1f22bd7..59c7338 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_debugfs.c
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_debugfs.c
@@ -32,7 +32,6 @@
#include <linux/module.h>
#include <linux/fsl_qman.h> /* struct qm_mcr_querycgr */
#include <linux/debugfs.h>
-#include <asm/debug.h>
#include "dpaa_debugfs.h"
#include "dpaa_eth.h" /* struct dpa_priv_s, dpa_percpu_priv_s, dpa_bp */
@@ -308,6 +307,8 @@ static int __cold dpa_debugfs_open(struct inode *inode, struct file *file)
int dpa_netdev_debugfs_create(struct net_device *net_dev)
{
struct dpa_priv_s *priv = netdev_priv(net_dev);
+ static int cnt;
+ char debugfs_file_name[100];
#ifdef CONFIG_FSL_DPAA_DBG_LOOP
char loop_file_name[100];
#endif
@@ -319,30 +320,29 @@ int dpa_netdev_debugfs_create(struct net_device *net_dev)
return -ENOMEM;
}
- priv->debugfs_file = debugfs_create_file(net_dev->name,
+ snprintf(debugfs_file_name, 100, "eth%d", ++cnt);
+ priv->debugfs_file = debugfs_create_file(debugfs_file_name,
S_IRUGO,
dpa_debugfs_root,
net_dev,
&dpa_debugfs_fops);
if (unlikely(priv->debugfs_file == NULL)) {
- netdev_err(net_dev, "debugfs_create_file(%s/%s/%s)",
- powerpc_debugfs_root->d_iname,
+ netdev_err(net_dev, "debugfs_create_file(%s/%s)",
dpa_debugfs_root->d_iname,
- net_dev->name);
+ debugfs_file_name);
return -ENOMEM;
}
#ifdef CONFIG_FSL_DPAA_DBG_LOOP
- sprintf(loop_file_name, "%s_loop", net_dev->name);
+ sprintf(loop_file_name, "eth%d_loop", cnt);
priv->debugfs_loop_file = debugfs_create_file(loop_file_name,
S_IRUGO,
dpa_debugfs_root,
net_dev,
&dpa_debugfs_lp_fops);
if (unlikely(priv->debugfs_loop_file == NULL)) {
- netdev_err(net_dev, "debugfs_create_file(%s/%s/%s)",
- powerpc_debugfs_root->d_iname,
+ netdev_err(net_dev, "debugfs_create_file(%s/%s)",
dpa_debugfs_root->d_iname,
loop_file_name);
@@ -362,30 +362,26 @@ void dpa_netdev_debugfs_remove(struct net_device *net_dev)
#endif
}
-static int __init dpa_debugfs_module_init(void)
+int __init dpa_debugfs_module_init(void)
{
int _errno = 0;
pr_info(KBUILD_MODNAME ": " DPA_DEBUGFS_DESCRIPTION " (" VERSION ")\n");
- dpa_debugfs_root = debugfs_create_dir(DPA_ETH_DEBUGFS_ROOT,
- powerpc_debugfs_root);
+ dpa_debugfs_root = debugfs_create_dir(DPA_ETH_DEBUGFS_ROOT, NULL);
+
if (unlikely(dpa_debugfs_root == NULL)) {
_errno = -ENOMEM;
pr_err(KBUILD_MODNAME ": %s:%hu:%s():\n",
KBUILD_BASENAME".c", __LINE__, __func__);
pr_err("\tdebugfs_create_dir(%s/"KBUILD_MODNAME") = %d\n",
- powerpc_debugfs_root->d_iname, _errno);
+ DPA_ETH_DEBUGFS_ROOT, _errno);
}
return _errno;
}
-static void __exit dpa_debugfs_module_exit(void)
+void __exit dpa_debugfs_module_exit(void)
{
debugfs_remove(dpa_debugfs_root);
}
-
-module_init(dpa_debugfs_module_init);
-module_exit(dpa_debugfs_module_exit);
-MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_debugfs.h b/drivers/net/ethernet/freescale/dpa/dpaa_debugfs.h
index f82cde5..63d3542 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_debugfs.h
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_debugfs.h
@@ -37,5 +37,7 @@
int dpa_netdev_debugfs_create(struct net_device *net_dev);
void dpa_netdev_debugfs_remove(struct net_device *net_dev);
+int __init dpa_debugfs_module_init(void);
+void __exit dpa_debugfs_module_exit(void);
#endif /* DPAA_DEBUGFS_H_ */
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth.c
index 08d1d3e..4167268 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth.c
@@ -373,6 +373,7 @@ int dpaa_eth_poll(struct napi_struct *napi, int budget)
return cleaned;
}
+EXPORT_SYMBOL(dpaa_eth_poll);
static void __hot _dpa_tx_conf(struct net_device *net_dev,
const struct dpa_priv_s *priv,
@@ -718,9 +719,9 @@ void dpa_private_napi_del(struct net_device *net_dev)
}
}
}
+EXPORT_SYMBOL(dpa_private_napi_del);
-static int dpa_private_netdev_init(struct device_node *dpa_node,
- struct net_device *net_dev)
+static int dpa_private_netdev_init(struct net_device *net_dev)
{
int i;
struct dpa_priv_s *priv = netdev_priv(net_dev);
@@ -755,7 +756,7 @@ static int dpa_private_netdev_init(struct device_node *dpa_node,
/* Advertise GRO support */
net_dev->features |= NETIF_F_GRO;
- return dpa_netdev_init(dpa_node, net_dev, mac_addr, tx_timeout);
+ return dpa_netdev_init(net_dev, mac_addr, tx_timeout);
}
static struct dpa_bp * __cold
@@ -769,7 +770,7 @@ dpa_priv_bp_probe(struct device *dev)
return ERR_PTR(-ENOMEM);
}
- dpa_bp->percpu_count = alloc_percpu(*dpa_bp->percpu_count);
+ dpa_bp->percpu_count = devm_alloc_percpu(dev, *dpa_bp->percpu_count);
dpa_bp->target_count = CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT;
dpa_bp->seed_cb = dpa_bp_priv_seed;
@@ -1042,10 +1043,10 @@ dpaa_eth_priv_probe(struct platform_device *_of_dev)
}
#endif
- priv->percpu_priv = alloc_percpu(*priv->percpu_priv);
+ priv->percpu_priv = devm_alloc_percpu(dev, *priv->percpu_priv);
if (priv->percpu_priv == NULL) {
- dev_err(dev, "alloc_percpu() failed\n");
+ dev_err(dev, "devm_alloc_percpu() failed\n");
err = -ENOMEM;
goto alloc_percpu_failed;
}
@@ -1060,7 +1061,7 @@ dpaa_eth_priv_probe(struct platform_device *_of_dev)
if (err < 0)
goto napi_add_failed;
- err = dpa_private_netdev_init(dpa_node, net_dev);
+ err = dpa_private_netdev_init(net_dev);
if (err < 0)
goto netdev_init_failed;
@@ -1078,25 +1079,23 @@ dpaa_eth_priv_probe(struct platform_device *_of_dev)
netdev_init_failed:
napi_add_failed:
dpa_private_napi_del(net_dev);
- free_percpu(priv->percpu_priv);
+alloc_percpu_failed:
#ifdef CONFIG_FMAN_PFC
pfc_mapping_failed:
#endif
-alloc_percpu_failed:
dpa_fq_free(dev, &priv->dpa_fq_list);
fq_alloc_failed:
+ qman_delete_cgr_safe(&priv->ingress_cgr);
qman_release_cgrid(priv->ingress_cgr.cgrid);
- qman_delete_cgr(&priv->ingress_cgr);
rx_cgr_init_failed:
+ qman_delete_cgr_safe(&priv->cgr_data.cgr);
qman_release_cgrid(priv->cgr_data.cgr.cgrid);
- qman_delete_cgr(&priv->cgr_data.cgr);
tx_cgr_init_failed:
add_channel_failed:
get_channel_failed:
dpa_bp_free(priv, priv->dpa_bp);
bp_create_failed:
fq_probe_failed:
- devm_kfree(dev, buf_layout);
alloc_failed:
mac_probe_failed:
dev_set_drvdata(dev, NULL);
@@ -1133,6 +1132,10 @@ static int __init __cold dpa_load(void)
pr_info(DPA_DESCRIPTION " (" VERSION ")\n");
+#ifdef CONFIG_FSL_DPAA_ETH_DEBUGFS
+ dpa_debugfs_module_init();
+#endif /* CONFIG_FSL_DPAA_ETH_DEBUGFS */
+
/* initialise dpaa_eth mirror values */
dpa_rx_extra_headroom = fm_get_rx_extra_headroom();
dpa_max_frm = fm_get_max_frm();
@@ -1163,6 +1166,15 @@ static void __exit __cold dpa_unload(void)
platform_driver_unregister(&dpa_driver);
+#ifdef CONFIG_FSL_DPAA_ETH_DEBUGFS
+ dpa_debugfs_module_exit();
+#endif /* CONFIG_FSL_DPAA_ETH_DEBUGFS */
+
+ /* Only one channel is used and needs to be relased after all
+ * interfaces are removed
+ */
+ dpa_release_channel();
+
pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
KBUILD_BASENAME".c", __func__);
}
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth.h b/drivers/net/ethernet/freescale/dpa/dpaa_eth.h
index 24504c0..99728f4 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_eth.h
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth.h
@@ -36,9 +36,6 @@
#include <linux/fsl_qman.h> /* struct qman_fq */
#include "fm_ext.h"
-#ifdef CONFIG_FSL_DPAA_ETH_DEBUGFS
-#include "dpaa_debugfs.h"
-#endif /* CONFIG_FSL_DPAA_ETH_DEBUGFS */
#include "dpaa_eth_trace.h"
extern int dpa_rx_extra_headroom;
@@ -471,7 +468,8 @@ dpa_fd_offset(const struct qm_fd *fd)
static inline int dpa_check_rx_mtu(struct sk_buff *skb, int mtu)
{
if (unlikely(skb->len > mtu))
- if ((skb->protocol != ETH_P_8021Q) || (skb->len > mtu + 4))
+ if ((skb->protocol != htons(ETH_P_8021Q))
+ || (skb->len > mtu + 4))
return -1;
return 0;
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_base.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth_base.c
index 2a744e5..9c2204d 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_base.c
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_base.c
@@ -29,6 +29,15 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
+#define pr_fmt(fmt) \
+ KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
+ KBUILD_BASENAME".c", __LINE__, __func__
+#else
+#define pr_fmt(fmt) \
+ KBUILD_MODNAME ": " fmt
+#endif
+
#include <linux/init.h>
#include <linux/module.h>
#include <linux/of_platform.h>
@@ -43,6 +52,14 @@
#include "dpaa_eth_common.h"
#include "dpaa_eth_base.h"
+#define DPA_DESCRIPTION "FSL DPAA Advanced drivers:"
+
+MODULE_LICENSE("Dual BSD/GPL");
+
+uint8_t advanced_debug = -1;
+module_param(advanced_debug, byte, S_IRUGO);
+MODULE_PARM_DESC(advanced_debug, "Module/Driver verbosity level");
+
static int dpa_bp_cmp(const void *dpa_bp0, const void *dpa_bp1)
{
return ((struct dpa_bp *)dpa_bp0)->size -
@@ -52,33 +69,24 @@ static int dpa_bp_cmp(const void *dpa_bp0, const void *dpa_bp1)
struct dpa_bp * __cold __must_check /* __attribute__((nonnull)) */
dpa_bp_probe(struct platform_device *_of_dev, size_t *count)
{
- int i, lenp, na, ns;
+ int i, lenp, na, ns, err;
struct device *dev;
struct device_node *dev_node;
- const phandle *phandle_prop;
- const uint32_t *bpid;
- const uint32_t *bpool_cfg;
+ const __be32 *bpool_cfg;
struct dpa_bp *dpa_bp;
+ u32 bpid;
dev = &_of_dev->dev;
- /* The default is one, if there's no property */
- *count = 1;
-
- /* Get the buffer pools to be used */
- phandle_prop = of_get_property(dev->of_node,
- "fsl,bman-buffer-pools", &lenp);
-
- if (phandle_prop)
- *count = lenp / sizeof(phandle);
- else {
- dev_err(dev,
- "missing fsl,bman-buffer-pools device tree entry\n");
+ *count = of_count_phandle_with_args(dev->of_node,
+ "fsl,bman-buffer-pools", NULL);
+ if (*count < 1) {
+ dev_err(dev, "missing fsl,bman-buffer-pools device tree entry\n");
return ERR_PTR(-EINVAL);
}
dpa_bp = devm_kzalloc(dev, *count * sizeof(*dpa_bp), GFP_KERNEL);
- if (unlikely(dpa_bp == NULL)) {
+ if (dpa_bp == NULL) {
dev_err(dev, "devm_kzalloc() failed\n");
return ERR_PTR(-ENOMEM);
}
@@ -92,10 +100,12 @@ dpa_bp_probe(struct platform_device *_of_dev, size_t *count)
na = of_n_addr_cells(dev_node);
ns = of_n_size_cells(dev_node);
- for (i = 0; i < *count && phandle_prop; i++) {
+ for (i = 0; i < *count; i++) {
of_node_put(dev_node);
- dev_node = of_find_node_by_phandle(phandle_prop[i]);
- if (unlikely(dev_node == NULL)) {
+
+ dev_node = of_parse_phandle(dev->of_node,
+ "fsl,bman-buffer-pools", i);
+ if (dev_node == NULL) {
dev_err(dev, "of_find_node_by_phandle() failed\n");
return ERR_PTR(-EFAULT);
}
@@ -108,13 +118,13 @@ dpa_bp_probe(struct platform_device *_of_dev, size_t *count)
goto _return_of_node_put;
}
- bpid = of_get_property(dev_node, "fsl,bpid", &lenp);
- if ((bpid == NULL) || (lenp != sizeof(*bpid))) {
- dev_err(dev, "fsl,bpid property not found.\n");
+ err = of_property_read_u32(dev_node, "fsl,bpid", &bpid);
+ if (err) {
+ dev_err(dev, "Cannot find buffer pool ID in the device tree\n");
dpa_bp = ERR_PTR(-EINVAL);
goto _return_of_node_put;
}
- dpa_bp[i].bpid = (uint8_t)*bpid;
+ dpa_bp[i].bpid = (uint8_t)bpid;
bpool_cfg = of_get_property(dev_node, "fsl,bpool-ethernet-cfg",
&lenp);
@@ -219,3 +229,18 @@ int dpa_bp_create(struct net_device *net_dev, struct dpa_bp *dpa_bp,
return 0;
}
+static int __init __cold dpa_advanced_load(void)
+{
+ pr_info(DPA_DESCRIPTION " (" VERSION ")\n");
+
+ return 0;
+}
+module_init(dpa_advanced_load);
+
+static void __exit __cold dpa_advanced_unload(void)
+{
+ pr_debug(KBUILD_MODNAME ": -> %s:%s()\n",
+ KBUILD_BASENAME".c", __func__);
+
+}
+module_exit(dpa_advanced_unload);
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_base.h b/drivers/net/ethernet/freescale/dpa/dpaa_eth_base.h
index 5b5ef1e..a75e270 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_base.h
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_base.h
@@ -37,10 +37,20 @@
#include <linux/of_platform.h> /* struct platform_device */
#include <linux/net_tstamp.h> /* struct hwtstamp_config */
+extern uint8_t advanced_debug;
+extern const struct dpa_fq_cbs_t shared_fq_cbs;
+extern int __hot dpa_shared_tx(struct sk_buff *skb, struct net_device *net_dev);
+
struct dpa_bp * __cold __must_check /* __attribute__((nonnull)) */
dpa_bp_probe(struct platform_device *_of_dev, size_t *count);
int dpa_bp_create(struct net_device *net_dev, struct dpa_bp *dpa_bp,
size_t count);
int dpa_bp_shared_port_seed(struct dpa_bp *bp);
+int __init __cold dpa_proxy_load(void);
+int __init __cold dpa_shared_load(void);
+int __init __cold dpa_macless_load(void);
+void __exit __cold dpa_proxy_unload(void);
+void __exit __cold dpa_shared_unload(void);
+void __exit __cold dpa_macless_unload(void);
#endif /* __DPAA_ETH_BASE_H */
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.c
index 32684d2..6e12a81 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.c
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.c
@@ -47,6 +47,9 @@
#ifdef CONFIG_FSL_DPAA_1588
#include "dpaa_1588.h"
#endif
+#ifdef CONFIG_FSL_DPAA_ETH_DEBUGFS
+#include "dpaa_debugfs.h"
+#endif /* CONFIG_FSL_DPAA_ETH_DEBUGFS */
#include "mac.h"
/* DPAA platforms benefit from hardware-assisted queue management */
@@ -66,14 +69,18 @@ struct ptp_priv_s ptp_priv;
static struct dpa_bp *dpa_bp_array[64];
int dpa_max_frm;
+EXPORT_SYMBOL(dpa_max_frm);
+
int dpa_rx_extra_headroom;
+EXPORT_SYMBOL(dpa_rx_extra_headroom);
+
int dpa_num_cpus = NR_CPUS;
static const struct fqid_cell tx_confirm_fqids[] = {
{0, DPAA_ETH_TX_QUEUES}
};
-static const struct fqid_cell default_fqids[][3] = {
+static struct fqid_cell default_fqids[][3] = {
[RX] = { {0, 1}, {0, 1}, {0, DPAA_ETH_RX_QUEUES} },
[TX] = { {0, 1}, {0, 1}, {0, DPAA_ETH_TX_QUEUES} }
};
@@ -98,10 +105,9 @@ void fsl_dpaa_eth_set_hooks(struct dpaa_eth_hooks_s *hooks)
EXPORT_SYMBOL(fsl_dpaa_eth_set_hooks);
#endif
-int dpa_netdev_init(struct device_node *dpa_node,
- struct net_device *net_dev,
- const uint8_t *mac_addr,
- uint16_t tx_timeout)
+int dpa_netdev_init(struct net_device *net_dev,
+ const uint8_t *mac_addr,
+ uint16_t tx_timeout)
{
int err;
struct dpa_priv_s *priv = netdev_priv(net_dev);
@@ -139,6 +145,7 @@ int dpa_netdev_init(struct device_node *dpa_node,
return 0;
}
+EXPORT_SYMBOL(dpa_netdev_init);
int __cold dpa_start(struct net_device *net_dev)
{
@@ -179,6 +186,7 @@ mac_start_failed:
return err;
}
+EXPORT_SYMBOL(dpa_start);
int __cold dpa_stop(struct net_device *net_dev)
{
@@ -212,6 +220,7 @@ int __cold dpa_stop(struct net_device *net_dev)
return _errno;
}
+EXPORT_SYMBOL(dpa_stop);
void __cold dpa_timeout(struct net_device *net_dev)
{
@@ -227,6 +236,7 @@ void __cold dpa_timeout(struct net_device *net_dev)
percpu_priv->stats.tx_errors++;
}
+EXPORT_SYMBOL(dpa_timeout);
/* net_device */
@@ -260,6 +270,7 @@ dpa_get_stats64(struct net_device *net_dev,
return stats;
}
+EXPORT_SYMBOL(dpa_get_stats64);
int dpa_change_mtu(struct net_device *net_dev, int new_mtu)
{
@@ -275,6 +286,7 @@ int dpa_change_mtu(struct net_device *net_dev, int new_mtu)
return 0;
}
+EXPORT_SYMBOL(dpa_change_mtu);
/* .ndo_init callback */
int dpa_ndo_init(struct net_device *net_dev)
@@ -293,6 +305,7 @@ int dpa_ndo_init(struct net_device *net_dev)
return 0;
}
+EXPORT_SYMBOL(dpa_ndo_init);
int dpa_set_features(struct net_device *dev, netdev_features_t features)
{
@@ -300,6 +313,7 @@ int dpa_set_features(struct net_device *dev, netdev_features_t features)
dev->features = features;
return 0;
}
+EXPORT_SYMBOL(dpa_set_features);
netdev_features_t dpa_fix_features(struct net_device *dev,
netdev_features_t features)
@@ -317,6 +331,7 @@ netdev_features_t dpa_fix_features(struct net_device *dev,
return features;
}
+EXPORT_SYMBOL(dpa_fix_features);
#ifdef CONFIG_FSL_DPAA_TS
u64 dpa_get_timestamp_ns(const struct dpa_priv_s *priv, enum port_type rx_tx,
@@ -478,6 +493,7 @@ int dpa_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
return ret;
}
+EXPORT_SYMBOL(dpa_ioctl);
int __cold dpa_remove(struct platform_device *of_dev)
{
@@ -498,11 +514,14 @@ int __cold dpa_remove(struct platform_device *of_dev)
err = dpa_fq_free(dev, &priv->dpa_fq_list);
+ qman_delete_cgr_safe(&priv->ingress_cgr);
+ qman_release_cgrid(priv->ingress_cgr.cgrid);
+ qman_delete_cgr_safe(&priv->cgr_data.cgr);
+ qman_release_cgrid(priv->cgr_data.cgr.cgrid);
+
dpa_private_napi_del(net_dev);
- free_percpu(priv->percpu_priv);
dpa_bp_free(priv, priv->dpa_bp);
- devm_kfree(dev, priv->dpa_bp);
if (priv->buf_layout)
devm_kfree(dev, priv->buf_layout);
@@ -521,6 +540,7 @@ int __cold dpa_remove(struct platform_device *of_dev)
return err;
}
+EXPORT_SYMBOL(dpa_remove);
struct mac_device * __cold __must_check
__attribute__((nonnull))
@@ -528,28 +548,20 @@ dpa_mac_probe(struct platform_device *_of_dev)
{
struct device *dpa_dev, *dev;
struct device_node *mac_node;
- int lenp;
- const phandle *phandle_prop;
struct platform_device *of_dev;
struct mac_device *mac_dev;
#ifdef CONFIG_FSL_DPAA_1588
+ int lenp;
struct net_device *net_dev = NULL;
struct dpa_priv_s *priv = NULL;
struct device_node *timer_node;
#endif
- phandle_prop = of_get_property(_of_dev->dev.of_node,
- "fsl,fman-mac", &lenp);
- if (phandle_prop == NULL)
- return NULL;
-
- BUG_ON(lenp != sizeof(phandle));
-
dpa_dev = &_of_dev->dev;
- mac_node = of_find_node_by_phandle(*phandle_prop);
+ mac_node = of_parse_phandle(_of_dev->dev.of_node, "fsl,fman-mac", 0);
if (unlikely(mac_node == NULL)) {
- dev_err(dpa_dev, "of_find_node_by_phandle() failed\n");
+ dev_err(dpa_dev, "Cannot find MAC device device tree node\n");
return ERR_PTR(-EFAULT);
}
@@ -608,6 +620,7 @@ dpa_mac_probe(struct platform_device *_of_dev)
#endif
return mac_dev;
}
+EXPORT_SYMBOL(dpa_mac_probe);
int dpa_set_mac_address(struct net_device *net_dev, void *addr)
{
@@ -640,6 +653,7 @@ int dpa_set_mac_address(struct net_device *net_dev, void *addr)
return 0;
}
+EXPORT_SYMBOL(dpa_set_mac_address);
void dpa_set_rx_mode(struct net_device *net_dev)
{
@@ -663,6 +677,7 @@ void dpa_set_rx_mode(struct net_device *net_dev)
if (unlikely(_errno < 0) && netif_msg_drv(priv))
netdev_err(net_dev, "mac_dev->set_multi() = %d\n", _errno);
}
+EXPORT_SYMBOL(dpa_set_rx_mode);
void dpa_set_buffers_layout(struct mac_device *mac_dev,
struct dpa_buffer_layout_s *layout)
@@ -694,6 +709,7 @@ void dpa_set_buffers_layout(struct mac_device *mac_dev,
layout[TX].manip_extra_space = params.manip_extra_space;
layout[TX].data_align = params.data_align ? : DPA_FD_DATA_ALIGNMENT;
}
+EXPORT_SYMBOL(dpa_set_buffers_layout);
int __attribute__((nonnull))
dpa_bp_alloc(struct dpa_bp *dpa_bp)
@@ -764,6 +780,7 @@ pdev_register_failed:
return err;
}
+EXPORT_SYMBOL(dpa_bp_alloc);
void dpa_bp_drain(struct dpa_bp *bp)
{
@@ -832,11 +849,13 @@ dpa_bp_free(struct dpa_priv_s *priv, struct dpa_bp *dpa_bp)
for (i = 0; i < priv->bp_count; i++)
_dpa_bp_free(&priv->dpa_bp[i]);
}
+EXPORT_SYMBOL(dpa_bp_free);
struct dpa_bp *dpa_bpid2pool(int bpid)
{
return dpa_bp_array[bpid];
}
+EXPORT_SYMBOL(dpa_bpid2pool);
void dpa_bpid2pool_map(int bpid, struct dpa_bp *dpa_bp)
{
@@ -859,6 +878,7 @@ u16 dpa_select_queue(struct net_device *net_dev, struct sk_buff *skb)
{
return dpa_get_queue_mapping(skb);
}
+EXPORT_SYMBOL(dpa_select_queue);
#endif
struct dpa_fq *dpa_fq_alloc(struct device *dev,
@@ -880,8 +900,7 @@ struct dpa_fq *dpa_fq_alloc(struct device *dev,
}
#ifdef CONFIG_FMAN_PFC
- if (fq_type == FQ_TYPE_TX ||
- fq_type == FQ_TYPE_TX_RECYCLE)
+ if (fq_type == FQ_TYPE_TX)
for (i = 0; i < fqids->count; i++)
dpa_fq[i].wq = i / dpa_num_cpus;
else
@@ -891,6 +910,7 @@ struct dpa_fq *dpa_fq_alloc(struct device *dev,
return dpa_fq;
}
+EXPORT_SYMBOL(dpa_fq_alloc);
/* Probing of FQs for MACful ports */
int dpa_fq_probe_mac(struct device *dev, struct list_head *list,
@@ -898,8 +918,9 @@ int dpa_fq_probe_mac(struct device *dev, struct list_head *list,
bool alloc_tx_conf_fqs,
enum port_type ptype)
{
- const struct fqid_cell *fqids;
- struct dpa_fq *dpa_fq;
+ struct fqid_cell *fqids = NULL;
+ const void *fqids_off = NULL;
+ struct dpa_fq *dpa_fq = NULL;
struct device_node *np = dev->of_node;
int num_ranges;
int i, lenp;
@@ -910,13 +931,26 @@ int dpa_fq_probe_mac(struct device *dev, struct list_head *list,
goto fq_alloc_failed;
}
- fqids = of_get_property(np, fsl_qman_frame_queues[ptype], &lenp);
- if (fqids == NULL) {
+ fqids_off = of_get_property(np, fsl_qman_frame_queues[ptype], &lenp);
+ if (fqids_off == NULL) {
/* No dts definition, so use the defaults. */
fqids = default_fqids[ptype];
num_ranges = 3;
} else {
num_ranges = lenp / sizeof(*fqids);
+
+ fqids = devm_kzalloc(dev, sizeof(*fqids) * num_ranges,
+ GFP_KERNEL);
+ if (fqids == NULL)
+ goto fqids_alloc_failed;
+
+ /* convert to CPU endianess */
+ for (i = 0; i < num_ranges; i++) {
+ fqids[i].start = be32_to_cpup(fqids_off +
+ i * sizeof(*fqids));
+ fqids[i].count = be32_to_cpup(fqids_off +
+ i * sizeof(*fqids) + sizeof(__be32));
+ }
}
for (i = 0; i < num_ranges; i++) {
@@ -967,7 +1001,8 @@ int dpa_fq_probe_mac(struct device *dev, struct list_head *list,
return 0;
fq_alloc_failed:
- dev_err(dev, "dpa_fq_alloc() failed\n");
+fqids_alloc_failed:
+ dev_err(dev, "Cannot allocate memory for frame queues\n");
return -ENOMEM;
invalid_default_queue:
@@ -975,6 +1010,7 @@ invalid_error_queue:
dev_err(dev, "Too many default or error queues\n");
return -EINVAL;
}
+EXPORT_SYMBOL(dpa_fq_probe_mac);
static u32 rx_pool_channel;
static DEFINE_SPINLOCK(rx_pool_channel_init);
@@ -993,6 +1029,13 @@ int dpa_get_channel(void)
return -ENOMEM;
return rx_pool_channel;
}
+EXPORT_SYMBOL(dpa_get_channel);
+
+void dpa_release_channel(void)
+{
+ qman_release_pool(rx_pool_channel);
+}
+EXPORT_SYMBOL(dpa_release_channel);
int dpaa_eth_add_channel(void *__arg)
{
@@ -1007,6 +1050,7 @@ int dpaa_eth_add_channel(void *__arg)
}
return 0;
}
+EXPORT_SYMBOL(dpaa_eth_add_channel);
/**
* Congestion group state change notification callback.
@@ -1015,6 +1059,7 @@ int dpaa_eth_add_channel(void *__arg)
* Also updates some CGR-related stats.
*/
static void dpaa_eth_cgscn(struct qman_portal *qm, struct qman_cgr *cgr,
+
int congested)
{
struct dpa_priv_s *priv = (struct dpa_priv_s *)container_of(cgr,
@@ -1077,6 +1122,7 @@ int dpaa_eth_cgr_init(struct dpa_priv_s *priv)
out_error:
return err;
}
+EXPORT_SYMBOL(dpaa_eth_cgr_init);
static inline void dpa_setup_ingress(const struct dpa_priv_s *priv,
struct dpa_fq *fq,
@@ -1215,6 +1261,8 @@ int dpa_fq_init(struct dpa_fq *dpa_fq, bool td_enable)
fq = &dpa_fq->fq_base;
if (dpa_fq->init) {
+ memset(&initfq, 0, sizeof(initfq));
+
initfq.we_mask = QM_INITFQ_WE_FQCTRL;
/* FIXME: why would we want to keep an empty FQ in cache? */
initfq.fqd.fq_ctrl = QM_FQCTRL_PREFERINCACHE;
@@ -1276,9 +1324,11 @@ int dpa_fq_init(struct dpa_fq *dpa_fq, bool td_enable)
/* ContextA: OVOM=1 (use contextA2 bits instead of ICAD)
* A2V=1 (contextA A2 field is valid)
* A0V=1 (contextA A0 field is valid)
+ * B0V=1 (contextB field is valid)
* ContextA A2: EBD=1 (deallocate buffers inside FMan)
+ * ContextB B0(ASPID): 0 (absolute Virtual Storage ID)
*/
- initfq.fqd.context_a.hi = 0x1a000000;
+ initfq.fqd.context_a.hi = 0x1e000000;
initfq.fqd.context_a.lo = 0x80000000;
}
}
@@ -1313,7 +1363,7 @@ int dpa_fq_init(struct dpa_fq *dpa_fq, bool td_enable)
initfq.fqd.context_a.stashing.annotation_cl = 1;
initfq.fqd.context_a.stashing.context_cl =
DIV_ROUND_UP(sizeof(struct qman_fq), 64);
- };
+ }
_errno = qman_init_fq(fq, QMAN_INITFQ_FLAG_SCHED, &initfq);
if (_errno < 0) {
@@ -1328,6 +1378,7 @@ int dpa_fq_init(struct dpa_fq *dpa_fq, bool td_enable)
return 0;
}
+EXPORT_SYMBOL(dpa_fq_init);
static int __cold __attribute__((nonnull))
_dpa_fq_free(struct device *dev, struct qman_fq *fq)
@@ -1377,6 +1428,7 @@ dpa_fq_free(struct device *dev, struct list_head *list)
return _errno;
}
+EXPORT_SYMBOL(dpa_fq_free);
static void
dpaa_eth_init_tx_port(struct fm_port *port, struct dpa_fq *errq,
@@ -1463,6 +1515,7 @@ void dpaa_eth_init_ports(struct mac_device *mac_dev,
rx_port_pcd_param.dev = dev;
fm_port_pcd_bind(rxport, &rx_port_pcd_param);
}
+EXPORT_SYMBOL(dpaa_eth_init_ports);
void dpa_release_sgt(struct qm_sg_entry *sgt)
{
@@ -1479,7 +1532,7 @@ void dpa_release_sgt(struct qm_sg_entry *sgt)
DPA_BUG_ON(sgt[i].extension);
bmb[j].hi = sgt[i].addr_hi;
- bmb[j].lo = sgt[i].addr_lo;
+ bmb[j].lo = be32_to_cpu(sgt[i].addr_lo);
j++; i++;
} while (j < ARRAY_SIZE(bmb) &&
@@ -1490,6 +1543,7 @@ void dpa_release_sgt(struct qm_sg_entry *sgt)
cpu_relax();
} while (!sgt[i-1].final);
}
+EXPORT_SYMBOL(dpa_release_sgt);
void __attribute__((nonnull))
dpa_fd_release(const struct net_device *net_dev, const struct qm_fd *fd)
@@ -1544,7 +1598,7 @@ void count_ern(struct dpa_percpu_priv_s *percpu_priv,
break;
}
}
-
+EXPORT_SYMBOL(count_ern);
/**
* Turn on HW checksum computation for this outgoing frame.
@@ -1563,8 +1617,8 @@ int dpa_enable_tx_csum(struct dpa_priv_s *priv,
fm_prs_result_t *parse_result;
struct iphdr *iph;
struct ipv6hdr *ipv6h = NULL;
- int l4_proto;
- int ethertype = ntohs(skb->protocol);
+ u8 l4_proto;
+ u16 ethertype = ntohs(skb->protocol);
int retval = 0;
if (skb->ip_summed != CHECKSUM_PARTIAL)
@@ -1593,16 +1647,16 @@ int dpa_enable_tx_csum(struct dpa_priv_s *priv,
*/
switch (ethertype) {
case ETH_P_IP:
- parse_result->l3r = FM_L3_PARSE_RESULT_IPV4;
+ parse_result->l3r = cpu_to_be16(FM_L3_PARSE_RESULT_IPV4);
iph = ip_hdr(skb);
DPA_BUG_ON(iph == NULL);
- l4_proto = ntohs(iph->protocol);
+ l4_proto = iph->protocol;
break;
case ETH_P_IPV6:
- parse_result->l3r = FM_L3_PARSE_RESULT_IPV6;
+ parse_result->l3r = cpu_to_be16(FM_L3_PARSE_RESULT_IPV6);
ipv6h = ipv6_hdr(skb);
DPA_BUG_ON(ipv6h == NULL);
- l4_proto = ntohs(ipv6h->nexthdr);
+ l4_proto = ipv6h->nexthdr;
break;
default:
/* We shouldn't even be here */
@@ -1648,3 +1702,4 @@ int dpa_enable_tx_csum(struct dpa_priv_s *priv,
return_error:
return retval;
}
+EXPORT_SYMBOL(dpa_enable_tx_csum);
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.h b/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.h
index 96ceee3..ee1c853 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.h
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.h
@@ -128,10 +128,9 @@ void fsl_dpaa_eth_set_hooks(struct dpaa_eth_hooks_s *hooks);
extern struct dpaa_eth_hooks_s dpaa_eth_hooks;
#endif
-int dpa_netdev_init(struct device_node *dpa_node,
- struct net_device *net_dev,
- const uint8_t *mac_addr,
- uint16_t tx_timeout);
+int dpa_netdev_init(struct net_device *net_dev,
+ const uint8_t *mac_addr,
+ uint16_t tx_timeout);
int __cold dpa_start(struct net_device *net_dev);
int __cold dpa_stop(struct net_device *net_dev);
void __cold dpa_timeout(struct net_device *net_dev);
@@ -178,6 +177,7 @@ int dpa_fq_probe_mac(struct device *dev, struct list_head *list,
bool tx_conf_fqs_per_core,
enum port_type ptype);
int dpa_get_channel(void);
+void dpa_release_channel(void);
int dpaa_eth_add_channel(void *__arg);
int dpaa_eth_cgr_init(struct dpa_priv_s *priv);
void dpa_fq_setup(struct dpa_priv_s *priv, const struct dpa_fq_cbs_t *fq_cbs,
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_generic.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth_generic.c
index 21d177a..f78e176 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_generic.c
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_generic.c
@@ -66,9 +66,9 @@
MODULE_LICENSE("Dual BSD/GPL");
MODULE_DESCRIPTION(DPA_GENERIC_DESCRIPTION);
-static uint8_t debug = -1;
-module_param(debug, byte, S_IRUGO);
-MODULE_PARM_DESC(debug, "Module/Driver verbosity level");
+static uint8_t generic_debug = -1;
+module_param(generic_debug, byte, S_IRUGO);
+MODULE_PARM_DESC(generic_debug, "Module/Driver verbosity level");
/* This has to work in tandem with the DPA_CS_THRESHOLD_xxx values. */
static uint16_t tx_timeout = 1000;
@@ -101,11 +101,10 @@ static const struct net_device_ops dpa_generic_ops = {
.ndo_init = dpa_ndo_init,
.ndo_set_features = dpa_set_features,
.ndo_fix_features = dpa_fix_features,
- .ndo_init = dpa_ndo_init,
.ndo_change_mtu = dpa_change_mtu,
};
-void dpa_generic_draining_timer(unsigned long arg)
+static void dpa_generic_draining_timer(unsigned long arg)
{
struct dpa_generic_priv_s *priv = (struct dpa_generic_priv_s *)arg;
@@ -174,31 +173,27 @@ static struct platform_driver dpa_generic_driver = {
.remove = dpa_generic_remove
};
-int get_port_ref(struct device_node dev_node,
+static int get_port_ref(struct device_node *dev_node,
struct fm_port **port)
{
- const phandle *dpa_port_ref_node = NULL;
- struct platform_device *dpa_port_of_dev = NULL;
+ struct platform_device *port_of_dev = NULL;
struct device *op_dev = NULL;
- struct device_node *dpa_port_node = NULL;
- int lenp = 0;
+ struct device_node *port_node = NULL;
- dpa_port_ref_node = of_get_property(&dev_node,
- "fsl,fman-oh-port", &lenp);
- if (dpa_port_ref_node == NULL)
+ port_node = of_parse_phandle(dev_node, "fsl,fman-oh-port", 0);
+ if (port_node == NULL)
return -EINVAL;
- dpa_port_node = of_find_node_by_phandle(*dpa_port_ref_node);
- if (dpa_port_node == NULL)
- return -EINVAL;
+ port_of_dev = of_find_device_by_node(port_node);
+ of_node_put(port_node);
- dpa_port_of_dev = of_find_device_by_node(dpa_port_node);
- of_node_put(dpa_port_node);
- if (dpa_port_of_dev == NULL)
+ if (port_of_dev == NULL)
return -EINVAL;
- op_dev = &dpa_port_of_dev->dev;
+ /* get the reference to oh port from FMD */
+ op_dev = &port_of_dev->dev;
*port = fm_port_bind(op_dev);
+
if (*port == NULL)
return -EINVAL;
@@ -234,31 +229,25 @@ static void dpaa_generic_napi_disable(struct dpa_generic_priv_s *priv)
static struct device_node *get_rx_op_port_node(struct platform_device *_of_dev)
{
struct device *dev = &_of_dev->dev;
- struct device_node *dev_node = NULL;
- const phandle *ports_handle = NULL;
+ struct device_node *port_node = NULL;
+ struct device_node *onic_node = NULL;
int num_ports = 0;
- int lenp = 0;
- ports_handle = of_get_property(dev->of_node,
- "fsl,oh-ports", &lenp);
- if (ports_handle == NULL) {
- dev_err(dev, "Cannot find node fsl,oh-ports property in device tree\n");
- return ERR_PTR(-EINVAL);
- }
+ onic_node = dev->of_node;
- num_ports = lenp / sizeof(*ports_handle);
- if (num_ports < 1) {
- dev_err(dev, "There should be at least one O/H port in device tree\n");
+ num_ports = of_count_phandle_with_args(onic_node, "fsl,oh-ports", NULL);
+ if (num_ports != 2) {
+ dev_err(dev, "There should be two O/H port handles in the device tree\n");
return ERR_PTR(-EINVAL);
}
- dev_node = of_find_node_by_phandle(*ports_handle);
- if (unlikely(dev_node == NULL)) {
- dev_err(dev, "Cannot find node oh port node in device tree\n");
+ port_node = of_parse_phandle(onic_node, "fsl,oh-ports", 0);
+ if (port_node == NULL) {
+ dev_err(dev, "Cannot find O/H port node in the device tree\n");
return ERR_PTR(-EFAULT);
}
- return dev_node;
+ return port_node;
}
static int __cold dpa_generic_start(struct net_device *netdev)
@@ -499,10 +488,10 @@ static void dpa_generic_drain_bp(struct dpa_bp *bp, u8 nbuf)
* Note that this function may modify the fd->cmd field and the skb data buffer
* (the Parse Results area).
*/
-int dpa_generic_tx_csum(struct dpa_generic_priv_s *priv,
- struct sk_buff *skb,
- struct qm_fd *fd,
- char *parse_results)
+static int dpa_generic_tx_csum(struct dpa_generic_priv_s *priv,
+ struct sk_buff *skb,
+ struct qm_fd *fd,
+ char *parse_results)
{
fm_prs_result_t *parse_result;
struct iphdr *iph;
@@ -540,13 +529,13 @@ int dpa_generic_tx_csum(struct dpa_generic_priv_s *priv,
parse_result->l3r = FM_L3_PARSE_RESULT_IPV4;
iph = ip_hdr(skb);
BUG_ON(iph == NULL);
- l4_proto = ntohs(iph->protocol);
+ l4_proto = iph->protocol;
break;
case ETH_P_IPV6:
parse_result->l3r = FM_L3_PARSE_RESULT_IPV6;
ipv6h = ipv6_hdr(skb);
BUG_ON(ipv6h == NULL);
- l4_proto = ntohs(ipv6h->nexthdr);
+ l4_proto = ipv6h->nexthdr;
break;
default:
/* We shouldn't even be here */
@@ -718,7 +707,7 @@ static int dpa_generic_napi_add(struct net_device *net_dev)
return 0;
}
-void dpa_generic_napi_del(struct net_device *net_dev)
+static void dpa_generic_napi_del(struct net_device *net_dev)
{
struct dpa_generic_priv_s *priv = netdev_priv(net_dev);
struct dpa_percpu_priv_s *percpu_priv;
@@ -785,82 +774,112 @@ static int dpa_generic_netdev_init(struct device_node *dpa_node,
return 0;
}
-struct dpa_fq_cbs_t generic_fq_cbs = {
+static struct dpa_fq_cbs_t generic_fq_cbs = {
.rx_defq = { .cb = { .dqrr = dpa_generic_rx_dqrr } },
.rx_errq = { .cb = { .dqrr = dpa_generic_rx_err_dqrr } },
.egress_ern = { .cb = { .ern = dpa_generic_ern } }
};
-struct list_head *dpa_generic_fq_probe(struct platform_device *_of_dev,
- struct fm_port *tx_port)
+static struct fqid_cell *__fq_alloc(struct device *dev,
+ int num_ranges,
+ const void *fqids_off)
+{
+ struct fqid_cell *fqids;
+ int i;
+
+ fqids = kzalloc(sizeof(*fqids) * num_ranges, GFP_KERNEL);
+ if (fqids == NULL)
+ return NULL;
+
+ /* convert to CPU endianess */
+ for (i = 0; i < num_ranges; i++) {
+ fqids[i].start = be32_to_cpup(fqids_off +
+ i * sizeof(*fqids));
+ fqids[i].count = be32_to_cpup(fqids_off +
+ i * sizeof(*fqids) + sizeof(__be32));
+ }
+
+ return fqids;
+}
+
+static struct list_head *dpa_generic_fq_probe(struct platform_device *_of_dev,
+ struct fm_port *tx_port)
{
struct device *dev = &_of_dev->dev;
- struct device_node *dev_node = NULL;
- const struct fqid_cell *fqids;
+ struct device_node *oh_node = NULL;
+ struct device_node *onic_node = NULL;
+ struct fqid_cell *fqids;
+ const void *fqids_off;
struct dpa_fq *fq, *tmp;
struct list_head *list;
int num_ranges;
int i, lenp;
- /* RX queues (RX error, RX default) are specified in Rx O/H port node */
- dev_node = get_rx_op_port_node(_of_dev);
+ onic_node = dev->of_node;
+
+ list = devm_kzalloc(dev, sizeof(*list), GFP_KERNEL);
+ if (!list) {
+ dev_err(dev, "Cannot allocate space for frame queues list\n");
+ return ERR_PTR(-ENOMEM);
+ }
- fqids = of_get_property(dev_node, "fsl,qman-frame-queues-oh", &lenp);
- if (fqids == NULL) {
+ INIT_LIST_HEAD(list);
+
+ /* RX queues (RX error, RX default) are specified in Rx O/H port node */
+ oh_node = get_rx_op_port_node(_of_dev);
+ fqids_off = of_get_property(oh_node, "fsl,qman-frame-queues-oh", &lenp);
+ if (fqids_off == NULL) {
dev_err(dev, "Need Rx FQ definition in dts for generic devices\n");
return ERR_PTR(-EINVAL);
}
+ of_node_put(oh_node);
- of_node_put(dev_node);
num_ranges = lenp / sizeof(*fqids);
if (num_ranges != 2) {
dev_err(dev, "Need 2 Rx FQ definitions in dts for generic devices\n");
return ERR_PTR(-EINVAL);
}
- list = devm_kzalloc(dev, sizeof(*list), GFP_KERNEL);
- if (!list) {
- dev_err(dev, "devm_kzalloc() failed\n");
- return ERR_PTR(-ENOMEM);
- }
-
- INIT_LIST_HEAD(list);
-
+ fqids = __fq_alloc(dev, num_ranges, fqids_off);
if (!dpa_fq_alloc(dev, &fqids[0], list, FQ_TYPE_RX_ERROR) ||
!dpa_fq_alloc(dev, &fqids[1], list,
FQ_TYPE_RX_DEFAULT)) {
- dev_err(dev, "_dpa_fq_alloc() failed\n");
+ dev_err(dev, "Cannot allocate space for default frame queues\n");
return ERR_PTR(-ENOMEM);
}
+ kfree(fqids);
/* TX queues */
- fqids = of_get_property(dev->of_node,
- "fsl,qman-frame-queues-tx", &lenp);
- if (fqids == NULL) {
+ fqids_off = of_get_property(onic_node, "fsl,qman-frame-queues-tx",
+ &lenp);
+ if (fqids_off == NULL) {
dev_err(dev, "Need Tx FQ definition in dts for generic devices\n");
return ERR_PTR(-EINVAL);
}
num_ranges = lenp / sizeof(*fqids);
+ fqids = __fq_alloc(dev, num_ranges, fqids_off);
for (i = 0; i < num_ranges; i++) {
if (!dpa_fq_alloc(dev, &fqids[i], list, FQ_TYPE_TX)) {
dev_err(dev, "_dpa_fq_alloc() failed\n");
return ERR_PTR(-ENOMEM);
}
}
+ kfree(fqids);
/* optional RX PCD queues */
lenp = 0;
- fqids = of_get_property(dev->of_node,
+ fqids_off = of_get_property(onic_node,
"fsl,qman-frame-queues-rx", &lenp);
-
num_ranges = lenp / sizeof(*fqids);
+ fqids = __fq_alloc(dev, num_ranges, fqids_off);
for (i = 0; i < num_ranges; i++) {
if (!dpa_fq_alloc(dev, &fqids[i], list, FQ_TYPE_RX_PCD)) {
dev_err(dev, "_dpa_fq_alloc() failed\n");
return ERR_PTR(-ENOMEM);
}
}
+ kfree(fqids);
list_for_each_entry_safe(fq, tmp, list, list) {
if (fq->fq_type == FQ_TYPE_TX)
@@ -898,36 +917,33 @@ static int dpa_generic_rx_bp_probe(struct platform_device *_of_dev,
struct dpa_buffer_layout_s **rx_buf_layout)
{
struct device *dev = &_of_dev->dev;
- const phandle *phandle_prop = NULL;
struct fm_port_params params;
struct dpa_bp *bp = NULL;
int bp_count = 0;
- const uint32_t *bpid = NULL;
- const uint32_t *bpool_cfg = NULL;
+ int bpid;
+ const __be32 *bpool_cfg = NULL;
struct device_node *dev_node = NULL;
+ struct device_node *oh_node = NULL;
struct dpa_buffer_layout_s *buf_layout = NULL;
int lenp = 0;
int na = 0, ns = 0;
int err = 0, i = 0;
- dev_node = get_rx_op_port_node(_of_dev);
+ oh_node = get_rx_op_port_node(_of_dev);
- phandle_prop = of_get_property(dev_node,
- "fsl,bman-buffer-pools", &lenp);
- if (!phandle_prop) {
- dev_err(dev, "missing fsl,bman-buffer-pools property from device tree\n");
+ bp_count = of_count_phandle_with_args(oh_node,
+ "fsl,bman-buffer-pools", NULL);
+ if (bp_count <= 0) {
+ dev_err(dev, "Missing buffer pool handles from onic node from device tree\n");
return -EINVAL;
}
- bp_count = lenp / sizeof(*phandle_prop);
-
bp = devm_kzalloc(dev, bp_count * sizeof(*bp), GFP_KERNEL);
if (unlikely(bp == NULL)) {
dev_err(dev, "devm_kzalloc() failed\n");
return -ENOMEM;
}
- of_node_put(dev_node);
dev_node = of_find_node_by_path("/");
if (unlikely(dev_node == NULL)) {
dev_err(dev, "of_find_node_by_path(/) failed\n");
@@ -940,27 +956,20 @@ static int dpa_generic_rx_bp_probe(struct platform_device *_of_dev,
of_node_put(dev_node);
for (i = 0; i < bp_count; i++) {
- dev_node = of_find_node_by_phandle(phandle_prop[i]);
- if (unlikely(dev_node == NULL)) {
- dev_err(dev, "of_find_node_by_phandle() failed\n");
+ dev_node = of_parse_phandle(oh_node,
+ "fsl,bman-buffer-pools", i);
+ if (dev_node == NULL) {
+ dev_err(dev, "Cannot find buffer pool node in the device tree\n");
return -EFAULT;
}
- if (unlikely(!of_device_is_compatible(dev_node, "fsl,bpool"))) {
- dev_err(dev, "!of_device_is_compatible(%s, fsl,bpool)\n",
- dev_node->full_name);
- err = -EINVAL;
+ err = of_property_read_u32(dev_node, "fsl,bpid", &bpid);
+ if (err) {
+ dev_err(dev, "Cannot find buffer pool ID in the buffer pool node in the device tree\n");
goto _return_of_node_put;
}
- bpid = of_get_property(dev_node, "fsl,bpid", &lenp);
- if ((bpid == NULL) || (lenp != sizeof(*bpid))) {
- dev_err(dev, "fsl,bpid property not found.\n");
- err = -EINVAL;
- goto _return_of_node_put;
- }
-
- bp[i].bpid = (uint8_t)*bpid;
+ bp[i].bpid = (uint8_t)bpid;
bpool_cfg = of_get_property(dev_node, "fsl,bpool-ethernet-cfg",
&lenp);
@@ -976,9 +985,12 @@ static int dpa_generic_rx_bp_probe(struct platform_device *_of_dev,
goto _return_of_node_put;
}
- bp[i].percpu_count = alloc_percpu(*(bp[i].percpu_count));
+ bp[i].percpu_count = devm_alloc_percpu(dev,
+ *bp[i].percpu_count);
}
+ of_node_put(oh_node);
+
buf_layout = devm_kzalloc(dev, sizeof(*buf_layout), GFP_KERNEL);
if (!buf_layout) {
dev_err(dev, "devm_kzalloc() failed\n");
@@ -1010,10 +1022,10 @@ _return_of_node_put:
return err;
}
-int dpa_generic_tx_bp_probe(struct platform_device *_of_dev,
- struct fm_port *tx_port,
- struct dpa_bp **draining_tx_bp,
- struct dpa_buffer_layout_s **tx_buf_layout)
+static int dpa_generic_tx_bp_probe(struct platform_device *_of_dev,
+ struct fm_port *tx_port,
+ struct dpa_bp **draining_tx_bp,
+ struct dpa_buffer_layout_s **tx_buf_layout)
{
struct device *dev = &_of_dev->dev;
struct fm_port_params params;
@@ -1042,7 +1054,7 @@ int dpa_generic_tx_bp_probe(struct platform_device *_of_dev,
}
bp->size = dpa_bp_size(buf_layout);
- bp->percpu_count = alloc_percpu(*bp->percpu_count);
+ bp->percpu_count = devm_alloc_percpu(dev, *bp->percpu_count);
bp->target_count = CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT;
*draining_tx_bp = bp;
@@ -1051,8 +1063,8 @@ int dpa_generic_tx_bp_probe(struct platform_device *_of_dev,
return 0;
}
-int dpa_generic_buff_dealloc_probe(struct platform_device *_of_dev,
- int *disable_buff_dealloc)
+static int dpa_generic_buff_dealloc_probe(struct platform_device *_of_dev,
+ int *disable_buff_dealloc)
{
struct device *dev = &_of_dev->dev;
const phandle *disable_handle = NULL;
@@ -1067,52 +1079,45 @@ int dpa_generic_buff_dealloc_probe(struct platform_device *_of_dev,
return err;
}
-int dpa_generic_port_probe(struct platform_device *_of_dev,
- struct fm_port **rx_port,
- struct fm_port **tx_port)
+static int dpa_generic_port_probe(struct platform_device *_of_dev,
+ struct fm_port **rx_port,
+ struct fm_port **tx_port)
{
struct device *dev = &_of_dev->dev;
struct device_node *dev_node = NULL;
- const phandle *ports_handle = NULL;
+ struct device_node *onic_node = NULL;
int num_ports = 0;
- int lenp = 0;
int err = 0;
- ports_handle = of_get_property(dev->of_node,
- "fsl,oh-ports", &lenp);
- if (ports_handle == NULL) {
- dev_err(dev, "Cannot find fsl,oh-ports property in device tree\n");
- return -EINVAL;
- }
+ onic_node = dev->of_node;
- num_ports = lenp / sizeof(*ports_handle);
+ num_ports = of_count_phandle_with_args(onic_node, "fsl,oh-ports", NULL);
if (num_ports != 2) {
- /* for the moment, only two ports are supported */
dev_err(dev, "There should be two OH ports in device tree (one for RX, one for TX\n");
return -EINVAL;
}
- dev_node = of_find_node_by_phandle(ports_handle[RX]);
- if (unlikely(dev_node == NULL)) {
- dev_err(dev, "Cannot find OH port node in device tree\n");
- return -EFAULT;
+ dev_node = of_parse_phandle(onic_node, "fsl,oh-ports", RX);
+ if (dev_node == NULL) {
+ dev_err(dev, "Cannot find Rx OH port node in device tree\n");
+ return err;
}
- err = get_port_ref(*dev_node, rx_port);
- if (err < 0) {
- dev_err(dev, "Cannot read OH port node in device tree\n");
+ err = get_port_ref(dev_node, rx_port);
+ if (err) {
+ dev_err(dev, "Cannot read Rx OH port node in device tree\n");
return err;
}
- dev_node = of_find_node_by_phandle(ports_handle[TX]);
- if (unlikely(dev_node == NULL)) {
- dev_err(dev, "Cannot find OH port node in device tree\n");
+ dev_node = of_parse_phandle(onic_node, "fsl,oh-ports", TX);
+ if (dev_node == NULL) {
+ dev_err(dev, "Cannot find Tx OH port node in device tree\n");
return -EFAULT;
}
- err = get_port_ref(*dev_node, tx_port);
- if (err < 0) {
- dev_err(dev, "Cannot read OH port node in device tree\n");
+ err = get_port_ref(dev_node, tx_port);
+ if (err) {
+ dev_err(dev, "Cannot read Tx OH port node in device tree\n");
return err;
}
@@ -1252,7 +1257,7 @@ static int dpa_generic_fq_init(struct dpa_fq *dpa_fq, int disable_buff_dealloc)
initfq.fqd.context_a.stashing.annotation_cl = 1;
initfq.fqd.context_a.stashing.context_cl =
DIV_ROUND_UP(sizeof(struct qman_fq), 64);
- };
+ }
_errno = qman_init_fq(fq, QMAN_INITFQ_FLAG_SCHED, &initfq);
if (_errno < 0) {
@@ -1308,12 +1313,12 @@ static int dpa_generic_fq_create(struct net_device *netdev,
return 0;
}
-int dpa_generic_bp_create(struct net_device *net_dev,
- int rx_bp_count,
- struct dpa_bp *rx_bp,
- struct dpa_buffer_layout_s *rx_buf_layout,
- struct dpa_bp *draining_tx_bp,
- struct dpa_buffer_layout_s *tx_buf_layout)
+static int dpa_generic_bp_create(struct net_device *net_dev,
+ int rx_bp_count,
+ struct dpa_bp *rx_bp,
+ struct dpa_buffer_layout_s *rx_buf_layout,
+ struct dpa_bp *draining_tx_bp,
+ struct dpa_buffer_layout_s *tx_buf_layout)
{
struct dpa_generic_priv_s *priv = netdev_priv(net_dev);
int err = 0;
@@ -1365,7 +1370,6 @@ static int dpa_generic_remove(struct platform_device *of_dev)
#endif
dpa_private_napi_del(net_dev);
- free_percpu(priv->percpu_priv);
/* TODO: this is for private dirver also; make generic */
#if 0
@@ -1439,7 +1443,7 @@ static int dpa_generic_eth_probe(struct platform_device *_of_dev)
priv = netdev_priv(netdev);
priv->net_dev = netdev;
sprintf(priv->if_type, "generic%d", generic_idx++);
- priv->msg_enable = netif_msg_init(debug, -1);
+ priv->msg_enable = netif_msg_init(generic_debug, -1);
priv->tx_headroom = DPA_DEFAULT_TX_HEADROOM;
init_timer(&priv->timer);
@@ -1465,9 +1469,9 @@ static int dpa_generic_eth_probe(struct platform_device *_of_dev)
priv->mac_dev = NULL;
- priv->percpu_priv = alloc_percpu(*priv->percpu_priv);
+ priv->percpu_priv = devm_alloc_percpu(dev, *priv->percpu_priv);
if (priv->percpu_priv == NULL) {
- dev_err(dev, "alloc_percpu() failed\n");
+ dev_err(dev, "devm_alloc_percpu() failed\n");
err = -ENOMEM;
goto alloc_percpu_failed;
}
@@ -1495,8 +1499,6 @@ static int dpa_generic_eth_probe(struct platform_device *_of_dev)
netdev_init_failed:
napi_add_failed:
dpa_generic_napi_del(netdev);
- if (netdev)
- free_percpu(priv->percpu_priv);
alloc_percpu_failed:
if (netdev)
dpa_fq_free(dev, &priv->dpa_fq_list);
@@ -1530,6 +1532,10 @@ static int __init __cold dpa_generic_load(void)
KBUILD_BASENAME".c", __LINE__, __func__, _errno);
}
+#ifdef CONFIG_FSL_DPAA_ETH_DEBUGFS
+ dpa_generic_debugfs_module_init();
+#endif /* CONFIG_FSL_DPAA_ETH_DEBUGFS */
+
pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
KBUILD_BASENAME".c", __func__);
@@ -1548,6 +1554,10 @@ static void __exit __cold dpa_generic_unload(void)
platform_driver_unregister(&dpa_generic_driver);
+#ifdef CONFIG_FSL_DPAA_ETH_DEBUGFS
+ dpa_generic_debugfs_module_exit();
+#endif /* CONFIG_FSL_DPAA_ETH_DEBUGFS */
+
pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
KBUILD_BASENAME".c", __func__);
}
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_generic.h b/drivers/net/ethernet/freescale/dpa/dpaa_eth_generic.h
index 606812f..aa74edf 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_generic.h
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_generic.h
@@ -38,7 +38,7 @@
struct dpa_generic_priv_s {
struct net_device *net_dev;
/* use the same percpu_priv as other DPAA Ethernet drivers */
- struct dpa_percpu_priv_s *percpu_priv;
+ struct dpa_percpu_priv_s __percpu *percpu_priv;
/* up to 4 bps supported for RX */
int rx_bp_count;
@@ -84,10 +84,11 @@ struct dpa_generic_priv_s {
struct timer_list timer;
};
+extern const struct ethtool_ops dpa_generic_ethtool_ops;
void dpaa_eth_generic_sysfs_init(struct device *dev);
void dpaa_eth_generic_sysfs_remove(struct device *dev);
-
-extern const struct ethtool_ops dpa_generic_ethtool_ops;
+int __init dpa_generic_debugfs_module_init(void);
+void __exit dpa_generic_debugfs_module_exit(void);
#endif /* __DPA_ETH_GENERIC_H */
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_macless.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth_macless.c
index 0258c90..c13e5cd 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_macless.c
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_macless.c
@@ -65,18 +65,10 @@ MODULE_LICENSE("Dual BSD/GPL");
MODULE_DESCRIPTION(DPA_DESCRIPTION);
-static uint8_t debug = -1;
-module_param(debug, byte, S_IRUGO);
-MODULE_PARM_DESC(debug, "Module/Driver verbosity level");
-
/* This has to work in tandem with the DPA_CS_THRESHOLD_xxx values. */
-static uint16_t tx_timeout = 1000;
-module_param(tx_timeout, ushort, S_IRUGO);
-MODULE_PARM_DESC(tx_timeout, "The Tx timeout in ms");
-
-/* reused from the shared driver */
-extern const struct dpa_fq_cbs_t shared_fq_cbs;
-int __hot dpa_shared_tx(struct sk_buff *skb, struct net_device *net_dev);
+static uint16_t macless_tx_timeout = 1000;
+module_param(macless_tx_timeout, ushort, S_IRUGO);
+MODULE_PARM_DESC(macless_tx_timeout, "The MACless Tx timeout in ms");
/* forward declarations */
static int __cold dpa_macless_start(struct net_device *net_dev);
@@ -88,8 +80,6 @@ static void __cold dpa_macless_set_rx_mode(struct net_device *net_dev);
static int dpaa_eth_macless_probe(struct platform_device *_of_dev);
static netdev_features_t
dpa_macless_fix_features(struct net_device *dev, netdev_features_t features);
-static int dpa_macless_netdev_init(struct device_node *dpa_node,
- struct net_device *net_dev);
static const struct net_device_ops dpa_macless_ops = {
.ndo_open = dpa_macless_start,
@@ -119,7 +109,7 @@ MODULE_DEVICE_TABLE(of, dpa_macless_match);
static struct platform_driver dpa_macless_driver = {
.driver = {
- .name = KBUILD_MODNAME,
+ .name = KBUILD_MODNAME "-macless",
.of_match_table = dpa_macless_match,
.owner = THIS_MODULE,
},
@@ -227,8 +217,8 @@ static int dpa_macless_netdev_init(struct device_node *dpa_node,
net_dev->mem_start = mac_dev->res->start;
net_dev->mem_end = mac_dev->res->end;
- return dpa_netdev_init(dpa_node, net_dev, mac_dev->addr,
- tx_timeout);
+ return dpa_netdev_init(net_dev, mac_dev->addr,
+ macless_tx_timeout);
} else {
/* Get the MAC address from device tree */
mac_addr = of_get_mac_address(dpa_node);
@@ -239,8 +229,8 @@ static int dpa_macless_netdev_init(struct device_node *dpa_node,
return -EINVAL;
}
- return dpa_netdev_init(dpa_node, net_dev, mac_addr,
- tx_timeout);
+ return dpa_netdev_init(net_dev, mac_addr,
+ macless_tx_timeout);
}
}
@@ -273,7 +263,8 @@ static int dpa_fq_probe_macless(struct device *dev, struct list_head *list,
return 0;
}
-struct proxy_device *dpa_macless_proxy_probe(struct platform_device *_of_dev)
+ static struct proxy_device *
+dpa_macless_proxy_probe(struct platform_device *_of_dev)
{
struct device *dev;
const phandle *proxy_prop;
@@ -358,7 +349,7 @@ static int dpaa_eth_macless_probe(struct platform_device *_of_dev)
priv->net_dev = net_dev;
sprintf(priv->if_type, "macless%d", macless_idx++);
- priv->msg_enable = netif_msg_init(debug, -1);
+ priv->msg_enable = netif_msg_init(advanced_debug, -1);
priv->peer = NULL;
priv->mac_dev = NULL;
@@ -432,10 +423,10 @@ static int dpaa_eth_macless_probe(struct platform_device *_of_dev)
priv->tx_headroom = DPA_DEFAULT_TX_HEADROOM;
- priv->percpu_priv = alloc_percpu(*priv->percpu_priv);
+ priv->percpu_priv = devm_alloc_percpu(dev, *priv->percpu_priv);
if (priv->percpu_priv == NULL) {
- dev_err(dev, "alloc_percpu() failed\n");
+ dev_err(dev, "devm_alloc_percpu() failed\n");
err = -ENOMEM;
goto alloc_percpu_failed;
}
@@ -456,8 +447,6 @@ static int dpaa_eth_macless_probe(struct platform_device *_of_dev)
return 0;
netdev_init_failed:
- if (net_dev)
- free_percpu(priv->percpu_priv);
alloc_percpu_failed:
fq_alloc_failed:
if (net_dev)
@@ -497,10 +486,7 @@ static int __init __cold dpa_macless_load(void)
return _errno;
}
-/* waits for proxy to initialize first, in case MAC device reference
- * is needed
- */
-late_initcall(dpa_macless_load);
+module_init(dpa_macless_load);
static void __exit __cold dpa_macless_unload(void)
{
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_proxy.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth_proxy.c
index 57aacb9..8f58203 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_proxy.c
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_proxy.c
@@ -53,10 +53,6 @@ MODULE_LICENSE("Dual BSD/GPL");
MODULE_DESCRIPTION(DPA_DESCRIPTION);
-static uint8_t debug = -1;
-module_param(debug, byte, S_IRUGO);
-MODULE_PARM_DESC(debug, "Module/Driver verbosity level");
-
static int __cold dpa_eth_proxy_remove(struct platform_device *of_dev);
#ifdef CONFIG_PM
@@ -329,7 +325,7 @@ MODULE_DEVICE_TABLE(of, dpa_proxy_match);
static struct platform_driver dpa_proxy_driver = {
.driver = {
- .name = KBUILD_MODNAME"-proxy",
+ .name = KBUILD_MODNAME "-proxy",
.of_match_table = dpa_proxy_match,
.owner = THIS_MODULE,
.pm = PROXY_PM_OPS,
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_sg.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth_sg.c
index fd1f2a8..2e541a8 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_sg.c
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_sg.c
@@ -102,6 +102,8 @@ static int _dpa_bp_add_8_bufs(const struct dpa_bp *dpa_bp)
struct device *dev = dpa_bp->dev;
struct sk_buff *skb, **skbh;
+ memset(bmb, 0, sizeof(struct bm_buffer) * 8);
+
for (i = 0; i < 8; i++) {
/* We'll prepend the skb back-pointer; can't use the DPA
* priv space, because FMan will overwrite it (from offset 0)
@@ -182,6 +184,7 @@ int dpa_bp_priv_seed(struct dpa_bp *dpa_bp)
}
return 0;
}
+EXPORT_SYMBOL(dpa_bp_priv_seed);
/* Add buffers/(pages) for Rx processing whenever bpool count falls below
* REFILL_THRESHOLD.
@@ -211,6 +214,7 @@ int dpaa_eth_refill_bpools(struct dpa_bp *dpa_bp, int *countptr)
return 0;
}
+EXPORT_SYMBOL(dpaa_eth_refill_bpools);
/* Cleanup function for outgoing frame descriptors that were built on Tx path,
* either contiguous frames or scatter/gather ones.
@@ -229,6 +233,7 @@ struct sk_buff *_dpa_cleanup_tx_fd(const struct dpa_priv_s *priv,
int i;
struct dpa_bp *dpa_bp = priv->dpa_bp;
dma_addr_t addr = qm_fd_addr(fd);
+ dma_addr_t sg_addr;
struct sk_buff **skbh;
struct sk_buff *skb = NULL;
const enum dma_data_direction dma_dir = DMA_TO_DEVICE;
@@ -261,15 +266,18 @@ struct sk_buff *_dpa_cleanup_tx_fd(const struct dpa_priv_s *priv,
#endif /* CONFIG_FSL_DPAA_TS */
/* sgt[0] is from lowmem, was dma_map_single()-ed */
- dma_unmap_single(dpa_bp->dev, (dma_addr_t)sgt[0].addr,
- sgt[0].length, dma_dir);
+ /* TODO: sg_addr should be in CPU endianess */
+ sg_addr = qm_sg_addr(&sgt[0]);
+ dma_unmap_single(dpa_bp->dev, sg_addr,
+ be32_to_cpu(sgt[0].length), dma_dir);
/* remaining pages were mapped with dma_map_page() */
for (i = 1; i < nr_frags; i++) {
DPA_BUG_ON(sgt[i].extension);
-
- dma_unmap_page(dpa_bp->dev, (dma_addr_t)sgt[i].addr,
- sgt[i].length, dma_dir);
+ /* TODO: sg_addr should be in CPU endianess */
+ sg_addr = qm_sg_addr(&sgt[i]);
+ dma_unmap_page(dpa_bp->dev, sg_addr,
+ be32_to_cpu(sgt[i].length), dma_dir);
}
/* Free the page frag that we allocated on Tx */
@@ -435,6 +443,7 @@ static struct sk_buff *__hot sg_fd_to_skb(const struct dpa_priv_s *priv,
/* We use a single global Rx pool */
DPA_BUG_ON(dpa_bp != dpa_bpid2pool(sgt[i].bpid));
+ /* TODO: sg_addr should be in CPU endianess */
sg_addr = qm_sg_addr(&sgt[i]);
sg_vaddr = phys_to_virt(sg_addr);
DPA_BUG_ON(!IS_ALIGNED((unsigned long)sg_vaddr,
@@ -469,7 +478,7 @@ static struct sk_buff *__hot sg_fd_to_skb(const struct dpa_priv_s *priv,
*/
DPA_BUG_ON(fd_off != priv->rx_headroom);
skb_reserve(skb, fd_off);
- skb_put(skb, sgt[i].length);
+ skb_put(skb, be32_to_cpu(sgt[i].length));
} else {
/* Not the first S/G entry; all data from buffer will
* be added in an skb fragment; fragment index is offset
@@ -495,8 +504,8 @@ static struct sk_buff *__hot sg_fd_to_skb(const struct dpa_priv_s *priv,
/* page_offset only refers to the beginning of sgt[i];
* but the buffer itself may have an internal offset.
*/
- frag_offset = sgt[i].offset + page_offset;
- frag_len = sgt[i].length;
+ frag_offset = be16_to_cpu(sgt[i].offset) + page_offset;
+ frag_len = be32_to_cpu(sgt[i].length);
/* skb_add_rx_frag() does no checking on the page; if
* we pass it a tail page, we'll end up with
* bad page accounting and eventually with segafults.
@@ -715,8 +724,8 @@ static int __hot skb_to_contig_fd(struct dpa_priv_s *priv,
netdev_err(net_dev, "dma_map_single() failed\n");
return -EINVAL;
}
- fd->addr_hi = (uint8_t)upper_32_bits(addr);
- fd->addr_lo = lower_32_bits(addr);
+ fd->addr = addr;
+
return 0;
}
@@ -764,7 +773,7 @@ static int __hot skb_to_sg_fd(struct dpa_priv_s *priv,
sgt = (struct qm_sg_entry *)(sgt_buf + priv->tx_headroom);
sgt[0].bpid = 0xff;
sgt[0].offset = 0;
- sgt[0].length = skb_headlen(skb);
+ sgt[0].length = cpu_to_be32(skb_headlen(skb));
sgt[0].extension = 0;
sgt[0].final = 0;
addr = dma_map_single(dpa_bp->dev, skb->data, sgt[0].length, dma_dir);
@@ -775,14 +784,14 @@ static int __hot skb_to_sg_fd(struct dpa_priv_s *priv,
}
sgt[0].addr_hi = (uint8_t)upper_32_bits(addr);
- sgt[0].addr_lo = lower_32_bits(addr);
+ sgt[0].addr_lo = cpu_to_be32(lower_32_bits(addr));
/* populate the rest of SGT entries */
for (i = 1; i <= nr_frags; i++) {
frag = &skb_shinfo(skb)->frags[i - 1];
sgt[i].bpid = 0xff;
sgt[i].offset = 0;
- sgt[i].length = frag->size;
+ sgt[i].length = cpu_to_be32(frag->size);
sgt[i].extension = 0;
sgt[i].final = 0;
@@ -797,7 +806,7 @@ static int __hot skb_to_sg_fd(struct dpa_priv_s *priv,
/* keep the offset in the address */
sgt[i].addr_hi = (uint8_t)upper_32_bits(addr);
- sgt[i].addr_lo = lower_32_bits(addr);
+ sgt[i].addr_lo = cpu_to_be32(lower_32_bits(addr));
}
sgt[i - 1].final = 1;
@@ -830,7 +839,7 @@ sgt_map_failed:
sg_map_failed:
for (j = 0; j < i; j++)
dma_unmap_page(dpa_bp->dev, qm_sg_addr(&sgt[j]),
- sgt[j].length, dma_dir);
+ be32_to_cpu(sgt[j].length), dma_dir);
sg0_map_failed:
csum_failed:
put_page(virt_to_head_page(sgt_buf));
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_shared.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth_shared.c
index 797dac9..1ac0007 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_shared.c
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_shared.c
@@ -67,7 +67,6 @@ shared_tx_error_dqrr(struct qman_portal *portal,
static void shared_ern(struct qman_portal *portal,
struct qman_fq *fq,
const struct qm_mr_entry *msg);
-int __hot dpa_shared_tx(struct sk_buff *skb, struct net_device *net_dev);
#define DPA_DESCRIPTION "FSL DPAA Shared Ethernet driver"
@@ -75,14 +74,10 @@ MODULE_LICENSE("Dual BSD/GPL");
MODULE_DESCRIPTION(DPA_DESCRIPTION);
-static uint8_t debug = -1;
-module_param(debug, byte, S_IRUGO);
-MODULE_PARM_DESC(debug, "Module/Driver verbosity level");
-
/* This has to work in tandem with the DPA_CS_THRESHOLD_xxx values. */
-static uint16_t tx_timeout = 1000;
-module_param(tx_timeout, ushort, S_IRUGO);
-MODULE_PARM_DESC(tx_timeout, "The Tx timeout in ms");
+static uint16_t shared_tx_timeout = 1000;
+module_param(shared_tx_timeout, ushort, S_IRUGO);
+MODULE_PARM_DESC(shared_tx_timeout, "The Tx timeout in ms");
static const struct of_device_id dpa_shared_match[];
@@ -274,18 +269,19 @@ shared_rx_dqrr(struct qman_portal *portal, struct qman_fq *fq,
if (fd->format == qm_fd_sg) {
if (dpa_bp->vaddr) {
- sgt = dpa_phys2virt(dpa_bp,
- qm_fd_addr(fd)) + dpa_fd_offset(fd);
+ sgt = dpa_phys2virt(dpa_bp, qm_fd_addr(fd)) +
+ dpa_fd_offset(fd);
for (i = 0; i < DPA_SGT_MAX_ENTRIES; i++) {
+ void *frag_addr = dpa_phys2virt(dpa_bp,
+ qm_sg_addr(&sgt[i]) +
+ be16_to_cpu(sgt[i].offset));
+ u32 frag_length = be32_to_cpu(sgt[i].length);
BUG_ON(sgt[i].extension);
/* copy from sgt[i] */
- memcpy(skb_put(skb, sgt[i].length),
- dpa_phys2virt(dpa_bp,
- qm_sg_addr(&sgt[i]) +
- sgt[i].offset),
- sgt[i].length);
+ memcpy(skb_put(skb, frag_length), frag_addr,
+ frag_length);
if (sgt[i].final)
break;
}
@@ -305,12 +301,13 @@ shared_rx_dqrr(struct qman_portal *portal, struct qman_fq *fq,
dpa_bp->size));
for (i = 0; i < DPA_SGT_MAX_ENTRIES; i++) {
+ u32 frag_length = be32_to_cpu(sgt[i].length);
BUG_ON(sgt[i].extension);
-
copy_from_unmapped_area(
- skb_put(skb, sgt[i].length),
- qm_sg_addr(&sgt[i]) + sgt[i].offset,
- sgt[i].length);
+ skb_put(skb, frag_length),
+ qm_sg_addr(&sgt[i]) +
+ be16_to_cpu(sgt[i].offset),
+ frag_length);
if (sgt[i].final)
break;
@@ -600,7 +597,7 @@ static int dpa_shared_netdev_init(struct device_node *dpa_node,
net_dev->hw_features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_LLTX);
- return dpa_netdev_init(dpa_node, net_dev, mac_addr, tx_timeout);
+ return dpa_netdev_init(net_dev, mac_addr, shared_tx_timeout);
}
#ifdef CONFIG_PM
@@ -717,7 +714,7 @@ dpaa_eth_shared_probe(struct platform_device *_of_dev)
priv->net_dev = net_dev;
strcpy(priv->if_type, "shared");
- priv->msg_enable = netif_msg_init(debug, -1);
+ priv->msg_enable = netif_msg_init(advanced_debug, -1);
mac_dev = dpa_mac_probe(_of_dev);
if (IS_ERR(mac_dev) || !mac_dev) {
@@ -805,10 +802,10 @@ dpaa_eth_shared_probe(struct platform_device *_of_dev)
buf_layout, dev);
/* Now we need to initialize either a private or shared interface */
- priv->percpu_priv = alloc_percpu(*priv->percpu_priv);
+ priv->percpu_priv = devm_alloc_percpu(dev, *priv->percpu_priv);
if (priv->percpu_priv == NULL) {
- dev_err(dev, "alloc_percpu() failed\n");
+ dev_err(dev, "devm_alloc_percpu() failed\n");
err = -ENOMEM;
goto alloc_percpu_failed;
}
@@ -830,8 +827,6 @@ dpaa_eth_shared_probe(struct platform_device *_of_dev)
return 0;
netdev_init_failed:
- if (net_dev)
- free_percpu(priv->percpu_priv);
alloc_percpu_failed:
fq_alloc_failed:
if (net_dev) {
@@ -866,7 +861,7 @@ MODULE_DEVICE_TABLE(of, dpa_shared_match);
static struct platform_driver dpa_shared_driver = {
.driver = {
- .name = KBUILD_MODNAME,
+ .name = KBUILD_MODNAME "-shared",
.of_match_table = dpa_shared_match,
.owner = THIS_MODULE,
.pm = SHARED_PM_OPS,
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_sysfs.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth_sysfs.c
index cd8b7d1..36f65a1 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_sysfs.c
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_sysfs.c
@@ -233,6 +233,7 @@ void dpaa_eth_sysfs_init(struct device *dev)
return;
}
}
+EXPORT_SYMBOL(dpaa_eth_sysfs_init);
void dpaa_eth_sysfs_remove(struct device *dev)
{
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_generic_debugfs.c b/drivers/net/ethernet/freescale/dpa/dpaa_generic_debugfs.c
index 6ab1ade..2b655cd 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_generic_debugfs.c
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_generic_debugfs.c
@@ -32,7 +32,6 @@
#include <linux/module.h>
#include <linux/fsl_qman.h>
#include <linux/debugfs.h>
-#include <asm/debug.h>
#include "dpaa_eth_generic.h"
@@ -236,8 +235,7 @@ int dpa_generic_debugfs_create(struct net_device *net_dev)
net_dev,
&dpa_debugfs_fops);
if (unlikely(priv->debugfs_file == NULL)) {
- netdev_err(net_dev, "debugfs_create_file(%s/%s/%s)",
- powerpc_debugfs_root->d_iname,
+ netdev_err(net_dev, "debugfs_create_file(%s/%s)",
dpa_debugfs_root->d_iname,
net_dev->name);
@@ -254,30 +252,26 @@ void dpa_generic_debugfs_remove(struct net_device *net_dev)
debugfs_remove(priv->debugfs_file);
}
-static int __init dpa_generic_debugfs_module_init(void)
+int __init dpa_generic_debugfs_module_init(void)
{
int _errno = 0;
pr_info(KBUILD_MODNAME ": " DPA_DEBUGFS_DESCRIPTION " (" VERSION ")\n");
dpa_debugfs_root = debugfs_create_dir(DPA_GENERIC_ETH_DEBUGFS_ROOT,
- powerpc_debugfs_root);
+ NULL);
if (unlikely(dpa_debugfs_root == NULL)) {
_errno = -ENOMEM;
pr_err(KBUILD_MODNAME ": %s:%hu:%s():\n",
KBUILD_BASENAME".c", __LINE__, __func__);
pr_err("\tdebugfs_create_dir(%s/"KBUILD_MODNAME") = %d\n",
- powerpc_debugfs_root->d_iname, _errno);
+ DPA_GENERIC_ETH_DEBUGFS_ROOT, _errno);
}
return _errno;
}
-static void __exit dpa_generic_debugfs_module_exit(void)
+void __exit dpa_generic_debugfs_module_exit(void)
{
debugfs_remove(dpa_debugfs_root);
}
-
-module_init(dpa_generic_debugfs_module_init);
-module_exit(dpa_generic_debugfs_module_exit);
-MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/ethernet/freescale/dpa/mac-api.c b/drivers/net/ethernet/freescale/dpa/mac-api.c
index f5d6c73..7fe569e 100644
--- a/drivers/net/ethernet/freescale/dpa/mac-api.c
+++ b/drivers/net/ethernet/freescale/dpa/mac-api.c
@@ -99,6 +99,8 @@ macdev2enetinterface(const struct mac_device *mac_dev)
return _100[mac_dev->phy_if];
case SPEED_1000:
return _1000[mac_dev->phy_if];
+ case SPEED_2500:
+ return e_ENET_MODE_SGMII_2500;
case SPEED_10000:
return e_ENET_MODE_XGMII_10000;
default:
@@ -352,6 +354,7 @@ int set_mac_active_pause(struct mac_device *mac_dev, bool rx, bool tx)
return _errno;
}
+EXPORT_SYMBOL(set_mac_active_pause);
/* Determine the MAC RX/TX PAUSE frames settings based on PHY
* autonegotiation or values set by eththool.
@@ -403,6 +406,7 @@ void get_pause_cfg(struct mac_device *mac_dev, bool *rx_pause, bool *tx_pause)
if (flowctrl & FLOW_CTRL_TX)
*tx_pause = true;
}
+EXPORT_SYMBOL(get_pause_cfg);
static void adjust_link(struct net_device *net_dev)
{
@@ -447,7 +451,7 @@ static int dtsec_init_phy(struct net_device *net_dev,
/* Remove any features not supported by the controller */
phy_dev->supported &= mac_dev->if_support;
- /* Enable the symmetric and asymmetric PAUSE frame advertisments,
+ /* Enable the symmetric and asymmetric PAUSE frame advertisements,
* as most of the PHY drivers do not enable them by default.
*/
phy_dev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause);
@@ -478,7 +482,7 @@ static int xgmac_init_phy(struct net_device *net_dev,
}
phy_dev->supported &= mac_dev->if_support;
- /* Enable the symmetric and asymmetric PAUSE frame advertisments,
+ /* Enable the symmetric and asymmetric PAUSE frame advertisements,
* as most of the PHY drivers do not enable them by default.
*/
phy_dev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause);
@@ -521,7 +525,7 @@ static int memac_init_phy(struct net_device *net_dev,
/* Remove any features not supported by the controller */
phy_dev->supported &= mac_dev->if_support;
- /* Enable the symmetric and asymmetric PAUSE frame advertisments,
+ /* Enable the symmetric and asymmetric PAUSE frame advertisements,
* as most of the PHY drivers do not enable them by default.
*/
phy_dev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause);
@@ -683,7 +687,7 @@ int fm_mac_dump_regs(struct mac_device *h_mac, char *buf, int nn)
return n;
}
-
+EXPORT_SYMBOL(fm_mac_dump_regs);
static void __cold setup_dtsec(struct mac_device *mac_dev)
{
diff --git a/drivers/net/ethernet/freescale/dpa/mac.c b/drivers/net/ethernet/freescale/dpa/mac.c
index 69b4b6c..faf00a1 100644
--- a/drivers/net/ethernet/freescale/dpa/mac.c
+++ b/drivers/net/ethernet/freescale/dpa/mac.c
@@ -45,6 +45,7 @@
#include <linux/of_net.h>
#include <linux/device.h>
#include <linux/phy.h>
+#include <linux/io.h>
#include "lnxwrp_fm_ext.h"
@@ -71,7 +72,8 @@ static const char phy_str[][11] = {
[PHY_INTERFACE_MODE_RGMII_RXID] = "rgmii-rxid",
[PHY_INTERFACE_MODE_RGMII_TXID] = "rgmii-txid",
[PHY_INTERFACE_MODE_RTBI] = "rtbi",
- [PHY_INTERFACE_MODE_XGMII] = "xgmii"
+ [PHY_INTERFACE_MODE_XGMII] = "xgmii",
+ [PHY_INTERFACE_MODE_SGMII_2500] = "sgmii_2500"
};
static phy_interface_t __pure __attribute__((nonnull)) str2phy(const char *str)
@@ -96,7 +98,8 @@ static const uint16_t phy2speed[] = {
[PHY_INTERFACE_MODE_RGMII_RXID] = SPEED_1000,
[PHY_INTERFACE_MODE_RGMII_TXID] = SPEED_1000,
[PHY_INTERFACE_MODE_RTBI] = SPEED_1000,
- [PHY_INTERFACE_MODE_XGMII] = SPEED_10000
+ [PHY_INTERFACE_MODE_XGMII] = SPEED_10000,
+ [PHY_INTERFACE_MODE_SGMII_2500] = SPEED_2500
};
static struct mac_device * __cold
@@ -140,7 +143,7 @@ MODULE_DEVICE_TABLE(of, mac_match);
static int __cold mac_probe(struct platform_device *_of_dev)
{
- int _errno, i, lenp;
+ int _errno, i;
struct device *dev;
struct device_node *mac_node, *dev_node;
struct mac_device *mac_dev;
@@ -148,8 +151,8 @@ static int __cold mac_probe(struct platform_device *_of_dev)
struct resource res;
const uint8_t *mac_addr;
const char *char_prop;
- const phandle *phandle_prop;
- const uint32_t *uint32_prop;
+ int nph;
+ u32 cell_index;
const struct of_device_id *match;
dev = &_of_dev->dev;
@@ -232,11 +235,15 @@ static int __cold mac_probe(struct platform_device *_of_dev)
mac_dev->tbi_node = of_parse_phandle(mac_node, "tbi-handle", 0);
if (mac_dev->tbi_node) {
u32 tbiaddr = TBIPA_DEFAULT_ADDR;
-
- uint32_prop = of_get_property(mac_dev->tbi_node, "reg", NULL);
- if (uint32_prop)
- tbiaddr = *uint32_prop;
- out_be32(mac_dev->vaddr + TBIPA_OFFSET, tbiaddr);
+ const __be32 *tbi_reg;
+ void __iomem *addr;
+
+ tbi_reg = of_get_property(mac_dev->tbi_node, "reg", NULL);
+ if (tbi_reg)
+ tbiaddr = be32_to_cpup(tbi_reg);
+ addr = mac_dev->vaddr + TBIPA_OFFSET;
+ /* TODO: out_be32 does not exist on ARM */
+ out_be32(addr, tbiaddr);
}
if (!of_device_is_available(mac_node)) {
@@ -250,15 +257,13 @@ static int __cold mac_probe(struct platform_device *_of_dev)
}
/* Get the cell-index */
- uint32_prop = of_get_property(mac_node, "cell-index", &lenp);
- if (unlikely(uint32_prop == NULL)) {
- dev_err(dev, "of_get_property(%s, cell-index) failed\n",
+ _errno = of_property_read_u32(mac_node, "cell-index", &cell_index);
+ if (unlikely(_errno)) {
+ dev_err(dev, "Cannot read cell-index of mac node %s from device tree\n",
mac_node->full_name);
- _errno = -EINVAL;
goto _return_dev_set_drvdata;
}
- BUG_ON(lenp != sizeof(uint32_t));
- mac_dev->cell_index = (uint8_t)*uint32_prop;
+ mac_dev->cell_index = (uint8_t)cell_index;
/* Get the MAC address */
mac_addr = of_get_mac_address(mac_node);
@@ -270,21 +275,27 @@ static int __cold mac_probe(struct platform_device *_of_dev)
}
memcpy(mac_dev->addr, mac_addr, sizeof(mac_dev->addr));
- /* Get the port handles */
- phandle_prop = of_get_property(mac_node, "fsl,port-handles", &lenp);
- if (unlikely(phandle_prop == NULL)) {
- dev_err(dev, "of_get_property(%s, port-handles) failed\n",
+ /* Verify the number of port handles */
+ nph = of_count_phandle_with_args(mac_node, "fsl,port-handles", NULL);
+ if (unlikely(nph < 0)) {
+ dev_err(dev, "Cannot read port handles of mac node %s from device tree\n",
+ mac_node->full_name);
+ _errno = nph;
+ goto _return_dev_set_drvdata;
+ }
+
+ if (nph != ARRAY_SIZE(mac_dev->port_dev)) {
+ dev_err(dev, "Not supported number of port handles of mac node %s from device tree\n",
mac_node->full_name);
_errno = -EINVAL;
goto _return_dev_set_drvdata;
}
- BUG_ON(lenp != sizeof(phandle) * ARRAY_SIZE(mac_dev->port_dev));
for_each_port_device(i, mac_dev->port_dev) {
- /* Find the port node */
- dev_node = of_find_node_by_phandle(phandle_prop[i]);
+ dev_node = of_parse_phandle(mac_node, "fsl,port-handles", i);
if (unlikely(dev_node == NULL)) {
- dev_err(dev, "of_find_node_by_phandle() failed\n");
+ dev_err(dev, "Cannot find port node referenced by mac node %s from device tree\n",
+ mac_node->full_name);
_errno = -EINVAL;
goto _return_of_node_put;
}
@@ -308,11 +319,11 @@ static int __cold mac_probe(struct platform_device *_of_dev)
}
/* Get the PHY connection type */
- char_prop = (const char *)of_get_property(mac_node,
- "phy-connection-type", NULL);
- if (unlikely(char_prop == NULL)) {
+ _errno = of_property_read_string(mac_node, "phy-connection-type",
+ &char_prop);
+ if (unlikely(_errno)) {
dev_warn(dev,
- "of_get_property(%s, phy-connection-type) failed. Defaulting to MII\n",
+ "Cannot read PHY connection type of mac node %s from device tree. Defaulting to MII\n",
mac_node->full_name);
mac_dev->phy_if = PHY_INTERFACE_MODE_MII;
} else
@@ -328,6 +339,10 @@ static int __cold mac_probe(struct platform_device *_of_dev)
mac_dev->if_support &= ~(SUPPORTED_10baseT_Half |
SUPPORTED_100baseT_Half);
+ if (strstr(char_prop, "sgmii_2500"))
+ mac_dev->if_support &= ~(SUPPORTED_10baseT_Half |
+ SUPPORTED_100baseT_Half);
+
/* Gigabit support (no half-duplex) */
if (mac_dev->max_speed == 1000)
mac_dev->if_support |= SUPPORTED_1000baseT_Full;
@@ -339,17 +354,17 @@ static int __cold mac_probe(struct platform_device *_of_dev)
/* Get the rest of the PHY information */
mac_dev->phy_node = of_parse_phandle(mac_node, "phy-handle", 0);
if (mac_dev->phy_node == NULL) {
- int sz;
- const u32 *phy_id = of_get_property(mac_node, "fixed-link",
- &sz);
- if (!phy_id || sz < sizeof(*phy_id)) {
+ u32 phy_id;
+
+ _errno = of_property_read_u32(mac_node, "fixed-link", &phy_id);
+ if (_errno) {
dev_err(dev, "No PHY (or fixed link) found\n");
_errno = -EINVAL;
goto _return_dev_set_drvdata;
}
sprintf(mac_dev->fixed_bus_id, PHY_ID_FMT, "fixed-0",
- phy_id[0]);
+ phy_id);
}
_errno = mac_dev->init(mac_dev);
diff --git a/drivers/net/ethernet/freescale/dpa/offline_port.c b/drivers/net/ethernet/freescale/dpa/offline_port.c
index 042f44a..ddbfdce 100644
--- a/drivers/net/ethernet/freescale/dpa/offline_port.c
+++ b/drivers/net/ethernet/freescale/dpa/offline_port.c
@@ -250,14 +250,13 @@ oh_port_probe(struct platform_device *_of_dev)
struct device_node *dpa_oh_node;
int lenp, _errno = 0, fq_idx, duple_idx;
int n_size, i, j, ret, duples_count;
- const phandle *oh_port_handle, *bpool_handle;
struct platform_device *oh_of_dev;
struct device_node *oh_node, *bpool_node = NULL, *root_node;
struct device *oh_dev;
struct dpa_oh_config_s *oh_config = NULL;
- uint32_t *oh_all_queues;
- uint32_t *channel_ids;
- uint32_t *oh_tx_queues;
+ const __be32 *oh_all_queues;
+ const __be32 *channel_ids;
+ const __be32 *oh_tx_queues;
uint32_t queues_count;
uint32_t crt_fqid_base;
uint32_t crt_fq_count;
@@ -270,17 +269,18 @@ oh_port_probe(struct platform_device *_of_dev)
bool init_oh_port;
const struct of_device_id *match;
- uint32_t crt_ext_pools_count, ext_pool_size;
- const unsigned int *port_id;
- const unsigned int *channel_id;
+ int crt_ext_pools_count;
+ u32 ext_pool_size;
+ u32 port_id;
+ u32 channel_id;
int channel_ids_count;
int channel_idx;
struct fq_duple *fqd;
struct list_head *fq_list, *fq_list_tmp;
- const uint32_t *bpool_cfg;
- const uint32_t *bpid;
+ const __be32 *bpool_cfg;
+ uint32_t bpid;
memset(&oh_port_tx_params, 0, sizeof(oh_port_tx_params));
dpa_oh_dev = &_of_dev->dev;
@@ -294,49 +294,28 @@ oh_port_probe(struct platform_device *_of_dev)
dev_dbg(dpa_oh_dev, "Probing OH port...\n");
/* Find the referenced OH node */
-
- oh_port_handle = of_get_property(dpa_oh_node,
- "fsl,fman-oh-port", &lenp);
- if (oh_port_handle == NULL) {
- dev_err(dpa_oh_dev, "No OH port handle found in node %s\n",
- dpa_oh_node->full_name);
- return -EINVAL;
- }
-
- BUG_ON(lenp % sizeof(*oh_port_handle));
- if (lenp != sizeof(*oh_port_handle)) {
- dev_err(dpa_oh_dev,
- "Found %lu OH port bindings in node %s, only 1 phandle is allowed.\n",
- (unsigned long int)(lenp / sizeof(*oh_port_handle)),
- dpa_oh_node->full_name);
- return -EINVAL;
- }
-
- /* Read configuration for the OH port */
- oh_node = of_find_node_by_phandle(*oh_port_handle);
+ oh_node = of_parse_phandle(dpa_oh_node, "fsl,fman-oh-port", 0);
if (oh_node == NULL) {
dev_err(dpa_oh_dev,
"Can't find OH node referenced from node %s\n",
dpa_oh_node->full_name);
return -EINVAL;
}
- dev_info(dpa_oh_dev, "Found OH node handle compatible with %s.\n",
+ dev_info(dpa_oh_dev, "Found OH node handle compatible with %s\n",
match->compatible);
- port_id = of_get_property(oh_node, "cell-index", &lenp);
- if (port_id == NULL) {
+ _errno = of_property_read_u32(oh_node, "cell-index", &port_id);
+ if (_errno) {
dev_err(dpa_oh_dev, "No port id found in node %s\n",
dpa_oh_node->full_name);
- _errno = -EINVAL;
goto return_kfree;
}
- BUG_ON(lenp % sizeof(*port_id));
- channel_id = of_get_property(oh_node, "fsl,qman-channel-id", &lenp);
- if (channel_id == NULL) {
+ _errno = of_property_read_u32(oh_node, "fsl,qman-channel-id",
+ &channel_id);
+ if (_errno) {
dev_err(dpa_oh_dev, "No channel id found in node %s\n",
dpa_oh_node->full_name);
- _errno = -EINVAL;
goto return_kfree;
}
@@ -383,7 +362,7 @@ oh_port_probe(struct platform_device *_of_dev)
/* FQs that enter OH port */
lenp = 0;
- oh_all_queues = (uint32_t *)of_get_property(dpa_oh_node,
+ oh_all_queues = of_get_property(dpa_oh_node,
"fsl,qman-frame-queues-ingress", &lenp);
if (lenp % (2 * sizeof(*oh_all_queues))) {
dev_warn(dpa_oh_dev,
@@ -396,8 +375,8 @@ oh_port_probe(struct platform_device *_of_dev)
dev_err(dpa_oh_dev, "Allocating %d ingress frame queues duples\n",
duples_count);
for (duple_idx = 0; duple_idx < duples_count; duple_idx++) {
- crt_fqid_base = oh_all_queues[2 * duple_idx];
- crt_fq_count = oh_all_queues[2 * duple_idx + 1];
+ crt_fqid_base = be32_to_cpu(oh_all_queues[2 * duple_idx]);
+ crt_fq_count = be32_to_cpu(oh_all_queues[2 * duple_idx + 1]);
fqd = devm_kzalloc(dpa_oh_dev,
sizeof(struct fq_duple), GFP_KERNEL);
@@ -423,7 +402,7 @@ oh_port_probe(struct platform_device *_of_dev)
for (j = 0; j < crt_fq_count; j++)
(fqd->fqs + j)->fqid = crt_fqid_base + j;
fqd->fqs_count = crt_fq_count;
- fqd->channel_id = (uint16_t)*channel_id;
+ fqd->channel_id = (uint16_t)channel_id;
list_add(&fqd->fq_list, &oh_config->fqs_ingress_list);
}
@@ -448,7 +427,7 @@ oh_port_probe(struct platform_device *_of_dev)
/* FQs that exit OH port */
lenp = 0;
- oh_all_queues = (uint32_t *)of_get_property(dpa_oh_node,
+ oh_all_queues = of_get_property(dpa_oh_node,
"fsl,qman-frame-queues-egress", &lenp);
if (lenp % (2 * sizeof(*oh_all_queues))) {
dev_warn(dpa_oh_dev,
@@ -461,8 +440,8 @@ oh_port_probe(struct platform_device *_of_dev)
dev_dbg(dpa_oh_dev, "Allocating %d egress frame queues duples\n",
duples_count);
for (duple_idx = 0; duple_idx < duples_count; duple_idx++) {
- crt_fqid_base = oh_all_queues[2 * duple_idx];
- crt_fq_count = oh_all_queues[2 * duple_idx + 1];
+ crt_fqid_base = be32_to_cpu(oh_all_queues[2 * duple_idx]);
+ crt_fq_count = be32_to_cpu(oh_all_queues[2 * duple_idx + 1]);
fqd = devm_kzalloc(dpa_oh_dev,
sizeof(struct fq_duple), GFP_KERNEL);
@@ -499,7 +478,7 @@ oh_port_probe(struct platform_device *_of_dev)
/* channel_ids for FQs that exit OH port */
lenp = 0;
- channel_ids = (uint32_t *)of_get_property(dpa_oh_node,
+ channel_ids = of_get_property(dpa_oh_node,
"fsl,qman-channel-ids-egress", &lenp);
channel_ids_count = lenp / (sizeof(*channel_ids));
@@ -515,7 +494,8 @@ oh_port_probe(struct platform_device *_of_dev)
if (channel_idx + 1 > channel_ids_count)
break;
fqd = list_entry(fq_list, struct fq_duple, fq_list);
- fqd->channel_id = (uint16_t)channel_ids[channel_idx++];
+ fqd->channel_id =
+ (uint16_t)be32_to_cpu(channel_ids[channel_idx++]);
}
/* create egress queues */
@@ -543,7 +523,7 @@ oh_port_probe(struct platform_device *_of_dev)
}
/* Read FQ ids/nums for the DPA OH node */
- oh_all_queues = (uint32_t *)of_get_property(dpa_oh_node,
+ oh_all_queues = of_get_property(dpa_oh_node,
"fsl,qman-frame-queues-oh", &lenp);
if (oh_all_queues == NULL) {
dev_err(dpa_oh_dev,
@@ -569,8 +549,8 @@ oh_port_probe(struct platform_device *_of_dev)
fq_idx = 0;
/* Error FQID - must be present */
- crt_fqid_base = oh_all_queues[fq_idx++];
- crt_fq_count = oh_all_queues[fq_idx++];
+ crt_fqid_base = be32_to_cpu(oh_all_queues[fq_idx++]);
+ crt_fq_count = be32_to_cpu(oh_all_queues[fq_idx++]);
if (crt_fq_count != 1) {
dev_err(dpa_oh_dev,
"Only 1 Error FQ allowed in OH node %s referenced from node %s (read: %d FQIDs).\n",
@@ -584,8 +564,8 @@ oh_port_probe(struct platform_device *_of_dev)
oh_config->error_fqid, oh_node->full_name);
/* Default FQID - must be present */
- crt_fqid_base = oh_all_queues[fq_idx++];
- crt_fq_count = oh_all_queues[fq_idx++];
+ crt_fqid_base = be32_to_cpu(oh_all_queues[fq_idx++]);
+ crt_fq_count = be32_to_cpu(oh_all_queues[fq_idx++]);
if (crt_fq_count != 1) {
dev_err(dpa_oh_dev,
"Only 1 Default FQ allowed in OH node %s referenced from %s (read: %d FQIDs).\n",
@@ -599,8 +579,8 @@ oh_port_probe(struct platform_device *_of_dev)
oh_config->default_fqid, oh_node->full_name);
/* TX FQID - presence is optional */
- oh_tx_queues = (uint32_t *)of_get_property(dpa_oh_node,
- "fsl,qman-frame-queues-tx", &lenp);
+ oh_tx_queues = of_get_property(dpa_oh_node, "fsl,qman-frame-queues-tx",
+ &lenp);
if (oh_tx_queues == NULL) {
dev_dbg(dpa_oh_dev,
"No tx queues have been defined for OH node %s referenced from node %s\n",
@@ -619,19 +599,9 @@ oh_port_probe(struct platform_device *_of_dev)
goto return_kfree;
}
- /* Read channel id for the queues */
- channel_id = of_get_property(oh_node, "fsl,qman-channel-id", &lenp);
- if (channel_id == NULL) {
- dev_err(dpa_oh_dev, "No channel id found in node %s\n",
- dpa_oh_node->full_name);
- _errno = -EINVAL;
- goto return_kfree;
- }
- BUG_ON(lenp % sizeof(*channel_id));
-
fq_idx = 0;
- crt_fqid_base = oh_tx_queues[fq_idx++];
- crt_fq_count = oh_tx_queues[fq_idx++];
+ crt_fqid_base = be32_to_cpu(oh_tx_queues[fq_idx++]);
+ crt_fq_count = be32_to_cpu(oh_tx_queues[fq_idx++]);
oh_config->egress_cnt = crt_fq_count;
/* Allocate TX queues */
@@ -649,7 +619,7 @@ oh_port_probe(struct platform_device *_of_dev)
/* Create TX queues */
for (i = 0; i < crt_fq_count; i++) {
ret = oh_fq_create(oh_config->egress_fqs + i,
- crt_fqid_base + i, (uint16_t)*channel_id, 3);
+ crt_fqid_base + i, (uint16_t)channel_id, 3);
if (ret != 0) {
dev_err(dpa_oh_dev,
"Unable to create TX frame queue %d for OH node %s referenced from node %s!\n",
@@ -673,10 +643,11 @@ config_port:
}
oh_set_buffer_layout(oh_config->oh_port, &buf_layout);
- bpool_handle = of_get_property(dpa_oh_node,
- "fsl,bman-buffer-pools", &lenp);
- if (bpool_handle == NULL) {
+ /* read the pool handlers */
+ crt_ext_pools_count = of_count_phandle_with_args(dpa_oh_node,
+ "fsl,bman-buffer-pools", NULL);
+ if (crt_ext_pools_count <= 0) {
dev_info(dpa_oh_dev,
"OH port %s has no buffer pool. Fragmentation will not be enabled\n",
oh_node->full_name);
@@ -694,29 +665,29 @@ config_port:
n_size = of_n_size_cells(root_node);
of_node_put(root_node);
- crt_ext_pools_count = lenp / sizeof(phandle);
- dev_dbg(dpa_oh_dev, "OH port number of pools = %u\n",
+ dev_dbg(dpa_oh_dev, "OH port number of pools = %d\n",
crt_ext_pools_count);
oh_port_tx_params.num_pools = (uint8_t)crt_ext_pools_count;
for (i = 0; i < crt_ext_pools_count; i++) {
- bpool_node = of_find_node_by_phandle(bpool_handle[i]);
+ bpool_node = of_parse_phandle(dpa_oh_node,
+ "fsl,bman-buffer-pools", i);
if (bpool_node == NULL) {
dev_err(dpa_oh_dev, "Invalid Buffer pool node\n");
_errno = -EINVAL;
goto return_kfree;
}
- bpid = of_get_property(bpool_node, "fsl,bpid", &lenp);
- if ((bpid == NULL) || (lenp != sizeof(*bpid))) {
- dev_err(dpa_oh_dev, "Invalid Buffer pool Id\n");
+ _errno = of_property_read_u32(bpool_node, "fsl,bpid", &bpid);
+ if (_errno) {
+ dev_err(dpa_oh_dev, "Invalid Buffer Pool ID\n");
_errno = -EINVAL;
goto return_kfree;
}
- oh_port_tx_params.pool_param[i].id = (uint8_t)*bpid;
- dev_dbg(dpa_oh_dev, "OH port bpool id = %u\n", *bpid);
+ oh_port_tx_params.pool_param[i].id = (uint8_t)bpid;
+ dev_dbg(dpa_oh_dev, "OH port bpool id = %u\n", bpid);
bpool_cfg = of_get_property(bpool_node,
"fsl,bpool-ethernet-cfg", &lenp);
@@ -726,7 +697,6 @@ config_port:
goto return_kfree;
}
- of_read_number(bpool_cfg, n_size);
ext_pool_size = of_read_number(bpool_cfg + n_size, n_size);
oh_port_tx_params.pool_param[i].size = (uint16_t)ext_pool_size;
dev_dbg(dpa_oh_dev, "OH port bpool size = %u\n",
@@ -741,7 +711,7 @@ config_port:
frag_enabled = true;
dev_info(dpa_oh_dev, "IP Fragmentation enabled for OH port %d",
- *port_id);
+ port_id);
init_port:
of_node_put(oh_node);
diff --git a/drivers/net/ethernet/freescale/fman/Peripherals/FM/MAC/memac.c b/drivers/net/ethernet/freescale/fman/Peripherals/FM/MAC/memac.c
index 9566521..24913de 100644
--- a/drivers/net/ethernet/freescale/fman/Peripherals/FM/MAC/memac.c
+++ b/drivers/net/ethernet/freescale/fman/Peripherals/FM/MAC/memac.c
@@ -93,6 +93,8 @@ static void SetupSgmiiInternalPhy(t_Memac *p_Memac, uint8_t phyAddr)
/* SGMII mode + AN enable */
tmpReg16 = PHY_SGMII_IF_MODE_AN | PHY_SGMII_IF_MODE_SGMII;
+ if ((p_Memac->enetMode) == e_ENET_MODE_SGMII_2500)
+ tmpReg16 = PHY_SGMII_CR_PHY_RESET | PHY_SGMII_IF_MODE_SGMII;
MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x14, tmpReg16);
/* Device ability according to SGMII specification */
@@ -693,6 +695,21 @@ static t_Error MemacDelExactMatchMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthA
/* ......................................................................... */
+static t_Error MemacGetId(t_Handle h_Memac, uint32_t *macId)
+{
+ t_Memac *p_Memac = (t_Memac *)h_Memac;
+
+ SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
+
+ *macId = p_Memac->macId;
+
+ return E_OK;
+}
+
+/* ......................................................................... */
+
+
static t_Error MemacAddHashMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr)
{
t_Memac *p_Memac = (t_Memac *)h_Memac;
@@ -1059,7 +1076,7 @@ static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacController
p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr = MemacDelHashMacAddress;
p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr = MemacAddExactMatchMacAddress;
p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr = MemacDelExactMatchMacAddress;
- p_FmMacControllerDriver->f_FM_MAC_GetId = NULL;
+ p_FmMacControllerDriver->f_FM_MAC_GetId = MemacGetId;
p_FmMacControllerDriver->f_FM_MAC_GetVersion = NULL;
p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength = MemacGetMaxFrameLength;
diff --git a/drivers/net/ethernet/freescale/fman/Peripherals/FM/MACSEC/Makefile b/drivers/net/ethernet/freescale/fman/Peripherals/FM/MACSEC/Makefile
new file mode 100644
index 0000000..4ab19a3
--- /dev/null
+++ b/drivers/net/ethernet/freescale/fman/Peripherals/FM/MACSEC/Makefile
@@ -0,0 +1,15 @@
+#
+# Makefile for the Freescale Ethernet controllers
+#
+EXTRA_CFLAGS += -DVERSION=\"\"
+#
+#Include netcomm SW specific definitions
+include $(srctree)/drivers/net/ethernet/freescale/fman/ncsw_config.mk
+
+NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/fman/Peripherals/FM/inc
+
+EXTRA_CFLAGS += -I$(NCSW_FM_INC)
+
+obj-y += fsl-ncsw-macsec.o
+
+fsl-ncsw-macsec-objs := fm_macsec.o fm_macsec_guest.o fm_macsec_master.o fm_macsec_secy.o
diff --git a/drivers/net/ethernet/freescale/fman/Peripherals/FM/MACSEC/fm_macsec.c b/drivers/net/ethernet/freescale/fman/Peripherals/FM/MACSEC/fm_macsec.c
new file mode 100644
index 0000000..0a1b31f
--- /dev/null
+++ b/drivers/net/ethernet/freescale/fman/Peripherals/FM/MACSEC/fm_macsec.c
@@ -0,0 +1,237 @@
+/*
+ * Copyright 2008-2015 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/******************************************************************************
+
+ @File fm_macsec.c
+
+ @Description FM MACSEC driver routines implementation.
+*//***************************************************************************/
+
+#include "std_ext.h"
+#include "error_ext.h"
+#include "xx_ext.h"
+#include "string_ext.h"
+#include "sprint_ext.h"
+#include "debug_ext.h"
+
+#include "fm_macsec.h"
+
+
+/****************************************/
+/* API Init unit functions */
+/****************************************/
+t_Handle FM_MACSEC_Config(t_FmMacsecParams *p_FmMacsecParam)
+{
+ t_FmMacsecControllerDriver *p_FmMacsecControllerDriver;
+
+ SANITY_CHECK_RETURN_VALUE(p_FmMacsecParam, E_INVALID_HANDLE, NULL);
+
+ if (p_FmMacsecParam->guestMode)
+ p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)FM_MACSEC_GUEST_Config(p_FmMacsecParam);
+ else
+ p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)FM_MACSEC_MASTER_Config(p_FmMacsecParam);
+
+ if (!p_FmMacsecControllerDriver)
+ return NULL;
+
+ return (t_Handle)p_FmMacsecControllerDriver;
+}
+
+t_Error FM_MACSEC_Init(t_Handle h_FmMacsec)
+{
+ t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacsecControllerDriver->f_FM_MACSEC_Init)
+ return p_FmMacsecControllerDriver->f_FM_MACSEC_Init(h_FmMacsec);
+
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+t_Error FM_MACSEC_Free(t_Handle h_FmMacsec)
+{
+ t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacsecControllerDriver->f_FM_MACSEC_Free)
+ return p_FmMacsecControllerDriver->f_FM_MACSEC_Free(h_FmMacsec);
+
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+t_Error FM_MACSEC_ConfigUnknownSciFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode)
+{
+ t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUnknownSciFrameTreatment)
+ return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUnknownSciFrameTreatment(h_FmMacsec, treatMode);
+
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+t_Error FM_MACSEC_ConfigInvalidTagsFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled)
+{
+ t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigInvalidTagsFrameTreatment)
+ return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigInvalidTagsFrameTreatment(h_FmMacsec, deliverUncontrolled);
+
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+t_Error FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(t_Handle h_FmMacsec, bool discardUncontrolled)
+{
+ t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment)
+ return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(h_FmMacsec, discardUncontrolled);
+
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+t_Error FM_MACSEC_ConfigUntagFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode)
+{
+ t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUntagFrameTreatment)
+ return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUntagFrameTreatment(h_FmMacsec, treatMode);
+
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+t_Error FM_MACSEC_ConfigPnExhaustionThreshold(t_Handle h_FmMacsec, uint32_t pnExhThr)
+{
+ t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigPnExhaustionThreshold)
+ return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigPnExhaustionThreshold(h_FmMacsec, pnExhThr);
+
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+t_Error FM_MACSEC_ConfigKeysUnreadable(t_Handle h_FmMacsec)
+{
+ t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigKeysUnreadable)
+ return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigKeysUnreadable(h_FmMacsec);
+
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+t_Error FM_MACSEC_ConfigSectagWithoutSCI(t_Handle h_FmMacsec)
+{
+ t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigSectagWithoutSCI)
+ return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigSectagWithoutSCI(h_FmMacsec);
+
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+t_Error FM_MACSEC_ConfigException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable)
+{
+ t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigException)
+ return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigException(h_FmMacsec, exception, enable);
+
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+t_Error FM_MACSEC_GetRevision(t_Handle h_FmMacsec, uint32_t *p_MacsecRevision)
+{
+ t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacsecControllerDriver->f_FM_MACSEC_GetRevision)
+ return p_FmMacsecControllerDriver->f_FM_MACSEC_GetRevision(h_FmMacsec, p_MacsecRevision);
+
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+
+t_Error FM_MACSEC_Enable(t_Handle h_FmMacsec)
+{
+ t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacsecControllerDriver->f_FM_MACSEC_Enable)
+ return p_FmMacsecControllerDriver->f_FM_MACSEC_Enable(h_FmMacsec);
+
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+t_Error FM_MACSEC_Disable(t_Handle h_FmMacsec)
+{
+ t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacsecControllerDriver->f_FM_MACSEC_Disable)
+ return p_FmMacsecControllerDriver->f_FM_MACSEC_Disable(h_FmMacsec);
+
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+t_Error FM_MACSEC_SetException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable)
+{
+ t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacsecControllerDriver->f_FM_MACSEC_SetException)
+ return p_FmMacsecControllerDriver->f_FM_MACSEC_SetException(h_FmMacsec, exception, enable);
+
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
diff --git a/drivers/net/ethernet/freescale/fman/Peripherals/FM/MACSEC/fm_macsec.h b/drivers/net/ethernet/freescale/fman/Peripherals/FM/MACSEC/fm_macsec.h
new file mode 100644
index 0000000..fbe5187
--- /dev/null
+++ b/drivers/net/ethernet/freescale/fman/Peripherals/FM/MACSEC/fm_macsec.h
@@ -0,0 +1,203 @@
+/*
+ * Copyright 2008-2015 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/******************************************************************************
+ @File fm_macsec.h
+
+ @Description FM MACSEC internal structures and definitions.
+*//***************************************************************************/
+#ifndef __FM_MACSEC_H
+#define __FM_MACSEC_H
+
+#include "error_ext.h"
+#include "std_ext.h"
+#include "fm_macsec_ext.h"
+
+#include "fm_common.h"
+
+
+#define __ERR_MODULE__ MODULE_FM_MACSEC
+
+
+typedef struct
+{
+ t_Error (*f_FM_MACSEC_Init) (t_Handle h_FmMacsec);
+ t_Error (*f_FM_MACSEC_Free) (t_Handle h_FmMacsec);
+
+ t_Error (*f_FM_MACSEC_ConfigUnknownSciFrameTreatment) (t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode);
+ t_Error (*f_FM_MACSEC_ConfigInvalidTagsFrameTreatment) (t_Handle h_FmMacsec, bool deliverUncontrolled);
+ t_Error (*f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment) (t_Handle h_FmMacsec, bool discardUncontrolled);
+ t_Error (*f_FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment) (t_Handle h_FmMacsec, bool deliverUncontrolled);
+ t_Error (*f_FM_MACSEC_ConfigUntagFrameTreatment) (t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode);
+ t_Error (*f_FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment) (t_Handle h_FmMacsec, bool deliverUncontrolled);
+ t_Error (*f_FM_MACSEC_ConfigPnExhaustionThreshold) (t_Handle h_FmMacsec, uint32_t pnExhThr);
+ t_Error (*f_FM_MACSEC_ConfigKeysUnreadable) (t_Handle h_FmMacsec);
+ t_Error (*f_FM_MACSEC_ConfigSectagWithoutSCI) (t_Handle h_FmMacsec);
+ t_Error (*f_FM_MACSEC_ConfigException) (t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable);
+
+ t_Error (*f_FM_MACSEC_GetRevision) (t_Handle h_FmMacsec, uint32_t *p_MacsecRevision);
+ t_Error (*f_FM_MACSEC_Enable) (t_Handle h_FmMacsec);
+ t_Error (*f_FM_MACSEC_Disable) (t_Handle h_FmMacsec);
+ t_Error (*f_FM_MACSEC_SetException) (t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable);
+
+} t_FmMacsecControllerDriver;
+
+t_Handle FM_MACSEC_GUEST_Config(t_FmMacsecParams *p_FmMacsecParam);
+t_Handle FM_MACSEC_MASTER_Config(t_FmMacsecParams *p_FmMacsecParams);
+
+/***********************************************************************/
+/* MACSEC internal routines */
+/***********************************************************************/
+
+/**************************************************************************//**
+
+ @Group FM_MACSEC_InterModule_grp FM MACSEC Inter-Module Unit
+
+ @Description FM MACSEC Inter Module functions -
+ These are not User API routines but routines that may be called
+ from other modules. This will be the case in a single core environment,
+ where instead of using the XX messaging mechanism, the routines may be
+ called from other modules. In a multicore environment, the other modules may
+ be run by other cores and therefore these routines may not be called directly.
+
+ @{
+*//***************************************************************************/
+
+#define MAX_NUM_OF_SA_PER_SC 4
+
+typedef enum
+{
+ e_SC_RX = 0,
+ e_SC_TX
+} e_ScType;
+
+typedef enum
+{
+ e_SC_SA_A = 0,
+ e_SC_SA_B ,
+ e_SC_SA_C ,
+ e_SC_SA_D
+} e_ScSaId;
+
+typedef struct
+{
+ uint32_t scId;
+ macsecSCI_t sci;
+ bool replayProtect;
+ uint32_t replayWindow;
+ e_FmMacsecValidFrameBehavior validateFrames;
+ uint16_t confidentialityOffset;
+ e_FmMacsecSecYCipherSuite cipherSuite;
+} t_RxScParams;
+
+typedef struct
+{
+ uint32_t scId;
+ macsecSCI_t sci;
+ bool protectFrames;
+ e_FmMacsecSciInsertionMode sciInsertionMode;
+ bool confidentialityEnable;
+ uint16_t confidentialityOffset;
+ e_FmMacsecSecYCipherSuite cipherSuite;
+} t_TxScParams;
+
+typedef enum e_FmMacsecGlobalExceptions {
+ e_FM_MACSEC_EX_TX_SC, /**< Tx Sc 0 frame discarded error. */
+ e_FM_MACSEC_EX_ECC /**< MACSEC memory ECC multiple-bit error. */
+} e_FmMacsecGlobalExceptions;
+
+typedef enum e_FmMacsecGlobalEvents {
+ e_FM_MACSEC_EV_TX_SC_NEXT_PN /**< Tx Sc 0 Next Pn exhaustion threshold reached. */
+} e_FmMacsecGlobalEvents;
+
+/**************************************************************************//**
+ @Description Enum for inter-module interrupts registration
+*//***************************************************************************/
+typedef enum e_FmMacsecEventModules{
+ e_FM_MACSEC_MOD_SC_TX,
+ e_FM_MACSEC_MOD_DUMMY_LAST
+} e_FmMacsecEventModules;
+
+typedef enum e_FmMacsecInterModuleEvent {
+ e_FM_MACSEC_EV_SC_TX,
+ e_FM_MACSEC_EV_ERR_SC_TX,
+ e_FM_MACSEC_EV_DUMMY_LAST
+} e_FmMacsecInterModuleEvent;
+
+#define NUM_OF_INTER_MODULE_EVENTS (NUM_OF_TX_SC * 2)
+
+#define GET_MACSEC_MODULE_EVENT(mod, id, intrType, event) \
+ switch(mod){ \
+ case e_FM_MACSEC_MOD_SC_TX: \
+ event = (intrType == e_FM_INTR_TYPE_ERR) ? \
+ e_FM_MACSEC_EV_ERR_SC_TX: \
+ e_FM_MACSEC_EV_SC_TX; \
+ event += (uint8_t)(2 * id);break; \
+ break; \
+ default:event = e_FM_MACSEC_EV_DUMMY_LAST; \
+ break;}
+
+void FmMacsecRegisterIntr(t_Handle h_FmMacsec,
+ e_FmMacsecEventModules module,
+ uint8_t modId,
+ e_FmIntrType intrType,
+ void (*f_Isr) (t_Handle h_Arg, uint32_t id),
+ t_Handle h_Arg);
+
+void FmMacsecUnregisterIntr(t_Handle h_FmMacsec,
+ e_FmMacsecEventModules module,
+ uint8_t modId,
+ e_FmIntrType intrType);
+
+t_Error FmMacsecAllocScs(t_Handle h_FmMacsec, e_ScType type, bool isPtp, uint32_t numOfScs, uint32_t *p_ScIds);
+t_Error FmMacsecFreeScs(t_Handle h_FmMacsec, e_ScType type, uint32_t numOfScs, uint32_t *p_ScIds);
+t_Error FmMacsecCreateRxSc(t_Handle h_FmMacsec, t_RxScParams *p_RxScParams);
+t_Error FmMacsecDeleteRxSc(t_Handle h_FmMacsec, uint32_t scId);
+t_Error FmMacsecCreateTxSc(t_Handle h_FmMacsec, t_TxScParams *p_RxScParams);
+t_Error FmMacsecDeleteTxSc(t_Handle h_FmMacsec, uint32_t scId);
+t_Error FmMacsecCreateRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key);
+t_Error FmMacsecCreateTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecSAKey_t key);
+t_Error FmMacsecDeleteRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId);
+t_Error FmMacsecDeleteTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId);
+t_Error FmMacsecRxSaSetReceive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, bool enableReceive);
+t_Error FmMacsecRxSaUpdateNextPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtNextPN);
+t_Error FmMacsecRxSaUpdateLowestPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtLowestPN);
+t_Error FmMacsecTxSaSetActive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an);
+t_Error FmMacsecTxSaGetActive(t_Handle h_FmMacsec, uint32_t scId, macsecAN_t *p_An);
+t_Error FmMacsecSetPTP(t_Handle h_FmMacsec, bool enable);
+
+t_Error FmMacsecSetException(t_Handle h_FmMacsec, e_FmMacsecGlobalExceptions exception, uint32_t scId, bool enable);
+t_Error FmMacsecSetEvent(t_Handle h_FmMacsec, e_FmMacsecGlobalEvents event, uint32_t scId, bool enable);
+
+
+
+#endif /* __FM_MACSEC_H */
diff --git a/drivers/net/ethernet/freescale/fman/Peripherals/FM/MACSEC/fm_macsec_guest.c b/drivers/net/ethernet/freescale/fman/Peripherals/FM/MACSEC/fm_macsec_guest.c
new file mode 100644
index 0000000..31d789d
--- /dev/null
+++ b/drivers/net/ethernet/freescale/fman/Peripherals/FM/MACSEC/fm_macsec_guest.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2008-2015 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/******************************************************************************
+ @File fm_macsec.c
+
+ @Description FM MACSEC driver routines implementation.
+*//***************************************************************************/
+
+#include "std_ext.h"
+#include "error_ext.h"
+#include "xx_ext.h"
+#include "string_ext.h"
+#include "sprint_ext.h"
+#include "debug_ext.h"
+#include "fm_macsec.h"
+
+
+/****************************************/
+/* static functions */
+/****************************************/
+
+/****************************************/
+/* API Init unit functions */
+/****************************************/
+t_Handle FM_MACSEC_GUEST_Config(t_FmMacsecParams *p_FmMacsecParam)
+{
+ UNUSED(p_FmMacsecParam);
+ return NULL;
+}
diff --git a/drivers/net/ethernet/freescale/fman/Peripherals/FM/MACSEC/fm_macsec_master.c b/drivers/net/ethernet/freescale/fman/Peripherals/FM/MACSEC/fm_macsec_master.c
new file mode 100644
index 0000000..237c4e5
--- /dev/null
+++ b/drivers/net/ethernet/freescale/fman/Peripherals/FM/MACSEC/fm_macsec_master.c
@@ -0,0 +1,1028 @@
+/*
+ * Copyright 2008-2015 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/******************************************************************************
+ @File fm_macsec.c
+
+ @Description FM MACSEC driver routines implementation.
+*//***************************************************************************/
+
+#include "std_ext.h"
+#include "error_ext.h"
+#include "xx_ext.h"
+#include "string_ext.h"
+#include "sprint_ext.h"
+#include "fm_mac_ext.h"
+
+#include "fm_macsec_master.h"
+
+
+extern uint16_t FM_MAC_GetMaxFrameLength(t_Handle FmMac);
+
+
+/****************************************/
+/* static functions */
+/****************************************/
+static t_Error CheckFmMacsecParameters(t_FmMacsec *p_FmMacsec)
+{
+ if (!p_FmMacsec->f_Exception)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
+
+ return E_OK;
+}
+
+static void UnimplementedIsr(t_Handle h_Arg, uint32_t id)
+{
+ UNUSED(h_Arg); UNUSED(id);
+
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unimplemented Isr!"));
+}
+
+static void MacsecEventIsr(t_Handle h_FmMacsec)
+{
+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
+ uint32_t events,event,i;
+
+ SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE);
+
+ events = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->evr);
+ events |= GET_UINT32(p_FmMacsec->p_FmMacsecRegs->ever);
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->evr,events);
+
+ for (i=0; i<NUM_OF_TX_SC; i++)
+ if (events & FM_MACSEC_EV_TX_SC_NEXT_PN(i))
+ {
+ GET_MACSEC_MODULE_EVENT(e_FM_MACSEC_MOD_SC_TX, i, e_FM_INTR_TYPE_NORMAL, event);
+ p_FmMacsec->intrMng[event].f_Isr(p_FmMacsec->intrMng[event].h_SrcHandle, i);
+ }
+}
+
+static void MacsecErrorIsr(t_Handle h_FmMacsec)
+{
+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
+ uint32_t errors,error,i;
+
+ SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE);
+
+ errors = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->err);
+ errors |= GET_UINT32(p_FmMacsec->p_FmMacsecRegs->erer);
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->err,errors);
+
+ for (i=0; i<NUM_OF_TX_SC; i++)
+ if (errors & FM_MACSEC_EX_TX_SC(i))
+ {
+ GET_MACSEC_MODULE_EVENT(e_FM_MACSEC_MOD_SC_TX, i, e_FM_INTR_TYPE_ERR, error);
+ p_FmMacsec->intrMng[error].f_Isr(p_FmMacsec->intrMng[error].h_SrcHandle, i);
+ }
+
+ if (errors & FM_MACSEC_EX_ECC)
+ {
+ uint8_t eccType;
+ uint32_t tmpReg;
+
+ tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->meec);
+ ASSERT_COND(tmpReg & MECC_CAP);
+ eccType = (uint8_t)((tmpReg & MECC_CET) >> MECC_CET_SHIFT);
+
+ if (!eccType && (p_FmMacsec->userExceptions & FM_MACSEC_USER_EX_SINGLE_BIT_ECC))
+ p_FmMacsec->f_Exception(p_FmMacsec->h_App,e_FM_MACSEC_EX_SINGLE_BIT_ECC);
+ else if (eccType && (p_FmMacsec->userExceptions & FM_MACSEC_USER_EX_MULTI_BIT_ECC))
+ p_FmMacsec->f_Exception(p_FmMacsec->h_App,e_FM_MACSEC_EX_MULTI_BIT_ECC);
+ else
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->meec,tmpReg);
+ }
+}
+
+static t_Error MacsecInit(t_Handle h_FmMacsec)
+{
+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
+ t_FmMacsecDriverParam *p_FmMacsecDriverParam = NULL;
+ uint32_t tmpReg,i,macId;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
+
+ CHECK_INIT_PARAMETERS(p_FmMacsec, CheckFmMacsecParameters);
+
+ p_FmMacsecDriverParam = p_FmMacsec->p_FmMacsecDriverParam;
+
+ for (i=0;i<e_FM_MACSEC_EV_DUMMY_LAST;i++)
+ p_FmMacsec->intrMng[i].f_Isr = UnimplementedIsr;
+
+ tmpReg = 0;
+ tmpReg |= (p_FmMacsecDriverParam->changedTextWithNoEncryptDeliverUncontrolled << CFG_UECT_SHIFT)|
+ (p_FmMacsecDriverParam->onlyScbIsSetDeliverUncontrolled << CFG_ESCBT_SHIFT) |
+ (p_FmMacsecDriverParam->unknownSciTreatMode << CFG_USFT_SHIFT) |
+ (p_FmMacsecDriverParam->invalidTagsDeliverUncontrolled << CFG_ITT_SHIFT) |
+ (p_FmMacsecDriverParam->encryptWithNoChangedTextDiscardUncontrolled << CFG_KFT_SHIFT) |
+ (p_FmMacsecDriverParam->untagTreatMode << CFG_UFT_SHIFT) |
+ (p_FmMacsecDriverParam->keysUnreadable << CFG_KSS_SHIFT) |
+ (p_FmMacsecDriverParam->reservedSc0 << CFG_S0I_SHIFT) |
+ (p_FmMacsecDriverParam->byPassMode << CFG_BYPN_SHIFT);
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg, tmpReg);
+
+ tmpReg = FM_MAC_GetMaxFrameLength(p_FmMacsec->h_FmMac);
+ /* Ethernet FCS (4 bytes) overhead must be subtracted from MFL*/
+ tmpReg -= 4;
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->mfl, tmpReg);
+
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->tpnet, p_FmMacsecDriverParam->pnExhThr);
+
+ if (!p_FmMacsec->userExceptions)
+ p_FmMacsec->exceptions &= ~FM_MACSEC_EX_ECC;
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->erer, p_FmMacsec->exceptions);
+
+ p_FmMacsec->numRxScAvailable = NUM_OF_RX_SC;
+ if (p_FmMacsecDriverParam->reservedSc0)
+ p_FmMacsec->numRxScAvailable --;
+ p_FmMacsec->numTxScAvailable = NUM_OF_TX_SC;
+
+ XX_Free(p_FmMacsecDriverParam);
+ p_FmMacsec->p_FmMacsecDriverParam = NULL;
+
+ FM_MAC_GetId(p_FmMacsec->h_FmMac, &macId);
+ FmRegisterIntr(p_FmMacsec->h_Fm,
+ e_FM_MOD_MACSEC,
+ (uint8_t)macId,
+ e_FM_INTR_TYPE_NORMAL,
+ MacsecEventIsr,
+ p_FmMacsec);
+
+ FmRegisterIntr(p_FmMacsec->h_Fm,
+ e_FM_MOD_MACSEC,
+ 0,
+ e_FM_INTR_TYPE_ERR,
+ MacsecErrorIsr,
+ p_FmMacsec);
+
+ return E_OK;
+}
+
+static t_Error MacsecFree(t_Handle h_FmMacsec)
+{
+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
+ uint32_t macId;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
+
+ FM_MAC_GetId(p_FmMacsec->h_FmMac, &macId);
+ FmUnregisterIntr(p_FmMacsec->h_Fm,
+ e_FM_MOD_MACSEC,
+ (uint8_t)macId,
+ e_FM_INTR_TYPE_NORMAL);
+
+ FmUnregisterIntr(p_FmMacsec->h_Fm,
+ e_FM_MOD_MACSEC,
+ 0,
+ e_FM_INTR_TYPE_ERR);
+
+ if (p_FmMacsec->rxScSpinLock)
+ XX_FreeSpinlock(p_FmMacsec->rxScSpinLock);
+ if (p_FmMacsec->txScSpinLock)
+ XX_FreeSpinlock(p_FmMacsec->txScSpinLock);
+
+ XX_Free(p_FmMacsec);
+
+ return E_OK;
+}
+
+static t_Error MacsecConfigUnknownSciFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode)
+{
+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
+
+ p_FmMacsec->p_FmMacsecDriverParam->unknownSciTreatMode = treatMode;
+
+ return E_OK;
+}
+
+static t_Error MacsecConfigInvalidTagsFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled)
+{
+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
+
+ p_FmMacsec->p_FmMacsecDriverParam->invalidTagsDeliverUncontrolled = deliverUncontrolled;
+
+ return E_OK;
+}
+
+static t_Error MacsecConfigChangedTextWithNoEncryptFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled)
+{
+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
+
+ p_FmMacsec->p_FmMacsecDriverParam->changedTextWithNoEncryptDeliverUncontrolled = deliverUncontrolled;
+
+ return E_OK;
+}
+
+static t_Error MacsecConfigOnlyScbIsSetFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled)
+{
+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
+
+ p_FmMacsec->p_FmMacsecDriverParam->onlyScbIsSetDeliverUncontrolled = deliverUncontrolled;
+
+ return E_OK;
+}
+
+static t_Error MacsecConfigEncryptWithNoChangedTextFrameTreatment(t_Handle h_FmMacsec, bool discardUncontrolled)
+{
+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
+
+ p_FmMacsec->p_FmMacsecDriverParam->encryptWithNoChangedTextDiscardUncontrolled = discardUncontrolled;
+
+ return E_OK;
+}
+
+static t_Error MacsecConfigUntagFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode)
+{
+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
+
+ p_FmMacsec->p_FmMacsecDriverParam->untagTreatMode = treatMode;
+
+ return E_OK;
+}
+
+static t_Error MacsecConfigPnExhaustionThreshold(t_Handle h_FmMacsec, uint32_t pnExhThr)
+{
+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
+
+ p_FmMacsec->p_FmMacsecDriverParam->pnExhThr = pnExhThr;
+
+ return E_OK;
+}
+
+static t_Error MacsecConfigKeysUnreadable(t_Handle h_FmMacsec)
+{
+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
+
+ p_FmMacsec->p_FmMacsecDriverParam->keysUnreadable = TRUE;
+
+ return E_OK;
+}
+
+static t_Error MacsecConfigSectagWithoutSCI(t_Handle h_FmMacsec)
+{
+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
+
+ p_FmMacsec->p_FmMacsecDriverParam->sectagOverhead -= MACSEC_SCI_SIZE;
+
+ return E_OK;
+}
+
+static t_Error MacsecConfigException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable)
+{
+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
+ uint32_t bitMask = 0;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
+
+ GET_USER_EXCEPTION_FLAG(bitMask, exception);
+ if (bitMask)
+ {
+ if (enable)
+ p_FmMacsec->userExceptions |= bitMask;
+ else
+ p_FmMacsec->userExceptions &= ~bitMask;
+ }
+ else
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
+
+ return E_OK;
+}
+
+static t_Error MacsecGetRevision(t_Handle h_FmMacsec, uint32_t *p_MacsecRevision)
+{
+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
+
+ *p_MacsecRevision = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->ip_rev1);
+
+ return E_OK;
+}
+
+static t_Error MacsecEnable(t_Handle h_FmMacsec)
+{
+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
+ uint32_t tmpReg;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
+
+ tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg);
+ tmpReg |= CFG_BYPN;
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg,tmpReg);
+
+ return E_OK;
+}
+
+static t_Error MacsecDisable(t_Handle h_FmMacsec)
+{
+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
+ uint32_t tmpReg;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
+
+ tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg);
+ tmpReg &= ~CFG_BYPN;
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg,tmpReg);
+
+ return E_OK;
+}
+
+static t_Error MacsecSetException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable)
+{
+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
+ uint32_t bitMask;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
+
+ GET_USER_EXCEPTION_FLAG(bitMask, exception);
+ if (bitMask)
+ {
+ if (enable)
+ p_FmMacsec->userExceptions |= bitMask;
+ else
+ p_FmMacsec->userExceptions &= ~bitMask;
+ }
+ else
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
+
+ if (!p_FmMacsec->userExceptions)
+ p_FmMacsec->exceptions &= ~FM_MACSEC_EX_ECC;
+ else
+ p_FmMacsec->exceptions |= FM_MACSEC_EX_ECC;
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->erer, p_FmMacsec->exceptions);
+
+ return E_OK;
+}
+
+static void InitFmMacsecControllerDriver(t_FmMacsecControllerDriver *p_FmMacsecControllerDriver)
+{
+ p_FmMacsecControllerDriver->f_FM_MACSEC_Init = MacsecInit;
+ p_FmMacsecControllerDriver->f_FM_MACSEC_Free = MacsecFree;
+ p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUnknownSciFrameTreatment = MacsecConfigUnknownSciFrameTreatment;
+ p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigInvalidTagsFrameTreatment = MacsecConfigInvalidTagsFrameTreatment;
+ p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment = MacsecConfigEncryptWithNoChangedTextFrameTreatment;
+ p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUntagFrameTreatment = MacsecConfigUntagFrameTreatment;
+ p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment = MacsecConfigChangedTextWithNoEncryptFrameTreatment;
+ p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment = MacsecConfigOnlyScbIsSetFrameTreatment;
+ p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigPnExhaustionThreshold = MacsecConfigPnExhaustionThreshold;
+ p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigKeysUnreadable = MacsecConfigKeysUnreadable;
+ p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigSectagWithoutSCI = MacsecConfigSectagWithoutSCI;
+ p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigException = MacsecConfigException;
+ p_FmMacsecControllerDriver->f_FM_MACSEC_GetRevision = MacsecGetRevision;
+ p_FmMacsecControllerDriver->f_FM_MACSEC_Enable = MacsecEnable;
+ p_FmMacsecControllerDriver->f_FM_MACSEC_Disable = MacsecDisable;
+ p_FmMacsecControllerDriver->f_FM_MACSEC_SetException = MacsecSetException;
+}
+
+/****************************************/
+/* Inter-Module functions */
+/****************************************/
+
+void FmMacsecRegisterIntr(t_Handle h_FmMacsec,
+ e_FmMacsecEventModules module,
+ uint8_t modId,
+ e_FmIntrType intrType,
+ void (*f_Isr) (t_Handle h_Arg, uint32_t id),
+ t_Handle h_Arg)
+{
+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
+ uint8_t event= 0;
+
+ SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE);
+
+ GET_MACSEC_MODULE_EVENT(module, modId, intrType, event);
+
+ ASSERT_COND(event != e_FM_MACSEC_EV_DUMMY_LAST);
+ p_FmMacsec->intrMng[event].f_Isr = f_Isr;
+ p_FmMacsec->intrMng[event].h_SrcHandle = h_Arg;
+}
+
+void FmMacsecUnregisterIntr(t_Handle h_FmMacsec,
+ e_FmMacsecEventModules module,
+ uint8_t modId,
+ e_FmIntrType intrType)
+{
+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
+ uint8_t event= 0;
+
+ SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE);
+
+ GET_MACSEC_MODULE_EVENT(module, modId,intrType, event);
+
+ ASSERT_COND(event != e_FM_MACSEC_EV_DUMMY_LAST);
+ p_FmMacsec->intrMng[event].f_Isr = NULL;
+ p_FmMacsec->intrMng[event].h_SrcHandle = NULL;
+}
+
+t_Error FmMacsecAllocScs(t_Handle h_FmMacsec, e_ScType type, bool isPtp, uint32_t numOfScs, uint32_t *p_ScIds)
+{
+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
+ t_Error err = E_OK;
+ bool *p_ScTable;
+ uint32_t *p_ScAvailable,i;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_ScIds, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(numOfScs, E_INVALID_HANDLE);
+
+ if (type == e_SC_RX)
+ {
+ p_ScTable = (bool *)p_FmMacsec->rxScTable;
+ p_ScAvailable = &p_FmMacsec->numRxScAvailable;
+ i = (NUM_OF_RX_SC - 1);
+ }
+ else
+ {
+ p_ScTable = (bool *)p_FmMacsec->txScTable;
+ p_ScAvailable = &p_FmMacsec->numTxScAvailable;
+ i = (NUM_OF_TX_SC - 1);
+
+ }
+ if (*p_ScAvailable < numOfScs)
+ RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Not enough SCs available"));
+
+ if (isPtp)
+ {
+ i = 0;
+ if (p_ScTable[i])
+ RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Sc 0 Not available"));
+ }
+
+ for (;numOfScs;i--)
+ {
+ if (p_ScTable[i])
+ continue;
+ numOfScs --;
+ (*p_ScAvailable)--;
+ p_ScIds[numOfScs] = i;
+ p_ScTable[i] = TRUE;
+ }
+
+ return err;
+}
+
+t_Error FmMacsecFreeScs(t_Handle h_FmMacsec, e_ScType type, uint32_t numOfScs, uint32_t *p_ScIds)
+{
+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
+ t_Error err = E_OK;
+ bool *p_ScTable;
+ uint32_t *p_ScAvailable,maxNumOfSc,i;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_ScIds, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(numOfScs, E_INVALID_HANDLE);
+
+ if (type == e_SC_RX)
+ {
+ p_ScTable = (bool *)p_FmMacsec->rxScTable;
+ p_ScAvailable = &p_FmMacsec->numRxScAvailable;
+ maxNumOfSc = NUM_OF_RX_SC;
+ }
+ else
+ {
+ p_ScTable = (bool *)p_FmMacsec->txScTable;
+ p_ScAvailable = &p_FmMacsec->numTxScAvailable;
+ maxNumOfSc = NUM_OF_TX_SC;
+ }
+
+ if ((*p_ScAvailable + numOfScs) > maxNumOfSc)
+ RETURN_ERROR(MINOR, E_FULL, ("Too much SCs"));
+
+ for (i=0;i<numOfScs;i++)
+ {
+ p_ScTable[p_ScIds[i]] = FALSE;
+ (*p_ScAvailable)++;
+ }
+
+ return err;
+
+}
+
+t_Error FmMacsecSetPTP(t_Handle h_FmMacsec, bool enable)
+{
+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
+ uint32_t tmpReg = 0;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
+
+ tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg);
+ if (enable && (tmpReg & CFG_S0I))
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("MACSEC already in point-to-point mode"));
+
+ if (enable)
+ tmpReg |= CFG_S0I;
+ else
+ tmpReg &= CFG_S0I;
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg, tmpReg);
+
+ return E_OK;
+}
+
+t_Error FmMacsecCreateRxSc(t_Handle h_FmMacsec, t_RxScParams *p_RxScParams)
+{
+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
+ t_Error err = E_OK;
+ uint32_t tmpReg = 0, intFlags;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_RxScParams, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_RxScParams->scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
+
+ intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
+
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, p_RxScParams->scId);
+ tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsccfg);
+ if (tmpReg & RX_SCCFG_SCI_EN_MASK)
+ {
+ XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Rx Sc %d must be disable",p_RxScParams->scId));
+ }
+
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsci1h, GET_SCI_FIRST_HALF(p_RxScParams->sci));
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsci2h, GET_SCI_SECOND_HALF(p_RxScParams->sci));
+ tmpReg |= ((p_RxScParams->replayProtect << RX_SCCFG_RP_SHIFT) & RX_SCCFG_RP_MASK);
+ tmpReg |= ((p_RxScParams->validateFrames << RX_SCCFG_VF_SHIFT) & RX_SCCFG_VF_MASK);
+ tmpReg |= ((p_RxScParams->confidentialityOffset << RX_SCCFG_CO_SHIFT) & RX_SCCFG_CO_MASK);
+ tmpReg |= RX_SCCFG_SCI_EN_MASK;
+ tmpReg |= (p_RxScParams->cipherSuite << RX_SCCFG_CS_SHIFT);
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsccfg, tmpReg);
+
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rpw, p_RxScParams->replayWindow);
+
+ XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
+
+ return err;
+}
+
+t_Error FmMacsecDeleteRxSc(t_Handle h_FmMacsec, uint32_t scId)
+{
+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
+ t_Error err = E_OK;
+ uint32_t tmpReg = 0, intFlags;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
+
+ intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
+
+ tmpReg &= ~RX_SCCFG_SCI_EN_MASK;
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsccfg, tmpReg);
+
+ XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
+
+ return err;
+}
+
+t_Error FmMacsecCreateTxSc(t_Handle h_FmMacsec, t_TxScParams *p_TxScParams)
+{
+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
+ t_Error err = E_OK;
+ uint32_t tmpReg = 0, intFlags;
+ bool alwaysIncludeSCI = FALSE, useES = FALSE, useSCB = FALSE;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_TxScParams, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_TxScParams->scId < NUM_OF_TX_SC, E_INVALID_HANDLE);
+
+ intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
+
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, p_TxScParams->scId);
+
+ tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg);
+ if (tmpReg & TX_SCCFG_SCE_MASK)
+ {
+ XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Tx Sc %d must be disable",p_TxScParams->scId));
+ }
+
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsci1h, GET_SCI_FIRST_HALF(p_TxScParams->sci));
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsci2h, GET_SCI_SECOND_HALF(p_TxScParams->sci));
+ alwaysIncludeSCI = (p_TxScParams->sciInsertionMode == e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG);
+ useES = (p_TxScParams->sciInsertionMode == e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_MAC_SA);
+
+ tmpReg |= ((p_TxScParams->protectFrames << TX_SCCFG_PF_SHIFT) & TX_SCCFG_PF_MASK);
+ tmpReg |= ((alwaysIncludeSCI << TX_SCCFG_AIS_SHIFT) & TX_SCCFG_AIS_MASK);
+ tmpReg |= ((useES << TX_SCCFG_UES_SHIFT) & TX_SCCFG_UES_MASK);
+ tmpReg |= ((useSCB << TX_SCCFG_USCB_SHIFT) & TX_SCCFG_USCB_MASK);
+ tmpReg |= ((p_TxScParams->confidentialityEnable << TX_SCCFG_CE_SHIFT) & TX_SCCFG_CE_MASK);
+ tmpReg |= ((p_TxScParams->confidentialityOffset << TX_SCCFG_CO_SHIFT) & TX_SCCFG_CO_MASK);
+ tmpReg |= TX_SCCFG_SCE_MASK;
+ tmpReg |= (p_TxScParams->cipherSuite << TX_SCCFG_CS_SHIFT);
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg, tmpReg);
+
+ XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
+
+ return err;
+}
+
+t_Error FmMacsecDeleteTxSc(t_Handle h_FmMacsec, uint32_t scId)
+{
+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
+ t_Error err = E_OK;
+ uint32_t tmpReg = 0, intFlags;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_TX_SC, E_INVALID_HANDLE);
+
+ intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
+
+ tmpReg &= ~TX_SCCFG_SCE_MASK;
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg, tmpReg);
+
+ XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
+
+ return err;
+}
+
+t_Error FmMacsecCreateRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key)
+{
+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
+ t_Error err = E_OK;
+ uint32_t tmpReg = 0, intFlags;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
+
+ intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
+
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsanpn, DEFAULT_initNextPn);
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsalpn, lowestPn);
+ Mem2IOCpy32((void*)p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsak, key, sizeof(macsecSAKey_t));
+
+ tmpReg |= RX_SACFG_ACTIVE;
+ tmpReg |= ((an << RX_SACFG_AN_SHIFT) & RX_SACFG_AN_MASK);
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs, tmpReg);
+
+ XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
+
+ return err;
+}
+
+t_Error FmMacsecCreateTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecSAKey_t key)
+{
+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
+ t_Error err = E_OK;
+ uint32_t tmpReg = 0, intFlags;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_TX_SC, E_INVALID_HANDLE);
+
+ intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
+
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsanpn, DEFAULT_initNextPn);
+ Mem2IOCpy32((void*)p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsak, key, sizeof(macsecSAKey_t));
+
+ tmpReg |= TX_SACFG_ACTIVE;
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsacs, tmpReg);
+
+ XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
+
+ return err;
+}
+
+t_Error FmMacsecDeleteRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId)
+{
+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
+ t_Error err = E_OK;
+ uint32_t tmpReg = 0, i, intFlags;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
+
+ intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
+
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsanpn, 0x0);
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsalpn, 0x0);
+ for (i=0; i<4; i++)
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsak[i], 0x0);
+
+ tmpReg |= RX_SACFG_ACTIVE;
+ tmpReg &= ~RX_SACFG_EN_MASK;
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs, tmpReg);
+
+ XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
+
+ return err;
+}
+
+t_Error FmMacsecDeleteTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId)
+{
+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
+ t_Error err = E_OK;
+ uint32_t tmpReg = 0, i, intFlags;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_TX_SC, E_INVALID_HANDLE);
+
+ intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
+
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsanpn, 0x0);
+ for (i=0; i<4; i++)
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsak[i], 0x0);
+
+ tmpReg |= TX_SACFG_ACTIVE;
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsacs, tmpReg);
+
+ XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
+
+ return err;
+}
+
+t_Error FmMacsecRxSaSetReceive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, bool enableReceive)
+{
+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
+ t_Error err = E_OK;
+ uint32_t tmpReg = 0, intFlags;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
+
+ intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
+
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
+ tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs);
+ if (enableReceive)
+ tmpReg |= RX_SACFG_EN_MASK;
+ else
+ tmpReg &= ~RX_SACFG_EN_MASK;
+
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs, tmpReg);
+
+ XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
+
+ return err;
+}
+
+t_Error FmMacsecRxSaUpdateNextPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtNextPN)
+{
+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
+ t_Error err = E_OK;
+ uint32_t intFlags;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
+
+ intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
+
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsanpn, updtNextPN);
+
+ XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
+
+ return err;
+}
+
+t_Error FmMacsecRxSaUpdateLowestPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtLowestPN)
+{
+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
+ t_Error err = E_OK;
+ uint32_t intFlags;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
+
+ intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
+
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsalpn, updtLowestPN);
+
+ XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
+
+ return err;
+}
+
+t_Error FmMacsecTxSaSetActive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an)
+{
+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
+ t_Error err = E_OK;
+ uint32_t tmpReg = 0, intFlags;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_TX_SC, E_INVALID_HANDLE);
+
+ intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
+
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
+
+ tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg);
+
+ tmpReg |= ((an << TX_SCCFG_AN_SHIFT) & TX_SCCFG_AN_MASK);
+ tmpReg |= ((saId << TX_SCCFG_ASA_SHIFT) & TX_SCCFG_ASA_MASK);
+
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg, tmpReg);
+
+ XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
+
+ return err;
+}
+
+t_Error FmMacsecTxSaGetActive(t_Handle h_FmMacsec, uint32_t scId, macsecAN_t *p_An)
+{
+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
+ t_Error err = E_OK;
+ uint32_t tmpReg = 0, intFlags;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_An, E_INVALID_HANDLE);
+
+ intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
+
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
+
+ tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg);
+
+ XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
+
+ *p_An = (macsecAN_t)((tmpReg & TX_SCCFG_AN_MASK) >> TX_SCCFG_AN_SHIFT);
+
+ return err;
+}
+
+t_Error FmMacsecSetException(t_Handle h_FmMacsec, e_FmMacsecGlobalExceptions exception, uint32_t scId, bool enable)
+{
+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
+ uint32_t bitMask;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
+
+ GET_EXCEPTION_FLAG(bitMask, exception, scId);
+ if (bitMask)
+ {
+ if (enable)
+ p_FmMacsec->exceptions |= bitMask;
+ else
+ p_FmMacsec->exceptions &= ~bitMask;
+ }
+ else
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
+
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->erer, p_FmMacsec->exceptions);
+
+ return E_OK;
+}
+
+t_Error FmMacsecSetEvent(t_Handle h_FmMacsec, e_FmMacsecGlobalEvents event, uint32_t scId, bool enable)
+{
+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
+ uint32_t bitMask;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
+
+ GET_EVENT_FLAG(bitMask, event, scId);
+ if (bitMask)
+ {
+ if (enable)
+ p_FmMacsec->events |= bitMask;
+ else
+ p_FmMacsec->events &= ~bitMask;
+ }
+ else
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined event"));
+
+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->ever, p_FmMacsec->events);
+
+ return E_OK;
+}
+
+/****************************************/
+/* API Init unit functions */
+/****************************************/
+t_Handle FM_MACSEC_MASTER_Config(t_FmMacsecParams *p_FmMacsecParam)
+{
+ t_FmMacsec *p_FmMacsec;
+ uint32_t macId;
+
+ /* Allocate FM MACSEC structure */
+ p_FmMacsec = (t_FmMacsec *) XX_Malloc(sizeof(t_FmMacsec));
+ if (!p_FmMacsec)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC driver structure"));
+ return NULL;
+ }
+ memset(p_FmMacsec, 0, sizeof(t_FmMacsec));
+ InitFmMacsecControllerDriver(&p_FmMacsec->fmMacsecControllerDriver);
+
+ /* Allocate the FM MACSEC driver's parameters structure */
+ p_FmMacsec->p_FmMacsecDriverParam = (t_FmMacsecDriverParam *)XX_Malloc(sizeof(t_FmMacsecDriverParam));
+ if (!p_FmMacsec->p_FmMacsecDriverParam)
+ {
+ XX_Free(p_FmMacsec);
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC driver parameters"));
+ return NULL;
+ }
+ memset(p_FmMacsec->p_FmMacsecDriverParam, 0, sizeof(t_FmMacsecDriverParam));
+
+ /* Initialize FM MACSEC parameters which will be kept by the driver */
+ p_FmMacsec->h_Fm = p_FmMacsecParam->h_Fm;
+ p_FmMacsec->h_FmMac = p_FmMacsecParam->nonGuestParams.h_FmMac;
+ p_FmMacsec->p_FmMacsecRegs = (t_FmMacsecRegs *)UINT_TO_PTR(p_FmMacsecParam->nonGuestParams.baseAddr);
+ p_FmMacsec->f_Exception = p_FmMacsecParam->nonGuestParams.f_Exception;
+ p_FmMacsec->h_App = p_FmMacsecParam->nonGuestParams.h_App;
+ p_FmMacsec->userExceptions = DEFAULT_userExceptions;
+ p_FmMacsec->exceptions = DEFAULT_exceptions;
+ p_FmMacsec->events = DEFAULT_events;
+ p_FmMacsec->rxScSpinLock = XX_InitSpinlock();
+ p_FmMacsec->txScSpinLock = XX_InitSpinlock();
+
+ /* Initialize FM MACSEC driver parameters parameters (for initialization phase only) */
+ p_FmMacsec->p_FmMacsecDriverParam->unknownSciTreatMode = DEFAULT_unknownSciFrameTreatment;
+ p_FmMacsec->p_FmMacsecDriverParam->invalidTagsDeliverUncontrolled = DEFAULT_invalidTagsFrameTreatment;
+ p_FmMacsec->p_FmMacsecDriverParam->encryptWithNoChangedTextDiscardUncontrolled = DEFAULT_encryptWithNoChangedTextFrameTreatment;
+ p_FmMacsec->p_FmMacsecDriverParam->untagTreatMode = DEFAULT_untagFrameTreatment;
+ p_FmMacsec->p_FmMacsecDriverParam->keysUnreadable = DEFAULT_keysUnreadable;
+ p_FmMacsec->p_FmMacsecDriverParam->reservedSc0 = DEFAULT_sc0ReservedForPTP;
+ p_FmMacsec->p_FmMacsecDriverParam->byPassMode = !DEFAULT_normalMode;
+ p_FmMacsec->p_FmMacsecDriverParam->pnExhThr = DEFAULT_pnExhThr;
+ p_FmMacsec->p_FmMacsecDriverParam->sectagOverhead = DEFAULT_overhead;
+ /* build the FM MACSEC master IPC address */
+ memset(p_FmMacsec->fmMacsecModuleName, 0, (sizeof(char))*MODULE_NAME_SIZE);
+ FM_MAC_GetId(p_FmMacsec->h_FmMac,&macId);
+ if (Sprint (p_FmMacsec->fmMacsecModuleName, "FM-%d-MAC-%d-MACSEC-Master",
+ FmGetId(p_FmMacsec->h_Fm),macId) != 24)
+ {
+ XX_Free(p_FmMacsec->p_FmMacsecDriverParam);
+ XX_Free(p_FmMacsec);
+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
+ return NULL;
+ }
+ return p_FmMacsec;
+}
diff --git a/drivers/net/ethernet/freescale/fman/Peripherals/FM/MACSEC/fm_macsec_master.h b/drivers/net/ethernet/freescale/fman/Peripherals/FM/MACSEC/fm_macsec_master.h
new file mode 100644
index 0000000..65eadf5
--- /dev/null
+++ b/drivers/net/ethernet/freescale/fman/Peripherals/FM/MACSEC/fm_macsec_master.h
@@ -0,0 +1,476 @@
+/*
+ * Copyright 2008-2015 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/******************************************************************************
+ @File fm_macsec_master.h
+
+ @Description FM MACSEC internal structures and definitions.
+*//***************************************************************************/
+#ifndef __FM_MACSEC_MASTER_H
+#define __FM_MACSEC_MASTER_H
+
+#include "error_ext.h"
+#include "std_ext.h"
+
+#include "fm_macsec.h"
+
+
+#define MACSEC_ICV_SIZE 16
+#define MACSEC_SECTAG_SIZE 16
+#define MACSEC_SCI_SIZE 8
+
+/**************************************************************************//**
+ @Description Exceptions
+*//***************************************************************************/
+
+#define FM_MACSEC_EX_TX_SC_0 0x80000000
+#define FM_MACSEC_EX_TX_SC(sc) (FM_MACSEC_EX_TX_SC_0 >> (sc))
+#define FM_MACSEC_EX_ECC 0x00000001
+
+#define GET_EXCEPTION_FLAG(bitMask, exception, id) switch (exception){ \
+ case e_FM_MACSEC_EX_TX_SC: \
+ bitMask = FM_MACSEC_EX_TX_SC(id); break; \
+ case e_FM_MACSEC_EX_ECC: \
+ bitMask = FM_MACSEC_EX_ECC; break; \
+ default: bitMask = 0;break;}
+
+#define FM_MACSEC_USER_EX_SINGLE_BIT_ECC 0x80000000
+#define FM_MACSEC_USER_EX_MULTI_BIT_ECC 0x40000000
+
+#define GET_USER_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \
+ case e_FM_MACSEC_EX_SINGLE_BIT_ECC: \
+ bitMask = FM_MACSEC_USER_EX_SINGLE_BIT_ECC; break; \
+ case e_FM_MACSEC_EX_MULTI_BIT_ECC: \
+ bitMask = FM_MACSEC_USER_EX_MULTI_BIT_ECC; break; \
+ default: bitMask = 0;break;}
+
+/**************************************************************************//**
+ @Description Events
+*//***************************************************************************/
+
+#define FM_MACSEC_EV_TX_SC_0_NEXT_PN 0x80000000
+#define FM_MACSEC_EV_TX_SC_NEXT_PN(sc) (FM_MACSEC_EV_TX_SC_0_NEXT_PN >> (sc))
+
+#define GET_EVENT_FLAG(bitMask, event, id) switch (event){ \
+ case e_FM_MACSEC_EV_TX_SC_NEXT_PN: \
+ bitMask = FM_MACSEC_EV_TX_SC_NEXT_PN(id); break; \
+ default: bitMask = 0;break;}
+
+/**************************************************************************//**
+ @Description Defaults
+*//***************************************************************************/
+#define DEFAULT_userExceptions (FM_MACSEC_USER_EX_SINGLE_BIT_ECC |\
+ FM_MACSEC_USER_EX_MULTI_BIT_ECC)
+
+#define DEFAULT_exceptions (FM_MACSEC_EX_TX_SC(0) |\
+ FM_MACSEC_EX_TX_SC(1) |\
+ FM_MACSEC_EX_TX_SC(2) |\
+ FM_MACSEC_EX_TX_SC(3) |\
+ FM_MACSEC_EX_TX_SC(4) |\
+ FM_MACSEC_EX_TX_SC(5) |\
+ FM_MACSEC_EX_TX_SC(6) |\
+ FM_MACSEC_EX_TX_SC(7) |\
+ FM_MACSEC_EX_TX_SC(8) |\
+ FM_MACSEC_EX_TX_SC(9) |\
+ FM_MACSEC_EX_TX_SC(10) |\
+ FM_MACSEC_EX_TX_SC(11) |\
+ FM_MACSEC_EX_TX_SC(12) |\
+ FM_MACSEC_EX_TX_SC(13) |\
+ FM_MACSEC_EX_TX_SC(14) |\
+ FM_MACSEC_EX_TX_SC(15) |\
+ FM_MACSEC_EX_ECC )
+
+#define DEFAULT_events (FM_MACSEC_EV_TX_SC_NEXT_PN(0) |\
+ FM_MACSEC_EV_TX_SC_NEXT_PN(1) |\
+ FM_MACSEC_EV_TX_SC_NEXT_PN(2) |\
+ FM_MACSEC_EV_TX_SC_NEXT_PN(3) |\
+ FM_MACSEC_EV_TX_SC_NEXT_PN(4) |\
+ FM_MACSEC_EV_TX_SC_NEXT_PN(5) |\
+ FM_MACSEC_EV_TX_SC_NEXT_PN(6) |\
+ FM_MACSEC_EV_TX_SC_NEXT_PN(7) |\
+ FM_MACSEC_EV_TX_SC_NEXT_PN(8) |\
+ FM_MACSEC_EV_TX_SC_NEXT_PN(9) |\
+ FM_MACSEC_EV_TX_SC_NEXT_PN(10) |\
+ FM_MACSEC_EV_TX_SC_NEXT_PN(11) |\
+ FM_MACSEC_EV_TX_SC_NEXT_PN(12) |\
+ FM_MACSEC_EV_TX_SC_NEXT_PN(13) |\
+ FM_MACSEC_EV_TX_SC_NEXT_PN(14) |\
+ FM_MACSEC_EV_TX_SC_NEXT_PN(15) )
+
+#define DEFAULT_unknownSciFrameTreatment e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_BOTH
+#define DEFAULT_invalidTagsFrameTreatment FALSE
+#define DEFAULT_encryptWithNoChangedTextFrameTreatment FALSE
+#define DEFAULT_untagFrameTreatment e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED
+#define DEFAULT_changedTextWithNoEncryptFrameTreatment FALSE
+#define DEFAULT_onlyScbIsSetFrameTreatment FALSE
+#define DEFAULT_keysUnreadable FALSE
+#define DEFAULT_normalMode TRUE
+#define DEFAULT_sc0ReservedForPTP FALSE
+#define DEFAULT_initNextPn 1
+#define DEFAULT_pnExhThr 0xffffffff
+#define DEFAULT_overhead (MACSEC_ICV_SIZE + MACSEC_SECTAG_SIZE)
+
+
+/**************************************************************************//**
+ @Description Memory Mapped Registers
+*//***************************************************************************/
+
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(push,1)
+#endif /* defined(__MWERKS__) && ... */
+
+typedef _Packed struct
+{
+ /* MACsec configuration */
+ volatile uint32_t cfg; /**< MACsec configuration */
+ volatile uint32_t et; /**< MACsec EtherType */
+ volatile uint8_t res1[56]; /**< reserved */
+ volatile uint32_t mfl; /**< Maximum Frame Length */
+ volatile uint32_t tpnet; /**< TX Packet Number exhaustion threshold */
+ volatile uint8_t res2[56]; /**< reserved */
+ volatile uint32_t rxsca; /**< RX SC access select */
+ volatile uint8_t res3[60]; /**< reserved */
+ volatile uint32_t txsca; /**< TX SC access select */
+ volatile uint8_t res4[60]; /**< reserved */
+
+ /* RX configuration, status and statistic */
+ volatile uint32_t rxsci1h; /**< RX Secure Channel Identifier first half */
+ volatile uint32_t rxsci2h; /**< RX Secure Channel Identifier second half */
+ volatile uint8_t res5[8]; /**< reserved */
+ volatile uint32_t ifio1hs; /**< ifInOctets first half Statistic */
+ volatile uint32_t ifio2hs; /**< ifInOctets second half Statistic */
+ volatile uint32_t ifiups; /**< ifInUcastPkts Statistic */
+ volatile uint8_t res6[4]; /**< reserved */
+ volatile uint32_t ifimps; /**< ifInMulticastPkts Statistic */
+ volatile uint32_t ifibps; /**< ifInBroadcastPkts Statistic */
+ volatile uint32_t rxsccfg; /**< RX Secure Channel configuration */
+ volatile uint32_t rpw; /**< replayWindow */
+ volatile uint8_t res7[16]; /**< reserved */
+ volatile uint32_t inov1hs; /**< InOctetsValidated first half Statistic */
+ volatile uint32_t inov2hs; /**< InOctetsValidated second half Statistic */
+ volatile uint32_t inod1hs; /**< InOctetsDecrypted first half Statistic */
+ volatile uint32_t inod2hs; /**< InOctetsDecrypted second half Statistic */
+ volatile uint32_t rxscipus; /**< RX Secure Channel InPktsUnchecked Statistic */
+ volatile uint32_t rxscipds; /**< RX Secure Channel InPktsDelayed Statistic */
+ volatile uint32_t rxscipls; /**< RX Secure Channel InPktsLate Statistic */
+ volatile uint8_t res8[4]; /**< reserved */
+ volatile uint32_t rxaninuss[MAX_NUM_OF_SA_PER_SC]; /**< RX AN 0-3 InNotUsingSA Statistic */
+ volatile uint32_t rxanipuss[MAX_NUM_OF_SA_PER_SC]; /**< RX AN 0-3 InPktsUnusedSA Statistic */
+ _Packed struct
+ {
+ volatile uint32_t rxsacs; /**< RX Security Association configuration and status */
+ volatile uint32_t rxsanpn; /**< RX Security Association nextPN */
+ volatile uint32_t rxsalpn; /**< RX Security Association lowestPN */
+ volatile uint32_t rxsaipos; /**< RX Security Association InPktsOK Statistic */
+ volatile uint32_t rxsak[4]; /**< RX Security Association key (128 bit) */
+ volatile uint32_t rxsah[4]; /**< RX Security Association hash (128 bit) */
+ volatile uint32_t rxsaipis; /**< RX Security Association InPktsInvalid Statistic */
+ volatile uint32_t rxsaipnvs; /**< RX Security Association InPktsNotValid Statistic */
+ volatile uint8_t res9[8]; /**< reserved */
+ } _PackedType fmMacsecRxScSa[NUM_OF_SA_PER_RX_SC];
+
+ /* TX configuration, status and statistic */
+ volatile uint32_t txsci1h; /**< TX Secure Channel Identifier first half */
+ volatile uint32_t txsci2h; /**< TX Secure Channel Identifier second half */
+ volatile uint8_t res10[8]; /**< reserved */
+ volatile uint32_t ifoo1hs; /**< ifOutOctets first half Statistic */
+ volatile uint32_t ifoo2hs; /**< ifOutOctets second half Statistic */
+ volatile uint32_t ifoups; /**< ifOutUcastPkts Statistic */
+ volatile uint32_t opus; /**< OutPktsUntagged Statistic */
+ volatile uint32_t ifomps; /**< ifOutMulticastPkts Statistic */
+ volatile uint32_t ifobps; /**< ifOutBroadcastPkts Statistic */
+ volatile uint32_t txsccfg; /**< TX Secure Channel configuration */
+ volatile uint32_t optls; /**< OutPktsTooLong Statistic */
+ volatile uint8_t res11[16]; /**< reserved */
+ volatile uint32_t oop1hs; /**< OutOctetsProtected first half Statistic */
+ volatile uint32_t oop2hs; /**< OutOctetsProtected second half Statistic */
+ volatile uint32_t ooe1hs; /**< OutOctetsEncrypted first half Statistic */
+ volatile uint32_t ooe2hs; /**< OutOctetsEncrypted second half Statistic */
+ volatile uint8_t res12[48]; /**< reserved */
+ _Packed struct
+ {
+ volatile uint32_t txsacs; /**< TX Security Association configuration and status */
+ volatile uint32_t txsanpn; /**< TX Security Association nextPN */
+ volatile uint32_t txsaopps; /**< TX Security Association OutPktsProtected Statistic */
+ volatile uint32_t txsaopes; /**< TX Security Association OutPktsEncrypted Statistic */
+ volatile uint32_t txsak[4]; /**< TX Security Association key (128 bit) */
+ volatile uint32_t txsah[4]; /**< TX Security Association hash (128 bit) */
+ volatile uint8_t res13[16]; /**< reserved */
+ } _PackedType fmMacsecTxScSa[NUM_OF_SA_PER_TX_SC];
+ volatile uint8_t res14[248]; /**< reserved */
+
+ /* Global configuration and status */
+ volatile uint32_t ip_rev1; /**< MACsec IP Block Revision 1 register */
+ volatile uint32_t ip_rev2; /**< MACsec IP Block Revision 2 register */
+ volatile uint32_t evr; /**< MACsec Event Register */
+ volatile uint32_t ever; /**< MACsec Event Enable Register */
+ volatile uint32_t evfr; /**< MACsec Event Force Register */
+ volatile uint32_t err; /**< MACsec Error Register */
+ volatile uint32_t erer; /**< MACsec Error Enable Register */
+ volatile uint32_t erfr; /**< MACsec Error Force Register */
+ volatile uint8_t res15[40]; /**< reserved */
+ volatile uint32_t meec; /**< MACsec Memory ECC Error Capture Register */
+ volatile uint32_t idle; /**< MACsec Idle status Register */
+ volatile uint8_t res16[184]; /**< reserved */
+ /* DEBUG */
+ volatile uint32_t rxec; /**< MACsec RX error capture Register */
+ volatile uint8_t res17[28]; /**< reserved */
+ volatile uint32_t txec; /**< MACsec TX error capture Register */
+ volatile uint8_t res18[220]; /**< reserved */
+
+ /* Macsec Rx global statistic */
+ volatile uint32_t ifiocp1hs; /**< ifInOctetsCp first half Statistic */
+ volatile uint32_t ifiocp2hs; /**< ifInOctetsCp second half Statistic */
+ volatile uint32_t ifiupcps; /**< ifInUcastPktsCp Statistic */
+ volatile uint8_t res19[4]; /**< reserved */
+ volatile uint32_t ifioup1hs; /**< ifInOctetsUp first half Statistic */
+ volatile uint32_t ifioup2hs; /**< ifInOctetsUp second half Statistic */
+ volatile uint32_t ifiupups; /**< ifInUcastPktsUp Statistic */
+ volatile uint8_t res20[4]; /**< reserved */
+ volatile uint32_t ifimpcps; /**< ifInMulticastPktsCp Statistic */
+ volatile uint32_t ifibpcps; /**< ifInBroadcastPktsCp Statistic */
+ volatile uint32_t ifimpups; /**< ifInMulticastPktsUp Statistic */
+ volatile uint32_t ifibpups; /**< ifInBroadcastPktsUp Statistic */
+ volatile uint32_t ipwts; /**< InPktsWithoutTag Statistic */
+ volatile uint32_t ipkays; /**< InPktsKaY Statistic */
+ volatile uint32_t ipbts; /**< InPktsBadTag Statistic */
+ volatile uint32_t ipsnfs; /**< InPktsSCINotFound Statistic */
+ volatile uint32_t ipuecs; /**< InPktsUnsupportedEC Statistic */
+ volatile uint32_t ipescbs; /**< InPktsEponSingleCopyBroadcast Statistic */
+ volatile uint32_t iptls; /**< InPktsTooLong Statistic */
+ volatile uint8_t res21[52]; /**< reserved */
+
+ /* Macsec Tx global statistic */
+ volatile uint32_t opds; /**< OutPktsDiscarded Statistic */
+#if (DPAA_VERSION >= 11)
+ volatile uint8_t res22[124]; /**< reserved */
+ _Packed struct
+ {
+ volatile uint32_t rxsak[8]; /**< RX Security Association key (128/256 bit) */
+ volatile uint8_t res23[32]; /**< reserved */
+ } _PackedType rxScSaKey[NUM_OF_SA_PER_RX_SC];
+ _Packed struct
+ {
+ volatile uint32_t txsak[8]; /**< TX Security Association key (128/256 bit) */
+ volatile uint8_t res24[32]; /**< reserved */
+ } _PackedType txScSaKey[NUM_OF_SA_PER_TX_SC];
+#endif /* (DPAA_VERSION >= 11) */
+} _PackedType t_FmMacsecRegs;
+
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(pop)
+#endif /* defined(__MWERKS__) && ... */
+
+
+/**************************************************************************//**
+ @Description General defines
+*//***************************************************************************/
+
+#define SCI_HIGH_MASK 0xffffffff00000000LL
+#define SCI_LOW_MASK 0x00000000ffffffffLL
+
+#define LONG_SHIFT 32
+
+#define GET_SCI_FIRST_HALF(sci) (uint32_t)((macsecSCI_t)((macsecSCI_t)(sci) & SCI_HIGH_MASK) >> LONG_SHIFT)
+#define GET_SCI_SECOND_HALF(sci) (uint32_t)((macsecSCI_t)(sci) & SCI_LOW_MASK)
+
+/**************************************************************************//**
+ @Description Configuration defines
+*//***************************************************************************/
+
+/* masks */
+#define CFG_UECT 0x00000800
+#define CFG_ESCBT 0x00000400
+#define CFG_USFT 0x00000300
+#define CFG_ITT 0x00000080
+#define CFG_KFT 0x00000040
+#define CFG_UFT 0x00000030
+#define CFG_KSS 0x00000004
+#define CFG_BYPN 0x00000002
+#define CFG_S0I 0x00000001
+
+#define ET_TYPE 0x0000ffff
+
+#define MFL_MAX_LEN 0x0000ffff
+
+#define RXSCA_SC_SEL 0x0000000f
+
+#define TXSCA_SC_SEL 0x0000000f
+
+#define IP_REV_1_IP_ID 0xffff0000
+#define IP_REV_1_IP_MJ 0x0000ff00
+#define IP_REV_1_IP_MM 0x000000ff
+
+#define IP_REV_2_IP_INT 0x00ff0000
+#define IP_REV_2_IP_ERR 0x0000ff00
+#define IP_REV_2_IP_CFG 0x000000ff
+
+#define MECC_CAP 0x80000000
+#define MECC_CET 0x40000000
+#define MECC_SERCNT 0x00ff0000
+#define MECC_MEMADDR 0x000001ff
+
+/* shifts */
+#define CFG_UECT_SHIFT (31-20)
+#define CFG_ESCBT_SHIFT (31-21)
+#define CFG_USFT_SHIFT (31-23)
+#define CFG_ITT_SHIFT (31-24)
+#define CFG_KFT_SHIFT (31-25)
+#define CFG_UFT_SHIFT (31-27)
+#define CFG_KSS_SHIFT (31-29)
+#define CFG_BYPN_SHIFT (31-30)
+#define CFG_S0I_SHIFT (31-31)
+
+#define IP_REV_1_IP_ID_SHIFT (31-15)
+#define IP_REV_1_IP_MJ_SHIFT (31-23)
+#define IP_REV_1_IP_MM_SHIFT (31-31)
+
+#define IP_REV_2_IP_INT_SHIFT (31-15)
+#define IP_REV_2_IP_ERR_SHIFT (31-23)
+#define IP_REV_2_IP_CFG_SHIFT (31-31)
+
+#define MECC_CAP_SHIFT (31-0)
+#define MECC_CET_SHIFT (31-1)
+#define MECC_SERCNT_SHIFT (31-15)
+#define MECC_MEMADDR_SHIFT (31-31)
+
+/**************************************************************************//**
+ @Description RX SC defines
+*//***************************************************************************/
+
+/* masks */
+#define RX_SCCFG_SCI_EN_MASK 0x00000800
+#define RX_SCCFG_RP_MASK 0x00000400
+#define RX_SCCFG_VF_MASK 0x00000300
+#define RX_SCCFG_CO_MASK 0x0000003f
+
+/* shifts */
+#define RX_SCCFG_SCI_EN_SHIFT (31-20)
+#define RX_SCCFG_RP_SHIFT (31-21)
+#define RX_SCCFG_VF_SHIFT (31-23)
+#define RX_SCCFG_CO_SHIFT (31-31)
+#define RX_SCCFG_CS_SHIFT (31-7)
+
+/**************************************************************************//**
+ @Description RX SA defines
+*//***************************************************************************/
+
+/* masks */
+#define RX_SACFG_ACTIVE 0x80000000
+#define RX_SACFG_AN_MASK 0x00000006
+#define RX_SACFG_EN_MASK 0x00000001
+
+/* shifts */
+#define RX_SACFG_AN_SHIFT (31-30)
+#define RX_SACFG_EN_SHIFT (31-31)
+
+/**************************************************************************//**
+ @Description TX SC defines
+*//***************************************************************************/
+
+/* masks */
+#define TX_SCCFG_AN_MASK 0x000c0000
+#define TX_SCCFG_ASA_MASK 0x00020000
+#define TX_SCCFG_SCE_MASK 0x00010000
+#define TX_SCCFG_CO_MASK 0x00003f00
+#define TX_SCCFG_CE_MASK 0x00000010
+#define TX_SCCFG_PF_MASK 0x00000008
+#define TX_SCCFG_AIS_MASK 0x00000004
+#define TX_SCCFG_UES_MASK 0x00000002
+#define TX_SCCFG_USCB_MASK 0x00000001
+
+/* shifts */
+#define TX_SCCFG_AN_SHIFT (31-13)
+#define TX_SCCFG_ASA_SHIFT (31-14)
+#define TX_SCCFG_SCE_SHIFT (31-15)
+#define TX_SCCFG_CO_SHIFT (31-23)
+#define TX_SCCFG_CE_SHIFT (31-27)
+#define TX_SCCFG_PF_SHIFT (31-28)
+#define TX_SCCFG_AIS_SHIFT (31-29)
+#define TX_SCCFG_UES_SHIFT (31-30)
+#define TX_SCCFG_USCB_SHIFT (31-31)
+#define TX_SCCFG_CS_SHIFT (31-7)
+
+/**************************************************************************//**
+ @Description TX SA defines
+*//***************************************************************************/
+
+/* masks */
+#define TX_SACFG_ACTIVE 0x80000000
+
+
+typedef struct
+{
+ void (*f_Isr) (t_Handle h_Arg, uint32_t id);
+ t_Handle h_SrcHandle;
+} t_FmMacsecIntrSrc;
+
+typedef struct
+{
+ e_FmMacsecUnknownSciFrameTreatment unknownSciTreatMode;
+ bool invalidTagsDeliverUncontrolled;
+ bool changedTextWithNoEncryptDeliverUncontrolled;
+ bool onlyScbIsSetDeliverUncontrolled;
+ bool encryptWithNoChangedTextDiscardUncontrolled;
+ e_FmMacsecUntagFrameTreatment untagTreatMode;
+ uint32_t pnExhThr;
+ bool keysUnreadable;
+ bool byPassMode;
+ bool reservedSc0;
+ uint32_t sectagOverhead;
+} t_FmMacsecDriverParam;
+
+typedef struct
+{
+ t_FmMacsecControllerDriver fmMacsecControllerDriver;
+ t_Handle h_Fm;
+ t_FmMacsecRegs *p_FmMacsecRegs;
+ t_Handle h_FmMac; /**< A handle to the FM MAC object related to */
+ char fmMacsecModuleName[MODULE_NAME_SIZE];
+ t_FmMacsecIntrSrc intrMng[NUM_OF_INTER_MODULE_EVENTS];
+ uint32_t events;
+ uint32_t exceptions;
+ uint32_t userExceptions;
+ t_FmMacsecExceptionsCallback *f_Exception; /**< Exception Callback Routine */
+ t_Handle h_App; /**< A handle to an application layer object; This handle will
+ be passed by the driver upon calling the above callbacks */
+ bool rxScTable[NUM_OF_RX_SC];
+ uint32_t numRxScAvailable;
+ bool txScTable[NUM_OF_TX_SC];
+ uint32_t numTxScAvailable;
+ t_Handle rxScSpinLock;
+ t_Handle txScSpinLock;
+ t_FmMacsecDriverParam *p_FmMacsecDriverParam;
+} t_FmMacsec;
+
+
+#endif /* __FM_MACSEC_MASTER_H */
diff --git a/drivers/net/ethernet/freescale/fman/Peripherals/FM/MACSEC/fm_macsec_secy.c b/drivers/net/ethernet/freescale/fman/Peripherals/FM/MACSEC/fm_macsec_secy.c
new file mode 100644
index 0000000..4d8c6e3
--- /dev/null
+++ b/drivers/net/ethernet/freescale/fman/Peripherals/FM/MACSEC/fm_macsec_secy.c
@@ -0,0 +1,908 @@
+/*
+ * Copyright 2008-2015 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/******************************************************************************
+ @File fm_macsec_secy.c
+
+ @Description FM MACSEC SECY driver routines implementation.
+*//***************************************************************************/
+
+#include "std_ext.h"
+#include "error_ext.h"
+#include "xx_ext.h"
+#include "string_ext.h"
+#include "sprint_ext.h"
+
+#include "fm_macsec_secy.h"
+
+
+/****************************************/
+/* static functions */
+/****************************************/
+static void FmMacsecSecYExceptionsIsr(t_Handle h_FmMacsecSecY, uint32_t id)
+{
+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
+
+ UNUSED(id);
+ SANITY_CHECK_RETURN(p_FmMacsecSecY, E_INVALID_HANDLE);
+
+ if (p_FmMacsecSecY->exceptions & FM_MACSEC_SECY_EX_FRAME_DISCARDED)
+ p_FmMacsecSecY->f_Exception(p_FmMacsecSecY->h_App, e_FM_MACSEC_SECY_EX_FRAME_DISCARDED);
+}
+
+static void FmMacsecSecYEventsIsr(t_Handle h_FmMacsecSecY, uint32_t id)
+{
+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
+
+ UNUSED(id);
+ SANITY_CHECK_RETURN(p_FmMacsecSecY, E_INVALID_HANDLE);
+
+ if (p_FmMacsecSecY->events & FM_MACSEC_SECY_EV_NEXT_PN)
+ p_FmMacsecSecY->f_Event(p_FmMacsecSecY->h_App, e_FM_MACSEC_SECY_EV_NEXT_PN);
+}
+
+static t_Error CheckFmMacsecSecYParameters(t_FmMacsecSecY *p_FmMacsecSecY)
+{
+ if (!p_FmMacsecSecY->f_Exception)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
+
+ if (!p_FmMacsecSecY->f_Event)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Events callback not provided"));
+
+ if (!p_FmMacsecSecY->numOfRxSc)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Num of Rx Scs must be greater than '0'"));
+
+
+ return E_OK;
+}
+
+static t_Handle FmMacsecSecYCreateSc(t_FmMacsecSecY *p_FmMacsecSecY,
+ macsecSCI_t sci,
+ e_FmMacsecSecYCipherSuite cipherSuite,
+ e_ScType type)
+{
+ t_SecYSc *p_ScTable;
+ void *p_Params;
+ uint32_t numOfSc,i;
+ t_Error err = E_OK;
+ t_RxScParams rxScParams;
+ t_TxScParams txScParams;
+
+ ASSERT_COND(p_FmMacsecSecY);
+ ASSERT_COND(p_FmMacsecSecY->h_FmMacsec);
+
+ if (type == e_SC_RX)
+ {
+ memset(&rxScParams, 0, sizeof(rxScParams));
+ i = (NUM_OF_RX_SC - 1);
+ p_ScTable = p_FmMacsecSecY->p_RxSc;
+ numOfSc = p_FmMacsecSecY->numOfRxSc;
+ rxScParams.confidentialityOffset = p_FmMacsecSecY->confidentialityOffset;
+ rxScParams.replayProtect = p_FmMacsecSecY->replayProtect;
+ rxScParams.replayWindow = p_FmMacsecSecY->replayWindow;
+ rxScParams.validateFrames = p_FmMacsecSecY->validateFrames;
+ rxScParams.cipherSuite = cipherSuite;
+ p_Params = &rxScParams;
+ }
+ else
+ {
+ memset(&txScParams, 0, sizeof(txScParams));
+ i = (NUM_OF_TX_SC - 1);
+ p_ScTable = p_FmMacsecSecY->p_TxSc;
+ numOfSc = p_FmMacsecSecY->numOfTxSc;
+ txScParams.sciInsertionMode = p_FmMacsecSecY->sciInsertionMode;
+ txScParams.protectFrames = p_FmMacsecSecY->protectFrames;
+ txScParams.confidentialityEnable = p_FmMacsecSecY->confidentialityEnable;
+ txScParams.confidentialityOffset = p_FmMacsecSecY->confidentialityOffset;
+ txScParams.cipherSuite = cipherSuite;
+ p_Params = &txScParams;
+ }
+
+ for (i=0;i<numOfSc;i++)
+ if (!p_ScTable[i].inUse)
+ break;
+ if (i == numOfSc)
+ {
+ REPORT_ERROR(MAJOR, E_FULL, ("FM MACSEC SECY SC"));
+ return NULL;
+ }
+
+ if (type == e_SC_RX)
+ {
+ ((t_RxScParams *)p_Params)->scId = p_ScTable[i].scId;
+ ((t_RxScParams *)p_Params)->sci = sci;
+ if ((err = FmMacsecCreateRxSc(p_FmMacsecSecY->h_FmMacsec, (t_RxScParams *)p_Params)) != E_OK)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY RX SC"));
+ return NULL;
+ }
+ }
+ else
+ {
+ ((t_TxScParams *)p_Params)->scId = p_ScTable[i].scId;
+ ((t_TxScParams *)p_Params)->sci = sci;
+ if ((err = FmMacsecCreateTxSc(p_FmMacsecSecY->h_FmMacsec, (t_TxScParams *)p_Params)) != E_OK)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY TX SC"));
+ return NULL;
+ }
+ }
+
+ p_ScTable[i].inUse = TRUE;
+ return &p_ScTable[i];
+}
+
+static t_Error FmMacsecSecYDeleteSc(t_FmMacsecSecY *p_FmMacsecSecY, t_SecYSc *p_FmSecYSc, e_ScType type)
+{
+ t_Error err = E_OK;
+
+ ASSERT_COND(p_FmMacsecSecY);
+ ASSERT_COND(p_FmMacsecSecY->h_FmMacsec);
+ ASSERT_COND(p_FmSecYSc);
+
+ if (type == e_SC_RX)
+ {
+ if ((err = FmMacsecDeleteRxSc(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ }
+ else
+ if ((err = FmMacsecDeleteTxSc(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+
+ p_FmSecYSc->inUse = FALSE;
+
+ return err;
+}
+
+/****************************************/
+/* API Init unit functions */
+/****************************************/
+t_Handle FM_MACSEC_SECY_Config(t_FmMacsecSecYParams *p_FmMacsecSecYParam)
+{
+ t_FmMacsecSecY *p_FmMacsecSecY;
+
+ /* Allocate FM MACSEC structure */
+ p_FmMacsecSecY = (t_FmMacsecSecY *) XX_Malloc(sizeof(t_FmMacsecSecY));
+ if (!p_FmMacsecSecY)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY driver structure"));
+ return NULL;
+ }
+ memset(p_FmMacsecSecY, 0, sizeof(t_FmMacsecSecY));
+
+ /* Allocate the FM MACSEC driver's parameters structure */
+ p_FmMacsecSecY->p_FmMacsecSecYDriverParam = (t_FmMacsecSecYDriverParam *)XX_Malloc(sizeof(t_FmMacsecSecYDriverParam));
+ if (!p_FmMacsecSecY->p_FmMacsecSecYDriverParam)
+ {
+ XX_Free(p_FmMacsecSecY);
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY driver parameters"));
+ return NULL;
+ }
+ memset(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, 0, sizeof(t_FmMacsecSecYDriverParam));
+
+ /* Initialize FM MACSEC SECY parameters which will be kept by the driver */
+ p_FmMacsecSecY->h_FmMacsec = p_FmMacsecSecYParam->h_FmMacsec;
+ p_FmMacsecSecY->f_Event = p_FmMacsecSecYParam->f_Event;
+ p_FmMacsecSecY->f_Exception = p_FmMacsecSecYParam->f_Exception;
+ p_FmMacsecSecY->h_App = p_FmMacsecSecYParam->h_App;
+ p_FmMacsecSecY->confidentialityEnable = DEFAULT_confidentialityEnable;
+ p_FmMacsecSecY->confidentialityOffset = DEFAULT_confidentialityOffset;
+ p_FmMacsecSecY->validateFrames = DEFAULT_validateFrames;
+ p_FmMacsecSecY->replayProtect = DEFAULT_replayEnable;
+ p_FmMacsecSecY->replayWindow = DEFAULT_replayWindow;
+ p_FmMacsecSecY->protectFrames = DEFAULT_protectFrames;
+ p_FmMacsecSecY->sciInsertionMode = DEFAULT_sciInsertionMode;
+ p_FmMacsecSecY->isPointToPoint = DEFAULT_ptp;
+ p_FmMacsecSecY->numOfRxSc = p_FmMacsecSecYParam->numReceiveChannels;
+ p_FmMacsecSecY->numOfTxSc = DEFAULT_numOfTxSc;
+ p_FmMacsecSecY->exceptions = DEFAULT_exceptions;
+ p_FmMacsecSecY->events = DEFAULT_events;
+
+ memcpy(&p_FmMacsecSecY->p_FmMacsecSecYDriverParam->txScParams,
+ &p_FmMacsecSecYParam->txScParams,
+ sizeof(t_FmMacsecSecYSCParams));
+ return p_FmMacsecSecY;
+}
+
+t_Error FM_MACSEC_SECY_Init(t_Handle h_FmMacsecSecY)
+{
+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
+ t_FmMacsecSecYDriverParam *p_FmMacsecSecYDriverParam = NULL;
+ uint32_t rxScIds[NUM_OF_RX_SC], txScIds[NUM_OF_TX_SC], i, j;
+ t_Error err;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_HANDLE);
+
+ CHECK_INIT_PARAMETERS(p_FmMacsecSecY, CheckFmMacsecSecYParameters);
+
+ p_FmMacsecSecYDriverParam = p_FmMacsecSecY->p_FmMacsecSecYDriverParam;
+
+ if ((p_FmMacsecSecY->isPointToPoint) &&
+ ((err = FmMacsecSetPTP(p_FmMacsecSecY->h_FmMacsec, TRUE)) != E_OK))
+ RETURN_ERROR(MAJOR, err, ("Can't set Poin-to-Point"));
+
+ /* Rx Sc Allocation */
+ p_FmMacsecSecY->p_RxSc = (t_SecYSc *)XX_Malloc(sizeof(t_SecYSc) * p_FmMacsecSecY->numOfRxSc);
+ if (!p_FmMacsecSecY->p_RxSc)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY RX SC"));
+ memset(p_FmMacsecSecY->p_RxSc, 0, sizeof(t_SecYSc) * p_FmMacsecSecY->numOfRxSc);
+ if ((err = FmMacsecAllocScs(p_FmMacsecSecY->h_FmMacsec, e_SC_RX, p_FmMacsecSecY->isPointToPoint, p_FmMacsecSecY->numOfRxSc, rxScIds)) != E_OK)
+ {
+ if (p_FmMacsecSecY->p_TxSc)
+ XX_Free(p_FmMacsecSecY->p_TxSc);
+ if (p_FmMacsecSecY->p_RxSc)
+ XX_Free(p_FmMacsecSecY->p_RxSc);
+ return ERROR_CODE(err);
+ }
+ for (i=0; i<p_FmMacsecSecY->numOfRxSc; i++)
+ {
+ p_FmMacsecSecY->p_RxSc[i].scId = rxScIds[i];
+ p_FmMacsecSecY->p_RxSc[i].type = e_SC_RX;
+ for (j=0; j<MAX_NUM_OF_SA_PER_SC;j++)
+ p_FmMacsecSecY->p_RxSc[i].sa[j].saId = (e_ScSaId)SECY_AN_FREE_VALUE;
+ }
+
+ /* Tx Sc Allocation */
+ p_FmMacsecSecY->p_TxSc = (t_SecYSc *)XX_Malloc(sizeof(t_SecYSc) * p_FmMacsecSecY->numOfTxSc);
+ if (!p_FmMacsecSecY->p_TxSc)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY TX SC"));
+ memset(p_FmMacsecSecY->p_TxSc, 0, sizeof(t_SecYSc) * p_FmMacsecSecY->numOfTxSc);
+
+ if ((err = FmMacsecAllocScs(p_FmMacsecSecY->h_FmMacsec, e_SC_TX, p_FmMacsecSecY->isPointToPoint, p_FmMacsecSecY->numOfTxSc, txScIds)) != E_OK)
+ {
+ if (p_FmMacsecSecY->p_TxSc)
+ XX_Free(p_FmMacsecSecY->p_TxSc);
+ if (p_FmMacsecSecY->p_RxSc)
+ XX_Free(p_FmMacsecSecY->p_RxSc);
+ return ERROR_CODE(err);
+ }
+ for (i=0; i<p_FmMacsecSecY->numOfTxSc; i++)
+ {
+ p_FmMacsecSecY->p_TxSc[i].scId = txScIds[i];
+ p_FmMacsecSecY->p_TxSc[i].type = e_SC_TX;
+ for (j=0; j<MAX_NUM_OF_SA_PER_SC;j++)
+ p_FmMacsecSecY->p_TxSc[i].sa[j].saId = (e_ScSaId)SECY_AN_FREE_VALUE;
+ FmMacsecRegisterIntr(p_FmMacsecSecY->h_FmMacsec,
+ e_FM_MACSEC_MOD_SC_TX,
+ (uint8_t)txScIds[i],
+ e_FM_INTR_TYPE_ERR,
+ FmMacsecSecYExceptionsIsr,
+ p_FmMacsecSecY);
+ FmMacsecRegisterIntr(p_FmMacsecSecY->h_FmMacsec,
+ e_FM_MACSEC_MOD_SC_TX,
+ (uint8_t)txScIds[i],
+ e_FM_INTR_TYPE_NORMAL,
+ FmMacsecSecYEventsIsr,
+ p_FmMacsecSecY);
+
+ if (p_FmMacsecSecY->exceptions & FM_MACSEC_SECY_EX_FRAME_DISCARDED)
+ FmMacsecSetException(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EX_TX_SC, txScIds[i], TRUE);
+ if (p_FmMacsecSecY->events & FM_MACSEC_SECY_EV_NEXT_PN)
+ FmMacsecSetEvent(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EV_TX_SC_NEXT_PN, txScIds[i], TRUE);
+ }
+
+ FmMacsecSecYCreateSc(p_FmMacsecSecY,
+ p_FmMacsecSecYDriverParam->txScParams.sci,
+ p_FmMacsecSecYDriverParam->txScParams.cipherSuite,
+ e_SC_TX);
+ XX_Free(p_FmMacsecSecYDriverParam);
+ p_FmMacsecSecY->p_FmMacsecSecYDriverParam = NULL;
+
+ return E_OK;
+}
+
+t_Error FM_MACSEC_SECY_Free(t_Handle h_FmMacsecSecY)
+{
+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
+ t_Error err = E_OK;
+ uint32_t rxScIds[NUM_OF_RX_SC], txScIds[NUM_OF_TX_SC], i;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
+
+ if (p_FmMacsecSecY->isPointToPoint)
+ FmMacsecSetPTP(p_FmMacsecSecY->h_FmMacsec, FALSE);
+ if (p_FmMacsecSecY->p_RxSc)
+ {
+ for (i=0; i<p_FmMacsecSecY->numOfRxSc; i++)
+ rxScIds[i] = p_FmMacsecSecY->p_RxSc[i].scId;
+ if ((err = FmMacsecFreeScs(p_FmMacsecSecY->h_FmMacsec, e_SC_RX, p_FmMacsecSecY->numOfRxSc, rxScIds)) != E_OK)
+ return ERROR_CODE(err);
+ XX_Free(p_FmMacsecSecY->p_RxSc);
+ }
+ if (p_FmMacsecSecY->p_TxSc)
+ {
+ FmMacsecSecYDeleteSc(p_FmMacsecSecY, &p_FmMacsecSecY->p_TxSc[0], e_SC_TX);
+
+ for (i=0; i<p_FmMacsecSecY->numOfTxSc; i++) {
+ txScIds[i] = p_FmMacsecSecY->p_TxSc[i].scId;
+ FmMacsecUnregisterIntr(p_FmMacsecSecY->h_FmMacsec,
+ e_FM_MACSEC_MOD_SC_TX,
+ (uint8_t)txScIds[i],
+ e_FM_INTR_TYPE_ERR);
+ FmMacsecUnregisterIntr(p_FmMacsecSecY->h_FmMacsec,
+ e_FM_MACSEC_MOD_SC_TX,
+ (uint8_t)txScIds[i],
+ e_FM_INTR_TYPE_NORMAL);
+
+ if (p_FmMacsecSecY->exceptions & FM_MACSEC_SECY_EX_FRAME_DISCARDED)
+ FmMacsecSetException(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EX_TX_SC, txScIds[i], FALSE);
+ if (p_FmMacsecSecY->events & FM_MACSEC_SECY_EV_NEXT_PN)
+ FmMacsecSetEvent(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EV_TX_SC_NEXT_PN, txScIds[i], FALSE);
+ }
+
+ if ((err = FmMacsecFreeScs(p_FmMacsecSecY->h_FmMacsec, e_SC_TX, p_FmMacsecSecY->numOfTxSc, txScIds)) != E_OK)
+ return ERROR_CODE(err);
+ XX_Free(p_FmMacsecSecY->p_TxSc);
+ }
+
+ XX_Free(p_FmMacsecSecY);
+
+ return err;
+}
+
+t_Error FM_MACSEC_SECY_ConfigSciInsertionMode(t_Handle h_FmMacsecSecY, e_FmMacsecSciInsertionMode sciInsertionMode)
+{
+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
+
+ p_FmMacsecSecY->sciInsertionMode = sciInsertionMode;
+
+ return E_OK;
+}
+
+t_Error FM_MACSEC_SECY_ConfigProtectFrames(t_Handle h_FmMacsecSecY, bool protectFrames)
+{
+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
+
+ p_FmMacsecSecY->protectFrames = protectFrames;
+
+ return E_OK;
+}
+
+t_Error FM_MACSEC_SECY_ConfigReplayWindow(t_Handle h_FmMacsecSecY, bool replayProtect, uint32_t replayWindow)
+{
+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
+
+ p_FmMacsecSecY->replayProtect = replayProtect;
+ p_FmMacsecSecY->replayWindow = replayWindow;
+
+ return E_OK;
+}
+
+t_Error FM_MACSEC_SECY_ConfigValidationMode(t_Handle h_FmMacsecSecY, e_FmMacsecValidFrameBehavior validateFrames)
+{
+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
+
+ p_FmMacsecSecY->validateFrames = validateFrames;
+
+ return E_OK;
+}
+
+t_Error FM_MACSEC_SECY_ConfigConfidentiality(t_Handle h_FmMacsecSecY, bool confidentialityEnable, uint16_t confidentialityOffset)
+{
+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
+
+ p_FmMacsecSecY->confidentialityEnable = confidentialityEnable;
+ p_FmMacsecSecY->confidentialityOffset = confidentialityOffset;
+
+ return E_OK;
+}
+
+t_Error FM_MACSEC_SECY_ConfigPointToPoint(t_Handle h_FmMacsecSecY)
+{
+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
+
+ p_FmMacsecSecY->numOfRxSc = 1;
+ p_FmMacsecSecY->isPointToPoint = TRUE;
+ p_FmMacsecSecY->sciInsertionMode = e_FM_MACSEC_SCI_INSERTION_MODE_IMPLICT_PTP;
+
+ return E_OK;
+}
+
+t_Error FM_MACSEC_SECY_ConfigException(t_Handle h_FmMacsecSecY, e_FmMacsecSecYExceptions exception, bool enable)
+{
+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
+ uint32_t bitMask = 0;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
+
+ GET_EXCEPTION_FLAG(bitMask, exception);
+ if (bitMask)
+ {
+ if (enable)
+ p_FmMacsecSecY->exceptions |= bitMask;
+ else
+ p_FmMacsecSecY->exceptions &= ~bitMask;
+ }
+ else
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
+
+ return E_OK;
+}
+
+t_Error FM_MACSEC_SECY_ConfigEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable)
+{
+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
+ uint32_t bitMask = 0;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
+
+ GET_EVENT_FLAG(bitMask, event);
+ if (bitMask)
+ {
+ if (enable)
+ p_FmMacsecSecY->events |= bitMask;
+ else
+ p_FmMacsecSecY->events &= ~bitMask;
+ }
+ else
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined event"));
+
+ return E_OK;
+}
+
+t_Handle FM_MACSEC_SECY_CreateRxSc(t_Handle h_FmMacsecSecY, t_FmMacsecSecYSCParams *p_ScParams)
+{
+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
+
+ SANITY_CHECK_RETURN_VALUE(p_FmMacsecSecY, E_INVALID_HANDLE, NULL);
+ SANITY_CHECK_RETURN_VALUE(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE, NULL);
+ SANITY_CHECK_RETURN_VALUE(p_ScParams, E_NULL_POINTER, NULL);
+ SANITY_CHECK_RETURN_VALUE(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE, NULL);
+
+ return FmMacsecSecYCreateSc(p_FmMacsecSecY, p_ScParams->sci, p_ScParams->cipherSuite, e_SC_RX);
+}
+
+t_Error FM_MACSEC_SECY_DeleteRxSc(t_Handle h_FmMacsecSecY, t_Handle h_Sc)
+{
+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
+ t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
+
+ return FmMacsecSecYDeleteSc(p_FmMacsecSecY, p_FmSecYSc, e_SC_RX);
+}
+
+t_Error FM_MACSEC_SECY_CreateRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key)
+{
+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
+ t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
+ t_Error err = E_OK;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
+
+ if (p_FmSecYSc->sa[an].saId != SECY_AN_FREE_VALUE)
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is already assigned",an));
+
+ if ((err = FmMacsecCreateRxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, (e_ScSaId)p_FmSecYSc->numOfSa, an, lowestPn, key)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+
+ p_FmSecYSc->sa[an].saId = (e_ScSaId)p_FmSecYSc->numOfSa++;
+ return err;
+}
+
+t_Error FM_MACSEC_SECY_DeleteRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an)
+{
+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
+ t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
+ t_Error err = E_OK;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
+
+ if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is already deleted",an));
+
+ if ((err = FmMacsecDeleteRxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+
+ p_FmSecYSc->numOfSa--;
+ p_FmSecYSc->sa[an].saId = (e_ScSaId)SECY_AN_FREE_VALUE;
+ /* TODO - check if statistics need to be read*/
+ return err;
+}
+
+t_Error FM_MACSEC_SECY_RxSaEnableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an)
+{
+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
+ t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
+ t_Error err = E_OK;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
+
+ if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
+
+ if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, TRUE)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+
+ p_FmSecYSc->sa[an].active = TRUE;
+ return err;
+}
+
+t_Error FM_MACSEC_SECY_RxSaDisableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an)
+{
+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
+ t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
+ t_Error err = E_OK;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
+
+ if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
+
+ if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, FALSE)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+
+ p_FmSecYSc->sa[an].active = FALSE;
+ return err;
+}
+
+t_Error FM_MACSEC_SECY_RxSaUpdateNextPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtNextPN)
+{
+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
+ t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
+ t_Error err = E_OK;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
+
+ if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
+
+ if ((err = FmMacsecRxSaUpdateNextPn(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, updtNextPN)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+
+ return err;
+}
+
+t_Error FM_MACSEC_SECY_RxSaUpdateLowestPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtLowestPN)
+{
+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
+ t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
+ t_Error err = E_OK;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
+
+ if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
+
+ if ((err = FmMacsecRxSaUpdateLowestPn(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, updtLowestPN)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+
+ return err;
+}
+
+t_Error FM_MACSEC_SECY_RxSaModifyKey(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, macsecSAKey_t key)
+{
+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
+ t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
+ t_Error err = E_OK;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
+
+ if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
+
+ if (p_FmSecYSc->sa[an].active)
+ if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, FALSE)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+
+ /* TODO - statistics should be read */
+
+ if ((err = FmMacsecCreateRxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, an, 1, key)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+
+ if (p_FmSecYSc->sa[an].active)
+ if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, TRUE)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ return err;
+}
+
+#if 0
+t_Handle FM_MACSEC_SECY_CreateTxSc(t_Handle h_FmMacsecSecY, macsecSCI_t sci)
+{
+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
+
+ SANITY_CHECK_RETURN_VALUE(p_FmMacsecSecY, E_INVALID_HANDLE, NULL);
+ SANITY_CHECK_RETURN_VALUE(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE, NULL);
+ SANITY_CHECK_RETURN_VALUE(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE, NULL);
+
+ return FmMacsecSecYCreateSc(p_FmMacsecSecY, sci, e_SC_TX);
+}
+
+t_Error FM_MACSEC_SECY_DeleteTxSc(t_Handle h_FmMacsecSecY, t_Handle h_Sc)
+{
+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
+ t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
+
+ return FmMacsecSecYDeleteSc(p_FmMacsecSecY, p_FmSecYSc, e_SC_TX);
+}
+#endif /* 0 */
+
+t_Error FM_MACSEC_SECY_CreateTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an, macsecSAKey_t key)
+{
+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
+ t_SecYSc *p_FmSecYSc;
+ t_Error err = E_OK;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
+ p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
+ SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
+
+ if (p_FmSecYSc->sa[an].saId != SECY_AN_FREE_VALUE)
+ RETURN_ERROR(MINOR, err, ("An %d is already assigned",an));
+
+ if ((err = FmMacsecCreateTxSa(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, (e_ScSaId)p_FmSecYSc->numOfSa, key)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+
+ p_FmSecYSc->sa[an].saId = (e_ScSaId)p_FmSecYSc->numOfSa++;
+ return err;
+}
+
+t_Error FM_MACSEC_SECY_DeleteTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an)
+{
+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
+ t_SecYSc *p_FmSecYSc;
+ t_Error err = E_OK;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
+ p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
+ SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
+
+ if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is already deleted",an));
+
+ if ((err = FmMacsecDeleteTxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+
+ p_FmSecYSc->numOfSa--;
+ p_FmSecYSc->sa[an].saId = (e_ScSaId)SECY_AN_FREE_VALUE;
+ /* TODO - check if statistics need to be read*/
+ return err;
+}
+
+t_Error FM_MACSEC_SECY_TxSaModifyKey(t_Handle h_FmMacsecSecY, macsecAN_t nextActiveAn, macsecSAKey_t key)
+{
+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
+ t_SecYSc *p_FmSecYSc;
+ macsecAN_t currentAn;
+ t_Error err = E_OK;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
+ p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
+ SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(nextActiveAn < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
+
+ if ((err = FmMacsecTxSaGetActive(p_FmMacsecSecY->h_FmMacsec,
+ p_FmSecYSc->scId,
+ &currentAn)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+
+ if ((err = FmMacsecTxSaSetActive(p_FmMacsecSecY->h_FmMacsec,
+ p_FmSecYSc->scId,
+ p_FmSecYSc->sa[nextActiveAn].saId,
+ nextActiveAn)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+
+ /* TODO - statistics should be read */
+
+ if ((err = FmMacsecCreateTxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[currentAn].saId, key)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+
+ return err;
+}
+
+t_Error FM_MACSEC_SECY_TxSaSetActive(t_Handle h_FmMacsecSecY, macsecAN_t an)
+{
+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
+ t_SecYSc *p_FmSecYSc;
+ t_Error err = E_OK;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
+ p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
+ SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
+
+ if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
+
+ if ((err = FmMacsecTxSaSetActive(p_FmMacsecSecY->h_FmMacsec,
+ p_FmSecYSc->scId,
+ p_FmSecYSc->sa[an].saId,
+ an)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+
+ return err;
+}
+
+t_Error FM_MACSEC_SECY_TxSaGetActive(t_Handle h_FmMacsecSecY, macsecAN_t *p_An)
+{
+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
+ t_SecYSc *p_FmSecYSc;
+ t_Error err = E_OK;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
+ p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
+ SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_An, E_INVALID_HANDLE);
+
+ if ((err = FmMacsecTxSaGetActive(p_FmMacsecSecY->h_FmMacsec,
+ p_FmSecYSc->scId,
+ p_An)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+
+ return err;
+}
+
+t_Error FM_MACSEC_SECY_GetRxScPhysId(t_Handle h_FmMacsecSecY, t_Handle h_Sc, uint32_t *p_ScPhysId)
+{
+ t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
+ t_Error err = E_OK;
+
+ SANITY_CHECK_RETURN_ERROR(h_FmMacsecSecY, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(((t_FmMacsecSecY *)h_FmMacsecSecY)->h_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!((t_FmMacsecSecY *)h_FmMacsecSecY)->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
+#ifdef DISABLE_SANITY_CHECKS
+ UNUSED(h_FmMacsecSecY);
+#endif /* DISABLE_SANITY_CHECKS */
+
+ *p_ScPhysId = p_FmSecYSc->scId;
+ return err;
+}
+
+t_Error FM_MACSEC_SECY_GetTxScPhysId(t_Handle h_FmMacsecSecY, uint32_t *p_ScPhysId)
+{
+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
+ t_SecYSc *p_FmSecYSc;
+ t_Error err = E_OK;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
+ p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
+ SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
+
+ *p_ScPhysId = p_FmSecYSc->scId;
+ return err;
+}
+
+t_Error FM_MACSEC_SECY_SetException(t_Handle h_FmMacsecSecY, e_FmMacsecExceptions exception, bool enable)
+{
+ UNUSED(h_FmMacsecSecY);UNUSED(exception);UNUSED(enable);
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+t_Error FM_MACSEC_SECY_SetEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable)
+{
+ UNUSED(h_FmMacsecSecY);UNUSED(event);UNUSED(enable);
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+t_Error FM_MACSEC_SECY_GetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYStatistics *p_Statistics)
+{
+ UNUSED(h_FmMacsecSecY);UNUSED(p_Statistics);
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+t_Error FM_MACSEC_SECY_RxScGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, t_FmMacsecSecYRxScStatistics *p_Statistics)
+{
+ UNUSED(h_FmMacsecSecY);UNUSED(h_Sc);UNUSED(p_Statistics);
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+t_Error FM_MACSEC_SECY_RxSaGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, t_FmMacsecSecYRxSaStatistics *p_Statistics)
+{
+ UNUSED(h_FmMacsecSecY);UNUSED(h_Sc);UNUSED(an);UNUSED(p_Statistics);
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+t_Error FM_MACSEC_SECY_TxScGetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYTxScStatistics *p_Statistics)
+{
+ UNUSED(h_FmMacsecSecY);UNUSED(p_Statistics);
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+t_Error FM_MACSEC_SECY_TxSaGetStatistics(t_Handle h_FmMacsecSecY, macsecAN_t an, t_FmMacsecSecYTxSaStatistics *p_Statistics)
+{
+ UNUSED(h_FmMacsecSecY);UNUSED(an);UNUSED(p_Statistics);
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
diff --git a/drivers/net/ethernet/freescale/fman/Peripherals/FM/MACSEC/fm_macsec_secy.h b/drivers/net/ethernet/freescale/fman/Peripherals/FM/MACSEC/fm_macsec_secy.h
new file mode 100644
index 0000000..0cf624e
--- /dev/null
+++ b/drivers/net/ethernet/freescale/fman/Peripherals/FM/MACSEC/fm_macsec_secy.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2008-2015 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/******************************************************************************
+ @File fm_macsec_secy.h
+
+ @Description FM MACSEC SecY internal structures and definitions.
+*//***************************************************************************/
+#ifndef __FM_MACSEC_SECY_H
+#define __FM_MACSEC_SECY_H
+
+#include "error_ext.h"
+#include "std_ext.h"
+
+#include "fm_macsec.h"
+
+
+/**************************************************************************//**
+ @Description Exceptions
+*//***************************************************************************/
+
+#define FM_MACSEC_SECY_EX_FRAME_DISCARDED 0x80000000
+
+#define GET_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \
+ case e_FM_MACSEC_SECY_EX_FRAME_DISCARDED: \
+ bitMask = FM_MACSEC_SECY_EX_FRAME_DISCARDED; break; \
+ default: bitMask = 0;break;}
+
+/**************************************************************************//**
+ @Description Events
+*//***************************************************************************/
+
+#define FM_MACSEC_SECY_EV_NEXT_PN 0x80000000
+
+#define GET_EVENT_FLAG(bitMask, event) switch (event){ \
+ case e_FM_MACSEC_SECY_EV_NEXT_PN: \
+ bitMask = FM_MACSEC_SECY_EV_NEXT_PN; break; \
+ default: bitMask = 0;break;}
+
+/**************************************************************************//**
+ @Description Defaults
+*//***************************************************************************/
+
+#define DEFAULT_exceptions (FM_MACSEC_SECY_EX_FRAME_DISCARDED)
+#define DEFAULT_events (FM_MACSEC_SECY_EV_NEXT_PN)
+#define DEFAULT_numOfTxSc 1
+#define DEFAULT_confidentialityEnable FALSE
+#define DEFAULT_confidentialityOffset 0
+#define DEFAULT_sciInsertionMode e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG
+#define DEFAULT_validateFrames e_FM_MACSEC_VALID_FRAME_BEHAVIOR_STRICT
+#define DEFAULT_replayEnable FALSE
+#define DEFAULT_replayWindow 0
+#define DEFAULT_protectFrames TRUE
+#define DEFAULT_ptp FALSE
+
+/**************************************************************************//**
+ @Description General defines
+*//***************************************************************************/
+
+#define SECY_AN_FREE_VALUE MAX_NUM_OF_SA_PER_SC
+
+
+typedef struct {
+ e_ScSaId saId;
+ bool active;
+ union {
+ t_FmMacsecSecYRxSaStatistics rxSaStatistics;
+ t_FmMacsecSecYTxSaStatistics txSaStatistics;
+ };
+} t_SecYSa;
+
+typedef struct {
+ bool inUse;
+ uint32_t scId;
+ e_ScType type;
+ uint8_t numOfSa;
+ t_SecYSa sa[MAX_NUM_OF_SA_PER_SC];
+ union {
+ t_FmMacsecSecYRxScStatistics rxScStatistics;
+ t_FmMacsecSecYTxScStatistics txScStatistics;
+ };
+} t_SecYSc;
+
+typedef struct {
+ t_FmMacsecSecYSCParams txScParams; /**< Tx SC Params */
+} t_FmMacsecSecYDriverParam;
+
+typedef struct {
+ t_Handle h_FmMacsec;
+ bool confidentialityEnable; /**< TRUE - confidentiality protection and integrity protection
+ FALSE - no confidentiality protection, only integrity protection*/
+ uint16_t confidentialityOffset; /**< The number of initial octets of each MSDU without confidentiality protection
+ common values are 0, 30, and 50 */
+ bool replayProtect; /**< replay protection function mode */
+ uint32_t replayWindow; /**< the size of the replay window */
+ e_FmMacsecValidFrameBehavior validateFrames; /**< validation function mode */
+ e_FmMacsecSciInsertionMode sciInsertionMode;
+ bool protectFrames;
+ bool isPointToPoint;
+ e_FmMacsecSecYCipherSuite cipherSuite; /**< Cipher suite to be used for this SecY */
+ uint32_t numOfRxSc; /**< Number of receive channels */
+ uint32_t numOfTxSc; /**< Number of transmit channels */
+ t_SecYSc *p_RxSc;
+ t_SecYSc *p_TxSc;
+ uint32_t events;
+ uint32_t exceptions;
+ t_FmMacsecSecYExceptionsCallback *f_Exception; /**< TODO */
+ t_FmMacsecSecYEventsCallback *f_Event; /**< TODO */
+ t_Handle h_App;
+ t_FmMacsecSecYStatistics statistics;
+ t_FmMacsecSecYDriverParam *p_FmMacsecSecYDriverParam;
+} t_FmMacsecSecY;
+
+
+#endif /* __FM_MACSEC_SECY_H */
diff --git a/drivers/net/ethernet/freescale/fman/Peripherals/FM/Makefile b/drivers/net/ethernet/freescale/fman/Peripherals/FM/Makefile
index e02b57e..d691a13 100644
--- a/drivers/net/ethernet/freescale/fman/Peripherals/FM/Makefile
+++ b/drivers/net/ethernet/freescale/fman/Peripherals/FM/Makefile
@@ -20,3 +20,4 @@ obj-y += SP/
obj-y += Port/
obj-y += HC/
obj-y += Rtc/
+obj-y += MACSEC/
diff --git a/drivers/net/ethernet/freescale/fman/Peripherals/FM/Pcd/fm_cc.c b/drivers/net/ethernet/freescale/fman/Peripherals/FM/Pcd/fm_cc.c
index fc42642..863b61d 100644
--- a/drivers/net/ethernet/freescale/fman/Peripherals/FM/Pcd/fm_cc.c
+++ b/drivers/net/ethernet/freescale/fman/Peripherals/FM/Pcd/fm_cc.c
@@ -3572,6 +3572,9 @@ static t_Error UpdatePtrWhichPointOnCrntMdfNode(
ccNodeInfo.h_CcNode = h_NewAd;
EnqueueNodeInfoToRelevantLst(h_NewLst, &ccNodeInfo, NULL);
+
+ if (p_NextEngineParams->h_Manip)
+ FmPcdManipUpdateOwner(p_NextEngineParams->h_Manip, FALSE);
}
return E_OK;
}
diff --git a/drivers/net/ethernet/freescale/fman/Peripherals/FM/Pcd/fm_kg.c b/drivers/net/ethernet/freescale/fman/Peripherals/FM/Pcd/fm_kg.c
index cadc12a..dae5575 100644
--- a/drivers/net/ethernet/freescale/fman/Peripherals/FM/Pcd/fm_kg.c
+++ b/drivers/net/ethernet/freescale/fman/Peripherals/FM/Pcd/fm_kg.c
@@ -2794,6 +2794,30 @@ uint8_t FmPcdKgGetRelativeSchemeId(t_Handle h_FmPcd, uint8_t schemeId)
return FM_PCD_KG_NUM_OF_SCHEMES;
}
+t_Handle FmPcdKgGetSchemeHandle(t_Handle h_FmPcd, uint8_t relativeSchemeId)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+
+ ASSERT_COND(p_FmPcd);
+
+ /* check that schemeId is in range */
+ if (relativeSchemeId >= p_FmPcd->p_FmPcdKg->numOfSchemes)
+ {
+ REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("relative-scheme-id %d!", relativeSchemeId));
+ return NULL;
+ }
+
+ if (!FmPcdKgIsSchemeValidSw(&p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId]))
+ return NULL;
+
+ return &p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId];
+}
+
+bool FmPcdKgIsSchemeHasOwners(t_Handle h_Scheme)
+{
+ return (((t_FmPcdKgScheme*)h_Scheme)->owners == 0)?FALSE:TRUE;
+}
+
t_Error FmPcdKgCcGetSetParams(t_Handle h_FmPcd, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value)
{
t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
diff --git a/drivers/net/ethernet/freescale/fman/Peripherals/FM/Pcd/fm_manip.c b/drivers/net/ethernet/freescale/fman/Peripherals/FM/Pcd/fm_manip.c
index e69ea1d..a21516b 100644
--- a/drivers/net/ethernet/freescale/fman/Peripherals/FM/Pcd/fm_manip.c
+++ b/drivers/net/ethernet/freescale/fman/Peripherals/FM/Pcd/fm_manip.c
@@ -4896,6 +4896,7 @@ t_Error FmPcdManipBuildIpReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv,
{
t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
t_FmPcdKgSchemeParams *p_SchemeParams = NULL;
+ t_Handle h_Scheme;
ASSERT_COND(p_FmPcd);
ASSERT_COND(h_NetEnv);
@@ -4905,7 +4906,23 @@ t_Error FmPcdManipBuildIpReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv,
if (p_Manip->reassmParams.ip.h_Ipv4Scheme)
return E_OK;
- p_SchemeParams = XX_Malloc(sizeof(t_FmPcdKgSchemeParams));
+ if (isIpv4) {
+ h_Scheme = FmPcdKgGetSchemeHandle(p_FmPcd, p_Manip->reassmParams.ip.relativeSchemeId[0]);
+ if (h_Scheme) {
+ /* scheme was found */
+ p_Manip->reassmParams.ip.h_Ipv4Scheme = h_Scheme;
+ return E_OK;
+ }
+ } else {
+ h_Scheme = FmPcdKgGetSchemeHandle(p_FmPcd, p_Manip->reassmParams.ip.relativeSchemeId[1]);
+ if (h_Scheme) {
+ /* scheme was found */
+ p_Manip->reassmParams.ip.h_Ipv6Scheme = h_Scheme;
+ return E_OK;
+ }
+ }
+
+ p_SchemeParams = XX_Malloc(sizeof(t_FmPcdKgSchemeParams));
if (!p_SchemeParams)
RETURN_ERROR(MAJOR, E_NO_MEMORY,
("Memory allocation failed for scheme"));
@@ -4946,10 +4963,12 @@ t_Error FmPcdManipDeleteIpReassmSchemes(t_Handle h_Manip)
ASSERT_COND(p_Manip);
- if (p_Manip->reassmParams.ip.h_Ipv4Scheme)
+ if ((p_Manip->reassmParams.ip.h_Ipv4Scheme) &&
+ !FmPcdKgIsSchemeHasOwners(p_Manip->reassmParams.ip.h_Ipv4Scheme))
FM_PCD_KgSchemeDelete(p_Manip->reassmParams.ip.h_Ipv4Scheme);
- if (p_Manip->reassmParams.ip.h_Ipv6Scheme)
+ if ((p_Manip->reassmParams.ip.h_Ipv6Scheme) &&
+ !FmPcdKgIsSchemeHasOwners(p_Manip->reassmParams.ip.h_Ipv6Scheme))
FM_PCD_KgSchemeDelete(p_Manip->reassmParams.ip.h_Ipv6Scheme);
return E_OK;
diff --git a/drivers/net/ethernet/freescale/fman/Peripherals/FM/fm.h b/drivers/net/ethernet/freescale/fman/Peripherals/FM/fm.h
index b7b42b5..4c1897b 100644
--- a/drivers/net/ethernet/freescale/fman/Peripherals/FM/fm.h
+++ b/drivers/net/ethernet/freescale/fman/Peripherals/FM/fm.h
@@ -331,8 +331,9 @@ switch (exception){ \
#else /* (DPAA_VERSION < 11) */
/* Defaults are registers' reset values */
-#define DEFAULT_totalFifoSize(major, minor) \
- (((major == 6) && ((minor == 1) || (minor == 4))) ? (142*KILOBYTE) : (295*KILOBYTE))
+#define DEFAULT_totalFifoSize(major, minor) \
+ (((major == 6) && ((minor == 1) || (minor == 4))) ? \
+ (156*KILOBYTE) : (295*KILOBYTE))
#define DEFAULT_totalNumOfTasks 124
diff --git a/drivers/net/ethernet/freescale/fman/Peripherals/FM/inc/fm_common.h b/drivers/net/ethernet/freescale/fman/Peripherals/FM/inc/fm_common.h
index 67728f1..1c08bb1 100644
--- a/drivers/net/ethernet/freescale/fman/Peripherals/FM/inc/fm_common.h
+++ b/drivers/net/ethernet/freescale/fman/Peripherals/FM/inc/fm_common.h
@@ -280,7 +280,7 @@ typedef struct {
typedef struct {
t_FmSetParams setParams;
t_FmGetParams getParams;
-} t_FmGetSetParams;
+} t_FmGetSetParams;
t_Error FmGetSetParams(t_Handle h_Fm, t_FmGetSetParams *p_Params);
@@ -701,6 +701,8 @@ void FmPcdKgUpdateRequiredAction(t_Handle h_Scheme, uint32_t requiredActi
bool FmPcdKgIsDirectPlcr(t_Handle h_FmPcd, uint8_t schemeId);
bool FmPcdKgIsDistrOnPlcrProfile(t_Handle h_FmPcd, uint8_t schemeId);
uint16_t FmPcdKgGetRelativeProfileId(t_Handle h_FmPcd, uint8_t schemeId);
+t_Handle FmPcdKgGetSchemeHandle(t_Handle h_FmPcd, uint8_t relativeSchemeId);
+bool FmPcdKgIsSchemeHasOwners(t_Handle h_Scheme);
t_Error FmPcdKgCcGetSetParams(t_Handle h_FmPcd, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value);
t_Error FmPcdKgSetOrBindToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t netEnvId, protocolOpt_t *p_OptArray, uint8_t *p_ClsPlanGrpId, bool *p_IsEmptyClsPlanGrp);
t_Error FmPcdKgDeleteOrUnbindPortToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId);
diff --git a/drivers/net/ethernet/freescale/fman/inc/Peripherals/fm_macsec_ext.h b/drivers/net/ethernet/freescale/fman/inc/Peripherals/fm_macsec_ext.h
new file mode 100644
index 0000000..57925f1
--- /dev/null
+++ b/drivers/net/ethernet/freescale/fman/inc/Peripherals/fm_macsec_ext.h
@@ -0,0 +1,1271 @@
+/*
+ * Copyright 2008-2015 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**************************************************************************//**
+ @File fm_macsec_ext.h
+
+ @Description FM MACSEC ...
+*//***************************************************************************/
+#ifndef __FM_MACSEC_EXT_H
+#define __FM_MACSEC_EXT_H
+
+#include "std_ext.h"
+
+
+/**************************************************************************//**
+ @Group FM_grp Frame Manager API
+
+ @Description FM API functions, definitions and enums
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Group FM_MACSEC_grp FM MACSEC
+
+ @Description FM MACSEC API functions, definitions and enums
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Description MACSEC Exceptions
+*//***************************************************************************/
+typedef enum e_FmMacsecExceptions {
+ e_FM_MACSEC_EX_SINGLE_BIT_ECC, /**< Single bit ECC error */
+ e_FM_MACSEC_EX_MULTI_BIT_ECC /**< Multi bit ECC error */
+} e_FmMacsecExceptions;
+
+
+/**************************************************************************//**
+ @Group FM_MACSEC_init_grp FM-MACSEC Initialization Unit
+
+ @Description FM MACSEC Initialization Unit
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Function t_FmMacsecExceptionsCallback
+
+ @Description Exceptions user callback routine, will be called upon an
+ exception passing the exception identification.
+
+ @Param[in] h_App A handle to an application layer object; This handle
+ will be passed by the driver upon calling this callback.
+ @Param[in] exception The exception.
+*//***************************************************************************/
+typedef void (t_FmMacsecExceptionsCallback) ( t_Handle h_App,
+ e_FmMacsecExceptions exception);
+
+
+/**************************************************************************//**
+ @Description FM MACSEC config input
+*//***************************************************************************/
+typedef struct t_FmMacsecParams {
+ t_Handle h_Fm; /**< A handle to the FM object related to */
+ bool guestMode; /**< Partition-id */
+ union {
+ struct {
+ uint8_t fmMacId; /**< FM MAC id */
+ } guestParams;
+
+ struct {
+ uintptr_t baseAddr; /**< Base of memory mapped FM MACSEC registers */
+ t_Handle h_FmMac; /**< A handle to the FM MAC object related to */
+ t_FmMacsecExceptionsCallback *f_Exception; /**< Exception Callback Routine */
+ t_Handle h_App; /**< A handle to an application layer object; This handle will
+ be passed by the driver upon calling the above callbacks */
+ } nonGuestParams;
+ };
+} t_FmMacsecParams;
+
+/**************************************************************************//**
+ @Function FM_MACSEC_Config
+
+ @Description Creates descriptor for the FM MACSEC module;
+
+ The routine returns a handle (descriptor) to the FM MACSEC object;
+ This descriptor must be passed as first parameter to all other
+ FM MACSEC function calls;
+
+ No actual initialization or configuration of FM MACSEC hardware is
+ done by this routine.
+
+ @Param[in] p_FmMacsecParam Pointer to data structure of parameters.
+
+ @Retval Handle to FM MACSEC object, or NULL for Failure.
+*//***************************************************************************/
+t_Handle FM_MACSEC_Config(t_FmMacsecParams *p_FmMacsecParam);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_Init
+
+ @Description Initializes the FM MACSEC module.
+
+ @Param[in] h_FmMacsec FM MACSEC module descriptor.
+
+ @Return E_OK on success; Error code otherwise.
+*//***************************************************************************/
+t_Error FM_MACSEC_Init(t_Handle h_FmMacsec);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_Free
+
+ @Description Frees all resources that were assigned to FM MACSEC module;
+
+ Calling this routine invalidates the descriptor.
+
+ @Param[in] h_FmMacsec FM MACSEC module descriptor.
+
+ @Return E_OK on success; Error code otherwise.
+*//***************************************************************************/
+t_Error FM_MACSEC_Free(t_Handle h_FmMacsec);
+
+
+/**************************************************************************//**
+ @Group FM_MACSEC_advanced_init_grp FM-MACSEC Advanced Configuration Unit
+
+ @Description Configuration functions used to change default values.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Description enum for unknown sci frame treatment
+*//***************************************************************************/
+typedef enum e_FmMacsecUnknownSciFrameTreatment {
+ e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_BOTH = 0, /**< Controlled port - Strict mode */
+ e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_UNCONTROLLED_DELIVER_OR_DISCARD_CONTROLLED, /**< If C bit clear deliver on controlled port, else discard
+ Controlled port - Check or Disable mode */
+ e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED, /**< Controlled port - Strict mode */
+ e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DELIVER_OR_DISCARD_UNCONTROLLED_DELIVER_OR_DISCARD_CONTROLLED /**< If C bit set deliver on uncontrolled port and discard on controlled port,
+ else discard on uncontrolled port and deliver on controlled port
+ Controlled port - Check or Disable mode */
+} e_FmMacsecUnknownSciFrameTreatment;
+
+/**************************************************************************//**
+ @Description enum for untag frame treatment
+*//***************************************************************************/
+typedef enum e_FmMacsecUntagFrameTreatment {
+ e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED = 0, /**< Controlled port - Strict mode */
+ e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DISCARD_BOTH, /**< Controlled port - Strict mode */
+ e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DISCARD_UNCONTROLLED_DELIVER_CONTROLLED_UNMODIFIED /**< Controlled port - Strict mode */
+} e_FmMacsecUntagFrameTreatment;
+
+/**************************************************************************//**
+ @Function FM_MACSEC_ConfigUnknownSciFrameTreatment
+
+ @Description Change the treatment for received frames with unknown sci from its default
+ configuration [DEFAULT_unknownSciFrameTreatment].
+
+ @Param[in] h_FmMacsec FM MACSEC module descriptor.
+ @Param[in] treatMode The selected mode.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
+*//***************************************************************************/
+t_Error FM_MACSEC_ConfigUnknownSciFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_ConfigInvalidTagsFrameTreatment
+
+ @Description Change the treatment for received frames with invalid tags or
+ a zero value PN or an invalid ICV from its default configuration
+ [DEFAULT_invalidTagsFrameTreatment].
+
+ @Param[in] h_FmMacsec FM MACSEC module descriptor.
+ @Param[in] deliverUncontrolled If True deliver on the uncontrolled port, else discard;
+ In both cases discard on the controlled port;
+ this provide Strict, Check or Disable mode.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
+*//***************************************************************************/
+t_Error FM_MACSEC_ConfigInvalidTagsFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment
+
+ @Description Change the treatment for received frames with the Encryption bit
+ set and the Changed Text bit clear from its default configuration
+ [DEFAULT_encryptWithNoChangedTextFrameTreatment].
+
+ @Param[in] h_FmMacsec FM MACSEC module descriptor.
+ @Param[in] discardUncontrolled If True discard on the uncontrolled port, else deliver;
+ In both cases discard on the controlled port;
+ this provide Strict, Check or Disable mode.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
+*//***************************************************************************/
+t_Error FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(t_Handle h_FmMacsec, bool discardUncontrolled);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment
+
+ @Description Change the treatment for received frames with the Encryption bit
+ clear and the Changed Text bit set from its default configuration
+ [DEFAULT_changedTextWithNoEncryptFrameTreatment].
+
+ @Param[in] h_FmMacsec FM MACSEC module descriptor.
+ @Param[in] deliverUncontrolled If True deliver on the uncontrolled port, else discard;
+ In both cases discard on the controlled port;
+ this provide Strict, Check or Disable mode.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
+*//***************************************************************************/
+t_Error FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_ConfigUntagFrameTreatment
+
+ @Description Change the treatment for received frames without the MAC security tag (SecTAG)
+ from its default configuration [DEFAULT_untagFrameTreatment].
+
+ @Param[in] h_FmMacsec FM MACSEC module descriptor.
+ @Param[in] treatMode The selected mode.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
+*//***************************************************************************/
+t_Error FM_MACSEC_ConfigUntagFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment
+
+ @Description Change the treatment for received frames with only SCB bit set
+ from its default configuration [DEFAULT_onlyScbIsSetFrameTreatment].
+
+ @Param[in] h_FmMacsec FM MACSEC module descriptor.
+ @Param[in] deliverUncontrolled If True deliver on the uncontrolled port, else discard;
+ In both cases discard on the controlled port;
+ this provide Strict, Check or Disable mode.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
+*//***************************************************************************/
+t_Error FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_ConfigPnExhaustionThreshold
+
+ @Description It's provide the ability to configure a PN exhaustion threshold;
+ When the NextPn crosses this value an interrupt event
+ is asserted to warn that the active SA should re-key.
+
+ @Param[in] h_FmMacsec FM MACSEC module descriptor.
+ @Param[in] pnExhThr If the threshold is reached, an interrupt event
+ is asserted to re-key.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
+*//***************************************************************************/
+t_Error FM_MACSEC_ConfigPnExhaustionThreshold(t_Handle h_FmMacsec, uint32_t pnExhThr);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_ConfigKeysUnreadable
+
+ @Description Turn on privacy mode; All the keys and their hash values can't be read any more;
+ Can not be cleared unless hard reset.
+
+ @Param[in] h_FmMacsec FM MACSEC module descriptor.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
+*//***************************************************************************/
+t_Error FM_MACSEC_ConfigKeysUnreadable(t_Handle h_FmMacsec);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_ConfigSectagWithoutSCI
+
+ @Description Promise that all generated Sectag will be without SCI included.
+
+ @Param[in] h_FmMacsec FM MACSEC module descriptor.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
+*//***************************************************************************/
+t_Error FM_MACSEC_ConfigSectagWithoutSCI(t_Handle h_FmMacsec);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_ConfigException
+
+ @Description Calling this routine changes the internal driver data base
+ from its default selection of exceptions enablement;
+ By default all exceptions are enabled.
+
+ @Param[in] h_FmMacsec FM MACSEC module descriptor.
+ @Param[in] exception The exception to be selected.
+ @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
+*//***************************************************************************/
+t_Error FM_MACSEC_ConfigException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable);
+
+/** @} */ /* end of FM_MACSEC_advanced_init_grp group */
+/** @} */ /* end of FM_MACSEC_init_grp group */
+
+
+/**************************************************************************//**
+ @Group FM_MACSEC_runtime_control_grp FM-MACSEC Runtime Control Data Unit
+
+ @Description FM MACSEC runtime control data unit API functions, definitions and enums.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Function FM_MACSEC_GetRevision
+
+ @Description Return MACSEC HW chip revision
+
+ @Param[in] h_FmMacsec FM MACSEC module descriptor.
+ @Param[out] p_MacsecRevision MACSEC revision as defined by the chip.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only after FM_MACSEC_Init().
+*//***************************************************************************/
+t_Error FM_MACSEC_GetRevision(t_Handle h_FmMacsec, uint32_t *p_MacsecRevision);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_Enable
+
+ @Description This routine should be called after MACSEC is initialized for enabling all
+ MACSEC engines according to their existing configuration.
+
+ @Param[in] h_FmMacsec FM MACSEC module descriptor.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_Init() and when MACSEC is disabled.
+*//***************************************************************************/
+t_Error FM_MACSEC_Enable(t_Handle h_FmMacsec);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_Disable
+
+ @Description This routine may be called when MACSEC is enabled in order to
+ disable all MACSEC engines; The MACSEC is working in bypass mode.
+
+ @Param[in] h_FmMacsec FM MACSEC module descriptor.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_Init() and when MACSEC is enabled.
+*//***************************************************************************/
+t_Error FM_MACSEC_Disable(t_Handle h_FmMacsec);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_SetException
+
+ @Description Calling this routine enables/disables the specified exception.
+
+ @Param[in] h_FmMacsec FM MACSEC module descriptor.
+ @Param[in] exception The exception to be selected.
+ @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_Init().
+*//***************************************************************************/
+t_Error FM_MACSEC_SetException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable);
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+/**************************************************************************//**
+ @Function FM_MACSEC_DumpRegs
+
+ @Description Dump internal registers.
+
+ @Param[in] h_FmMacsec - FM MACSEC module descriptor.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only after FM_MACSEC_Init().
+*//***************************************************************************/
+t_Error FM_MACSEC_DumpRegs(t_Handle h_FmMacsec);
+#endif /* (defined(DEBUG_ERRORS) && ... */
+
+#ifdef VERIFICATION_SUPPORT
+/********************* VERIFICATION ONLY ********************************/
+/**************************************************************************//**
+ @Function FM_MACSEC_BackdoorSet
+
+ @Description Set register of the MACSEC memory map
+
+ @Param[in] h_FmMacsec FM MACSEC module descriptor.
+ @Param[out] offset Register offset.
+ @Param[out] value Value to write.
+
+
+ @Return None
+
+ @Cautions Allowed only following FM_MACSEC_Init().
+*//***************************************************************************/
+t_Error FM_MACSEC_BackdoorSet(t_Handle h_FmMacsec, uint32_t offset, uint32_t value);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_BackdoorGet
+
+ @Description Read from register of the MACSEC memory map.
+
+ @Param[in] h_FmMacsec FM MACSEC module descriptor.
+ @Param[out] offset Register offset.
+
+ @Return Value read
+
+ @Cautions Allowed only following FM_MACSEC_Init().
+*//***************************************************************************/
+uint32_t FM_MACSEC_BackdoorGet(t_Handle h_FmMacsec, uint32_t offset);
+#endif /* VERIFICATION_SUPPORT */
+
+/** @} */ /* end of FM_MACSEC_runtime_control_grp group */
+
+
+/**************************************************************************//**
+ @Group FM_MACSEC_SECY_grp FM-MACSEC SecY
+
+ @Description FM-MACSEC SecY API functions, definitions and enums
+
+ @{
+*//***************************************************************************/
+
+typedef uint8_t macsecSAKey_t[32];
+typedef uint64_t macsecSCI_t;
+typedef uint8_t macsecAN_t;
+
+/**************************************************************************//**
+@Description MACSEC SECY Cipher Suite
+*//***************************************************************************/
+typedef enum e_FmMacsecSecYCipherSuite {
+ e_FM_MACSEC_SECY_GCM_AES_128 = 0, /**< GCM-AES-128 */
+#if (DPAA_VERSION >= 11)
+ e_FM_MACSEC_SECY_GCM_AES_256 /**< GCM-AES-256 */
+#endif /* (DPAA_VERSION >= 11) */
+} e_FmMacsecSecYCipherSuite;
+
+/**************************************************************************//**
+ @Description MACSEC SECY Exceptions
+*//***************************************************************************/
+typedef enum e_FmMacsecSecYExceptions {
+ e_FM_MACSEC_SECY_EX_FRAME_DISCARDED /**< Frame Discarded */
+} e_FmMacsecSecYExceptions;
+
+/**************************************************************************//**
+ @Description MACSEC SECY Events
+*//***************************************************************************/
+typedef enum e_FmMacsecSecYEvents {
+ e_FM_MACSEC_SECY_EV_NEXT_PN /**< Next Packet Number exhaustion threshold reached */
+} e_FmMacsecSecYEvents;
+
+/**************************************************************************//**
+ @Collection MACSEC SECY Frame Discarded Descriptor error
+*//***************************************************************************/
+typedef uint8_t macsecTxScFrameDiscardedErrSelect_t; /**< typedef for defining Frame Discarded Descriptor errors */
+
+#define FM_MACSEC_SECY_TX_SC_FRM_DISCAR_ERR_NEXT_PN_ZERO 0x8000 /**< NextPn == 0 */
+#define FM_MACSEC_SECY_TX_SC_FRM_DISCAR_ERR_SC_DISBALE 0x4000 /**< SC is disable */
+/* @} */
+
+/**************************************************************************//**
+ @Function t_FmMacsecSecYExceptionsCallback
+
+ @Description Exceptions user callback routine, will be called upon an
+ exception passing the exception identification.
+
+ @Param[in] h_App A handle to an application layer object; This handle
+ will be passed by the driver upon calling this callback.
+ @Param[in] exception The exception.
+*//***************************************************************************/
+typedef void (t_FmMacsecSecYExceptionsCallback) ( t_Handle h_App,
+ e_FmMacsecSecYExceptions exception);
+
+/**************************************************************************//**
+ @Function t_FmMacsecSecYEventsCallback
+
+ @Description Events user callback routine, will be called upon an
+ event passing the event identification.
+
+ @Param[in] h_App A handle to an application layer object; This handle
+ will be passed by the driver upon calling this callback.
+ @Param[in] event The event.
+*//***************************************************************************/
+typedef void (t_FmMacsecSecYEventsCallback) ( t_Handle h_App,
+ e_FmMacsecSecYEvents event);
+
+/**************************************************************************//**
+ @Description RFC2863 MIB
+*//***************************************************************************/
+typedef struct t_MIBStatistics {
+ uint64_t ifInOctets; /**< Total number of byte received */
+ uint64_t ifInPkts; /**< Total number of packets received */
+ uint64_t ifInMcastPkts; /**< Total number of multicast frame received */
+ uint64_t ifInBcastPkts; /**< Total number of broadcast frame received */
+ uint64_t ifInDiscards; /**< Frames received, but discarded due to problems within the MAC RX :
+ - InPktsNoTag,
+ - InPktsLate,
+ - InPktsOverrun */
+ uint64_t ifInErrors; /**< Number of frames received with error:
+ - InPktsBadTag,
+ - InPktsNoSCI,
+ - InPktsNotUsingSA
+ - InPktsNotValid */
+ uint64_t ifOutOctets; /**< Total number of byte sent */
+ uint64_t ifOutPkts; /**< Total number of packets sent */
+ uint64_t ifOutMcastPkts; /**< Total number of multicast frame sent */
+ uint64_t ifOutBcastPkts; /**< Total number of multicast frame sent */
+ uint64_t ifOutDiscards; /**< Frames received, but discarded due to problems within the MAC TX N/A! */
+ uint64_t ifOutErrors; /**< Number of frames transmitted with error:
+ - FIFO Overflow Error
+ - FIFO Underflow Error
+ - Other */
+} t_MIBStatistics;
+
+/**************************************************************************//**
+ @Description MACSEC SecY Rx SA Statistics
+*//***************************************************************************/
+typedef struct t_FmMacsecSecYRxSaStatistics {
+ uint32_t inPktsOK; /**< The number of frames with resolved SCI, have passed all
+ frame validation frame validation with the validateFrame not set to disable */
+ uint32_t inPktsInvalid; /**< The number of frames with resolved SCI, that have failed frame
+ validation with the validateFrame set to check */
+ uint32_t inPktsNotValid; /**< The number of frames with resolved SCI, discarded on the controlled port,
+ that have failed frame validation with the validateFrame set to strict or the c bit is set */
+ uint32_t inPktsNotUsingSA; /**< The number of frames received with resolved SCI and discarded on disabled or
+ not provisioned SA with validateFrame in the strict mode or the C bit is set */
+ uint32_t inPktsUnusedSA; /**< The number of frames received with resolved SCI on disabled or not provisioned SA
+ with validateFrame not in the strict mode and the C bit is cleared */
+} t_FmMacsecSecYRxSaStatistics;
+
+/**************************************************************************//**
+ @Description MACSEC SecY Tx SA Statistics
+*//***************************************************************************/
+typedef struct t_FmMacsecSecYTxSaStatistics {
+ uint64_t outPktsProtected; /**< The number of frames, that the user of the controlled port requested to
+ be transmitted, which were integrity protected */
+ uint64_t outPktsEncrypted; /**< The number of frames, that the user of the controlled port requested to
+ be transmitted, which were confidentiality protected */
+} t_FmMacsecSecYTxSaStatistics;
+
+/**************************************************************************//**
+ @Description MACSEC SecY Rx SC Statistics
+*//***************************************************************************/
+typedef struct t_FmMacsecSecYRxScStatistics {
+ uint64_t inPktsUnchecked; /**< The number of frames with resolved SCI, delivered to the user of a controlled port,
+ that are not validated with the validateFrame set to disable */
+ uint64_t inPktsDelayed; /**< The number of frames with resolved SCI, delivered to the user of a controlled port,
+ that have their PN smaller than the lowest_PN with the validateFrame set to
+ disable or replayProtect disabled */
+ uint64_t inPktsLate; /**< The number of frames with resolved SCI, discarded on the controlled port,
+ that have their PN smaller than the lowest_PN with the validateFrame set to
+ Check or Strict and replayProtect enabled */
+ uint64_t inPktsOK; /**< The number of frames with resolved SCI, have passed all
+ frame validation frame validation with the validateFrame not set to disable */
+ uint64_t inPktsInvalid; /**< The number of frames with resolved SCI, that have failed frame
+ validation with the validateFrame set to check */
+ uint64_t inPktsNotValid; /**< The number of frames with resolved SCI, discarded on the controlled port,
+ that have failed frame validation with the validateFrame set to strict or the c bit is set */
+ uint64_t inPktsNotUsingSA; /**< The number of frames received with resolved SCI and discarded on disabled or
+ not provisioned SA with validateFrame in the strict mode or the C bit is set */
+ uint64_t inPktsUnusedSA; /**< The number of frames received with resolved SCI on disabled or not provisioned SA
+ with validateFrame not in the strict mode and the C bit is cleared */
+} t_FmMacsecSecYRxScStatistics;
+
+/**************************************************************************//**
+ @Description MACSEC SecY Tx SC Statistics
+*//***************************************************************************/
+typedef struct t_FmMacsecSecYTxScStatistics {
+ uint64_t outPktsProtected; /**< The number of frames, that the user of the controlled port requested to
+ be transmitted, which were integrity protected */
+ uint64_t outPktsEncrypted; /**< The number of frames, that the user of the controlled port requested to
+ be transmitted, which were confidentiality protected */
+} t_FmMacsecSecYTxScStatistics;
+
+/**************************************************************************//**
+ @Description MACSEC SecY Statistics
+*//***************************************************************************/
+typedef struct t_FmMacsecSecYStatistics {
+ t_MIBStatistics mibCtrlStatistics; /**< Controlled port MIB statistics */
+ t_MIBStatistics mibNonCtrlStatistics; /**< Uncontrolled port MIB statistics */
+/* Frame verification statistics */
+ uint64_t inPktsUntagged; /**< The number of received packets without the MAC security tag
+ (SecTAG) with validateFrames which is not in the strict mode */
+ uint64_t inPktsNoTag; /**< The number of received packets discarded without the
+ MAC security tag (SecTAG) with validateFrames which is in the strict mode */
+ uint64_t inPktsBadTag; /**< The number of received packets discarded with an invalid
+ SecTAG or a zero value PN or an invalid ICV */
+ uint64_t inPktsUnknownSCI; /**< The number of received packets with unknown SCI with the
+ condition : validateFrames is not in the strict mode and the
+ C bit in the SecTAG is not set */
+ uint64_t inPktsNoSCI; /**< The number of received packets discarded with unknown SCI
+ information with the condition : validateFrames is in the strict mode
+ or the C bit in the SecTAG is set */
+ uint64_t inPktsOverrun; /**< The number of packets discarded because the number of
+ received packets exceeded the cryptographic performance capabilities */
+/* Frame validation statistics */
+ uint64_t inOctetsValidated; /**< The number of octets of plaintext recovered from received frames with
+ resolved SCI that were integrity protected but not encrypted */
+ uint64_t inOctetsDecrypted; /**< The number of octets of plaintext recovered from received frames with
+ resolved SCI that were integrity protected and encrypted */
+/* Frame generation statistics */
+ uint64_t outPktsUntagged; /**< The number of frames, that the user of the controlled port requested to
+ be transmitted, with protectFrame false */
+ uint64_t outPktsTooLong; /**< The number of frames, that the user of the controlled port requested to
+ be transmitted, discarded due to length being larger than Maximum Frame Length (MACSEC_MFL) */
+/* Frame protection statistics */
+ uint64_t outOctetsProtected; /**< The number of octets of User Data in transmitted frames that were
+ integrity protected but not encrypted */
+ uint64_t outOctetsEncrypted; /**< The number of octets of User Data in transmitted frames that were
+ both integrity protected and encrypted */
+} t_FmMacsecSecYStatistics;
+
+
+/**************************************************************************//**
+ @Description MACSEC SecY SC Params
+*//***************************************************************************/
+typedef struct t_FmMacsecSecYSCParams {
+ macsecSCI_t sci; /**< The secure channel identification of the SC */
+ e_FmMacsecSecYCipherSuite cipherSuite; /**< Cipher suite to be used for the SC */
+} t_FmMacsecSecYSCParams;
+
+/**************************************************************************//**
+ @Group FM_MACSEC_SECY_init_grp FM-MACSEC SecY Initialization Unit
+
+ @Description FM-MACSEC SecY Initialization Unit
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Description enum for validate frames
+*//***************************************************************************/
+typedef enum e_FmMacsecValidFrameBehavior {
+ e_FM_MACSEC_VALID_FRAME_BEHAVIOR_DISABLE = 0, /**< disable the validation function */
+ e_FM_MACSEC_VALID_FRAME_BEHAVIOR_CHECK, /**< enable the validation function but only for checking
+ without filtering out invalid frames */
+ e_FM_MACSEC_VALID_FRAME_BEHAVIOR_STRICT /**< enable the validation function and also strictly filter
+ out those invalid frames */
+} e_FmMacsecValidFrameBehavior;
+
+/**************************************************************************//**
+ @Description enum for sci insertion
+*//***************************************************************************/
+typedef enum e_FmMacsecSciInsertionMode {
+ e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG = 0, /**< explicit sci in the sectag */
+ e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_MAC_SA, /**< mac sa is overwritten with the sci*/
+ e_FM_MACSEC_SCI_INSERTION_MODE_IMPLICT_PTP /**< implicit point-to-point sci (pre-shared) */
+} e_FmMacsecSciInsertionMode;
+
+/**************************************************************************//**
+ @Description FM MACSEC SecY config input
+*//***************************************************************************/
+typedef struct t_FmMacsecSecYParams {
+ t_Handle h_FmMacsec; /**< A handle to the FM MACSEC object */
+ t_FmMacsecSecYSCParams txScParams; /**< Tx SC Params */
+ uint32_t numReceiveChannels; /**< Number of receive channels dedicated to this SecY */
+ t_FmMacsecSecYExceptionsCallback *f_Exception; /**< Callback routine to be called by the driver upon SecY exception */
+ t_FmMacsecSecYEventsCallback *f_Event; /**< Callback routine to be called by the driver upon SecY event */
+ t_Handle h_App; /**< A handle to an application layer object; This handle will
+ be passed by the driver upon calling the above callbacks */
+} t_FmMacsecSecYParams;
+
+/**************************************************************************//**
+ @Function FM_MACSEC_SECY_Config
+
+ @Description Creates descriptor for the FM MACSEC SECY module;
+
+ The routine returns a handle (descriptor) to the FM MACSEC SECY object;
+ This descriptor must be passed as first parameter to all other
+ FM MACSEC SECY function calls;
+ No actual initialization or configuration of FM MACSEC SecY hardware is
+ done by this routine.
+
+ @Param[in] p_FmMacsecSecYParam Pointer to data structure of parameters.
+
+ @Return Handle to FM MACSEC SECY object, or NULL for Failure.
+*//***************************************************************************/
+t_Handle FM_MACSEC_SECY_Config(t_FmMacsecSecYParams *p_FmMacsecSecYParam);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_SECY_Init
+
+ @Description Initializes the FM MACSEC SECY module.
+
+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
+
+ @Return E_OK on success; Error code otherwise.
+*//***************************************************************************/
+t_Error FM_MACSEC_SECY_Init(t_Handle h_FmMacsecSecY);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_SECY_Free
+
+ @Description Frees all resources that were assigned to FM MACSEC SECY module.
+
+ Calling this routine invalidates the descriptor.
+
+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
+
+ @Return E_OK on success; Error code otherwise.
+*//***************************************************************************/
+t_Error FM_MACSEC_SECY_Free(t_Handle h_FmMacsecSecY);
+
+/**************************************************************************//**
+ @Group FM_MACSEC_SECY_advanced_init_grp FM-MACSEC SecY Advanced Configuration Unit
+
+ @Description Configuration functions used to change default values.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Function FM_MACSEC_SECY_ConfigSciInsertionMode
+
+ @Description Calling this routine changes the SCI-insertion-mode in the
+ internal driver data base from its default configuration
+ [DEFAULT_sciInsertionMode]
+
+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
+ @Param[in] sciInsertionMode Sci insertion mode
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
+
+*//***************************************************************************/
+t_Error FM_MACSEC_SECY_ConfigSciInsertionMode(t_Handle h_FmMacsecSecY, e_FmMacsecSciInsertionMode sciInsertionMode);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_SECY_ConfigProtectFrames
+
+ @Description Calling this routine changes the protect-frame mode in the
+ internal driver data base from its default configuration
+ [DEFAULT_protectFrames]
+
+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
+ @Param[in] protectFrames If FALSE, frames are transmitted without modification
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
+
+*//***************************************************************************/
+t_Error FM_MACSEC_SECY_ConfigProtectFrames(t_Handle h_FmMacsecSecY, bool protectFrames);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_SECY_ConfigReplayWindow
+
+ @Description Calling this routine changes the replay-window settings in the
+ internal driver data base from its default configuration
+ [DEFAULT_replayEnable], [DEFAULT_replayWindow]
+
+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
+ @Param[in] replayProtect; Replay protection function mode
+ @Param[in] replayWindow; The size of the replay window
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
+
+*//***************************************************************************/
+t_Error FM_MACSEC_SECY_ConfigReplayWindow(t_Handle h_FmMacsecSecY, bool replayProtect, uint32_t replayWindow);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_SECY_ConfigValidationMode
+
+ @Description Calling this routine changes the frame-validation-behavior mode
+ in the internal driver data base from its default configuration
+ [DEFAULT_validateFrames]
+
+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
+ @Param[in] validateFrames Validation function mode
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
+
+*//***************************************************************************/
+t_Error FM_MACSEC_SECY_ConfigValidationMode(t_Handle h_FmMacsecSecY, e_FmMacsecValidFrameBehavior validateFrames);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_SECY_ConfigConfidentiality
+
+ @Description Calling this routine changes the confidentiality settings in the
+ internal driver data base from its default configuration
+ [DEFAULT_confidentialityEnable], [DEFAULT_confidentialityOffset]
+
+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
+ @Param[in] confidentialityEnable TRUE - confidentiality protection and integrity protection
+ FALSE - no confidentiality protection, only integrity protection
+ @Param[in] confidentialityOffset The number of initial octets of each MSDU without confidentiality protection
+ common values are 0, 30, and 50
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
+
+*//***************************************************************************/
+t_Error FM_MACSEC_SECY_ConfigConfidentiality(t_Handle h_FmMacsecSecY, bool confidentialityEnable, uint16_t confidentialityOffset);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_SECY_ConfigPointToPoint
+
+ @Description configure this SecY to work in point-to-point mode, means that
+ it will have only one rx sc;
+
+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
+ Can be called only once in a system; only the first secY that will call this
+ routine will be able to operate in Point-To-Point mode.
+*//***************************************************************************/
+t_Error FM_MACSEC_SECY_ConfigPointToPoint(t_Handle h_FmMacsecSecY);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_SECY_ConfigException
+
+ @Description Calling this routine changes the internal driver data base
+ from its default selection of exceptions enablement;
+ By default all exceptions are enabled.
+
+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
+ @Param[in] exception The exception to be selected.
+ @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init().
+*//***************************************************************************/
+t_Error FM_MACSEC_SECY_ConfigException(t_Handle h_FmMacsecSecY, e_FmMacsecSecYExceptions exception, bool enable);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_SECY_ConfigEvent
+
+ @Description Calling this routine changes the internal driver data base
+ from its default selection of events enablement;
+ By default all events are enabled.
+
+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
+ @Param[in] event The event to be selected.
+ @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init().
+*//***************************************************************************/
+t_Error FM_MACSEC_SECY_ConfigEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable);
+
+/** @} */ /* end of FM_MACSEC_SECY_advanced_init_grp group */
+/** @} */ /* end of FM_MACSEC_SECY_init_grp group */
+
+
+/**************************************************************************//**
+ @Group FM_MACSEC_SECY_runtime_control_grp FM-MACSEC SecY Runtime Control Unit
+
+ @Description FM MACSEC SECY Runtime control unit API functions, definitions and enums.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Function FM_MACSEC_SECY_CreateRxSc
+
+ @Description Create a receive secure channel.
+
+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
+ @Param[in] scParams secure channel params.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_SECY_Init().
+*//***************************************************************************/
+t_Handle FM_MACSEC_SECY_CreateRxSc(t_Handle h_FmMacsecSecY, t_FmMacsecSecYSCParams *p_ScParams);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_SECY_DeleteRxSc
+
+ @Description Deleting an initialized secure channel.
+
+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
+ @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSc().
+*//***************************************************************************/
+t_Error FM_MACSEC_SECY_DeleteRxSc(t_Handle h_FmMacsecSecY, t_Handle h_Sc);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_SECY_CreateRxSa
+
+ @Description Create a receive secure association for the secure channel;
+ the SA cannot be used to receive frames until FM_MACSEC_SECY_RxSaEnableReceive is called.
+
+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
+ @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
+ @Param[in] an association number represent the SA.
+ @Param[in] lowestPn the lowest acceptable PN value for a received frame.
+ @Param[in] key the desired key for this SA.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSc().
+*//***************************************************************************/
+t_Error FM_MACSEC_SECY_CreateRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_SECY_DeleteRxSa
+
+ @Description Deleting an initialized secure association.
+
+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
+ @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
+ @Param[in] an association number represent the SA.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_SECY_Init().
+*//***************************************************************************/
+t_Error FM_MACSEC_SECY_DeleteRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_SECY_RxSaEnableReceive
+
+ @Description Enabling the SA to receive frames.
+
+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
+ @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
+ @Param[in] an association number represent the SA.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
+*//***************************************************************************/
+t_Error FM_MACSEC_SECY_RxSaEnableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_SECY_RxSaDisableReceive
+
+ @Description Disabling the SA from receive frames.
+
+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
+ @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
+ @Param[in] an association number represent the SA.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
+*//***************************************************************************/
+t_Error FM_MACSEC_SECY_RxSaDisableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_SECY_RxSaUpdateNextPn
+
+ @Description Update the next packet number expected on RX;
+ The value of nextPN shall be set to the greater of its existing value and the
+ supplied of updtNextPN (802.1AE-2006 10.7.15).
+
+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
+ @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
+ @Param[in] an association number represent the SA.
+ @Param[in] updtNextPN the next PN value for a received frame.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
+*//***************************************************************************/
+t_Error FM_MACSEC_SECY_RxSaUpdateNextPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtNextPN);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_SECY_RxSaUpdateLowestPn
+
+ @Description Update the lowest packet number expected on RX;
+ The value of lowestPN shall be set to the greater of its existing value and the
+ supplied of updtLowestPN (802.1AE-2006 10.7.15).
+
+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
+ @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
+ @Param[in] an association number represent the SA.
+ @Param[in] updtLowestPN the lowest PN acceptable value for a received frame.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
+*//***************************************************************************/
+t_Error FM_MACSEC_SECY_RxSaUpdateLowestPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtLowestPN);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_SECY_RxSaModifyKey
+
+ @Description Modify the current key of the SA with a new one.
+
+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
+ @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
+ @Param[in] an association number represent the SA.
+ @Param[in] key new key to replace the current key.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
+*//***************************************************************************/
+t_Error FM_MACSEC_SECY_RxSaModifyKey(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, macsecSAKey_t key);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_SECY_CreateTxSa
+
+ @Description Create a transmit secure association for the secure channel;
+ the SA cannot be used to transmit frames until FM_MACSEC_SECY_TxSaSetActivate is called;
+ Only one SA can be active at a time.
+
+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
+ @Param[in] an association number represent the SA.
+ @Param[in] key the desired key for this SA.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_SECY_Init().
+*//***************************************************************************/
+t_Error FM_MACSEC_SECY_CreateTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an, macsecSAKey_t key);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_SECY_DeleteTxSa
+
+ @Description Deleting an initialized secure association.
+
+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
+ @Param[in] an association number represent the SA.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_SECY_Init().
+*//***************************************************************************/
+t_Error FM_MACSEC_SECY_DeleteTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_SECY_TxSaModifyKey
+
+ @Description Modify the key of the inactive SA with a new one.
+
+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
+ @Param[in] nextActiveAn association number represent the next SA to be activated.
+ @Param[in] key new key to replace the current key.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_SECY_Init().
+*//***************************************************************************/
+t_Error FM_MACSEC_SECY_TxSaModifyKey(t_Handle h_FmMacsecSecY, macsecAN_t nextActiveAn, macsecSAKey_t key);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_SECY_TxSaSetActive
+
+ @Description Set this SA to the active SA to be used on TX for SC;
+ only one SA can be active at a time.
+
+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
+ @Param[in] an association number represent the SA.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_SECY_Init().
+*//***************************************************************************/
+t_Error FM_MACSEC_SECY_TxSaSetActive(t_Handle h_FmMacsecSecY, macsecAN_t an);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_SECY_TxSaGetActive
+
+ @Description Get the active SA that being used for TX.
+
+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
+ @Param[out] p_An the active an.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_SECY_Init().
+*//***************************************************************************/
+t_Error FM_MACSEC_SECY_TxSaGetActive(t_Handle h_FmMacsecSecY, macsecAN_t *p_An);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_SECY_GetStatistics
+
+ @Description get all statistics counters.
+
+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
+ @Param[in] p_Statistics Structure with statistics.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_SECY_Init().
+*//***************************************************************************/
+t_Error FM_MACSEC_SECY_GetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYStatistics *p_Statistics);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_SECY_RxScGetStatistics
+
+ @Description get all statistics counters.
+
+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
+ @Param[in] h_Sc Rx Sc handle.
+ @Param[in] p_Statistics Structure with statistics.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_SECY_Init().
+*//***************************************************************************/
+t_Error FM_MACSEC_SECY_RxScGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, t_FmMacsecSecYRxScStatistics *p_Statistics);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_SECY_RxSaGetStatistics
+
+ @Description get all statistics counters
+
+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
+ @Param[in] h_Sc Rx Sc handle.
+ @Param[in] an association number represent the SA.
+ @Param[in] p_Statistics Structure with statistics.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_SECY_Init().
+*//***************************************************************************/
+t_Error FM_MACSEC_SECY_RxSaGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, t_FmMacsecSecYRxSaStatistics *p_Statistics);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_SECY_TxScGetStatistics
+
+ @Description get all statistics counters.
+
+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
+ @Param[in] p_Statistics Structure with statistics.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_SECY_Init().
+*//***************************************************************************/
+t_Error FM_MACSEC_SECY_TxScGetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYTxScStatistics *p_Statistics);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_SECY_TxSaGetStatistics
+
+ @Description get all statistics counters.
+
+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
+ @Param[in] an association number represent the SA.
+ @Param[in] p_Statistics Structure with statistics.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_SECY_Init().
+*//***************************************************************************/
+t_Error FM_MACSEC_SECY_TxSaGetStatistics(t_Handle h_FmMacsecSecY, macsecAN_t an, t_FmMacsecSecYTxSaStatistics *p_Statistics);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_SECY_SetException
+
+ @Description Calling this routine enables/disables the specified exception.
+
+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
+ @Param[in] exception The exception to be selected.
+ @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_SECY_Init().
+*//***************************************************************************/
+t_Error FM_MACSEC_SECY_SetException(t_Handle h_FmMacsecSecY, e_FmMacsecExceptions exception, bool enable);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_SECY_SetEvent
+
+ @Description Calling this routine enables/disables the specified event.
+
+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
+ @Param[in] event The event to be selected.
+ @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init().
+*//***************************************************************************/
+t_Error FM_MACSEC_SECY_SetEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_SECY_GetRxScPhysId
+
+ @Description return the physical id of the Secure Channel.
+
+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
+ @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
+ @Param[out] p_ScPhysId the SC physical id.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSc().
+*//***************************************************************************/
+t_Error FM_MACSEC_SECY_GetRxScPhysId(t_Handle h_FmMacsecSecY, t_Handle h_Sc, uint32_t *p_ScPhysId);
+
+/**************************************************************************//**
+ @Function FM_MACSEC_SECY_GetTxScPhysId
+
+ @Description return the physical id of the Secure Channel.
+
+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
+ @Param[out] p_ScPhysId the SC physical id.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MACSEC_SECY_Init().
+*//***************************************************************************/
+t_Error FM_MACSEC_SECY_GetTxScPhysId(t_Handle h_FmMacsecSecY, uint32_t *p_ScPhysId);
+
+/** @} */ /* end of FM_MACSEC_SECY_runtime_control_grp group */
+/** @} */ /* end of FM_MACSEC_SECY_grp group */
+/** @} */ /* end of FM_MACSEC_grp group */
+/** @} */ /* end of FM_grp group */
+
+
+#endif /* __FM_MACSEC_EXT_H */
diff --git a/drivers/net/ethernet/freescale/fman/inc/enet_ext.h b/drivers/net/ethernet/freescale/fman/inc/enet_ext.h
index c6b9071..ef3bee5 100644
--- a/drivers/net/ethernet/freescale/fman/inc/enet_ext.h
+++ b/drivers/net/ethernet/freescale/fman/inc/enet_ext.h
@@ -104,6 +104,7 @@ typedef enum e_EnetSpeed
e_ENET_SPEED_10 = E_ENET_SPEED_10, /**< 10 Mbps */
e_ENET_SPEED_100 = E_ENET_SPEED_100, /**< 100 Mbps */
e_ENET_SPEED_1000 = E_ENET_SPEED_1000, /**< 1000 Mbps = 1 Gbps */
+ e_ENET_SPEED_2500 = E_ENET_SPEED_2500, /**< 2500 Mbps = 2.5 Gbps */
e_ENET_SPEED_10000 = E_ENET_SPEED_10000 /**< 10000 Mbps = 10 Gbps */
} e_EnetSpeed;
@@ -134,6 +135,7 @@ typedef enum e_EnetMode
e_ENET_MODE_SGMII_1000 = (e_ENET_IF_SGMII | e_ENET_SPEED_1000),
/**< 1000 Mbps SGMII with auto-negotiation between MAC and
SGMII phy according to Cisco SGMII specification */
+ e_ENET_MODE_SGMII_2500 = (e_ENET_IF_SGMII | e_ENET_SPEED_2500),
e_ENET_MODE_SGMII_BASEX_10 = (ENET_IF_SGMII_BASEX | e_ENET_IF_SGMII | e_ENET_SPEED_10),
/**< 10 Mbps SGMII with 1000BaseX auto-negotiation between
MAC and SGMII phy or backplane */
diff --git a/drivers/net/ethernet/freescale/fman/inc/flib/fsl_enet.h b/drivers/net/ethernet/freescale/fman/inc/flib/fsl_enet.h
index dde6a4e..caa87fc 100644
--- a/drivers/net/ethernet/freescale/fman/inc/flib/fsl_enet.h
+++ b/drivers/net/ethernet/freescale/fman/inc/flib/fsl_enet.h
@@ -58,6 +58,7 @@ enum enet_speed {
E_ENET_SPEED_10 = 10, /**< 10 Mbps */
E_ENET_SPEED_100 = 100, /**< 100 Mbps */
E_ENET_SPEED_1000 = 1000, /**< 1000 Mbps = 1 Gbps */
+ E_ENET_SPEED_2500 = 2500, /**< 2500 Mbps = 2.5 Gbps */
E_ENET_SPEED_10000 = 10000 /**< 10000 Mbps = 10 Gbps */
};
diff --git a/drivers/net/ethernet/freescale/fman/inc/integrations/P3040_P4080_P5020/dpaa_integration_ext.h b/drivers/net/ethernet/freescale/fman/inc/integrations/P3040_P4080_P5020/dpaa_integration_ext.h
index 257acb0..f4e5980 100644
--- a/drivers/net/ethernet/freescale/fman/inc/integrations/P3040_P4080_P5020/dpaa_integration_ext.h
+++ b/drivers/net/ethernet/freescale/fman/inc/integrations/P3040_P4080_P5020/dpaa_integration_ext.h
@@ -263,4 +263,14 @@ typedef enum
#define FM_NO_CTXA_COPY_ERRATA_FMAN_SW001
#define FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004
+/*****************************************************************************
+ FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS
+******************************************************************************/
+#define NUM_OF_RX_SC 16
+#define NUM_OF_TX_SC 16
+
+#define NUM_OF_SA_PER_RX_SC 2
+#define NUM_OF_SA_PER_TX_SC 2
+
+
#endif /* __DPAA_INTEGRATION_EXT_H */
diff --git a/drivers/net/ethernet/freescale/fman/inc/integrations/T4240/dpaa_integration_ext.h b/drivers/net/ethernet/freescale/fman/inc/integrations/T4240/dpaa_integration_ext.h
index 2fb5527..58fa5d7 100644
--- a/drivers/net/ethernet/freescale/fman/inc/integrations/T4240/dpaa_integration_ext.h
+++ b/drivers/net/ethernet/freescale/fman/inc/integrations/T4240/dpaa_integration_ext.h
@@ -291,4 +291,13 @@ typedef enum
/* RMan erratas */
#define RM_ERRONEOUS_ACK_ERRATA_RMAN_A006756
+/*****************************************************************************
+ FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS
+******************************************************************************/
+#define NUM_OF_RX_SC 16
+#define NUM_OF_TX_SC 16
+
+#define NUM_OF_SA_PER_RX_SC 2
+#define NUM_OF_SA_PER_TX_SC 2
+
#endif /* __DPAA_INTEGRATION_EXT_H */
diff --git a/drivers/net/ethernet/freescale/fman/inc/xx_common.h b/drivers/net/ethernet/freescale/fman/inc/xx_common.h
index 1c45177..8e81094 100644
--- a/drivers/net/ethernet/freescale/fman/inc/xx_common.h
+++ b/drivers/net/ethernet/freescale/fman/inc/xx_common.h
@@ -52,5 +52,5 @@
#define MODULE_FM_PORT 0x00060000
#define MODULE_MM 0x00070000
#define MODULE_FM_SP 0x00080000
-
+#define MODULE_FM_MACSEC 0x00090000
#endif /* __XX_COMMON_H */
diff --git a/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_fm.c b/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_fm.c
index d7f94ab..67e64d0 100755
--- a/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_fm.c
+++ b/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_fm.c
@@ -156,11 +156,13 @@ int fm_get_max_frm()
{
return fsl_fm_max_frm;
}
+EXPORT_SYMBOL(fm_get_max_frm);
int fm_get_rx_extra_headroom()
{
return ALIGN(fsl_fm_rx_extra_headroom, 16);
}
+EXPORT_SYMBOL(fm_get_rx_extra_headroom);
static int __init fm_set_max_frm(char *str)
{
diff --git a/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_ioctls_fm.c b/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_ioctls_fm.c
index 75c628a..ffa1a2d 100644
--- a/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_ioctls_fm.c
+++ b/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_ioctls_fm.c
@@ -1957,62 +1957,138 @@ invalid_port_id:
#if defined(CONFIG_COMPAT)
+ case FM_PCD_IOC_MATCH_TABLE_GET_KEY_STAT_COMPAT:
+#endif
+ case FM_PCD_IOC_MATCH_TABLE_GET_KEY_STAT:
+ {
+ ioc_fm_pcd_cc_tbl_get_stats_t param;
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
+
+ compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t *) XX_Malloc(
+ sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
+ if (!compat_param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
+ if (copy_from_user(compat_param,
+ (ioc_compat_fm_pcd_cc_tbl_get_stats_t *)compat_ptr(arg),
+ sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t)))
+ {
+ XX_Free(compat_param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_US_TO_K);
+
+ XX_Free(compat_param);
+ }
+ else
+#endif
+ {
+ if (copy_from_user(&param, (ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
+ sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+
+ err = FM_PCD_MatchTableGetKeyStatistics((t_Handle) param.id,
+ param.key_index,
+ (t_FmPcdCcKeyStatistics *) &param.statistics);
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
+
+ compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t*) XX_Malloc(
+ sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
+ if (!compat_param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
+ compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_K_TO_US);
+ if (copy_to_user((ioc_compat_fm_pcd_cc_tbl_get_stats_t*) compat_ptr(arg),
+ compat_param,
+ sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t))){
+ XX_Free(compat_param);
+ RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
+ }
+ XX_Free(compat_param);
+ }
+ else
+#endif
+ {
+ if (copy_to_user((ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
+ &param,
+ sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
+ RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
+ }
+
+ break;
+ }
+
+
+#if defined(CONFIG_COMPAT)
case FM_PCD_IOC_MATCH_TABLE_GET_MISS_STAT_COMPAT:
#endif
case FM_PCD_IOC_MATCH_TABLE_GET_MISS_STAT:
{
- ioc_fm_pcd_cc_tbl_get_miss_params_t param;
+ ioc_fm_pcd_cc_tbl_get_stats_t param;
#if defined(CONFIG_COMPAT)
if (compat)
{
- ioc_compat_fm_pcd_cc_tbl_get_miss_params_t *compat_param;
+ ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
- compat_param = (ioc_compat_fm_pcd_cc_tbl_get_miss_params_t *) XX_Malloc(
- sizeof(ioc_compat_fm_pcd_cc_tbl_get_miss_params_t));
+ compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t *) XX_Malloc(
+ sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
if (!compat_param)
RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
- memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_miss_params_t));
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
if (copy_from_user(compat_param,
- (ioc_compat_fm_pcd_cc_tbl_get_miss_params_t *)compat_ptr(arg),
- sizeof(ioc_compat_fm_pcd_cc_tbl_get_miss_params_t)))
+ (ioc_compat_fm_pcd_cc_tbl_get_stats_t *)compat_ptr(arg),
+ sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t)))
{
XX_Free(compat_param);
RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
}
- compat_copy_fm_pcd_cc_tbl_get_miss(compat_param, &param, COMPAT_US_TO_K);
+ compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_US_TO_K);
XX_Free(compat_param);
}
else
#endif
{
- if (copy_from_user(&param, (ioc_fm_pcd_cc_tbl_get_miss_params_t *)arg,
- sizeof(ioc_fm_pcd_cc_tbl_get_miss_params_t)))
+ if (copy_from_user(&param, (ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
+ sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
}
err = FM_PCD_MatchTableGetMissStatistics((t_Handle) param.id,
- (t_FmPcdCcKeyStatistics *) &param.miss_statistics);
+ (t_FmPcdCcKeyStatistics *) &param.statistics);
#if defined(CONFIG_COMPAT)
if (compat)
{
- ioc_compat_fm_pcd_cc_tbl_get_miss_params_t *compat_param;
+ ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
- compat_param = (ioc_compat_fm_pcd_cc_tbl_get_miss_params_t*) XX_Malloc(
- sizeof(ioc_compat_fm_pcd_cc_tbl_get_miss_params_t));
+ compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t*) XX_Malloc(
+ sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
if (!compat_param)
RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
- memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_miss_params_t));
- compat_copy_fm_pcd_cc_tbl_get_miss(compat_param, &param, COMPAT_K_TO_US);
- if (copy_to_user((ioc_compat_fm_pcd_cc_tbl_get_miss_params_t*) compat_ptr(arg),
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
+ compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_K_TO_US);
+ if (copy_to_user((ioc_compat_fm_pcd_cc_tbl_get_stats_t*) compat_ptr(arg),
compat_param,
- sizeof(ioc_compat_fm_pcd_cc_tbl_get_miss_params_t))){
+ sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t))){
XX_Free(compat_param);
RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
}
@@ -2021,9 +2097,9 @@ invalid_port_id:
else
#endif
{
- if (copy_to_user((ioc_fm_pcd_hash_table_params_t *)arg,
+ if (copy_to_user((ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
&param,
- sizeof(ioc_fm_pcd_cc_tbl_get_miss_params_t)))
+ sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
}
@@ -2036,58 +2112,58 @@ invalid_port_id:
#endif
case FM_PCD_IOC_HASH_TABLE_GET_MISS_STAT:
{
- ioc_fm_pcd_cc_tbl_get_miss_params_t param;
+ ioc_fm_pcd_cc_tbl_get_stats_t param;
#if defined(CONFIG_COMPAT)
if (compat)
{
- ioc_compat_fm_pcd_cc_tbl_get_miss_params_t *compat_param;
+ ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
- compat_param = (ioc_compat_fm_pcd_cc_tbl_get_miss_params_t *) XX_Malloc(
- sizeof(ioc_compat_fm_pcd_cc_tbl_get_miss_params_t));
+ compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t *) XX_Malloc(
+ sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
if (!compat_param)
RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
- memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_miss_params_t));
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
if (copy_from_user(compat_param,
- (ioc_compat_fm_pcd_cc_tbl_get_miss_params_t *)compat_ptr(arg),
- sizeof(ioc_compat_fm_pcd_cc_tbl_get_miss_params_t)))
+ (ioc_compat_fm_pcd_cc_tbl_get_stats_t *)compat_ptr(arg),
+ sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t)))
{
XX_Free(compat_param);
RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
}
- compat_copy_fm_pcd_cc_tbl_get_miss(compat_param, &param, COMPAT_US_TO_K);
+ compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_US_TO_K);
XX_Free(compat_param);
}
else
#endif
{
- if (copy_from_user(&param, (ioc_fm_pcd_cc_tbl_get_miss_params_t *)arg,
- sizeof(ioc_fm_pcd_cc_tbl_get_miss_params_t)))
+ if (copy_from_user(&param, (ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
+ sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
}
err = FM_PCD_HashTableGetMissStatistics((t_Handle) param.id,
- (t_FmPcdCcKeyStatistics *) &param.miss_statistics);
+ (t_FmPcdCcKeyStatistics *) &param.statistics);
#if defined(CONFIG_COMPAT)
if (compat)
{
- ioc_compat_fm_pcd_cc_tbl_get_miss_params_t *compat_param;
+ ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
- compat_param = (ioc_compat_fm_pcd_cc_tbl_get_miss_params_t*) XX_Malloc(
- sizeof(ioc_compat_fm_pcd_cc_tbl_get_miss_params_t));
+ compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t*) XX_Malloc(
+ sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
if (!compat_param)
RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
- memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_miss_params_t));
- compat_copy_fm_pcd_cc_tbl_get_miss(compat_param, &param, COMPAT_K_TO_US);
- if (copy_to_user((ioc_compat_fm_pcd_cc_tbl_get_miss_params_t*) compat_ptr(arg),
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
+ compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_K_TO_US);
+ if (copy_to_user((ioc_compat_fm_pcd_cc_tbl_get_stats_t*) compat_ptr(arg),
compat_param,
- sizeof(ioc_compat_fm_pcd_cc_tbl_get_miss_params_t))){
+ sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t))){
XX_Free(compat_param);
RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
}
@@ -2096,9 +2172,9 @@ invalid_port_id:
else
#endif
{
- if (copy_to_user((ioc_fm_pcd_hash_table_params_t *)arg,
+ if (copy_to_user((ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
&param,
- sizeof(ioc_fm_pcd_cc_tbl_get_miss_params_t)))
+ sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
}
diff --git a/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_ioctls_fm_compat.c b/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_ioctls_fm_compat.c
index 76e5c4d..b5ffe5c 100644
--- a/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_ioctls_fm_compat.c
+++ b/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_ioctls_fm_compat.c
@@ -849,18 +849,20 @@ void compat_copy_fm_port_vsp_alloc_params(
}
#endif /* (DPAA_VERSION >= 11) */
-void compat_copy_fm_pcd_cc_tbl_get_miss(
- ioc_compat_fm_pcd_cc_tbl_get_miss_params_t *compat_param,
- ioc_fm_pcd_cc_tbl_get_miss_params_t *param,
+void compat_copy_fm_pcd_cc_tbl_get_stats(
+ ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param,
+ ioc_fm_pcd_cc_tbl_get_stats_t *param,
uint8_t compat)
{
if (compat == COMPAT_US_TO_K)
{
param->id = compat_pcd_id2ptr(compat_param->id);
- memcpy(&param->miss_statistics, &compat_param->miss_statistics, sizeof(ioc_fm_pcd_cc_key_statistics_t));
+ param->key_index = compat_param->key_index;
+ memcpy(&param->statistics, &compat_param->statistics, sizeof(ioc_fm_pcd_cc_key_statistics_t));
} else {
compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
- memcpy(&compat_param->miss_statistics, &param->miss_statistics, sizeof(ioc_fm_pcd_cc_key_statistics_t));
+ compat_param->key_index = param->key_index;
+ memcpy(&compat_param->statistics, &param->statistics, sizeof(ioc_fm_pcd_cc_key_statistics_t));
}
}
diff --git a/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_ioctls_fm_compat.h b/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_ioctls_fm_compat.h
index 7340396..d89a64d 100644
--- a/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_ioctls_fm_compat.h
+++ b/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_ioctls_fm_compat.h
@@ -544,10 +544,11 @@ typedef struct ioc_compat_fm_ctrl_mon_counters_params_t {
compat_uptr_t p_mon;
} ioc_compat_fm_ctrl_mon_counters_params_t;
-typedef struct ioc_compat_fm_pcd_cc_tbl_get_miss_params_t {
+typedef struct ioc_compat_fm_pcd_cc_tbl_get_stats_t {
compat_uptr_t id;
- ioc_fm_pcd_cc_key_statistics_t miss_statistics;
-} ioc_compat_fm_pcd_cc_tbl_get_miss_params_t;
+ uint16_t key_index;
+ ioc_fm_pcd_cc_key_statistics_t statistics;
+} ioc_compat_fm_pcd_cc_tbl_get_stats_t;
/* } pcd compat structures */
@@ -597,9 +598,9 @@ void compat_copy_fm_pcd_cc_tree(
ioc_fm_pcd_cc_tree_params_t *param,
uint8_t compat);
-void compat_copy_fm_pcd_cc_tbl_get_miss(
- ioc_compat_fm_pcd_cc_tbl_get_miss_params_t *compat_param,
- ioc_fm_pcd_cc_tbl_get_miss_params_t *param,
+void compat_copy_fm_pcd_cc_tbl_get_stats(
+ ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param,
+ ioc_fm_pcd_cc_tbl_get_stats_t *param,
uint8_t compat);
void compat_fm_pcd_prs_sw(
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
index 38cd3f2..406d0f0 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -198,7 +198,7 @@ static int gfar_init_bds(struct net_device *ndev)
struct gfar_priv_rx_q *rx_queue = NULL;
struct txbd8 *txbdp;
struct rxbd8 *rxbdp;
- u32 *rfbptr;
+ u32 __iomem *rfbptr;
int i, j;
for (i = 0; i < priv->num_tx_queues; i++) {
@@ -392,7 +392,7 @@ static void gfar_init_rqprm(struct gfar_private *priv)
static void gfar_rx_buff_size_config(struct gfar_private *priv)
{
- int frame_size = priv->ndev->mtu + ETH_HLEN;
+ int frame_size = priv->ndev->mtu + ETH_HLEN + ETH_FCS_LEN;
/* set this when rx hw offload (TOE) functions are being used */
priv->uses_rxfcb = 0;
@@ -601,22 +601,6 @@ static void gfar_ints_enable(struct gfar_private *priv)
}
}
-void lock_tx_qs(struct gfar_private *priv)
-{
- int i;
-
- for (i = 0; i < priv->num_tx_queues; i++)
- spin_lock(&priv->tx_queue[i]->txlock);
-}
-
-void unlock_tx_qs(struct gfar_private *priv)
-{
- int i;
-
- for (i = 0; i < priv->num_tx_queues; i++)
- spin_unlock(&priv->tx_queue[i]->txlock);
-}
-
static int gfar_alloc_tx_queues(struct gfar_private *priv)
{
int i;
@@ -816,7 +800,7 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev)
unsigned int num_tx_qs, num_rx_qs;
unsigned short mode, poll_mode;
- if (!np || !of_device_is_available(np))
+ if (!np)
return -ENODEV;
if (of_device_is_compatible(np, "fsl,etsec2")) {
@@ -3432,8 +3416,8 @@ static void adjust_link(struct net_device *dev)
struct phy_device *phydev = priv->phydev;
if (unlikely(phydev->link != priv->oldlink ||
- phydev->duplex != priv->oldduplex ||
- phydev->speed != priv->oldspeed))
+ (phydev->link && (phydev->duplex != priv->oldduplex ||
+ phydev->speed != priv->oldspeed))))
gfar_update_link_state(priv);
}
diff --git a/drivers/net/ethernet/freescale/gianfar.h b/drivers/net/ethernet/freescale/gianfar.h
index c1130ca..262e896 100644
--- a/drivers/net/ethernet/freescale/gianfar.h
+++ b/drivers/net/ethernet/freescale/gianfar.h
@@ -1249,7 +1249,7 @@ struct gfar_priv_rx_q {
/* RX Coalescing values */
unsigned char rxcoalescing;
unsigned long rxic;
- u32 *rfbptr;
+ u32 __iomem *rfbptr;
};
enum gfar_irqinfo_id {
diff --git a/drivers/net/ethernet/freescale/gianfar_ethtool.c b/drivers/net/ethernet/freescale/gianfar_ethtool.c
index 3f6c6ec..96edd33 100644
--- a/drivers/net/ethernet/freescale/gianfar_ethtool.c
+++ b/drivers/net/ethernet/freescale/gianfar_ethtool.c
@@ -1618,7 +1618,7 @@ static int gfar_write_filer_table(struct gfar_private *priv,
return -EBUSY;
/* Fill regular entries */
- for (; i < MAX_FILER_IDX - 1 && (tab->fe[i].ctrl | tab->fe[i].ctrl);
+ for (; i < MAX_FILER_IDX - 1 && (tab->fe[i].ctrl | tab->fe[i].prop);
i++)
gfar_write_filer(priv, i, tab->fe[i].ctrl, tab->fe[i].prop);
/* Fill the rest with fall-troughs */
diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c
index 6c0fd8e..895b086 100644
--- a/drivers/net/ethernet/ibm/ibmveth.c
+++ b/drivers/net/ethernet/ibm/ibmveth.c
@@ -293,6 +293,18 @@ failure:
atomic_add(buffers_added, &(pool->available));
}
+/*
+ * The final 8 bytes of the buffer list is a counter of frames dropped
+ * because there was not a buffer in the buffer list capable of holding
+ * the frame.
+ */
+static void ibmveth_update_rx_no_buffer(struct ibmveth_adapter *adapter)
+{
+ __be64 *p = adapter->buffer_list_addr + 4096 - 8;
+
+ adapter->rx_no_buffer = be64_to_cpup(p);
+}
+
/* replenish routine */
static void ibmveth_replenish_task(struct ibmveth_adapter *adapter)
{
@@ -308,8 +320,7 @@ static void ibmveth_replenish_task(struct ibmveth_adapter *adapter)
ibmveth_replenish_buffer_pool(adapter, pool);
}
- adapter->rx_no_buffer = *(u64 *)(((char*)adapter->buffer_list_addr) +
- 4096 - 8);
+ ibmveth_update_rx_no_buffer(adapter);
}
/* empty and free ana buffer pool - also used to do cleanup in error paths */
@@ -699,8 +710,7 @@ static int ibmveth_close(struct net_device *netdev)
free_irq(netdev->irq, netdev);
- adapter->rx_no_buffer = *(u64 *)(((char *)adapter->buffer_list_addr) +
- 4096 - 8);
+ ibmveth_update_rx_no_buffer(adapter);
ibmveth_cleanup(adapter);
diff --git a/drivers/net/ethernet/intel/e1000/e1000.h b/drivers/net/ethernet/intel/e1000/e1000.h
index 26d9cd5..d5775ae 100644
--- a/drivers/net/ethernet/intel/e1000/e1000.h
+++ b/drivers/net/ethernet/intel/e1000/e1000.h
@@ -83,6 +83,11 @@ struct e1000_adapter;
#define E1000_MAX_INTR 10
+/*
+ * Count for polling __E1000_RESET condition every 10-20msec.
+ */
+#define E1000_CHECK_RESET_COUNT 50
+
/* TX/RX descriptor defines */
#define E1000_DEFAULT_TXD 256
#define E1000_MAX_TXD 256
diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c
index 59ad007..15c85d4 100644
--- a/drivers/net/ethernet/intel/e1000/e1000_main.c
+++ b/drivers/net/ethernet/intel/e1000/e1000_main.c
@@ -494,13 +494,20 @@ static void e1000_down_and_stop(struct e1000_adapter *adapter)
{
set_bit(__E1000_DOWN, &adapter->flags);
- /* Only kill reset task if adapter is not resetting */
- if (!test_bit(__E1000_RESETTING, &adapter->flags))
- cancel_work_sync(&adapter->reset_task);
-
cancel_delayed_work_sync(&adapter->watchdog_task);
+
+ /*
+ * Since the watchdog task can reschedule other tasks, we should cancel
+ * it first, otherwise we can run into the situation when a work is
+ * still running after the adapter has been turned down.
+ */
+
cancel_delayed_work_sync(&adapter->phy_info_task);
cancel_delayed_work_sync(&adapter->fifo_stall_task);
+
+ /* Only kill reset task if adapter is not resetting */
+ if (!test_bit(__E1000_RESETTING, &adapter->flags))
+ cancel_work_sync(&adapter->reset_task);
}
void e1000_down(struct e1000_adapter *adapter)
@@ -1445,6 +1452,10 @@ static int e1000_close(struct net_device *netdev)
{
struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
+ int count = E1000_CHECK_RESET_COUNT;
+
+ while (test_bit(__E1000_RESETTING, &adapter->flags) && count--)
+ usleep_range(10000, 20000);
WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
e1000_down(adapter);
@@ -3917,8 +3928,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
" next_to_watch <%x>\n"
" jiffies <%lx>\n"
" next_to_watch.status <%x>\n",
- (unsigned long)((tx_ring - adapter->tx_ring) /
- sizeof(struct e1000_tx_ring)),
+ (unsigned long)(tx_ring - adapter->tx_ring),
readl(hw->hw_addr + tx_ring->tdh),
readl(hw->hw_addr + tx_ring->tdt),
tx_ring->next_to_use,
@@ -4969,6 +4979,11 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
netif_device_detach(netdev);
if (netif_running(netdev)) {
+ int count = E1000_CHECK_RESET_COUNT;
+
+ while (test_bit(__E1000_RESETTING, &adapter->flags) && count--)
+ usleep_range(10000, 20000);
+
WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
e1000_down(adapter);
}
diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c
index 42f0f67..70e16f7 100644
--- a/drivers/net/ethernet/intel/e1000e/ich8lan.c
+++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c
@@ -1374,7 +1374,7 @@ static void e1000_rar_set_pch2lan(struct e1000_hw *hw, u8 *addr, u32 index)
/* RAR[1-6] are owned by manageability. Skip those and program the
* next address into the SHRA register array.
*/
- if (index < (u32)(hw->mac.rar_entry_count - 6)) {
+ if (index < (u32)(hw->mac.rar_entry_count)) {
s32 ret_val;
ret_val = e1000_acquire_swflag_ich8lan(hw);
diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.h b/drivers/net/ethernet/intel/e1000e/ich8lan.h
index 217090d..5986569 100644
--- a/drivers/net/ethernet/intel/e1000e/ich8lan.h
+++ b/drivers/net/ethernet/intel/e1000e/ich8lan.h
@@ -98,7 +98,7 @@
#define PCIE_ICH8_SNOOP_ALL PCIE_NO_SNOOP_ALL
#define E1000_ICH_RAR_ENTRIES 7
-#define E1000_PCH2_RAR_ENTRIES 11 /* RAR[0-6], SHRA[0-3] */
+#define E1000_PCH2_RAR_ENTRIES 5 /* RAR[0], SHRA[0-3] */
#define E1000_PCH_LPT_RAR_ENTRIES 12 /* RAR[0], SHRA[0-10] */
#define PHY_PAGE_SHIFT 5
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
index 9cb400c..07547f6 100644
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -6563,21 +6563,15 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
return err;
pci_using_dac = 0;
- err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
+ err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
if (!err) {
- err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
- if (!err)
- pci_using_dac = 1;
+ pci_using_dac = 1;
} else {
- err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
+ err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
if (err) {
- err = dma_set_coherent_mask(&pdev->dev,
- DMA_BIT_MASK(32));
- if (err) {
- dev_err(&pdev->dev,
- "No usable DMA configuration, aborting\n");
- goto err_dma;
- }
+ dev_err(&pdev->dev,
+ "No usable DMA configuration, aborting\n");
+ goto err_dma;
}
}
@@ -7033,13 +7027,11 @@ static DEFINE_PCI_DEVICE_TABLE(e1000_pci_tbl) = {
};
MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
-#ifdef CONFIG_PM
static const struct dev_pm_ops e1000_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(e1000_suspend, e1000_resume)
SET_RUNTIME_PM_OPS(e1000_runtime_suspend, e1000_runtime_resume,
e1000_idle)
};
-#endif
/* PCI Device API Driver */
static struct pci_driver e1000_driver = {
@@ -7047,11 +7039,9 @@ static struct pci_driver e1000_driver = {
.id_table = e1000_pci_tbl,
.probe = e1000_probe,
.remove = e1000_remove,
-#ifdef CONFIG_PM
.driver = {
.pm = &e1000_pm_ops,
},
-#endif
.shutdown = e1000_shutdown,
.err_handler = &e1000_err_handler
};
diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c
index 47c2d10..974558e 100644
--- a/drivers/net/ethernet/intel/igb/e1000_82575.c
+++ b/drivers/net/ethernet/intel/igb/e1000_82575.c
@@ -1403,6 +1403,13 @@ static s32 igb_init_hw_82575(struct e1000_hw *hw)
s32 ret_val;
u16 i, rar_count = mac->rar_entry_count;
+ if ((hw->mac.type >= e1000_i210) &&
+ !(igb_get_flash_presence_i210(hw))) {
+ ret_val = igb_pll_workaround_i210(hw);
+ if (ret_val)
+ return ret_val;
+ }
+
/* Initialize identification LED */
ret_val = igb_id_led_init(hw);
if (ret_val) {
diff --git a/drivers/net/ethernet/intel/igb/e1000_defines.h b/drivers/net/ethernet/intel/igb/e1000_defines.h
index 978eca3..956c4c3 100644
--- a/drivers/net/ethernet/intel/igb/e1000_defines.h
+++ b/drivers/net/ethernet/intel/igb/e1000_defines.h
@@ -46,14 +46,15 @@
/* Extended Device Control */
#define E1000_CTRL_EXT_SDP3_DATA 0x00000080 /* Value of SW Defineable Pin 3 */
/* Physical Func Reset Done Indication */
-#define E1000_CTRL_EXT_PFRSTD 0x00004000
-#define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
-#define E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES 0x00C00000
-#define E1000_CTRL_EXT_LINK_MODE_1000BASE_KX 0x00400000
-#define E1000_CTRL_EXT_LINK_MODE_SGMII 0x00800000
-#define E1000_CTRL_EXT_LINK_MODE_GMII 0x00000000
-#define E1000_CTRL_EXT_EIAME 0x01000000
-#define E1000_CTRL_EXT_IRCA 0x00000001
+#define E1000_CTRL_EXT_PFRSTD 0x00004000
+#define E1000_CTRL_EXT_SDLPE 0X00040000 /* SerDes Low Power Enable */
+#define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
+#define E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES 0x00C00000
+#define E1000_CTRL_EXT_LINK_MODE_1000BASE_KX 0x00400000
+#define E1000_CTRL_EXT_LINK_MODE_SGMII 0x00800000
+#define E1000_CTRL_EXT_LINK_MODE_GMII 0x00000000
+#define E1000_CTRL_EXT_EIAME 0x01000000
+#define E1000_CTRL_EXT_IRCA 0x00000001
/* Interrupt delay cancellation */
/* Driver loaded bit for FW */
#define E1000_CTRL_EXT_DRV_LOAD 0x10000000
@@ -62,6 +63,7 @@
/* packet buffer parity error detection enabled */
/* descriptor FIFO parity error detection enable */
#define E1000_CTRL_EXT_PBA_CLR 0x80000000 /* PBA Clear */
+#define E1000_CTRL_EXT_PHYPDEN 0x00100000
#define E1000_I2CCMD_REG_ADDR_SHIFT 16
#define E1000_I2CCMD_PHY_ADDR_SHIFT 24
#define E1000_I2CCMD_OPCODE_READ 0x08000000
diff --git a/drivers/net/ethernet/intel/igb/e1000_hw.h b/drivers/net/ethernet/intel/igb/e1000_hw.h
index 37a9c06..80f20d1 100644
--- a/drivers/net/ethernet/intel/igb/e1000_hw.h
+++ b/drivers/net/ethernet/intel/igb/e1000_hw.h
@@ -569,4 +569,7 @@ extern struct net_device *igb_get_hw_dev(struct e1000_hw *hw);
/* These functions must be implemented by drivers */
s32 igb_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value);
s32 igb_write_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value);
+
+void igb_read_pci_cfg(struct e1000_hw *hw, u32 reg, u16 *value);
+void igb_write_pci_cfg(struct e1000_hw *hw, u32 reg, u16 *value);
#endif /* _E1000_HW_H_ */
diff --git a/drivers/net/ethernet/intel/igb/e1000_i210.c b/drivers/net/ethernet/intel/igb/e1000_i210.c
index 0c03933..0217d4e 100644
--- a/drivers/net/ethernet/intel/igb/e1000_i210.c
+++ b/drivers/net/ethernet/intel/igb/e1000_i210.c
@@ -835,3 +835,69 @@ s32 igb_init_nvm_params_i210(struct e1000_hw *hw)
}
return ret_val;
}
+
+/**
+ * igb_pll_workaround_i210
+ * @hw: pointer to the HW structure
+ *
+ * Works around an errata in the PLL circuit where it occasionally
+ * provides the wrong clock frequency after power up.
+ **/
+s32 igb_pll_workaround_i210(struct e1000_hw *hw)
+{
+ s32 ret_val;
+ u32 wuc, mdicnfg, ctrl, ctrl_ext, reg_val;
+ u16 nvm_word, phy_word, pci_word, tmp_nvm;
+ int i;
+
+ /* Get and set needed register values */
+ wuc = rd32(E1000_WUC);
+ mdicnfg = rd32(E1000_MDICNFG);
+ reg_val = mdicnfg & ~E1000_MDICNFG_EXT_MDIO;
+ wr32(E1000_MDICNFG, reg_val);
+
+ /* Get data from NVM, or set default */
+ ret_val = igb_read_invm_word_i210(hw, E1000_INVM_AUTOLOAD,
+ &nvm_word);
+ if (ret_val)
+ nvm_word = E1000_INVM_DEFAULT_AL;
+ tmp_nvm = nvm_word | E1000_INVM_PLL_WO_VAL;
+ for (i = 0; i < E1000_MAX_PLL_TRIES; i++) {
+ /* check current state directly from internal PHY */
+ igb_read_phy_reg_gs40g(hw, (E1000_PHY_PLL_FREQ_PAGE |
+ E1000_PHY_PLL_FREQ_REG), &phy_word);
+ if ((phy_word & E1000_PHY_PLL_UNCONF)
+ != E1000_PHY_PLL_UNCONF) {
+ ret_val = 0;
+ break;
+ } else {
+ ret_val = -E1000_ERR_PHY;
+ }
+ /* directly reset the internal PHY */
+ ctrl = rd32(E1000_CTRL);
+ wr32(E1000_CTRL, ctrl|E1000_CTRL_PHY_RST);
+
+ ctrl_ext = rd32(E1000_CTRL_EXT);
+ ctrl_ext |= (E1000_CTRL_EXT_PHYPDEN | E1000_CTRL_EXT_SDLPE);
+ wr32(E1000_CTRL_EXT, ctrl_ext);
+
+ wr32(E1000_WUC, 0);
+ reg_val = (E1000_INVM_AUTOLOAD << 4) | (tmp_nvm << 16);
+ wr32(E1000_EEARBC_I210, reg_val);
+
+ igb_read_pci_cfg(hw, E1000_PCI_PMCSR, &pci_word);
+ pci_word |= E1000_PCI_PMCSR_D3;
+ igb_write_pci_cfg(hw, E1000_PCI_PMCSR, &pci_word);
+ usleep_range(1000, 2000);
+ pci_word &= ~E1000_PCI_PMCSR_D3;
+ igb_write_pci_cfg(hw, E1000_PCI_PMCSR, &pci_word);
+ reg_val = (E1000_INVM_AUTOLOAD << 4) | (nvm_word << 16);
+ wr32(E1000_EEARBC_I210, reg_val);
+
+ /* restore WUC register */
+ wr32(E1000_WUC, wuc);
+ }
+ /* restore MDICNFG setting */
+ wr32(E1000_MDICNFG, mdicnfg);
+ return ret_val;
+}
diff --git a/drivers/net/ethernet/intel/igb/e1000_i210.h b/drivers/net/ethernet/intel/igb/e1000_i210.h
index dde3c4b..99f4611 100644
--- a/drivers/net/ethernet/intel/igb/e1000_i210.h
+++ b/drivers/net/ethernet/intel/igb/e1000_i210.h
@@ -48,6 +48,7 @@ extern s32 igb_write_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr,
u16 data);
extern s32 igb_init_nvm_params_i210(struct e1000_hw *hw);
extern bool igb_get_flash_presence_i210(struct e1000_hw *hw);
+s32 igb_pll_workaround_i210(struct e1000_hw *hw);
#define E1000_STM_OPCODE 0xDB00
#define E1000_EEPROM_FLASH_SIZE_WORD 0x11
@@ -93,4 +94,15 @@ enum E1000_INVM_STRUCTURE_TYPE {
#define NVM_LED_1_CFG_DEFAULT_I211 0x0184
#define NVM_LED_0_2_CFG_DEFAULT_I211 0x200C
+/* PLL Defines */
+#define E1000_PCI_PMCSR 0x44
+#define E1000_PCI_PMCSR_D3 0x03
+#define E1000_MAX_PLL_TRIES 5
+#define E1000_PHY_PLL_UNCONF 0xFF
+#define E1000_PHY_PLL_FREQ_PAGE 0xFC0000
+#define E1000_PHY_PLL_FREQ_REG 0x000E
+#define E1000_INVM_DEFAULT_AL 0x202F
+#define E1000_INVM_AUTOLOAD 0x0A
+#define E1000_INVM_PLL_WO_VAL 0x0010
+
#endif
diff --git a/drivers/net/ethernet/intel/igb/e1000_phy.c b/drivers/net/ethernet/intel/igb/e1000_phy.c
index 556da81..ad2b74d 100644
--- a/drivers/net/ethernet/intel/igb/e1000_phy.c
+++ b/drivers/net/ethernet/intel/igb/e1000_phy.c
@@ -708,11 +708,6 @@ s32 igb_copper_link_setup_m88(struct e1000_hw *hw)
hw_dbg("Error committing the PHY changes\n");
goto out;
}
- if (phy->type == e1000_phy_i210) {
- ret_val = igb_set_master_slave_mode(hw);
- if (ret_val)
- return ret_val;
- }
out:
return ret_val;
@@ -806,6 +801,9 @@ s32 igb_copper_link_setup_m88_gen2(struct e1000_hw *hw)
hw_dbg("Error committing the PHY changes\n");
return ret_val;
}
+ ret_val = igb_set_master_slave_mode(hw);
+ if (ret_val)
+ return ret_val;
return 0;
}
diff --git a/drivers/net/ethernet/intel/igb/e1000_regs.h b/drivers/net/ethernet/intel/igb/e1000_regs.h
index 82632c6..7156981 100644
--- a/drivers/net/ethernet/intel/igb/e1000_regs.h
+++ b/drivers/net/ethernet/intel/igb/e1000_regs.h
@@ -69,6 +69,7 @@
#define E1000_PBA 0x01000 /* Packet Buffer Allocation - RW */
#define E1000_PBS 0x01008 /* Packet Buffer Size */
#define E1000_EEMNGCTL 0x01010 /* MNG EEprom Control */
+#define E1000_EEARBC_I210 0x12024 /* EEPROM Auto Read Bus Control */
#define E1000_EEWR 0x0102C /* EEPROM Write Register - RW */
#define E1000_I2CCMD 0x01028 /* SFPI2C Command Register - RW */
#define E1000_FRTIMER 0x01048 /* Free Running Timer - RW */
diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c
index 151e00c..3eb020c 100644
--- a/drivers/net/ethernet/intel/igb/igb_ethtool.c
+++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c
@@ -771,8 +771,10 @@ static int igb_set_eeprom(struct net_device *netdev,
if (eeprom->len == 0)
return -EOPNOTSUPP;
- if (hw->mac.type == e1000_i211)
+ if ((hw->mac.type >= e1000_i210) &&
+ !igb_get_flash_presence_i210(hw)) {
return -EOPNOTSUPP;
+ }
if (eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
return -EFAULT;
@@ -1659,7 +1661,8 @@ static int igb_setup_loopback_test(struct igb_adapter *adapter)
if ((hw->device_id == E1000_DEV_ID_DH89XXCC_SGMII) ||
(hw->device_id == E1000_DEV_ID_DH89XXCC_SERDES) ||
(hw->device_id == E1000_DEV_ID_DH89XXCC_BACKPLANE) ||
- (hw->device_id == E1000_DEV_ID_DH89XXCC_SFP)) {
+ (hw->device_id == E1000_DEV_ID_DH89XXCC_SFP) ||
+ (hw->device_id == E1000_DEV_ID_I354_SGMII)) {
/* Enable DH89xxCC MPHY for near end loopback */
reg = rd32(E1000_MPHY_ADDR_CTL);
@@ -1725,7 +1728,8 @@ static void igb_loopback_cleanup(struct igb_adapter *adapter)
if ((hw->device_id == E1000_DEV_ID_DH89XXCC_SGMII) ||
(hw->device_id == E1000_DEV_ID_DH89XXCC_SERDES) ||
(hw->device_id == E1000_DEV_ID_DH89XXCC_BACKPLANE) ||
- (hw->device_id == E1000_DEV_ID_DH89XXCC_SFP)) {
+ (hw->device_id == E1000_DEV_ID_DH89XXCC_SFP) ||
+ (hw->device_id == E1000_DEV_ID_I354_SGMII)) {
u32 reg;
/* Disable near end loopback on DH89xxCC */
@@ -2055,14 +2059,15 @@ static void igb_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
{
struct igb_adapter *adapter = netdev_priv(netdev);
- wol->supported = WAKE_UCAST | WAKE_MCAST |
- WAKE_BCAST | WAKE_MAGIC |
- WAKE_PHY;
wol->wolopts = 0;
if (!(adapter->flags & IGB_FLAG_WOL_SUPPORTED))
return;
+ wol->supported = WAKE_UCAST | WAKE_MCAST |
+ WAKE_BCAST | WAKE_MAGIC |
+ WAKE_PHY;
+
/* apply any specific unsupported masks here */
switch (adapter->hw.device_id) {
default:
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index 8cf44f2..02544ce 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -182,6 +182,7 @@ static void igb_check_vf_rate_limit(struct igb_adapter *);
#ifdef CONFIG_PCI_IOV
static int igb_vf_configure(struct igb_adapter *adapter, int vf);
+static int igb_pci_enable_sriov(struct pci_dev *dev, int num_vfs);
#endif
#ifdef CONFIG_PM
@@ -1586,6 +1587,8 @@ void igb_power_up_link(struct igb_adapter *adapter)
igb_power_up_phy_copper(&adapter->hw);
else
igb_power_up_serdes_link_82575(&adapter->hw);
+
+ igb_setup_link(&adapter->hw);
}
/**
@@ -2034,21 +2037,15 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
return err;
pci_using_dac = 0;
- err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
+ err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
if (!err) {
- err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
- if (!err)
- pci_using_dac = 1;
+ pci_using_dac = 1;
} else {
- err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
+ err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
if (err) {
- err = dma_set_coherent_mask(&pdev->dev,
- DMA_BIT_MASK(32));
- if (err) {
- dev_err(&pdev->dev,
- "No usable DMA configuration, aborting\n");
- goto err_dma;
- }
+ dev_err(&pdev->dev,
+ "No usable DMA configuration, aborting\n");
+ goto err_dma;
}
}
@@ -2429,7 +2426,7 @@ err_dma:
}
#ifdef CONFIG_PCI_IOV
-static int igb_disable_sriov(struct pci_dev *pdev)
+static int igb_disable_sriov(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct igb_adapter *adapter = netdev_priv(netdev);
@@ -2470,27 +2467,19 @@ static int igb_enable_sriov(struct pci_dev *pdev, int num_vfs)
int err = 0;
int i;
- if (!adapter->msix_entries) {
+ if (!adapter->msix_entries || num_vfs > 7) {
err = -EPERM;
goto out;
}
-
if (!num_vfs)
goto out;
- else if (old_vfs && old_vfs == num_vfs)
- goto out;
- else if (old_vfs && old_vfs != num_vfs)
- err = igb_disable_sriov(pdev);
-
- if (err)
- goto out;
-
- if (num_vfs > 7) {
- err = -EPERM;
- goto out;
- }
- adapter->vfs_allocated_count = num_vfs;
+ if (old_vfs) {
+ dev_info(&pdev->dev, "%d pre-allocated VFs found - override max_vfs setting of %d\n",
+ old_vfs, max_vfs);
+ adapter->vfs_allocated_count = old_vfs;
+ } else
+ adapter->vfs_allocated_count = num_vfs;
adapter->vf_data = kcalloc(adapter->vfs_allocated_count,
sizeof(struct vf_data_storage), GFP_KERNEL);
@@ -2504,10 +2493,12 @@ static int igb_enable_sriov(struct pci_dev *pdev, int num_vfs)
goto out;
}
- err = pci_enable_sriov(pdev, adapter->vfs_allocated_count);
- if (err)
- goto err_out;
-
+ /* only call pci_enable_sriov() if no VFs are allocated already */
+ if (!old_vfs) {
+ err = pci_enable_sriov(pdev, adapter->vfs_allocated_count);
+ if (err)
+ goto err_out;
+ }
dev_info(&pdev->dev, "%d VFs allocated\n",
adapter->vfs_allocated_count);
for (i = 0; i < adapter->vfs_allocated_count; i++)
@@ -2623,7 +2614,7 @@ static void igb_probe_vfs(struct igb_adapter *adapter)
return;
pci_sriov_set_totalvfs(pdev, 7);
- igb_enable_sriov(pdev, max_vfs);
+ igb_pci_enable_sriov(pdev, max_vfs);
#endif /* CONFIG_PCI_IOV */
}
@@ -6918,6 +6909,20 @@ static int igb_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
}
}
+void igb_read_pci_cfg(struct e1000_hw *hw, u32 reg, u16 *value)
+{
+ struct igb_adapter *adapter = hw->back;
+
+ pci_read_config_word(adapter->pdev, reg, value);
+}
+
+void igb_write_pci_cfg(struct e1000_hw *hw, u32 reg, u16 *value)
+{
+ struct igb_adapter *adapter = hw->back;
+
+ pci_write_config_word(adapter->pdev, reg, *value);
+}
+
s32 igb_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value)
{
struct igb_adapter *adapter = hw->back;
@@ -7281,6 +7286,8 @@ static int igb_sriov_reinit(struct pci_dev *dev)
if (netif_running(netdev))
igb_close(netdev);
+ else
+ igb_reset(adapter);
igb_clear_interrupt_scheme(adapter);
diff --git a/drivers/net/ethernet/intel/igbvf/netdev.c b/drivers/net/ethernet/intel/igbvf/netdev.c
index 93eb7ee..04bf22e 100644
--- a/drivers/net/ethernet/intel/igbvf/netdev.c
+++ b/drivers/net/ethernet/intel/igbvf/netdev.c
@@ -2343,10 +2343,9 @@ static int igbvf_change_mtu(struct net_device *netdev, int new_mtu)
struct igbvf_adapter *adapter = netdev_priv(netdev);
int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
- if ((new_mtu < 68) || (max_frame > MAX_JUMBO_FRAME_SIZE)) {
- dev_err(&adapter->pdev->dev, "Invalid MTU setting\n");
+ if (new_mtu < 68 || new_mtu > INT_MAX - ETH_HLEN - ETH_FCS_LEN ||
+ max_frame > MAX_JUMBO_FRAME_SIZE)
return -EINVAL;
- }
#define MAX_STD_JUMBO_FRAME_SIZE 9234
if (max_frame > MAX_STD_JUMBO_FRAME_SIZE) {
@@ -2638,21 +2637,15 @@ static int igbvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
return err;
pci_using_dac = 0;
- err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
+ err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
if (!err) {
- err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
- if (!err)
- pci_using_dac = 1;
+ pci_using_dac = 1;
} else {
- err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
+ err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
if (err) {
- err = dma_set_coherent_mask(&pdev->dev,
- DMA_BIT_MASK(32));
- if (err) {
- dev_err(&pdev->dev, "No usable DMA "
- "configuration, aborting\n");
- goto err_dma;
- }
+ dev_err(&pdev->dev, "No usable DMA "
+ "configuration, aborting\n");
+ goto err_dma;
}
}
@@ -2699,7 +2692,7 @@ static int igbvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (ei->get_variants) {
err = ei->get_variants(adapter);
if (err)
- goto err_ioremap;
+ goto err_get_variants;
}
/* setup adapter struct */
@@ -2796,6 +2789,7 @@ err_hw_init:
kfree(adapter->rx_ring);
err_sw_init:
igbvf_reset_interrupt_capability(adapter);
+err_get_variants:
iounmap(adapter->hw.hw_addr);
err_ioremap:
free_netdev(netdev);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 0ac6b11..4506f8a 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -369,11 +369,13 @@ struct ixgbe_q_vector {
#ifdef CONFIG_NET_RX_BUSY_POLL
unsigned int state;
#define IXGBE_QV_STATE_IDLE 0
-#define IXGBE_QV_STATE_NAPI 1 /* NAPI owns this QV */
-#define IXGBE_QV_STATE_POLL 2 /* poll owns this QV */
-#define IXGBE_QV_LOCKED (IXGBE_QV_STATE_NAPI | IXGBE_QV_STATE_POLL)
-#define IXGBE_QV_STATE_NAPI_YIELD 4 /* NAPI yielded this QV */
-#define IXGBE_QV_STATE_POLL_YIELD 8 /* poll yielded this QV */
+#define IXGBE_QV_STATE_NAPI 1 /* NAPI owns this QV */
+#define IXGBE_QV_STATE_POLL 2 /* poll owns this QV */
+#define IXGBE_QV_STATE_DISABLED 4 /* QV is disabled */
+#define IXGBE_QV_OWNED (IXGBE_QV_STATE_NAPI | IXGBE_QV_STATE_POLL)
+#define IXGBE_QV_LOCKED (IXGBE_QV_OWNED | IXGBE_QV_STATE_DISABLED)
+#define IXGBE_QV_STATE_NAPI_YIELD 8 /* NAPI yielded this QV */
+#define IXGBE_QV_STATE_POLL_YIELD 16 /* poll yielded this QV */
#define IXGBE_QV_YIELD (IXGBE_QV_STATE_NAPI_YIELD | IXGBE_QV_STATE_POLL_YIELD)
#define IXGBE_QV_USER_PEND (IXGBE_QV_STATE_POLL | IXGBE_QV_STATE_POLL_YIELD)
spinlock_t lock;
@@ -394,7 +396,7 @@ static inline void ixgbe_qv_init_lock(struct ixgbe_q_vector *q_vector)
static inline bool ixgbe_qv_lock_napi(struct ixgbe_q_vector *q_vector)
{
int rc = true;
- spin_lock(&q_vector->lock);
+ spin_lock_bh(&q_vector->lock);
if (q_vector->state & IXGBE_QV_LOCKED) {
WARN_ON(q_vector->state & IXGBE_QV_STATE_NAPI);
q_vector->state |= IXGBE_QV_STATE_NAPI_YIELD;
@@ -405,7 +407,7 @@ static inline bool ixgbe_qv_lock_napi(struct ixgbe_q_vector *q_vector)
} else
/* we don't care if someone yielded */
q_vector->state = IXGBE_QV_STATE_NAPI;
- spin_unlock(&q_vector->lock);
+ spin_unlock_bh(&q_vector->lock);
return rc;
}
@@ -413,14 +415,15 @@ static inline bool ixgbe_qv_lock_napi(struct ixgbe_q_vector *q_vector)
static inline bool ixgbe_qv_unlock_napi(struct ixgbe_q_vector *q_vector)
{
int rc = false;
- spin_lock(&q_vector->lock);
+ spin_lock_bh(&q_vector->lock);
WARN_ON(q_vector->state & (IXGBE_QV_STATE_POLL |
IXGBE_QV_STATE_NAPI_YIELD));
if (q_vector->state & IXGBE_QV_STATE_POLL_YIELD)
rc = true;
- q_vector->state = IXGBE_QV_STATE_IDLE;
- spin_unlock(&q_vector->lock);
+ /* will reset state to idle, unless QV is disabled */
+ q_vector->state &= IXGBE_QV_STATE_DISABLED;
+ spin_unlock_bh(&q_vector->lock);
return rc;
}
@@ -451,7 +454,8 @@ static inline bool ixgbe_qv_unlock_poll(struct ixgbe_q_vector *q_vector)
if (q_vector->state & IXGBE_QV_STATE_POLL_YIELD)
rc = true;
- q_vector->state = IXGBE_QV_STATE_IDLE;
+ /* will reset state to idle, unless QV is disabled */
+ q_vector->state &= IXGBE_QV_STATE_DISABLED;
spin_unlock_bh(&q_vector->lock);
return rc;
}
@@ -459,9 +463,23 @@ static inline bool ixgbe_qv_unlock_poll(struct ixgbe_q_vector *q_vector)
/* true if a socket is polling, even if it did not get the lock */
static inline bool ixgbe_qv_ll_polling(struct ixgbe_q_vector *q_vector)
{
- WARN_ON(!(q_vector->state & IXGBE_QV_LOCKED));
+ WARN_ON(!(q_vector->state & IXGBE_QV_OWNED));
return q_vector->state & IXGBE_QV_USER_PEND;
}
+
+/* false if QV is currently owned */
+static inline bool ixgbe_qv_disable(struct ixgbe_q_vector *q_vector)
+{
+ int rc = true;
+ spin_lock_bh(&q_vector->lock);
+ if (q_vector->state & IXGBE_QV_OWNED)
+ rc = false;
+ q_vector->state |= IXGBE_QV_STATE_DISABLED;
+ spin_unlock_bh(&q_vector->lock);
+
+ return rc;
+}
+
#else /* CONFIG_NET_RX_BUSY_POLL */
static inline void ixgbe_qv_init_lock(struct ixgbe_q_vector *q_vector)
{
@@ -491,6 +509,12 @@ static inline bool ixgbe_qv_ll_polling(struct ixgbe_q_vector *q_vector)
{
return false;
}
+
+static inline bool ixgbe_qv_disable(struct ixgbe_q_vector *q_vector)
+{
+ return true;
+}
+
#endif /* CONFIG_NET_RX_BUSY_POLL */
#ifdef CONFIG_IXGBE_HWMON
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
index e8649ab..2cd86d3 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
@@ -2212,13 +2212,13 @@ static int ixgbe_set_coalesce(struct net_device *netdev,
#if IS_ENABLED(CONFIG_BQL)
/* detect ITR changes that require update of TXDCTL.WTHRESH */
- if ((adapter->tx_itr_setting > 1) &&
+ if ((adapter->tx_itr_setting != 1) &&
(adapter->tx_itr_setting < IXGBE_100K_ITR)) {
if ((tx_itr_prev == 1) ||
- (tx_itr_prev > IXGBE_100K_ITR))
+ (tx_itr_prev >= IXGBE_100K_ITR))
need_reset = true;
} else {
- if ((tx_itr_prev > 1) &&
+ if ((tx_itr_prev != 1) &&
(tx_itr_prev < IXGBE_100K_ITR))
need_reset = true;
}
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 0ade0cd..8a14f96 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -3825,14 +3825,6 @@ void ixgbe_set_rx_mode(struct net_device *netdev)
if (netdev->flags & IFF_ALLMULTI) {
fctrl |= IXGBE_FCTRL_MPE;
vmolr |= IXGBE_VMOLR_MPE;
- } else {
- /*
- * Write addresses to the MTA, if the attempt fails
- * then we should just turn on promiscuous mode so
- * that we can at least receive multicast traffic
- */
- hw->mac.ops.update_mc_addr_list(hw, netdev);
- vmolr |= IXGBE_VMOLR_ROMPE;
}
ixgbe_vlan_filter_enable(adapter);
hw->addr_ctrl.user_set_promisc = false;
@@ -3849,6 +3841,13 @@ void ixgbe_set_rx_mode(struct net_device *netdev)
vmolr |= IXGBE_VMOLR_ROPE;
}
+ /* Write addresses to the MTA, if the attempt fails
+ * then we should just turn on promiscuous mode so
+ * that we can at least receive multicast traffic
+ */
+ hw->mac.ops.update_mc_addr_list(hw, netdev);
+ vmolr |= IXGBE_VMOLR_ROMPE;
+
if (adapter->num_vfs)
ixgbe_restore_vf_multicasts(adapter);
@@ -3893,15 +3892,13 @@ static void ixgbe_napi_disable_all(struct ixgbe_adapter *adapter)
{
int q_idx;
- local_bh_disable(); /* for ixgbe_qv_lock_napi() */
for (q_idx = 0; q_idx < adapter->num_q_vectors; q_idx++) {
napi_disable(&adapter->q_vector[q_idx]->napi);
- while (!ixgbe_qv_lock_napi(adapter->q_vector[q_idx])) {
+ while (!ixgbe_qv_disable(adapter->q_vector[q_idx])) {
pr_info("QV %d locked\n", q_idx);
- mdelay(1);
+ usleep_range(1000, 20000);
}
}
- local_bh_enable();
}
#ifdef CONFIG_IXGBE_DCB
@@ -7490,19 +7487,14 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (err)
return err;
- if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)) &&
- !dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64))) {
+ if (!dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64))) {
pci_using_dac = 1;
} else {
- err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
+ err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
if (err) {
- err = dma_set_coherent_mask(&pdev->dev,
- DMA_BIT_MASK(32));
- if (err) {
- dev_err(&pdev->dev,
- "No usable DMA configuration, aborting\n");
- goto err_dma;
- }
+ dev_err(&pdev->dev,
+ "No usable DMA configuration, aborting\n");
+ goto err_dma;
}
pci_using_dac = 0;
}
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index 59a62bb..83544f8 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -756,37 +756,12 @@ static void ixgbevf_set_itr(struct ixgbevf_q_vector *q_vector)
static irqreturn_t ixgbevf_msix_other(int irq, void *data)
{
struct ixgbevf_adapter *adapter = data;
- struct pci_dev *pdev = adapter->pdev;
struct ixgbe_hw *hw = &adapter->hw;
- u32 msg;
- bool got_ack = false;
hw->mac.get_link_status = 1;
- if (!hw->mbx.ops.check_for_ack(hw))
- got_ack = true;
-
- if (!hw->mbx.ops.check_for_msg(hw)) {
- hw->mbx.ops.read(hw, &msg, 1);
-
- if ((msg & IXGBE_MBVFICR_VFREQ_MASK) == IXGBE_PF_CONTROL_MSG) {
- mod_timer(&adapter->watchdog_timer,
- round_jiffies(jiffies + 1));
- adapter->link_up = false;
- }
-
- if (msg & IXGBE_VT_MSGTYPE_NACK)
- dev_info(&pdev->dev,
- "Last Request of type %2.2x to PF Nacked\n",
- msg & 0xFF);
- hw->mbx.v2p_mailbox |= IXGBE_VFMAILBOX_PFSTS;
- }
- /* checking for the ack clears the PFACK bit. Place
- * it back in the v2p_mailbox cache so that anyone
- * polling for an ack will not miss it
- */
- if (got_ack)
- hw->mbx.v2p_mailbox |= IXGBE_VFMAILBOX_PFACK;
+ if (!test_bit(__IXGBEVF_DOWN, &adapter->state))
+ mod_timer(&adapter->watchdog_timer, jiffies);
IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, adapter->eims_other);
@@ -3326,19 +3301,14 @@ static int ixgbevf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (err)
return err;
- if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)) &&
- !dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64))) {
+ if (!dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64))) {
pci_using_dac = 1;
} else {
- err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
+ err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
if (err) {
- err = dma_set_coherent_mask(&pdev->dev,
- DMA_BIT_MASK(32));
- if (err) {
- dev_err(&pdev->dev, "No usable DMA "
- "configuration, aborting\n");
- goto err_dma;
- }
+ dev_err(&pdev->dev, "No usable DMA "
+ "configuration, aborting\n");
+ goto err_dma;
}
pci_using_dac = 0;
}
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index 71d9cad..9c66d31 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -88,9 +88,8 @@
#define MVNETA_TX_IN_PRGRS BIT(1)
#define MVNETA_TX_FIFO_EMPTY BIT(8)
#define MVNETA_RX_MIN_FRAME_SIZE 0x247c
-#define MVNETA_SERDES_CFG 0x24A0
+#define MVNETA_SGMII_SERDES_CFG 0x24A0
#define MVNETA_SGMII_SERDES_PROTO 0x0cc7
-#define MVNETA_RGMII_SERDES_PROTO 0x0667
#define MVNETA_TYPE_PRIO 0x24bc
#define MVNETA_FORCE_UNI BIT(21)
#define MVNETA_TXQ_CMD_1 0x24e4
@@ -173,7 +172,7 @@
/* Various constants */
/* Coalescing */
-#define MVNETA_TXDONE_COAL_PKTS 16
+#define MVNETA_TXDONE_COAL_PKTS 1
#define MVNETA_RX_COAL_PKTS 32
#define MVNETA_RX_COAL_USEC 100
@@ -666,6 +665,35 @@ static void mvneta_rxq_bm_disable(struct mvneta_port *pp,
mvreg_write(pp, MVNETA_RXQ_CONFIG_REG(rxq->id), val);
}
+
+
+/* Sets the RGMII Enable bit (RGMIIEn) in port MAC control register */
+static void mvneta_gmac_rgmii_set(struct mvneta_port *pp, int enable)
+{
+ u32 val;
+
+ val = mvreg_read(pp, MVNETA_GMAC_CTRL_2);
+
+ if (enable)
+ val |= MVNETA_GMAC2_PORT_RGMII;
+ else
+ val &= ~MVNETA_GMAC2_PORT_RGMII;
+
+ mvreg_write(pp, MVNETA_GMAC_CTRL_2, val);
+}
+
+/* Config SGMII port */
+static void mvneta_port_sgmii_config(struct mvneta_port *pp)
+{
+ u32 val;
+
+ val = mvreg_read(pp, MVNETA_GMAC_CTRL_2);
+ val |= MVNETA_GMAC2_PCS_ENABLE;
+ mvreg_write(pp, MVNETA_GMAC_CTRL_2, val);
+
+ mvreg_write(pp, MVNETA_SGMII_SERDES_CFG, MVNETA_SGMII_SERDES_PROTO);
+}
+
/* Start the Ethernet port RX and TX activity */
static void mvneta_port_up(struct mvneta_port *pp)
{
@@ -1496,6 +1524,7 @@ static int mvneta_tx(struct sk_buff *skb, struct net_device *dev)
struct mvneta_tx_queue *txq = &pp->txqs[txq_id];
struct mvneta_tx_desc *tx_desc;
struct netdev_queue *nq;
+ int len = skb->len;
int frags = 0;
u32 tx_cmd;
@@ -1556,7 +1585,7 @@ out:
if (frags > 0) {
u64_stats_update_begin(&pp->tx_stats.syncp);
pp->tx_stats.packets++;
- pp->tx_stats.bytes += skb->len;
+ pp->tx_stats.bytes += len;
u64_stats_update_end(&pp->tx_stats.syncp);
} else {
@@ -2330,7 +2359,7 @@ static void mvneta_adjust_link(struct net_device *ndev)
if (phydev->speed == SPEED_1000)
val |= MVNETA_GMAC_CONFIG_GMII_SPEED;
- else
+ else if (phydev->speed == SPEED_100)
val |= MVNETA_GMAC_CONFIG_MII_SPEED;
mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val);
@@ -2695,15 +2724,12 @@ static void mvneta_port_power_up(struct mvneta_port *pp, int phy_mode)
mvreg_write(pp, MVNETA_UNIT_INTR_CAUSE, 0);
if (phy_mode == PHY_INTERFACE_MODE_SGMII)
- mvreg_write(pp, MVNETA_SERDES_CFG, MVNETA_SGMII_SERDES_PROTO);
- else
- mvreg_write(pp, MVNETA_SERDES_CFG, MVNETA_RGMII_SERDES_PROTO);
+ mvneta_port_sgmii_config(pp);
- val = mvreg_read(pp, MVNETA_GMAC_CTRL_2);
-
- val |= MVNETA_GMAC2_PCS_ENABLE | MVNETA_GMAC2_PORT_RGMII;
+ mvneta_gmac_rgmii_set(pp, 1);
/* Cancel Port Reset */
+ val = mvreg_read(pp, MVNETA_GMAC_CTRL_2);
val &= ~MVNETA_GMAC2_PORT_RESET;
mvreg_write(pp, MVNETA_GMAC_CTRL_2, val);
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_cq.c b/drivers/net/ethernet/mellanox/mlx4/en_cq.c
index 3e2d504..d9303d8 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_cq.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_cq.c
@@ -55,7 +55,6 @@ int mlx4_en_create_cq(struct mlx4_en_priv *priv,
cq->ring = ring;
cq->is_tx = mode;
- spin_lock_init(&cq->lock);
err = mlx4_alloc_hwq_res(mdev->dev, &cq->wqres,
cq->buf_size, 2 * PAGE_SIZE);
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index fa37b7a..35d3821 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -1219,15 +1219,11 @@ static void mlx4_en_netpoll(struct net_device *dev)
{
struct mlx4_en_priv *priv = netdev_priv(dev);
struct mlx4_en_cq *cq;
- unsigned long flags;
int i;
for (i = 0; i < priv->rx_ring_num; i++) {
cq = &priv->rx_cq[i];
- spin_lock_irqsave(&cq->lock, flags);
- napi_synchronize(&cq->napi);
- mlx4_en_process_rx_cq(dev, cq, 0);
- spin_unlock_irqrestore(&cq->lock, flags);
+ napi_schedule(&cq->napi);
}
}
#endif
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
index bf06e36..a47455f 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
@@ -306,7 +306,6 @@ struct mlx4_en_cq {
struct mlx4_cq mcq;
struct mlx4_hwq_resources wqres;
int ring;
- spinlock_t lock;
struct net_device *dev;
struct napi_struct napi;
int size;
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
index dd68763..cdbe637 100644
--- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
+++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
@@ -1227,7 +1227,7 @@ static int qp_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
switch (op) {
case RES_OP_RESERVE:
- count = get_param_l(&in_param);
+ count = get_param_l(&in_param) & 0xffffff;
align = get_param_h(&in_param);
err = __mlx4_qp_reserve_range(dev, count, align, &base);
if (err)
diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
index 149355b..c155b92 100644
--- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
+++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
@@ -872,6 +872,10 @@ static int myri10ge_dma_test(struct myri10ge_priv *mgp, int test_type)
return -ENOMEM;
dmatest_bus = pci_map_page(mgp->pdev, dmatest_page, 0, PAGE_SIZE,
DMA_BIDIRECTIONAL);
+ if (unlikely(pci_dma_mapping_error(mgp->pdev, dmatest_bus))) {
+ __free_page(dmatest_page);
+ return -ENOMEM;
+ }
/* Run a small DMA test.
* The magic multipliers to the length tell the firmware
@@ -1293,6 +1297,7 @@ myri10ge_alloc_rx_pages(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx,
int bytes, int watchdog)
{
struct page *page;
+ dma_addr_t bus;
int idx;
#if MYRI10GE_ALLOC_SIZE > 4096
int end_offset;
@@ -1317,11 +1322,21 @@ myri10ge_alloc_rx_pages(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx,
rx->watchdog_needed = 1;
return;
}
+
+ bus = pci_map_page(mgp->pdev, page, 0,
+ MYRI10GE_ALLOC_SIZE,
+ PCI_DMA_FROMDEVICE);
+ if (unlikely(pci_dma_mapping_error(mgp->pdev, bus))) {
+ __free_pages(page, MYRI10GE_ALLOC_ORDER);
+ if (rx->fill_cnt - rx->cnt < 16)
+ rx->watchdog_needed = 1;
+ return;
+ }
+
rx->page = page;
rx->page_offset = 0;
- rx->bus = pci_map_page(mgp->pdev, page, 0,
- MYRI10GE_ALLOC_SIZE,
- PCI_DMA_FROMDEVICE);
+ rx->bus = bus;
+
}
rx->info[idx].page = rx->page;
rx->info[idx].page_offset = rx->page_offset;
@@ -2765,6 +2780,35 @@ myri10ge_submit_req(struct myri10ge_tx_buf *tx, struct mcp_kreq_ether_send *src,
mb();
}
+static void myri10ge_unmap_tx_dma(struct myri10ge_priv *mgp,
+ struct myri10ge_tx_buf *tx, int idx)
+{
+ unsigned int len;
+ int last_idx;
+
+ /* Free any DMA resources we've alloced and clear out the skb slot */
+ last_idx = (idx + 1) & tx->mask;
+ idx = tx->req & tx->mask;
+ do {
+ len = dma_unmap_len(&tx->info[idx], len);
+ if (len) {
+ if (tx->info[idx].skb != NULL)
+ pci_unmap_single(mgp->pdev,
+ dma_unmap_addr(&tx->info[idx],
+ bus), len,
+ PCI_DMA_TODEVICE);
+ else
+ pci_unmap_page(mgp->pdev,
+ dma_unmap_addr(&tx->info[idx],
+ bus), len,
+ PCI_DMA_TODEVICE);
+ dma_unmap_len_set(&tx->info[idx], len, 0);
+ tx->info[idx].skb = NULL;
+ }
+ idx = (idx + 1) & tx->mask;
+ } while (idx != last_idx);
+}
+
/*
* Transmit a packet. We need to split the packet so that a single
* segment does not cross myri10ge->tx_boundary, so this makes segment
@@ -2788,7 +2832,7 @@ static netdev_tx_t myri10ge_xmit(struct sk_buff *skb,
u32 low;
__be32 high_swapped;
unsigned int len;
- int idx, last_idx, avail, frag_cnt, frag_idx, count, mss, max_segments;
+ int idx, avail, frag_cnt, frag_idx, count, mss, max_segments;
u16 pseudo_hdr_offset, cksum_offset, queue;
int cum_len, seglen, boundary, rdma_count;
u8 flags, odd_flag;
@@ -2885,9 +2929,12 @@ again:
/* map the skb for DMA */
len = skb_headlen(skb);
+ bus = pci_map_single(mgp->pdev, skb->data, len, PCI_DMA_TODEVICE);
+ if (unlikely(pci_dma_mapping_error(mgp->pdev, bus)))
+ goto drop;
+
idx = tx->req & tx->mask;
tx->info[idx].skb = skb;
- bus = pci_map_single(mgp->pdev, skb->data, len, PCI_DMA_TODEVICE);
dma_unmap_addr_set(&tx->info[idx], bus, bus);
dma_unmap_len_set(&tx->info[idx], len, len);
@@ -2986,12 +3033,16 @@ again:
break;
/* map next fragment for DMA */
- idx = (count + tx->req) & tx->mask;
frag = &skb_shinfo(skb)->frags[frag_idx];
frag_idx++;
len = skb_frag_size(frag);
bus = skb_frag_dma_map(&mgp->pdev->dev, frag, 0, len,
DMA_TO_DEVICE);
+ if (unlikely(pci_dma_mapping_error(mgp->pdev, bus))) {
+ myri10ge_unmap_tx_dma(mgp, tx, idx);
+ goto drop;
+ }
+ idx = (count + tx->req) & tx->mask;
dma_unmap_addr_set(&tx->info[idx], bus, bus);
dma_unmap_len_set(&tx->info[idx], len, len);
}
@@ -3022,31 +3073,8 @@ again:
return NETDEV_TX_OK;
abort_linearize:
- /* Free any DMA resources we've alloced and clear out the skb
- * slot so as to not trip up assertions, and to avoid a
- * double-free if linearizing fails */
+ myri10ge_unmap_tx_dma(mgp, tx, idx);
- last_idx = (idx + 1) & tx->mask;
- idx = tx->req & tx->mask;
- tx->info[idx].skb = NULL;
- do {
- len = dma_unmap_len(&tx->info[idx], len);
- if (len) {
- if (tx->info[idx].skb != NULL)
- pci_unmap_single(mgp->pdev,
- dma_unmap_addr(&tx->info[idx],
- bus), len,
- PCI_DMA_TODEVICE);
- else
- pci_unmap_page(mgp->pdev,
- dma_unmap_addr(&tx->info[idx],
- bus), len,
- PCI_DMA_TODEVICE);
- dma_unmap_len_set(&tx->info[idx], len, 0);
- tx->info[idx].skb = NULL;
- }
- idx = (idx + 1) & tx->mask;
- } while (idx != last_idx);
if (skb_is_gso(skb)) {
netdev_err(mgp->dev, "TSO but wanted to linearize?!?!?\n");
goto drop;
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c
index 7692dfd..cc68657 100644
--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c
+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c
@@ -1604,13 +1604,13 @@ netxen_process_lro(struct netxen_adapter *adapter,
u32 seq_number;
u8 vhdr_len = 0;
- if (unlikely(ring > adapter->max_rds_rings))
+ if (unlikely(ring >= adapter->max_rds_rings))
return NULL;
rds_ring = &recv_ctx->rds_rings[ring];
index = netxen_get_lro_sts_refhandle(sts_data0);
- if (unlikely(index > rds_ring->num_desc))
+ if (unlikely(index >= rds_ring->num_desc))
return NULL;
buffer = &rds_ring->rx_buf_arr[index];
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c
index d62d5ce..d677eab 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c
@@ -1053,6 +1053,7 @@ static int qlcnic_dcb_peer_app_info(struct net_device *netdev,
struct qlcnic_dcb_cee *peer;
int i;
+ memset(info, 0, sizeof(*info));
*app_count = 0;
if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index b57c278..36119b3 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -247,6 +247,27 @@ static const u16 sh_eth_offset_fast_sh4[SH_ETH_MAX_REGISTER_OFFSET] = {
};
static const u16 sh_eth_offset_fast_sh3_sh2[SH_ETH_MAX_REGISTER_OFFSET] = {
+ [EDMR] = 0x0000,
+ [EDTRR] = 0x0004,
+ [EDRRR] = 0x0008,
+ [TDLAR] = 0x000c,
+ [RDLAR] = 0x0010,
+ [EESR] = 0x0014,
+ [EESIPR] = 0x0018,
+ [TRSCER] = 0x001c,
+ [RMFCR] = 0x0020,
+ [TFTR] = 0x0024,
+ [FDR] = 0x0028,
+ [RMCR] = 0x002c,
+ [EDOCR] = 0x0030,
+ [FCFTR] = 0x0034,
+ [RPADIR] = 0x0038,
+ [TRIMD] = 0x003c,
+ [RBWAR] = 0x0040,
+ [RDFAR] = 0x0044,
+ [TBRAR] = 0x004c,
+ [TDFAR] = 0x0050,
+
[ECMR] = 0x0160,
[ECSR] = 0x0164,
[ECSIPR] = 0x0168,
@@ -483,7 +504,6 @@ static struct sh_eth_cpu_data sh7757_data = {
.register_type = SH_ETH_REG_FAST_SH4,
.eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
- .rmcr_value = 0x00000001,
.tx_check = EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO,
.eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE |
@@ -561,7 +581,6 @@ static struct sh_eth_cpu_data sh7757_data_giga = {
EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE |
EESR_TDE | EESR_ECI,
.fdr_value = 0x0000072f,
- .rmcr_value = 0x00000001,
.irq_flags = IRQF_SHARED,
.apr = 1,
@@ -689,7 +708,6 @@ static struct sh_eth_cpu_data r8a7740_data = {
EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE |
EESR_TDE | EESR_ECI,
.fdr_value = 0x0000070f,
- .rmcr_value = 0x00000001,
.apr = 1,
.mpr = 1,
@@ -738,9 +756,6 @@ static void sh_eth_set_default_cpu_data(struct sh_eth_cpu_data *cd)
if (!cd->fdr_value)
cd->fdr_value = DEFAULT_FDR_INIT;
- if (!cd->rmcr_value)
- cd->rmcr_value = DEFAULT_RMCR_VALUE;
-
if (!cd->tx_check)
cd->tx_check = DEFAULT_TX_CHECK;
@@ -1193,8 +1208,8 @@ static int sh_eth_dev_init(struct net_device *ndev, bool start)
sh_eth_write(ndev, mdp->cd->fdr_value, FDR);
sh_eth_write(ndev, 0, TFTR);
- /* Frame recv control */
- sh_eth_write(ndev, mdp->cd->rmcr_value, RMCR);
+ /* Frame recv control (enable multiple-packets per rx irq) */
+ sh_eth_write(ndev, 0x00000001, RMCR);
sh_eth_write(ndev, DESC_I_RINT8 | DESC_I_RINT5 | DESC_I_TINT2, TRSCER);
diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h
index a0db02c..8cd5ad2 100644
--- a/drivers/net/ethernet/renesas/sh_eth.h
+++ b/drivers/net/ethernet/renesas/sh_eth.h
@@ -321,7 +321,6 @@ enum TD_STS_BIT {
#define TD_TFP (TD_TFP1|TD_TFP0)
/* RMCR */
-#define DEFAULT_RMCR_VALUE 0x00000000
/* ECMR */
enum FELIC_MODE_BIT {
@@ -470,7 +469,6 @@ struct sh_eth_cpu_data {
unsigned long fdr_value;
unsigned long fcftr_value;
unsigned long rpadir_value;
- unsigned long rmcr_value;
/* interrupt checking mask */
unsigned long tx_check;
diff --git a/drivers/net/ethernet/sfc/nic.c b/drivers/net/ethernet/sfc/nic.c
index 9826594..6508717 100644
--- a/drivers/net/ethernet/sfc/nic.c
+++ b/drivers/net/ethernet/sfc/nic.c
@@ -155,13 +155,15 @@ void efx_nic_fini_interrupt(struct efx_nic *efx)
efx->net_dev->rx_cpu_rmap = NULL;
#endif
- /* Disable MSI/MSI-X interrupts */
- efx_for_each_channel(channel, efx)
- free_irq(channel->irq, &efx->msi_context[channel->channel]);
-
- /* Disable legacy interrupt */
- if (efx->legacy_irq)
+ if (EFX_INT_MODE_USE_MSI(efx)) {
+ /* Disable MSI/MSI-X interrupts */
+ efx_for_each_channel(channel, efx)
+ free_irq(channel->irq,
+ &efx->msi_context[channel->channel]);
+ } else {
+ /* Disable legacy interrupt */
free_irq(efx->legacy_irq, efx);
+ }
}
/* Register dump */
diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c
index 3df5684..ade8bdf 100644
--- a/drivers/net/ethernet/sun/sunvnet.c
+++ b/drivers/net/ethernet/sun/sunvnet.c
@@ -656,7 +656,7 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
spin_lock_irqsave(&port->vio.lock, flags);
dr = &port->vio.drings[VIO_DRIVER_TX_RING];
- if (unlikely(vnet_tx_dring_avail(dr) < 2)) {
+ if (unlikely(vnet_tx_dring_avail(dr) < 1)) {
if (!netif_queue_stopped(dev)) {
netif_stop_queue(dev);
@@ -704,7 +704,7 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
dev->stats.tx_bytes += skb->len;
dr->prod = (dr->prod + 1) & (VNET_TX_RING_SIZE - 1);
- if (unlikely(vnet_tx_dring_avail(dr) < 2)) {
+ if (unlikely(vnet_tx_dring_avail(dr) < 1)) {
netif_stop_queue(dev);
if (vnet_tx_dring_avail(dr) > VNET_TX_WAKEUP_THRESH(dr))
netif_wake_queue(dev);
@@ -1083,6 +1083,24 @@ static struct vnet *vnet_find_or_create(const u64 *local_mac)
return vp;
}
+static void vnet_cleanup(void)
+{
+ struct vnet *vp;
+ struct net_device *dev;
+
+ mutex_lock(&vnet_list_mutex);
+ while (!list_empty(&vnet_list)) {
+ vp = list_first_entry(&vnet_list, struct vnet, list);
+ list_del(&vp->list);
+ dev = vp->dev;
+ /* vio_unregister_driver() should have cleaned up port_list */
+ BUG_ON(!list_empty(&vp->port_list));
+ unregister_netdev(dev);
+ free_netdev(dev);
+ }
+ mutex_unlock(&vnet_list_mutex);
+}
+
static const char *local_mac_prop = "local-mac-address";
static struct vnet *vnet_find_parent(struct mdesc_handle *hp,
@@ -1240,7 +1258,6 @@ static int vnet_port_remove(struct vio_dev *vdev)
kfree(port);
- unregister_netdev(vp->dev);
}
return 0;
}
@@ -1268,6 +1285,7 @@ static int __init vnet_init(void)
static void __exit vnet_exit(void)
{
vio_unregister_driver(&vnet_port_driver);
+ vnet_cleanup();
}
module_init(vnet_init);
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index cc3ce55..07cd14d 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -546,6 +546,12 @@ static inline int cpsw_get_slave_port(struct cpsw_priv *priv, u32 slave_num)
static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
{
struct cpsw_priv *priv = netdev_priv(ndev);
+ int vid;
+
+ if (priv->data.dual_emac)
+ vid = priv->slaves[priv->emac_port].port_vlan;
+ else
+ vid = priv->data.default_vlan;
if (ndev->flags & IFF_PROMISC) {
/* Enable promiscuous mode */
@@ -554,7 +560,8 @@ static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
}
/* Clear all mcast from ALE */
- cpsw_ale_flush_multicast(priv->ale, ALE_ALL_PORTS << priv->host_port);
+ cpsw_ale_flush_multicast(priv->ale, ALE_ALL_PORTS << priv->host_port,
+ vid);
if (!netdev_mc_empty(ndev)) {
struct netdev_hw_addr *ha;
@@ -639,6 +646,14 @@ void cpsw_rx_handler(void *token, int len, int status)
static irqreturn_t cpsw_interrupt(int irq, void *dev_id)
{
struct cpsw_priv *priv = dev_id;
+ int value = irq - priv->irqs_table[0];
+
+ /* NOTICE: Ending IRQ here. The trick with the 'value' variable above
+ * is to make sure we will always write the correct value to the EOI
+ * register. Namely 0 for RX_THRESH Interrupt, 1 for RX Interrupt, 2
+ * for TX Interrupt and 3 for MISC Interrupt.
+ */
+ cpdma_ctlr_eoi(priv->dma, value);
cpsw_intr_disable(priv);
if (priv->irq_enabled == true) {
@@ -668,8 +683,6 @@ static int cpsw_poll(struct napi_struct *napi, int budget)
int num_tx, num_rx;
num_tx = cpdma_chan_process(priv->txch, 128);
- if (num_tx)
- cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX);
num_rx = cpdma_chan_process(priv->rxch, budget);
if (num_rx < budget) {
@@ -677,7 +690,6 @@ static int cpsw_poll(struct napi_struct *napi, int budget)
napi_complete(napi);
cpsw_intr_enable(priv);
- cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX);
prim_cpsw = cpsw_get_slave_priv(priv, 0);
if (prim_cpsw->irq_enabled == false) {
prim_cpsw->irq_enabled = true;
@@ -1165,8 +1177,6 @@ static int cpsw_ndo_open(struct net_device *ndev)
napi_enable(&priv->napi);
cpdma_ctlr_start(priv->dma);
cpsw_intr_enable(priv);
- cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX);
- cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX);
if (priv->data.dual_emac)
priv->slaves[priv->emac_port].open_stat = true;
@@ -1416,9 +1426,6 @@ static void cpsw_ndo_tx_timeout(struct net_device *ndev)
cpdma_chan_start(priv->txch);
cpdma_ctlr_int_ctrl(priv->dma, true);
cpsw_intr_enable(priv);
- cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX);
- cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX);
-
}
static int cpsw_ndo_set_mac_address(struct net_device *ndev, void *p)
@@ -1464,9 +1471,6 @@ static void cpsw_ndo_poll_controller(struct net_device *ndev)
cpsw_interrupt(ndev->irq, priv);
cpdma_ctlr_int_ctrl(priv->dma, true);
cpsw_intr_enable(priv);
- cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX);
- cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX);
-
}
#endif
@@ -1797,6 +1801,10 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data,
mdio_node = of_find_node_by_phandle(be32_to_cpup(parp));
phyid = be32_to_cpup(parp+1);
mdio = of_find_device_by_node(mdio_node);
+ if (!mdio) {
+ pr_err("Missing mdio platform device\n");
+ return -EINVAL;
+ }
snprintf(slave_data->phy_id, sizeof(slave_data->phy_id),
PHY_ID_FMT, mdio->name, phyid);
diff --git a/drivers/net/ethernet/ti/cpsw_ale.c b/drivers/net/ethernet/ti/cpsw_ale.c
index 7fa60d6..f7acf76 100644
--- a/drivers/net/ethernet/ti/cpsw_ale.c
+++ b/drivers/net/ethernet/ti/cpsw_ale.c
@@ -236,7 +236,7 @@ static void cpsw_ale_flush_mcast(struct cpsw_ale *ale, u32 *ale_entry,
cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE);
}
-int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask)
+int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask, int vid)
{
u32 ale_entry[ALE_ENTRY_WORDS];
int ret, idx;
@@ -247,6 +247,14 @@ int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask)
if (ret != ALE_TYPE_ADDR && ret != ALE_TYPE_VLAN_ADDR)
continue;
+ /* if vid passed is -1 then remove all multicast entry from
+ * the table irrespective of vlan id, if a valid vlan id is
+ * passed then remove only multicast added to that vlan id.
+ * if vlan id doesn't match then move on to next entry.
+ */
+ if (vid != -1 && cpsw_ale_get_vlan_id(ale_entry) != vid)
+ continue;
+
if (cpsw_ale_get_mcast(ale_entry)) {
u8 addr[6];
diff --git a/drivers/net/ethernet/ti/cpsw_ale.h b/drivers/net/ethernet/ti/cpsw_ale.h
index 30daa12..20c7976 100644
--- a/drivers/net/ethernet/ti/cpsw_ale.h
+++ b/drivers/net/ethernet/ti/cpsw_ale.h
@@ -86,7 +86,7 @@ void cpsw_ale_stop(struct cpsw_ale *ale);
int cpsw_ale_set_ageout(struct cpsw_ale *ale, int ageout);
int cpsw_ale_flush(struct cpsw_ale *ale, int port_mask);
-int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask);
+int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask, int vid);
int cpsw_ale_add_ucast(struct cpsw_ale *ale, u8 *addr, int port,
int flags, u16 vid);
int cpsw_ale_del_ucast(struct cpsw_ale *ale, u8 *addr, int port,
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index f813572..616b4e1 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -138,6 +138,7 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
struct hv_netvsc_packet *packet;
int ret;
unsigned int i, num_pages, npg_data;
+ u32 skb_length = skb->len;
/* Add multipages for skb->data and additional 2 for RNDIS */
npg_data = (((unsigned long)skb->data + skb_headlen(skb) - 1)
@@ -208,7 +209,7 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
ret = rndis_filter_send(net_device_ctx->device_ctx,
packet);
if (ret == 0) {
- net->stats.tx_bytes += skb->len;
+ net->stats.tx_bytes += skb_length;
net->stats.tx_packets++;
} else {
kfree(packet);
diff --git a/drivers/net/ieee802154/fakehard.c b/drivers/net/ieee802154/fakehard.c
index bf0d55e..6adbef8 100644
--- a/drivers/net/ieee802154/fakehard.c
+++ b/drivers/net/ieee802154/fakehard.c
@@ -376,17 +376,20 @@ static int ieee802154fake_probe(struct platform_device *pdev)
err = wpan_phy_register(phy);
if (err)
- goto out;
+ goto err_phy_reg;
err = register_netdev(dev);
- if (err < 0)
- goto out;
+ if (err)
+ goto err_netdev_reg;
dev_info(&pdev->dev, "Added ieee802154 HardMAC hardware\n");
return 0;
-out:
- unregister_netdev(dev);
+err_netdev_reg:
+ wpan_phy_unregister(phy);
+err_phy_reg:
+ free_netdev(dev);
+ wpan_phy_free(phy);
return err;
}
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 9bf46bd..1124ea0 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -263,11 +263,9 @@ static int macvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev)
const struct macvlan_dev *vlan = netdev_priv(dev);
const struct macvlan_port *port = vlan->port;
const struct macvlan_dev *dest;
- __u8 ip_summed = skb->ip_summed;
if (vlan->mode == MACVLAN_MODE_BRIDGE) {
const struct ethhdr *eth = (void *)skb->data;
- skb->ip_summed = CHECKSUM_UNNECESSARY;
/* send to other bridge ports directly */
if (is_multicast_ether_addr(eth->h_dest)) {
@@ -285,7 +283,6 @@ static int macvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev)
}
xmit_world:
- skb->ip_summed = ip_summed;
skb->dev = vlan->lowerdev;
return dev_queue_xmit(skb);
}
@@ -428,8 +425,10 @@ static void macvlan_change_rx_flags(struct net_device *dev, int change)
struct macvlan_dev *vlan = netdev_priv(dev);
struct net_device *lowerdev = vlan->lowerdev;
- if (change & IFF_ALLMULTI)
- dev_set_allmulti(lowerdev, dev->flags & IFF_ALLMULTI ? 1 : -1);
+ if (dev->flags & IFF_UP) {
+ if (change & IFF_ALLMULTI)
+ dev_set_allmulti(lowerdev, dev->flags & IFF_ALLMULTI ? 1 : -1);
+ }
}
static void macvlan_set_mac_lists(struct net_device *dev)
@@ -506,6 +505,7 @@ static int macvlan_init(struct net_device *dev)
(lowerdev->state & MACVLAN_STATE_MASK);
dev->features = lowerdev->features & MACVLAN_FEATURES;
dev->features |= NETIF_F_LLTX;
+ dev->vlan_features = lowerdev->vlan_features & MACVLAN_FEATURES;
dev->gso_max_size = lowerdev->gso_max_size;
dev->iflink = lowerdev->ifindex;
dev->hard_header_len = lowerdev->hard_header_len;
@@ -992,7 +992,6 @@ static int macvlan_device_event(struct notifier_block *unused,
list_for_each_entry_safe(vlan, next, &port->vlans, list)
vlan->dev->rtnl_link_ops->dellink(vlan->dev, &list_kill);
unregister_netdevice_many(&list_kill);
- list_del(&list_kill);
break;
case NETDEV_PRE_TYPE_CHANGE:
/* Forbid underlaying device to change its type. */
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
index 5895e4d..89d21fc 100644
--- a/drivers/net/macvtap.c
+++ b/drivers/net/macvtap.c
@@ -17,6 +17,7 @@
#include <linux/idr.h>
#include <linux/fs.h>
+#include <net/ipv6.h>
#include <net/net_namespace.h>
#include <net/rtnetlink.h>
#include <net/sock.h>
@@ -108,17 +109,15 @@ out:
return err;
}
+/* Requires RTNL */
static int macvtap_set_queue(struct net_device *dev, struct file *file,
struct macvtap_queue *q)
{
struct macvlan_dev *vlan = netdev_priv(dev);
- int err = -EBUSY;
- rtnl_lock();
if (vlan->numqueues == MAX_MACVTAP_QUEUES)
- goto out;
+ return -EBUSY;
- err = 0;
rcu_assign_pointer(q->vlan, vlan);
rcu_assign_pointer(vlan->taps[vlan->numvtaps], q);
sock_hold(&q->sk);
@@ -132,9 +131,7 @@ static int macvtap_set_queue(struct net_device *dev, struct file *file,
vlan->numvtaps++;
vlan->numqueues++;
-out:
- rtnl_unlock();
- return err;
+ return 0;
}
static int macvtap_disable_queue(struct macvtap_queue *q)
@@ -315,6 +312,15 @@ static int macvtap_forward(struct net_device *dev, struct sk_buff *skb)
segs = nskb;
}
} else {
+ /* If we receive a partial checksum and the tap side
+ * doesn't support checksum offload, compute the checksum.
+ * Note: it doesn't matter which checksum feature to
+ * check, we either support them all or none.
+ */
+ if (skb->ip_summed == CHECKSUM_PARTIAL &&
+ !(features & NETIF_F_ALL_CSUM) &&
+ skb_checksum_help(skb))
+ goto drop;
skb_queue_tail(&q->sk.sk_receive_queue, skb);
}
@@ -441,11 +447,12 @@ static void macvtap_sock_destruct(struct sock *sk)
static int macvtap_open(struct inode *inode, struct file *file)
{
struct net *net = current->nsproxy->net_ns;
- struct net_device *dev = dev_get_by_macvtap_minor(iminor(inode));
+ struct net_device *dev;
struct macvtap_queue *q;
- int err;
+ int err = -ENODEV;
- err = -ENODEV;
+ rtnl_lock();
+ dev = dev_get_by_macvtap_minor(iminor(inode));
if (!dev)
goto out;
@@ -485,6 +492,7 @@ out:
if (dev)
dev_put(dev);
+ rtnl_unlock();
return err;
}
@@ -559,6 +567,8 @@ static int macvtap_skb_from_vnet_hdr(struct sk_buff *skb,
break;
case VIRTIO_NET_HDR_GSO_UDP:
gso_type = SKB_GSO_UDP;
+ if (skb->protocol == htons(ETH_P_IPV6))
+ ipv6_proxy_select_ident(skb);
break;
default:
return -EINVAL;
@@ -615,6 +625,8 @@ static int macvtap_skb_to_vnet_hdr(const struct sk_buff *skb,
if (skb->ip_summed == CHECKSUM_PARTIAL) {
vnet_hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
vnet_hdr->csum_start = skb_checksum_start_offset(skb);
+ if (vlan_tx_tag_present(skb))
+ vnet_hdr->csum_start += VLAN_HLEN;
vnet_hdr->csum_offset = skb->csum_offset;
} else if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
vnet_hdr->flags = VIRTIO_NET_HDR_F_DATA_VALID;
diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
index 936f091..cceae07 100644
--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
@@ -604,7 +604,7 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
if (file == ppp->owner)
ppp_shutdown_interface(ppp);
}
- if (atomic_long_read(&file->f_count) <= 2) {
+ if (atomic_long_read(&file->f_count) < 2) {
ppp_release(NULL, file);
err = 0;
} else
diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c
index 82ee6ed..addd232 100644
--- a/drivers/net/ppp/pppoe.c
+++ b/drivers/net/ppp/pppoe.c
@@ -675,7 +675,7 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr,
po->chan.hdrlen = (sizeof(struct pppoe_hdr) +
dev->hard_header_len);
- po->chan.mtu = dev->mtu - sizeof(struct pppoe_hdr);
+ po->chan.mtu = dev->mtu - sizeof(struct pppoe_hdr) - 2;
po->chan.private = sk;
po->chan.ops = &pppoe_chan_ops;
diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c
index 0180531..1dc628f 100644
--- a/drivers/net/ppp/pptp.c
+++ b/drivers/net/ppp/pptp.c
@@ -281,7 +281,7 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
nf_reset(skb);
skb->ip_summed = CHECKSUM_NONE;
- ip_select_ident(skb, &rt->dst, NULL);
+ ip_select_ident(skb, NULL);
ip_send_check(iph);
ip_local_out(skb);
@@ -506,7 +506,9 @@ static int pptp_getname(struct socket *sock, struct sockaddr *uaddr,
int len = sizeof(struct sockaddr_pppox);
struct sockaddr_pppox sp;
- sp.sa_family = AF_PPPOX;
+ memset(&sp.sa_addr, 0, sizeof(sp.sa_addr));
+
+ sp.sa_family = AF_PPPOX;
sp.sa_protocol = PX_PROTO_PPTP;
sp.sa_addr.pptp = pppox_sk(sock->sk)->proto.pptp.src_addr;
diff --git a/drivers/net/slip/slip.c b/drivers/net/slip/slip.c
index cc70ecf..8752644 100644
--- a/drivers/net/slip/slip.c
+++ b/drivers/net/slip/slip.c
@@ -83,6 +83,7 @@
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/slab.h>
+#include <linux/workqueue.h>
#include "slip.h"
#ifdef CONFIG_INET
#include <linux/ip.h>
@@ -416,34 +417,44 @@ static void sl_encaps(struct slip *sl, unsigned char *icp, int len)
#endif
}
-/*
- * Called by the driver when there's room for more data. If we have
- * more packets to send, we send them here.
- */
-static void slip_write_wakeup(struct tty_struct *tty)
+/* Write out any remaining transmit buffer. Scheduled when tty is writable */
+static void slip_transmit(struct work_struct *work)
{
+ struct slip *sl = container_of(work, struct slip, tx_work);
int actual;
- struct slip *sl = tty->disc_data;
+ spin_lock_bh(&sl->lock);
/* First make sure we're connected. */
- if (!sl || sl->magic != SLIP_MAGIC || !netif_running(sl->dev))
+ if (!sl->tty || sl->magic != SLIP_MAGIC || !netif_running(sl->dev)) {
+ spin_unlock_bh(&sl->lock);
return;
+ }
- spin_lock(&sl->lock);
if (sl->xleft <= 0) {
/* Now serial buffer is almost free & we can start
* transmission of another packet */
sl->dev->stats.tx_packets++;
- clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
- spin_unlock(&sl->lock);
+ clear_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags);
+ spin_unlock_bh(&sl->lock);
sl_unlock(sl);
return;
}
- actual = tty->ops->write(tty, sl->xhead, sl->xleft);
+ actual = sl->tty->ops->write(sl->tty, sl->xhead, sl->xleft);
sl->xleft -= actual;
sl->xhead += actual;
- spin_unlock(&sl->lock);
+ spin_unlock_bh(&sl->lock);
+}
+
+/*
+ * Called by the driver when there's room for more data.
+ * Schedule the transmit.
+ */
+static void slip_write_wakeup(struct tty_struct *tty)
+{
+ struct slip *sl = tty->disc_data;
+
+ schedule_work(&sl->tx_work);
}
static void sl_tx_timeout(struct net_device *dev)
@@ -749,6 +760,7 @@ static struct slip *sl_alloc(dev_t line)
sl->magic = SLIP_MAGIC;
sl->dev = dev;
spin_lock_init(&sl->lock);
+ INIT_WORK(&sl->tx_work, slip_transmit);
sl->mode = SL_MODE_DEFAULT;
#ifdef CONFIG_SLIP_SMART
/* initialize timer_list struct */
@@ -872,8 +884,12 @@ static void slip_close(struct tty_struct *tty)
if (!sl || sl->magic != SLIP_MAGIC || sl->tty != tty)
return;
+ spin_lock_bh(&sl->lock);
tty->disc_data = NULL;
sl->tty = NULL;
+ spin_unlock_bh(&sl->lock);
+
+ flush_work(&sl->tx_work);
/* VSV = very important to remove timers */
#ifdef CONFIG_SLIP_SMART
diff --git a/drivers/net/slip/slip.h b/drivers/net/slip/slip.h
index 67673cf..cf32aad 100644
--- a/drivers/net/slip/slip.h
+++ b/drivers/net/slip/slip.h
@@ -53,6 +53,7 @@ struct slip {
struct tty_struct *tty; /* ptr to TTY structure */
struct net_device *dev; /* easy for intr handling */
spinlock_t lock;
+ struct work_struct tx_work; /* Flushes transmit buffer */
#ifdef SL_INCLUDE_CSLIP
struct slcompress *slcomp; /* for header compression */
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index 6327df2..258f65b 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -629,6 +629,7 @@ static int team_change_mode(struct team *team, const char *kind)
static void team_notify_peers_work(struct work_struct *work)
{
struct team *team;
+ int val;
team = container_of(work, struct team, notify_peers.dw.work);
@@ -636,9 +637,14 @@ static void team_notify_peers_work(struct work_struct *work)
schedule_delayed_work(&team->notify_peers.dw, 0);
return;
}
+ val = atomic_dec_if_positive(&team->notify_peers.count_pending);
+ if (val < 0) {
+ rtnl_unlock();
+ return;
+ }
call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, team->dev);
rtnl_unlock();
- if (!atomic_dec_and_test(&team->notify_peers.count_pending))
+ if (val)
schedule_delayed_work(&team->notify_peers.dw,
msecs_to_jiffies(team->notify_peers.interval));
}
@@ -647,7 +653,7 @@ static void team_notify_peers(struct team *team)
{
if (!team->notify_peers.count || !netif_running(team->dev))
return;
- atomic_set(&team->notify_peers.count_pending, team->notify_peers.count);
+ atomic_add(team->notify_peers.count, &team->notify_peers.count_pending);
schedule_delayed_work(&team->notify_peers.dw, 0);
}
@@ -669,6 +675,7 @@ static void team_notify_peers_fini(struct team *team)
static void team_mcast_rejoin_work(struct work_struct *work)
{
struct team *team;
+ int val;
team = container_of(work, struct team, mcast_rejoin.dw.work);
@@ -676,9 +683,14 @@ static void team_mcast_rejoin_work(struct work_struct *work)
schedule_delayed_work(&team->mcast_rejoin.dw, 0);
return;
}
+ val = atomic_dec_if_positive(&team->mcast_rejoin.count_pending);
+ if (val < 0) {
+ rtnl_unlock();
+ return;
+ }
call_netdevice_notifiers(NETDEV_RESEND_IGMP, team->dev);
rtnl_unlock();
- if (!atomic_dec_and_test(&team->mcast_rejoin.count_pending))
+ if (val)
schedule_delayed_work(&team->mcast_rejoin.dw,
msecs_to_jiffies(team->mcast_rejoin.interval));
}
@@ -687,7 +699,7 @@ static void team_mcast_rejoin(struct team *team)
{
if (!team->mcast_rejoin.count || !netif_running(team->dev))
return;
- atomic_set(&team->mcast_rejoin.count_pending, team->mcast_rejoin.count);
+ atomic_add(team->mcast_rejoin.count, &team->mcast_rejoin.count_pending);
schedule_delayed_work(&team->mcast_rejoin.dw, 0);
}
@@ -1725,6 +1737,7 @@ static int team_change_mtu(struct net_device *dev, int new_mtu)
* to traverse list in reverse under rcu_read_lock
*/
mutex_lock(&team->lock);
+ team->port_mtu_change_allowed = true;
list_for_each_entry(port, &team->port_list, list) {
err = dev_set_mtu(port->dev, new_mtu);
if (err) {
@@ -1733,6 +1746,7 @@ static int team_change_mtu(struct net_device *dev, int new_mtu)
goto unwind;
}
}
+ team->port_mtu_change_allowed = false;
mutex_unlock(&team->lock);
dev->mtu = new_mtu;
@@ -1742,6 +1756,7 @@ static int team_change_mtu(struct net_device *dev, int new_mtu)
unwind:
list_for_each_entry_continue_reverse(port, &team->port_list, list)
dev_set_mtu(port->dev, dev->mtu);
+ team->port_mtu_change_allowed = false;
mutex_unlock(&team->lock);
return err;
@@ -2861,7 +2876,9 @@ static int team_device_event(struct notifier_block *unused,
break;
case NETDEV_CHANGEMTU:
/* Forbid to change mtu of underlaying device */
- return NOTIFY_BAD;
+ if (!port->team->port_mtu_change_allowed)
+ return NOTIFY_BAD;
+ break;
case NETDEV_PRE_TYPE_CHANGE:
/* Forbid to change type of underlaying device */
return NOTIFY_BAD;
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 10636cb..d72d063 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -65,6 +65,7 @@
#include <linux/nsproxy.h>
#include <linux/virtio_net.h>
#include <linux/rcupdate.h>
+#include <net/ipv6.h>
#include <net/net_namespace.h>
#include <net/netns/generic.h>
#include <net/rtnetlink.h>
@@ -1103,6 +1104,8 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
break;
}
+ skb_reset_network_header(skb);
+
if (gso.gso_type != VIRTIO_NET_HDR_GSO_NONE) {
pr_debug("GSO!\n");
switch (gso.gso_type & ~VIRTIO_NET_HDR_GSO_ECN) {
@@ -1114,6 +1117,8 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
break;
case VIRTIO_NET_HDR_GSO_UDP:
skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
+ if (skb->protocol == htons(ETH_P_IPV6))
+ ipv6_proxy_select_ident(skb);
break;
default:
tun->dev->stats.rx_frame_errors++;
@@ -1143,7 +1148,6 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG;
}
- skb_reset_network_header(skb);
skb_probe_transport_header(skb, 0);
rxhash = skb_get_rxhash(skb);
@@ -1185,6 +1189,10 @@ static ssize_t tun_put_user(struct tun_struct *tun,
struct tun_pi pi = { 0, skb->protocol };
ssize_t total = 0;
int vlan_offset = 0, copied;
+ int vlan_hlen = 0;
+
+ if (vlan_tx_tag_present(skb))
+ vlan_hlen = VLAN_HLEN;
if (!(tun->flags & TUN_NO_PI)) {
if ((len -= sizeof(pi)) < 0)
@@ -1236,7 +1244,8 @@ static ssize_t tun_put_user(struct tun_struct *tun,
if (skb->ip_summed == CHECKSUM_PARTIAL) {
gso.flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
- gso.csum_start = skb_checksum_start_offset(skb);
+ gso.csum_start = skb_checksum_start_offset(skb) +
+ vlan_hlen;
gso.csum_offset = skb->csum_offset;
} else if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
gso.flags = VIRTIO_NET_HDR_F_DATA_VALID;
@@ -1249,10 +1258,9 @@ static ssize_t tun_put_user(struct tun_struct *tun,
}
copied = total;
- total += skb->len;
- if (!vlan_tx_tag_present(skb)) {
- len = min_t(int, skb->len, len);
- } else {
+ len = min_t(int, skb->len + vlan_hlen, len);
+ total += skb->len + vlan_hlen;
+ if (vlan_hlen) {
int copy, ret;
struct {
__be16 h_vlan_proto;
@@ -1263,8 +1271,6 @@ static ssize_t tun_put_user(struct tun_struct *tun,
veth.h_vlan_TCI = htons(vlan_tx_tag_get(skb));
vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto);
- len = min_t(int, skb->len + VLAN_HLEN, len);
- total += VLAN_HLEN;
copy = min_t(int, vlan_offset, len);
ret = skb_copy_datagram_const_iovec(skb, 0, iv, copied, copy);
diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c
index 3ecb213..b8b8f99 100644
--- a/drivers/net/usb/ax88179_178a.c
+++ b/drivers/net/usb/ax88179_178a.c
@@ -698,6 +698,7 @@ static int ax88179_set_mac_addr(struct net_device *net, void *p)
{
struct usbnet *dev = netdev_priv(net);
struct sockaddr *addr = p;
+ int ret;
if (netif_running(net))
return -EBUSY;
@@ -707,8 +708,12 @@ static int ax88179_set_mac_addr(struct net_device *net, void *p)
memcpy(net->dev_addr, addr->sa_data, ETH_ALEN);
/* Set the MAC address */
- return ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN,
+ ret = ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN,
ETH_ALEN, net->dev_addr);
+ if (ret < 0)
+ return ret;
+
+ return 0;
}
static const struct net_device_ops ax88179_netdev_ops = {
diff --git a/drivers/net/usb/cdc_mbim.c b/drivers/net/usb/cdc_mbim.c
index 25ba7ec..7cabe45 100644
--- a/drivers/net/usb/cdc_mbim.c
+++ b/drivers/net/usb/cdc_mbim.c
@@ -120,6 +120,16 @@ static void cdc_mbim_unbind(struct usbnet *dev, struct usb_interface *intf)
cdc_ncm_unbind(dev, intf);
}
+/* verify that the ethernet protocol is IPv4 or IPv6 */
+static bool is_ip_proto(__be16 proto)
+{
+ switch (proto) {
+ case htons(ETH_P_IP):
+ case htons(ETH_P_IPV6):
+ return true;
+ }
+ return false;
+}
static struct sk_buff *cdc_mbim_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
{
@@ -128,6 +138,7 @@ static struct sk_buff *cdc_mbim_tx_fixup(struct usbnet *dev, struct sk_buff *skb
struct cdc_ncm_ctx *ctx = info->ctx;
__le32 sign = cpu_to_le32(USB_CDC_MBIM_NDP16_IPS_SIGN);
u16 tci = 0;
+ bool is_ip;
u8 *c;
if (!ctx)
@@ -137,25 +148,32 @@ static struct sk_buff *cdc_mbim_tx_fixup(struct usbnet *dev, struct sk_buff *skb
if (skb->len <= ETH_HLEN)
goto error;
+ /* Some applications using e.g. packet sockets will
+ * bypass the VLAN acceleration and create tagged
+ * ethernet frames directly. We primarily look for
+ * the accelerated out-of-band tag, but fall back if
+ * required
+ */
+ skb_reset_mac_header(skb);
+ if (vlan_get_tag(skb, &tci) < 0 && skb->len > VLAN_ETH_HLEN &&
+ __vlan_get_tag(skb, &tci) == 0) {
+ is_ip = is_ip_proto(vlan_eth_hdr(skb)->h_vlan_encapsulated_proto);
+ skb_pull(skb, VLAN_ETH_HLEN);
+ } else {
+ is_ip = is_ip_proto(eth_hdr(skb)->h_proto);
+ skb_pull(skb, ETH_HLEN);
+ }
+
/* mapping VLANs to MBIM sessions:
* no tag => IPS session <0>
* 1 - 255 => IPS session <vlanid>
* 256 - 511 => DSS session <vlanid - 256>
* 512 - 4095 => unsupported, drop
*/
- vlan_get_tag(skb, &tci);
-
switch (tci & 0x0f00) {
case 0x0000: /* VLAN ID 0 - 255 */
- /* verify that datagram is IPv4 or IPv6 */
- skb_reset_mac_header(skb);
- switch (eth_hdr(skb)->h_proto) {
- case htons(ETH_P_IP):
- case htons(ETH_P_IPV6):
- break;
- default:
+ if (!is_ip)
goto error;
- }
c = (u8 *)&sign;
c[3] = tci;
break;
@@ -169,7 +187,6 @@ static struct sk_buff *cdc_mbim_tx_fixup(struct usbnet *dev, struct sk_buff *skb
"unsupported tci=0x%04x\n", tci);
goto error;
}
- skb_pull(skb, ETH_HLEN);
}
spin_lock_bh(&ctx->mtx);
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index 558469f..7f22d27 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -647,8 +647,25 @@ static const struct usb_device_id products[] = {
{QMI_FIXED_INTF(0x05c6, 0x9084, 4)},
{QMI_FIXED_INTF(0x05c6, 0x920d, 0)},
{QMI_FIXED_INTF(0x05c6, 0x920d, 5)},
+ {QMI_FIXED_INTF(0x0846, 0x68a2, 8)},
{QMI_FIXED_INTF(0x12d1, 0x140c, 1)}, /* Huawei E173 */
{QMI_FIXED_INTF(0x12d1, 0x14ac, 1)}, /* Huawei E1820 */
+ {QMI_FIXED_INTF(0x16d8, 0x6003, 0)}, /* CMOTech 6003 */
+ {QMI_FIXED_INTF(0x16d8, 0x6007, 0)}, /* CMOTech CHE-628S */
+ {QMI_FIXED_INTF(0x16d8, 0x6008, 0)}, /* CMOTech CMU-301 */
+ {QMI_FIXED_INTF(0x16d8, 0x6280, 0)}, /* CMOTech CHU-628 */
+ {QMI_FIXED_INTF(0x16d8, 0x7001, 0)}, /* CMOTech CHU-720S */
+ {QMI_FIXED_INTF(0x16d8, 0x7002, 0)}, /* CMOTech 7002 */
+ {QMI_FIXED_INTF(0x16d8, 0x7003, 4)}, /* CMOTech CHU-629K */
+ {QMI_FIXED_INTF(0x16d8, 0x7004, 3)}, /* CMOTech 7004 */
+ {QMI_FIXED_INTF(0x16d8, 0x7006, 5)}, /* CMOTech CGU-629 */
+ {QMI_FIXED_INTF(0x16d8, 0x700a, 4)}, /* CMOTech CHU-629S */
+ {QMI_FIXED_INTF(0x16d8, 0x7211, 0)}, /* CMOTech CHU-720I */
+ {QMI_FIXED_INTF(0x16d8, 0x7212, 0)}, /* CMOTech 7212 */
+ {QMI_FIXED_INTF(0x16d8, 0x7213, 0)}, /* CMOTech 7213 */
+ {QMI_FIXED_INTF(0x16d8, 0x7251, 1)}, /* CMOTech 7251 */
+ {QMI_FIXED_INTF(0x16d8, 0x7252, 1)}, /* CMOTech 7252 */
+ {QMI_FIXED_INTF(0x16d8, 0x7253, 1)}, /* CMOTech 7253 */
{QMI_FIXED_INTF(0x19d2, 0x0002, 1)},
{QMI_FIXED_INTF(0x19d2, 0x0012, 1)},
{QMI_FIXED_INTF(0x19d2, 0x0017, 3)},
@@ -699,24 +716,47 @@ static const struct usb_device_id products[] = {
{QMI_FIXED_INTF(0x19d2, 0x1255, 3)},
{QMI_FIXED_INTF(0x19d2, 0x1255, 4)},
{QMI_FIXED_INTF(0x19d2, 0x1256, 4)},
+ {QMI_FIXED_INTF(0x19d2, 0x1270, 5)}, /* ZTE MF667 */
{QMI_FIXED_INTF(0x19d2, 0x1401, 2)},
{QMI_FIXED_INTF(0x19d2, 0x1402, 2)}, /* ZTE MF60 */
{QMI_FIXED_INTF(0x19d2, 0x1424, 2)},
{QMI_FIXED_INTF(0x19d2, 0x1425, 2)},
{QMI_FIXED_INTF(0x19d2, 0x1426, 2)}, /* ZTE MF91 */
+ {QMI_FIXED_INTF(0x19d2, 0x1428, 2)}, /* Telewell TW-LTE 4G v2 */
{QMI_FIXED_INTF(0x19d2, 0x2002, 4)}, /* ZTE (Vodafone) K3765-Z */
{QMI_FIXED_INTF(0x0f3d, 0x68a2, 8)}, /* Sierra Wireless MC7700 */
{QMI_FIXED_INTF(0x114f, 0x68a2, 8)}, /* Sierra Wireless MC7750 */
{QMI_FIXED_INTF(0x1199, 0x68a2, 8)}, /* Sierra Wireless MC7710 in QMI mode */
{QMI_FIXED_INTF(0x1199, 0x68a2, 19)}, /* Sierra Wireless MC7710 in QMI mode */
+ {QMI_FIXED_INTF(0x1199, 0x68c0, 8)}, /* Sierra Wireless MC73xx */
+ {QMI_FIXED_INTF(0x1199, 0x68c0, 10)}, /* Sierra Wireless MC73xx */
+ {QMI_FIXED_INTF(0x1199, 0x68c0, 11)}, /* Sierra Wireless MC73xx */
{QMI_FIXED_INTF(0x1199, 0x901c, 8)}, /* Sierra Wireless EM7700 */
+ {QMI_FIXED_INTF(0x1199, 0x901f, 8)}, /* Sierra Wireless EM7355 */
+ {QMI_FIXED_INTF(0x1199, 0x9041, 8)}, /* Sierra Wireless MC7305/MC7355 */
{QMI_FIXED_INTF(0x1199, 0x9051, 8)}, /* Netgear AirCard 340U */
+ {QMI_FIXED_INTF(0x1199, 0x9057, 8)},
{QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */
+ {QMI_FIXED_INTF(0x1bbb, 0x0203, 2)}, /* Alcatel L800MA */
{QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */
{QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */
{QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */
- {QMI_FIXED_INTF(0x0b3c, 0xc005, 6)}, /* Olivetti Olicard 200 */
+ {QMI_FIXED_INTF(0x1bc7, 0x1201, 2)}, /* Telit LE920 */
+ {QMI_FIXED_INTF(0x0b3c, 0xc000, 4)}, /* Olivetti Olicard 100 */
+ {QMI_FIXED_INTF(0x0b3c, 0xc001, 4)}, /* Olivetti Olicard 120 */
+ {QMI_FIXED_INTF(0x0b3c, 0xc002, 4)}, /* Olivetti Olicard 140 */
+ {QMI_FIXED_INTF(0x0b3c, 0xc004, 6)}, /* Olivetti Olicard 155 */
+ {QMI_FIXED_INTF(0x0b3c, 0xc005, 6)}, /* Olivetti Olicard 200 */
+ {QMI_FIXED_INTF(0x0b3c, 0xc00a, 6)}, /* Olivetti Olicard 160 */
+ {QMI_FIXED_INTF(0x0b3c, 0xc00b, 4)}, /* Olivetti Olicard 500 */
{QMI_FIXED_INTF(0x1e2d, 0x0060, 4)}, /* Cinterion PLxx */
+ {QMI_FIXED_INTF(0x1e2d, 0x0053, 4)}, /* Cinterion PHxx,PXxx */
+ {QMI_FIXED_INTF(0x413c, 0x81a2, 8)}, /* Dell Wireless 5806 Gobi(TM) 4G LTE Mobile Broadband Card */
+ {QMI_FIXED_INTF(0x413c, 0x81a3, 8)}, /* Dell Wireless 5570 HSPA+ (42Mbps) Mobile Broadband Card */
+ {QMI_FIXED_INTF(0x413c, 0x81a4, 8)}, /* Dell Wireless 5570e HSPA+ (42Mbps) Mobile Broadband Card */
+ {QMI_FIXED_INTF(0x413c, 0x81a8, 8)}, /* Dell Wireless 5808 Gobi(TM) 4G LTE Mobile Broadband Card */
+ {QMI_FIXED_INTF(0x413c, 0x81a9, 8)}, /* Dell Wireless 5808e Gobi(TM) 4G LTE Mobile Broadband Card */
+ {QMI_FIXED_INTF(0x03f0, 0x581d, 4)}, /* HP lt4112 LTE/HSPA+ Gobi 4G Module (Huawei me906e) */
/* 4. Gobi 1000 devices */
{QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 4ecdf3c..c8e3333 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -282,13 +282,15 @@ static inline struct vxlan_rdst *first_remote_rtnl(struct vxlan_fdb *fdb)
return list_first_entry(&fdb->remotes, struct vxlan_rdst, list);
}
-/* Find VXLAN socket based on network namespace and UDP port */
-static struct vxlan_sock *vxlan_find_sock(struct net *net, __be16 port)
+/* Find VXLAN socket based on network namespace, address family and UDP port */
+static struct vxlan_sock *vxlan_find_sock(struct net *net,
+ sa_family_t family, __be16 port)
{
struct vxlan_sock *vs;
hlist_for_each_entry_rcu(vs, vs_head(net, port), hlist) {
- if (inet_sk(vs->sock->sk)->inet_sport == port)
+ if (inet_sk(vs->sock->sk)->inet_sport == port &&
+ inet_sk(vs->sock->sk)->sk.sk_family == family)
return vs;
}
return NULL;
@@ -307,11 +309,12 @@ static struct vxlan_dev *vxlan_vs_find_vni(struct vxlan_sock *vs, u32 id)
}
/* Look up VNI in a per net namespace table */
-static struct vxlan_dev *vxlan_find_vni(struct net *net, u32 id, __be16 port)
+static struct vxlan_dev *vxlan_find_vni(struct net *net, u32 id,
+ sa_family_t family, __be16 port)
{
struct vxlan_sock *vs;
- vs = vxlan_find_sock(net, port);
+ vs = vxlan_find_sock(net, family, port);
if (!vs)
return NULL;
@@ -1228,7 +1231,7 @@ static int arp_reduce(struct net_device *dev, struct sk_buff *skb)
} else if (vxlan->flags & VXLAN_F_L3MISS) {
union vxlan_addr ipa = {
.sin.sin_addr.s_addr = tip,
- .sa.sa_family = AF_INET,
+ .sin.sin_family = AF_INET,
};
vxlan_ip_miss(dev, &ipa);
@@ -1341,9 +1344,6 @@ static int neigh_reduce(struct net_device *dev, struct sk_buff *skb)
if (!in6_dev)
goto out;
- if (!pskb_may_pull(skb, skb->len))
- goto out;
-
iphdr = ipv6_hdr(skb);
saddr = &iphdr->saddr;
daddr = &iphdr->daddr;
@@ -1389,7 +1389,7 @@ static int neigh_reduce(struct net_device *dev, struct sk_buff *skb)
} else if (vxlan->flags & VXLAN_F_L3MISS) {
union vxlan_addr ipa = {
.sin6.sin6_addr = msg->target,
- .sa.sa_family = AF_INET6,
+ .sin6.sin6_family = AF_INET6,
};
vxlan_ip_miss(dev, &ipa);
@@ -1422,7 +1422,7 @@ static bool route_shortcircuit(struct net_device *dev, struct sk_buff *skb)
if (!n && (vxlan->flags & VXLAN_F_L3MISS)) {
union vxlan_addr ipa = {
.sin.sin_addr.s_addr = pip->daddr,
- .sa.sa_family = AF_INET,
+ .sin.sin_family = AF_INET,
};
vxlan_ip_miss(dev, &ipa);
@@ -1443,7 +1443,7 @@ static bool route_shortcircuit(struct net_device *dev, struct sk_buff *skb)
if (!n && (vxlan->flags & VXLAN_F_L3MISS)) {
union vxlan_addr ipa = {
.sin6.sin6_addr = pip6->daddr,
- .sa.sa_family = AF_INET6,
+ .sin6.sin6_family = AF_INET6,
};
vxlan_ip_miss(dev, &ipa);
@@ -1683,6 +1683,8 @@ static void vxlan_encap_bypass(struct sk_buff *skb, struct vxlan_dev *src_vxlan,
struct pcpu_tstats *rx_stats = this_cpu_ptr(dst_vxlan->dev->tstats);
union vxlan_addr loopback;
union vxlan_addr *remote_ip = &dst_vxlan->default_dst.remote_ip;
+ struct net_device *dev = skb->dev;
+ int len = skb->len;
skb->pkt_type = PACKET_HOST;
skb->encapsulation = 0;
@@ -1704,16 +1706,16 @@ static void vxlan_encap_bypass(struct sk_buff *skb, struct vxlan_dev *src_vxlan,
u64_stats_update_begin(&tx_stats->syncp);
tx_stats->tx_packets++;
- tx_stats->tx_bytes += skb->len;
+ tx_stats->tx_bytes += len;
u64_stats_update_end(&tx_stats->syncp);
if (netif_rx(skb) == NET_RX_SUCCESS) {
u64_stats_update_begin(&rx_stats->syncp);
rx_stats->rx_packets++;
- rx_stats->rx_bytes += skb->len;
+ rx_stats->rx_bytes += len;
u64_stats_update_end(&rx_stats->syncp);
} else {
- skb->dev->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
}
}
@@ -1784,7 +1786,8 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
struct vxlan_dev *dst_vxlan;
ip_rt_put(rt);
- dst_vxlan = vxlan_find_vni(dev_net(dev), vni, dst_port);
+ dst_vxlan = vxlan_find_vni(dev_net(dev), vni,
+ dst->sa.sa_family, dst_port);
if (!dst_vxlan)
goto tx_error;
vxlan_encap_bypass(skb, vxlan, dst_vxlan);
@@ -1837,7 +1840,8 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
struct vxlan_dev *dst_vxlan;
dst_release(ndst);
- dst_vxlan = vxlan_find_vni(dev_net(dev), vni, dst_port);
+ dst_vxlan = vxlan_find_vni(dev_net(dev), vni,
+ dst->sa.sa_family, dst_port);
if (!dst_vxlan)
goto tx_error;
vxlan_encap_bypass(skb, vxlan, dst_vxlan);
@@ -1888,7 +1892,8 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
return arp_reduce(dev, skb);
#if IS_ENABLED(CONFIG_IPV6)
else if (ntohs(eth->h_proto) == ETH_P_IPV6 &&
- skb->len >= sizeof(struct ipv6hdr) + sizeof(struct nd_msg) &&
+ pskb_may_pull(skb, sizeof(struct ipv6hdr)
+ + sizeof(struct nd_msg)) &&
ipv6_hdr(skb)->nexthdr == IPPROTO_ICMPV6) {
struct nd_msg *msg;
@@ -1897,6 +1902,7 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
msg->icmph.icmp6_type == NDISC_NEIGHBOUR_SOLICITATION)
return neigh_reduce(dev, skb);
}
+ eth = eth_hdr(skb);
#endif
}
@@ -1986,6 +1992,7 @@ static int vxlan_init(struct net_device *dev)
{
struct vxlan_dev *vxlan = netdev_priv(dev);
struct vxlan_net *vn = net_generic(dev_net(dev), vxlan_net_id);
+ bool ipv6 = vxlan->flags & VXLAN_F_IPV6;
struct vxlan_sock *vs;
dev->tstats = alloc_percpu(struct pcpu_tstats);
@@ -1993,10 +2000,10 @@ static int vxlan_init(struct net_device *dev)
return -ENOMEM;
spin_lock(&vn->sock_lock);
- vs = vxlan_find_sock(dev_net(dev), vxlan->dst_port);
- if (vs) {
+ vs = vxlan_find_sock(dev_net(dev), ipv6 ? AF_INET6 : AF_INET,
+ vxlan->dst_port);
+ if (vs && atomic_add_unless(&vs->refcnt, 1, 0)) {
/* If we have a socket with same port already, reuse it */
- atomic_inc(&vs->refcnt);
vxlan_vs_add_dev(vs, vxlan);
} else {
/* otherwise make new socket outside of RTNL */
@@ -2157,9 +2164,9 @@ static void vxlan_setup(struct net_device *dev)
eth_hw_addr_random(dev);
ether_setup(dev);
if (vxlan->default_dst.remote_ip.sa.sa_family == AF_INET6)
- dev->hard_header_len = ETH_HLEN + VXLAN6_HEADROOM;
+ dev->needed_headroom = ETH_HLEN + VXLAN6_HEADROOM;
else
- dev->hard_header_len = ETH_HLEN + VXLAN_HEADROOM;
+ dev->needed_headroom = ETH_HLEN + VXLAN_HEADROOM;
dev->netdev_ops = &vxlan_netdev_ops;
dev->destructor = free_netdev;
@@ -2438,13 +2445,10 @@ struct vxlan_sock *vxlan_sock_add(struct net *net, __be16 port,
return vs;
spin_lock(&vn->sock_lock);
- vs = vxlan_find_sock(net, port);
- if (vs) {
- if (vs->rcv == rcv)
- atomic_inc(&vs->refcnt);
- else
+ vs = vxlan_find_sock(net, ipv6 ? AF_INET6 : AF_INET, port);
+ if (vs && ((vs->rcv != rcv) ||
+ !atomic_add_unless(&vs->refcnt, 1, 0)))
vs = ERR_PTR(-EBUSY);
- }
spin_unlock(&vn->sock_lock);
if (!vs)
@@ -2540,8 +2544,7 @@ static int vxlan_newlink(struct net *net, struct net_device *dev,
if (!tb[IFLA_MTU])
dev->mtu = lowerdev->mtu - (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM);
- /* update header length based on lower device */
- dev->hard_header_len = lowerdev->hard_header_len +
+ dev->needed_headroom = lowerdev->hard_header_len +
(use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM);
}
@@ -2584,7 +2587,8 @@ static int vxlan_newlink(struct net *net, struct net_device *dev,
if (data[IFLA_VXLAN_PORT])
vxlan->dst_port = nla_get_be16(data[IFLA_VXLAN_PORT]);
- if (vxlan_find_vni(net, vni, vxlan->dst_port)) {
+ if (vxlan_find_vni(net, vni, use_ipv6 ? AF_INET6 : AF_INET,
+ vxlan->dst_port)) {
pr_info("duplicate VNI %u\n", vni);
return -EEXIST;
}
diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c
index 0583c69..ddaad71 100644
--- a/drivers/net/wireless/ath/ath5k/qcu.c
+++ b/drivers/net/wireless/ath/ath5k/qcu.c
@@ -225,13 +225,7 @@ ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type,
} else {
switch (queue_type) {
case AR5K_TX_QUEUE_DATA:
- for (queue = AR5K_TX_QUEUE_ID_DATA_MIN;
- ah->ah_txq[queue].tqi_type !=
- AR5K_TX_QUEUE_INACTIVE; queue++) {
-
- if (queue > AR5K_TX_QUEUE_ID_DATA_MAX)
- return -EINVAL;
- }
+ queue = queue_info->tqi_subtype;
break;
case AR5K_TX_QUEUE_UAPSD:
queue = AR5K_TX_QUEUE_ID_UAPSD;
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index e897648..5092343 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -648,6 +648,19 @@ static void ar9003_hw_override_ini(struct ath_hw *ah)
else
ah->enabled_cals &= ~TX_CL_CAL;
}
+
+ if (AR_SREV_9340(ah) || AR_SREV_9550(ah)) {
+ if (ah->is_clk_25mhz) {
+ REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x17c << 1);
+ REG_WRITE(ah, AR_SLP32_MODE, 0x0010f3d7);
+ REG_WRITE(ah, AR_SLP32_INC, 0x0001e7ae);
+ } else {
+ REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x261 << 1);
+ REG_WRITE(ah, AR_SLP32_MODE, 0x0010f400);
+ REG_WRITE(ah, AR_SLP32_INC, 0x0001e800);
+ }
+ udelay(100);
+ }
}
static void ar9003_hw_prog_ini(struct ath_hw *ah,
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 4e0a942..c6f255f 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -916,19 +916,6 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
udelay(RTC_PLL_SETTLE_DELAY);
REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK);
-
- if (AR_SREV_9340(ah) || AR_SREV_9550(ah)) {
- if (ah->is_clk_25mhz) {
- REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x17c << 1);
- REG_WRITE(ah, AR_SLP32_MODE, 0x0010f3d7);
- REG_WRITE(ah, AR_SLP32_INC, 0x0001e7ae);
- } else {
- REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x261 << 1);
- REG_WRITE(ah, AR_SLP32_MODE, 0x0010f400);
- REG_WRITE(ah, AR_SLP32_INC, 0x0001e800);
- }
- udelay(100);
- }
}
static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 69a907b..5bf775e 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -215,8 +215,8 @@
#define AH_WOW_BEACON_MISS BIT(3)
enum ath_hw_txq_subtype {
- ATH_TXQ_AC_BE = 0,
- ATH_TXQ_AC_BK = 1,
+ ATH_TXQ_AC_BK = 0,
+ ATH_TXQ_AC_BE = 1,
ATH_TXQ_AC_VI = 2,
ATH_TXQ_AC_VO = 3,
};
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index a3eff09..0244680 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -311,14 +311,7 @@ int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,
q = ATH9K_NUM_TX_QUEUES - 3;
break;
case ATH9K_TX_QUEUE_DATA:
- for (q = 0; q < ATH9K_NUM_TX_QUEUES; q++)
- if (ah->txq[q].tqi_type ==
- ATH9K_TX_QUEUE_INACTIVE)
- break;
- if (q == ATH9K_NUM_TX_QUEUES) {
- ath_err(common, "No available TX queue\n");
- return -1;
- }
+ q = qinfo->tqi_subtype;
break;
default:
ath_err(common, "Invalid TX queue type: %u\n", type);
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index ba39178..d92c6ff 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -904,6 +904,15 @@ ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq,
tx_info = IEEE80211_SKB_CB(skb);
tx_info->flags &= ~IEEE80211_TX_CTL_CLEAR_PS_FILT;
+
+ /*
+ * No aggregation session is running, but there may be frames
+ * from a previous session or a failed attempt in the queue.
+ * Send them out as normal data frames
+ */
+ if (!tid->active)
+ tx_info->flags &= ~IEEE80211_TX_CTL_AMPDU;
+
if (!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) {
bf->bf_state.bf_type = 0;
return bf;
@@ -1718,7 +1727,7 @@ int ath_cabq_update(struct ath_softc *sc)
else if (sc->config.cabqReadytime > ATH9K_READY_TIME_HI_BOUND)
sc->config.cabqReadytime = ATH9K_READY_TIME_HI_BOUND;
- qi.tqi_readyTime = (cur_conf->beacon_interval *
+ qi.tqi_readyTime = (TU_TO_USEC(cur_conf->beacon_interval) *
sc->config.cabqReadytime) / 100;
ath_txq_update(sc, qnum, &qi);
@@ -2078,7 +2087,7 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
ATH_TXBUF_RESET(bf);
- if (tid) {
+ if (tid && ieee80211_is_data_present(hdr->frame_control)) {
fragno = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG;
seqno = tid->seq_next;
hdr->seq_ctrl = cpu_to_le16(tid->seq_next << IEEE80211_SEQ_SEQ_SHIFT);
@@ -2201,7 +2210,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
txq->stopped = true;
}
- if (txctl->an)
+ if (txctl->an && ieee80211_is_data_present(hdr->frame_control))
tid = ath_get_skb_tid(sc, txctl->an, skb);
if (info->flags & IEEE80211_TX_CTL_PS_RESPONSE) {
diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h
index 8596aba..237d0cd 100644
--- a/drivers/net/wireless/ath/carl9170/carl9170.h
+++ b/drivers/net/wireless/ath/carl9170/carl9170.h
@@ -256,6 +256,7 @@ struct ar9170 {
atomic_t rx_work_urbs;
atomic_t rx_pool_urbs;
kernel_ulong_t features;
+ bool usb_ep_cmd_is_bulk;
/* firmware settings */
struct completion fw_load_wait;
diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c
index 307bc0d..83d20c8 100644
--- a/drivers/net/wireless/ath/carl9170/usb.c
+++ b/drivers/net/wireless/ath/carl9170/usb.c
@@ -621,9 +621,16 @@ int __carl9170_exec_cmd(struct ar9170 *ar, struct carl9170_cmd *cmd,
goto err_free;
}
- usb_fill_int_urb(urb, ar->udev, usb_sndintpipe(ar->udev,
- AR9170_USB_EP_CMD), cmd, cmd->hdr.len + 4,
- carl9170_usb_cmd_complete, ar, 1);
+ if (ar->usb_ep_cmd_is_bulk)
+ usb_fill_bulk_urb(urb, ar->udev,
+ usb_sndbulkpipe(ar->udev, AR9170_USB_EP_CMD),
+ cmd, cmd->hdr.len + 4,
+ carl9170_usb_cmd_complete, ar);
+ else
+ usb_fill_int_urb(urb, ar->udev,
+ usb_sndintpipe(ar->udev, AR9170_USB_EP_CMD),
+ cmd, cmd->hdr.len + 4,
+ carl9170_usb_cmd_complete, ar, 1);
if (free_buf)
urb->transfer_flags |= URB_FREE_BUFFER;
@@ -1032,9 +1039,10 @@ static void carl9170_usb_firmware_step2(const struct firmware *fw,
static int carl9170_usb_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
+ struct usb_endpoint_descriptor *ep;
struct ar9170 *ar;
struct usb_device *udev;
- int err;
+ int i, err;
err = usb_reset_device(interface_to_usbdev(intf));
if (err)
@@ -1050,6 +1058,21 @@ static int carl9170_usb_probe(struct usb_interface *intf,
ar->intf = intf;
ar->features = id->driver_info;
+ /* We need to remember the type of endpoint 4 because it differs
+ * between high- and full-speed configuration. The high-speed
+ * configuration specifies it as interrupt and the full-speed
+ * configuration as bulk endpoint. This information is required
+ * later when sending urbs to that endpoint.
+ */
+ for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; ++i) {
+ ep = &intf->cur_altsetting->endpoint[i].desc;
+
+ if (usb_endpoint_num(ep) == AR9170_USB_EP_CMD &&
+ usb_endpoint_dir_out(ep) &&
+ usb_endpoint_type(ep) == USB_ENDPOINT_XFER_BULK)
+ ar->usb_ep_cmd_is_bulk = true;
+ }
+
usb_set_intfdata(intf, ar);
SET_IEEE80211_DEV(ar->hw, &intf->dev);
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index 7c970d3..80ecca3 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -5175,22 +5175,22 @@ static void b43_nphy_channel_setup(struct b43_wldev *dev,
int ch = new_channel->hw_value;
u16 old_band_5ghz;
- u32 tmp32;
+ u16 tmp16;
old_band_5ghz =
b43_phy_read(dev, B43_NPHY_BANDCTL) & B43_NPHY_BANDCTL_5GHZ;
if (new_channel->band == IEEE80211_BAND_5GHZ && !old_band_5ghz) {
- tmp32 = b43_read32(dev, B43_MMIO_PSM_PHY_HDR);
- b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32 | 4);
+ tmp16 = b43_read16(dev, B43_MMIO_PSM_PHY_HDR);
+ b43_write16(dev, B43_MMIO_PSM_PHY_HDR, tmp16 | 4);
b43_phy_set(dev, B43_PHY_B_BBCFG, 0xC000);
- b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32);
+ b43_write16(dev, B43_MMIO_PSM_PHY_HDR, tmp16);
b43_phy_set(dev, B43_NPHY_BANDCTL, B43_NPHY_BANDCTL_5GHZ);
} else if (new_channel->band == IEEE80211_BAND_2GHZ && old_band_5ghz) {
b43_phy_mask(dev, B43_NPHY_BANDCTL, ~B43_NPHY_BANDCTL_5GHZ);
- tmp32 = b43_read32(dev, B43_MMIO_PSM_PHY_HDR);
- b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32 | 4);
+ tmp16 = b43_read16(dev, B43_MMIO_PSM_PHY_HDR);
+ b43_write16(dev, B43_MMIO_PSM_PHY_HDR, tmp16 | 4);
b43_phy_mask(dev, B43_PHY_B_BBCFG, 0x3FFF);
- b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32);
+ b43_write16(dev, B43_MMIO_PSM_PHY_HDR, tmp16);
}
b43_chantab_phy_upload(dev, e);
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index e85d34b..ebcce00 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -810,9 +810,13 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
break;
case B43_PHYTYPE_G:
status.band = IEEE80211_BAND_2GHZ;
- /* chanid is the radio channel cookie value as used
- * to tune the radio. */
- status.freq = chanid + 2400;
+ /* Somewhere between 478.104 and 508.1084 firmware for G-PHY
+ * has been modified to be compatible with N-PHY and others.
+ */
+ if (dev->fw.rev >= 508)
+ status.freq = ieee80211_channel_to_frequency(chanid, status.band);
+ else
+ status.freq = chanid + 2400;
break;
case B43_PHYTYPE_N:
case B43_PHYTYPE_LP:
diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c
index 7aad766..ca9c4f1 100644
--- a/drivers/net/wireless/iwlwifi/dvm/main.c
+++ b/drivers/net/wireless/iwlwifi/dvm/main.c
@@ -252,13 +252,17 @@ static void iwl_bg_bt_runtime_config(struct work_struct *work)
struct iwl_priv *priv =
container_of(work, struct iwl_priv, bt_runtime_config);
+ mutex_lock(&priv->mutex);
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
+ goto out;
/* dont send host command if rf-kill is on */
if (!iwl_is_ready_rf(priv))
- return;
+ goto out;
+
iwlagn_send_advance_bt_config(priv);
+out:
+ mutex_unlock(&priv->mutex);
}
static void iwl_bg_bt_full_concurrency(struct work_struct *work)
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index 80b4750..c8d1e37 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -484,6 +484,7 @@ enum iwl_trans_state {
* Set during transport allocation.
* @hw_id_str: a string with info about HW ID. Set during transport allocation.
* @pm_support: set to true in start_hw if link pm is supported
+ * @ltr_enabled: set to true if the LTR is enabled
* @dev_cmd_pool: pool for Tx cmd allocation - for internal use only.
* The user should use iwl_trans_{alloc,free}_tx_cmd.
* @dev_cmd_headroom: room needed for the transport's private use before the
@@ -508,6 +509,7 @@ struct iwl_trans {
u8 rx_mpdu_cmd, rx_mpdu_cmd_hdr_size;
bool pm_support;
+ bool ltr_enabled;
/* The following fields are internal only */
struct kmem_cache *dev_cmd_pool;
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
index 8e7ab41..4dacb20 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
@@ -66,13 +66,46 @@
/* Power Management Commands, Responses, Notifications */
+/**
+ * enum iwl_ltr_config_flags - masks for LTR config command flags
+ * @LTR_CFG_FLAG_FEATURE_ENABLE: Feature operational status
+ * @LTR_CFG_FLAG_HW_DIS_ON_SHADOW_REG_ACCESS: allow LTR change on shadow
+ * memory access
+ * @LTR_CFG_FLAG_HW_EN_SHRT_WR_THROUGH: allow LTR msg send on ANY LTR
+ * reg change
+ * @LTR_CFG_FLAG_HW_DIS_ON_D0_2_D3: allow LTR msg send on transition from
+ * D0 to D3
+ * @LTR_CFG_FLAG_SW_SET_SHORT: fixed static short LTR register
+ * @LTR_CFG_FLAG_SW_SET_LONG: fixed static short LONG register
+ * @LTR_CFG_FLAG_DENIE_C10_ON_PD: allow going into C10 on PD
+ */
+enum iwl_ltr_config_flags {
+ LTR_CFG_FLAG_FEATURE_ENABLE = BIT(0),
+ LTR_CFG_FLAG_HW_DIS_ON_SHADOW_REG_ACCESS = BIT(1),
+ LTR_CFG_FLAG_HW_EN_SHRT_WR_THROUGH = BIT(2),
+ LTR_CFG_FLAG_HW_DIS_ON_D0_2_D3 = BIT(3),
+ LTR_CFG_FLAG_SW_SET_SHORT = BIT(4),
+ LTR_CFG_FLAG_SW_SET_LONG = BIT(5),
+ LTR_CFG_FLAG_DENIE_C10_ON_PD = BIT(6),
+};
+
+/**
+ * struct iwl_ltr_config_cmd - configures the LTR
+ * @flags: See %enum iwl_ltr_config_flags
+ */
+struct iwl_ltr_config_cmd {
+ __le32 flags;
+ __le32 static_long;
+ __le32 static_short;
+} __packed;
+
/* Radio LP RX Energy Threshold measured in dBm */
#define POWER_LPRX_RSSI_THRESHOLD 75
#define POWER_LPRX_RSSI_THRESHOLD_MAX 94
#define POWER_LPRX_RSSI_THRESHOLD_MIN 30
/**
- * enum iwl_scan_flags - masks for power table command flags
+ * enum iwl_power_flags - masks for power table command flags
* @POWER_FLAGS_POWER_SAVE_ENA_MSK: '1' Allow to save power by turning off
* receiver and transmitter. '0' - does not allow.
* @POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK: '0' Driver disables power management,
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
index 66264cc..cd59ae1 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
@@ -138,6 +138,7 @@ enum {
/* Power - legacy power table command */
POWER_TABLE_CMD = 0x77,
+ LTR_CONFIG = 0xee,
/* Thermal Throttling*/
REPLY_THERMAL_MNG_BACKOFF = 0x7e,
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c
index c76299a..08f1200 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/iwlwifi/mvm/fw.c
@@ -424,6 +424,15 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
goto error;
}
+ if (mvm->trans->ltr_enabled) {
+ struct iwl_ltr_config_cmd cmd = {
+ .flags = cpu_to_le32(LTR_CFG_FLAG_FEATURE_ENABLE),
+ };
+
+ WARN_ON(iwl_mvm_send_cmd_pdu(mvm, LTR_CONFIG, 0,
+ sizeof(cmd), &cmd));
+ }
+
IWL_DEBUG_INFO(mvm, "RT uCode started.\n");
return 0;
error:
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
index 5fe23a5..72c6415 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
@@ -1102,10 +1102,18 @@ int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm,
static void iwl_mvm_beacon_loss_iterator(void *_data, u8 *mac,
struct ieee80211_vif *vif)
{
- u16 *id = _data;
+ struct iwl_missed_beacons_notif *missed_beacons = _data;
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
- if (mvmvif->id == *id)
+ if (mvmvif->id != (u16)le32_to_cpu(missed_beacons->mac_id))
+ return;
+
+ /*
+ * TODO: the threshold should be adjusted based on latency conditions,
+ * and/or in case of a CS flow on one of the other AP vifs.
+ */
+ if (le32_to_cpu(missed_beacons->consec_missed_beacons_since_last_rx) >
+ IWL_MVM_MISSED_BEACONS_THRESHOLD)
ieee80211_beacon_loss(vif);
}
@@ -1114,12 +1122,19 @@ int iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm,
struct iwl_device_cmd *cmd)
{
struct iwl_rx_packet *pkt = rxb_addr(rxb);
- struct iwl_missed_beacons_notif *missed_beacons = (void *)pkt->data;
- u16 id = (u16)le32_to_cpu(missed_beacons->mac_id);
+ struct iwl_missed_beacons_notif *mb = (void *)pkt->data;
+
+ IWL_DEBUG_INFO(mvm,
+ "missed bcn mac_id=%u, consecutive=%u (%u, %u, %u)\n",
+ le32_to_cpu(mb->mac_id),
+ le32_to_cpu(mb->consec_missed_beacons),
+ le32_to_cpu(mb->consec_missed_beacons_since_last_rx),
+ le32_to_cpu(mb->num_recvd_beacons),
+ le32_to_cpu(mb->num_expected_beacons));
ieee80211_iterate_active_interfaces_atomic(mvm->hw,
IEEE80211_IFACE_ITER_NORMAL,
iwl_mvm_beacon_loss_iterator,
- &id);
+ mb);
return 0;
}
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index c86663e..2103447 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -82,6 +82,7 @@
#define IWL_MVM_MAX_ADDRESSES 5
/* RSSI offset for WkP */
#define IWL_RSSI_OFFSET 50
+#define IWL_MVM_MISSED_BEACONS_THRESHOLD 8
enum iwl_mvm_tx_fifo {
IWL_MVM_TX_FIFO_BK = 0,
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index 1fd08ba..e3cdc97 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -303,6 +303,7 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = {
CMD(REPLY_BEACON_FILTERING_CMD),
CMD(REPLY_THERMAL_MNG_BACKOFF),
CMD(MAC_PM_POWER_TABLE),
+ CMD(LTR_CONFIG),
};
#undef CMD
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c
index 26108a1..968c128 100644
--- a/drivers/net/wireless/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/iwlwifi/pcie/drv.c
@@ -272,6 +272,8 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
{IWL_PCI_DEVICE(0x08B1, 0x4070, iwl7260_2ac_cfg)},
{IWL_PCI_DEVICE(0x08B1, 0x4072, iwl7260_2ac_cfg)},
{IWL_PCI_DEVICE(0x08B1, 0x4170, iwl7260_2ac_cfg)},
+ {IWL_PCI_DEVICE(0x08B1, 0x4C60, iwl7260_2ac_cfg)},
+ {IWL_PCI_DEVICE(0x08B1, 0x4C70, iwl7260_2ac_cfg)},
{IWL_PCI_DEVICE(0x08B1, 0x4060, iwl7260_2n_cfg)},
{IWL_PCI_DEVICE(0x08B1, 0x406A, iwl7260_2n_cfg)},
{IWL_PCI_DEVICE(0x08B1, 0x4160, iwl7260_2n_cfg)},
@@ -312,6 +314,8 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
{IWL_PCI_DEVICE(0x08B1, 0xC770, iwl7260_2ac_cfg)},
{IWL_PCI_DEVICE(0x08B1, 0xC760, iwl7260_2n_cfg)},
{IWL_PCI_DEVICE(0x08B2, 0xC270, iwl7260_2ac_cfg)},
+ {IWL_PCI_DEVICE(0x08B1, 0xCC70, iwl7260_2ac_cfg)},
+ {IWL_PCI_DEVICE(0x08B1, 0xCC60, iwl7260_2ac_cfg)},
{IWL_PCI_DEVICE(0x08B2, 0xC272, iwl7260_2ac_cfg)},
{IWL_PCI_DEVICE(0x08B2, 0xC260, iwl7260_2n_cfg)},
{IWL_PCI_DEVICE(0x08B2, 0xC26A, iwl7260_n_cfg)},
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index 62aac3b..e10646b 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -121,6 +121,7 @@ static void iwl_pcie_apm_config(struct iwl_trans *trans)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
u16 lctl;
+ u16 cap;
/*
* HW bug W/A for instability in PCIe bus L0S->L1 transition.
@@ -131,16 +132,17 @@ static void iwl_pcie_apm_config(struct iwl_trans *trans)
* power savings, even without L1.
*/
pcie_capability_read_word(trans_pcie->pci_dev, PCI_EXP_LNKCTL, &lctl);
- if (lctl & PCI_EXP_LNKCTL_ASPM_L1) {
- /* L1-ASPM enabled; disable(!) L0S */
+ if (lctl & PCI_EXP_LNKCTL_ASPM_L1)
iwl_set_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
- dev_info(trans->dev, "L1 Enabled; Disabling L0S\n");
- } else {
- /* L1-ASPM disabled; enable(!) L0S */
+ else
iwl_clear_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
- dev_info(trans->dev, "L1 Disabled; Enabling L0S\n");
- }
trans->pm_support = !(lctl & PCI_EXP_LNKCTL_ASPM_L0S);
+
+ pcie_capability_read_word(trans_pcie->pci_dev, PCI_EXP_DEVCTL2, &cap);
+ trans->ltr_enabled = cap & PCI_EXP_DEVCTL2_LTR_EN;
+ dev_info(trans->dev, "L1 %sabled - LTR %sabled\n",
+ (lctl & PCI_EXP_LNKCTL_ASPM_L1) ? "En" : "Dis",
+ trans->ltr_enabled ? "En" : "Dis");
}
/*
@@ -345,6 +347,7 @@ static int iwl_pcie_prepare_card_hw(struct iwl_trans *trans)
{
int ret;
int t = 0;
+ int iter;
IWL_DEBUG_INFO(trans, "iwl_trans_prepare_card_hw enter\n");
@@ -353,18 +356,23 @@ static int iwl_pcie_prepare_card_hw(struct iwl_trans *trans)
if (ret >= 0)
return 0;
- /* If HW is not ready, prepare the conditions to check again */
- iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG,
- CSR_HW_IF_CONFIG_REG_PREPARE);
+ for (iter = 0; iter < 10; iter++) {
+ /* If HW is not ready, prepare the conditions to check again */
+ iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG,
+ CSR_HW_IF_CONFIG_REG_PREPARE);
+
+ do {
+ ret = iwl_pcie_set_hw_ready(trans);
+ if (ret >= 0)
+ return 0;
- do {
- ret = iwl_pcie_set_hw_ready(trans);
- if (ret >= 0)
- return 0;
+ usleep_range(200, 1000);
+ t += 200;
+ } while (t < 150000);
+ msleep(25);
+ }
- usleep_range(200, 1000);
- t += 200;
- } while (t < 150000);
+ IWL_DEBUG_INFO(trans, "got NIC after %d iterations\n", iter);
return ret;
}
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 2cd3f54..38b8b71 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -2261,7 +2261,7 @@ static int __init init_mac80211_hwsim(void)
printk(KERN_DEBUG
"mac80211_hwsim: device_bind_driver failed (%d)\n",
err);
- goto failed_hw;
+ goto failed_bind;
}
skb_queue_head_init(&data->pending);
@@ -2563,6 +2563,8 @@ failed_mon:
return err;
failed_hw:
+ device_release_driver(data->dev);
+failed_bind:
device_unregister(data->dev);
failed_drvdata:
ieee80211_free_hw(hw);
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index c2b91f5..edf5239 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -654,6 +654,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
tx_info = MWIFIEX_SKB_TXCB(skb);
+ memset(tx_info, 0, sizeof(*tx_info));
tx_info->bss_num = priv->bss_num;
tx_info->bss_type = priv->bss_type;
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 0ac5c58..13f557a 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1684,8 +1684,13 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
/*
* Detect if this device has an hardware controlled radio.
*/
- if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO))
+ if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO)) {
__set_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags);
+ /*
+ * On this device RFKILL initialized during probe does not work.
+ */
+ __set_bit(REQUIRE_DELAYED_RFKILL, &rt2x00dev->cap_flags);
+ }
/*
* Check if the BBP tuning should be enabled.
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index e3eb952..71f70c7 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -54,6 +54,7 @@
* RF5592 2.4G/5G 2T2R
* RF3070 2.4G 1T1R
* RF5360 2.4G 1T1R
+ * RF5362 2.4G 1T1R
* RF5370 2.4G 1T1R
* RF5390 2.4G 1T1R
*/
@@ -74,6 +75,7 @@
#define RF3070 0x3070
#define RF3290 0x3290
#define RF5360 0x5360
+#define RF5362 0x5362
#define RF5370 0x5370
#define RF5372 0x5372
#define RF5390 0x5390
@@ -2041,7 +2043,7 @@ struct mac_iveiv_entry {
* 2 - drop tx power by 12dBm,
* 3 - increase tx power by 6dBm
*/
-#define BBP1_TX_POWER_CTRL FIELD8(0x07)
+#define BBP1_TX_POWER_CTRL FIELD8(0x03)
#define BBP1_TX_ANTENNA FIELD8(0x18)
/*
@@ -2147,7 +2149,7 @@ struct mac_iveiv_entry {
/* Bits [7-4] for RF3320 (RT3370/RT3390), on other chipsets reserved */
#define RFCSR3_PA1_BIAS_CCK FIELD8(0x70)
#define RFCSR3_PA2_CASCODE_BIAS_CCKK FIELD8(0x80)
-/* Bits for RF3290/RF5360/RF5370/RF5372/RF5390/RF5392 */
+/* Bits for RF3290/RF5360/RF5362/RF5370/RF5372/RF5390/RF5392 */
#define RFCSR3_VCOCAL_EN FIELD8(0x80)
/* Bits for RF3050 */
#define RFCSR3_BIT1 FIELD8(0x02)
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 446eade..3bbd03c 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -3154,6 +3154,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
break;
case RF3070:
case RF5360:
+ case RF5362:
case RF5370:
case RF5372:
case RF5390:
@@ -3171,6 +3172,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
rt2x00_rf(rt2x00dev, RF3290) ||
rt2x00_rf(rt2x00dev, RF3322) ||
rt2x00_rf(rt2x00dev, RF5360) ||
+ rt2x00_rf(rt2x00dev, RF5362) ||
rt2x00_rf(rt2x00dev, RF5370) ||
rt2x00_rf(rt2x00dev, RF5372) ||
rt2x00_rf(rt2x00dev, RF5390) ||
@@ -4269,6 +4271,7 @@ void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev)
case RF3070:
case RF3290:
case RF5360:
+ case RF5362:
case RF5370:
case RF5372:
case RF5390:
@@ -7032,6 +7035,7 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
case RF3320:
case RF3322:
case RF5360:
+ case RF5362:
case RF5370:
case RF5372:
case RF5390:
@@ -7555,6 +7559,7 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
rt2x00_rf(rt2x00dev, RF3320) ||
rt2x00_rf(rt2x00dev, RF3322) ||
rt2x00_rf(rt2x00dev, RF5360) ||
+ rt2x00_rf(rt2x00dev, RF5362) ||
rt2x00_rf(rt2x00dev, RF5370) ||
rt2x00_rf(rt2x00dev, RF5372) ||
rt2x00_rf(rt2x00dev, RF5390) ||
@@ -7682,6 +7687,7 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
case RF3070:
case RF3290:
case RF5360:
+ case RF5362:
case RF5370:
case RF5372:
case RF5390:
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 8c64627..e42fa72 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -992,6 +992,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
{ USB_DEVICE(0x07d1, 0x3c15) },
{ USB_DEVICE(0x07d1, 0x3c16) },
{ USB_DEVICE(0x07d1, 0x3c17) },
+ { USB_DEVICE(0x2001, 0x3317) },
{ USB_DEVICE(0x2001, 0x3c1b) },
/* Draytek */
{ USB_DEVICE(0x07fa, 0x7712) },
@@ -1064,6 +1065,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
/* Ovislink */
{ USB_DEVICE(0x1b75, 0x3071) },
{ USB_DEVICE(0x1b75, 0x3072) },
+ { USB_DEVICE(0x1b75, 0xa200) },
/* Para */
{ USB_DEVICE(0x20b8, 0x8888) },
/* Pegatron */
@@ -1180,6 +1182,8 @@ static struct usb_device_id rt2800usb_device_table[] = {
/* Linksys */
{ USB_DEVICE(0x13b1, 0x002f) },
{ USB_DEVICE(0x1737, 0x0079) },
+ /* Logitec */
+ { USB_DEVICE(0x0789, 0x0170) },
/* Ralink */
{ USB_DEVICE(0x148f, 0x3572) },
/* Sitecom */
@@ -1203,6 +1207,8 @@ static struct usb_device_id rt2800usb_device_table[] = {
{ USB_DEVICE(0x050d, 0x1103) },
/* Cameo */
{ USB_DEVICE(0x148f, 0xf301) },
+ /* D-Link */
+ { USB_DEVICE(0x2001, 0x3c1f) },
/* Edimax */
{ USB_DEVICE(0x7392, 0x7733) },
/* Hawking */
@@ -1216,6 +1222,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
{ USB_DEVICE(0x0789, 0x016b) },
/* NETGEAR */
{ USB_DEVICE(0x0846, 0x9012) },
+ { USB_DEVICE(0x0846, 0x9013) },
{ USB_DEVICE(0x0846, 0x9019) },
/* Planex */
{ USB_DEVICE(0x2019, 0xed19) },
@@ -1224,6 +1231,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
/* Sitecom */
{ USB_DEVICE(0x0df6, 0x0067) },
{ USB_DEVICE(0x0df6, 0x006a) },
+ { USB_DEVICE(0x0df6, 0x006e) },
/* ZyXEL */
{ USB_DEVICE(0x0586, 0x3421) },
#endif
@@ -1231,6 +1239,8 @@ static struct usb_device_id rt2800usb_device_table[] = {
/* Arcadyan */
{ USB_DEVICE(0x043e, 0x7a12) },
{ USB_DEVICE(0x043e, 0x7a32) },
+ /* ASUS */
+ { USB_DEVICE(0x0b05, 0x17e8) },
/* Azurewave */
{ USB_DEVICE(0x13d3, 0x3329) },
{ USB_DEVICE(0x13d3, 0x3365) },
@@ -1240,6 +1250,9 @@ static struct usb_device_id rt2800usb_device_table[] = {
{ USB_DEVICE(0x2001, 0x3c1c) },
{ USB_DEVICE(0x2001, 0x3c1d) },
{ USB_DEVICE(0x2001, 0x3c1e) },
+ { USB_DEVICE(0x2001, 0x3c20) },
+ { USB_DEVICE(0x2001, 0x3c22) },
+ { USB_DEVICE(0x2001, 0x3c23) },
/* LG innotek */
{ USB_DEVICE(0x043e, 0x7a22) },
{ USB_DEVICE(0x043e, 0x7a42) },
@@ -1262,12 +1275,18 @@ static struct usb_device_id rt2800usb_device_table[] = {
{ USB_DEVICE(0x043e, 0x7a32) },
/* AVM GmbH */
{ USB_DEVICE(0x057c, 0x8501) },
- /* D-Link DWA-160-B2 */
+ /* Buffalo */
+ { USB_DEVICE(0x0411, 0x0241) },
+ { USB_DEVICE(0x0411, 0x0253) },
+ /* D-Link */
{ USB_DEVICE(0x2001, 0x3c1a) },
+ { USB_DEVICE(0x2001, 0x3c21) },
/* Proware */
{ USB_DEVICE(0x043e, 0x7a13) },
/* Ralink */
{ USB_DEVICE(0x148f, 0x5572) },
+ /* TRENDnet */
+ { USB_DEVICE(0x20f4, 0x724a) },
#endif
#ifdef CONFIG_RT2800USB_UNKNOWN
/*
@@ -1337,6 +1356,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
{ USB_DEVICE(0x1d4d, 0x0010) },
/* Planex */
{ USB_DEVICE(0x2019, 0xab24) },
+ { USB_DEVICE(0x2019, 0xab29) },
/* Qcom */
{ USB_DEVICE(0x18e8, 0x6259) },
/* RadioShack */
@@ -1348,6 +1368,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
{ USB_DEVICE(0x0df6, 0x0053) },
{ USB_DEVICE(0x0df6, 0x0069) },
{ USB_DEVICE(0x0df6, 0x006f) },
+ { USB_DEVICE(0x0df6, 0x0078) },
/* SMC */
{ USB_DEVICE(0x083a, 0xa512) },
{ USB_DEVICE(0x083a, 0xc522) },
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index fe4c572..89dbf2d 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -705,6 +705,7 @@ enum rt2x00_capability_flags {
REQUIRE_SW_SEQNO,
REQUIRE_HT_TX_DESC,
REQUIRE_PS_AUTOWAKE,
+ REQUIRE_DELAYED_RFKILL,
/*
* Capabilities
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index f12e909..6ccfa0a 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -1128,9 +1128,10 @@ static void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev)
return;
/*
- * Unregister extra components.
+ * Stop rfkill polling.
*/
- rt2x00rfkill_unregister(rt2x00dev);
+ if (test_bit(REQUIRE_DELAYED_RFKILL, &rt2x00dev->cap_flags))
+ rt2x00rfkill_unregister(rt2x00dev);
/*
* Allow the HW to uninitialize.
@@ -1168,6 +1169,12 @@ static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev)
set_bit(DEVICE_STATE_INITIALIZED, &rt2x00dev->flags);
+ /*
+ * Start rfkill polling.
+ */
+ if (test_bit(REQUIRE_DELAYED_RFKILL, &rt2x00dev->cap_flags))
+ rt2x00rfkill_register(rt2x00dev);
+
return 0;
}
@@ -1377,7 +1384,12 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
rt2x00link_register(rt2x00dev);
rt2x00leds_register(rt2x00dev);
rt2x00debug_register(rt2x00dev);
- rt2x00rfkill_register(rt2x00dev);
+
+ /*
+ * Start rfkill polling.
+ */
+ if (!test_bit(REQUIRE_DELAYED_RFKILL, &rt2x00dev->cap_flags))
+ rt2x00rfkill_register(rt2x00dev);
return 0;
@@ -1393,6 +1405,12 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
/*
+ * Stop rfkill polling.
+ */
+ if (!test_bit(REQUIRE_DELAYED_RFKILL, &rt2x00dev->cap_flags))
+ rt2x00rfkill_unregister(rt2x00dev);
+
+ /*
* Disable radio.
*/
rt2x00lib_disable_radio(rt2x00dev);
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index f8cff1f..c03748d 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -489,6 +489,8 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
crypto.cipher = rt2x00crypto_key_to_cipher(key);
if (crypto.cipher == CIPHER_NONE)
return -EOPNOTSUPP;
+ if (crypto.cipher == CIPHER_TKIP && rt2x00_is_usb(rt2x00dev))
+ return -EOPNOTSUPP;
crypto.cmd = cmd;
@@ -623,20 +625,18 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
bss_conf->bssid);
/*
- * Update the beacon. This is only required on USB devices. PCI
- * devices fetch beacons periodically.
- */
- if (changes & BSS_CHANGED_BEACON && rt2x00_is_usb(rt2x00dev))
- rt2x00queue_update_beacon(rt2x00dev, vif);
-
- /*
* Start/stop beaconing.
*/
if (changes & BSS_CHANGED_BEACON_ENABLED) {
if (!bss_conf->enable_beacon && intf->enable_beacon) {
- rt2x00queue_clear_beacon(rt2x00dev, vif);
rt2x00dev->intf_beaconing--;
intf->enable_beacon = false;
+ /*
+ * Clear beacon in the H/W for this vif. This is needed
+ * to disable beaconing on this particular interface
+ * and keep it running on other interfaces.
+ */
+ rt2x00queue_clear_beacon(rt2x00dev, vif);
if (rt2x00dev->intf_beaconing == 0) {
/*
@@ -647,11 +647,15 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
rt2x00queue_stop_queue(rt2x00dev->bcn);
mutex_unlock(&intf->beacon_skb_mutex);
}
-
-
} else if (bss_conf->enable_beacon && !intf->enable_beacon) {
rt2x00dev->intf_beaconing++;
intf->enable_beacon = true;
+ /*
+ * Upload beacon to the H/W. This is only required on
+ * USB devices. PCI devices fetch beacons periodically.
+ */
+ if (rt2x00_is_usb(rt2x00dev))
+ rt2x00queue_update_beacon(rt2x00dev, vif);
if (rt2x00dev->intf_beaconing == 1) {
/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 66a2db8..e618217 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -160,55 +160,29 @@ void rt2x00queue_align_frame(struct sk_buff *skb)
skb_trim(skb, frame_length);
}
-void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int header_length)
+/*
+ * H/W needs L2 padding between the header and the paylod if header size
+ * is not 4 bytes aligned.
+ */
+void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int hdr_len)
{
- unsigned int payload_length = skb->len - header_length;
- unsigned int header_align = ALIGN_SIZE(skb, 0);
- unsigned int payload_align = ALIGN_SIZE(skb, header_length);
- unsigned int l2pad = payload_length ? L2PAD_SIZE(header_length) : 0;
+ unsigned int l2pad = (skb->len > hdr_len) ? L2PAD_SIZE(hdr_len) : 0;
- /*
- * Adjust the header alignment if the payload needs to be moved more
- * than the header.
- */
- if (payload_align > header_align)
- header_align += 4;
-
- /* There is nothing to do if no alignment is needed */
- if (!header_align)
+ if (!l2pad)
return;
- /* Reserve the amount of space needed in front of the frame */
- skb_push(skb, header_align);
-
- /*
- * Move the header.
- */
- memmove(skb->data, skb->data + header_align, header_length);
-
- /* Move the payload, if present and if required */
- if (payload_length && payload_align)
- memmove(skb->data + header_length + l2pad,
- skb->data + header_length + l2pad + payload_align,
- payload_length);
-
- /* Trim the skb to the correct size */
- skb_trim(skb, header_length + l2pad + payload_length);
+ skb_push(skb, l2pad);
+ memmove(skb->data, skb->data + l2pad, hdr_len);
}
-void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int header_length)
+void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int hdr_len)
{
- /*
- * L2 padding is only present if the skb contains more than just the
- * IEEE 802.11 header.
- */
- unsigned int l2pad = (skb->len > header_length) ?
- L2PAD_SIZE(header_length) : 0;
+ unsigned int l2pad = (skb->len > hdr_len) ? L2PAD_SIZE(hdr_len) : 0;
if (!l2pad)
return;
- memmove(skb->data + l2pad, skb->data, header_length);
+ memmove(skb->data + l2pad, skb->data, hdr_len);
skb_pull(skb, l2pad);
}
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c b/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c
index e06971b..f923d8c 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c
@@ -1025,9 +1025,20 @@ int rtl88ee_hw_init(struct ieee80211_hw *hw)
bool rtstatus = true;
int err = 0;
u8 tmp_u1b, u1byte;
+ unsigned long flags;
RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Rtl8188EE hw init\n");
rtlpriv->rtlhal.being_init_adapter = true;
+ /* As this function can take a very long time (up to 350 ms)
+ * and can be called with irqs disabled, reenable the irqs
+ * to let the other devices continue being serviced.
+ *
+ * It is safe doing so since our own interrupts will only be enabled
+ * in a subsequent step.
+ */
+ local_save_flags(flags);
+ local_irq_enable();
+
rtlpriv->intf_ops->disable_aspm(hw);
tmp_u1b = rtl_read_byte(rtlpriv, REG_SYS_CLKR+1);
@@ -1043,7 +1054,7 @@ int rtl88ee_hw_init(struct ieee80211_hw *hw)
if (rtstatus != true) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n");
err = 1;
- return err;
+ goto exit;
}
err = rtl88e_download_fw(hw, false);
@@ -1051,8 +1062,7 @@ int rtl88ee_hw_init(struct ieee80211_hw *hw)
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
"Failed to download FW. Init HW without FW now..\n");
err = 1;
- rtlhal->fw_ready = false;
- return err;
+ goto exit;
} else {
rtlhal->fw_ready = true;
}
@@ -1135,10 +1145,12 @@ int rtl88ee_hw_init(struct ieee80211_hw *hw)
}
rtl_write_byte(rtlpriv, REG_NAV_CTRL+2, ((30000+127)/128));
rtl88e_dm_init(hw);
+exit:
+ local_irq_restore(flags);
rtlpriv->rtlhal.being_init_adapter = false;
RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "end of Rtl8188EE hw init %x\n",
err);
- return 0;
+ return err;
}
static enum version_8188e _rtl88ee_read_chip_version(struct ieee80211_hw *hw)
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c b/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c
index 68685a8..749d417 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c
@@ -293,7 +293,7 @@ static void _rtl88ee_translate_rx_signal_stuff(struct ieee80211_hw *hw,
u8 *psaddr;
__le16 fc;
u16 type, ufc;
- bool match_bssid, packet_toself, packet_beacon, addr;
+ bool match_bssid, packet_toself, packet_beacon = false, addr;
tmp_buf = skb->data + pstatus->rx_drvinfo_size + pstatus->rx_bufshift;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
index 189ba12..c3f2b55 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
@@ -985,19 +985,30 @@ int rtl92cu_hw_init(struct ieee80211_hw *hw)
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
int err = 0;
static bool iqk_initialized;
+ unsigned long flags;
+
+ /* As this function can take a very long time (up to 350 ms)
+ * and can be called with irqs disabled, reenable the irqs
+ * to let the other devices continue being serviced.
+ *
+ * It is safe doing so since our own interrupts will only be enabled
+ * in a subsequent step.
+ */
+ local_save_flags(flags);
+ local_irq_enable();
rtlhal->hw_type = HARDWARE_TYPE_RTL8192CU;
err = _rtl92cu_init_mac(hw);
if (err) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "init mac failed!\n");
- return err;
+ goto exit;
}
err = rtl92c_download_fw(hw);
if (err) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
"Failed to download FW. Init HW without FW now..\n");
err = 1;
- return err;
+ goto exit;
}
rtlhal->last_hmeboxnum = 0; /* h2c */
_rtl92cu_phy_param_tab_init(hw);
@@ -1034,6 +1045,8 @@ int rtl92cu_hw_init(struct ieee80211_hw *hw)
_InitPABias(hw);
_update_mac_setting(hw);
rtl92c_dm_init(hw);
+exit:
+ local_irq_restore(flags);
return err;
}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
index 8188dcb..e7a2af3 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
@@ -316,6 +316,7 @@ static struct usb_device_id rtl8192c_usb_ids[] = {
{RTL_USB_DEVICE(0x0bda, 0x5088, rtl92cu_hal_cfg)}, /*Thinkware-CC&C*/
{RTL_USB_DEVICE(0x0df6, 0x0052, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/
{RTL_USB_DEVICE(0x0df6, 0x005c, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/
+ {RTL_USB_DEVICE(0x0df6, 0x0070, rtl92cu_hal_cfg)}, /*Sitecom - 150N */
{RTL_USB_DEVICE(0x0df6, 0x0077, rtl92cu_hal_cfg)}, /*Sitecom-WLA2100V2*/
{RTL_USB_DEVICE(0x0eb0, 0x9071, rtl92cu_hal_cfg)}, /*NO Brand - Etop*/
{RTL_USB_DEVICE(0x4856, 0x0091, rtl92cu_hal_cfg)}, /*NetweeN - Feixun*/
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
index 4f46178..c471400 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
@@ -955,7 +955,7 @@ int rtl92se_hw_init(struct ieee80211_hw *hw)
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
u8 tmp_byte = 0;
-
+ unsigned long flags;
bool rtstatus = true;
u8 tmp_u1b;
int err = false;
@@ -967,6 +967,16 @@ int rtl92se_hw_init(struct ieee80211_hw *hw)
rtlpci->being_init_adapter = true;
+ /* As this function can take a very long time (up to 350 ms)
+ * and can be called with irqs disabled, reenable the irqs
+ * to let the other devices continue being serviced.
+ *
+ * It is safe doing so since our own interrupts will only be enabled
+ * in a subsequent step.
+ */
+ local_save_flags(flags);
+ local_irq_enable();
+
rtlpriv->intf_ops->disable_aspm(hw);
/* 1. MAC Initialize */
@@ -984,7 +994,8 @@ int rtl92se_hw_init(struct ieee80211_hw *hw)
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
"Failed to download FW. Init HW without FW now... "
"Please copy FW into /lib/firmware/rtlwifi\n");
- return 1;
+ err = 1;
+ goto exit;
}
/* After FW download, we have to reset MAC register */
@@ -997,7 +1008,8 @@ int rtl92se_hw_init(struct ieee80211_hw *hw)
/* 3. Initialize MAC/PHY Config by MACPHY_reg.txt */
if (!rtl92s_phy_mac_config(hw)) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "MAC Config failed\n");
- return rtstatus;
+ err = rtstatus;
+ goto exit;
}
/* because last function modify RCR, so we update
@@ -1016,7 +1028,8 @@ int rtl92se_hw_init(struct ieee80211_hw *hw)
/* 4. Initialize BB After MAC Config PHY_reg.txt, AGC_Tab.txt */
if (!rtl92s_phy_bb_config(hw)) {
RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "BB Config failed\n");
- return rtstatus;
+ err = rtstatus;
+ goto exit;
}
/* 5. Initiailze RF RAIO_A.txt RF RAIO_B.txt */
@@ -1033,7 +1046,8 @@ int rtl92se_hw_init(struct ieee80211_hw *hw)
if (!rtl92s_phy_rf_config(hw)) {
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "RF Config failed\n");
- return rtstatus;
+ err = rtstatus;
+ goto exit;
}
/* After read predefined TXT, we must set BB/MAC/RF
@@ -1122,8 +1136,9 @@ int rtl92se_hw_init(struct ieee80211_hw *hw)
rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_ON);
rtl92s_dm_init(hw);
+exit:
+ local_irq_restore(flags);
rtlpci->being_init_adapter = false;
-
return err;
}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
index 7d0f2e2..c240b75 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
@@ -49,6 +49,12 @@ static u8 _rtl92se_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 skb_queue)
if (ieee80211_is_nullfunc(fc))
return QSLT_HIGH;
+ /* Kernel commit 1bf4bbb4024dcdab changed EAPOL packets to use
+ * queue V0 at priority 7; however, the RTL8192SE appears to have
+ * that queue at priority 6
+ */
+ if (skb->priority == 7)
+ return QSLT_VO;
return skb->priority;
}
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c b/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c
index c333dfd..99f6bc5 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c
@@ -880,14 +880,25 @@ int rtl8723ae_hw_init(struct ieee80211_hw *hw)
bool rtstatus = true;
int err;
u8 tmp_u1b;
+ unsigned long flags;
rtlpriv->rtlhal.being_init_adapter = true;
+ /* As this function can take a very long time (up to 350 ms)
+ * and can be called with irqs disabled, reenable the irqs
+ * to let the other devices continue being serviced.
+ *
+ * It is safe doing so since our own interrupts will only be enabled
+ * in a subsequent step.
+ */
+ local_save_flags(flags);
+ local_irq_enable();
+
rtlpriv->intf_ops->disable_aspm(hw);
rtstatus = _rtl8712e_init_mac(hw);
if (rtstatus != true) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n");
err = 1;
- return err;
+ goto exit;
}
err = rtl8723ae_download_fw(hw);
@@ -895,8 +906,7 @@ int rtl8723ae_hw_init(struct ieee80211_hw *hw)
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
"Failed to download FW. Init HW without FW now..\n");
err = 1;
- rtlhal->fw_ready = false;
- return err;
+ goto exit;
} else {
rtlhal->fw_ready = true;
}
@@ -971,6 +981,8 @@ int rtl8723ae_hw_init(struct ieee80211_hw *hw)
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "under 1.5V\n");
}
rtl8723ae_dm_init(hw);
+exit:
+ local_irq_restore(flags);
rtlpriv->rtlhal.being_init_adapter = false;
return err;
}
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 7c541dc..fd3c1da 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -468,9 +468,6 @@ static void xennet_make_frags(struct sk_buff *skb, struct net_device *dev,
len = skb_frag_size(frag);
offset = frag->page_offset;
- /* Data must not cross a page boundary. */
- BUG_ON(len + offset > PAGE_SIZE<<compound_order(page));
-
/* Skip unused frames from start of page */
page += offset >> PAGE_SHIFT;
offset &= ~PAGE_MASK;
@@ -478,8 +475,6 @@ static void xennet_make_frags(struct sk_buff *skb, struct net_device *dev,
while (len > 0) {
unsigned long bytes;
- BUG_ON(offset >= PAGE_SIZE);
-
bytes = PAGE_SIZE - offset;
if (bytes > len)
bytes = len;