@@ -206,6 +206,9 @@ enum ravb_reg {
CXR55 = 0x0768, /* RZ/G2L only */
CXR56 = 0x0770, /* RZ/G2L only */
MAFCR = 0x0778,
+ CSR0 = 0x0800, /* RZ/G2L only */
+ CSR1 = 0x0804, /* RZ/G2L only */
+ CSR2 = 0x0808, /* RZ/G2L only */
};
@@ -966,6 +969,41 @@ enum CXR31_BIT {
CXR31_SEL_LINK1 = 0x00000008,
};
+enum CSR0_BIT {
+ CSR0_TPE = 0x00000010,
+ CSR0_RPE = 0x00000020,
+};
+
+enum CSR1_BIT {
+ CSR1_TIP4 = 0x00000001,
+ CSR1_TTCP4 = 0x00000010,
+ CSR1_TUDP4 = 0x00000020,
+ CSR1_TICMP4 = 0x00000040,
+ CSR1_TTCP6 = 0x00100000,
+ CSR1_TUDP6 = 0x00200000,
+ CSR1_TICMP6 = 0x00400000,
+ CSR1_THOP = 0x01000000,
+ CSR1_TROUT = 0x02000000,
+ CSR1_TAHD = 0x04000000,
+ CSR1_TDHD = 0x08000000,
+ CSR1_ALL = 0x0F700071,
+};
+
+enum CSR2_BIT {
+ CSR2_RIP4 = 0x00000001,
+ CSR2_RTCP4 = 0x00000010,
+ CSR2_RUDP4 = 0x00000020,
+ CSR2_RICMP4 = 0x00000040,
+ CSR2_RTCP6 = 0x00100000,
+ CSR2_RUDP6 = 0x00200000,
+ CSR2_RICMP6 = 0x00400000,
+ CSR2_RHOP = 0x01000000,
+ CSR2_RROUT = 0x02000000,
+ CSR2_RAHD = 0x04000000,
+ CSR2_RDHD = 0x08000000,
+ CSR2_ALL = 0x0F700071,
+};
+
#define DBAT_ENTRY_NUM 22
#define RX_QUEUE_OFFSET 4
#define NUM_RX_QUEUE 2
@@ -533,6 +533,7 @@ static void ravb_emac_init_gbeth(struct net_device *ndev)
/* E-MAC status register clear */
ravb_write(ndev, ECSR_ICD | ECSR_LCHNG | ECSR_PFRI, ECSR);
+ ravb_write(ndev, CSR0_TPE | CSR0_RPE, CSR0);
/* E-MAC interrupt enable register */
ravb_write(ndev, ECSIPR_ICDIP, ECSIPR);
@@ -2330,7 +2331,37 @@ static void ravb_set_rx_csum(struct net_device *ndev, bool enable)
static int ravb_set_features_gbeth(struct net_device *ndev,
netdev_features_t features)
{
- /* Place holder */
+ netdev_features_t changed = features ^ ndev->features;
+ int error;
+ u32 csr0;
+
+ csr0 = ravb_read(ndev, CSR0);
+ ravb_write(ndev, csr0 & ~(CSR0_RPE | CSR0_TPE), CSR0);
+ error = ravb_wait(ndev, CSR0, CSR0_RPE | CSR0_TPE, 0);
+ if (error) {
+ ravb_write(ndev, csr0, CSR0);
+ return error;
+ }
+
+ if (changed & NETIF_F_RXCSUM) {
+ if (features & NETIF_F_RXCSUM)
+ ravb_write(ndev, CSR2_ALL, CSR2);
+ else
+ ravb_write(ndev, 0, CSR2);
+ }
+
+ if (changed & NETIF_F_HW_CSUM) {
+ if (features & NETIF_F_HW_CSUM) {
+ ravb_write(ndev, CSR1_ALL, CSR1);
+ ndev->features |= NETIF_F_CSUM_MASK;
+ } else {
+ ravb_write(ndev, 0, CSR1);
+ }
+ }
+ ravb_write(ndev, csr0, CSR0);
+
+ ndev->features = features;
+
return 0;
}
@@ -2473,6 +2504,7 @@ static const struct ravb_hw_info gbeth_hw_info = {
.set_feature = ravb_set_features_gbeth,
.dmac_init = ravb_dmac_init_gbeth,
.emac_init = ravb_emac_init_gbeth,
+ .net_hw_features = (NETIF_F_HW_CSUM | NETIF_F_RXCSUM),
.gstrings_stats = ravb_gstrings_stats_gbeth,
.gstrings_size = sizeof(ravb_gstrings_stats_gbeth),
.stats_len = ARRAY_SIZE(ravb_gstrings_stats_gbeth),