2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
7 * Copyright(c) 2012 Intel Corporation. All rights reserved.
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
15 * Copyright(c) 2012 Intel Corporation. All rights reserved.
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions
21 * * Redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer.
23 * * Redistributions in binary form must reproduce the above copy
24 * notice, this list of conditions and the following disclaimer in
25 * the documentation and/or other materials provided with the
27 * * Neither the name of Intel Corporation nor the names of its
28 * contributors may be used to endorse or promote products derived
29 * from this software without specific prior written permission.
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
36 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
37 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
38 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
39 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
40 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
41 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43 * Intel PCIe NTB Network Linux driver
45 * Contact Information:
46 * Jon Mason <jon.mason@intel.com>
48 #include <linux/etherdevice.h>
49 #include <linux/ethtool.h>
50 #include <linux/module.h>
51 #include <linux/pci.h>
52 #include <linux/ntb.h>
54 #define NTB_NETDEV_VER "0.7"
56 MODULE_DESCRIPTION(KBUILD_MODNAME
);
57 MODULE_VERSION(NTB_NETDEV_VER
);
58 MODULE_LICENSE("Dual BSD/GPL");
59 MODULE_AUTHOR("Intel Corporation");
62 struct list_head list
;
64 struct net_device
*ndev
;
65 struct ntb_transport_qp
*qp
;
68 #define NTB_TX_TIMEOUT_MS 1000
69 #define NTB_RXQ_SIZE 100
71 static LIST_HEAD(dev_list
);
73 static void ntb_netdev_event_handler(void *data
, int status
)
75 struct net_device
*ndev
= data
;
76 struct ntb_netdev
*dev
= netdev_priv(ndev
);
78 netdev_dbg(ndev
, "Event %x, Link %x\n", status
,
79 ntb_transport_link_query(dev
->qp
));
81 /* Currently, only link status event is supported */
83 netif_carrier_on(ndev
);
85 netif_carrier_off(ndev
);
88 static void ntb_netdev_rx_handler(struct ntb_transport_qp
*qp
, void *qp_data
,
91 struct net_device
*ndev
= qp_data
;
99 netdev_dbg(ndev
, "%s: %d byte payload received\n", __func__
, len
);
102 skb
->protocol
= eth_type_trans(skb
, ndev
);
103 skb
->ip_summed
= CHECKSUM_NONE
;
105 if (netif_rx(skb
) == NET_RX_DROP
) {
106 ndev
->stats
.rx_errors
++;
107 ndev
->stats
.rx_dropped
++;
109 ndev
->stats
.rx_packets
++;
110 ndev
->stats
.rx_bytes
+= len
;
113 skb
= netdev_alloc_skb(ndev
, ndev
->mtu
+ ETH_HLEN
);
115 ndev
->stats
.rx_errors
++;
116 ndev
->stats
.rx_frame_errors
++;
120 rc
= ntb_transport_rx_enqueue(qp
, skb
, skb
->data
, ndev
->mtu
+ ETH_HLEN
);
123 ndev
->stats
.rx_errors
++;
124 ndev
->stats
.rx_fifo_errors
++;
128 static void ntb_netdev_tx_handler(struct ntb_transport_qp
*qp
, void *qp_data
,
131 struct net_device
*ndev
= qp_data
;
139 ndev
->stats
.tx_packets
++;
140 ndev
->stats
.tx_bytes
+= skb
->len
;
142 ndev
->stats
.tx_errors
++;
143 ndev
->stats
.tx_aborted_errors
++;
149 static netdev_tx_t
ntb_netdev_start_xmit(struct sk_buff
*skb
,
150 struct net_device
*ndev
)
152 struct ntb_netdev
*dev
= netdev_priv(ndev
);
155 netdev_dbg(ndev
, "%s: skb len %d\n", __func__
, skb
->len
);
157 rc
= ntb_transport_tx_enqueue(dev
->qp
, skb
, skb
->data
, skb
->len
);
164 ndev
->stats
.tx_dropped
++;
165 ndev
->stats
.tx_errors
++;
166 return NETDEV_TX_BUSY
;
169 static int ntb_netdev_open(struct net_device
*ndev
)
171 struct ntb_netdev
*dev
= netdev_priv(ndev
);
175 /* Add some empty rx bufs */
176 for (i
= 0; i
< NTB_RXQ_SIZE
; i
++) {
177 skb
= netdev_alloc_skb(ndev
, ndev
->mtu
+ ETH_HLEN
);
183 rc
= ntb_transport_rx_enqueue(dev
->qp
, skb
, skb
->data
,
184 ndev
->mtu
+ ETH_HLEN
);
189 netif_carrier_off(ndev
);
190 ntb_transport_link_up(dev
->qp
);
195 while ((skb
= ntb_transport_rx_remove(dev
->qp
, &len
)))
200 static int ntb_netdev_close(struct net_device
*ndev
)
202 struct ntb_netdev
*dev
= netdev_priv(ndev
);
206 ntb_transport_link_down(dev
->qp
);
208 while ((skb
= ntb_transport_rx_remove(dev
->qp
, &len
)))
214 static int ntb_netdev_change_mtu(struct net_device
*ndev
, int new_mtu
)
216 struct ntb_netdev
*dev
= netdev_priv(ndev
);
220 if (new_mtu
> ntb_transport_max_size(dev
->qp
) - ETH_HLEN
)
223 if (!netif_running(ndev
)) {
228 /* Bring down the link and dispose of posted rx entries */
229 ntb_transport_link_down(dev
->qp
);
231 if (ndev
->mtu
< new_mtu
) {
234 for (i
= 0; (skb
= ntb_transport_rx_remove(dev
->qp
, &len
)); i
++)
238 skb
= netdev_alloc_skb(ndev
, new_mtu
+ ETH_HLEN
);
244 rc
= ntb_transport_rx_enqueue(dev
->qp
, skb
, skb
->data
,
255 ntb_transport_link_up(dev
->qp
);
260 ntb_transport_link_down(dev
->qp
);
262 while ((skb
= ntb_transport_rx_remove(dev
->qp
, &len
)))
265 netdev_err(ndev
, "Error changing MTU, device inoperable\n");
269 static const struct net_device_ops ntb_netdev_ops
= {
270 .ndo_open
= ntb_netdev_open
,
271 .ndo_stop
= ntb_netdev_close
,
272 .ndo_start_xmit
= ntb_netdev_start_xmit
,
273 .ndo_change_mtu
= ntb_netdev_change_mtu
,
274 .ndo_set_mac_address
= eth_mac_addr
,
277 static void ntb_get_drvinfo(struct net_device
*ndev
,
278 struct ethtool_drvinfo
*info
)
280 struct ntb_netdev
*dev
= netdev_priv(ndev
);
282 strlcpy(info
->driver
, KBUILD_MODNAME
, sizeof(info
->driver
));
283 strlcpy(info
->version
, NTB_NETDEV_VER
, sizeof(info
->version
));
284 strlcpy(info
->bus_info
, pci_name(dev
->pdev
), sizeof(info
->bus_info
));
287 static int ntb_get_settings(struct net_device
*dev
, struct ethtool_cmd
*cmd
)
289 cmd
->supported
= SUPPORTED_Backplane
;
290 cmd
->advertising
= ADVERTISED_Backplane
;
291 cmd
->speed
= SPEED_UNKNOWN
;
292 ethtool_cmd_speed_set(cmd
, SPEED_UNKNOWN
);
293 cmd
->duplex
= DUPLEX_FULL
;
294 cmd
->port
= PORT_OTHER
;
295 cmd
->phy_address
= 0;
296 cmd
->transceiver
= XCVR_DUMMY1
;
297 cmd
->autoneg
= AUTONEG_ENABLE
;
304 static const struct ethtool_ops ntb_ethtool_ops
= {
305 .get_drvinfo
= ntb_get_drvinfo
,
306 .get_link
= ethtool_op_get_link
,
307 .get_settings
= ntb_get_settings
,
310 static const struct ntb_queue_handlers ntb_netdev_handlers
= {
311 .tx_handler
= ntb_netdev_tx_handler
,
312 .rx_handler
= ntb_netdev_rx_handler
,
313 .event_handler
= ntb_netdev_event_handler
,
316 static int ntb_netdev_probe(struct pci_dev
*pdev
)
318 struct net_device
*ndev
;
319 struct ntb_netdev
*dev
;
322 ndev
= alloc_etherdev(sizeof(struct ntb_netdev
));
326 dev
= netdev_priv(ndev
);
330 ndev
->features
= NETIF_F_HIGHDMA
;
332 ndev
->priv_flags
|= IFF_LIVE_ADDR_CHANGE
;
334 ndev
->hw_features
= ndev
->features
;
335 ndev
->watchdog_timeo
= msecs_to_jiffies(NTB_TX_TIMEOUT_MS
);
337 random_ether_addr(ndev
->perm_addr
);
338 memcpy(ndev
->dev_addr
, ndev
->perm_addr
, ndev
->addr_len
);
340 ndev
->netdev_ops
= &ntb_netdev_ops
;
341 SET_ETHTOOL_OPS(ndev
, &ntb_ethtool_ops
);
343 dev
->qp
= ntb_transport_create_queue(ndev
, pdev
, &ntb_netdev_handlers
);
349 ndev
->mtu
= ntb_transport_max_size(dev
->qp
) - ETH_HLEN
;
351 rc
= register_netdev(ndev
);
355 list_add(&dev
->list
, &dev_list
);
356 dev_info(&pdev
->dev
, "%s created\n", ndev
->name
);
360 ntb_transport_free_queue(dev
->qp
);
366 static void ntb_netdev_remove(struct pci_dev
*pdev
)
368 struct net_device
*ndev
;
369 struct ntb_netdev
*dev
;
371 list_for_each_entry(dev
, &dev_list
, list
) {
372 if (dev
->pdev
== pdev
)
378 list_del(&dev
->list
);
382 unregister_netdev(ndev
);
383 ntb_transport_free_queue(dev
->qp
);
387 static struct ntb_client ntb_netdev_client
= {
388 .driver
.name
= KBUILD_MODNAME
,
389 .driver
.owner
= THIS_MODULE
,
390 .probe
= ntb_netdev_probe
,
391 .remove
= ntb_netdev_remove
,
394 static int __init
ntb_netdev_init_module(void)
398 rc
= ntb_register_client_dev(KBUILD_MODNAME
);
401 return ntb_register_client(&ntb_netdev_client
);
403 module_init(ntb_netdev_init_module
);
405 static void __exit
ntb_netdev_exit_module(void)
407 ntb_unregister_client(&ntb_netdev_client
);
408 ntb_unregister_client_dev(KBUILD_MODNAME
);
410 module_exit(ntb_netdev_exit_module
);