aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/amd/xgbe/xgbe-dev.c')
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-dev.c148
1 files changed, 147 insertions, 1 deletions
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
354static 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
384unlock:
385 mutex_unlock(&pdata->rss_mutex);
386
387 return ret;
388}
389
390static 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
406static 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
422static 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
448static 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
458static 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
354static int xgbe_disable_tx_flow_control(struct xgbe_prv_data *pdata) 475static 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}