net: netcp: ale: use ale_status to size the ale table
authorKaricheri, Muralidharan <m-karicheri2@ti.com>
Fri, 6 Jan 2017 20:37:45 +0000 (15:37 -0500)
committerDavid S. Miller <davem@davemloft.net>
Sun, 8 Jan 2017 02:03:50 +0000 (21:03 -0500)
ALE h/w on newer version of NetCP (K2E/L/G) does provide a ALE_STATUS
register for the size of the ALE Table implemented in h/w. Currently
for example we set ALE Table size to 1024 for NetCP ALE on
K2E even though the ALE Status/Documentation shows it has 8192 entries.
So take advantage of this register to read the size of ALE table supported
and use that value in the driver for the newer version of NetCP ALE.
For NetCP lite, ALE Table size is much less (64) and indicated by a size
of zero in ALE_STATUS. So use that as a default for now. While at it,
also fix the ale table size on 10G switch to 2048 per User guide
http://www.ti.com/lit/ug/spruhj5/spruhj5.pdf

Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
Signed-off-by: Sekhar Nori <nsekhar@ti.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/ti/cpsw_ale.c
drivers/net/ethernet/ti/netcp_ethss.c

index e15db39a2b69c920da84bafff9a64a654196b7d9..62a18d61e0aaf88229fcc97f3496a6bb04bef0aa 100644 (file)
@@ -33,6 +33,7 @@
 
 /* ALE Registers */
 #define ALE_IDVER              0x00
+#define ALE_STATUS             0x04
 #define ALE_CONTROL            0x08
 #define ALE_PRESCALE           0x10
 #define ALE_UNKNOWNVLAN                0x18
 #define ALE_UCAST_OUI                  2
 #define ALE_UCAST_TOUCHED              3
 
+#define ALE_TABLE_SIZE_MULTIPLIER      1024
+#define ALE_STATUS_SIZE_MASK           0x1f
+#define ALE_TABLE_SIZE_DEFAULT         64
+
 static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits)
 {
        int idx;
@@ -728,7 +733,7 @@ static void cpsw_ale_timer(unsigned long arg)
 
 void cpsw_ale_start(struct cpsw_ale *ale)
 {
-       u32 rev;
+       u32 rev, ale_entries;
 
        rev = __raw_readl(ale->params.ale_regs + ALE_IDVER);
        if (!ale->params.major_ver_mask)
@@ -740,6 +745,30 @@ void cpsw_ale_start(struct cpsw_ale *ale)
                 ALE_VERSION_MAJOR(rev, ale->params.major_ver_mask),
                 ALE_VERSION_MINOR(rev));
 
+       if (!ale->params.ale_entries) {
+               ale_entries =
+                       __raw_readl(ale->params.ale_regs + ALE_STATUS) &
+                                   ALE_STATUS_SIZE_MASK;
+               /* ALE available on newer NetCP switches has introduced
+                * a register, ALE_STATUS, to indicate the size of ALE
+                * table which shows the size as a multiple of 1024 entries.
+                * For these, params.ale_entries will be set to zero. So
+                * read the register and update the value of ale_entries.
+                * ALE table on NetCP lite, is much smaller and is indicated
+                * by a value of zero in ALE_STATUS. So use a default value
+                * of ALE_TABLE_SIZE_DEFAULT for this. Caller is expected
+                * to set the value of ale_entries for all other versions
+                * of ALE.
+                */
+               if (!ale_entries)
+                       ale_entries = ALE_TABLE_SIZE_DEFAULT;
+               else
+                       ale_entries *= ALE_TABLE_SIZE_MULTIPLIER;
+               ale->params.ale_entries = ale_entries;
+       }
+       dev_info(ale->params.dev,
+                "ALE Table size %ld\n", ale->params.ale_entries);
+
        if (ale->params.nu_switch_ale) {
                /* Separate registers for unknown vlan configuration.
                 * Also there are N bits, where N is number of ale
index e4a18628d23d767f231906b02da4116033514986..f7bb241b17abb69c7a114078afefe658f95ca0c5 100644 (file)
@@ -81,7 +81,6 @@
 #define GBENU_CPTS_OFFSET              0x1d000
 #define GBENU_ALE_OFFSET               0x1e000
 #define GBENU_HOST_PORT_NUM            0
-#define GBENU_NUM_ALE_ENTRIES          1024
 #define GBENU_SGMII_MODULE_SIZE                0x100
 
 /* 10G Ethernet SS defines */
 #define XGBE10_ALE_OFFSET              0x700
 #define XGBE10_HW_STATS_OFFSET         0x800
 #define XGBE10_HOST_PORT_NUM           0
-#define XGBE10_NUM_ALE_ENTRIES         1024
+#define XGBE10_NUM_ALE_ENTRIES         2048
 
 #define        GBE_TIMER_INTERVAL                      (HZ / 2)
 
@@ -3441,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_ports = gbe_dev->max_num_ports;
        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;
 
        /* Subsystem registers */