Skip to content

Commit e46c5b8

Browse files
committed
Merge branch 'tsnep-minor-improvements'
Gerhard Engleder says: ==================== tsnep: Various minor driver improvements During XDP development some general driver improvements has been done which I want to keep out of future patch series. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents c21ab2a + d113efb commit e46c5b8

File tree

3 files changed

+88
-31
lines changed

3 files changed

+88
-31
lines changed

drivers/net/ethernet/engleder/tsnep.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ struct tsnep_rx_entry {
8787
struct tsnep_rx {
8888
struct tsnep_adapter *adapter;
8989
void __iomem *addr;
90+
int queue_index;
9091

9192
void *page[TSNEP_RING_PAGE_COUNT];
9293
dma_addr_t page_dma[TSNEP_RING_PAGE_COUNT];

drivers/net/ethernet/engleder/tsnep_hw.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,7 @@
9292

9393
/* tsnep register */
9494
#define TSNEP_INFO 0x0100
95-
#define TSNEP_INFO_RX_ASSIGN 0x00010000
96-
#define TSNEP_INFO_TX_TIME 0x00020000
95+
#define TSNEP_INFO_TX_TIME 0x00010000
9796
#define TSNEP_CONTROL 0x0108
9897
#define TSNEP_CONTROL_TX_RESET 0x00000001
9998
#define TSNEP_CONTROL_TX_ENABLE 0x00000002

drivers/net/ethernet/engleder/tsnep_main.c

Lines changed: 86 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -124,30 +124,51 @@ static int tsnep_mdiobus_write(struct mii_bus *bus, int addr, int regnum,
124124
return 0;
125125
}
126126

127+
static void tsnep_set_link_mode(struct tsnep_adapter *adapter)
128+
{
129+
u32 mode;
130+
131+
switch (adapter->phydev->speed) {
132+
case SPEED_100:
133+
mode = ECM_LINK_MODE_100;
134+
break;
135+
case SPEED_1000:
136+
mode = ECM_LINK_MODE_1000;
137+
break;
138+
default:
139+
mode = ECM_LINK_MODE_OFF;
140+
break;
141+
}
142+
iowrite32(mode, adapter->addr + ECM_STATUS);
143+
}
144+
127145
static void tsnep_phy_link_status_change(struct net_device *netdev)
128146
{
129147
struct tsnep_adapter *adapter = netdev_priv(netdev);
130148
struct phy_device *phydev = netdev->phydev;
131-
u32 mode;
132149

133-
if (phydev->link) {
134-
switch (phydev->speed) {
135-
case SPEED_100:
136-
mode = ECM_LINK_MODE_100;
137-
break;
138-
case SPEED_1000:
139-
mode = ECM_LINK_MODE_1000;
140-
break;
141-
default:
142-
mode = ECM_LINK_MODE_OFF;
143-
break;
144-
}
145-
iowrite32(mode, adapter->addr + ECM_STATUS);
146-
}
150+
if (phydev->link)
151+
tsnep_set_link_mode(adapter);
147152

148153
phy_print_status(netdev->phydev);
149154
}
150155

156+
static int tsnep_phy_loopback(struct tsnep_adapter *adapter, bool enable)
157+
{
158+
int retval;
159+
160+
retval = phy_loopback(adapter->phydev, enable);
161+
162+
/* PHY link state change is not signaled if loopback is enabled, it
163+
* would delay a working loopback anyway, let's ensure that loopback
164+
* is working immediately by setting link mode directly
165+
*/
166+
if (!retval && enable)
167+
tsnep_set_link_mode(adapter);
168+
169+
return retval;
170+
}
171+
151172
static int tsnep_phy_open(struct tsnep_adapter *adapter)
152173
{
153174
struct phy_device *phydev;
@@ -241,14 +262,14 @@ static int tsnep_tx_ring_init(struct tsnep_tx *tx)
241262
return retval;
242263
}
243264

244-
static void tsnep_tx_activate(struct tsnep_tx *tx, int index, bool last)
265+
static void tsnep_tx_activate(struct tsnep_tx *tx, int index, int length,
266+
bool last)
245267
{
246268
struct tsnep_tx_entry *entry = &tx->entry[index];
247269

248270
entry->properties = 0;
249271
if (entry->skb) {
250-
entry->properties =
251-
skb_pagelen(entry->skb) & TSNEP_DESC_LENGTH_MASK;
272+
entry->properties = length & TSNEP_DESC_LENGTH_MASK;
252273
entry->properties |= TSNEP_DESC_INTERRUPT_FLAG;
253274
if (skb_shinfo(entry->skb)->tx_flags & SKBTX_IN_PROGRESS)
254275
entry->properties |= TSNEP_DESC_EXTENDED_WRITEBACK_FLAG;
@@ -313,6 +334,7 @@ static int tsnep_tx_map(struct sk_buff *skb, struct tsnep_tx *tx, int count)
313334
struct tsnep_tx_entry *entry;
314335
unsigned int len;
315336
dma_addr_t dma;
337+
int map_len = 0;
316338
int i;
317339

318340
for (i = 0; i < count; i++) {
@@ -335,15 +357,18 @@ static int tsnep_tx_map(struct sk_buff *skb, struct tsnep_tx *tx, int count)
335357
dma_unmap_addr_set(entry, dma, dma);
336358

337359
entry->desc->tx = __cpu_to_le64(dma);
360+
361+
map_len += len;
338362
}
339363

340-
return 0;
364+
return map_len;
341365
}
342366

343-
static void tsnep_tx_unmap(struct tsnep_tx *tx, int index, int count)
367+
static int tsnep_tx_unmap(struct tsnep_tx *tx, int index, int count)
344368
{
345369
struct device *dmadev = tx->adapter->dmadev;
346370
struct tsnep_tx_entry *entry;
371+
int map_len = 0;
347372
int i;
348373

349374
for (i = 0; i < count; i++) {
@@ -360,9 +385,12 @@ static void tsnep_tx_unmap(struct tsnep_tx *tx, int index, int count)
360385
dma_unmap_addr(entry, dma),
361386
dma_unmap_len(entry, len),
362387
DMA_TO_DEVICE);
388+
map_len += entry->len;
363389
entry->len = 0;
364390
}
365391
}
392+
393+
return map_len;
366394
}
367395

368396
static netdev_tx_t tsnep_xmit_frame_ring(struct sk_buff *skb,
@@ -371,6 +399,7 @@ static netdev_tx_t tsnep_xmit_frame_ring(struct sk_buff *skb,
371399
unsigned long flags;
372400
int count = 1;
373401
struct tsnep_tx_entry *entry;
402+
int length;
374403
int i;
375404
int retval;
376405

@@ -394,7 +423,7 @@ static netdev_tx_t tsnep_xmit_frame_ring(struct sk_buff *skb,
394423
entry->skb = skb;
395424

396425
retval = tsnep_tx_map(skb, tx, count);
397-
if (retval != 0) {
426+
if (retval < 0) {
398427
tsnep_tx_unmap(tx, tx->write, count);
399428
dev_kfree_skb_any(entry->skb);
400429
entry->skb = NULL;
@@ -407,12 +436,13 @@ static netdev_tx_t tsnep_xmit_frame_ring(struct sk_buff *skb,
407436

408437
return NETDEV_TX_OK;
409438
}
439+
length = retval;
410440

411441
if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
412442
skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
413443

414444
for (i = 0; i < count; i++)
415-
tsnep_tx_activate(tx, (tx->write + i) % TSNEP_RING_SIZE,
445+
tsnep_tx_activate(tx, (tx->write + i) % TSNEP_RING_SIZE, length,
416446
i == (count - 1));
417447
tx->write = (tx->write + count) % TSNEP_RING_SIZE;
418448

@@ -428,9 +458,6 @@ static netdev_tx_t tsnep_xmit_frame_ring(struct sk_buff *skb,
428458
netif_stop_queue(tx->adapter->netdev);
429459
}
430460

431-
tx->packets++;
432-
tx->bytes += skb_pagelen(entry->skb) + ETH_FCS_LEN;
433-
434461
spin_unlock_irqrestore(&tx->lock, flags);
435462

436463
return NETDEV_TX_OK;
@@ -442,6 +469,7 @@ static bool tsnep_tx_poll(struct tsnep_tx *tx, int napi_budget)
442469
int budget = 128;
443470
struct tsnep_tx_entry *entry;
444471
int count;
472+
int length;
445473

446474
spin_lock_irqsave(&tx->lock, flags);
447475

@@ -464,7 +492,7 @@ static bool tsnep_tx_poll(struct tsnep_tx *tx, int napi_budget)
464492
if (skb_shinfo(entry->skb)->nr_frags > 0)
465493
count += skb_shinfo(entry->skb)->nr_frags;
466494

467-
tsnep_tx_unmap(tx, tx->read, count);
495+
length = tsnep_tx_unmap(tx, tx->read, count);
468496

469497
if ((skb_shinfo(entry->skb)->tx_flags & SKBTX_IN_PROGRESS) &&
470498
(__le32_to_cpu(entry->desc_wb->properties) &
@@ -491,6 +519,9 @@ static bool tsnep_tx_poll(struct tsnep_tx *tx, int napi_budget)
491519

492520
tx->read = (tx->read + count) % TSNEP_RING_SIZE;
493521

522+
tx->packets++;
523+
tx->bytes += length + ETH_FCS_LEN;
524+
494525
budget--;
495526
} while (likely(budget));
496527

@@ -718,6 +749,7 @@ static int tsnep_rx_poll(struct tsnep_rx *rx, struct napi_struct *napi,
718749
hwtstamps->netdev_data = rx_inline;
719750
}
720751
skb_pull(skb, TSNEP_RX_INLINE_METADATA_SIZE);
752+
skb_record_rx_queue(skb, rx->queue_index);
721753
skb->protocol = eth_type_trans(skb,
722754
rx->adapter->netdev);
723755

@@ -752,7 +784,7 @@ static int tsnep_rx_poll(struct tsnep_rx *rx, struct napi_struct *napi,
752784
}
753785

754786
static int tsnep_rx_open(struct tsnep_adapter *adapter, void __iomem *addr,
755-
struct tsnep_rx *rx)
787+
int queue_index, struct tsnep_rx *rx)
756788
{
757789
dma_addr_t dma;
758790
int i;
@@ -761,6 +793,7 @@ static int tsnep_rx_open(struct tsnep_adapter *adapter, void __iomem *addr,
761793
memset(rx, 0, sizeof(*rx));
762794
rx->adapter = adapter;
763795
rx->addr = addr;
796+
rx->queue_index = queue_index;
764797

765798
retval = tsnep_rx_ring_init(rx);
766799
if (retval)
@@ -847,6 +880,7 @@ static int tsnep_netdev_open(struct net_device *netdev)
847880
if (adapter->queue[i].rx) {
848881
addr = adapter->addr + TSNEP_QUEUE(rx_queue_index);
849882
retval = tsnep_rx_open(adapter, addr,
883+
rx_queue_index,
850884
adapter->queue[i].rx);
851885
if (retval)
852886
goto failed;
@@ -1017,6 +1051,22 @@ static int tsnep_netdev_set_mac_address(struct net_device *netdev, void *addr)
10171051
return 0;
10181052
}
10191053

1054+
static int tsnep_netdev_set_features(struct net_device *netdev,
1055+
netdev_features_t features)
1056+
{
1057+
struct tsnep_adapter *adapter = netdev_priv(netdev);
1058+
netdev_features_t changed = netdev->features ^ features;
1059+
bool enable;
1060+
int retval = 0;
1061+
1062+
if (changed & NETIF_F_LOOPBACK) {
1063+
enable = !!(features & NETIF_F_LOOPBACK);
1064+
retval = tsnep_phy_loopback(adapter, enable);
1065+
}
1066+
1067+
return retval;
1068+
}
1069+
10201070
static ktime_t tsnep_netdev_get_tstamp(struct net_device *netdev,
10211071
const struct skb_shared_hwtstamps *hwtstamps,
10221072
bool cycles)
@@ -1038,9 +1088,9 @@ static const struct net_device_ops tsnep_netdev_ops = {
10381088
.ndo_start_xmit = tsnep_netdev_xmit_frame,
10391089
.ndo_eth_ioctl = tsnep_netdev_ioctl,
10401090
.ndo_set_rx_mode = tsnep_netdev_set_multicast,
1041-
10421091
.ndo_get_stats64 = tsnep_netdev_get_stats64,
10431092
.ndo_set_mac_address = tsnep_netdev_set_mac_address,
1093+
.ndo_set_features = tsnep_netdev_set_features,
10441094
.ndo_get_tstamp = tsnep_netdev_get_tstamp,
10451095
.ndo_setup_tc = tsnep_tc_setup,
10461096
};
@@ -1192,6 +1242,13 @@ static int tsnep_probe(struct platform_device *pdev)
11921242
adapter->queue[0].rx = &adapter->rx[0];
11931243
adapter->queue[0].irq_mask = ECM_INT_TX_0 | ECM_INT_RX_0;
11941244

1245+
retval = dma_set_mask_and_coherent(&adapter->pdev->dev,
1246+
DMA_BIT_MASK(64));
1247+
if (retval) {
1248+
dev_err(&adapter->pdev->dev, "no usable DMA configuration.\n");
1249+
return retval;
1250+
}
1251+
11951252
tsnep_disable_irq(adapter, ECM_INT_ALL);
11961253
retval = devm_request_irq(&adapter->pdev->dev, adapter->irq, tsnep_irq,
11971254
0, TSNEP, adapter);
@@ -1225,7 +1282,7 @@ static int tsnep_probe(struct platform_device *pdev)
12251282
netdev->netdev_ops = &tsnep_netdev_ops;
12261283
netdev->ethtool_ops = &tsnep_ethtool_ops;
12271284
netdev->features = NETIF_F_SG;
1228-
netdev->hw_features = netdev->features;
1285+
netdev->hw_features = netdev->features | NETIF_F_LOOPBACK;
12291286

12301287
/* carrier off reporting is important to ethtool even BEFORE open */
12311288
netif_carrier_off(netdev);

0 commit comments

Comments
 (0)