diff options
author | David S. Miller <davem@davemloft.net> | 2016-09-19 01:40:54 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-09-19 01:40:54 -0400 |
commit | 4646651e754f3593761142c7a9e11c5ee2a983a6 (patch) | |
tree | f26f092f7d32e5d5e681799b211a873ddcbbc53a | |
parent | 0fbc81b3ad513fecaaf62b48f42b89fcd57f7682 (diff) | |
parent | 004e6cc6c181aa109427594fca35eb55d89d780e (diff) |
Merge branch 'mediatek-hw-lro'
Nelson Chang says:
====================
net: ethernet: mediatek: add HW LRO functions
The series add the large receive offload (LRO) functions by hardware and
the ethtool functions to configure RX flows of HW LRO.
changes since v3:
- Respin the patch by the newer driver
- Move the dts description of hwlro to optional properties
changes since v2:
- Add ndo_fix_features to prevent NETIF_F_LRO off while RX flow is programmed
- Rephrase the dts property is a capability if the hardware supports LRO
changes since v1:
- Add HW LRO support
- Add ethtool hooks to set LRO RX flows
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | Documentation/devicetree/bindings/net/mediatek-net.txt | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/mediatek/mtk_eth_soc.c | 451 | ||||
-rw-r--r-- | drivers/net/ethernet/mediatek/mtk_eth_soc.h | 75 |
3 files changed, 503 insertions, 26 deletions
diff --git a/Documentation/devicetree/bindings/net/mediatek-net.txt b/Documentation/devicetree/bindings/net/mediatek-net.txt index 32eaaca04d9b..6103e5583070 100644 --- a/Documentation/devicetree/bindings/net/mediatek-net.txt +++ b/Documentation/devicetree/bindings/net/mediatek-net.txt | |||
@@ -24,7 +24,7 @@ Required properties: | |||
24 | Optional properties: | 24 | Optional properties: |
25 | - interrupt-parent: Should be the phandle for the interrupt controller | 25 | - interrupt-parent: Should be the phandle for the interrupt controller |
26 | that services interrupts for this device | 26 | that services interrupts for this device |
27 | 27 | - mediatek,hwlro: the capability if the hardware supports LRO functions | |
28 | 28 | ||
29 | * Ethernet MAC node | 29 | * Ethernet MAC node |
30 | 30 | ||
@@ -51,6 +51,7 @@ eth: ethernet@1b100000 { | |||
51 | reset-names = "eth"; | 51 | reset-names = "eth"; |
52 | mediatek,ethsys = <ðsys>; | 52 | mediatek,ethsys = <ðsys>; |
53 | mediatek,pctl = <&syscfg_pctl_a>; | 53 | mediatek,pctl = <&syscfg_pctl_a>; |
54 | mediatek,hwlro; | ||
54 | #address-cells = <1>; | 55 | #address-cells = <1>; |
55 | #size-cells = <0>; | 56 | #size-cells = <0>; |
56 | 57 | ||
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c index 522fe8dda6c3..481f3609a1ea 100644 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c | |||
@@ -820,11 +820,51 @@ drop: | |||
820 | return NETDEV_TX_OK; | 820 | return NETDEV_TX_OK; |
821 | } | 821 | } |
822 | 822 | ||
823 | static struct mtk_rx_ring *mtk_get_rx_ring(struct mtk_eth *eth) | ||
824 | { | ||
825 | int i; | ||
826 | struct mtk_rx_ring *ring; | ||
827 | int idx; | ||
828 | |||
829 | if (!eth->hwlro) | ||
830 | return ð->rx_ring[0]; | ||
831 | |||
832 | for (i = 0; i < MTK_MAX_RX_RING_NUM; i++) { | ||
833 | ring = ð->rx_ring[i]; | ||
834 | idx = NEXT_RX_DESP_IDX(ring->calc_idx, ring->dma_size); | ||
835 | if (ring->dma[idx].rxd2 & RX_DMA_DONE) { | ||
836 | ring->calc_idx_update = true; | ||
837 | return ring; | ||
838 | } | ||
839 | } | ||
840 | |||
841 | return NULL; | ||
842 | } | ||
843 | |||
844 | static void mtk_update_rx_cpu_idx(struct mtk_eth *eth) | ||
845 | { | ||
846 | struct mtk_rx_ring *ring; | ||
847 | int i; | ||
848 | |||
849 | if (!eth->hwlro) { | ||
850 | ring = ð->rx_ring[0]; | ||
851 | mtk_w32(eth, ring->calc_idx, ring->crx_idx_reg); | ||
852 | } else { | ||
853 | for (i = 0; i < MTK_MAX_RX_RING_NUM; i++) { | ||
854 | ring = ð->rx_ring[i]; | ||
855 | if (ring->calc_idx_update) { | ||
856 | ring->calc_idx_update = false; | ||
857 | mtk_w32(eth, ring->calc_idx, ring->crx_idx_reg); | ||
858 | } | ||
859 | } | ||
860 | } | ||
861 | } | ||
862 | |||
823 | static int mtk_poll_rx(struct napi_struct *napi, int budget, | 863 | static int mtk_poll_rx(struct napi_struct *napi, int budget, |
824 | struct mtk_eth *eth) | 864 | struct mtk_eth *eth) |
825 | { | 865 | { |
826 | struct mtk_rx_ring *ring = ð->rx_ring; | 866 | struct mtk_rx_ring *ring; |
827 | int idx = ring->calc_idx; | 867 | int idx; |
828 | struct sk_buff *skb; | 868 | struct sk_buff *skb; |
829 | u8 *data, *new_data; | 869 | u8 *data, *new_data; |
830 | struct mtk_rx_dma *rxd, trxd; | 870 | struct mtk_rx_dma *rxd, trxd; |
@@ -836,7 +876,11 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget, | |||
836 | dma_addr_t dma_addr; | 876 | dma_addr_t dma_addr; |
837 | int mac = 0; | 877 | int mac = 0; |
838 | 878 | ||
839 | idx = NEXT_RX_DESP_IDX(idx); | 879 | ring = mtk_get_rx_ring(eth); |
880 | if (unlikely(!ring)) | ||
881 | goto rx_done; | ||
882 | |||
883 | idx = NEXT_RX_DESP_IDX(ring->calc_idx, ring->dma_size); | ||
840 | rxd = &ring->dma[idx]; | 884 | rxd = &ring->dma[idx]; |
841 | data = ring->data[idx]; | 885 | data = ring->data[idx]; |
842 | 886 | ||
@@ -907,12 +951,13 @@ release_desc: | |||
907 | done++; | 951 | done++; |
908 | } | 952 | } |
909 | 953 | ||
954 | rx_done: | ||
910 | if (done) { | 955 | if (done) { |
911 | /* make sure that all changes to the dma ring are flushed before | 956 | /* make sure that all changes to the dma ring are flushed before |
912 | * we continue | 957 | * we continue |
913 | */ | 958 | */ |
914 | wmb(); | 959 | wmb(); |
915 | mtk_w32(eth, ring->calc_idx, MTK_PRX_CRX_IDX0); | 960 | mtk_update_rx_cpu_idx(eth); |
916 | } | 961 | } |
917 | 962 | ||
918 | return done; | 963 | return done; |
@@ -1135,32 +1180,41 @@ static void mtk_tx_clean(struct mtk_eth *eth) | |||
1135 | } | 1180 | } |
1136 | } | 1181 | } |
1137 | 1182 | ||
1138 | static int mtk_rx_alloc(struct mtk_eth *eth) | 1183 | static int mtk_rx_alloc(struct mtk_eth *eth, int ring_no, int rx_flag) |
1139 | { | 1184 | { |
1140 | struct mtk_rx_ring *ring = ð->rx_ring; | 1185 | struct mtk_rx_ring *ring = ð->rx_ring[ring_no]; |
1186 | int rx_data_len, rx_dma_size; | ||
1141 | int i; | 1187 | int i; |
1142 | 1188 | ||
1143 | ring->frag_size = mtk_max_frag_size(ETH_DATA_LEN); | 1189 | if (rx_flag == MTK_RX_FLAGS_HWLRO) { |
1190 | rx_data_len = MTK_MAX_LRO_RX_LENGTH; | ||
1191 | rx_dma_size = MTK_HW_LRO_DMA_SIZE; | ||
1192 | } else { | ||
1193 | rx_data_len = ETH_DATA_LEN; | ||
1194 | rx_dma_size = MTK_DMA_SIZE; | ||
1195 | } | ||
1196 | |||
1197 | ring->frag_size = mtk_max_frag_size(rx_data_len); | ||
1144 | ring->buf_size = mtk_max_buf_size(ring->frag_size); | 1198 | ring->buf_size = mtk_max_buf_size(ring->frag_size); |
1145 | ring->data = kcalloc(MTK_DMA_SIZE, sizeof(*ring->data), | 1199 | ring->data = kcalloc(rx_dma_size, sizeof(*ring->data), |
1146 | GFP_KERNEL); | 1200 | GFP_KERNEL); |
1147 | if (!ring->data) | 1201 | if (!ring->data) |
1148 | return -ENOMEM; | 1202 | return -ENOMEM; |
1149 | 1203 | ||
1150 | for (i = 0; i < MTK_DMA_SIZE; i++) { | 1204 | for (i = 0; i < rx_dma_size; i++) { |
1151 | ring->data[i] = netdev_alloc_frag(ring->frag_size); | 1205 | ring->data[i] = netdev_alloc_frag(ring->frag_size); |
1152 | if (!ring->data[i]) | 1206 | if (!ring->data[i]) |
1153 | return -ENOMEM; | 1207 | return -ENOMEM; |
1154 | } | 1208 | } |
1155 | 1209 | ||
1156 | ring->dma = dma_alloc_coherent(eth->dev, | 1210 | ring->dma = dma_alloc_coherent(eth->dev, |
1157 | MTK_DMA_SIZE * sizeof(*ring->dma), | 1211 | rx_dma_size * sizeof(*ring->dma), |
1158 | &ring->phys, | 1212 | &ring->phys, |
1159 | GFP_ATOMIC | __GFP_ZERO); | 1213 | GFP_ATOMIC | __GFP_ZERO); |
1160 | if (!ring->dma) | 1214 | if (!ring->dma) |
1161 | return -ENOMEM; | 1215 | return -ENOMEM; |
1162 | 1216 | ||
1163 | for (i = 0; i < MTK_DMA_SIZE; i++) { | 1217 | for (i = 0; i < rx_dma_size; i++) { |
1164 | dma_addr_t dma_addr = dma_map_single(eth->dev, | 1218 | dma_addr_t dma_addr = dma_map_single(eth->dev, |
1165 | ring->data[i] + NET_SKB_PAD, | 1219 | ring->data[i] + NET_SKB_PAD, |
1166 | ring->buf_size, | 1220 | ring->buf_size, |
@@ -1171,27 +1225,30 @@ static int mtk_rx_alloc(struct mtk_eth *eth) | |||
1171 | 1225 | ||
1172 | ring->dma[i].rxd2 = RX_DMA_PLEN0(ring->buf_size); | 1226 | ring->dma[i].rxd2 = RX_DMA_PLEN0(ring->buf_size); |
1173 | } | 1227 | } |
1174 | ring->calc_idx = MTK_DMA_SIZE - 1; | 1228 | ring->dma_size = rx_dma_size; |
1229 | ring->calc_idx_update = false; | ||
1230 | ring->calc_idx = rx_dma_size - 1; | ||
1231 | ring->crx_idx_reg = MTK_PRX_CRX_IDX_CFG(ring_no); | ||
1175 | /* make sure that all changes to the dma ring are flushed before we | 1232 | /* make sure that all changes to the dma ring are flushed before we |
1176 | * continue | 1233 | * continue |
1177 | */ | 1234 | */ |
1178 | wmb(); | 1235 | wmb(); |
1179 | 1236 | ||
1180 | mtk_w32(eth, eth->rx_ring.phys, MTK_PRX_BASE_PTR0); | 1237 | mtk_w32(eth, ring->phys, MTK_PRX_BASE_PTR_CFG(ring_no)); |
1181 | mtk_w32(eth, MTK_DMA_SIZE, MTK_PRX_MAX_CNT0); | 1238 | mtk_w32(eth, rx_dma_size, MTK_PRX_MAX_CNT_CFG(ring_no)); |
1182 | mtk_w32(eth, eth->rx_ring.calc_idx, MTK_PRX_CRX_IDX0); | 1239 | mtk_w32(eth, ring->calc_idx, ring->crx_idx_reg); |
1183 | mtk_w32(eth, MTK_PST_DRX_IDX0, MTK_PDMA_RST_IDX); | 1240 | mtk_w32(eth, MTK_PST_DRX_IDX_CFG(ring_no), MTK_PDMA_RST_IDX); |
1184 | 1241 | ||
1185 | return 0; | 1242 | return 0; |
1186 | } | 1243 | } |
1187 | 1244 | ||
1188 | static void mtk_rx_clean(struct mtk_eth *eth) | 1245 | static void mtk_rx_clean(struct mtk_eth *eth, int ring_no) |
1189 | { | 1246 | { |
1190 | struct mtk_rx_ring *ring = ð->rx_ring; | 1247 | struct mtk_rx_ring *ring = ð->rx_ring[ring_no]; |
1191 | int i; | 1248 | int i; |
1192 | 1249 | ||
1193 | if (ring->data && ring->dma) { | 1250 | if (ring->data && ring->dma) { |
1194 | for (i = 0; i < MTK_DMA_SIZE; i++) { | 1251 | for (i = 0; i < ring->dma_size; i++) { |
1195 | if (!ring->data[i]) | 1252 | if (!ring->data[i]) |
1196 | continue; | 1253 | continue; |
1197 | if (!ring->dma[i].rxd1) | 1254 | if (!ring->dma[i].rxd1) |
@@ -1208,13 +1265,274 @@ static void mtk_rx_clean(struct mtk_eth *eth) | |||
1208 | 1265 | ||
1209 | if (ring->dma) { | 1266 | if (ring->dma) { |
1210 | dma_free_coherent(eth->dev, | 1267 | dma_free_coherent(eth->dev, |
1211 | MTK_DMA_SIZE * sizeof(*ring->dma), | 1268 | ring->dma_size * sizeof(*ring->dma), |
1212 | ring->dma, | 1269 | ring->dma, |
1213 | ring->phys); | 1270 | ring->phys); |
1214 | ring->dma = NULL; | 1271 | ring->dma = NULL; |
1215 | } | 1272 | } |
1216 | } | 1273 | } |
1217 | 1274 | ||
1275 | static int mtk_hwlro_rx_init(struct mtk_eth *eth) | ||
1276 | { | ||
1277 | int i; | ||
1278 | u32 ring_ctrl_dw1 = 0, ring_ctrl_dw2 = 0, ring_ctrl_dw3 = 0; | ||
1279 | u32 lro_ctrl_dw0 = 0, lro_ctrl_dw3 = 0; | ||
1280 | |||
1281 | /* set LRO rings to auto-learn modes */ | ||
1282 | ring_ctrl_dw2 |= MTK_RING_AUTO_LERAN_MODE; | ||
1283 | |||
1284 | /* validate LRO ring */ | ||
1285 | ring_ctrl_dw2 |= MTK_RING_VLD; | ||
1286 | |||
1287 | /* set AGE timer (unit: 20us) */ | ||
1288 | ring_ctrl_dw2 |= MTK_RING_AGE_TIME_H; | ||
1289 | ring_ctrl_dw1 |= MTK_RING_AGE_TIME_L; | ||
1290 | |||
1291 | /* set max AGG timer (unit: 20us) */ | ||
1292 | ring_ctrl_dw2 |= MTK_RING_MAX_AGG_TIME; | ||
1293 | |||
1294 | /* set max LRO AGG count */ | ||
1295 | ring_ctrl_dw2 |= MTK_RING_MAX_AGG_CNT_L; | ||
1296 | ring_ctrl_dw3 |= MTK_RING_MAX_AGG_CNT_H; | ||
1297 | |||
1298 | for (i = 1; i < MTK_MAX_RX_RING_NUM; i++) { | ||
1299 | mtk_w32(eth, ring_ctrl_dw1, MTK_LRO_CTRL_DW1_CFG(i)); | ||
1300 | mtk_w32(eth, ring_ctrl_dw2, MTK_LRO_CTRL_DW2_CFG(i)); | ||
1301 | mtk_w32(eth, ring_ctrl_dw3, MTK_LRO_CTRL_DW3_CFG(i)); | ||
1302 | } | ||
1303 | |||
1304 | /* IPv4 checksum update enable */ | ||
1305 | lro_ctrl_dw0 |= MTK_L3_CKS_UPD_EN; | ||
1306 | |||
1307 | /* switch priority comparison to packet count mode */ | ||
1308 | lro_ctrl_dw0 |= MTK_LRO_ALT_PKT_CNT_MODE; | ||
1309 | |||
1310 | /* bandwidth threshold setting */ | ||
1311 | mtk_w32(eth, MTK_HW_LRO_BW_THRE, MTK_PDMA_LRO_CTRL_DW2); | ||
1312 | |||
1313 | /* auto-learn score delta setting */ | ||
1314 | mtk_w32(eth, MTK_HW_LRO_REPLACE_DELTA, MTK_PDMA_LRO_ALT_SCORE_DELTA); | ||
1315 | |||
1316 | /* set refresh timer for altering flows to 1 sec. (unit: 20us) */ | ||
1317 | mtk_w32(eth, (MTK_HW_LRO_TIMER_UNIT << 16) | MTK_HW_LRO_REFRESH_TIME, | ||
1318 | MTK_PDMA_LRO_ALT_REFRESH_TIMER); | ||
1319 | |||
1320 | /* set HW LRO mode & the max aggregation count for rx packets */ | ||
1321 | lro_ctrl_dw3 |= MTK_ADMA_MODE | (MTK_HW_LRO_MAX_AGG_CNT & 0xff); | ||
1322 | |||
1323 | /* the minimal remaining room of SDL0 in RXD for lro aggregation */ | ||
1324 | lro_ctrl_dw3 |= MTK_LRO_MIN_RXD_SDL; | ||
1325 | |||
1326 | /* enable HW LRO */ | ||
1327 | lro_ctrl_dw0 |= MTK_LRO_EN; | ||
1328 | |||
1329 | mtk_w32(eth, lro_ctrl_dw3, MTK_PDMA_LRO_CTRL_DW3); | ||
1330 | mtk_w32(eth, lro_ctrl_dw0, MTK_PDMA_LRO_CTRL_DW0); | ||
1331 | |||
1332 | return 0; | ||
1333 | } | ||
1334 | |||
1335 | static void mtk_hwlro_rx_uninit(struct mtk_eth *eth) | ||
1336 | { | ||
1337 | int i; | ||
1338 | u32 val; | ||
1339 | |||
1340 | /* relinquish lro rings, flush aggregated packets */ | ||
1341 | mtk_w32(eth, MTK_LRO_RING_RELINQUISH_REQ, MTK_PDMA_LRO_CTRL_DW0); | ||
1342 | |||
1343 | /* wait for relinquishments done */ | ||
1344 | for (i = 0; i < 10; i++) { | ||
1345 | val = mtk_r32(eth, MTK_PDMA_LRO_CTRL_DW0); | ||
1346 | if (val & MTK_LRO_RING_RELINQUISH_DONE) { | ||
1347 | msleep(20); | ||
1348 | continue; | ||
1349 | } | ||
1350 | } | ||
1351 | |||
1352 | /* invalidate lro rings */ | ||
1353 | for (i = 1; i < MTK_MAX_RX_RING_NUM; i++) | ||
1354 | mtk_w32(eth, 0, MTK_LRO_CTRL_DW2_CFG(i)); | ||
1355 | |||
1356 | /* disable HW LRO */ | ||
1357 | mtk_w32(eth, 0, MTK_PDMA_LRO_CTRL_DW0); | ||
1358 | } | ||
1359 | |||
1360 | static void mtk_hwlro_val_ipaddr(struct mtk_eth *eth, int idx, __be32 ip) | ||
1361 | { | ||
1362 | u32 reg_val; | ||
1363 | |||
1364 | reg_val = mtk_r32(eth, MTK_LRO_CTRL_DW2_CFG(idx)); | ||
1365 | |||
1366 | /* invalidate the IP setting */ | ||
1367 | mtk_w32(eth, (reg_val & ~MTK_RING_MYIP_VLD), MTK_LRO_CTRL_DW2_CFG(idx)); | ||
1368 | |||
1369 | mtk_w32(eth, ip, MTK_LRO_DIP_DW0_CFG(idx)); | ||
1370 | |||
1371 | /* validate the IP setting */ | ||
1372 | mtk_w32(eth, (reg_val | MTK_RING_MYIP_VLD), MTK_LRO_CTRL_DW2_CFG(idx)); | ||
1373 | } | ||
1374 | |||
1375 | static void mtk_hwlro_inval_ipaddr(struct mtk_eth *eth, int idx) | ||
1376 | { | ||
1377 | u32 reg_val; | ||
1378 | |||
1379 | reg_val = mtk_r32(eth, MTK_LRO_CTRL_DW2_CFG(idx)); | ||
1380 | |||
1381 | /* invalidate the IP setting */ | ||
1382 | mtk_w32(eth, (reg_val & ~MTK_RING_MYIP_VLD), MTK_LRO_CTRL_DW2_CFG(idx)); | ||
1383 | |||
1384 | mtk_w32(eth, 0, MTK_LRO_DIP_DW0_CFG(idx)); | ||
1385 | } | ||
1386 | |||
1387 | static int mtk_hwlro_get_ip_cnt(struct mtk_mac *mac) | ||
1388 | { | ||
1389 | int cnt = 0; | ||
1390 | int i; | ||
1391 | |||
1392 | for (i = 0; i < MTK_MAX_LRO_IP_CNT; i++) { | ||
1393 | if (mac->hwlro_ip[i]) | ||
1394 | cnt++; | ||
1395 | } | ||
1396 | |||
1397 | return cnt; | ||
1398 | } | ||
1399 | |||
1400 | static int mtk_hwlro_add_ipaddr(struct net_device *dev, | ||
1401 | struct ethtool_rxnfc *cmd) | ||
1402 | { | ||
1403 | struct ethtool_rx_flow_spec *fsp = | ||
1404 | (struct ethtool_rx_flow_spec *)&cmd->fs; | ||
1405 | struct mtk_mac *mac = netdev_priv(dev); | ||
1406 | struct mtk_eth *eth = mac->hw; | ||
1407 | int hwlro_idx; | ||
1408 | |||
1409 | if ((fsp->flow_type != TCP_V4_FLOW) || | ||
1410 | (!fsp->h_u.tcp_ip4_spec.ip4dst) || | ||
1411 | (fsp->location > 1)) | ||
1412 | return -EINVAL; | ||
1413 | |||
1414 | mac->hwlro_ip[fsp->location] = htonl(fsp->h_u.tcp_ip4_spec.ip4dst); | ||
1415 | hwlro_idx = (mac->id * MTK_MAX_LRO_IP_CNT) + fsp->location; | ||
1416 | |||
1417 | mac->hwlro_ip_cnt = mtk_hwlro_get_ip_cnt(mac); | ||
1418 | |||
1419 | mtk_hwlro_val_ipaddr(eth, hwlro_idx, mac->hwlro_ip[fsp->location]); | ||
1420 | |||
1421 | return 0; | ||
1422 | } | ||
1423 | |||
1424 | static int mtk_hwlro_del_ipaddr(struct net_device *dev, | ||
1425 | struct ethtool_rxnfc *cmd) | ||
1426 | { | ||
1427 | struct ethtool_rx_flow_spec *fsp = | ||
1428 | (struct ethtool_rx_flow_spec *)&cmd->fs; | ||
1429 | struct mtk_mac *mac = netdev_priv(dev); | ||
1430 | struct mtk_eth *eth = mac->hw; | ||
1431 | int hwlro_idx; | ||
1432 | |||
1433 | if (fsp->location > 1) | ||
1434 | return -EINVAL; | ||
1435 | |||
1436 | mac->hwlro_ip[fsp->location] = 0; | ||
1437 | hwlro_idx = (mac->id * MTK_MAX_LRO_IP_CNT) + fsp->location; | ||
1438 | |||
1439 | mac->hwlro_ip_cnt = mtk_hwlro_get_ip_cnt(mac); | ||
1440 | |||
1441 | mtk_hwlro_inval_ipaddr(eth, hwlro_idx); | ||
1442 | |||
1443 | return 0; | ||
1444 | } | ||
1445 | |||
1446 | static void mtk_hwlro_netdev_disable(struct net_device *dev) | ||
1447 | { | ||
1448 | struct mtk_mac *mac = netdev_priv(dev); | ||
1449 | struct mtk_eth *eth = mac->hw; | ||
1450 | int i, hwlro_idx; | ||
1451 | |||
1452 | for (i = 0; i < MTK_MAX_LRO_IP_CNT; i++) { | ||
1453 | mac->hwlro_ip[i] = 0; | ||
1454 | hwlro_idx = (mac->id * MTK_MAX_LRO_IP_CNT) + i; | ||
1455 | |||
1456 | mtk_hwlro_inval_ipaddr(eth, hwlro_idx); | ||
1457 | } | ||
1458 | |||
1459 | mac->hwlro_ip_cnt = 0; | ||
1460 | } | ||
1461 | |||
1462 | static int mtk_hwlro_get_fdir_entry(struct net_device *dev, | ||
1463 | struct ethtool_rxnfc *cmd) | ||
1464 | { | ||
1465 | struct mtk_mac *mac = netdev_priv(dev); | ||
1466 | struct ethtool_rx_flow_spec *fsp = | ||
1467 | (struct ethtool_rx_flow_spec *)&cmd->fs; | ||
1468 | |||
1469 | /* only tcp dst ipv4 is meaningful, others are meaningless */ | ||
1470 | fsp->flow_type = TCP_V4_FLOW; | ||
1471 | fsp->h_u.tcp_ip4_spec.ip4dst = ntohl(mac->hwlro_ip[fsp->location]); | ||
1472 | fsp->m_u.tcp_ip4_spec.ip4dst = 0; | ||
1473 | |||
1474 | fsp->h_u.tcp_ip4_spec.ip4src = 0; | ||
1475 | fsp->m_u.tcp_ip4_spec.ip4src = 0xffffffff; | ||
1476 | fsp->h_u.tcp_ip4_spec.psrc = 0; | ||
1477 | fsp->m_u.tcp_ip4_spec.psrc = 0xffff; | ||
1478 | fsp->h_u.tcp_ip4_spec.pdst = 0; | ||
1479 | fsp->m_u.tcp_ip4_spec.pdst = 0xffff; | ||
1480 | fsp->h_u.tcp_ip4_spec.tos = 0; | ||
1481 | fsp->m_u.tcp_ip4_spec.tos = 0xff; | ||
1482 | |||
1483 | return 0; | ||
1484 | } | ||
1485 | |||
1486 | static int mtk_hwlro_get_fdir_all(struct net_device *dev, | ||
1487 | struct ethtool_rxnfc *cmd, | ||
1488 | u32 *rule_locs) | ||
1489 | { | ||
1490 | struct mtk_mac *mac = netdev_priv(dev); | ||
1491 | int cnt = 0; | ||
1492 | int i; | ||
1493 | |||
1494 | for (i = 0; i < MTK_MAX_LRO_IP_CNT; i++) { | ||
1495 | if (mac->hwlro_ip[i]) { | ||
1496 | rule_locs[cnt] = i; | ||
1497 | cnt++; | ||
1498 | } | ||
1499 | } | ||
1500 | |||
1501 | cmd->rule_cnt = cnt; | ||
1502 | |||
1503 | return 0; | ||
1504 | } | ||
1505 | |||
1506 | static netdev_features_t mtk_fix_features(struct net_device *dev, | ||
1507 | netdev_features_t features) | ||
1508 | { | ||
1509 | if (!(features & NETIF_F_LRO)) { | ||
1510 | struct mtk_mac *mac = netdev_priv(dev); | ||
1511 | int ip_cnt = mtk_hwlro_get_ip_cnt(mac); | ||
1512 | |||
1513 | if (ip_cnt) { | ||
1514 | netdev_info(dev, "RX flow is programmed, LRO should keep on\n"); | ||
1515 | |||
1516 | features |= NETIF_F_LRO; | ||
1517 | } | ||
1518 | } | ||
1519 | |||
1520 | return features; | ||
1521 | } | ||
1522 | |||
1523 | static int mtk_set_features(struct net_device *dev, netdev_features_t features) | ||
1524 | { | ||
1525 | int err = 0; | ||
1526 | |||
1527 | if (!((dev->features ^ features) & NETIF_F_LRO)) | ||
1528 | return 0; | ||
1529 | |||
1530 | if (!(features & NETIF_F_LRO)) | ||
1531 | mtk_hwlro_netdev_disable(dev); | ||
1532 | |||
1533 | return err; | ||
1534 | } | ||
1535 | |||
1218 | /* wait for DMA to finish whatever it is doing before we start using it again */ | 1536 | /* wait for DMA to finish whatever it is doing before we start using it again */ |
1219 | static int mtk_dma_busy_wait(struct mtk_eth *eth) | 1537 | static int mtk_dma_busy_wait(struct mtk_eth *eth) |
1220 | { | 1538 | { |
@@ -1235,6 +1553,7 @@ static int mtk_dma_busy_wait(struct mtk_eth *eth) | |||
1235 | static int mtk_dma_init(struct mtk_eth *eth) | 1553 | static int mtk_dma_init(struct mtk_eth *eth) |
1236 | { | 1554 | { |
1237 | int err; | 1555 | int err; |
1556 | u32 i; | ||
1238 | 1557 | ||
1239 | if (mtk_dma_busy_wait(eth)) | 1558 | if (mtk_dma_busy_wait(eth)) |
1240 | return -EBUSY; | 1559 | return -EBUSY; |
@@ -1250,10 +1569,21 @@ static int mtk_dma_init(struct mtk_eth *eth) | |||
1250 | if (err) | 1569 | if (err) |
1251 | return err; | 1570 | return err; |
1252 | 1571 | ||
1253 | err = mtk_rx_alloc(eth); | 1572 | err = mtk_rx_alloc(eth, 0, MTK_RX_FLAGS_NORMAL); |
1254 | if (err) | 1573 | if (err) |
1255 | return err; | 1574 | return err; |
1256 | 1575 | ||
1576 | if (eth->hwlro) { | ||
1577 | for (i = 1; i < MTK_MAX_RX_RING_NUM; i++) { | ||
1578 | err = mtk_rx_alloc(eth, i, MTK_RX_FLAGS_HWLRO); | ||
1579 | if (err) | ||
1580 | return err; | ||
1581 | } | ||
1582 | err = mtk_hwlro_rx_init(eth); | ||
1583 | if (err) | ||
1584 | return err; | ||
1585 | } | ||
1586 | |||
1257 | /* Enable random early drop and set drop threshold automatically */ | 1587 | /* Enable random early drop and set drop threshold automatically */ |
1258 | mtk_w32(eth, FC_THRES_DROP_MODE | FC_THRES_DROP_EN | FC_THRES_MIN, | 1588 | mtk_w32(eth, FC_THRES_DROP_MODE | FC_THRES_DROP_EN | FC_THRES_MIN, |
1259 | MTK_QDMA_FC_THRES); | 1589 | MTK_QDMA_FC_THRES); |
@@ -1278,7 +1608,14 @@ static void mtk_dma_free(struct mtk_eth *eth) | |||
1278 | eth->phy_scratch_ring = 0; | 1608 | eth->phy_scratch_ring = 0; |
1279 | } | 1609 | } |
1280 | mtk_tx_clean(eth); | 1610 | mtk_tx_clean(eth); |
1281 | mtk_rx_clean(eth); | 1611 | mtk_rx_clean(eth, 0); |
1612 | |||
1613 | if (eth->hwlro) { | ||
1614 | mtk_hwlro_rx_uninit(eth); | ||
1615 | for (i = 1; i < MTK_MAX_RX_RING_NUM; i++) | ||
1616 | mtk_rx_clean(eth, i); | ||
1617 | } | ||
1618 | |||
1282 | kfree(eth->scratch_head); | 1619 | kfree(eth->scratch_head); |
1283 | } | 1620 | } |
1284 | 1621 | ||
@@ -1810,6 +2147,62 @@ static void mtk_get_ethtool_stats(struct net_device *dev, | |||
1810 | } while (u64_stats_fetch_retry_irq(&hwstats->syncp, start)); | 2147 | } while (u64_stats_fetch_retry_irq(&hwstats->syncp, start)); |
1811 | } | 2148 | } |
1812 | 2149 | ||
2150 | static int mtk_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd, | ||
2151 | u32 *rule_locs) | ||
2152 | { | ||
2153 | int ret = -EOPNOTSUPP; | ||
2154 | |||
2155 | switch (cmd->cmd) { | ||
2156 | case ETHTOOL_GRXRINGS: | ||
2157 | if (dev->features & NETIF_F_LRO) { | ||
2158 | cmd->data = MTK_MAX_RX_RING_NUM; | ||
2159 | ret = 0; | ||
2160 | } | ||
2161 | break; | ||
2162 | case ETHTOOL_GRXCLSRLCNT: | ||
2163 | if (dev->features & NETIF_F_LRO) { | ||
2164 | struct mtk_mac *mac = netdev_priv(dev); | ||
2165 | |||
2166 | cmd->rule_cnt = mac->hwlro_ip_cnt; | ||
2167 | ret = 0; | ||
2168 | } | ||
2169 | break; | ||
2170 | case ETHTOOL_GRXCLSRULE: | ||
2171 | if (dev->features & NETIF_F_LRO) | ||
2172 | ret = mtk_hwlro_get_fdir_entry(dev, cmd); | ||
2173 | break; | ||
2174 | case ETHTOOL_GRXCLSRLALL: | ||
2175 | if (dev->features & NETIF_F_LRO) | ||
2176 | ret = mtk_hwlro_get_fdir_all(dev, cmd, | ||
2177 | rule_locs); | ||
2178 | break; | ||
2179 | default: | ||
2180 | break; | ||
2181 | } | ||
2182 | |||
2183 | return ret; | ||
2184 | } | ||
2185 | |||
2186 | static int mtk_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd) | ||
2187 | { | ||
2188 | int ret = -EOPNOTSUPP; | ||
2189 | |||
2190 | switch (cmd->cmd) { | ||
2191 | case ETHTOOL_SRXCLSRLINS: | ||
2192 | if (dev->features & NETIF_F_LRO) | ||
2193 | ret = mtk_hwlro_add_ipaddr(dev, cmd); | ||
2194 | break; | ||
2195 | case ETHTOOL_SRXCLSRLDEL: | ||
2196 | if (dev->features & NETIF_F_LRO) | ||
2197 | ret = mtk_hwlro_del_ipaddr(dev, cmd); | ||
2198 | break; | ||
2199 | default: | ||
2200 | break; | ||
2201 | } | ||
2202 | |||
2203 | return ret; | ||
2204 | } | ||
2205 | |||
1813 | static const struct ethtool_ops mtk_ethtool_ops = { | 2206 | static const struct ethtool_ops mtk_ethtool_ops = { |
1814 | .get_settings = mtk_get_settings, | 2207 | .get_settings = mtk_get_settings, |
1815 | .set_settings = mtk_set_settings, | 2208 | .set_settings = mtk_set_settings, |
@@ -1821,6 +2214,8 @@ static const struct ethtool_ops mtk_ethtool_ops = { | |||
1821 | .get_strings = mtk_get_strings, | 2214 | .get_strings = mtk_get_strings, |
1822 | .get_sset_count = mtk_get_sset_count, | 2215 | .get_sset_count = mtk_get_sset_count, |
1823 | .get_ethtool_stats = mtk_get_ethtool_stats, | 2216 | .get_ethtool_stats = mtk_get_ethtool_stats, |
2217 | .get_rxnfc = mtk_get_rxnfc, | ||
2218 | .set_rxnfc = mtk_set_rxnfc, | ||
1824 | }; | 2219 | }; |
1825 | 2220 | ||
1826 | static const struct net_device_ops mtk_netdev_ops = { | 2221 | static const struct net_device_ops mtk_netdev_ops = { |
@@ -1835,6 +2230,8 @@ static const struct net_device_ops mtk_netdev_ops = { | |||
1835 | .ndo_change_mtu = eth_change_mtu, | 2230 | .ndo_change_mtu = eth_change_mtu, |
1836 | .ndo_tx_timeout = mtk_tx_timeout, | 2231 | .ndo_tx_timeout = mtk_tx_timeout, |
1837 | .ndo_get_stats64 = mtk_get_stats64, | 2232 | .ndo_get_stats64 = mtk_get_stats64, |
2233 | .ndo_fix_features = mtk_fix_features, | ||
2234 | .ndo_set_features = mtk_set_features, | ||
1838 | #ifdef CONFIG_NET_POLL_CONTROLLER | 2235 | #ifdef CONFIG_NET_POLL_CONTROLLER |
1839 | .ndo_poll_controller = mtk_poll_controller, | 2236 | .ndo_poll_controller = mtk_poll_controller, |
1840 | #endif | 2237 | #endif |
@@ -1873,6 +2270,9 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) | |||
1873 | mac->hw = eth; | 2270 | mac->hw = eth; |
1874 | mac->of_node = np; | 2271 | mac->of_node = np; |
1875 | 2272 | ||
2273 | memset(mac->hwlro_ip, 0, sizeof(mac->hwlro_ip)); | ||
2274 | mac->hwlro_ip_cnt = 0; | ||
2275 | |||
1876 | mac->hw_stats = devm_kzalloc(eth->dev, | 2276 | mac->hw_stats = devm_kzalloc(eth->dev, |
1877 | sizeof(*mac->hw_stats), | 2277 | sizeof(*mac->hw_stats), |
1878 | GFP_KERNEL); | 2278 | GFP_KERNEL); |
@@ -1889,6 +2289,11 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) | |||
1889 | eth->netdev[id]->watchdog_timeo = 5 * HZ; | 2289 | eth->netdev[id]->watchdog_timeo = 5 * HZ; |
1890 | eth->netdev[id]->netdev_ops = &mtk_netdev_ops; | 2290 | eth->netdev[id]->netdev_ops = &mtk_netdev_ops; |
1891 | eth->netdev[id]->base_addr = (unsigned long)eth->base; | 2291 | eth->netdev[id]->base_addr = (unsigned long)eth->base; |
2292 | |||
2293 | eth->netdev[id]->hw_features = MTK_HW_FEATURES; | ||
2294 | if (eth->hwlro) | ||
2295 | eth->netdev[id]->hw_features |= NETIF_F_LRO; | ||
2296 | |||
1892 | eth->netdev[id]->vlan_features = MTK_HW_FEATURES & | 2297 | eth->netdev[id]->vlan_features = MTK_HW_FEATURES & |
1893 | ~(NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX); | 2298 | ~(NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX); |
1894 | eth->netdev[id]->features |= MTK_HW_FEATURES; | 2299 | eth->netdev[id]->features |= MTK_HW_FEATURES; |
@@ -1941,6 +2346,8 @@ static int mtk_probe(struct platform_device *pdev) | |||
1941 | return PTR_ERR(eth->pctl); | 2346 | return PTR_ERR(eth->pctl); |
1942 | } | 2347 | } |
1943 | 2348 | ||
2349 | eth->hwlro = of_property_read_bool(pdev->dev.of_node, "mediatek,hwlro"); | ||
2350 | |||
1944 | for (i = 0; i < 3; i++) { | 2351 | for (i = 0; i < 3; i++) { |
1945 | eth->irq[i] = platform_get_irq(pdev, i); | 2352 | eth->irq[i] = platform_get_irq(pdev, i); |
1946 | if (eth->irq[i] < 0) { | 2353 | if (eth->irq[i] < 0) { |
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h index 79954b419b53..7c5e534d2120 100644 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h | |||
@@ -39,7 +39,21 @@ | |||
39 | NETIF_F_SG | NETIF_F_TSO | \ | 39 | NETIF_F_SG | NETIF_F_TSO | \ |
40 | NETIF_F_TSO6 | \ | 40 | NETIF_F_TSO6 | \ |
41 | NETIF_F_IPV6_CSUM) | 41 | NETIF_F_IPV6_CSUM) |
42 | #define NEXT_RX_DESP_IDX(X) (((X) + 1) & (MTK_DMA_SIZE - 1)) | 42 | #define NEXT_RX_DESP_IDX(X, Y) (((X) + 1) & ((Y) - 1)) |
43 | |||
44 | #define MTK_MAX_RX_RING_NUM 4 | ||
45 | #define MTK_HW_LRO_DMA_SIZE 8 | ||
46 | |||
47 | #define MTK_MAX_LRO_RX_LENGTH (4096 * 3) | ||
48 | #define MTK_MAX_LRO_IP_CNT 2 | ||
49 | #define MTK_HW_LRO_TIMER_UNIT 1 /* 20 us */ | ||
50 | #define MTK_HW_LRO_REFRESH_TIME 50000 /* 1 sec. */ | ||
51 | #define MTK_HW_LRO_AGG_TIME 10 /* 200us */ | ||
52 | #define MTK_HW_LRO_AGE_TIME 50 /* 1ms */ | ||
53 | #define MTK_HW_LRO_MAX_AGG_CNT 64 | ||
54 | #define MTK_HW_LRO_BW_THRE 3000 | ||
55 | #define MTK_HW_LRO_REPLACE_DELTA 1000 | ||
56 | #define MTK_HW_LRO_SDL_REMAIN_ROOM 1522 | ||
43 | 57 | ||
44 | /* Frame Engine Global Reset Register */ | 58 | /* Frame Engine Global Reset Register */ |
45 | #define MTK_RST_GL 0x04 | 59 | #define MTK_RST_GL 0x04 |
@@ -50,6 +64,9 @@ | |||
50 | #define MTK_GDM1_AF BIT(28) | 64 | #define MTK_GDM1_AF BIT(28) |
51 | #define MTK_GDM2_AF BIT(29) | 65 | #define MTK_GDM2_AF BIT(29) |
52 | 66 | ||
67 | /* PDMA HW LRO Alter Flow Timer Register */ | ||
68 | #define MTK_PDMA_LRO_ALT_REFRESH_TIMER 0x1c | ||
69 | |||
53 | /* Frame Engine Interrupt Grouping Register */ | 70 | /* Frame Engine Interrupt Grouping Register */ |
54 | #define MTK_FE_INT_GRP 0x20 | 71 | #define MTK_FE_INT_GRP 0x20 |
55 | 72 | ||
@@ -70,12 +87,29 @@ | |||
70 | 87 | ||
71 | /* PDMA RX Base Pointer Register */ | 88 | /* PDMA RX Base Pointer Register */ |
72 | #define MTK_PRX_BASE_PTR0 0x900 | 89 | #define MTK_PRX_BASE_PTR0 0x900 |
90 | #define MTK_PRX_BASE_PTR_CFG(x) (MTK_PRX_BASE_PTR0 + (x * 0x10)) | ||
73 | 91 | ||
74 | /* PDMA RX Maximum Count Register */ | 92 | /* PDMA RX Maximum Count Register */ |
75 | #define MTK_PRX_MAX_CNT0 0x904 | 93 | #define MTK_PRX_MAX_CNT0 0x904 |
94 | #define MTK_PRX_MAX_CNT_CFG(x) (MTK_PRX_MAX_CNT0 + (x * 0x10)) | ||
76 | 95 | ||
77 | /* PDMA RX CPU Pointer Register */ | 96 | /* PDMA RX CPU Pointer Register */ |
78 | #define MTK_PRX_CRX_IDX0 0x908 | 97 | #define MTK_PRX_CRX_IDX0 0x908 |
98 | #define MTK_PRX_CRX_IDX_CFG(x) (MTK_PRX_CRX_IDX0 + (x * 0x10)) | ||
99 | |||
100 | /* PDMA HW LRO Control Registers */ | ||
101 | #define MTK_PDMA_LRO_CTRL_DW0 0x980 | ||
102 | #define MTK_LRO_EN BIT(0) | ||
103 | #define MTK_L3_CKS_UPD_EN BIT(7) | ||
104 | #define MTK_LRO_ALT_PKT_CNT_MODE BIT(21) | ||
105 | #define MTK_LRO_RING_RELINQUISH_REQ (0x3 << 26) | ||
106 | #define MTK_LRO_RING_RELINQUISH_DONE (0x3 << 29) | ||
107 | |||
108 | #define MTK_PDMA_LRO_CTRL_DW1 0x984 | ||
109 | #define MTK_PDMA_LRO_CTRL_DW2 0x988 | ||
110 | #define MTK_PDMA_LRO_CTRL_DW3 0x98c | ||
111 | #define MTK_ADMA_MODE BIT(15) | ||
112 | #define MTK_LRO_MIN_RXD_SDL (MTK_HW_LRO_SDL_REMAIN_ROOM << 16) | ||
79 | 113 | ||
80 | /* PDMA Global Configuration Register */ | 114 | /* PDMA Global Configuration Register */ |
81 | #define MTK_PDMA_GLO_CFG 0xa04 | 115 | #define MTK_PDMA_GLO_CFG 0xa04 |
@@ -84,6 +118,7 @@ | |||
84 | /* PDMA Reset Index Register */ | 118 | /* PDMA Reset Index Register */ |
85 | #define MTK_PDMA_RST_IDX 0xa08 | 119 | #define MTK_PDMA_RST_IDX 0xa08 |
86 | #define MTK_PST_DRX_IDX0 BIT(16) | 120 | #define MTK_PST_DRX_IDX0 BIT(16) |
121 | #define MTK_PST_DRX_IDX_CFG(x) (MTK_PST_DRX_IDX0 << (x)) | ||
87 | 122 | ||
88 | /* PDMA Delay Interrupt Register */ | 123 | /* PDMA Delay Interrupt Register */ |
89 | #define MTK_PDMA_DELAY_INT 0xa0c | 124 | #define MTK_PDMA_DELAY_INT 0xa0c |
@@ -94,10 +129,33 @@ | |||
94 | /* PDMA Interrupt Mask Register */ | 129 | /* PDMA Interrupt Mask Register */ |
95 | #define MTK_PDMA_INT_MASK 0xa28 | 130 | #define MTK_PDMA_INT_MASK 0xa28 |
96 | 131 | ||
132 | /* PDMA HW LRO Alter Flow Delta Register */ | ||
133 | #define MTK_PDMA_LRO_ALT_SCORE_DELTA 0xa4c | ||
134 | |||
97 | /* PDMA Interrupt grouping registers */ | 135 | /* PDMA Interrupt grouping registers */ |
98 | #define MTK_PDMA_INT_GRP1 0xa50 | 136 | #define MTK_PDMA_INT_GRP1 0xa50 |
99 | #define MTK_PDMA_INT_GRP2 0xa54 | 137 | #define MTK_PDMA_INT_GRP2 0xa54 |
100 | 138 | ||
139 | /* PDMA HW LRO IP Setting Registers */ | ||
140 | #define MTK_LRO_RX_RING0_DIP_DW0 0xb04 | ||
141 | #define MTK_LRO_DIP_DW0_CFG(x) (MTK_LRO_RX_RING0_DIP_DW0 + (x * 0x40)) | ||
142 | #define MTK_RING_MYIP_VLD BIT(9) | ||
143 | |||
144 | /* PDMA HW LRO Ring Control Registers */ | ||
145 | #define MTK_LRO_RX_RING0_CTRL_DW1 0xb28 | ||
146 | #define MTK_LRO_RX_RING0_CTRL_DW2 0xb2c | ||
147 | #define MTK_LRO_RX_RING0_CTRL_DW3 0xb30 | ||
148 | #define MTK_LRO_CTRL_DW1_CFG(x) (MTK_LRO_RX_RING0_CTRL_DW1 + (x * 0x40)) | ||
149 | #define MTK_LRO_CTRL_DW2_CFG(x) (MTK_LRO_RX_RING0_CTRL_DW2 + (x * 0x40)) | ||
150 | #define MTK_LRO_CTRL_DW3_CFG(x) (MTK_LRO_RX_RING0_CTRL_DW3 + (x * 0x40)) | ||
151 | #define MTK_RING_AGE_TIME_L ((MTK_HW_LRO_AGE_TIME & 0x3ff) << 22) | ||
152 | #define MTK_RING_AGE_TIME_H ((MTK_HW_LRO_AGE_TIME >> 10) & 0x3f) | ||
153 | #define MTK_RING_AUTO_LERAN_MODE (3 << 6) | ||
154 | #define MTK_RING_VLD BIT(8) | ||
155 | #define MTK_RING_MAX_AGG_TIME ((MTK_HW_LRO_AGG_TIME & 0xffff) << 10) | ||
156 | #define MTK_RING_MAX_AGG_CNT_L ((MTK_HW_LRO_MAX_AGG_CNT & 0x3f) << 26) | ||
157 | #define MTK_RING_MAX_AGG_CNT_H ((MTK_HW_LRO_MAX_AGG_CNT >> 6) & 0x3) | ||
158 | |||
101 | /* QDMA TX Queue Configuration Registers */ | 159 | /* QDMA TX Queue Configuration Registers */ |
102 | #define MTK_QTX_CFG(x) (0x1800 + (x * 0x10)) | 160 | #define MTK_QTX_CFG(x) (0x1800 + (x * 0x10)) |
103 | #define QDMA_RES_THRES 4 | 161 | #define QDMA_RES_THRES 4 |
@@ -132,7 +190,6 @@ | |||
132 | 190 | ||
133 | /* QDMA Reset Index Register */ | 191 | /* QDMA Reset Index Register */ |
134 | #define MTK_QDMA_RST_IDX 0x1A08 | 192 | #define MTK_QDMA_RST_IDX 0x1A08 |
135 | #define MTK_PST_DRX_IDX0 BIT(16) | ||
136 | 193 | ||
137 | /* QDMA Delay Interrupt Register */ | 194 | /* QDMA Delay Interrupt Register */ |
138 | #define MTK_QDMA_DELAY_INT 0x1A0C | 195 | #define MTK_QDMA_DELAY_INT 0x1A0C |
@@ -377,6 +434,12 @@ struct mtk_tx_ring { | |||
377 | atomic_t free_count; | 434 | atomic_t free_count; |
378 | }; | 435 | }; |
379 | 436 | ||
437 | /* PDMA rx ring mode */ | ||
438 | enum mtk_rx_flags { | ||
439 | MTK_RX_FLAGS_NORMAL = 0, | ||
440 | MTK_RX_FLAGS_HWLRO, | ||
441 | }; | ||
442 | |||
380 | /* struct mtk_rx_ring - This struct holds info describing a RX ring | 443 | /* struct mtk_rx_ring - This struct holds info describing a RX ring |
381 | * @dma: The descriptor ring | 444 | * @dma: The descriptor ring |
382 | * @data: The memory pointed at by the ring | 445 | * @data: The memory pointed at by the ring |
@@ -391,7 +454,10 @@ struct mtk_rx_ring { | |||
391 | dma_addr_t phys; | 454 | dma_addr_t phys; |
392 | u16 frag_size; | 455 | u16 frag_size; |
393 | u16 buf_size; | 456 | u16 buf_size; |
457 | u16 dma_size; | ||
458 | bool calc_idx_update; | ||
394 | u16 calc_idx; | 459 | u16 calc_idx; |
460 | u32 crx_idx_reg; | ||
395 | }; | 461 | }; |
396 | 462 | ||
397 | /* currently no SoC has more than 2 macs */ | 463 | /* currently no SoC has more than 2 macs */ |
@@ -439,9 +505,10 @@ struct mtk_eth { | |||
439 | unsigned long sysclk; | 505 | unsigned long sysclk; |
440 | struct regmap *ethsys; | 506 | struct regmap *ethsys; |
441 | struct regmap *pctl; | 507 | struct regmap *pctl; |
508 | bool hwlro; | ||
442 | atomic_t dma_refcnt; | 509 | atomic_t dma_refcnt; |
443 | struct mtk_tx_ring tx_ring; | 510 | struct mtk_tx_ring tx_ring; |
444 | struct mtk_rx_ring rx_ring; | 511 | struct mtk_rx_ring rx_ring[MTK_MAX_RX_RING_NUM]; |
445 | struct napi_struct tx_napi; | 512 | struct napi_struct tx_napi; |
446 | struct napi_struct rx_napi; | 513 | struct napi_struct rx_napi; |
447 | struct mtk_tx_dma *scratch_ring; | 514 | struct mtk_tx_dma *scratch_ring; |
@@ -470,6 +537,8 @@ struct mtk_mac { | |||
470 | struct mtk_eth *hw; | 537 | struct mtk_eth *hw; |
471 | struct mtk_hw_stats *hw_stats; | 538 | struct mtk_hw_stats *hw_stats; |
472 | struct phy_device *phy_dev; | 539 | struct phy_device *phy_dev; |
540 | __be32 hwlro_ip[MTK_MAX_LRO_IP_CNT]; | ||
541 | int hwlro_ip_cnt; | ||
473 | }; | 542 | }; |
474 | 543 | ||
475 | /* the struct describing the SoC. these are declared in the soc_xyz.c files */ | 544 | /* the struct describing the SoC. these are declared in the soc_xyz.c files */ |