summaryrefslogtreecommitdiffstats
path: root/drivers/net/usb/r8152_shield.c
diff options
context:
space:
mode:
authorhayeswang <hayeswang@realtek.com>2014-03-06 22:04:39 -0500
committerVladislav Zhurba <vzhurba@nvidia.com>2018-02-01 16:58:00 -0500
commit871e3a05e91237501cfc91af7d24c17ab363c740 (patch)
tree81b2041a5d04c7c066bcb8e920064b81cbf9d81e /drivers/net/usb/r8152_shield.c
parent2fdab93e71896e888891e87efc2048c7adda74ec (diff)
r8152: support TSO
Support scatter gather and TSO. Adjust the tx checksum function and set the max gso size to fix the size of the tx aggregation buffer. Change-Id: Iff3dde25a2329fb47de6a5b6bfce92f260276992 Signed-off-by: Hayes Wang <hayeswang@realtek.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Aly Hirani <ahirani@nvidia.com> Reviewed-on: http://git-master/r/390297 (cherry picked from commit 5af199861e22e25c0454676b992298ddfe4d6111) Reviewed-on: http://git-master/r/396899 Reviewed-by: Preetham Chandru <pchandru@nvidia.com> Tested-by: Preetham Chandru <pchandru@nvidia.com> Reviewed-by: Bitan Biswas <bbiswas@nvidia.com>
Diffstat (limited to 'drivers/net/usb/r8152_shield.c')
-rw-r--r--drivers/net/usb/r8152_shield.c117
1 files changed, 87 insertions, 30 deletions
diff --git a/drivers/net/usb/r8152_shield.c b/drivers/net/usb/r8152_shield.c
index 571a2af3c..6d86f5943 100644
--- a/drivers/net/usb/r8152_shield.c
+++ b/drivers/net/usb/r8152_shield.c
@@ -24,7 +24,7 @@
24#include <linux/ipv6.h> 24#include <linux/ipv6.h>
25 25
26/* Version Information */ 26/* Version Information */
27#define DRIVER_VERSION "v1.05.0 (2014/02/18)" 27#define DRIVER_VERSION "v1.06.0 (2014/03/03)"
28#define DRIVER_AUTHOR "Realtek linux nic maintainers <nic_swsd@realtek.com>" 28#define DRIVER_AUTHOR "Realtek linux nic maintainers <nic_swsd@realtek.com>"
29#define DRIVER_DESC "Realtek RTL8152/RTL8153 Based USB Ethernet Adapters" 29#define DRIVER_DESC "Realtek RTL8152/RTL8153 Based USB Ethernet Adapters"
30#define MODULENAME "r8152" 30#define MODULENAME "r8152"
@@ -485,13 +485,18 @@ struct tx_desc {
485 __le32 opts1; 485 __le32 opts1;
486#define TX_FS (1 << 31) /* First segment of a packet */ 486#define TX_FS (1 << 31) /* First segment of a packet */
487#define TX_LS (1 << 30) /* Final segment of a packet */ 487#define TX_LS (1 << 30) /* Final segment of a packet */
488#define TX_LEN_MASK 0x3ffff 488#define GTSENDV4 (1 << 28)
489#define GTTCPHO_SHIFT 18
490#define TX_LEN_MAX 0x3ffffU
489 491
490 __le32 opts2; 492 __le32 opts2;
491#define UDP_CS (1 << 31) /* Calculate UDP/IP checksum */ 493#define UDP_CS (1 << 31) /* Calculate UDP/IP checksum */
492#define TCP_CS (1 << 30) /* Calculate TCP/IP checksum */ 494#define TCP_CS (1 << 30) /* Calculate TCP/IP checksum */
493#define IPV4_CS (1 << 29) /* Calculate IPv4 checksum */ 495#define IPV4_CS (1 << 29) /* Calculate IPv4 checksum */
494#define IPV6_CS (1 << 28) /* Calculate IPv6 checksum */ 496#define IPV6_CS (1 << 28) /* Calculate IPv6 checksum */
497#define MSS_SHIFT 17
498#define MSS_MAX 0x7ffU
499#define TCPHO_SHIFT 17
495}; 500};
496 501
497struct r8152; 502struct r8152;
@@ -558,12 +563,21 @@ enum rtl_version {
558 RTL_VER_MAX 563 RTL_VER_MAX
559}; 564};
560 565
566enum tx_csum_stat {
567 TX_CSUM_SUCCESS = 0,
568 TX_CSUM_TSO,
569 TX_CSUM_NONE
570};
571
561/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast). 572/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
562 * The RTL chips use a 64 element hash table based on the Ethernet CRC. 573 * The RTL chips use a 64 element hash table based on the Ethernet CRC.
563 */ 574 */
564static const int multicast_filter_limit = 32; 575static const int multicast_filter_limit = 32;
565static unsigned int rx_buf_sz = 16384; 576static unsigned int rx_buf_sz = 16384;
566 577
578#define RTL_LIMITED_TSO_SIZE (rx_buf_sz - sizeof(struct tx_desc) - \
579 VLAN_ETH_HLEN - VLAN_HLEN)
580
567static 581static
568int get_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) 582int get_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data)
569{ 583{
@@ -1290,24 +1304,46 @@ static struct tx_agg *r8152_get_tx_agg(struct r8152 *tp)
1290 return agg; 1304 return agg;
1291} 1305}
1292 1306
1293static void 1307static inline __be16 get_protocol(struct sk_buff *skb)
1294r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc, struct sk_buff *skb)
1295{ 1308{
1296 memset(desc, 0, sizeof(*desc)); 1309 __be16 protocol;
1297 1310
1298 desc->opts1 = cpu_to_le32((skb->len & TX_LEN_MASK) | TX_FS | TX_LS); 1311 if (skb->protocol == htons(ETH_P_8021Q))
1312 protocol = vlan_eth_hdr(skb)->h_vlan_encapsulated_proto;
1313 else
1314 protocol = skb->protocol;
1299 1315
1300 if (skb->ip_summed == CHECKSUM_PARTIAL) { 1316 return protocol;
1301 __be16 protocol; 1317}
1302 u8 ip_protocol;
1303 u32 opts2 = 0;
1304 1318
1305 if (skb->protocol == htons(ETH_P_8021Q)) 1319static int r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc,
1306 protocol = vlan_eth_hdr(skb)->h_vlan_encapsulated_proto; 1320 struct sk_buff *skb, u32 len, u32 transport_offset)
1307 else 1321{
1308 protocol = skb->protocol; 1322 u32 mss = skb_shinfo(skb)->gso_size;
1323 u32 opts1, opts2 = 0;
1324 int ret = TX_CSUM_SUCCESS;
1325
1326 WARN_ON_ONCE(len > TX_LEN_MAX);
1327
1328 opts1 = len | TX_FS | TX_LS;
1329
1330 if (mss) {
1331 switch (get_protocol(skb)) {
1332 case htons(ETH_P_IP):
1333 opts1 |= GTSENDV4;
1334 break;
1335
1336 default:
1337 WARN_ON_ONCE(1);
1338 break;
1339 }
1340
1341 opts1 |= transport_offset << GTTCPHO_SHIFT;
1342 opts2 |= min(mss, MSS_MAX) << MSS_SHIFT;
1343 } else if (skb->ip_summed == CHECKSUM_PARTIAL) {
1344 u8 ip_protocol;
1309 1345
1310 switch (protocol) { 1346 switch (get_protocol(skb)) {
1311 case htons(ETH_P_IP): 1347 case htons(ETH_P_IP):
1312 opts2 |= IPV4_CS; 1348 opts2 |= IPV4_CS;
1313 ip_protocol = ip_hdr(skb)->protocol; 1349 ip_protocol = ip_hdr(skb)->protocol;
@@ -1323,17 +1359,20 @@ r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc, struct sk_buff *skb)
1323 break; 1359 break;
1324 } 1360 }
1325 1361
1326 if (ip_protocol == IPPROTO_TCP) { 1362 if (ip_protocol == IPPROTO_TCP)
1327 opts2 |= TCP_CS; 1363 opts2 |= TCP_CS;
1328 opts2 |= (skb_transport_offset(skb) & 0x7fff) << 17; 1364 else if (ip_protocol == IPPROTO_UDP)
1329 } else if (ip_protocol == IPPROTO_UDP) {
1330 opts2 |= UDP_CS; 1365 opts2 |= UDP_CS;
1331 } else { 1366 else
1332 WARN_ON_ONCE(1); 1367 WARN_ON_ONCE(1);
1333 }
1334 1368
1335 desc->opts2 = cpu_to_le32(opts2); 1369 opts2 |= transport_offset << TCPHO_SHIFT;
1336 } 1370 }
1371
1372 desc->opts2 = cpu_to_le32(opts2);
1373 desc->opts1 = cpu_to_le32(opts1);
1374
1375 return ret;
1337} 1376}
1338 1377
1339static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg) 1378static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
@@ -1355,29 +1394,44 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
1355 struct tx_desc *tx_desc; 1394 struct tx_desc *tx_desc;
1356 struct sk_buff *skb; 1395 struct sk_buff *skb;
1357 unsigned int len; 1396 unsigned int len;
1397 u32 offset;
1358 1398
1359 skb = __skb_dequeue(&skb_head); 1399 skb = __skb_dequeue(&skb_head);
1360 if (!skb) 1400 if (!skb)
1361 break; 1401 break;
1362 1402
1363 remain -= sizeof(*tx_desc); 1403 len = skb->len + sizeof(*tx_desc);
1364 len = skb->len; 1404
1365 if (remain < len) { 1405 if (len > remain) {
1366 __skb_queue_head(&skb_head, skb); 1406 __skb_queue_head(&skb_head, skb);
1367 break; 1407 break;
1368 } 1408 }
1369 1409
1370 tx_data = tx_agg_align(tx_data); 1410 tx_data = tx_agg_align(tx_data);
1371 tx_desc = (struct tx_desc *)tx_data; 1411 tx_desc = (struct tx_desc *)tx_data;
1412
1413 offset = (u32)skb_transport_offset(skb);
1414
1415 r8152_tx_csum(tp, tx_desc, skb, skb->len, offset);
1416
1372 tx_data += sizeof(*tx_desc); 1417 tx_data += sizeof(*tx_desc);
1373 1418
1374 r8152_tx_csum(tp, tx_desc, skb); 1419 len = skb->len;
1375 memcpy(tx_data, skb->data, len); 1420 if (skb_copy_bits(skb, 0, tx_data, len) < 0) {
1376 agg->skb_num++; 1421 struct net_device_stats *stats = &tp->netdev->stats;
1422
1423 stats->tx_dropped++;
1424 dev_kfree_skb_any(skb);
1425 tx_data -= sizeof(*tx_desc);
1426 continue;
1427 }
1428
1429 tx_data += len;
1377 agg->skb_len += len; 1430 agg->skb_len += len;
1431 agg->skb_num++;
1432
1378 dev_kfree_skb_any(skb); 1433 dev_kfree_skb_any(skb);
1379 1434
1380 tx_data += len;
1381 remain = rx_buf_sz - (int)(tx_agg_align(tx_data) - agg->head); 1435 remain = rx_buf_sz - (int)(tx_agg_align(tx_data) - agg->head);
1382 } 1436 }
1383 1437
@@ -3143,10 +3197,13 @@ static int rtl8152_probe(struct usb_interface *intf,
3143 netdev->netdev_ops = &rtl8152_netdev_ops; 3197 netdev->netdev_ops = &rtl8152_netdev_ops;
3144 netdev->watchdog_timeo = RTL8152_TX_TIMEOUT; 3198 netdev->watchdog_timeo = RTL8152_TX_TIMEOUT;
3145 3199
3146 netdev->features |= NETIF_F_RXCSUM | NETIF_F_IP_CSUM; 3200 netdev->features |= NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_SG |
3147 netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM; 3201 NETIF_F_TSO | NETIF_F_FRAGLIST;
3202 netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_SG |
3203 NETIF_F_TSO | NETIF_F_FRAGLIST;
3148 3204
3149 SET_ETHTOOL_OPS(netdev, &ops); 3205 SET_ETHTOOL_OPS(netdev, &ops);
3206 netif_set_gso_max_size(netdev, RTL_LIMITED_TSO_SIZE);
3150 3207
3151 tp->mii.dev = netdev; 3208 tp->mii.dev = netdev;
3152 tp->mii.mdio_read = read_mii_word; 3209 tp->mii.mdio_read = read_mii_word;