1 /* 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. 4 * 5 * GPL LICENSE SUMMARY 6 * 7 * Copyright(c) 2012 Intel Corporation. All rights reserved. 8 * 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. 12 * 13 * BSD LICENSE 14 * 15 * Copyright(c) 2012 Intel Corporation. All rights reserved. 16 * 17 * Redistribution and use in source and binary forms, with or without 18 * modification, are permitted provided that the following conditions 19 * are met: 20 * 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 26 * distribution. 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. 30 * 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. 42 * 43 * Intel PCIe NTB Network Linux driver 44 * 45 * Contact Information: 46 * Jon Mason <jon.mason@intel.com> 47 */ 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> 53 54 #define NTB_NETDEV_VER "0.7" 55 56 MODULE_DESCRIPTION(KBUILD_MODNAME); 57 MODULE_VERSION(NTB_NETDEV_VER); 58 MODULE_LICENSE("Dual BSD/GPL"); 59 MODULE_AUTHOR("Intel Corporation"); 60 61 struct ntb_netdev { 62 struct list_head list; 63 struct pci_dev *pdev; 64 struct net_device *ndev; 65 struct ntb_transport_qp *qp; 66 }; 67 68 #define NTB_TX_TIMEOUT_MS 1000 69 #define NTB_RXQ_SIZE 100 70 71 static LIST_HEAD(dev_list); 72 73 static void ntb_netdev_event_handler(void *data, int status) 74 { 75 struct net_device *ndev = data; 76 struct ntb_netdev *dev = netdev_priv(ndev); 77 78 netdev_dbg(ndev, "Event %x, Link %x\n", status, 79 ntb_transport_link_query(dev->qp)); 80 81 switch (status) { 82 case NTB_LINK_DOWN: 83 netif_carrier_off(ndev); 84 break; 85 case NTB_LINK_UP: 86 if (!ntb_transport_link_query(dev->qp)) 87 return; 88 89 netif_carrier_on(ndev); 90 break; 91 default: 92 netdev_warn(ndev, "Unsupported event type %d\n", status); 93 } 94 } 95 96 static void ntb_netdev_rx_handler(struct ntb_transport_qp *qp, void *qp_data, 97 void *data, int len) 98 { 99 struct net_device *ndev = qp_data; 100 struct sk_buff *skb; 101 int rc; 102 103 skb = data; 104 if (!skb) 105 return; 106 107 netdev_dbg(ndev, "%s: %d byte payload received\n", __func__, len); 108 109 skb_put(skb, len); 110 skb->protocol = eth_type_trans(skb, ndev); 111 skb->ip_summed = CHECKSUM_NONE; 112 113 if (netif_rx(skb) == NET_RX_DROP) { 114 ndev->stats.rx_errors++; 115 ndev->stats.rx_dropped++; 116 } else { 117 ndev->stats.rx_packets++; 118 ndev->stats.rx_bytes += len; 119 } 120 121 skb = netdev_alloc_skb(ndev, ndev->mtu + ETH_HLEN); 122 if (!skb) { 123 ndev->stats.rx_errors++; 124 ndev->stats.rx_frame_errors++; 125 return; 126 } 127 128 rc = ntb_transport_rx_enqueue(qp, skb, skb->data, ndev->mtu + ETH_HLEN); 129 if (rc) { 130 dev_kfree_skb(skb); 131 ndev->stats.rx_errors++; 132 ndev->stats.rx_fifo_errors++; 133 } 134 } 135 136 static void ntb_netdev_tx_handler(struct ntb_transport_qp *qp, void *qp_data, 137 void *data, int len) 138 { 139 struct net_device *ndev = qp_data; 140 struct sk_buff *skb; 141 142 skb = data; 143 if (!skb || !ndev) 144 return; 145 146 if (len > 0) { 147 ndev->stats.tx_packets++; 148 ndev->stats.tx_bytes += skb->len; 149 } else { 150 ndev->stats.tx_errors++; 151 ndev->stats.tx_aborted_errors++; 152 } 153 154 dev_kfree_skb(skb); 155 } 156 157 static netdev_tx_t ntb_netdev_start_xmit(struct sk_buff *skb, 158 struct net_device *ndev) 159 { 160 struct ntb_netdev *dev = netdev_priv(ndev); 161 int rc; 162 163 netdev_dbg(ndev, "%s: skb len %d\n", __func__, skb->len); 164 165 rc = ntb_transport_tx_enqueue(dev->qp, skb, skb->data, skb->len); 166 if (rc) 167 goto err; 168 169 return NETDEV_TX_OK; 170 171 err: 172 ndev->stats.tx_dropped++; 173 ndev->stats.tx_errors++; 174 return NETDEV_TX_BUSY; 175 } 176 177 static int ntb_netdev_open(struct net_device *ndev) 178 { 179 struct ntb_netdev *dev = netdev_priv(ndev); 180 struct sk_buff *skb; 181 int rc, i, len; 182 183 /* Add some empty rx bufs */ 184 for (i = 0; i < NTB_RXQ_SIZE; i++) { 185 skb = netdev_alloc_skb(ndev, ndev->mtu + ETH_HLEN); 186 if (!skb) { 187 rc = -ENOMEM; 188 goto err; 189 } 190 191 rc = ntb_transport_rx_enqueue(dev->qp, skb, skb->data, 192 ndev->mtu + ETH_HLEN); 193 if (rc == -EINVAL) { 194 dev_kfree_skb(skb); 195 goto err; 196 } 197 } 198 199 netif_carrier_off(ndev); 200 ntb_transport_link_up(dev->qp); 201 202 return 0; 203 204 err: 205 while ((skb = ntb_transport_rx_remove(dev->qp, &len))) 206 dev_kfree_skb(skb); 207 return rc; 208 } 209 210 static int ntb_netdev_close(struct net_device *ndev) 211 { 212 struct ntb_netdev *dev = netdev_priv(ndev); 213 struct sk_buff *skb; 214 int len; 215 216 ntb_transport_link_down(dev->qp); 217 218 while ((skb = ntb_transport_rx_remove(dev->qp, &len))) 219 dev_kfree_skb(skb); 220 221 return 0; 222 } 223 224 static int ntb_netdev_change_mtu(struct net_device *ndev, int new_mtu) 225 { 226 struct ntb_netdev *dev = netdev_priv(ndev); 227 struct sk_buff *skb; 228 int len, rc; 229 230 if (new_mtu > ntb_transport_max_size(dev->qp) - ETH_HLEN) 231 return -EINVAL; 232 233 if (!netif_running(ndev)) { 234 ndev->mtu = new_mtu; 235 return 0; 236 } 237 238 /* Bring down the link and dispose of posted rx entries */ 239 ntb_transport_link_down(dev->qp); 240 241 if (ndev->mtu < new_mtu) { 242 int i; 243 244 for (i = 0; (skb = ntb_transport_rx_remove(dev->qp, &len)); i++) 245 dev_kfree_skb(skb); 246 247 for (; i; i--) { 248 skb = netdev_alloc_skb(ndev, new_mtu + ETH_HLEN); 249 if (!skb) { 250 rc = -ENOMEM; 251 goto err; 252 } 253 254 rc = ntb_transport_rx_enqueue(dev->qp, skb, skb->data, 255 new_mtu + ETH_HLEN); 256 if (rc) { 257 dev_kfree_skb(skb); 258 goto err; 259 } 260 } 261 } 262 263 ndev->mtu = new_mtu; 264 265 ntb_transport_link_up(dev->qp); 266 267 return 0; 268 269 err: 270 ntb_transport_link_down(dev->qp); 271 272 while ((skb = ntb_transport_rx_remove(dev->qp, &len))) 273 dev_kfree_skb(skb); 274 275 netdev_err(ndev, "Error changing MTU, device inoperable\n"); 276 return rc; 277 } 278 279 static const struct net_device_ops ntb_netdev_ops = { 280 .ndo_open = ntb_netdev_open, 281 .ndo_stop = ntb_netdev_close, 282 .ndo_start_xmit = ntb_netdev_start_xmit, 283 .ndo_change_mtu = ntb_netdev_change_mtu, 284 .ndo_set_mac_address = eth_mac_addr, 285 }; 286 287 static void ntb_get_drvinfo(struct net_device *ndev, 288 struct ethtool_drvinfo *info) 289 { 290 struct ntb_netdev *dev = netdev_priv(ndev); 291 292 strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); 293 strlcpy(info->version, NTB_NETDEV_VER, sizeof(info->version)); 294 strlcpy(info->bus_info, pci_name(dev->pdev), sizeof(info->bus_info)); 295 } 296 297 static int ntb_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) 298 { 299 cmd->supported = SUPPORTED_Backplane; 300 cmd->advertising = ADVERTISED_Backplane; 301 ethtool_cmd_speed_set(cmd, SPEED_UNKNOWN); 302 cmd->duplex = DUPLEX_FULL; 303 cmd->port = PORT_OTHER; 304 cmd->phy_address = 0; 305 cmd->transceiver = XCVR_DUMMY1; 306 cmd->autoneg = AUTONEG_ENABLE; 307 cmd->maxtxpkt = 0; 308 cmd->maxrxpkt = 0; 309 310 return 0; 311 } 312 313 static const struct ethtool_ops ntb_ethtool_ops = { 314 .get_drvinfo = ntb_get_drvinfo, 315 .get_link = ethtool_op_get_link, 316 .get_settings = ntb_get_settings, 317 }; 318 319 static const struct ntb_queue_handlers ntb_netdev_handlers = { 320 .tx_handler = ntb_netdev_tx_handler, 321 .rx_handler = ntb_netdev_rx_handler, 322 .event_handler = ntb_netdev_event_handler, 323 }; 324 325 static int ntb_netdev_probe(struct pci_dev *pdev) 326 { 327 struct net_device *ndev; 328 struct ntb_netdev *dev; 329 int rc; 330 331 ndev = alloc_etherdev(sizeof(struct ntb_netdev)); 332 if (!ndev) 333 return -ENOMEM; 334 335 dev = netdev_priv(ndev); 336 dev->ndev = ndev; 337 dev->pdev = pdev; 338 BUG_ON(!dev->pdev); 339 ndev->features = NETIF_F_HIGHDMA; 340 341 ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE; 342 343 ndev->hw_features = ndev->features; 344 ndev->watchdog_timeo = msecs_to_jiffies(NTB_TX_TIMEOUT_MS); 345 346 random_ether_addr(ndev->perm_addr); 347 memcpy(ndev->dev_addr, ndev->perm_addr, ndev->addr_len); 348 349 ndev->netdev_ops = &ntb_netdev_ops; 350 ndev->ethtool_ops = &ntb_ethtool_ops; 351 352 dev->qp = ntb_transport_create_queue(ndev, pdev, &ntb_netdev_handlers); 353 if (!dev->qp) { 354 rc = -EIO; 355 goto err; 356 } 357 358 ndev->mtu = ntb_transport_max_size(dev->qp) - ETH_HLEN; 359 360 rc = register_netdev(ndev); 361 if (rc) 362 goto err1; 363 364 list_add(&dev->list, &dev_list); 365 dev_info(&pdev->dev, "%s created\n", ndev->name); 366 return 0; 367 368 err1: 369 ntb_transport_free_queue(dev->qp); 370 err: 371 free_netdev(ndev); 372 return rc; 373 } 374 375 static void ntb_netdev_remove(struct pci_dev *pdev) 376 { 377 struct net_device *ndev; 378 struct ntb_netdev *dev; 379 bool found = false; 380 381 list_for_each_entry(dev, &dev_list, list) { 382 if (dev->pdev == pdev) { 383 found = true; 384 break; 385 } 386 } 387 if (!found) 388 return; 389 390 list_del(&dev->list); 391 392 ndev = dev->ndev; 393 394 unregister_netdev(ndev); 395 ntb_transport_free_queue(dev->qp); 396 free_netdev(ndev); 397 } 398 399 static struct ntb_client ntb_netdev_client = { 400 .driver.name = KBUILD_MODNAME, 401 .driver.owner = THIS_MODULE, 402 .probe = ntb_netdev_probe, 403 .remove = ntb_netdev_remove, 404 }; 405 406 static int __init ntb_netdev_init_module(void) 407 { 408 int rc; 409 410 rc = ntb_register_client_dev(KBUILD_MODNAME); 411 if (rc) 412 return rc; 413 return ntb_register_client(&ntb_netdev_client); 414 } 415 module_init(ntb_netdev_init_module); 416 417 static void __exit ntb_netdev_exit_module(void) 418 { 419 ntb_unregister_client(&ntb_netdev_client); 420 ntb_unregister_client_dev(KBUILD_MODNAME); 421 } 422 module_exit(ntb_netdev_exit_module); 423