Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

sfc: hook up ef100 representor TX

Implement .ndo_start_xmit() by calling into the parent PF's TX path.

Signed-off-by: Edward Cree <ecree.xilinx@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Edward Cree and committed by
David S. Miller
f72c38fa 02443ab8

+38 -1
+10 -1
drivers/net/ethernet/sfc/ef100_netdev.c
··· 195 195 struct net_device *net_dev) 196 196 { 197 197 struct efx_nic *efx = efx_netdev_priv(net_dev); 198 + 199 + return __ef100_hard_start_xmit(skb, efx, net_dev, NULL); 200 + } 201 + 202 + netdev_tx_t __ef100_hard_start_xmit(struct sk_buff *skb, 203 + struct efx_nic *efx, 204 + struct net_device *net_dev, 205 + struct efx_rep *efv) 206 + { 198 207 struct efx_tx_queue *tx_queue; 199 208 struct efx_channel *channel; 200 209 int rc; ··· 218 209 } 219 210 220 211 tx_queue = &channel->tx_queue[0]; 221 - rc = ef100_enqueue_skb(tx_queue, skb); 212 + rc = __ef100_enqueue_skb(tx_queue, skb, efv); 222 213 if (rc == 0) 223 214 return NETDEV_TX_OK; 224 215
+5
drivers/net/ethernet/sfc/ef100_netdev.h
··· 10 10 */ 11 11 12 12 #include <linux/netdevice.h> 13 + #include "ef100_rep.h" 13 14 15 + netdev_tx_t __ef100_hard_start_xmit(struct sk_buff *skb, 16 + struct efx_nic *efx, 17 + struct net_device *net_dev, 18 + struct efx_rep *efv); 14 19 int ef100_netdev_event(struct notifier_block *this, 15 20 unsigned long event, void *ptr); 16 21 int ef100_probe_netdev(struct efx_probe_data *probe_data);
+23
drivers/net/ethernet/sfc/ef100_rep.c
··· 10 10 */ 11 11 12 12 #include "ef100_rep.h" 13 + #include "ef100_netdev.h" 13 14 #include "ef100_nic.h" 14 15 #include "mae.h" 15 16 ··· 27 26 NETIF_MSG_IFUP | NETIF_MSG_RX_ERR | 28 27 NETIF_MSG_TX_ERR | NETIF_MSG_HW; 29 28 return 0; 29 + } 30 + 31 + static netdev_tx_t efx_ef100_rep_xmit(struct sk_buff *skb, 32 + struct net_device *dev) 33 + { 34 + struct efx_rep *efv = netdev_priv(dev); 35 + struct efx_nic *efx = efv->parent; 36 + netdev_tx_t rc; 37 + 38 + /* __ef100_hard_start_xmit() will always return success even in the 39 + * case of TX drops, where it will increment efx's tx_dropped. The 40 + * efv stats really only count attempted TX, not success/failure. 41 + */ 42 + atomic64_inc(&efv->stats.tx_packets); 43 + atomic64_add(skb->len, &efv->stats.tx_bytes); 44 + netif_tx_lock(efx->net_dev); 45 + rc = __ef100_hard_start_xmit(skb, efx, dev, efv); 46 + netif_tx_unlock(efx->net_dev); 47 + return rc; 30 48 } 31 49 32 50 static int efx_ef100_rep_get_port_parent_id(struct net_device *dev, ··· 80 60 } 81 61 82 62 static const struct net_device_ops efx_ef100_rep_netdev_ops = { 63 + .ndo_start_xmit = efx_ef100_rep_xmit, 83 64 .ndo_get_port_parent_id = efx_ef100_rep_get_port_parent_id, 84 65 .ndo_get_phys_port_name = efx_ef100_rep_get_phys_port_name, 85 66 }; ··· 140 119 net_dev->ethtool_ops = &efx_ef100_rep_ethtool_ops; 141 120 net_dev->min_mtu = EFX_MIN_MTU; 142 121 net_dev->max_mtu = EFX_MAX_MTU; 122 + net_dev->features |= NETIF_F_LLTX; 123 + net_dev->hw_features |= NETIF_F_LLTX; 143 124 return efv; 144 125 fail1: 145 126 free_netdev(net_dev);