diff options
Diffstat (limited to 'drivers/net/ethernet/amd')
| -rw-r--r-- | drivers/net/ethernet/amd/xgbe/xgbe-common.h | 34 | ||||
| -rw-r--r-- | drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 148 | ||||
| -rw-r--r-- | drivers/net/ethernet/amd/xgbe/xgbe-drv.c | 16 | ||||
| -rw-r--r-- | drivers/net/ethernet/amd/xgbe/xgbe-main.c | 16 | ||||
| -rw-r--r-- | drivers/net/ethernet/amd/xgbe/xgbe.h | 21 |
5 files changed, 233 insertions, 2 deletions
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-common.h b/drivers/net/ethernet/amd/xgbe/xgbe-common.h index 39bcb1140198..2fe8fc71fe01 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-common.h +++ b/drivers/net/ethernet/amd/xgbe/xgbe-common.h | |||
| @@ -308,6 +308,9 @@ | |||
| 308 | #define MAC_MACA0LR 0x0304 | 308 | #define MAC_MACA0LR 0x0304 |
| 309 | #define MAC_MACA1HR 0x0308 | 309 | #define MAC_MACA1HR 0x0308 |
| 310 | #define MAC_MACA1LR 0x030c | 310 | #define MAC_MACA1LR 0x030c |
| 311 | #define MAC_RSSCR 0x0c80 | ||
| 312 | #define MAC_RSSAR 0x0c88 | ||
| 313 | #define MAC_RSSDR 0x0c8c | ||
| 311 | #define MAC_TSCR 0x0d00 | 314 | #define MAC_TSCR 0x0d00 |
| 312 | #define MAC_SSIR 0x0d04 | 315 | #define MAC_SSIR 0x0d04 |
| 313 | #define MAC_STSR 0x0d08 | 316 | #define MAC_STSR 0x0d08 |
| @@ -449,6 +452,24 @@ | |||
| 449 | #define MAC_RFCR_UP_WIDTH 1 | 452 | #define MAC_RFCR_UP_WIDTH 1 |
| 450 | #define MAC_RQC0R_RXQ0EN_INDEX 0 | 453 | #define MAC_RQC0R_RXQ0EN_INDEX 0 |
| 451 | #define MAC_RQC0R_RXQ0EN_WIDTH 2 | 454 | #define MAC_RQC0R_RXQ0EN_WIDTH 2 |
| 455 | #define MAC_RSSAR_ADDRT_INDEX 2 | ||
| 456 | #define MAC_RSSAR_ADDRT_WIDTH 1 | ||
| 457 | #define MAC_RSSAR_CT_INDEX 1 | ||
| 458 | #define MAC_RSSAR_CT_WIDTH 1 | ||
| 459 | #define MAC_RSSAR_OB_INDEX 0 | ||
| 460 | #define MAC_RSSAR_OB_WIDTH 1 | ||
| 461 | #define MAC_RSSAR_RSSIA_INDEX 8 | ||
| 462 | #define MAC_RSSAR_RSSIA_WIDTH 8 | ||
| 463 | #define MAC_RSSCR_IP2TE_INDEX 1 | ||
| 464 | #define MAC_RSSCR_IP2TE_WIDTH 1 | ||
| 465 | #define MAC_RSSCR_RSSE_INDEX 0 | ||
| 466 | #define MAC_RSSCR_RSSE_WIDTH 1 | ||
| 467 | #define MAC_RSSCR_TCP4TE_INDEX 2 | ||
| 468 | #define MAC_RSSCR_TCP4TE_WIDTH 1 | ||
| 469 | #define MAC_RSSCR_UDP4TE_INDEX 3 | ||
| 470 | #define MAC_RSSCR_UDP4TE_WIDTH 1 | ||
| 471 | #define MAC_RSSDR_DMCH_INDEX 0 | ||
| 472 | #define MAC_RSSDR_DMCH_WIDTH 4 | ||
| 452 | #define MAC_SSIR_SNSINC_INDEX 8 | 473 | #define MAC_SSIR_SNSINC_INDEX 8 |
| 453 | #define MAC_SSIR_SNSINC_WIDTH 8 | 474 | #define MAC_SSIR_SNSINC_WIDTH 8 |
| 454 | #define MAC_SSIR_SSINC_INDEX 16 | 475 | #define MAC_SSIR_SSINC_INDEX 16 |
| @@ -848,6 +869,8 @@ | |||
| 848 | #define RX_PACKET_ATTRIBUTES_CONTEXT_WIDTH 1 | 869 | #define RX_PACKET_ATTRIBUTES_CONTEXT_WIDTH 1 |
| 849 | #define RX_PACKET_ATTRIBUTES_RX_TSTAMP_INDEX 5 | 870 | #define RX_PACKET_ATTRIBUTES_RX_TSTAMP_INDEX 5 |
| 850 | #define RX_PACKET_ATTRIBUTES_RX_TSTAMP_WIDTH 1 | 871 | #define RX_PACKET_ATTRIBUTES_RX_TSTAMP_WIDTH 1 |
| 872 | #define RX_PACKET_ATTRIBUTES_RSS_HASH_INDEX 6 | ||
| 873 | #define RX_PACKET_ATTRIBUTES_RSS_HASH_WIDTH 1 | ||
| 851 | 874 | ||
| 852 | #define RX_NORMAL_DESC0_OVT_INDEX 0 | 875 | #define RX_NORMAL_DESC0_OVT_INDEX 0 |
| 853 | #define RX_NORMAL_DESC0_OVT_WIDTH 16 | 876 | #define RX_NORMAL_DESC0_OVT_WIDTH 16 |
| @@ -865,12 +888,23 @@ | |||
| 865 | #define RX_NORMAL_DESC3_FD_WIDTH 1 | 888 | #define RX_NORMAL_DESC3_FD_WIDTH 1 |
| 866 | #define RX_NORMAL_DESC3_INTE_INDEX 30 | 889 | #define RX_NORMAL_DESC3_INTE_INDEX 30 |
| 867 | #define RX_NORMAL_DESC3_INTE_WIDTH 1 | 890 | #define RX_NORMAL_DESC3_INTE_WIDTH 1 |
| 891 | #define RX_NORMAL_DESC3_L34T_INDEX 20 | ||
| 892 | #define RX_NORMAL_DESC3_L34T_WIDTH 4 | ||
| 868 | #define RX_NORMAL_DESC3_LD_INDEX 28 | 893 | #define RX_NORMAL_DESC3_LD_INDEX 28 |
| 869 | #define RX_NORMAL_DESC3_LD_WIDTH 1 | 894 | #define RX_NORMAL_DESC3_LD_WIDTH 1 |
| 870 | #define RX_NORMAL_DESC3_OWN_INDEX 31 | 895 | #define RX_NORMAL_DESC3_OWN_INDEX 31 |
| 871 | #define RX_NORMAL_DESC3_OWN_WIDTH 1 | 896 | #define RX_NORMAL_DESC3_OWN_WIDTH 1 |
| 872 | #define RX_NORMAL_DESC3_PL_INDEX 0 | 897 | #define RX_NORMAL_DESC3_PL_INDEX 0 |
| 873 | #define RX_NORMAL_DESC3_PL_WIDTH 14 | 898 | #define RX_NORMAL_DESC3_PL_WIDTH 14 |
| 899 | #define RX_NORMAL_DESC3_RSV_INDEX 26 | ||
| 900 | #define RX_NORMAL_DESC3_RSV_WIDTH 1 | ||
| 901 | |||
| 902 | #define RX_DESC3_L34T_IPV4_TCP 1 | ||
| 903 | #define RX_DESC3_L34T_IPV4_UDP 2 | ||
| 904 | #define RX_DESC3_L34T_IPV4_ICMP 3 | ||
| 905 | #define RX_DESC3_L34T_IPV6_TCP 9 | ||
| 906 | #define RX_DESC3_L34T_IPV6_UDP 10 | ||
| 907 | #define RX_DESC3_L34T_IPV6_ICMP 11 | ||
| 874 | 908 | ||
| 875 | #define RX_CONTEXT_DESC3_TSA_INDEX 4 | 909 | #define RX_CONTEXT_DESC3_TSA_INDEX 4 |
| 876 | #define RX_CONTEXT_DESC3_TSA_WIDTH 1 | 910 | #define RX_CONTEXT_DESC3_TSA_WIDTH 1 |
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c index ac3d319ffab3..551794c29d09 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c | |||
| @@ -351,6 +351,127 @@ static void xgbe_config_sph_mode(struct xgbe_prv_data *pdata) | |||
| 351 | XGMAC_IOWRITE_BITS(pdata, MAC_RCR, HDSMS, XGBE_SPH_HDSMS_SIZE); | 351 | XGMAC_IOWRITE_BITS(pdata, MAC_RCR, HDSMS, XGBE_SPH_HDSMS_SIZE); |
| 352 | } | 352 | } |
| 353 | 353 | ||
| 354 | static int xgbe_write_rss_reg(struct xgbe_prv_data *pdata, unsigned int type, | ||
| 355 | unsigned int index, unsigned int val) | ||
| 356 | { | ||
| 357 | unsigned int wait; | ||
| 358 | int ret = 0; | ||
| 359 | |||
| 360 | mutex_lock(&pdata->rss_mutex); | ||
| 361 | |||
| 362 | if (XGMAC_IOREAD_BITS(pdata, MAC_RSSAR, OB)) { | ||
| 363 | ret = -EBUSY; | ||
| 364 | goto unlock; | ||
| 365 | } | ||
| 366 | |||
| 367 | XGMAC_IOWRITE(pdata, MAC_RSSDR, val); | ||
| 368 | |||
| 369 | XGMAC_IOWRITE_BITS(pdata, MAC_RSSAR, RSSIA, index); | ||
| 370 | XGMAC_IOWRITE_BITS(pdata, MAC_RSSAR, ADDRT, type); | ||
| 371 | XGMAC_IOWRITE_BITS(pdata, MAC_RSSAR, CT, 0); | ||
| 372 | XGMAC_IOWRITE_BITS(pdata, MAC_RSSAR, OB, 1); | ||
| 373 | |||
| 374 | wait = 1000; | ||
| 375 | while (wait--) { | ||
| 376 | if (!XGMAC_IOREAD_BITS(pdata, MAC_RSSAR, OB)) | ||
| 377 | goto unlock; | ||
| 378 | |||
| 379 | usleep_range(1000, 1500); | ||
| 380 | } | ||
| 381 | |||
| 382 | ret = -EBUSY; | ||
| 383 | |||
| 384 | unlock: | ||
| 385 | mutex_unlock(&pdata->rss_mutex); | ||
| 386 | |||
| 387 | return ret; | ||
| 388 | } | ||
| 389 | |||
| 390 | static int xgbe_write_rss_hash_key(struct xgbe_prv_data *pdata) | ||
| 391 | { | ||
| 392 | unsigned int key_regs = sizeof(pdata->rss_key) / sizeof(u32); | ||
| 393 | unsigned int *key = (unsigned int *)&pdata->rss_key; | ||
| 394 | int ret; | ||
| 395 | |||
| 396 | while (key_regs--) { | ||
| 397 | ret = xgbe_write_rss_reg(pdata, XGBE_RSS_HASH_KEY_TYPE, | ||
| 398 | key_regs, *key++); | ||
| 399 | if (ret) | ||
| 400 | return ret; | ||
| 401 | } | ||
| 402 | |||
| 403 | return 0; | ||
| 404 | } | ||
| 405 | |||
| 406 | static int xgbe_write_rss_lookup_table(struct xgbe_prv_data *pdata) | ||
| 407 | { | ||
| 408 | unsigned int i; | ||
| 409 | int ret; | ||
| 410 | |||
| 411 | for (i = 0; i < ARRAY_SIZE(pdata->rss_table); i++) { | ||
| 412 | ret = xgbe_write_rss_reg(pdata, | ||
| 413 | XGBE_RSS_LOOKUP_TABLE_TYPE, i, | ||
| 414 | pdata->rss_table[i]); | ||
| 415 | if (ret) | ||
| 416 | return ret; | ||
| 417 | } | ||
| 418 | |||
| 419 | return 0; | ||
| 420 | } | ||
| 421 | |||
| 422 | static int xgbe_enable_rss(struct xgbe_prv_data *pdata) | ||
| 423 | { | ||
| 424 | int ret; | ||
| 425 | |||
| 426 | if (!pdata->hw_feat.rss) | ||
| 427 | return -EOPNOTSUPP; | ||
| 428 | |||
| 429 | /* Program the hash key */ | ||
| 430 | ret = xgbe_write_rss_hash_key(pdata); | ||
| 431 | if (ret) | ||
| 432 | return ret; | ||
| 433 | |||
| 434 | /* Program the lookup table */ | ||
| 435 | ret = xgbe_write_rss_lookup_table(pdata); | ||
| 436 | if (ret) | ||
| 437 | return ret; | ||
| 438 | |||
| 439 | /* Set the RSS options */ | ||
| 440 | XGMAC_IOWRITE(pdata, MAC_RSSCR, pdata->rss_options); | ||
| 441 | |||
| 442 | /* Enable RSS */ | ||
| 443 | XGMAC_IOWRITE_BITS(pdata, MAC_RSSCR, RSSE, 1); | ||
| 444 | |||
| 445 | return 0; | ||
| 446 | } | ||
| 447 | |||
| 448 | static int xgbe_disable_rss(struct xgbe_prv_data *pdata) | ||
| 449 | { | ||
| 450 | if (!pdata->hw_feat.rss) | ||
| 451 | return -EOPNOTSUPP; | ||
| 452 | |||
| 453 | XGMAC_IOWRITE_BITS(pdata, MAC_RSSCR, RSSE, 0); | ||
| 454 | |||
| 455 | return 0; | ||
| 456 | } | ||
| 457 | |||
| 458 | static void xgbe_config_rss(struct xgbe_prv_data *pdata) | ||
| 459 | { | ||
| 460 | int ret; | ||
| 461 | |||
| 462 | if (!pdata->hw_feat.rss) | ||
| 463 | return; | ||
| 464 | |||
| 465 | if (pdata->netdev->features & NETIF_F_RXHASH) | ||
| 466 | ret = xgbe_enable_rss(pdata); | ||
| 467 | else | ||
| 468 | ret = xgbe_disable_rss(pdata); | ||
| 469 | |||
| 470 | if (ret) | ||
| 471 | netdev_err(pdata->netdev, | ||
| 472 | "error configuring RSS, RSS disabled\n"); | ||
| 473 | } | ||
| 474 | |||
| 354 | static int xgbe_disable_tx_flow_control(struct xgbe_prv_data *pdata) | 475 | static int xgbe_disable_tx_flow_control(struct xgbe_prv_data *pdata) |
| 355 | { | 476 | { |
| 356 | unsigned int max_q_count, q_count; | 477 | unsigned int max_q_count, q_count; |
| @@ -1408,7 +1529,7 @@ static int xgbe_dev_read(struct xgbe_channel *channel) | |||
| 1408 | struct xgbe_ring_desc *rdesc; | 1529 | struct xgbe_ring_desc *rdesc; |
| 1409 | struct xgbe_packet_data *packet = &ring->packet_data; | 1530 | struct xgbe_packet_data *packet = &ring->packet_data; |
| 1410 | struct net_device *netdev = channel->pdata->netdev; | 1531 | struct net_device *netdev = channel->pdata->netdev; |
| 1411 | unsigned int err, etlt; | 1532 | unsigned int err, etlt, l34t; |
| 1412 | 1533 | ||
| 1413 | DBGPR("-->xgbe_dev_read: cur = %d\n", ring->cur); | 1534 | DBGPR("-->xgbe_dev_read: cur = %d\n", ring->cur); |
| 1414 | 1535 | ||
| @@ -1447,6 +1568,26 @@ static int xgbe_dev_read(struct xgbe_channel *channel) | |||
| 1447 | rdata->hdr_len = XGMAC_GET_BITS_LE(rdesc->desc2, | 1568 | rdata->hdr_len = XGMAC_GET_BITS_LE(rdesc->desc2, |
| 1448 | RX_NORMAL_DESC2, HL); | 1569 | RX_NORMAL_DESC2, HL); |
| 1449 | 1570 | ||
| 1571 | /* Get the RSS hash */ | ||
| 1572 | if (XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, RSV)) { | ||
| 1573 | XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES, | ||
| 1574 | RSS_HASH, 1); | ||
| 1575 | |||
| 1576 | packet->rss_hash = le32_to_cpu(rdesc->desc1); | ||
| 1577 | |||
| 1578 | l34t = XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, L34T); | ||
| 1579 | switch (l34t) { | ||
| 1580 | case RX_DESC3_L34T_IPV4_TCP: | ||
| 1581 | case RX_DESC3_L34T_IPV4_UDP: | ||
| 1582 | case RX_DESC3_L34T_IPV6_TCP: | ||
| 1583 | case RX_DESC3_L34T_IPV6_UDP: | ||
| 1584 | packet->rss_hash_type = PKT_HASH_TYPE_L4; | ||
| 1585 | |||
| 1586 | default: | ||
| 1587 | packet->rss_hash_type = PKT_HASH_TYPE_L3; | ||
| 1588 | } | ||
| 1589 | } | ||
| 1590 | |||
| 1450 | /* Get the packet length */ | 1591 | /* Get the packet length */ |
| 1451 | rdata->len = XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, PL); | 1592 | rdata->len = XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, PL); |
| 1452 | 1593 | ||
| @@ -2479,6 +2620,7 @@ static int xgbe_init(struct xgbe_prv_data *pdata) | |||
| 2479 | xgbe_config_rx_buffer_size(pdata); | 2620 | xgbe_config_rx_buffer_size(pdata); |
| 2480 | xgbe_config_tso_mode(pdata); | 2621 | xgbe_config_tso_mode(pdata); |
| 2481 | xgbe_config_sph_mode(pdata); | 2622 | xgbe_config_sph_mode(pdata); |
| 2623 | xgbe_config_rss(pdata); | ||
| 2482 | desc_if->wrapper_tx_desc_init(pdata); | 2624 | desc_if->wrapper_tx_desc_init(pdata); |
| 2483 | desc_if->wrapper_rx_desc_init(pdata); | 2625 | desc_if->wrapper_rx_desc_init(pdata); |
| 2484 | xgbe_enable_dma_interrupts(pdata); | 2626 | xgbe_enable_dma_interrupts(pdata); |
| @@ -2614,5 +2756,9 @@ void xgbe_init_function_ptrs_dev(struct xgbe_hw_if *hw_if) | |||
| 2614 | hw_if->config_dcb_tc = xgbe_config_dcb_tc; | 2756 | hw_if->config_dcb_tc = xgbe_config_dcb_tc; |
| 2615 | hw_if->config_dcb_pfc = xgbe_config_dcb_pfc; | 2757 | hw_if->config_dcb_pfc = xgbe_config_dcb_pfc; |
| 2616 | 2758 | ||
| 2759 | /* For Receive Side Scaling */ | ||
| 2760 | hw_if->enable_rss = xgbe_enable_rss; | ||
| 2761 | hw_if->disable_rss = xgbe_disable_rss; | ||
| 2762 | |||
| 2617 | DBGPR("<--xgbe_init_function_ptrs\n"); | 2763 | DBGPR("<--xgbe_init_function_ptrs\n"); |
| 2618 | } | 2764 | } |
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c index c3533e104c61..6c5a7079697c 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c | |||
| @@ -1661,12 +1661,21 @@ static int xgbe_set_features(struct net_device *netdev, | |||
| 1661 | { | 1661 | { |
| 1662 | struct xgbe_prv_data *pdata = netdev_priv(netdev); | 1662 | struct xgbe_prv_data *pdata = netdev_priv(netdev); |
| 1663 | struct xgbe_hw_if *hw_if = &pdata->hw_if; | 1663 | struct xgbe_hw_if *hw_if = &pdata->hw_if; |
| 1664 | netdev_features_t rxcsum, rxvlan, rxvlan_filter; | 1664 | netdev_features_t rxhash, rxcsum, rxvlan, rxvlan_filter; |
| 1665 | int ret = 0; | ||
| 1665 | 1666 | ||
| 1667 | rxhash = pdata->netdev_features & NETIF_F_RXHASH; | ||
| 1666 | rxcsum = pdata->netdev_features & NETIF_F_RXCSUM; | 1668 | rxcsum = pdata->netdev_features & NETIF_F_RXCSUM; |
| 1667 | rxvlan = pdata->netdev_features & NETIF_F_HW_VLAN_CTAG_RX; | 1669 | rxvlan = pdata->netdev_features & NETIF_F_HW_VLAN_CTAG_RX; |
| 1668 | rxvlan_filter = pdata->netdev_features & NETIF_F_HW_VLAN_CTAG_FILTER; | 1670 | rxvlan_filter = pdata->netdev_features & NETIF_F_HW_VLAN_CTAG_FILTER; |
| 1669 | 1671 | ||
| 1672 | if ((features & NETIF_F_RXHASH) && !rxhash) | ||
| 1673 | ret = hw_if->enable_rss(pdata); | ||
| 1674 | else if (!(features & NETIF_F_RXHASH) && rxhash) | ||
| 1675 | ret = hw_if->disable_rss(pdata); | ||
| 1676 | if (ret) | ||
| 1677 | return ret; | ||
| 1678 | |||
| 1670 | if ((features & NETIF_F_RXCSUM) && !rxcsum) | 1679 | if ((features & NETIF_F_RXCSUM) && !rxcsum) |
| 1671 | hw_if->enable_rx_csum(pdata); | 1680 | hw_if->enable_rx_csum(pdata); |
| 1672 | else if (!(features & NETIF_F_RXCSUM) && rxcsum) | 1681 | else if (!(features & NETIF_F_RXCSUM) && rxcsum) |
| @@ -1960,6 +1969,11 @@ read_again: | |||
| 1960 | hwtstamps->hwtstamp = ns_to_ktime(nsec); | 1969 | hwtstamps->hwtstamp = ns_to_ktime(nsec); |
| 1961 | } | 1970 | } |
| 1962 | 1971 | ||
| 1972 | if (XGMAC_GET_BITS(packet->attributes, | ||
| 1973 | RX_PACKET_ATTRIBUTES, RSS_HASH)) | ||
| 1974 | skb_set_hash(skb, packet->rss_hash, | ||
| 1975 | packet->rss_hash_type); | ||
| 1976 | |||
| 1963 | skb->dev = netdev; | 1977 | skb->dev = netdev; |
| 1964 | skb->protocol = eth_type_trans(skb, netdev); | 1978 | skb->protocol = eth_type_trans(skb, netdev); |
| 1965 | skb_record_rx_queue(skb, channel->queue_index); | 1979 | skb_record_rx_queue(skb, channel->queue_index); |
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-main.c b/drivers/net/ethernet/amd/xgbe/xgbe-main.c index cff9902d1456..05fbdf96e77e 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-main.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-main.c | |||
| @@ -170,6 +170,7 @@ static int xgbe_probe(struct platform_device *pdev) | |||
| 170 | struct device *dev = &pdev->dev; | 170 | struct device *dev = &pdev->dev; |
| 171 | struct resource *res; | 171 | struct resource *res; |
| 172 | const u8 *mac_addr; | 172 | const u8 *mac_addr; |
| 173 | unsigned int i; | ||
| 173 | int ret; | 174 | int ret; |
| 174 | 175 | ||
| 175 | DBGPR("--> xgbe_probe\n"); | 176 | DBGPR("--> xgbe_probe\n"); |
| @@ -190,6 +191,7 @@ static int xgbe_probe(struct platform_device *pdev) | |||
| 190 | 191 | ||
| 191 | spin_lock_init(&pdata->lock); | 192 | spin_lock_init(&pdata->lock); |
| 192 | mutex_init(&pdata->xpcs_mutex); | 193 | mutex_init(&pdata->xpcs_mutex); |
| 194 | mutex_init(&pdata->rss_mutex); | ||
| 193 | spin_lock_init(&pdata->tstamp_lock); | 195 | spin_lock_init(&pdata->tstamp_lock); |
| 194 | 196 | ||
| 195 | /* Set and validate the number of descriptors for a ring */ | 197 | /* Set and validate the number of descriptors for a ring */ |
| @@ -335,6 +337,17 @@ static int xgbe_probe(struct platform_device *pdev) | |||
| 335 | goto err_io; | 337 | goto err_io; |
| 336 | } | 338 | } |
| 337 | 339 | ||
| 340 | /* Initialize RSS hash key and lookup table */ | ||
| 341 | get_random_bytes(pdata->rss_key, sizeof(pdata->rss_key)); | ||
| 342 | |||
| 343 | for (i = 0; i < XGBE_RSS_MAX_TABLE_SIZE; i++) | ||
| 344 | XGMAC_SET_BITS(pdata->rss_table[i], MAC_RSSDR, DMCH, | ||
| 345 | i % pdata->rx_ring_count); | ||
| 346 | |||
| 347 | XGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, IP2TE, 1); | ||
| 348 | XGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, TCP4TE, 1); | ||
| 349 | XGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, UDP4TE, 1); | ||
| 350 | |||
| 338 | /* Prepare to regsiter with MDIO */ | 351 | /* Prepare to regsiter with MDIO */ |
| 339 | pdata->mii_bus_id = kasprintf(GFP_KERNEL, "%s", pdev->name); | 352 | pdata->mii_bus_id = kasprintf(GFP_KERNEL, "%s", pdev->name); |
| 340 | if (!pdata->mii_bus_id) { | 353 | if (!pdata->mii_bus_id) { |
| @@ -365,6 +378,9 @@ static int xgbe_probe(struct platform_device *pdev) | |||
| 365 | NETIF_F_HW_VLAN_CTAG_TX | | 378 | NETIF_F_HW_VLAN_CTAG_TX | |
| 366 | NETIF_F_HW_VLAN_CTAG_FILTER; | 379 | NETIF_F_HW_VLAN_CTAG_FILTER; |
| 367 | 380 | ||
| 381 | if (pdata->hw_feat.rss) | ||
| 382 | netdev->hw_features |= NETIF_F_RXHASH; | ||
| 383 | |||
| 368 | netdev->vlan_features |= NETIF_F_SG | | 384 | netdev->vlan_features |= NETIF_F_SG | |
| 369 | NETIF_F_IP_CSUM | | 385 | NETIF_F_IP_CSUM | |
| 370 | NETIF_F_IPV6_CSUM | | 386 | NETIF_F_IPV6_CSUM | |
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h index 55c935f4884a..2ac4f176ad88 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe.h +++ b/drivers/net/ethernet/amd/xgbe/xgbe.h | |||
| @@ -215,6 +215,12 @@ | |||
| 215 | /* Maximum MAC address hash table size (256 bits = 8 bytes) */ | 215 | /* Maximum MAC address hash table size (256 bits = 8 bytes) */ |
| 216 | #define XGBE_MAC_HASH_TABLE_SIZE 8 | 216 | #define XGBE_MAC_HASH_TABLE_SIZE 8 |
| 217 | 217 | ||
| 218 | /* Receive Side Scaling */ | ||
| 219 | #define XGBE_RSS_HASH_KEY_SIZE 40 | ||
| 220 | #define XGBE_RSS_MAX_TABLE_SIZE 256 | ||
| 221 | #define XGBE_RSS_LOOKUP_TABLE_TYPE 0 | ||
| 222 | #define XGBE_RSS_HASH_KEY_TYPE 1 | ||
| 223 | |||
| 218 | struct xgbe_prv_data; | 224 | struct xgbe_prv_data; |
| 219 | 225 | ||
| 220 | struct xgbe_packet_data { | 226 | struct xgbe_packet_data { |
| @@ -233,6 +239,9 @@ struct xgbe_packet_data { | |||
| 233 | unsigned short vlan_ctag; | 239 | unsigned short vlan_ctag; |
| 234 | 240 | ||
| 235 | u64 rx_tstamp; | 241 | u64 rx_tstamp; |
| 242 | |||
| 243 | u32 rss_hash; | ||
| 244 | enum pkt_hash_types rss_hash_type; | ||
| 236 | }; | 245 | }; |
| 237 | 246 | ||
| 238 | /* Common Rx and Tx descriptor mapping */ | 247 | /* Common Rx and Tx descriptor mapping */ |
| @@ -544,6 +553,10 @@ struct xgbe_hw_if { | |||
| 544 | /* For Data Center Bridging config */ | 553 | /* For Data Center Bridging config */ |
| 545 | void (*config_dcb_tc)(struct xgbe_prv_data *); | 554 | void (*config_dcb_tc)(struct xgbe_prv_data *); |
| 546 | void (*config_dcb_pfc)(struct xgbe_prv_data *); | 555 | void (*config_dcb_pfc)(struct xgbe_prv_data *); |
| 556 | |||
| 557 | /* For Receive Side Scaling */ | ||
| 558 | int (*enable_rss)(struct xgbe_prv_data *); | ||
| 559 | int (*disable_rss)(struct xgbe_prv_data *); | ||
| 547 | }; | 560 | }; |
| 548 | 561 | ||
| 549 | struct xgbe_desc_if { | 562 | struct xgbe_desc_if { |
| @@ -616,6 +629,9 @@ struct xgbe_prv_data { | |||
| 616 | /* XPCS indirect addressing mutex */ | 629 | /* XPCS indirect addressing mutex */ |
| 617 | struct mutex xpcs_mutex; | 630 | struct mutex xpcs_mutex; |
| 618 | 631 | ||
| 632 | /* RSS addressing mutex */ | ||
| 633 | struct mutex rss_mutex; | ||
| 634 | |||
| 619 | int dev_irq; | 635 | int dev_irq; |
| 620 | unsigned int per_channel_irq; | 636 | unsigned int per_channel_irq; |
| 621 | 637 | ||
| @@ -668,6 +684,11 @@ struct xgbe_prv_data { | |||
| 668 | unsigned int tx_pause; | 684 | unsigned int tx_pause; |
| 669 | unsigned int rx_pause; | 685 | unsigned int rx_pause; |
| 670 | 686 | ||
| 687 | /* Receive Side Scaling settings */ | ||
| 688 | u8 rss_key[XGBE_RSS_HASH_KEY_SIZE]; | ||
| 689 | u32 rss_table[XGBE_RSS_MAX_TABLE_SIZE]; | ||
| 690 | u32 rss_options; | ||
| 691 | |||
| 671 | /* MDIO settings */ | 692 | /* MDIO settings */ |
| 672 | struct module *phy_module; | 693 | struct module *phy_module; |
| 673 | char *mii_bus_id; | 694 | char *mii_bus_id; |
