Commit 82e4869d authored by David S. Miller's avatar David S. Miller

Merge branch 'netcp-next'

Murali Karicheri says:

====================
netcp: enhancements and minor fixes

This series is for net-next. This propagates enhancements and minor
bug fixes from internal version of the driver to keep the upstream
in sync. Please review and apply if this looks good.

Tested on all of K2HK/E/L boards with nfs rootfs.
Test logs below
K2HK-EVM: http://pastebin.ubuntu.com/23754106/
k2L-EVM: http://pastebin.ubuntu.com/23754143/
K2E-EVM: http://pastebin.ubuntu.com/23754159/

History:
  v1 - dropped 1/10 amd 2/10 of v0 based on comments from Rob as
       it needs more work before submission
  v0 - Initial version
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents b14ad90c b361da83
This diff is collapsed.
/* /*
* Texas Instruments 3-Port Ethernet Switch Address Lookup Engine APIs * Texas Instruments N-Port Ethernet Switch Address Lookup Engine APIs
* *
* Copyright (C) 2012 Texas Instruments * Copyright (C) 2012 Texas Instruments
* *
...@@ -21,6 +21,16 @@ struct cpsw_ale_params { ...@@ -21,6 +21,16 @@ struct cpsw_ale_params {
unsigned long ale_ageout; /* in secs */ unsigned long ale_ageout; /* in secs */
unsigned long ale_entries; unsigned long ale_entries;
unsigned long ale_ports; unsigned long ale_ports;
/* NU Switch has specific handling as number of bits in ALE entries
* are different than other versions of ALE. Also there are specific
* registers for unknown vlan specific fields. So use nu_switch_ale
* to identify this hardware.
*/
bool nu_switch_ale;
/* mask bit used in NU Switch ALE is 3 bits instead of 8 bits. So
* pass it from caller.
*/
u32 major_ver_mask;
}; };
struct cpsw_ale { struct cpsw_ale {
...@@ -28,6 +38,11 @@ struct cpsw_ale { ...@@ -28,6 +38,11 @@ struct cpsw_ale {
struct timer_list timer; struct timer_list timer;
unsigned long ageout; unsigned long ageout;
int allmulti; int allmulti;
u32 version;
/* These bits are different on NetCP NU Switch ALE */
u32 port_mask_bits;
u32 port_num_bits;
u32 vlan_field_bits;
}; };
enum cpsw_ale_control { enum cpsw_ale_control {
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/soc/ti/knav_dma.h> #include <linux/soc/ti/knav_dma.h>
#include <linux/u64_stats_sync.h>
/* Maximum Ethernet frame size supported by Keystone switch */ /* Maximum Ethernet frame size supported by Keystone switch */
#define NETCP_MAX_FRAME_SIZE 9504 #define NETCP_MAX_FRAME_SIZE 9504
...@@ -68,6 +69,20 @@ struct netcp_addr { ...@@ -68,6 +69,20 @@ struct netcp_addr {
struct list_head node; struct list_head node;
}; };
struct netcp_stats {
struct u64_stats_sync syncp_rx ____cacheline_aligned_in_smp;
u64 rx_packets;
u64 rx_bytes;
u32 rx_errors;
u32 rx_dropped;
struct u64_stats_sync syncp_tx ____cacheline_aligned_in_smp;
u64 tx_packets;
u64 tx_bytes;
u32 tx_errors;
u32 tx_dropped;
};
struct netcp_intf { struct netcp_intf {
struct device *dev; struct device *dev;
struct device *ndev_dev; struct device *ndev_dev;
...@@ -87,6 +102,11 @@ struct netcp_intf { ...@@ -87,6 +102,11 @@ struct netcp_intf {
void *rx_fdq[KNAV_DMA_FDQ_PER_CHAN]; void *rx_fdq[KNAV_DMA_FDQ_PER_CHAN];
struct napi_struct rx_napi; struct napi_struct rx_napi;
struct napi_struct tx_napi; struct napi_struct tx_napi;
#define ETH_SW_CAN_REMOVE_ETH_FCS BIT(0)
u32 hw_cap;
/* 64-bit netcp stats */
struct netcp_stats stats;
void *rx_channel; void *rx_channel;
const char *dma_chan_name; const char *dma_chan_name;
...@@ -115,6 +135,7 @@ struct netcp_packet { ...@@ -115,6 +135,7 @@ struct netcp_packet {
struct sk_buff *skb; struct sk_buff *skb;
__le32 *epib; __le32 *epib;
u32 *psdata; u32 *psdata;
u32 eflags;
unsigned int psdata_len; unsigned int psdata_len;
struct netcp_intf *netcp; struct netcp_intf *netcp;
struct netcp_tx_pipe *tx_pipe; struct netcp_tx_pipe *tx_pipe;
......
...@@ -122,6 +122,13 @@ static void get_pkt_info(dma_addr_t *buff, u32 *buff_len, dma_addr_t *ndesc, ...@@ -122,6 +122,13 @@ static void get_pkt_info(dma_addr_t *buff, u32 *buff_len, dma_addr_t *ndesc,
*ndesc = le32_to_cpu(desc->next_desc); *ndesc = le32_to_cpu(desc->next_desc);
} }
static void get_desc_info(u32 *desc_info, u32 *pkt_info,
struct knav_dma_desc *desc)
{
*desc_info = le32_to_cpu(desc->desc_info);
*pkt_info = le32_to_cpu(desc->packet_info);
}
static u32 get_sw_data(int index, struct knav_dma_desc *desc) static u32 get_sw_data(int index, struct knav_dma_desc *desc)
{ {
/* No Endian conversion needed as this data is untouched by hw */ /* No Endian conversion needed as this data is untouched by hw */
...@@ -622,6 +629,7 @@ static void netcp_free_rx_desc_chain(struct netcp_intf *netcp, ...@@ -622,6 +629,7 @@ static void netcp_free_rx_desc_chain(struct netcp_intf *netcp,
static void netcp_empty_rx_queue(struct netcp_intf *netcp) static void netcp_empty_rx_queue(struct netcp_intf *netcp)
{ {
struct netcp_stats *rx_stats = &netcp->stats;
struct knav_dma_desc *desc; struct knav_dma_desc *desc;
unsigned int dma_sz; unsigned int dma_sz;
dma_addr_t dma; dma_addr_t dma;
...@@ -635,16 +643,17 @@ static void netcp_empty_rx_queue(struct netcp_intf *netcp) ...@@ -635,16 +643,17 @@ static void netcp_empty_rx_queue(struct netcp_intf *netcp)
if (unlikely(!desc)) { if (unlikely(!desc)) {
dev_err(netcp->ndev_dev, "%s: failed to unmap Rx desc\n", dev_err(netcp->ndev_dev, "%s: failed to unmap Rx desc\n",
__func__); __func__);
netcp->ndev->stats.rx_errors++; rx_stats->rx_errors++;
continue; continue;
} }
netcp_free_rx_desc_chain(netcp, desc); netcp_free_rx_desc_chain(netcp, desc);
netcp->ndev->stats.rx_dropped++; rx_stats->rx_dropped++;
} }
} }
static int netcp_process_one_rx_packet(struct netcp_intf *netcp) static int netcp_process_one_rx_packet(struct netcp_intf *netcp)
{ {
struct netcp_stats *rx_stats = &netcp->stats;
unsigned int dma_sz, buf_len, org_buf_len; unsigned int dma_sz, buf_len, org_buf_len;
struct knav_dma_desc *desc, *ndesc; struct knav_dma_desc *desc, *ndesc;
unsigned int pkt_sz = 0, accum_sz; unsigned int pkt_sz = 0, accum_sz;
...@@ -653,6 +662,7 @@ static int netcp_process_one_rx_packet(struct netcp_intf *netcp) ...@@ -653,6 +662,7 @@ static int netcp_process_one_rx_packet(struct netcp_intf *netcp)
struct netcp_packet p_info; struct netcp_packet p_info;
struct sk_buff *skb; struct sk_buff *skb;
void *org_buf_ptr; void *org_buf_ptr;
u32 tmp;
dma_desc = knav_queue_pop(netcp->rx_queue, &dma_sz); dma_desc = knav_queue_pop(netcp->rx_queue, &dma_sz);
if (!dma_desc) if (!dma_desc)
...@@ -724,21 +734,27 @@ static int netcp_process_one_rx_packet(struct netcp_intf *netcp) ...@@ -724,21 +734,27 @@ static int netcp_process_one_rx_packet(struct netcp_intf *netcp)
knav_pool_desc_put(netcp->rx_pool, ndesc); knav_pool_desc_put(netcp->rx_pool, ndesc);
} }
/* Free the primary descriptor */
knav_pool_desc_put(netcp->rx_pool, desc);
/* check for packet len and warn */ /* check for packet len and warn */
if (unlikely(pkt_sz != accum_sz)) if (unlikely(pkt_sz != accum_sz))
dev_dbg(netcp->ndev_dev, "mismatch in packet size(%d) & sum of fragments(%d)\n", dev_dbg(netcp->ndev_dev, "mismatch in packet size(%d) & sum of fragments(%d)\n",
pkt_sz, accum_sz); pkt_sz, accum_sz);
/* Remove ethernet FCS from the packet */ /* Newer version of the Ethernet switch can trim the Ethernet FCS
__pskb_trim(skb, skb->len - ETH_FCS_LEN); * from the packet and is indicated in hw_cap. So trim it only for
* older h/w
*/
if (!(netcp->hw_cap & ETH_SW_CAN_REMOVE_ETH_FCS))
__pskb_trim(skb, skb->len - ETH_FCS_LEN);
/* Call each of the RX hooks */ /* Call each of the RX hooks */
p_info.skb = skb; p_info.skb = skb;
skb->dev = netcp->ndev; skb->dev = netcp->ndev;
p_info.rxtstamp_complete = false; p_info.rxtstamp_complete = false;
get_desc_info(&tmp, &p_info.eflags, desc);
p_info.epib = desc->epib;
p_info.psdata = (u32 __force *)desc->psdata;
p_info.eflags = ((p_info.eflags >> KNAV_DMA_DESC_EFLAGS_SHIFT) &
KNAV_DMA_DESC_EFLAGS_MASK);
list_for_each_entry(rx_hook, &netcp->rxhook_list_head, list) { list_for_each_entry(rx_hook, &netcp->rxhook_list_head, list) {
int ret; int ret;
...@@ -747,14 +763,20 @@ static int netcp_process_one_rx_packet(struct netcp_intf *netcp) ...@@ -747,14 +763,20 @@ static int netcp_process_one_rx_packet(struct netcp_intf *netcp)
if (unlikely(ret)) { if (unlikely(ret)) {
dev_err(netcp->ndev_dev, "RX hook %d failed: %d\n", dev_err(netcp->ndev_dev, "RX hook %d failed: %d\n",
rx_hook->order, ret); rx_hook->order, ret);
netcp->ndev->stats.rx_errors++; /* Free the primary descriptor */
rx_stats->rx_dropped++;
knav_pool_desc_put(netcp->rx_pool, desc);
dev_kfree_skb(skb); dev_kfree_skb(skb);
return 0; return 0;
} }
} }
/* Free the primary descriptor */
knav_pool_desc_put(netcp->rx_pool, desc);
netcp->ndev->stats.rx_packets++; u64_stats_update_begin(&rx_stats->syncp_rx);
netcp->ndev->stats.rx_bytes += skb->len; rx_stats->rx_packets++;
rx_stats->rx_bytes += skb->len;
u64_stats_update_end(&rx_stats->syncp_rx);
/* push skb up the stack */ /* push skb up the stack */
skb->protocol = eth_type_trans(skb, netcp->ndev); skb->protocol = eth_type_trans(skb, netcp->ndev);
...@@ -763,7 +785,7 @@ static int netcp_process_one_rx_packet(struct netcp_intf *netcp) ...@@ -763,7 +785,7 @@ static int netcp_process_one_rx_packet(struct netcp_intf *netcp)
free_desc: free_desc:
netcp_free_rx_desc_chain(netcp, desc); netcp_free_rx_desc_chain(netcp, desc);
netcp->ndev->stats.rx_errors++; rx_stats->rx_errors++;
return 0; return 0;
} }
...@@ -994,6 +1016,7 @@ static void netcp_free_tx_desc_chain(struct netcp_intf *netcp, ...@@ -994,6 +1016,7 @@ static void netcp_free_tx_desc_chain(struct netcp_intf *netcp,
static int netcp_process_tx_compl_packets(struct netcp_intf *netcp, static int netcp_process_tx_compl_packets(struct netcp_intf *netcp,
unsigned int budget) unsigned int budget)
{ {
struct netcp_stats *tx_stats = &netcp->stats;
struct knav_dma_desc *desc; struct knav_dma_desc *desc;
struct netcp_tx_cb *tx_cb; struct netcp_tx_cb *tx_cb;
struct sk_buff *skb; struct sk_buff *skb;
...@@ -1008,7 +1031,7 @@ static int netcp_process_tx_compl_packets(struct netcp_intf *netcp, ...@@ -1008,7 +1031,7 @@ static int netcp_process_tx_compl_packets(struct netcp_intf *netcp,
desc = knav_pool_desc_unmap(netcp->tx_pool, dma, dma_sz); desc = knav_pool_desc_unmap(netcp->tx_pool, dma, dma_sz);
if (unlikely(!desc)) { if (unlikely(!desc)) {
dev_err(netcp->ndev_dev, "failed to unmap Tx desc\n"); dev_err(netcp->ndev_dev, "failed to unmap Tx desc\n");
netcp->ndev->stats.tx_errors++; tx_stats->tx_errors++;
continue; continue;
} }
...@@ -1019,7 +1042,7 @@ static int netcp_process_tx_compl_packets(struct netcp_intf *netcp, ...@@ -1019,7 +1042,7 @@ static int netcp_process_tx_compl_packets(struct netcp_intf *netcp,
netcp_free_tx_desc_chain(netcp, desc, dma_sz); netcp_free_tx_desc_chain(netcp, desc, dma_sz);
if (!skb) { if (!skb) {
dev_err(netcp->ndev_dev, "No skb in Tx desc\n"); dev_err(netcp->ndev_dev, "No skb in Tx desc\n");
netcp->ndev->stats.tx_errors++; tx_stats->tx_errors++;
continue; continue;
} }
...@@ -1036,8 +1059,10 @@ static int netcp_process_tx_compl_packets(struct netcp_intf *netcp, ...@@ -1036,8 +1059,10 @@ static int netcp_process_tx_compl_packets(struct netcp_intf *netcp,
netif_wake_subqueue(netcp->ndev, subqueue); netif_wake_subqueue(netcp->ndev, subqueue);
} }
netcp->ndev->stats.tx_packets++; u64_stats_update_begin(&tx_stats->syncp_tx);
netcp->ndev->stats.tx_bytes += skb->len; tx_stats->tx_packets++;
tx_stats->tx_bytes += skb->len;
u64_stats_update_end(&tx_stats->syncp_tx);
dev_kfree_skb(skb); dev_kfree_skb(skb);
pkts++; pkts++;
} }
...@@ -1212,9 +1237,9 @@ static int netcp_tx_submit_skb(struct netcp_intf *netcp, ...@@ -1212,9 +1237,9 @@ static int netcp_tx_submit_skb(struct netcp_intf *netcp,
/* psdata points to both native-endian and device-endian data */ /* psdata points to both native-endian and device-endian data */
__le32 *psdata = (void __force *)p_info.psdata; __le32 *psdata = (void __force *)p_info.psdata;
memmove(p_info.psdata, p_info.psdata + p_info.psdata_len, set_words((u32 *)psdata +
p_info.psdata_len); (KNAV_DMA_NUM_PS_WORDS - p_info.psdata_len),
set_words(p_info.psdata, p_info.psdata_len, psdata); p_info.psdata_len, psdata);
tmp |= (p_info.psdata_len & KNAV_DMA_DESC_PSLEN_MASK) << tmp |= (p_info.psdata_len & KNAV_DMA_DESC_PSLEN_MASK) <<
KNAV_DMA_DESC_PSLEN_SHIFT; KNAV_DMA_DESC_PSLEN_SHIFT;
} }
...@@ -1258,6 +1283,7 @@ static int netcp_tx_submit_skb(struct netcp_intf *netcp, ...@@ -1258,6 +1283,7 @@ static int netcp_tx_submit_skb(struct netcp_intf *netcp,
static int netcp_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev) static int netcp_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev)
{ {
struct netcp_intf *netcp = netdev_priv(ndev); struct netcp_intf *netcp = netdev_priv(ndev);
struct netcp_stats *tx_stats = &netcp->stats;
int subqueue = skb_get_queue_mapping(skb); int subqueue = skb_get_queue_mapping(skb);
struct knav_dma_desc *desc; struct knav_dma_desc *desc;
int desc_count, ret = 0; int desc_count, ret = 0;
...@@ -1273,7 +1299,7 @@ static int netcp_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev) ...@@ -1273,7 +1299,7 @@ static int netcp_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev)
/* If we get here, the skb has already been dropped */ /* If we get here, the skb has already been dropped */
dev_warn(netcp->ndev_dev, "padding failed (%d), packet dropped\n", dev_warn(netcp->ndev_dev, "padding failed (%d), packet dropped\n",
ret); ret);
ndev->stats.tx_dropped++; tx_stats->tx_dropped++;
return ret; return ret;
} }
skb->len = NETCP_MIN_PACKET_SIZE; skb->len = NETCP_MIN_PACKET_SIZE;
...@@ -1301,7 +1327,7 @@ static int netcp_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev) ...@@ -1301,7 +1327,7 @@ static int netcp_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev)
return NETDEV_TX_OK; return NETDEV_TX_OK;
drop: drop:
ndev->stats.tx_dropped++; tx_stats->tx_dropped++;
if (desc) if (desc)
netcp_free_tx_desc_chain(netcp, desc, sizeof(*desc)); netcp_free_tx_desc_chain(netcp, desc, sizeof(*desc));
dev_kfree_skb(skb); dev_kfree_skb(skb);
...@@ -1883,12 +1909,46 @@ static int netcp_setup_tc(struct net_device *dev, u32 handle, __be16 proto, ...@@ -1883,12 +1909,46 @@ static int netcp_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
return 0; return 0;
} }
static struct rtnl_link_stats64 *
netcp_get_stats(struct net_device *ndev, struct rtnl_link_stats64 *stats)
{
struct netcp_intf *netcp = netdev_priv(ndev);
struct netcp_stats *p = &netcp->stats;
u64 rxpackets, rxbytes, txpackets, txbytes;
unsigned int start;
do {
start = u64_stats_fetch_begin_irq(&p->syncp_rx);
rxpackets = p->rx_packets;
rxbytes = p->rx_bytes;
} while (u64_stats_fetch_retry_irq(&p->syncp_rx, start));
do {
start = u64_stats_fetch_begin_irq(&p->syncp_tx);
txpackets = p->tx_packets;
txbytes = p->tx_bytes;
} while (u64_stats_fetch_retry_irq(&p->syncp_tx, start));
stats->rx_packets = rxpackets;
stats->rx_bytes = rxbytes;
stats->tx_packets = txpackets;
stats->tx_bytes = txbytes;
/* The following are stored as 32 bit */
stats->rx_errors = p->rx_errors;
stats->rx_dropped = p->rx_dropped;
stats->tx_dropped = p->tx_dropped;
return stats;
}
static const struct net_device_ops netcp_netdev_ops = { static const struct net_device_ops netcp_netdev_ops = {
.ndo_open = netcp_ndo_open, .ndo_open = netcp_ndo_open,
.ndo_stop = netcp_ndo_stop, .ndo_stop = netcp_ndo_stop,
.ndo_start_xmit = netcp_ndo_start_xmit, .ndo_start_xmit = netcp_ndo_start_xmit,
.ndo_set_rx_mode = netcp_set_rx_mode, .ndo_set_rx_mode = netcp_set_rx_mode,
.ndo_do_ioctl = netcp_ndo_ioctl, .ndo_do_ioctl = netcp_ndo_ioctl,
.ndo_get_stats64 = netcp_get_stats,
.ndo_set_mac_address = eth_mac_addr, .ndo_set_mac_address = eth_mac_addr,
.ndo_validate_addr = eth_validate_addr, .ndo_validate_addr = eth_validate_addr,
.ndo_vlan_rx_add_vid = netcp_rx_add_vid, .ndo_vlan_rx_add_vid = netcp_rx_add_vid,
...@@ -1935,6 +1995,8 @@ static int netcp_create_interface(struct netcp_device *netcp_device, ...@@ -1935,6 +1995,8 @@ static int netcp_create_interface(struct netcp_device *netcp_device,
INIT_LIST_HEAD(&netcp->txhook_list_head); INIT_LIST_HEAD(&netcp->txhook_list_head);
INIT_LIST_HEAD(&netcp->rxhook_list_head); INIT_LIST_HEAD(&netcp->rxhook_list_head);
INIT_LIST_HEAD(&netcp->addr_list); INIT_LIST_HEAD(&netcp->addr_list);
u64_stats_init(&netcp->stats.syncp_rx);
u64_stats_init(&netcp->stats.syncp_tx);
netcp->netcp_device = netcp_device; netcp->netcp_device = netcp_device;
netcp->dev = netcp_device->device; netcp->dev = netcp_device->device;
netcp->ndev = ndev; netcp->ndev = ndev;
......
...@@ -81,7 +81,6 @@ ...@@ -81,7 +81,6 @@
#define GBENU_CPTS_OFFSET 0x1d000 #define GBENU_CPTS_OFFSET 0x1d000
#define GBENU_ALE_OFFSET 0x1e000 #define GBENU_ALE_OFFSET 0x1e000
#define GBENU_HOST_PORT_NUM 0 #define GBENU_HOST_PORT_NUM 0
#define GBENU_NUM_ALE_ENTRIES 1024
#define GBENU_SGMII_MODULE_SIZE 0x100 #define GBENU_SGMII_MODULE_SIZE 0x100
/* 10G Ethernet SS defines */ /* 10G Ethernet SS defines */
...@@ -103,7 +102,7 @@ ...@@ -103,7 +102,7 @@
#define XGBE10_ALE_OFFSET 0x700 #define XGBE10_ALE_OFFSET 0x700
#define XGBE10_HW_STATS_OFFSET 0x800 #define XGBE10_HW_STATS_OFFSET 0x800
#define XGBE10_HOST_PORT_NUM 0 #define XGBE10_HOST_PORT_NUM 0
#define XGBE10_NUM_ALE_ENTRIES 1024 #define XGBE10_NUM_ALE_ENTRIES 2048
#define GBE_TIMER_INTERVAL (HZ / 2) #define GBE_TIMER_INTERVAL (HZ / 2)
...@@ -122,6 +121,7 @@ ...@@ -122,6 +121,7 @@
#define MACSL_FULLDUPLEX BIT(0) #define MACSL_FULLDUPLEX BIT(0)
#define GBE_CTL_P0_ENABLE BIT(2) #define GBE_CTL_P0_ENABLE BIT(2)
#define ETH_SW_CTL_P0_TX_CRC_REMOVE BIT(13)
#define GBE13_REG_VAL_STAT_ENABLE_ALL 0xff #define GBE13_REG_VAL_STAT_ENABLE_ALL 0xff
#define XGBE_REG_VAL_STAT_ENABLE_ALL 0xf #define XGBE_REG_VAL_STAT_ENABLE_ALL 0xf
#define GBE_STATS_CD_SEL BIT(28) #define GBE_STATS_CD_SEL BIT(28)
...@@ -2821,7 +2821,7 @@ static int gbe_open(void *intf_priv, struct net_device *ndev) ...@@ -2821,7 +2821,7 @@ static int gbe_open(void *intf_priv, struct net_device *ndev)
struct netcp_intf *netcp = netdev_priv(ndev); struct netcp_intf *netcp = netdev_priv(ndev);
struct gbe_slave *slave = gbe_intf->slave; struct gbe_slave *slave = gbe_intf->slave;
int port_num = slave->port_num; int port_num = slave->port_num;
u32 reg; u32 reg, val;
int ret; int ret;
reg = readl(GBE_REG_ADDR(gbe_dev, switch_regs, id_ver)); reg = readl(GBE_REG_ADDR(gbe_dev, switch_regs, id_ver));
...@@ -2851,7 +2851,12 @@ static int gbe_open(void *intf_priv, struct net_device *ndev) ...@@ -2851,7 +2851,12 @@ static int gbe_open(void *intf_priv, struct net_device *ndev)
writel(0, GBE_REG_ADDR(gbe_dev, switch_regs, ptype)); writel(0, GBE_REG_ADDR(gbe_dev, switch_regs, ptype));
/* Control register */ /* Control register */
writel(GBE_CTL_P0_ENABLE, GBE_REG_ADDR(gbe_dev, switch_regs, control)); val = GBE_CTL_P0_ENABLE;
if (IS_SS_ID_MU(gbe_dev)) {
val |= ETH_SW_CTL_P0_TX_CRC_REMOVE;
netcp->hw_cap = ETH_SW_CAN_REMOVE_ETH_FCS;
}
writel(val, GBE_REG_ADDR(gbe_dev, switch_regs, control));
/* All statistics enabled and STAT AB visible by default */ /* All statistics enabled and STAT AB visible by default */
writel(gbe_dev->stats_en_mask, GBE_REG_ADDR(gbe_dev, switch_regs, writel(gbe_dev->stats_en_mask, GBE_REG_ADDR(gbe_dev, switch_regs,
...@@ -2930,7 +2935,9 @@ static int init_slave(struct gbe_priv *gbe_dev, struct gbe_slave *slave, ...@@ -2930,7 +2935,9 @@ static int init_slave(struct gbe_priv *gbe_dev, struct gbe_slave *slave,
} }
slave->open = false; slave->open = false;
slave->phy_node = of_parse_phandle(node, "phy-handle", 0); if ((slave->link_interface == SGMII_LINK_MAC_PHY) ||
(slave->link_interface == XGMII_LINK_MAC_PHY))
slave->phy_node = of_parse_phandle(node, "phy-handle", 0);
slave->port_num = gbe_get_slave_port(gbe_dev, slave->slave_num); slave->port_num = gbe_get_slave_port(gbe_dev, slave->slave_num);
if (slave->link_interface >= XGMII_LINK_MAC_PHY) if (slave->link_interface >= XGMII_LINK_MAC_PHY)
...@@ -3433,7 +3440,6 @@ static int set_gbenu_ethss_priv(struct gbe_priv *gbe_dev, ...@@ -3433,7 +3440,6 @@ static int set_gbenu_ethss_priv(struct gbe_priv *gbe_dev,
gbe_dev->ale_reg = gbe_dev->switch_regs + GBENU_ALE_OFFSET; gbe_dev->ale_reg = gbe_dev->switch_regs + GBENU_ALE_OFFSET;
gbe_dev->ale_ports = gbe_dev->max_num_ports; gbe_dev->ale_ports = gbe_dev->max_num_ports;
gbe_dev->host_port = GBENU_HOST_PORT_NUM; gbe_dev->host_port = GBENU_HOST_PORT_NUM;
gbe_dev->ale_entries = GBE13_NUM_ALE_ENTRIES;
gbe_dev->stats_en_mask = (1 << (gbe_dev->max_num_ports)) - 1; gbe_dev->stats_en_mask = (1 << (gbe_dev->max_num_ports)) - 1;
/* Subsystem registers */ /* Subsystem registers */
...@@ -3601,7 +3607,10 @@ static int gbe_probe(struct netcp_device *netcp_device, struct device *dev, ...@@ -3601,7 +3607,10 @@ static int gbe_probe(struct netcp_device *netcp_device, struct device *dev,
ale_params.ale_ageout = GBE_DEFAULT_ALE_AGEOUT; ale_params.ale_ageout = GBE_DEFAULT_ALE_AGEOUT;
ale_params.ale_entries = gbe_dev->ale_entries; ale_params.ale_entries = gbe_dev->ale_entries;
ale_params.ale_ports = gbe_dev->ale_ports; ale_params.ale_ports = gbe_dev->ale_ports;
if (IS_SS_ID_MU(gbe_dev)) {
ale_params.major_ver_mask = 0x7;
ale_params.nu_switch_ale = true;
}
gbe_dev->ale = cpsw_ale_create(&ale_params); gbe_dev->ale = cpsw_ale_create(&ale_params);
if (!gbe_dev->ale) { if (!gbe_dev->ale) {
dev_err(gbe_dev->dev, "error initializing ale engine\n"); dev_err(gbe_dev->dev, "error initializing ale engine\n");
......
...@@ -41,6 +41,8 @@ ...@@ -41,6 +41,8 @@
#define KNAV_DMA_DESC_RETQ_SHIFT 0 #define KNAV_DMA_DESC_RETQ_SHIFT 0
#define KNAV_DMA_DESC_RETQ_MASK MASK(14) #define KNAV_DMA_DESC_RETQ_MASK MASK(14)
#define KNAV_DMA_DESC_BUF_LEN_MASK MASK(22) #define KNAV_DMA_DESC_BUF_LEN_MASK MASK(22)
#define KNAV_DMA_DESC_EFLAGS_MASK MASK(4)
#define KNAV_DMA_DESC_EFLAGS_SHIFT 20
#define KNAV_DMA_NUM_EPIB_WORDS 4 #define KNAV_DMA_NUM_EPIB_WORDS 4
#define KNAV_DMA_NUM_PS_WORDS 16 #define KNAV_DMA_NUM_PS_WORDS 16
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment