lio_vf_rep.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672
  1. /**********************************************************************
  2. * Author: Cavium, Inc.
  3. *
  4. * Contact: support@cavium.com
  5. * Please include "LiquidIO" in the subject.
  6. *
  7. * Copyright (c) 2003-2017 Cavium, Inc.
  8. *
  9. * This file is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License, Version 2, as
  11. * published by the Free Software Foundation.
  12. *
  13. * This file is distributed in the hope that it will be useful, but
  14. * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
  15. * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
  16. * NONINFRINGEMENT. See the GNU General Public License for more details.
  17. ***********************************************************************/
  18. #include <linux/pci.h>
  19. #include <linux/if_vlan.h>
  20. #include "liquidio_common.h"
  21. #include "octeon_droq.h"
  22. #include "octeon_iq.h"
  23. #include "response_manager.h"
  24. #include "octeon_device.h"
  25. #include "octeon_nic.h"
  26. #include "octeon_main.h"
  27. #include "octeon_network.h"
  28. #include "lio_vf_rep.h"
  29. static int lio_vf_rep_open(struct net_device *ndev);
  30. static int lio_vf_rep_stop(struct net_device *ndev);
  31. static netdev_tx_t lio_vf_rep_pkt_xmit(struct sk_buff *skb,
  32. struct net_device *ndev);
  33. static void lio_vf_rep_tx_timeout(struct net_device *netdev, unsigned int txqueue);
  34. static int lio_vf_rep_phys_port_name(struct net_device *dev,
  35. char *buf, size_t len);
  36. static void lio_vf_rep_get_stats64(struct net_device *dev,
  37. struct rtnl_link_stats64 *stats64);
  38. static int lio_vf_rep_change_mtu(struct net_device *ndev, int new_mtu);
  39. static int lio_vf_get_port_parent_id(struct net_device *dev,
  40. struct netdev_phys_item_id *ppid);
  41. static const struct net_device_ops lio_vf_rep_ndev_ops = {
  42. .ndo_open = lio_vf_rep_open,
  43. .ndo_stop = lio_vf_rep_stop,
  44. .ndo_start_xmit = lio_vf_rep_pkt_xmit,
  45. .ndo_tx_timeout = lio_vf_rep_tx_timeout,
  46. .ndo_get_phys_port_name = lio_vf_rep_phys_port_name,
  47. .ndo_get_stats64 = lio_vf_rep_get_stats64,
  48. .ndo_change_mtu = lio_vf_rep_change_mtu,
  49. .ndo_get_port_parent_id = lio_vf_get_port_parent_id,
  50. };
  51. static int
  52. lio_vf_rep_send_soft_command(struct octeon_device *oct,
  53. void *req, int req_size,
  54. void *resp, int resp_size)
  55. {
  56. int tot_resp_size = sizeof(struct lio_vf_rep_resp) + resp_size;
  57. struct octeon_soft_command *sc = NULL;
  58. struct lio_vf_rep_resp *rep_resp;
  59. void *sc_req;
  60. int err;
  61. sc = (struct octeon_soft_command *)
  62. octeon_alloc_soft_command(oct, req_size,
  63. tot_resp_size, 0);
  64. if (!sc)
  65. return -ENOMEM;
  66. init_completion(&sc->complete);
  67. sc->sc_status = OCTEON_REQUEST_PENDING;
  68. sc_req = (struct lio_vf_rep_req *)sc->virtdptr;
  69. memcpy(sc_req, req, req_size);
  70. rep_resp = (struct lio_vf_rep_resp *)sc->virtrptr;
  71. memset(rep_resp, 0, tot_resp_size);
  72. WRITE_ONCE(rep_resp->status, 1);
  73. sc->iq_no = 0;
  74. octeon_prepare_soft_command(oct, sc, OPCODE_NIC,
  75. OPCODE_NIC_VF_REP_CMD, 0, 0, 0);
  76. err = octeon_send_soft_command(oct, sc);
  77. if (err == IQ_SEND_FAILED)
  78. goto free_buff;
  79. err = wait_for_sc_completion_timeout(oct, sc, 0);
  80. if (err)
  81. return err;
  82. err = READ_ONCE(rep_resp->status) ? -EBUSY : 0;
  83. if (err)
  84. dev_err(&oct->pci_dev->dev, "VF rep send config failed\n");
  85. else if (resp)
  86. memcpy(resp, (rep_resp + 1), resp_size);
  87. WRITE_ONCE(sc->caller_is_done, true);
  88. return err;
  89. free_buff:
  90. octeon_free_soft_command(oct, sc);
  91. return err;
  92. }
  93. static int
  94. lio_vf_rep_open(struct net_device *ndev)
  95. {
  96. struct lio_vf_rep_desc *vf_rep = netdev_priv(ndev);
  97. struct lio_vf_rep_req rep_cfg;
  98. struct octeon_device *oct;
  99. int ret;
  100. oct = vf_rep->oct;
  101. memset(&rep_cfg, 0, sizeof(rep_cfg));
  102. rep_cfg.req_type = LIO_VF_REP_REQ_STATE;
  103. rep_cfg.ifidx = vf_rep->ifidx;
  104. rep_cfg.rep_state.state = LIO_VF_REP_STATE_UP;
  105. ret = lio_vf_rep_send_soft_command(oct, &rep_cfg,
  106. sizeof(rep_cfg), NULL, 0);
  107. if (ret) {
  108. dev_err(&oct->pci_dev->dev,
  109. "VF_REP open failed with err %d\n", ret);
  110. return -EIO;
  111. }
  112. atomic_set(&vf_rep->ifstate, (atomic_read(&vf_rep->ifstate) |
  113. LIO_IFSTATE_RUNNING));
  114. netif_carrier_on(ndev);
  115. netif_start_queue(ndev);
  116. return 0;
  117. }
  118. static int
  119. lio_vf_rep_stop(struct net_device *ndev)
  120. {
  121. struct lio_vf_rep_desc *vf_rep = netdev_priv(ndev);
  122. struct lio_vf_rep_req rep_cfg;
  123. struct octeon_device *oct;
  124. int ret;
  125. oct = vf_rep->oct;
  126. memset(&rep_cfg, 0, sizeof(rep_cfg));
  127. rep_cfg.req_type = LIO_VF_REP_REQ_STATE;
  128. rep_cfg.ifidx = vf_rep->ifidx;
  129. rep_cfg.rep_state.state = LIO_VF_REP_STATE_DOWN;
  130. ret = lio_vf_rep_send_soft_command(oct, &rep_cfg,
  131. sizeof(rep_cfg), NULL, 0);
  132. if (ret) {
  133. dev_err(&oct->pci_dev->dev,
  134. "VF_REP dev stop failed with err %d\n", ret);
  135. return -EIO;
  136. }
  137. atomic_set(&vf_rep->ifstate, (atomic_read(&vf_rep->ifstate) &
  138. ~LIO_IFSTATE_RUNNING));
  139. netif_tx_disable(ndev);
  140. netif_carrier_off(ndev);
  141. return 0;
  142. }
  143. static void
  144. lio_vf_rep_tx_timeout(struct net_device *ndev, unsigned int txqueue)
  145. {
  146. netif_trans_update(ndev);
  147. netif_wake_queue(ndev);
  148. }
  149. static void
  150. lio_vf_rep_get_stats64(struct net_device *dev,
  151. struct rtnl_link_stats64 *stats64)
  152. {
  153. struct lio_vf_rep_desc *vf_rep = netdev_priv(dev);
  154. /* Swap tx and rx stats as VF rep is a switch port */
  155. stats64->tx_packets = vf_rep->stats.rx_packets;
  156. stats64->tx_bytes = vf_rep->stats.rx_bytes;
  157. stats64->tx_dropped = vf_rep->stats.rx_dropped;
  158. stats64->rx_packets = vf_rep->stats.tx_packets;
  159. stats64->rx_bytes = vf_rep->stats.tx_bytes;
  160. stats64->rx_dropped = vf_rep->stats.tx_dropped;
  161. }
  162. static int
  163. lio_vf_rep_change_mtu(struct net_device *ndev, int new_mtu)
  164. {
  165. struct lio_vf_rep_desc *vf_rep = netdev_priv(ndev);
  166. struct lio_vf_rep_req rep_cfg;
  167. struct octeon_device *oct;
  168. int ret;
  169. oct = vf_rep->oct;
  170. memset(&rep_cfg, 0, sizeof(rep_cfg));
  171. rep_cfg.req_type = LIO_VF_REP_REQ_MTU;
  172. rep_cfg.ifidx = vf_rep->ifidx;
  173. rep_cfg.rep_mtu.mtu = cpu_to_be32(new_mtu);
  174. ret = lio_vf_rep_send_soft_command(oct, &rep_cfg,
  175. sizeof(rep_cfg), NULL, 0);
  176. if (ret) {
  177. dev_err(&oct->pci_dev->dev,
  178. "Change MTU failed with err %d\n", ret);
  179. return -EIO;
  180. }
  181. WRITE_ONCE(ndev->mtu, new_mtu);
  182. return 0;
  183. }
  184. static int
  185. lio_vf_rep_phys_port_name(struct net_device *dev,
  186. char *buf, size_t len)
  187. {
  188. struct lio_vf_rep_desc *vf_rep = netdev_priv(dev);
  189. struct octeon_device *oct = vf_rep->oct;
  190. int ret;
  191. ret = snprintf(buf, len, "pf%dvf%d", oct->pf_num,
  192. vf_rep->ifidx - oct->pf_num * 64 - 1);
  193. if (ret >= len)
  194. return -EOPNOTSUPP;
  195. return 0;
  196. }
  197. static struct net_device *
  198. lio_vf_rep_get_ndev(struct octeon_device *oct, int ifidx)
  199. {
  200. int vf_id, max_vfs = CN23XX_MAX_VFS_PER_PF + 1;
  201. int vfid_mask = max_vfs - 1;
  202. if (ifidx <= oct->pf_num * max_vfs ||
  203. ifidx >= oct->pf_num * max_vfs + max_vfs)
  204. return NULL;
  205. /* ifidx 1-63 for PF0 VFs
  206. * ifidx 65-127 for PF1 VFs
  207. */
  208. vf_id = (ifidx & vfid_mask) - 1;
  209. return oct->vf_rep_list.ndev[vf_id];
  210. }
  211. static void
  212. lio_vf_rep_copy_packet(struct octeon_device *oct,
  213. struct sk_buff *skb,
  214. int len)
  215. {
  216. if (likely(len > MIN_SKB_SIZE)) {
  217. struct octeon_skb_page_info *pg_info;
  218. unsigned char *va;
  219. pg_info = ((struct octeon_skb_page_info *)(skb->cb));
  220. if (pg_info->page) {
  221. va = page_address(pg_info->page) +
  222. pg_info->page_offset;
  223. memcpy(skb->data, va, MIN_SKB_SIZE);
  224. skb_put(skb, MIN_SKB_SIZE);
  225. skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
  226. pg_info->page,
  227. pg_info->page_offset + MIN_SKB_SIZE,
  228. len - MIN_SKB_SIZE,
  229. LIO_RXBUFFER_SZ);
  230. }
  231. } else {
  232. struct octeon_skb_page_info *pg_info =
  233. ((struct octeon_skb_page_info *)(skb->cb));
  234. skb_copy_to_linear_data(skb, page_address(pg_info->page) +
  235. pg_info->page_offset, len);
  236. skb_put(skb, len);
  237. put_page(pg_info->page);
  238. }
  239. }
  240. static int
  241. lio_vf_rep_pkt_recv(struct octeon_recv_info *recv_info, void *buf)
  242. {
  243. struct octeon_recv_pkt *recv_pkt = recv_info->recv_pkt;
  244. struct lio_vf_rep_desc *vf_rep;
  245. struct net_device *vf_ndev;
  246. struct octeon_device *oct;
  247. union octeon_rh *rh;
  248. struct sk_buff *skb;
  249. int i, ifidx;
  250. oct = lio_get_device(recv_pkt->octeon_id);
  251. if (!oct)
  252. goto free_buffers;
  253. skb = recv_pkt->buffer_ptr[0];
  254. rh = &recv_pkt->rh;
  255. ifidx = rh->r.ossp;
  256. vf_ndev = lio_vf_rep_get_ndev(oct, ifidx);
  257. if (!vf_ndev)
  258. goto free_buffers;
  259. vf_rep = netdev_priv(vf_ndev);
  260. if (!(atomic_read(&vf_rep->ifstate) & LIO_IFSTATE_RUNNING) ||
  261. recv_pkt->buffer_count > 1)
  262. goto free_buffers;
  263. skb->dev = vf_ndev;
  264. /* Multiple buffers are not used for vf_rep packets.
  265. * So just buffer_size[0] is valid.
  266. */
  267. lio_vf_rep_copy_packet(oct, skb, recv_pkt->buffer_size[0]);
  268. skb_pull(skb, rh->r_dh.len * BYTES_PER_DHLEN_UNIT);
  269. skb->protocol = eth_type_trans(skb, skb->dev);
  270. skb->ip_summed = CHECKSUM_NONE;
  271. netif_rx(skb);
  272. octeon_free_recv_info(recv_info);
  273. return 0;
  274. free_buffers:
  275. for (i = 0; i < recv_pkt->buffer_count; i++)
  276. recv_buffer_free(recv_pkt->buffer_ptr[i]);
  277. octeon_free_recv_info(recv_info);
  278. return 0;
  279. }
  280. static void
  281. lio_vf_rep_packet_sent_callback(struct octeon_device *oct,
  282. u32 status, void *buf)
  283. {
  284. struct octeon_soft_command *sc = (struct octeon_soft_command *)buf;
  285. struct sk_buff *skb = sc->ctxptr;
  286. struct net_device *ndev = skb->dev;
  287. u32 iq_no;
  288. dma_unmap_single(&oct->pci_dev->dev, sc->dmadptr,
  289. sc->datasize, DMA_TO_DEVICE);
  290. dev_kfree_skb_any(skb);
  291. iq_no = sc->iq_no;
  292. octeon_free_soft_command(oct, sc);
  293. if (octnet_iq_is_full(oct, iq_no))
  294. return;
  295. if (netif_queue_stopped(ndev))
  296. netif_wake_queue(ndev);
  297. }
  298. static netdev_tx_t
  299. lio_vf_rep_pkt_xmit(struct sk_buff *skb, struct net_device *ndev)
  300. {
  301. struct lio_vf_rep_desc *vf_rep = netdev_priv(ndev);
  302. struct net_device *parent_ndev = vf_rep->parent_ndev;
  303. struct octeon_device *oct = vf_rep->oct;
  304. struct octeon_instr_pki_ih3 *pki_ih3;
  305. struct octeon_soft_command *sc;
  306. struct lio *parent_lio;
  307. int status;
  308. parent_lio = GET_LIO(parent_ndev);
  309. if (!(atomic_read(&vf_rep->ifstate) & LIO_IFSTATE_RUNNING) ||
  310. skb->len <= 0)
  311. goto xmit_failed;
  312. if (octnet_iq_is_full(vf_rep->oct, parent_lio->txq)) {
  313. dev_err(&oct->pci_dev->dev, "VF rep: Device IQ full\n");
  314. netif_stop_queue(ndev);
  315. return NETDEV_TX_BUSY;
  316. }
  317. sc = (struct octeon_soft_command *)
  318. octeon_alloc_soft_command(oct, 0, 16, 0);
  319. if (!sc) {
  320. dev_err(&oct->pci_dev->dev, "VF rep: Soft command alloc failed\n");
  321. goto xmit_failed;
  322. }
  323. /* Multiple buffers are not used for vf_rep packets. */
  324. if (skb_shinfo(skb)->nr_frags != 0) {
  325. dev_err(&oct->pci_dev->dev, "VF rep: nr_frags != 0. Dropping packet\n");
  326. octeon_free_soft_command(oct, sc);
  327. goto xmit_failed;
  328. }
  329. sc->dmadptr = dma_map_single(&oct->pci_dev->dev,
  330. skb->data, skb->len, DMA_TO_DEVICE);
  331. if (dma_mapping_error(&oct->pci_dev->dev, sc->dmadptr)) {
  332. dev_err(&oct->pci_dev->dev, "VF rep: DMA mapping failed\n");
  333. octeon_free_soft_command(oct, sc);
  334. goto xmit_failed;
  335. }
  336. sc->virtdptr = skb->data;
  337. sc->datasize = skb->len;
  338. sc->ctxptr = skb;
  339. sc->iq_no = parent_lio->txq;
  340. octeon_prepare_soft_command(oct, sc, OPCODE_NIC, OPCODE_NIC_VF_REP_PKT,
  341. vf_rep->ifidx, 0, 0);
  342. pki_ih3 = (struct octeon_instr_pki_ih3 *)&sc->cmd.cmd3.pki_ih3;
  343. pki_ih3->tagtype = ORDERED_TAG;
  344. sc->callback = lio_vf_rep_packet_sent_callback;
  345. sc->callback_arg = sc;
  346. status = octeon_send_soft_command(oct, sc);
  347. if (status == IQ_SEND_FAILED) {
  348. dma_unmap_single(&oct->pci_dev->dev, sc->dmadptr,
  349. sc->datasize, DMA_TO_DEVICE);
  350. octeon_free_soft_command(oct, sc);
  351. goto xmit_failed;
  352. }
  353. if (status == IQ_SEND_STOP)
  354. netif_stop_queue(ndev);
  355. netif_trans_update(ndev);
  356. return NETDEV_TX_OK;
  357. xmit_failed:
  358. dev_kfree_skb_any(skb);
  359. return NETDEV_TX_OK;
  360. }
  361. static int lio_vf_get_port_parent_id(struct net_device *dev,
  362. struct netdev_phys_item_id *ppid)
  363. {
  364. struct lio_vf_rep_desc *vf_rep = netdev_priv(dev);
  365. struct net_device *parent_ndev = vf_rep->parent_ndev;
  366. struct lio *lio = GET_LIO(parent_ndev);
  367. ppid->id_len = ETH_ALEN;
  368. ether_addr_copy(ppid->id, (void *)&lio->linfo.hw_addr + 2);
  369. return 0;
  370. }
  371. static void
  372. lio_vf_rep_fetch_stats(struct work_struct *work)
  373. {
  374. struct cavium_wk *wk = (struct cavium_wk *)work;
  375. struct lio_vf_rep_desc *vf_rep = wk->ctxptr;
  376. struct lio_vf_rep_stats stats;
  377. struct lio_vf_rep_req rep_cfg;
  378. struct octeon_device *oct;
  379. int ret;
  380. oct = vf_rep->oct;
  381. memset(&rep_cfg, 0, sizeof(rep_cfg));
  382. rep_cfg.req_type = LIO_VF_REP_REQ_STATS;
  383. rep_cfg.ifidx = vf_rep->ifidx;
  384. ret = lio_vf_rep_send_soft_command(oct, &rep_cfg, sizeof(rep_cfg),
  385. &stats, sizeof(stats));
  386. if (!ret) {
  387. octeon_swap_8B_data((u64 *)&stats, (sizeof(stats) >> 3));
  388. memcpy(&vf_rep->stats, &stats, sizeof(stats));
  389. }
  390. schedule_delayed_work(&vf_rep->stats_wk.work,
  391. msecs_to_jiffies(LIO_VF_REP_STATS_POLL_TIME_MS));
  392. }
  393. int
  394. lio_vf_rep_create(struct octeon_device *oct)
  395. {
  396. struct lio_vf_rep_desc *vf_rep;
  397. struct net_device *ndev;
  398. int i, num_vfs;
  399. if (oct->eswitch_mode != DEVLINK_ESWITCH_MODE_SWITCHDEV)
  400. return 0;
  401. if (!oct->sriov_info.sriov_enabled)
  402. return 0;
  403. num_vfs = oct->sriov_info.num_vfs_alloced;
  404. oct->vf_rep_list.num_vfs = 0;
  405. for (i = 0; i < num_vfs; i++) {
  406. ndev = alloc_etherdev(sizeof(struct lio_vf_rep_desc));
  407. if (!ndev) {
  408. dev_err(&oct->pci_dev->dev,
  409. "VF rep device %d creation failed\n", i);
  410. goto cleanup;
  411. }
  412. ndev->min_mtu = LIO_MIN_MTU_SIZE;
  413. ndev->max_mtu = LIO_MAX_MTU_SIZE;
  414. ndev->netdev_ops = &lio_vf_rep_ndev_ops;
  415. vf_rep = netdev_priv(ndev);
  416. memset(vf_rep, 0, sizeof(*vf_rep));
  417. vf_rep->ndev = ndev;
  418. vf_rep->oct = oct;
  419. vf_rep->parent_ndev = oct->props[0].netdev;
  420. vf_rep->ifidx = (oct->pf_num * 64) + i + 1;
  421. eth_hw_addr_random(ndev);
  422. if (register_netdev(ndev)) {
  423. dev_err(&oct->pci_dev->dev, "VF rep nerdev registration failed\n");
  424. free_netdev(ndev);
  425. goto cleanup;
  426. }
  427. netif_carrier_off(ndev);
  428. INIT_DELAYED_WORK(&vf_rep->stats_wk.work,
  429. lio_vf_rep_fetch_stats);
  430. vf_rep->stats_wk.ctxptr = (void *)vf_rep;
  431. schedule_delayed_work(&vf_rep->stats_wk.work,
  432. msecs_to_jiffies
  433. (LIO_VF_REP_STATS_POLL_TIME_MS));
  434. oct->vf_rep_list.num_vfs++;
  435. oct->vf_rep_list.ndev[i] = ndev;
  436. }
  437. if (octeon_register_dispatch_fn(oct, OPCODE_NIC,
  438. OPCODE_NIC_VF_REP_PKT,
  439. lio_vf_rep_pkt_recv, oct)) {
  440. dev_err(&oct->pci_dev->dev, "VF rep Dispatch func registration failed\n");
  441. goto cleanup;
  442. }
  443. return 0;
  444. cleanup:
  445. for (i = 0; i < oct->vf_rep_list.num_vfs; i++) {
  446. ndev = oct->vf_rep_list.ndev[i];
  447. oct->vf_rep_list.ndev[i] = NULL;
  448. if (ndev) {
  449. vf_rep = netdev_priv(ndev);
  450. cancel_delayed_work_sync
  451. (&vf_rep->stats_wk.work);
  452. unregister_netdev(ndev);
  453. free_netdev(ndev);
  454. }
  455. }
  456. oct->vf_rep_list.num_vfs = 0;
  457. return -1;
  458. }
  459. void
  460. lio_vf_rep_destroy(struct octeon_device *oct)
  461. {
  462. struct lio_vf_rep_desc *vf_rep;
  463. struct net_device *ndev;
  464. int i;
  465. if (oct->eswitch_mode != DEVLINK_ESWITCH_MODE_SWITCHDEV)
  466. return;
  467. if (!oct->sriov_info.sriov_enabled)
  468. return;
  469. for (i = 0; i < oct->vf_rep_list.num_vfs; i++) {
  470. ndev = oct->vf_rep_list.ndev[i];
  471. oct->vf_rep_list.ndev[i] = NULL;
  472. if (ndev) {
  473. vf_rep = netdev_priv(ndev);
  474. cancel_delayed_work_sync
  475. (&vf_rep->stats_wk.work);
  476. netif_tx_disable(ndev);
  477. netif_carrier_off(ndev);
  478. unregister_netdev(ndev);
  479. free_netdev(ndev);
  480. }
  481. }
  482. oct->vf_rep_list.num_vfs = 0;
  483. }
  484. static int
  485. lio_vf_rep_netdev_event(struct notifier_block *nb,
  486. unsigned long event, void *ptr)
  487. {
  488. struct net_device *ndev = netdev_notifier_info_to_dev(ptr);
  489. struct lio_vf_rep_desc *vf_rep;
  490. struct lio_vf_rep_req rep_cfg;
  491. struct octeon_device *oct;
  492. int ret;
  493. switch (event) {
  494. case NETDEV_REGISTER:
  495. case NETDEV_CHANGENAME:
  496. break;
  497. default:
  498. return NOTIFY_DONE;
  499. }
  500. if (ndev->netdev_ops != &lio_vf_rep_ndev_ops)
  501. return NOTIFY_DONE;
  502. vf_rep = netdev_priv(ndev);
  503. oct = vf_rep->oct;
  504. if (strlen(ndev->name) > LIO_IF_NAME_SIZE) {
  505. dev_err(&oct->pci_dev->dev,
  506. "Device name change sync failed as the size is > %d\n",
  507. LIO_IF_NAME_SIZE);
  508. return NOTIFY_DONE;
  509. }
  510. memset(&rep_cfg, 0, sizeof(rep_cfg));
  511. rep_cfg.req_type = LIO_VF_REP_REQ_DEVNAME;
  512. rep_cfg.ifidx = vf_rep->ifidx;
  513. strscpy(rep_cfg.rep_name.name, ndev->name,
  514. sizeof(rep_cfg.rep_name.name));
  515. ret = lio_vf_rep_send_soft_command(oct, &rep_cfg,
  516. sizeof(rep_cfg), NULL, 0);
  517. if (ret)
  518. dev_err(&oct->pci_dev->dev,
  519. "vf_rep netdev name change failed with err %d\n", ret);
  520. return NOTIFY_DONE;
  521. }
  522. static struct notifier_block lio_vf_rep_netdev_notifier = {
  523. .notifier_call = lio_vf_rep_netdev_event,
  524. };
  525. int
  526. lio_vf_rep_modinit(void)
  527. {
  528. if (register_netdevice_notifier(&lio_vf_rep_netdev_notifier)) {
  529. pr_err("netdev notifier registration failed\n");
  530. return -EFAULT;
  531. }
  532. return 0;
  533. }
  534. void
  535. lio_vf_rep_modexit(void)
  536. {
  537. if (unregister_netdevice_notifier(&lio_vf_rep_netdev_notifier))
  538. pr_err("netdev notifier unregister failed\n");
  539. }