@@ -219,8 +219,6 @@ void xgene_enet_parse_error(struct xgene_enet_desc_ring *ring,
struct xgene_enet_pdata *pdata,
enum xgene_enet_err_code status)
{
- struct rtnl_link_stats64 *stats = &pdata->stats;
-
switch (status) {
case INGRESS_CRC:
ring->rx_crc_errors++;
@@ -227,6 +227,8 @@ enum xgene_enet_rm {
#define TCPHDR_LEN 6
#define IPHDR_POS 6
#define IPHDR_LEN 6
+#define MSS_POS 20
+#define MSS_LEN 2
#define EC_POS 22 /* Enable checksum */
#define EC_LEN 1
#define ET_POS 23 /* Enable TSO */
@@ -179,6 +179,46 @@ static int xgene_enet_tx_completion(struct xgene_enet_desc_ring *cp_ring,
return ret;
}
+static void apm_enet_init_mss_values(struct net_device *ndev)
+{
+ struct xgene_enet_pdata *pdata = netdev_priv(ndev);
+ int i;
+
+ pdata->mss_sw[0] = 64;
+ pdata->mss_sw[1] = 1024;
+ pdata->mss_sw[2] = 1400;
+ pdata->mss_sw[3] = 1446;
+
+ for (i = 0; i < NUM_MSS_REG; i++)
+ pdata->mac_ops->set_mss(pdata, pdata->mss_sw[i], i);
+}
+
+static int apm_enet_get_mss_index(struct net_device *ndev, u32 new_mss)
+{
+ struct xgene_enet_pdata *pdata = netdev_priv(ndev);
+ int i;
+
+ for (i = NUM_MSS_REG - 1; i >= 0; i--) {
+ if (new_mss >= pdata->mss_sw[i])
+ return i;
+ }
+
+ return -1;
+}
+
+static int xgene_enet_setup_mss(struct net_device *ndev, u64 *hopinfo, u32 mss)
+{
+ int mss_index;
+
+ mss_index = apm_enet_get_mss_index(ndev, mss);
+ if (mss_index < 0)
+ return mss_index;
+
+ *hopinfo |= SET_VAL(MSS, mss_index);
+
+ return 0;
+}
+
static u64 xgene_enet_work_msg(struct sk_buff *skb)
{
struct net_device *ndev = skb->dev;
@@ -227,6 +267,9 @@ static u64 xgene_enet_work_msg(struct sk_buff *skb)
if (!mss || ((skb->len - hdr_len) <= mss))
goto out;
+ if (xgene_enet_setup_mss(ndev, &hopinfo, mss))
+ return 0;
+
hopinfo |= SET_BIT(ET);
}
} else if (iph->protocol == IPPROTO_UDP) {
@@ -1625,7 +1668,7 @@ static int xgene_enet_probe(struct platform_device *pdev)
if (pdata->phy_mode == PHY_INTERFACE_MODE_XGMII) {
ndev->features |= NETIF_F_TSO;
- pdata->mss = XGENE_ENET_MSS;
+ apm_enet_init_mss_values(ndev);
}
ndev->hw_features = ndev->features;
@@ -46,7 +46,7 @@
#define NUM_PKT_BUF 64
#define NUM_BUFPOOL 32
#define MAX_EXP_BUFFS 256
-#define XGENE_ENET_MSS 1448
+#define NUM_MSS_REG 4
#define XGENE_MIN_ENET_FRAME_SIZE 60
#define XGENE_MAX_ENET_IRQ 16
@@ -141,7 +141,7 @@ struct xgene_mac_ops {
void (*tx_disable)(struct xgene_enet_pdata *pdata);
void (*rx_disable)(struct xgene_enet_pdata *pdata);
void (*set_mac_addr)(struct xgene_enet_pdata *pdata);
- void (*set_mss)(struct xgene_enet_pdata *pdata);
+ void (*set_mss)(struct xgene_enet_pdata *pdata, u16 mss, u8 index);
void (*link_state)(struct work_struct *work);
};
@@ -208,7 +208,7 @@ struct xgene_enet_pdata {
u8 eth_bufnum;
u8 bp_bufnum;
u16 ring_num;
- u32 mss;
+ u32 mss_sw[NUM_MSS_REG];
u8 tx_delay;
u8 rx_delay;
};
@@ -184,9 +184,24 @@ static void xgene_xgmac_set_mac_addr(struct xgene_enet_pdata *pdata)
xgene_enet_wr_mac(pdata, HSTMACADR_MSW_ADDR, addr1);
}
-static void xgene_xgmac_set_mss(struct xgene_enet_pdata *pdata)
+static void xgene_xgmac_set_mss(struct xgene_enet_pdata *pdata, u16 mss,
+ u8 index)
{
- xgene_enet_wr_csr(pdata, XG_TSIF_MSS_REG0_ADDR, pdata->mss);
+ bool reg_index;
+ u32 data;
+
+ xgene_enet_rd_csr(pdata, XG_TSIF_MSS_REG0_ADDR, &data);
+ reg_index = (index < 2) ? 0 : 1;
+
+ if (!(index & 0x1)) {
+ data &= 0xffff0000;
+ data |= mss;
+ } else {
+ data &= 0xffff;
+ data |= (mss << 16);
+ }
+
+ xgene_enet_wr_csr(pdata, XG_TSIF_MSS_REG0_ADDR + reg_index * 4, data);
}
static u32 xgene_enet_link_status(struct xgene_enet_pdata *pdata)
@@ -210,7 +225,6 @@ static void xgene_xgmac_init(struct xgene_enet_pdata *pdata)
xgene_enet_wr_mac(pdata, AXGMAC_CONFIG_1, data);
xgene_xgmac_set_mac_addr(pdata);
- xgene_xgmac_set_mss(pdata);
xgene_enet_rd_csr(pdata, XG_RSIF_CONFIG_REG_ADDR, &data);
data |= CFG_RSIF_FPBUFF_TIMEOUT_EN;